use crate::types::errors::{Error, ErrorKind};
use thiserror::Error;
#[derive(Debug, Error)]
pub enum AttestationError {
#[error("attestation signing failed: {msg}")]
Signing { msg: String },
#[error("attestation verification failed: {msg}")]
Verification { msg: String },
}
impl From<AttestationError> for Error {
fn from(e: AttestationError) -> Self {
Error {
kind: ErrorKind::Io, msg: e.to_string(),
}
}
}
#[derive(Clone, Debug)]
pub struct Signature(pub Vec<u8>);
pub trait Attestor: Send + Sync {
fn sign(&self, bundle: &[u8]) -> Result<Signature, AttestationError>;
fn key_id(&self) -> String;
fn algorithm(&self) -> &'static str {
"ed25519"
}
}
pub fn build_attestation_fields<A: Attestor + ?Sized>(
att: &A,
bundle: &[u8],
) -> Option<serde_json::Value> {
use base64::Engine as _;
use sha2::Digest as _;
let sig = att.sign(bundle).ok()?;
let sig_b64 = base64::engine::general_purpose::STANDARD.encode(sig.0.clone());
let mut hasher = sha2::Sha256::new();
hasher.update(bundle);
let bundle_hash = hex::encode(hasher.finalize());
Some(serde_json::json!({
"sig_alg": att.algorithm(),
"signature": sig_b64,
"bundle_hash": bundle_hash,
"public_key_id": att.key_id(),
}))
}