mirror of
https://github.com/mikedilger/chorus.git
synced 2026-05-03 06:51:42 +00:00
Verify events (verify id and signature), configurable
This commit is contained in:
parent
01a519be63
commit
68a8cc6ad4
@ -10,5 +10,6 @@ FriendlyConfig(
|
|||||||
public_key_hex: None,
|
public_key_hex: None,
|
||||||
user_hex_keys: [
|
user_hex_keys: [
|
||||||
"ee11a5dff40c19a555f41fe42b48f00e618c91225622ae37b6c2bb67b76c4e49"
|
"ee11a5dff40c19a555f41fe42b48f00e618c91225622ae37b6c2bb67b76c4e49"
|
||||||
]
|
],
|
||||||
|
verify_events: true,
|
||||||
)
|
)
|
||||||
@ -14,6 +14,7 @@ pub struct FriendlyConfig {
|
|||||||
pub description: Option<String>,
|
pub description: Option<String>,
|
||||||
pub public_key_hex: Option<String>,
|
pub public_key_hex: Option<String>,
|
||||||
pub user_hex_keys: Vec<String>,
|
pub user_hex_keys: Vec<String>,
|
||||||
|
pub verify_events: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for FriendlyConfig {
|
impl Default for FriendlyConfig {
|
||||||
@ -29,6 +30,7 @@ impl Default for FriendlyConfig {
|
|||||||
description: None,
|
description: None,
|
||||||
public_key_hex: None,
|
public_key_hex: None,
|
||||||
user_hex_keys: vec![],
|
user_hex_keys: vec![],
|
||||||
|
verify_events: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -46,6 +48,7 @@ impl FriendlyConfig {
|
|||||||
description,
|
description,
|
||||||
public_key_hex,
|
public_key_hex,
|
||||||
user_hex_keys,
|
user_hex_keys,
|
||||||
|
verify_events,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
let mut public_key: Option<Pubkey> = None;
|
let mut public_key: Option<Pubkey> = None;
|
||||||
@ -70,6 +73,7 @@ impl FriendlyConfig {
|
|||||||
public_key,
|
public_key,
|
||||||
user_keys,
|
user_keys,
|
||||||
user_hex_keys,
|
user_hex_keys,
|
||||||
|
verify_events,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,4 +91,5 @@ pub struct Config {
|
|||||||
pub public_key: Option<Pubkey>,
|
pub public_key: Option<Pubkey>,
|
||||||
pub user_keys: Vec<Pubkey>,
|
pub user_keys: Vec<Pubkey>,
|
||||||
pub user_hex_keys: Vec<String>,
|
pub user_hex_keys: Vec<String>,
|
||||||
|
pub verify_events: bool,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,10 @@ use thiserror::Error;
|
|||||||
/// Errors that can occur in the chorus crate
|
/// Errors that can occur in the chorus crate
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
// Bad event id
|
||||||
|
#[error("Bad event id, does not match hash")]
|
||||||
|
BadEventId,
|
||||||
|
|
||||||
// Bad hex input
|
// Bad hex input
|
||||||
#[error("Bad hex input")]
|
#[error("Bad hex input")]
|
||||||
BadHexInput,
|
BadHexInput,
|
||||||
@ -23,6 +27,10 @@ pub enum Error {
|
|||||||
#[error("Config: {0}")]
|
#[error("Config: {0}")]
|
||||||
Config(#[from] ron::error::SpannedError),
|
Config(#[from] ron::error::SpannedError),
|
||||||
|
|
||||||
|
// Crypto
|
||||||
|
#[error("Crypto: {0}")]
|
||||||
|
Crypto(#[from] secp256k1::Error),
|
||||||
|
|
||||||
// Duplicate event
|
// Duplicate event
|
||||||
#[error("Duplicate")]
|
#[error("Duplicate")]
|
||||||
Duplicate,
|
Duplicate,
|
||||||
|
|||||||
@ -186,7 +186,10 @@ impl WebSocketService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn validate_event(event: &Event<'_>) -> Result<bool, Error> {
|
async fn validate_event(event: &Event<'_>) -> Result<bool, Error> {
|
||||||
// FIXME: check signature
|
// Verify event is valid
|
||||||
|
if GLOBALS.config.read().await.verify_events {
|
||||||
|
event.verify()?;
|
||||||
|
}
|
||||||
|
|
||||||
// Accept relay lists from anybody
|
// Accept relay lists from anybody
|
||||||
if event.kind() == Kind(10002) {
|
if event.kind() == Kind(10002) {
|
||||||
|
|||||||
@ -125,6 +125,35 @@ impl<'a> Event<'a> {
|
|||||||
output.extend(br#""}"#);
|
output.extend(br#""}"#);
|
||||||
Ok(output)
|
Ok(output)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn verify(&self) -> Result<(), Error> {
|
||||||
|
use secp256k1::hashes::{sha256, Hash};
|
||||||
|
use secp256k1::schnorr::Signature;
|
||||||
|
use secp256k1::{Message, XOnlyPublicKey};
|
||||||
|
|
||||||
|
let signable = format!(
|
||||||
|
r#"[0,"{}",{},{},{},"{}"]"#,
|
||||||
|
self.pubkey(),
|
||||||
|
self.created_at(),
|
||||||
|
self.kind(),
|
||||||
|
self.tags()?,
|
||||||
|
unsafe { std::str::from_utf8_unchecked(self.content()) },
|
||||||
|
);
|
||||||
|
|
||||||
|
let hash = sha256::Hash::hash(signable.as_bytes());
|
||||||
|
|
||||||
|
let hashref = <sha256::Hash as AsRef<[u8]>>::as_ref(&hash);
|
||||||
|
if hashref != self.id().as_slice() {
|
||||||
|
return Err(Error::BadEventId);
|
||||||
|
}
|
||||||
|
|
||||||
|
let pubkey = XOnlyPublicKey::from_slice(self.pubkey().as_slice())?;
|
||||||
|
let sig = Signature::from_slice(self.sig().as_slice())?;
|
||||||
|
let message = Message::from_digest_slice(hashref)?;
|
||||||
|
sig.verify(&message, &pubkey)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Event<'_> {
|
impl fmt::Display for Event<'_> {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user