use crate::error::{Error, Result};
use crate::message::{Jwe, JweProtected, JwsProtected};
use async_trait::async_trait;
use serde_json::Value;
use std::fmt::Debug;
use std::sync::Arc;
#[async_trait]
pub trait AgentKey: Send + Sync + Debug {
fn key_id(&self) -> &str;
fn public_key_jwk(&self) -> Result<Value>;
fn did(&self) -> &str;
fn key_type(&self) -> &str;
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum JwsAlgorithm {
EdDSA,
ES256,
ES256K,
}
impl JwsAlgorithm {
pub fn as_str(&self) -> &'static str {
match self {
JwsAlgorithm::EdDSA => "EdDSA",
JwsAlgorithm::ES256 => "ES256",
JwsAlgorithm::ES256K => "ES256K",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum JweAlgorithm {
EcdhEsA256kw,
EcdhEs,
}
impl JweAlgorithm {
pub fn as_str(&self) -> &'static str {
match self {
JweAlgorithm::EcdhEsA256kw => "ECDH-ES+A256KW",
JweAlgorithm::EcdhEs => "ECDH-ES",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum JweEncryption {
A256GCM,
}
impl JweEncryption {
pub fn as_str(&self) -> &'static str {
match self {
JweEncryption::A256GCM => "A256GCM",
}
}
}
#[async_trait]
pub trait SigningKey: AgentKey {
async fn sign(&self, data: &[u8]) -> Result<Vec<u8>>;
fn recommended_jws_alg(&self) -> JwsAlgorithm;
async fn create_jws(
&self,
payload: &[u8],
protected_header: Option<JwsProtected>,
) -> Result<crate::message::Jws>;
}
#[async_trait]
pub trait VerificationKey: Send + Sync + Debug {
fn key_id(&self) -> &str;
fn public_key_jwk(&self) -> Result<Value>;
async fn verify_signature(
&self,
payload: &[u8],
signature: &[u8],
protected_header: &JwsProtected,
) -> Result<bool>;
}
#[async_trait]
pub trait EncryptionKey: AgentKey {
async fn encrypt(
&self,
plaintext: &[u8],
aad: Option<&[u8]>,
recipient_public_key: &dyn VerificationKey,
) -> Result<(Vec<u8>, Vec<u8>, Vec<u8>)>;
fn recommended_jwe_alg_enc(&self) -> (JweAlgorithm, JweEncryption);
async fn create_jwe(
&self,
plaintext: &[u8],
recipients: &[Arc<dyn VerificationKey>],
protected_header: Option<JweProtected>,
) -> Result<Jwe>;
}
#[async_trait]
pub trait DecryptionKey: AgentKey {
async fn decrypt(
&self,
ciphertext: &[u8],
encrypted_key: &[u8],
iv: &[u8],
tag: &[u8],
aad: Option<&[u8]>,
sender_key: Option<&dyn VerificationKey>,
) -> Result<Vec<u8>>;
async fn unwrap_jwe(&self, jwe: &Jwe) -> Result<Vec<u8>>;
}
#[derive(Debug, thiserror::Error)]
pub enum AgentKeyError {
#[error("Key operation failed: {0}")]
Operation(String),
#[error("Invalid key: {0}")]
InvalidKey(String),
#[error("Unsupported algorithm: {0}")]
UnsupportedAlgorithm(String),
#[error("Verification failed")]
VerificationFailed,
#[error("Decryption failed: {0}")]
DecryptionFailed(String),
#[error("Serialization error: {0}")]
Serialization(String),
#[error("Invalid format: {0}")]
InvalidFormat(String),
}
impl From<AgentKeyError> for Error {
fn from(err: AgentKeyError) -> Self {
Error::Cryptography(err.to_string())
}
}