jsonwebtoken/header.rs
1use std::result;
2
3use base64::{engine::general_purpose::STANDARD, Engine};
4use serde::{Deserialize, Serialize};
5
6use crate::algorithms::Algorithm;
7use crate::errors::Result;
8use crate::jwk::Jwk;
9use crate::serialization::b64_decode;
10
11/// A basic JWT header, the alg defaults to HS256 and typ is automatically
12/// set to `JWT`. All the other fields are optional.
13#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
14pub struct Header {
15 /// The type of JWS: it can only be "JWT" here
16 ///
17 /// Defined in [RFC7515#4.1.9](https://tools.ietf.org/html/rfc7515#section-4.1.9).
18 #[serde(skip_serializing_if = "Option::is_none")]
19 pub typ: Option<String>,
20 /// The algorithm used
21 ///
22 /// Defined in [RFC7515#4.1.1](https://tools.ietf.org/html/rfc7515#section-4.1.1).
23 pub alg: Algorithm,
24 /// Content type
25 ///
26 /// Defined in [RFC7519#5.2](https://tools.ietf.org/html/rfc7519#section-5.2).
27 #[serde(skip_serializing_if = "Option::is_none")]
28 pub cty: Option<String>,
29 /// JSON Key URL
30 ///
31 /// Defined in [RFC7515#4.1.2](https://tools.ietf.org/html/rfc7515#section-4.1.2).
32 #[serde(skip_serializing_if = "Option::is_none")]
33 pub jku: Option<String>,
34 /// JSON Web Key
35 ///
36 /// Defined in [RFC7515#4.1.3](https://tools.ietf.org/html/rfc7515#section-4.1.3).
37 #[serde(skip_serializing_if = "Option::is_none")]
38 pub jwk: Option<Jwk>,
39 /// Key ID
40 ///
41 /// Defined in [RFC7515#4.1.4](https://tools.ietf.org/html/rfc7515#section-4.1.4).
42 #[serde(skip_serializing_if = "Option::is_none")]
43 pub kid: Option<String>,
44 /// X.509 URL
45 ///
46 /// Defined in [RFC7515#4.1.5](https://tools.ietf.org/html/rfc7515#section-4.1.5).
47 #[serde(skip_serializing_if = "Option::is_none")]
48 pub x5u: Option<String>,
49 /// X.509 certificate chain. A Vec of base64 encoded ASN.1 DER certificates.
50 ///
51 /// Defined in [RFC7515#4.1.6](https://tools.ietf.org/html/rfc7515#section-4.1.6).
52 #[serde(skip_serializing_if = "Option::is_none")]
53 pub x5c: Option<Vec<String>>,
54 /// X.509 SHA1 certificate thumbprint
55 ///
56 /// Defined in [RFC7515#4.1.7](https://tools.ietf.org/html/rfc7515#section-4.1.7).
57 #[serde(skip_serializing_if = "Option::is_none")]
58 pub x5t: Option<String>,
59 /// X.509 SHA256 certificate thumbprint
60 ///
61 /// Defined in [RFC7515#4.1.8](https://tools.ietf.org/html/rfc7515#section-4.1.8).
62 ///
63 /// This will be serialized/deserialized as "x5t#S256", as defined by the RFC.
64 #[serde(skip_serializing_if = "Option::is_none")]
65 #[serde(rename = "x5t#S256")]
66 pub x5t_s256: Option<String>,
67}
68
69impl Header {
70 /// Returns a JWT header with the algorithm given
71 pub fn new(algorithm: Algorithm) -> Self {
72 Header {
73 typ: Some("JWT".to_string()),
74 alg: algorithm,
75 cty: None,
76 jku: None,
77 jwk: None,
78 kid: None,
79 x5u: None,
80 x5c: None,
81 x5t: None,
82 x5t_s256: None,
83 }
84 }
85
86 /// Converts an encoded part into the Header struct if possible
87 pub(crate) fn from_encoded<T: AsRef<[u8]>>(encoded_part: T) -> Result<Self> {
88 let decoded = b64_decode(encoded_part)?;
89 Ok(serde_json::from_slice(&decoded)?)
90 }
91
92 /// Decodes the X.509 certificate chain into ASN.1 DER format.
93 pub fn x5c_der(&self) -> Result<Option<Vec<Vec<u8>>>> {
94 Ok(self
95 .x5c
96 .as_ref()
97 .map(|b64_certs| {
98 b64_certs.iter().map(|x| STANDARD.decode(x)).collect::<result::Result<_, _>>()
99 })
100 .transpose()?)
101 }
102}
103
104impl Default for Header {
105 /// Returns a JWT header using the default Algorithm, HS256
106 fn default() -> Self {
107 Header::new(Algorithm::default())
108 }
109}