Skip to content

Commit c6bca67

Browse files
committed
feat: add BasicHeader with Hash impl
Add `BasicHeader` as a backwards-compatible fix for the regression introduced in #420 which dropped the `Hash` derive trait from `Header`. Resolves #439
1 parent 54e4e4b commit c6bca67

File tree

1 file changed

+117
-0
lines changed

1 file changed

+117
-0
lines changed

src/header.rs

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,3 +268,120 @@ impl Alg for Header {
268268
}
269269

270270
impl FromEncoded for Header {}
271+
272+
/// A truly basic JWT header, the alg defaults to HS256 and typ is automatically
273+
/// set to `JWT`. All the other fields are optional.
274+
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
275+
pub struct BasicHeader {
276+
/// The type of JWS: it can only be "JWT" here
277+
///
278+
/// Defined in [RFC7515#4.1.9](https://tools.ietf.org/html/rfc7515#section-4.1.9).
279+
#[serde(skip_serializing_if = "Option::is_none")]
280+
pub typ: Option<String>,
281+
/// The algorithm used
282+
///
283+
/// Defined in [RFC7515#4.1.1](https://tools.ietf.org/html/rfc7515#section-4.1.1).
284+
pub alg: Algorithm,
285+
/// Content type
286+
///
287+
/// Defined in [RFC7519#5.2](https://tools.ietf.org/html/rfc7519#section-5.2).
288+
#[serde(skip_serializing_if = "Option::is_none")]
289+
pub cty: Option<String>,
290+
/// JSON Key URL
291+
///
292+
/// Defined in [RFC7515#4.1.2](https://tools.ietf.org/html/rfc7515#section-4.1.2).
293+
#[serde(skip_serializing_if = "Option::is_none")]
294+
pub jku: Option<String>,
295+
/// JSON Web Key
296+
///
297+
/// Defined in [RFC7515#4.1.3](https://tools.ietf.org/html/rfc7515#section-4.1.3).
298+
#[serde(skip_serializing_if = "Option::is_none")]
299+
pub jwk: Option<Jwk>,
300+
/// Key ID
301+
///
302+
/// Defined in [RFC7515#4.1.4](https://tools.ietf.org/html/rfc7515#section-4.1.4).
303+
#[serde(skip_serializing_if = "Option::is_none")]
304+
pub kid: Option<String>,
305+
/// X.509 URL
306+
///
307+
/// Defined in [RFC7515#4.1.5](https://tools.ietf.org/html/rfc7515#section-4.1.5).
308+
#[serde(skip_serializing_if = "Option::is_none")]
309+
pub x5u: Option<String>,
310+
/// X.509 certificate chain. A Vec of base64 encoded ASN.1 DER certificates.
311+
///
312+
/// Defined in [RFC7515#4.1.6](https://tools.ietf.org/html/rfc7515#section-4.1.6).
313+
#[serde(skip_serializing_if = "Option::is_none")]
314+
pub x5c: Option<Vec<String>>,
315+
/// X.509 SHA1 certificate thumbprint
316+
///
317+
/// Defined in [RFC7515#4.1.7](https://tools.ietf.org/html/rfc7515#section-4.1.7).
318+
#[serde(skip_serializing_if = "Option::is_none")]
319+
pub x5t: Option<String>,
320+
/// X.509 SHA256 certificate thumbprint
321+
///
322+
/// Defined in [RFC7515#4.1.8](https://tools.ietf.org/html/rfc7515#section-4.1.8).
323+
///
324+
/// This will be serialized/deserialized as "x5t#S256", as defined by the RFC.
325+
#[serde(skip_serializing_if = "Option::is_none")]
326+
#[serde(rename = "x5t#S256")]
327+
pub x5t_s256: Option<String>,
328+
/// Critical - indicates header fields that must be understood by the receiver.
329+
///
330+
/// Defined in [RFC7515#4.1.6](https://tools.ietf.org/html/rfc7515#section-4.1.6).
331+
#[serde(skip_serializing_if = "Option::is_none")]
332+
pub crit: Option<Vec<String>>,
333+
/// See `Enc` for description.
334+
#[serde(skip_serializing_if = "Option::is_none")]
335+
pub enc: Option<Enc>,
336+
/// See `Zip` for description.
337+
#[serde(skip_serializing_if = "Option::is_none")]
338+
pub zip: Option<Zip>,
339+
/// ACME: The URL to which this JWS object is directed
340+
///
341+
/// Defined in [RFC8555#6.4](https://datatracker.ietf.org/doc/html/rfc8555#section-6.4).
342+
#[serde(skip_serializing_if = "Option::is_none")]
343+
pub url: Option<String>,
344+
/// ACME: Random data for preventing replay attacks.
345+
///
346+
/// Defined in [RFC8555#6.5.2](https://datatracker.ietf.org/doc/html/rfc8555#section-6.5.2).
347+
#[serde(skip_serializing_if = "Option::is_none")]
348+
pub nonce: Option<String>,
349+
}
350+
351+
impl BasicHeader {
352+
/// Returns a JWT header with the algorithm given
353+
pub fn new(algorithm: Algorithm) -> Self {
354+
Self {
355+
typ: Some("JWT".to_string()),
356+
alg: algorithm,
357+
cty: None,
358+
jku: None,
359+
jwk: None,
360+
kid: None,
361+
x5u: None,
362+
x5c: None,
363+
x5t: None,
364+
x5t_s256: None,
365+
crit: None,
366+
enc: None,
367+
zip: None,
368+
url: None,
369+
nonce: None,
370+
}
371+
}
372+
}
373+
374+
impl Default for BasicHeader {
375+
/// Returns a JWT header using the default Algorithm, HS256
376+
fn default() -> Self {
377+
Self::new(Algorithm::default())
378+
}
379+
}
380+
381+
impl Alg for BasicHeader {
382+
fn alg(&self) -> &Algorithm {
383+
&self.alg
384+
}
385+
}
386+
387+
impl FromEncoded for BasicHeader {}

0 commit comments

Comments
 (0)