@@ -2,13 +2,110 @@ use std::collections::HashMap;
22use std:: result;
33
44use base64:: { engine:: general_purpose:: STANDARD , Engine } ;
5- use serde:: { Deserialize , Serialize } ;
5+ use serde:: { Deserialize , Deserializer , Serialize , Serializer } ;
66
77use crate :: algorithms:: Algorithm ;
88use crate :: errors:: Result ;
99use crate :: jwk:: Jwk ;
1010use crate :: serialization:: b64_decode;
1111
12+ const ZIP_SERIAL_DEFLATE : & str = "DEF" ;
13+ const ENC_A128CBC_HS256 : & str = "A128CBC-HS256" ;
14+ const ENC_A192CBC_HS384 : & str = "A192CBC-HS384" ;
15+ const ENC_A256CBC_HS512 : & str = "A256CBC-HS512" ;
16+ const ENC_A128GCM : & str = "A128GCM" ;
17+ const ENC_A192GCM : & str = "A192GCM" ;
18+ const ENC_A256GCM : & str = "A256GCM" ;
19+
20+ /// Encryption algorithm for encrypted payloads.
21+ ///
22+ /// Defined in [RFC7516#4.1.2](https://datatracker.ietf.org/doc/html/rfc7516#section-4.1.2).
23+ ///
24+ /// Values defined in [RFC7518#5.1](https://datatracker.ietf.org/doc/html/rfc7518#section-5.1).
25+ #[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
26+ #[ allow( clippy:: upper_case_acronyms, non_camel_case_types) ]
27+ pub enum Enc {
28+ A128CBC_HS256 ,
29+ A192CBC_HS384 ,
30+ A256CBC_HS512 ,
31+ A128GCM ,
32+ A192GCM ,
33+ A256GCM ,
34+ Other ( String ) ,
35+ }
36+
37+ impl Serialize for Enc {
38+ fn serialize < S > ( & self , serializer : S ) -> std:: result:: Result < S :: Ok , S :: Error >
39+ where
40+ S : Serializer ,
41+ {
42+ match self {
43+ Enc :: A128CBC_HS256 => ENC_A128CBC_HS256 ,
44+ Enc :: A192CBC_HS384 => ENC_A192CBC_HS384 ,
45+ Enc :: A256CBC_HS512 => ENC_A256CBC_HS512 ,
46+ Enc :: A128GCM => ENC_A128GCM ,
47+ Enc :: A192GCM => ENC_A192GCM ,
48+ Enc :: A256GCM => ENC_A256GCM ,
49+ Enc :: Other ( v) => v,
50+ }
51+ . serialize ( serializer)
52+ }
53+ }
54+
55+ impl < ' de > Deserialize < ' de > for Enc {
56+ fn deserialize < D > ( deserializer : D ) -> std:: result:: Result < Self , D :: Error >
57+ where
58+ D : Deserializer < ' de > ,
59+ {
60+ let s = String :: deserialize ( deserializer) ?;
61+ match s. as_str ( ) {
62+ ENC_A128CBC_HS256 => return Ok ( Enc :: A128CBC_HS256 ) ,
63+ ENC_A192CBC_HS384 => return Ok ( Enc :: A192CBC_HS384 ) ,
64+ ENC_A256CBC_HS512 => return Ok ( Enc :: A256CBC_HS512 ) ,
65+ ENC_A128GCM => return Ok ( Enc :: A128GCM ) ,
66+ ENC_A192GCM => return Ok ( Enc :: A192GCM ) ,
67+ ENC_A256GCM => return Ok ( Enc :: A256GCM ) ,
68+ _ => ( ) ,
69+ }
70+ Ok ( Enc :: Other ( s) )
71+ }
72+ }
73+
74+ /// Compression applied to plaintext.
75+ ///
76+ /// Defined in [RFC7516#4.1.3](https://datatracker.ietf.org/doc/html/rfc7516#section-4.1.3).
77+ #[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
78+ pub enum Zip {
79+ Deflate ,
80+ Other ( String ) ,
81+ }
82+
83+ impl Serialize for Zip {
84+ fn serialize < S > ( & self , serializer : S ) -> std:: result:: Result < S :: Ok , S :: Error >
85+ where
86+ S : Serializer ,
87+ {
88+ match self {
89+ Zip :: Deflate => ZIP_SERIAL_DEFLATE ,
90+ Zip :: Other ( v) => v,
91+ }
92+ . serialize ( serializer)
93+ }
94+ }
95+
96+ impl < ' de > Deserialize < ' de > for Zip {
97+ fn deserialize < D > ( deserializer : D ) -> std:: result:: Result < Self , D :: Error >
98+ where
99+ D : Deserializer < ' de > ,
100+ {
101+ let s = String :: deserialize ( deserializer) ?;
102+ match s. as_str ( ) {
103+ ZIP_SERIAL_DEFLATE => Ok ( Zip :: Deflate ) ,
104+ _ => Ok ( Zip :: Other ( s) ) ,
105+ }
106+ }
107+ }
108+
12109/// A basic JWT header, the alg defaults to HS256 and typ is automatically
13110/// set to `JWT`. All the other fields are optional.
14111#[ derive( Debug , Clone , PartialEq , Eq , Serialize , Deserialize ) ]
@@ -65,7 +162,27 @@ pub struct Header {
65162 #[ serde( skip_serializing_if = "Option::is_none" ) ]
66163 #[ serde( rename = "x5t#S256" ) ]
67164 pub x5t_s256 : Option < String > ,
68-
165+ /// Critical - indicates header fields that must be understood by the receiver.
166+ ///
167+ /// Defined in [RFC7515#4.1.6](https://tools.ietf.org/html/rfc7515#section-4.1.6).
168+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
169+ pub crit : Option < Vec < String > > ,
170+ /// See `Enc` for description.
171+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
172+ pub enc : Option < Enc > ,
173+ /// See `Zip` for description.
174+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
175+ pub zip : Option < Zip > ,
176+ /// ACME: The URL to which this JWS object is directed
177+ ///
178+ /// Defined in [RFC8555#6.4](https://datatracker.ietf.org/doc/html/rfc8555#section-6.4).
179+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
180+ pub url : Option < String > ,
181+ /// ACME: Random data for preventing replay attacks.
182+ ///
183+ /// Defined in [RFC8555#6.5.2](https://datatracker.ietf.org/doc/html/rfc8555#section-6.5.2).
184+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
185+ pub nonce : Option < String > ,
69186 /// Any additional non-standard headers not defined in [RFC7515#4.1](https://datatracker.ietf.org/doc/html/rfc7515#section-4.1).
70187 /// Once serialized, all keys will be converted to fields at the root level of the header payload
71188 /// Ex: Dict("custom" -> "header") will be converted to "{"typ": "JWT", ..., "custom": "header"}"
@@ -87,6 +204,11 @@ impl Header {
87204 x5c : None ,
88205 x5t : None ,
89206 x5t_s256 : None ,
207+ crit : None ,
208+ enc : None ,
209+ zip : None ,
210+ url : None ,
211+ nonce : None ,
90212 extras : Default :: default ( ) ,
91213 }
92214 }
0 commit comments