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,
|
||||
user_hex_keys: [
|
||||
"ee11a5dff40c19a555f41fe42b48f00e618c91225622ae37b6c2bb67b76c4e49"
|
||||
]
|
||||
],
|
||||
verify_events: true,
|
||||
)
|
||||
@ -14,6 +14,7 @@ pub struct FriendlyConfig {
|
||||
pub description: Option<String>,
|
||||
pub public_key_hex: Option<String>,
|
||||
pub user_hex_keys: Vec<String>,
|
||||
pub verify_events: bool,
|
||||
}
|
||||
|
||||
impl Default for FriendlyConfig {
|
||||
@ -29,6 +30,7 @@ impl Default for FriendlyConfig {
|
||||
description: None,
|
||||
public_key_hex: None,
|
||||
user_hex_keys: vec![],
|
||||
verify_events: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -46,6 +48,7 @@ impl FriendlyConfig {
|
||||
description,
|
||||
public_key_hex,
|
||||
user_hex_keys,
|
||||
verify_events,
|
||||
} = self;
|
||||
|
||||
let mut public_key: Option<Pubkey> = None;
|
||||
@ -70,6 +73,7 @@ impl FriendlyConfig {
|
||||
public_key,
|
||||
user_keys,
|
||||
user_hex_keys,
|
||||
verify_events,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -87,4 +91,5 @@ pub struct Config {
|
||||
pub public_key: Option<Pubkey>,
|
||||
pub user_keys: Vec<Pubkey>,
|
||||
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
|
||||
#[derive(Error, Debug)]
|
||||
pub enum Error {
|
||||
// Bad event id
|
||||
#[error("Bad event id, does not match hash")]
|
||||
BadEventId,
|
||||
|
||||
// Bad hex input
|
||||
#[error("Bad hex input")]
|
||||
BadHexInput,
|
||||
@ -23,6 +27,10 @@ pub enum Error {
|
||||
#[error("Config: {0}")]
|
||||
Config(#[from] ron::error::SpannedError),
|
||||
|
||||
// Crypto
|
||||
#[error("Crypto: {0}")]
|
||||
Crypto(#[from] secp256k1::Error),
|
||||
|
||||
// Duplicate event
|
||||
#[error("Duplicate")]
|
||||
Duplicate,
|
||||
|
||||
@ -186,7 +186,10 @@ impl WebSocketService {
|
||||
}
|
||||
|
||||
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
|
||||
if event.kind() == Kind(10002) {
|
||||
|
||||
@ -125,6 +125,35 @@ impl<'a> Event<'a> {
|
||||
output.extend(br#""}"#);
|
||||
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<'_> {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user