co_didcomm/messages/jws.rs
1use crate::{
2 helpers::create_fallback_getter,
3 messages::helpers::{serialization_base64_buffer, serialization_base64_jwm_header},
4 Jwk,
5 JwmHeader,
6};
7
8/// Signature data for [JWS](https://datatracker.ietf.org/doc/html/rfc7515) envelopes.
9/// They can be used per recipient in [General JWS JSON](https://datatracker.ietf.org/doc/html/rfc7515#section-7.2.1),
10/// triggered by using [`.as_jws`][crate::Message::as_jws()] or as a single signature for the entire JWS in
11/// [Flattened JWS JSON](https://datatracker.ietf.org/doc/html/rfc7515#section-7.2.2), triggered by
12/// [`.as_flat_jws`][crate::Message::as_flat_jws()].
13#[derive(Serialize, Deserialize, Debug, Clone)]
14pub struct Signature {
15 /// integrity protected header elements
16 #[serde(default)]
17 #[serde(skip_serializing_if = "Option::is_none")]
18 #[serde(with = "serialization_base64_jwm_header")]
19 pub protected: Option<JwmHeader>,
20
21 /// header elements that are not integrity protected
22 #[serde(skip_serializing_if = "Option::is_none")]
23 pub header: Option<JwmHeader>,
24
25 /// signature computed over protected header elements
26 #[serde(default)]
27 #[serde(with = "serialization_base64_buffer")]
28 pub signature: Vec<u8>,
29}
30
31impl Signature {
32 /// Creates a new `Signature` that can be used in JWS `signatures` property or
33 /// as top-level (flattened) property in flattened JWS JSON serialization.
34 ///
35 /// # Arguments
36 ///
37 /// * `protected` - JWM header protected by signing
38 ///
39 /// * `header` - JWM header not protected by signing
40 ///
41 /// * `signature` - signature over JWS payload and protected header
42 pub fn new(
43 protected: Option<JwmHeader>,
44 header: Option<JwmHeader>,
45 signature: Vec<u8>,
46 ) -> Self {
47 Signature {
48 protected,
49 header,
50 signature,
51 }
52 }
53
54 create_fallback_getter!(header, protected, alg, String);
55
56 create_fallback_getter!(header, protected, cty, String);
57
58 create_fallback_getter!(header, protected, enc, String);
59
60 create_fallback_getter!(header, protected, epk, Jwk);
61
62 create_fallback_getter!(header, protected, jku, String);
63
64 create_fallback_getter!(header, protected, jwk, Jwk);
65
66 create_fallback_getter!(header, protected, kid, String);
67
68 create_fallback_getter!(header, protected, skid, String);
69}
70
71/// A struct to generate and serialize [JWS](https://datatracker.ietf.org/doc/html/rfc7515)
72/// envelopes for DIDComm messages.
73#[derive(Serialize, Deserialize, Debug)]
74pub struct Jws {
75 /// base64 encoded payload of the JWS
76 pub payload: String,
77
78 /// Top-level signature for flat JWS JSON messages.
79 /// Will be ignored if `signatures` is not `None`
80 #[serde(flatten)]
81 #[serde(skip_serializing_if = "Option::is_none")]
82 pub signature: Option<Signature>,
83
84 /// Pre-recipient signatures for flat JWS JSON messages.
85 /// If not `None`, will be preferred over `signature`.
86 #[serde(skip_serializing_if = "Option::is_none")]
87 pub signatures: Option<Vec<Signature>>,
88}
89
90impl Jws {
91 /// Creates a new [general JWS](https://datatracker.ietf.org/doc/html/rfc7515#section-7.2.1)
92 /// object with signature values per recipient.
93 ///
94 /// # Arguments
95 ///
96 /// * `payload` - payload with encoded data
97 ///
98 /// * `signatures` - signature values per recipient
99 pub fn new(payload: String, signatures: Vec<Signature>) -> Self {
100 Jws {
101 payload,
102 signature: None,
103 signatures: Some(signatures),
104 }
105 }
106
107 /// Creates a new [flattened JWS](https://datatracker.ietf.org/doc/html/rfc7515#section-7.2.2)
108 /// object with signature information on JWS' top level.
109 ///
110 /// # Arguments
111 ///
112 /// * `payload` - payload with encoded data
113 ///
114 /// * `signatures_value` - signature value that is used on JWS top-level
115 pub fn new_flat(payload: String, signature_value: Signature) -> Self {
116 Jws {
117 payload,
118 signature: Some(signature_value),
119 signatures: None,
120 }
121 }
122}