use agent_mesh_protocol::CertChain;
use base64::{engine::general_purpose::STANDARD as B64, Engine as _};
use content_addressable::RawContentId;
use newt_core::Caveats;
pub struct VerifiedDelegation {
cert: CertChain,
}
impl VerifiedDelegation {
pub fn caveats(&self) -> &Caveats {
&self.cert.metadata.caveats
}
}
#[derive(Debug, thiserror::Error)]
pub enum DelegationError {
#[error("invalid delegated authority envelope")]
InvalidEnvelope,
#[error("invalid delegated authority certificate")]
InvalidCertificate,
#[error("delegated authority does not match the trusted launch anchor")]
UnexpectedEnvelope,
}
pub fn verify_delegation(
envelope: &[u8],
expected: &RawContentId,
) -> Result<VerifiedDelegation, DelegationError> {
if RawContentId::from_content(envelope) != *expected {
return Err(DelegationError::UnexpectedEnvelope);
}
let bytes = B64
.decode(envelope)
.map_err(|_| DelegationError::InvalidEnvelope)?;
let cert: CertChain =
serde_json::from_slice(&bytes).map_err(|_| DelegationError::InvalidEnvelope)?;
cert.verify()
.map_err(|_| DelegationError::InvalidCertificate)?;
Ok(VerifiedDelegation { cert })
}
#[cfg(test)]
#[path = "delegation_tests.rs"]
mod tests;