1use std::fmt;
2use std::hash::{Hash, Hasher};
3
4#[cfg(all(feature = "aws_lc_rs_unstable", not(feature = "fips")))]
5use aws_lc_rs::unstable::signature::{
6 PqdsaSigningAlgorithm, ML_DSA_44_SIGNING, ML_DSA_65_SIGNING, ML_DSA_87_SIGNING,
7};
8use yasna::models::ObjectIdentifier;
9use yasna::{DERWriter, Tag};
10
11#[cfg(feature = "crypto")]
12use crate::ring_like::signature::{self, EcdsaSigningAlgorithm, EdDSAParameters, RsaEncoding};
13use crate::Error;
14
15#[cfg(feature = "crypto")]
16#[derive(Clone, Copy, Debug)]
17pub(crate) enum SignAlgo {
18 EcDsa(&'static EcdsaSigningAlgorithm),
19 EdDsa(&'static EdDSAParameters),
20 #[cfg(all(feature = "aws_lc_rs_unstable", not(feature = "fips")))]
21 PqDsa(&'static PqdsaSigningAlgorithm),
22 Rsa(&'static dyn RsaEncoding),
23}
24
25#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
26pub(crate) enum SignatureAlgorithmParams {
27 None,
29 Null,
31 RsaPss {
33 hash_algorithm: &'static [u64],
34 salt_length: u64,
35 },
36}
37
38#[derive(Clone)]
40pub struct SignatureAlgorithm {
41 oids_sign_alg: &'static [&'static [u64]],
42 #[cfg(feature = "crypto")]
43 pub(crate) sign_alg: SignAlgo,
44 oid_components: &'static [u64],
45 params: SignatureAlgorithmParams,
46}
47
48impl fmt::Debug for SignatureAlgorithm {
49 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
50 use algo::*;
51 if self == &PKCS_RSA_SHA256 {
52 write!(f, "PKCS_RSA_SHA256")
53 } else if self == &PKCS_RSA_SHA384 {
54 write!(f, "PKCS_RSA_SHA384")
55 } else if self == &PKCS_RSA_SHA512 {
56 write!(f, "PKCS_RSA_SHA512")
57 } else if self == &PKCS_RSA_PSS_SHA256 {
58 write!(f, "PKCS_RSA_PSS_SHA256")
59 } else if self == &PKCS_ECDSA_P256_SHA256 {
60 write!(f, "PKCS_ECDSA_P256_SHA256")
61 } else if self == &PKCS_ECDSA_P384_SHA384 {
62 write!(f, "PKCS_ECDSA_P384_SHA384")
63 } else if self == &PKCS_ED25519 {
64 write!(f, "PKCS_ED25519")
65 } else {
66 #[cfg(feature = "aws_lc_rs")]
67 if self == &PKCS_ECDSA_P521_SHA256 {
68 return write!(f, "PKCS_ECDSA_P521_SHA256");
69 }
70 #[cfg(feature = "aws_lc_rs")]
71 if self == &PKCS_ECDSA_P521_SHA384 {
72 return write!(f, "PKCS_ECDSA_P521_SHA384");
73 }
74 #[cfg(feature = "aws_lc_rs")]
75 if self == &PKCS_ECDSA_P521_SHA512 {
76 return write!(f, "PKCS_ECDSA_P521_SHA512");
77 }
78
79 write!(f, "Unknown")
80 }
81 }
82}
83
84impl PartialEq for SignatureAlgorithm {
85 fn eq(&self, other: &Self) -> bool {
86 (self.oids_sign_alg, self.oid_components) == (other.oids_sign_alg, other.oid_components)
87 }
88}
89
90impl Eq for SignatureAlgorithm {}
91
92impl Hash for SignatureAlgorithm {
94 fn hash<H: Hasher>(&self, state: &mut H) {
95 self.oids_sign_alg.hash(state);
97 }
98}
99impl SignatureAlgorithm {
100 pub(crate) fn iter() -> std::slice::Iter<'static, &'static SignatureAlgorithm> {
101 use algo::*;
102 static ALGORITHMS: &[&SignatureAlgorithm] = &[
103 &PKCS_RSA_SHA256,
104 &PKCS_RSA_SHA384,
105 &PKCS_RSA_SHA512,
106 &PKCS_ECDSA_P256_SHA256,
108 &PKCS_ECDSA_P384_SHA384,
109 #[cfg(feature = "aws_lc_rs")]
110 &PKCS_ECDSA_P521_SHA256,
111 #[cfg(feature = "aws_lc_rs")]
112 &PKCS_ECDSA_P521_SHA384,
113 #[cfg(feature = "aws_lc_rs")]
114 &PKCS_ECDSA_P521_SHA512,
115 &PKCS_ED25519,
116 ];
117 ALGORITHMS.iter()
118 }
119
120 pub fn from_oid(oid: &[u64]) -> Result<&'static SignatureAlgorithm, Error> {
122 for algo in Self::iter() {
123 if algo.oid_components == oid {
124 return Ok(algo);
125 }
126 }
127 Err(Error::UnsupportedSignatureAlgorithm)
128 }
129}
130
131pub(crate) mod algo {
133 use super::*;
134 use crate::oid::*;
135
136 pub static PKCS_RSA_SHA256: SignatureAlgorithm = SignatureAlgorithm {
138 oids_sign_alg: &[RSA_ENCRYPTION],
139 #[cfg(feature = "crypto")]
140 sign_alg: SignAlgo::Rsa(&signature::RSA_PKCS1_SHA256),
141 oid_components: &[1, 2, 840, 113549, 1, 1, 11],
143 params: SignatureAlgorithmParams::Null,
144 };
145
146 pub static PKCS_RSA_SHA384: SignatureAlgorithm = SignatureAlgorithm {
148 oids_sign_alg: &[RSA_ENCRYPTION],
149 #[cfg(feature = "crypto")]
150 sign_alg: SignAlgo::Rsa(&signature::RSA_PKCS1_SHA384),
151 oid_components: &[1, 2, 840, 113549, 1, 1, 12],
153 params: SignatureAlgorithmParams::Null,
154 };
155
156 pub static PKCS_RSA_SHA512: SignatureAlgorithm = SignatureAlgorithm {
158 oids_sign_alg: &[RSA_ENCRYPTION],
159 #[cfg(feature = "crypto")]
160 sign_alg: SignAlgo::Rsa(&signature::RSA_PKCS1_SHA512),
161 oid_components: &[1, 2, 840, 113549, 1, 1, 13],
163 params: SignatureAlgorithmParams::Null,
164 };
165
166 pub(crate) static PKCS_RSA_PSS_SHA256: SignatureAlgorithm = SignatureAlgorithm {
173 oids_sign_alg: &[RSASSA_PSS],
176 #[cfg(feature = "crypto")]
177 sign_alg: SignAlgo::Rsa(&signature::RSA_PSS_SHA256),
178 oid_components: RSASSA_PSS, params: SignatureAlgorithmParams::RsaPss {
181 hash_algorithm: &[2, 16, 840, 1, 101, 3, 4, 2, 1],
183 salt_length: 20,
184 },
185 };
186
187 pub static PKCS_ECDSA_P256_SHA256: SignatureAlgorithm = SignatureAlgorithm {
189 oids_sign_alg: &[EC_PUBLIC_KEY, EC_SECP_256_R1],
190 #[cfg(feature = "crypto")]
191 sign_alg: SignAlgo::EcDsa(&signature::ECDSA_P256_SHA256_ASN1_SIGNING),
192 oid_components: &[1, 2, 840, 10045, 4, 3, 2],
194 params: SignatureAlgorithmParams::None,
195 };
196
197 pub static PKCS_ECDSA_P384_SHA384: SignatureAlgorithm = SignatureAlgorithm {
199 oids_sign_alg: &[EC_PUBLIC_KEY, EC_SECP_384_R1],
200 #[cfg(feature = "crypto")]
201 sign_alg: SignAlgo::EcDsa(&signature::ECDSA_P384_SHA384_ASN1_SIGNING),
202 oid_components: &[1, 2, 840, 10045, 4, 3, 3],
204 params: SignatureAlgorithmParams::None,
205 };
206
207 #[cfg(feature = "aws_lc_rs")]
213 pub static PKCS_ECDSA_P521_SHA256: SignatureAlgorithm = SignatureAlgorithm {
214 oids_sign_alg: &[EC_PUBLIC_KEY, EC_SECP_521_R1],
215 #[cfg(feature = "crypto")]
216 sign_alg: SignAlgo::EcDsa(&signature::ECDSA_P521_SHA256_ASN1_SIGNING),
217 oid_components: &[1, 2, 840, 10045, 4, 3, 2],
219 params: SignatureAlgorithmParams::None,
220 };
221
222 #[cfg(feature = "aws_lc_rs")]
228 pub static PKCS_ECDSA_P521_SHA384: SignatureAlgorithm = SignatureAlgorithm {
229 oids_sign_alg: &[EC_PUBLIC_KEY, EC_SECP_521_R1],
230 #[cfg(feature = "crypto")]
231 sign_alg: SignAlgo::EcDsa(&signature::ECDSA_P521_SHA384_ASN1_SIGNING),
232 oid_components: &[1, 2, 840, 10045, 4, 3, 3],
234 params: SignatureAlgorithmParams::None,
235 };
236
237 #[cfg(feature = "aws_lc_rs")]
241 pub static PKCS_ECDSA_P521_SHA512: SignatureAlgorithm = SignatureAlgorithm {
242 oids_sign_alg: &[EC_PUBLIC_KEY, EC_SECP_521_R1],
243 #[cfg(feature = "crypto")]
244 sign_alg: SignAlgo::EcDsa(&signature::ECDSA_P521_SHA512_ASN1_SIGNING),
245 oid_components: &[1, 2, 840, 10045, 4, 3, 4],
247 params: SignatureAlgorithmParams::None,
248 };
249
250 pub static PKCS_ED25519: SignatureAlgorithm = SignatureAlgorithm {
252 oids_sign_alg: &[&[1, 3, 101, 112]],
254 #[cfg(feature = "crypto")]
255 sign_alg: SignAlgo::EdDsa(&signature::ED25519),
256 oid_components: &[1, 3, 101, 112],
258 params: SignatureAlgorithmParams::None,
259 };
260
261 #[cfg(all(feature = "aws_lc_rs_unstable", not(feature = "fips")))]
263 pub static PKCS_ML_DSA_44: SignatureAlgorithm = SignatureAlgorithm {
264 oids_sign_alg: &[ML_DSA_44],
265 #[cfg(all(feature = "crypto", feature = "aws_lc_rs_unstable"))]
266 sign_alg: SignAlgo::PqDsa(&ML_DSA_44_SIGNING),
267 oid_components: ML_DSA_44,
268 params: SignatureAlgorithmParams::None,
269 };
270
271 #[cfg(all(feature = "aws_lc_rs_unstable", not(feature = "fips")))]
273 pub static PKCS_ML_DSA_65: SignatureAlgorithm = SignatureAlgorithm {
274 oids_sign_alg: &[ML_DSA_65],
275 #[cfg(all(feature = "crypto", feature = "aws_lc_rs_unstable"))]
276 sign_alg: SignAlgo::PqDsa(&ML_DSA_65_SIGNING),
277 oid_components: ML_DSA_65,
278 params: SignatureAlgorithmParams::None,
279 };
280
281 #[cfg(all(feature = "aws_lc_rs_unstable", not(feature = "fips")))]
283 pub static PKCS_ML_DSA_87: SignatureAlgorithm = SignatureAlgorithm {
284 oids_sign_alg: &[ML_DSA_87],
285 #[cfg(all(feature = "crypto", feature = "aws_lc_rs_unstable"))]
286 sign_alg: SignAlgo::PqDsa(&ML_DSA_87_SIGNING),
287 oid_components: ML_DSA_87,
288 params: SignatureAlgorithmParams::None,
289 };
290}
291impl SignatureAlgorithm {
293 fn alg_ident_oid(&self) -> ObjectIdentifier {
294 ObjectIdentifier::from_slice(self.oid_components)
295 }
296 fn write_params(&self, writer: &mut yasna::DERWriterSeq) {
297 match self.params {
298 SignatureAlgorithmParams::None => (),
299 SignatureAlgorithmParams::Null => {
300 writer.next().write_null();
301 },
302 SignatureAlgorithmParams::RsaPss {
303 hash_algorithm,
304 salt_length,
305 } => {
306 writer.next().write_sequence(|writer| {
307 let oid = ObjectIdentifier::from_slice(hash_algorithm);
310 writer.next().write_tagged(Tag::context(0), |writer| {
312 writer.write_sequence(|writer| {
313 writer.next().write_oid(&oid);
314 });
315 });
316 writer.next().write_tagged(Tag::context(1), |writer| {
318 writer.write_sequence(|writer| {
319 const ID_MGF1: &[u64] = &[1, 2, 840, 113549, 1, 1, 8];
321 let oid = ObjectIdentifier::from_slice(ID_MGF1);
322 writer.next().write_oid(&oid);
323 writer.next().write_sequence(|writer| {
324 let oid = ObjectIdentifier::from_slice(hash_algorithm);
325 writer.next().write_oid(&oid);
326 writer.next().write_null();
327 });
328 });
329 });
330 writer.next().write_tagged(Tag::context(2), |writer| {
332 writer.write_u64(salt_length);
333 });
334 })
336 },
337 }
338 }
339 pub(crate) fn write_alg_ident(&self, writer: DERWriter) {
341 writer.write_sequence(|writer| {
342 writer.next().write_oid(&self.alg_ident_oid());
343 self.write_params(writer);
344 });
345 }
346 pub(crate) fn write_oids_sign_alg(&self, writer: DERWriter) {
348 writer.write_sequence(|writer| {
349 for oid in self.oids_sign_alg {
350 let oid = ObjectIdentifier::from_slice(oid);
351 writer.next().write_oid(&oid);
352 }
353 self.write_params(writer);
354 });
355 }
356}