A better Rust ATProto crate
1use jacquard_common::{
2 IntoStatic,
3 bos::{BosStr, DefaultStr},
4};
5use jose_jwa::Algorithm;
6use jose_jwk::Jwk;
7use serde::{Deserialize, Serialize};
8
9/// A JWS compact-serialization header, wrapping the registered header fields.
10#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
11#[serde(bound(deserialize = "S: serde::Deserialize<'de> + BosStr"))]
12pub struct Header<S: BosStr = DefaultStr> {
13 /// The registered header parameters defined by the JWS specification.
14 #[serde(flatten)]
15 pub registered: RegisteredHeader<S>,
16}
17
18impl<S: BosStr> From<Header<S>> for super::super::jose::Header<S> {
19 fn from(header: Header<S>) -> Self {
20 super::super::jose::Header::Jws(header)
21 }
22}
23
24/// Registered JWS header parameters as defined in RFC 7515 §4.1.
25#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
26#[serde(bound(deserialize = "S: serde::Deserialize<'de> + BosStr"))]
27pub struct RegisteredHeader<S: BosStr = DefaultStr> {
28 /// The cryptographic algorithm used to sign the JWS (e.g., `ES256`).
29 pub alg: Algorithm,
30 /// JWK Set URL: a URI pointing to a resource containing the public key(s) used to sign the JWS.
31 #[serde(skip_serializing_if = "Option::is_none")]
32 pub jku: Option<S>,
33 /// JSON Web Key: the public key used to verify the JWS, embedded directly in the header.
34 #[serde(skip_serializing_if = "Option::is_none")]
35 pub jwk: Option<Jwk>,
36 /// Key ID: a hint indicating which key was used to sign the JWS.
37 #[serde(skip_serializing_if = "Option::is_none")]
38 pub kid: Option<S>,
39 /// X.509 URL: a URI pointing to a resource for the X.509 certificate used to sign the JWS.
40 #[serde(skip_serializing_if = "Option::is_none")]
41 pub x5u: Option<S>,
42 /// X.509 certificate chain: the certificate (and chain) corresponding to the key used to sign the JWS.
43 #[serde(skip_serializing_if = "Option::is_none")]
44 pub x5c: Option<S>,
45 /// X.509 certificate SHA-1 thumbprint: base64url-encoded SHA-1 digest of the DER-encoded certificate.
46 #[serde(skip_serializing_if = "Option::is_none")]
47 pub x5t: Option<S>,
48 /// X.509 certificate SHA-256 thumbprint: base64url-encoded SHA-256 digest of the DER-encoded certificate.
49 #[serde(skip_serializing_if = "Option::is_none")]
50 #[serde(rename = "x5t#S256")]
51 pub x5ts256: Option<S>,
52 /// Type: declares the media type of the complete JWS, used by applications to disambiguate among JOSe objects.
53 #[serde(skip_serializing_if = "Option::is_none")]
54 pub typ: Option<S>,
55 /// Content type: declares the media type of the secured content (the payload).
56 #[serde(skip_serializing_if = "Option::is_none")]
57 pub cty: Option<S>,
58}
59
60impl<S: BosStr> From<Algorithm> for RegisteredHeader<S> {
61 fn from(alg: Algorithm) -> Self {
62 Self {
63 alg,
64 jku: None,
65 jwk: None,
66 kid: None,
67 x5u: None,
68 x5c: None,
69 x5t: None,
70 x5ts256: None,
71 typ: None,
72 cty: None,
73 }
74 }
75}
76
77impl<S: BosStr> From<RegisteredHeader<S>> for super::super::jose::Header<S> {
78 fn from(registered: RegisteredHeader<S>) -> Self {
79 super::super::jose::Header::Jws(Header { registered })
80 }
81}
82
83impl<S> IntoStatic for RegisteredHeader<S>
84where
85 S: BosStr + IntoStatic,
86 S::Output: BosStr,
87{
88 type Output = RegisteredHeader<S::Output>;
89 fn into_static(self) -> Self::Output {
90 RegisteredHeader {
91 alg: self.alg,
92 jku: self.jku.map(IntoStatic::into_static),
93 jwk: self.jwk,
94 kid: self.kid.map(IntoStatic::into_static),
95 x5u: self.x5u.map(IntoStatic::into_static),
96 x5c: self.x5c.map(IntoStatic::into_static),
97 x5t: self.x5t.map(IntoStatic::into_static),
98 x5ts256: self.x5ts256.map(IntoStatic::into_static),
99 typ: self.typ.map(IntoStatic::into_static),
100 cty: self.cty.map(IntoStatic::into_static),
101 }
102 }
103}
104
105impl<S> IntoStatic for Header<S>
106where
107 S: BosStr + IntoStatic,
108 S::Output: BosStr,
109{
110 type Output = Header<S::Output>;
111 fn into_static(self) -> Self::Output {
112 Header {
113 registered: self.registered.into_static(),
114 }
115 }
116}