use std::sync::Arc;
use agentstategraph_policy::{
Policy, PolicySignature, SignatureVerificationError, SignatureVerifier,
};
use agentstategraph_policy_sign::{
Ed25519Verifier, InMemoryKeyRegistry, KeyRegistry, PolicyVerifier, canonicalize,
};
pub struct Ed25519SignatureVerifier<R: KeyRegistry> {
inner: Ed25519Verifier<R>,
}
impl<R: KeyRegistry> Ed25519SignatureVerifier<R> {
pub fn new(registry: R) -> Self {
Self {
inner: Ed25519Verifier::new(registry),
}
}
pub fn inner(&self) -> &Ed25519Verifier<R> {
&self.inner
}
}
impl<R: KeyRegistry> SignatureVerifier for Ed25519SignatureVerifier<R> {
fn verify_policy(&self, policy: &Policy) -> Result<(), SignatureVerificationError> {
let sig = policy
.signature
.as_ref()
.ok_or(SignatureVerificationError::Missing)?;
match sig {
PolicySignature::Ed25519 {
signer_key_id,
signature_hex,
} => {
let sig_bytes =
hex::decode(signature_hex).map_err(|_| SignatureVerificationError::Encoding)?;
let canonical = canonicalize(policy)
.map_err(|e| SignatureVerificationError::Invalid(e.to_string()))?;
self.inner
.verify(signer_key_id, &sig_bytes, &canonical)
.map_err(|e| SignatureVerificationError::Invalid(e.to_string()))
}
}
}
}
pub fn new_in_memory_verifier(
keys: Vec<(String, ed25519_dalek::VerifyingKey)>,
) -> Arc<Ed25519SignatureVerifier<InMemoryKeyRegistry>> {
let mut registry = InMemoryKeyRegistry::new();
for (id, key) in keys {
registry.insert(id, key);
}
Arc::new(Ed25519SignatureVerifier::new(registry))
}