1#![allow(dead_code)]
2
3#[cfg(feature = "raw-crypto")]
4use crate::{
5 crypto::{CryptoAlgorithm, Cypher, SignatureAlgorithm, Signer},
6 helpers::{encrypt_cek, get_crypter_from_header, get_message_type, receive_jwe, receive_jws},
7 Jwe, Mediated,
8};
9use crate::{Attachment, DidCommHeader, Error, JwmHeader, MessageType, PriorClaims, Recipient};
10#[cfg(feature = "raw-crypto")]
11use base64_url::decode;
12#[cfg(all(feature = "resolve", feature = "raw-crypto"))]
13use ddoresolver_rs::*;
14#[cfg(feature = "raw-crypto")]
15use rand::{RngCore, SeedableRng};
16#[cfg(feature = "raw-crypto")]
17use rand_chacha::ChaCha20Rng;
18use serde::{Deserialize, Serialize};
19use serde_json::{json, Value};
20use crate::Result;
21
22#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
39pub struct Message {
40 #[serde(flatten)]
42 pub(crate) jwm_header: JwmHeader,
43
44 #[serde(flatten)]
46 pub(crate) didcomm_header: DidCommHeader,
47
48 #[serde(skip_serializing_if = "Option::is_none")]
50 pub(crate) recipients: Option<Vec<Recipient>>,
51
52 pub(crate) body: Value,
56
57 #[serde(skip)]
60 pub(crate) serialize_flat_jwe: bool,
61
62 #[serde(skip)]
65 pub(crate) serialize_flat_jws: bool,
66
67 #[serde(skip_serializing_if = "Vec::is_empty", default)]
68 pub(crate) attachments: Vec<Attachment>,
69}
70
71impl Message {
72 pub fn new() -> Self {
75 Message {
76 jwm_header: JwmHeader::default(),
77 didcomm_header: DidCommHeader::new(),
78 recipients: None,
79 body: json!({}),
80 attachments: Vec::new(),
81 serialize_flat_jwe: false,
82 serialize_flat_jws: false,
83 }
84 }
85
86 pub fn add_header_field(mut self, key: String, value: String) -> Self {
89 if key.is_empty() {
90 return self;
91 }
92 self.didcomm_header.other.insert(key, value);
93 self
94 }
95
96 #[cfg(feature = "raw-crypto")]
99 pub fn as_flat_jwe(
100 mut self,
101 alg: &CryptoAlgorithm,
102 recipient_public_key: Option<Vec<u8>>,
103 ) -> Self {
104 self.serialize_flat_jwe = true;
105 self.as_jwe(alg, recipient_public_key)
106 }
107
108 #[cfg(feature = "raw-crypto")]
111 pub fn as_flat_jws(mut self, alg: &SignatureAlgorithm) -> Self {
112 self.serialize_flat_jws = true;
113 self.as_jws(alg)
114 }
115
116 pub fn get_message_uri(&self) -> String {
119 self.didcomm_header.get_message_uri()
120 }
121
122 pub fn reply_to(mut self, replying_to: &Self) -> Self {
127 self.didcomm_header.reply_to(&replying_to.didcomm_header);
128 self
129 }
130
131 pub fn with_parent(mut self, parent: &Self) -> Self {
139 self.didcomm_header.pthid = Some(
140 if let Some(thid_ref) = parent.didcomm_header.thid.as_ref() {
141 thid_ref.clone()
142 } else {
143 parent.didcomm_header.id.clone()
144 },
145 );
146
147 self
148 }
149
150 #[cfg(feature = "raw-crypto")]
156 pub fn as_jwe(mut self, alg: &CryptoAlgorithm, recipient_public_key: Option<Vec<u8>>) -> Self {
157 self.jwm_header.as_encrypted(alg);
158 if let Some(key) = recipient_public_key {
159 self.jwm_header.kid = Some(base64_url::encode(&key));
160 } else {
161 #[cfg(feature = "resolve")]
162 {
163 if let Some(from) = &self.didcomm_header.from {
164 if let Some(document) = resolve_any(from) {
165 match alg {
166 CryptoAlgorithm::XC20P => {
167 self.jwm_header.kid =
168 document.find_public_key_id_for_curve("X25519")
169 }
170 CryptoAlgorithm::A256GCM | CryptoAlgorithm::A256CBC => {
171 self.jwm_header.kid = document.find_public_key_id_for_curve("P-256")
172 }
173 }
174 }
175 }
176 }
177 }
178 self
179 }
180
181 #[cfg(feature = "raw-crypto")]
186 pub fn as_jws(mut self, alg: &SignatureAlgorithm) -> Self {
187 self.jwm_header.as_signed(alg);
188 self
189 }
190
191 pub fn body(mut self, body: &str) -> Result<Self> {
194 self.body = serde_json::from_str(body)?;
195 Ok(self)
196 }
197
198 pub fn didcomm_header(mut self, h: DidCommHeader) -> Self {
202 self.didcomm_header = h;
203 self
204 }
205
206 pub fn from(mut self, from: &str) -> Self {
208 self.didcomm_header.from = Some(String::from(from));
209 self
210 }
211
212 pub fn get_body(&self) -> Result<String> {
214 Ok(serde_json::to_string(&self.body)?)
215 }
216
217 pub fn get_didcomm_header(&self) -> &DidCommHeader {
219 &self.didcomm_header
220 }
221
222 pub fn get_jwm_header(&self) -> &JwmHeader {
224 &self.jwm_header
225 }
226
227 pub fn get_prior(&self) -> Result<PriorClaims> {
230 if self.is_rotation() {
231 Ok(self
232 .didcomm_header
233 .from_prior()
234 .ok_or(Error::NoRotationData)?
235 .clone())
236 } else {
237 Err(Error::NoRotationData)
238 }
239 }
240
241 pub fn is_rotation(&self) -> bool {
244 self.didcomm_header.from_prior().is_some()
245 }
246
247 pub fn jwm_header(mut self, h: JwmHeader) -> Self {
251 self.jwm_header = h;
252 self
253 }
254
255 pub fn m_type(mut self, m_type: &str) -> Self {
257 self.didcomm_header.m_type = m_type.into();
258 self
259 }
260
261 pub fn typ(mut self, typ: MessageType) -> Self {
267 self.jwm_header.typ = typ;
268 self
269 }
270
271 pub fn kid(mut self, kid: &str) -> Self {
273 match &mut self.jwm_header.kid {
274 Some(h) => *h = kid.into(),
275 None => {
276 self.jwm_header.kid = Some(kid.into());
277 }
278 }
279 self
280 }
281
282 pub fn timed(mut self, expires: Option<u64>) -> Self {
289 self.didcomm_header.expires_time = expires;
290 self.didcomm_header.created_time = crate::helpers::now_epoch_secs();
291 self
292 }
293
294 pub fn to(mut self, to: &[&str]) -> Self {
296 for s in to {
297 self.didcomm_header.to.push(s.to_string());
298 }
299 while let Some(a) = self
300 .didcomm_header
301 .to
302 .iter()
303 .position(|e| e == &String::default())
304 {
305 self.didcomm_header.to.remove(a);
306 }
307 self
308 }
309
310 pub fn set_didcomm_header(mut self, h: DidCommHeader) -> Self {
314 self.didcomm_header = h;
315 self
316 }
317
318 pub fn get_application_params(&self) -> impl Iterator<Item = (&String, &String)> {
320 self.didcomm_header.other.iter()
321 }
322
323 pub fn thid(mut self, thid: &str) -> Self {
325 self.didcomm_header.thid = Some(thid.to_string());
326 self
327 }
328
329 pub fn pthid(mut self, pthid: &str) -> Self {
331 self.didcomm_header.pthid = Some(pthid.to_string());
332 self
333 }
334}
335
336#[cfg(feature = "raw-crypto")]
338impl Message {
339 pub fn as_raw_json(self) -> Result<String> {
342 Ok(serde_json::to_string(&self)?)
343 }
344
345 pub fn export_for_encryption(&self) -> Result<(Vec<u8>, Vec<u8>)> {
351 Ok((
352 decode(&Jwe::generate_iv())?,
353 serde_json::to_string(&self)?.as_bytes().to_vec(),
354 ))
355 }
356
357 pub fn seal_pre_encrypted(self, cyphertext: impl AsRef<[u8]>) -> Result<String> {
367 let d_header = self.get_didcomm_header();
368
369 let mut unprotected = JwmHeader {
370 skid: d_header.from.clone(),
371 ..Default::default()
372 };
373
374 if self.recipients.is_none() {
375 unprotected.kid = Some(d_header.to[0].clone());
376 }
377
378 let jwe = Jwe::new(
379 Some(unprotected),
380 self.recipients.clone(),
381 cyphertext,
382 Some(self.jwm_header.clone()),
383 None::<&[u8]>,
384 None,
385 );
386
387 Ok(serde_json::to_string(&jwe)?)
388 }
389
390 pub fn receive(
403 incoming: &str,
404 encryption_recipient_private_key: Option<&[u8]>,
405 encryption_sender_public_key: Option<Vec<u8>>,
406 signing_sender_public_key: Option<&[u8]>,
407 ) -> Result<Self> {
408 let mut current_message: String = incoming.to_string();
409
410 if get_message_type(¤t_message)? == MessageType::DidCommJwe {
411 let recipient_private_key = encryption_recipient_private_key.ok_or_else(|| {
412 Error::Generic("missing encryption recipient private key".to_string())
413 })?;
414 current_message = receive_jwe(
415 ¤t_message,
416 recipient_private_key,
417 encryption_sender_public_key,
418 )?;
419 }
420
421 if get_message_type(¤t_message)? == MessageType::DidCommJws {
422 current_message = receive_jws(¤t_message, signing_sender_public_key)?;
423 }
424
425 Ok(serde_json::from_str(¤t_message)?)
426 }
427
428 pub fn routed_by(
447 self,
448 sender_private_key: &[u8],
449 recipient_public_keys: Option<Vec<Option<Vec<u8>>>>,
450 mediator_did: &str,
451 mediator_public_key: Option<Vec<u8>>,
452 ) -> Result<String> {
453 let from = &self.didcomm_header.from.clone().unwrap_or_default();
454 let alg = get_crypter_from_header(&self.jwm_header)?;
455 let body = Mediated::new(self.didcomm_header.to[0].clone()).with_payload(
456 self.seal(sender_private_key, recipient_public_keys)?
457 .as_bytes()
458 .to_vec(),
459 );
460 Message::new()
461 .to(&[mediator_did])
462 .from(from)
463 .as_jwe(&alg, mediator_public_key.clone())
464 .typ(MessageType::DidCommForward)
465 .body(&serde_json::to_string(&body)?)?
466 .seal(sender_private_key, Some(vec![mediator_public_key]))
467 }
468
469 pub fn seal(
478 mut self,
479 sender_private_key: impl AsRef<[u8]>,
480 recipient_public_keys: Option<Vec<Option<Vec<u8>>>>,
481 ) -> Result<String> {
482 if sender_private_key.as_ref().len() != 32 {
483 return Err(Error::InvalidKeySize("!32".into()));
484 }
485 let to_len = self.didcomm_header.to.len();
486 let public_keys = if let Some(recipient_public_keys_value) = recipient_public_keys {
487 if recipient_public_keys_value.len() != to_len {
488 return Err(Error::Generic(
489 "`to` and `recipient_public_keys` must have same length".to_string(),
490 ));
491 }
492 recipient_public_keys_value
493 } else {
494 vec![None; to_len]
495 };
496
497 let mut cek = [0u8; 32];
499 let mut rng = ChaCha20Rng::from_seed(Default::default());
500 rng.fill_bytes(&mut cek);
501 trace!("sealing message with shared_key: {:?}", &cek.as_ref());
502
503 if to_len == 0_usize {
504 return Err(Error::NoJweRecipient);
505 } else if self.serialize_flat_jwe && self.didcomm_header.to.len() > 1 {
506 return Err(Error::Generic(
507 "flat JWE serialization only supports a single `to`".to_string(),
508 ));
509 }
510
511 let mut recipients: Vec<Recipient> = vec![];
512 for (i, public_key) in public_keys.iter().enumerate().take(to_len) {
514 let rv = encrypt_cek(
515 &self,
516 sender_private_key.as_ref(),
517 &self.didcomm_header.to[i],
518 &cek,
519 public_key.to_owned(),
520 )?;
521 recipients.push(Recipient::new(rv.header, rv.encrypted_key));
522 }
523 self.recipients = Some(recipients);
524 let alg = get_crypter_from_header(&self.jwm_header)?;
526 self.encrypt(alg.encryptor(), cek.as_ref())
527 }
528}
529
530impl Message {
533 pub fn get_iv(received: &[u8]) -> Result<Vec<u8>> {
538 let as_str = String::from_utf8(received.to_vec())?;
540 let json: serde_json::Value = if let Some(header_end) = as_str.find('.') {
541 serde_json::from_str(&String::from_utf8(base64_url::decode(
542 &as_str[..header_end],
543 )?)?)?
544 } else {
545 serde_json::from_str(&as_str)?
546 };
547 if let Some(iv) = json.get("iv") {
548 if let Some(t) = iv.as_str() {
549 if t.len() != 24 {
550 Err(Error::Generic(format!(
551 "IV [nonce] size is incorrect: {}",
552 t.len()
553 )))
554 } else {
555 Ok(t.as_bytes().to_vec())
556 }
557 } else {
558 Err(Error::Generic("wrong nonce format".into()))
559 }
560 } else {
561 Err(Error::Generic("iv is not found in JOSE header".into()))
562 }
563 }
564
565 #[cfg(feature = "raw-crypto")]
576 pub fn received_as_jwe(incomming: impl AsRef<[u8]>) -> Option<Jwe> {
577 if let Ok(jwe) = serde_json::from_slice::<Jwe>(incomming.as_ref()) {
578 if jwe.get_skid().is_some() {
579 Some(jwe)
580 } else {
581 None
582 }
583 } else {
584 None
585 }
586 }
587 pub fn receive_external_crypto(decrypted: impl AsRef<[u8]>) -> Result<Self> {
595 Ok(serde_json::from_slice(decrypted.as_ref())?)
596 }
597
598 #[cfg(feature = "raw-crypto")]
613 pub fn seal_signed(
614 self,
615 encryption_sender_private_key: &[u8],
616 encryption_recipient_public_keys: Option<Vec<Option<Vec<u8>>>>,
617 signing_algorithm: SignatureAlgorithm,
618 signing_sender_private_key: &[u8],
619 ) -> Result<String> {
620 let mut to = self.clone();
621 let signed = self
622 .as_jws(&signing_algorithm)
623 .sign(signing_algorithm.signer(), signing_sender_private_key)?;
624 to.body = serde_json::from_str(&signed)?;
625 to.typ(MessageType::DidCommJws).seal(
626 encryption_sender_private_key,
627 encryption_recipient_public_keys,
628 )
629 }
630}
631
632impl Default for Message {
633 fn default() -> Self {
634 Self::new()
635 }
636}
637
638#[cfg(test)]
639mod parse_tests {
640 use super::*;
641
642 #[test]
643 fn iv_from_json_test() {
644 let raw_json = r#" { "protected": "eyJ0eXAiOiJKV00iLCJlbmMiOiJBMjU2R0NNIiwia2lkIjoiUEdvWHpzME5XYVJfbWVLZ1RaTGJFdURvU1ZUYUZ1eXJiV0k3VjlkcGpDZyIsImFsZyI6IkVDREgtRVMrQTI1NktXIiwiZXBrIjp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoiLU5oN1NoUkJfeGFDQlpSZElpVkN1bDNTb1IwWXc0VEdFUXFxR2lqMXZKcyIsInkiOiI5dEx4ODFQTWZRa3JPdzh5dUkyWXdJMG83TXROemFDR2ZDQmJaQlc1WXJNIn19",
648 "recipients": [
649 {
650 "encrypted_key": "J1Fs9JaDjOT_5481ORQWfEZmHy7OjE3pTNKccnK7hlqjxbPalQWWLg"
651 }
652 ],
653 "iv": "u5kIzo0m_d2PjI4mu5kIzo0m",
654 "ciphertext": "qGuFFoHy7HBmkf2BaY6eREwzEjn6O_FnRoXj2H-DAXo1PgQdfON-_1QbxtnT8e8z_M6Gown7s8fLtYNmIHAuixqFQnSA4fdMcMSi02z1MYEn2JC-1EkVbWr4TqQgFP1EyymB6XjCWDiwTYd2xpKoUshu8WW601HLSgFIRUG3-cK_ZSdFaoWosIgAH5EQ2ayJkRB_7dXuo9Bi1MK6TYGZKezc6rpCK_VRSnLXhFwa1C3T0QBes",
655 "tag": "doeAoagwJe9BwKayfcduiw"
656 }"#;
657 let iv = Message::get_iv(raw_json.as_bytes());
659 assert!(iv.is_ok());
661 assert_eq!(
662 "u5kIzo0m_d2PjI4mu5kIzo0m",
663 &String::from_utf8(iv.unwrap()).unwrap()
664 );
665 }
666
667 #[test]
668 fn iv_from_compact_json_test() {
669 let compact = r#"eyJ0eXAiOiJKV00iLCJlbmMiOiJBMjU2R0NNIiwia2lkIjoiUEdvWHpzME5XYVJfbWVLZ1RaTGJFdURvU1ZUYUZ1eXJiV0k3VjlkcGpDZyIsImFsZyI6IkVDREgtRVMrQTI1NktXIiwiaXYiOiAidTVrSXpvMG1fZDJQakk0bXU1a0l6bzBtIn0."#;
672 let iv = Message::get_iv(compact.as_bytes());
674 assert!(iv.is_ok());
676 assert_eq!(
677 "u5kIzo0m_d2PjI4mu5kIzo0m",
678 &String::from_utf8(iv.unwrap()).unwrap()
679 );
680 }
681}
682
683#[cfg(all(test, feature = "raw-crypto"))]
684mod crypto_tests {
685 extern crate chacha20poly1305;
686 extern crate sodiumoxide;
687
688 #[cfg(feature = "resolve")]
689 use base58::FromBase58;
690 use rand_core::OsRng;
691 use utilities::{get_keypair_set, KeyPairSet};
692
693 use super::*;
694 #[cfg(feature = "resolve")]
695 use crate::{Jwe, Mediated};
696
697 #[test]
698 #[cfg(not(feature = "resolve"))]
699 fn create_and_send() {
700 let KeyPairSet {
701 alice_private,
702 bobs_public,
703 ..
704 } = get_keypair_set();
705 let m = Message::new().as_jwe(&CryptoAlgorithm::XC20P, Some(bobs_public.to_vec()));
706 let p = m.seal(&alice_private, Some(vec![Some(bobs_public.to_vec())]));
707 assert!(p.is_ok());
708 }
709
710 #[test]
711 #[cfg(feature = "resolve")]
712 fn create_and_send() {
713 let KeyPairSet { alice_private, .. } = get_keypair_set();
714 let m = Message::new()
715 .from("did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp")
716 .to(&["did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG"])
717 .as_jwe(&CryptoAlgorithm::XC20P, None);
718 let p = m.seal(&alice_private, None);
719 assert!(p.is_ok());
720 }
721
722 #[test]
723 fn create_and_send_without_resolving_dids() {
724 let KeyPairSet {
725 alice_private,
726 bobs_public,
727 ..
728 } = get_keypair_set();
729 let m = Message::new().as_jwe(&CryptoAlgorithm::XC20P, Some(bobs_public.to_vec()));
730 let p = m.seal(&alice_private, Some(vec![Some(bobs_public.to_vec())]));
731 assert!(p.is_ok());
732 }
733
734 #[test]
735 #[cfg(feature = "resolve")]
736 fn receive_test() {
737 let KeyPairSet {
739 alice_public,
740 alice_private,
741 bobs_private,
742 ..
743 } = get_keypair_set();
744 let m = Message::new()
746 .from("did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp")
747 .to(&["did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG"])
748 .as_jwe(&CryptoAlgorithm::XC20P, None);
749 let jwe = m.seal(&alice_private, None).unwrap();
750
751 let received =
754 Message::receive(&jwe, Some(&bobs_private), Some(alice_public.to_vec()), None);
755
756 assert!(received.is_ok());
758 }
759
760 #[test]
761 fn receive_test_without_resolving_dids() {
762 let KeyPairSet {
764 alice_public,
765 alice_private,
766 bobs_private,
767 bobs_public,
768 ..
769 } = get_keypair_set();
770 let m = Message::new()
772 .from("did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp")
773 .to(&["did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG"])
774 .as_jwe(&CryptoAlgorithm::XC20P, Some(bobs_public.to_vec()));
775 let jwe = m
776 .seal(&alice_private, Some(vec![Some(bobs_public.to_vec())]))
777 .unwrap();
778
779 let received =
782 Message::receive(&jwe, Some(&bobs_private), Some(alice_public.to_vec()), None);
783
784 assert!(received.is_ok());
786 }
787
788 #[test]
789 #[cfg(feature = "resolve")]
790 fn send_receive_didkey_test() {
791 let m = Message::new()
792 .from("did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp")
793 .to(&["did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG"])
794 .as_jwe(&CryptoAlgorithm::XC20P, None);
795 let KeyPairSet {
797 alice_private,
798 bobs_private,
799 ..
800 } = get_keypair_set();
801 let jwe = m.seal(&alice_private, None);
802 assert!(jwe.is_ok());
803
804 let received = Message::receive(&jwe.unwrap(), Some(&bobs_private), None, None);
805 assert!(received.is_ok());
806 }
807
808 #[test]
809 fn send_receive_didkey_explicit_pubkey_test() {
810 let KeyPairSet {
811 alice_public,
812 alice_private,
813 bobs_private,
814 bobs_public,
815 ..
816 } = get_keypair_set();
817 let m = Message::new()
818 .from("did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp")
819 .to(&["did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG"])
820 .as_jwe(&CryptoAlgorithm::XC20P, Some(bobs_public.to_vec()));
821
822 let jwe = m.seal(&alice_private, Some(vec![Some(bobs_public.to_vec())]));
823 assert!(jwe.is_ok());
824
825 let received = Message::receive(
826 &jwe.unwrap(),
827 Some(&bobs_private),
828 Some(alice_public.to_vec()),
829 None,
830 );
831 assert!(received.is_ok());
832 }
833
834 #[test]
835 #[cfg(feature = "resolve")]
836 fn send_receive_didkey_test_1pu_aes256() {
837 let m = Message::new()
838 .from("did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp")
839 .to(&["did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG"])
840 .as_jwe(&CryptoAlgorithm::A256GCM, None);
841 let KeyPairSet {
843 alice_private,
844 bobs_private,
845 ..
846 } = get_keypair_set();
847 let jwe = m.seal(&alice_private, None);
848 assert!(jwe.is_ok());
849
850 let received = Message::receive(&jwe.unwrap(), Some(&bobs_private), None, None);
851 assert!(received.is_ok());
852 }
853
854 #[test]
855 #[cfg(feature = "resolve")]
856 fn send_receive_didkey_test_1pu_aes256_explicit_pubkey() {
857 let m = Message::new()
858 .from("did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp")
859 .to(&["did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG"])
860 .as_jwe(&CryptoAlgorithm::A256GCM, None);
861 let KeyPairSet {
863 alice_private,
864 bobs_private,
865 ..
866 } = get_keypair_set();
867 let jwe = m.seal(&alice_private, None);
868 assert!(jwe.is_ok());
869
870 let KeyPairSet { alice_public, .. } = get_keypair_set();
871
872 let received = Message::receive(
873 &jwe.unwrap(),
874 Some(&bobs_private),
875 Some(alice_public.to_vec()),
876 None,
877 );
878 assert!(received.is_ok());
879 }
880
881 #[test]
882 #[cfg(feature = "resolve")]
883 fn send_receive_didkey_multiple_recipients_test() {
884 let m = Message::new()
885 .from("did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp")
886 .to(&[
887 "did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG",
888 "did:key:z6MknGc3ocHs3zdPiJbnaaqDi58NGb4pk1Sp9WxWufuXSdxf",
889 ])
890 .as_jwe(&CryptoAlgorithm::XC20P, None);
891 let KeyPairSet {
892 alice_private,
893 bobs_private,
894 ..
895 } = get_keypair_set();
896 let third_private = "ACa4PPJ1LnPNq1iwS33V3Akh7WtnC71WkKFZ9ccM6sX2"
897 .from_base58()
898 .unwrap();
899 let jwe = m.seal(&alice_private, None);
900 assert!(jwe.is_ok());
901
902 let jwe = jwe.unwrap();
903 let received_bob = Message::receive(&jwe, Some(&bobs_private), None, None);
904 let received_third = Message::receive(&jwe, Some(&third_private), None, None);
905 assert!(received_bob.is_ok());
906 assert!(received_third.is_ok());
907 }
908
909 #[test]
910 #[cfg(feature = "resolve")]
911 fn mediated_didkey_test() {
912 let mediator_private = "ACa4PPJ1LnPNq1iwS33V3Akh7WtnC71WkKFZ9ccM6sX2"
913 .from_base58()
914 .unwrap();
915 let KeyPairSet {
916 alice_private,
917 bobs_private,
918 ..
919 } = get_keypair_set();
920 let sealed = Message::new()
921 .from("did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp")
922 .to(&["did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG"])
923 .as_jwe(&CryptoAlgorithm::XC20P, None)
924 .routed_by(
925 &alice_private,
926 None,
927 "did:key:z6MknGc3ocHs3zdPiJbnaaqDi58NGb4pk1Sp9WxWufuXSdxf",
928 None,
929 );
930 assert!(sealed.is_ok());
931
932 let mediator_received =
933 Message::receive(&sealed.unwrap(), Some(&mediator_private), None, None);
934 assert!(mediator_received.is_ok());
935
936 let mediator_received_unwrapped = mediator_received.unwrap().get_body().unwrap();
937 let pl_string = String::from_utf8_lossy(mediator_received_unwrapped.as_ref());
938 let message_to_forward: Mediated = serde_json::from_str(&pl_string).unwrap();
939 let attached_jwe = serde_json::from_slice::<Jwe>(&message_to_forward.payload);
940 assert!(attached_jwe.is_ok());
941 let str_jwe = serde_json::to_string(&attached_jwe.unwrap());
942 assert!(str_jwe.is_ok());
943
944 let bob_received = Message::receive(
945 &String::from_utf8_lossy(&message_to_forward.payload),
946 Some(&bobs_private),
947 None,
948 None,
949 );
950 assert!(bob_received.is_ok());
951 }
952
953 #[test]
954 fn can_pass_explicit_signing_verification_keys() -> Result<()> {
955 let KeyPairSet {
956 alice_private,
957 alice_public,
958 bobs_private,
959 bobs_public,
960 ..
961 } = get_keypair_set();
962 let sign_keypair = ed25519_dalek::SigningKey::generate(&mut OsRng);
963 let body = r#"{"foo":"bar"}"#;
964 let message = Message::new()
965 .from("did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp")
966 .to(&["did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG"])
967 .body(body)? .as_flat_jwe(&CryptoAlgorithm::XC20P, Some(bobs_public.to_vec()))
969 .kid(&hex::encode(vec![1; 32])); let jwe_string = message.seal_signed(
972 &alice_private,
973 Some(vec![Some(bobs_public.to_vec())]),
974 SignatureAlgorithm::EdDsa,
975 &sign_keypair.to_bytes(),
976 )?;
977
978 let received_failure_no_key = Message::receive(
979 &jwe_string,
980 Some(&bobs_private),
981 Some(alice_public.to_vec()),
982 None,
983 );
984 let received_failure_wrong_key = Message::receive(
985 &jwe_string,
986 Some(&bobs_private),
987 Some(alice_public.to_vec()),
988 Some(&[0; 32]),
989 );
990 let received_success = Message::receive(
991 &jwe_string,
992 Some(&bobs_private),
993 Some(alice_public.to_vec()),
994 Some(&sign_keypair.verifying_key().to_bytes()),
995 );
996
997 assert!(&received_failure_no_key.is_err());
999 assert!(&received_failure_wrong_key.is_err());
1000 assert!(&received_success.is_ok());
1001 let received = received_success.unwrap();
1002 let sample_body: Value = serde_json::from_str(body).unwrap();
1003 let received_body: Value = serde_json::from_str(&received.get_body().unwrap()).unwrap();
1004 assert_eq!(sample_body.to_string(), received_body.to_string(),);
1005
1006 Ok(())
1007 }
1008}