1use serde::{Deserialize, Serialize};
2
3extern crate alloc;
4use super::Bytes;
5use alloc::{boxed::Box, collections::BTreeSet, string::String, vec::Vec};
6use base64ct::Base64;
7use core::fmt;
8
9#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
11pub struct Parameters {
12 #[serde(skip_serializing_if = "Option::is_none", default)]
14 pub alg: Option<Algorithm>,
15
16 #[serde(skip_serializing_if = "Option::is_none", default)]
18 pub kid: Option<String>,
19
20 #[serde(skip_serializing_if = "Option::is_none", default, rename = "use")]
22 pub cls: Option<Class>,
23
24 #[serde(skip_serializing_if = "Option::is_none", default, rename = "key_ops")]
26 pub ops: Option<BTreeSet<Operations>>,
27
28 #[serde(skip_serializing_if = "Option::is_none", default)]
30 #[cfg(feature = "url")]
31 pub x5u: Option<url::Url>,
32
33 #[serde(skip_serializing_if = "Option::is_none", default)]
35 pub x5c: Option<Vec<Bytes<Box<[u8]>, Base64>>>, #[serde(flatten)]
39 pub x5t: Thumbprint,
40}
41
42impl<T: Into<Algorithm>> From<T> for Parameters {
43 fn from(value: T) -> Self {
44 let alg = Some(value.into());
45
46 let cls = match alg {
47 Some(Algorithm::Signing(..)) => Some(Class::Signing),
48 _ => None,
49 };
50
51 Self {
52 alg,
53 cls,
54 ..Default::default()
55 }
56 }
57}
58
59#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
61#[allow(missing_docs)]
62#[non_exhaustive]
63pub enum Class {
64 #[serde(rename = "enc")]
65 Encryption,
66
67 #[serde(rename = "sig")]
68 Signing,
69}
70
71#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
74#[serde(rename_all = "camelCase")]
75#[allow(missing_docs)]
76#[non_exhaustive]
77pub enum Operations {
78 Decrypt,
79 DeriveBits,
80 DeriveKey,
81 Encrypt,
82 Sign,
83 UnwrapKey,
84 Verify,
85 WrapKey,
86}
87
88#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
90pub struct Thumbprint {
91 #[serde(skip_serializing_if = "Option::is_none", rename = "x5t", default)]
93 pub s1: Option<Bytes<[u8; 20]>>,
94
95 #[serde(skip_serializing_if = "Option::is_none", rename = "x5t#S256", default)]
97 pub s256: Option<Bytes<[u8; 32]>>,
98}
99
100#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
104#[allow(missing_docs)]
105#[serde(untagged)]
106#[non_exhaustive]
107pub enum Algorithm {
108 Signing(Signing),
110}
111
112impl From<Signing> for Algorithm {
113 #[inline(always)]
114 fn from(alg: Signing) -> Self {
115 Self::Signing(alg)
116 }
117}
118
119#[non_exhaustive]
123#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
124#[serde(rename_all = "UPPERCASE")]
125pub enum Signing {
126 #[serde(rename = "EdDSA")]
128 EdDsa,
129
130 Es256,
132
133 Es256K,
135
136 Es384,
138
139 Es512,
141
142 Hs256,
144
145 Hs384,
147
148 Hs512,
150
151 Ps256,
153
154 Ps384,
156
157 Ps512,
159
160 Rs256,
162
163 Rs384,
165
166 Rs512,
168
169 #[serde(rename = "none")]
173 Null,
174}
175
176impl fmt::Display for Signing {
177 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
178 self.serialize(f)
179 }
180}
181
182#[cfg(test)]
183mod tests {
184 extern crate std;
185
186 use std::prelude::rust_2021::*;
187 use std::vec;
188
189 use super::*;
190
191 #[test]
192 fn signing_algs() {
193 use Signing::*;
194
195 let input = vec![
196 EdDsa, Es256, Es256K, Es384, Es512, Hs256, Hs384, Hs512, Ps256, Ps384, Ps512, Rs256, Rs384, Rs512, Null,
197 ];
198 let ser = serde_json::to_string(&input).expect("serialization failed");
199
200 assert_eq!(
201 ser,
202 r#"["EdDSA","ES256","ES256K","ES384","ES512","HS256","HS384","HS512","PS256","PS384","PS512","RS256","RS384","RS512","none"]"#
203 );
204
205 assert_eq!(serde_json::from_str::<Vec<Signing>>(&ser).expect("deserialization failed"), input);
206 }
207}