use super::into_didcomm_rs_header::{from_didcomm_rs_header, into_didcomm_rs_header};
use crate::{DidCommHeader, DidKeyIdentity, Identity, ReceiveError, SignError};
use co_primitives::Secret;
use didcomm_rs::{
crypto::{CryptoAlgorithm, SignatureAlgorithm},
Jwe, Message,
};
pub fn didcomm_anoncrypt(
from_private_key: Secret,
to_public_key: Vec<u8>,
header: DidCommHeader,
body: Option<&str>,
) -> Result<String, SignError> {
let mut message = Message::new().didcomm_header(into_didcomm_rs_header(header));
if let Some(body) = body {
message = message.body(body).map_err(|e| SignError::Other(e.into()))?;
}
let signer = DidKeyIdentity::generate(None);
let result = message
.from(signer.identity())
.as_jwe(&CryptoAlgorithm::XC20P, Some(to_public_key.clone()))
.kid(&hex::encode(signer.public_key_bytes()))
.seal_signed(
from_private_key.divulge(),
Some(vec![Some(signer.public_key_bytes())]),
SignatureAlgorithm::EdDsa,
signer.private_key_bytes().divulge(),
)
.map_err(|e| SignError::Other(e.into()))?;
Ok(result)
}
pub fn didcomm_anoncrypt_receive(
to_private_key: Secret,
incoming: &str,
) -> Result<(DidCommHeader, Option<String>), ReceiveError> {
let jwe: Jwe = serde_json::from_str(&incoming).map_err(|e| ReceiveError::UnknownFormat(e.into()))?;
let skid = jwe.get_skid().ok_or_else(|| ReceiveError::MissingSigningKeyId)?;
let sign_identity = DidKeyIdentity::from_identity(&skid).map_err(|e| ReceiveError::InvalidSigningKeyId(e))?;
let message =
Message::receive(incoming, Some(to_private_key.divulge()), Some(sign_identity.public_key_bytes()), None)
.map_err(|e| ReceiveError::Decrypt(e.into()))?;
Ok((from_didcomm_rs_header(message.get_didcomm_header().clone()), message.get_body().ok()))
}
#[cfg(test)]
mod tests {
use super::{didcomm_jwe, didcomm_jwe_receive};
use crate::{DidCommHeader, DidKeyIdentity, Identity};
#[test]
fn smoke() {
let from = DidKeyIdentity::generate(Some(&vec![1; 32]));
let to = DidKeyIdentity::generate(Some(&vec![2; 32]));
let other = DidKeyIdentity::generate(Some(&vec![3; 32]));
println!("from: {}", from.identity());
println!("to: {}", to.identity());
let header = DidCommHeader {
id: "test".to_owned(),
from: Some(from.identity().to_owned()),
to: vec![to.identity().to_owned()].into_iter().collect(),
message_type: "hello".to_owned(),
..Default::default()
};
let message = didcomm_jwe(from.private_key_bytes(), to.public_key_bytes(), header, None).unwrap();
println!("message({}): {}", message.len(), message);
let (receviced_header, receviced_body) = didcomm_jwe_receive(to.private_key_bytes(), &message).unwrap();
assert_eq!(None, receviced_body);
assert_eq!("test", receviced_header.id);
let received_other = didcomm_jwe_receive(other.private_key_bytes(), &message);
assert!(received_other.is_err());
}
}