1use crate::oids;
2use oid::ObjectIdentifier;
3use picky_asn1::tag::{Tag, TagPeeker};
4use picky_asn1::wrapper::{
5 ExplicitContextTag0, ExplicitContextTag1, ExplicitContextTag2, IntegerAsn1, ObjectIdentifierAsn1, OctetStringAsn1,
6};
7use picky_asn1_der::Asn1RawDer;
8use serde::{Deserialize, Serialize, de, ser};
9use std::cmp::Ordering;
10use std::error::Error;
11use std::fmt;
12
13#[derive(Debug)]
15pub struct UnsupportedAlgorithmError {
16 pub algorithm: String,
17}
18
19impl fmt::Display for UnsupportedAlgorithmError {
20 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21 write!(f, "unsupported algorithm: {}", self.algorithm)
22 }
23}
24
25impl Error for UnsupportedAlgorithmError {}
26
27#[derive(Debug, PartialEq, Eq, Clone)]
28pub struct AlgorithmIdentifier {
29 algorithm: ObjectIdentifierAsn1,
30 parameters: AlgorithmIdentifierParameters,
31}
32
33impl AlgorithmIdentifier {
34 pub fn oid(&self) -> &ObjectIdentifier {
35 &self.algorithm.0
36 }
37
38 pub fn oid_asn1(&self) -> &ObjectIdentifierAsn1 {
39 &self.algorithm
40 }
41
42 pub fn parameters(&self) -> &AlgorithmIdentifierParameters {
43 &self.parameters
44 }
45
46 pub fn is_a(&self, algorithm: ObjectIdentifier) -> bool {
47 algorithm.eq(&self.algorithm.0)
48 }
49
50 pub fn is_one_of(&self, algorithms: impl IntoIterator<Item = ObjectIdentifier>) -> bool {
51 algorithms.into_iter().any(|oid| self.is_a(oid))
52 }
53
54 pub fn new_md5_with_rsa_encryption() -> Self {
55 Self {
56 algorithm: oids::md5_with_rsa_encryption().into(),
57 parameters: AlgorithmIdentifierParameters::Null,
58 }
59 }
60
61 pub fn new_sha1_with_rsa_encryption() -> Self {
62 Self {
63 algorithm: oids::sha1_with_rsa_encryption().into(),
64 parameters: AlgorithmIdentifierParameters::Null,
65 }
66 }
67
68 pub fn new_sha1() -> Self {
69 Self {
70 algorithm: oids::sha1().into(),
71 parameters: AlgorithmIdentifierParameters::Null,
72 }
73 }
74
75 pub fn new_sha224_with_rsa_encryption() -> Self {
76 Self {
77 algorithm: oids::sha224_with_rsa_encryption().into(),
78 parameters: AlgorithmIdentifierParameters::Null,
79 }
80 }
81
82 pub fn new_sha256_with_rsa_encryption() -> Self {
83 Self {
84 algorithm: oids::sha256_with_rsa_encryption().into(),
85 parameters: AlgorithmIdentifierParameters::Null,
86 }
87 }
88
89 pub fn new_sha384_with_rsa_encryption() -> Self {
90 Self {
91 algorithm: oids::sha384_with_rsa_encryption().into(),
92 parameters: AlgorithmIdentifierParameters::Null,
93 }
94 }
95
96 pub fn new_sha512_with_rsa_encryption() -> Self {
97 Self {
98 algorithm: oids::sha512_with_rsa_encryption().into(),
99 parameters: AlgorithmIdentifierParameters::Null,
100 }
101 }
102
103 pub fn new_sha3_224_with_rsa_encryption() -> Self {
104 Self {
105 algorithm: oids::id_rsassa_pkcs1_v1_5_with_sha3_224().into(),
106 parameters: AlgorithmIdentifierParameters::Null,
107 }
108 }
109
110 pub fn new_sha3_256_with_rsa_encryption() -> Self {
111 Self {
112 algorithm: oids::id_rsassa_pkcs1_v1_5_with_sha3_256().into(),
113 parameters: AlgorithmIdentifierParameters::Null,
114 }
115 }
116
117 pub fn new_sha3_384_with_rsa_encryption() -> Self {
118 Self {
119 algorithm: oids::id_rsassa_pkcs1_v1_5_with_sha3_384().into(),
120 parameters: AlgorithmIdentifierParameters::Null,
121 }
122 }
123
124 pub fn new_sha3_512_with_rsa_encryption() -> Self {
125 Self {
126 algorithm: oids::id_rsassa_pkcs1_v1_5_with_sha3_512().into(),
127 parameters: AlgorithmIdentifierParameters::Null,
128 }
129 }
130
131 pub fn new_rsassa_pss(parameters: RsassaPssParams) -> Self {
132 Self {
133 algorithm: oids::rsassa_pss().into(),
134 parameters: AlgorithmIdentifierParameters::RsassaPss(parameters),
135 }
136 }
137
138 pub fn new_rsa_encryption() -> Self {
139 Self {
140 algorithm: oids::rsa_encryption().into(),
141 parameters: AlgorithmIdentifierParameters::Null,
142 }
143 }
144
145 pub fn new_rsa_encryption_with_sha(variant: ShaVariant) -> Result<Self, UnsupportedAlgorithmError> {
146 let algorithm = match variant {
147 ShaVariant::SHA2_224 => oids::sha224_with_rsa_encryption(),
148 ShaVariant::SHA2_256 => oids::sha256_with_rsa_encryption(),
149 ShaVariant::SHA2_384 => oids::sha384_with_rsa_encryption(),
150 ShaVariant::SHA2_512 => oids::sha512_with_rsa_encryption(),
151 ShaVariant::SHA3_384 => oids::id_rsassa_pkcs1_v1_5_with_sha3_384(),
152 ShaVariant::SHA3_512 => oids::id_rsassa_pkcs1_v1_5_with_sha3_512(),
153 _ => {
154 return Err(UnsupportedAlgorithmError {
155 algorithm: format!("{variant:?}"),
156 });
157 }
158 };
159
160 Ok(Self {
161 algorithm: algorithm.into(),
162 parameters: AlgorithmIdentifierParameters::Null,
163 })
164 }
165
166 pub fn new_dsa_with_sha1() -> Self {
167 Self {
168 algorithm: oids::dsa_with_sha1().into(),
169 parameters: AlgorithmIdentifierParameters::Null,
170 }
171 }
172
173 pub fn new_ecdsa_with_sha512() -> Self {
174 Self {
175 algorithm: oids::ecdsa_with_sha512().into(),
176 parameters: AlgorithmIdentifierParameters::None,
177 }
178 }
179
180 pub fn new_ecdsa_with_sha384() -> Self {
181 Self {
182 algorithm: oids::ecdsa_with_sha384().into(),
183 parameters: AlgorithmIdentifierParameters::None,
184 }
185 }
186
187 pub fn new_ecdsa_with_sha256() -> Self {
188 Self {
189 algorithm: oids::ecdsa_with_sha256().into(),
190 parameters: AlgorithmIdentifierParameters::None,
191 }
192 }
193
194 pub fn new_elliptic_curve(ec_params: EcParameters) -> Self {
195 Self {
196 algorithm: oids::ec_public_key().into(),
197 parameters: AlgorithmIdentifierParameters::Ec(ec_params),
198 }
199 }
200
201 pub(crate) fn new_unchecked(algorithm: ObjectIdentifier, parameters: AlgorithmIdentifierParameters) -> Self {
204 Self {
205 algorithm: algorithm.into(),
206 parameters,
207 }
208 }
209
210 pub fn new_ed25519() -> Self {
211 Self {
212 algorithm: oids::ed25519().into(),
213 parameters: AlgorithmIdentifierParameters::None,
214 }
215 }
216
217 pub fn new_x25519() -> Self {
218 Self {
219 algorithm: oids::x25519().into(),
220 parameters: AlgorithmIdentifierParameters::None,
221 }
222 }
223
224 pub fn new_ed448() -> Self {
225 Self {
226 algorithm: oids::ed448().into(),
227 parameters: AlgorithmIdentifierParameters::None,
228 }
229 }
230
231 pub fn new_x448() -> Self {
232 Self {
233 algorithm: oids::x448().into(),
234 parameters: AlgorithmIdentifierParameters::None,
235 }
236 }
237
238 pub fn new_aes128(mode: AesMode, params: AesParameters) -> Self {
239 Self {
240 algorithm: mode.to_128bit_oid(),
241 parameters: AlgorithmIdentifierParameters::Aes(params),
242 }
243 }
244
245 pub fn new_aes192(mode: AesMode, params: AesParameters) -> Self {
246 Self {
247 algorithm: mode.to_192bit_oid(),
248 parameters: AlgorithmIdentifierParameters::Aes(params),
249 }
250 }
251
252 pub fn new_aes256(mode: AesMode, params: AesParameters) -> Self {
253 Self {
254 algorithm: mode.to_256bit_oid(),
255 parameters: AlgorithmIdentifierParameters::Aes(params),
256 }
257 }
258
259 pub fn new_aes256_empty(mode: AesMode) -> Self {
260 Self {
261 algorithm: mode.to_256bit_oid(),
262 parameters: AlgorithmIdentifierParameters::None,
263 }
264 }
265
266 pub fn new_sha(variant: ShaVariant) -> Self {
267 Self {
268 algorithm: variant.into(),
269 parameters: AlgorithmIdentifierParameters::Null,
270 }
271 }
272
273 pub fn new_ecdsa_with_sha3_224() -> Self {
274 Self {
275 algorithm: oids::id_ecdsa_with_sha3_224().into(),
276 parameters: AlgorithmIdentifierParameters::None,
277 }
278 }
279
280 pub fn new_ecdsa_with_sha3_256() -> Self {
281 Self {
282 algorithm: oids::id_ecdsa_with_sha3_256().into(),
283 parameters: AlgorithmIdentifierParameters::None,
284 }
285 }
286
287 pub fn new_ecdsa_with_sha3_384() -> Self {
288 Self {
289 algorithm: oids::id_ecdsa_with_sha3_384().into(),
290 parameters: AlgorithmIdentifierParameters::None,
291 }
292 }
293
294 pub fn new_ecdsa_with_sha3_512() -> Self {
295 Self {
296 algorithm: oids::id_ecdsa_with_sha3_512().into(),
297 parameters: AlgorithmIdentifierParameters::None,
298 }
299 }
300
301 pub fn new_mldsa_44() -> Self {
302 Self {
303 algorithm: oids::id_mldsa_44().into(),
304 parameters: AlgorithmIdentifierParameters::None,
305 }
306 }
307
308 pub fn new_mldsa_65() -> Self {
309 Self {
310 algorithm: oids::id_mldsa_65().into(),
311 parameters: AlgorithmIdentifierParameters::None,
312 }
313 }
314
315 pub fn new_mldsa_87() -> Self {
316 Self {
317 algorithm: oids::id_mldsa_87().into(),
318 parameters: AlgorithmIdentifierParameters::None,
319 }
320 }
321}
322
323impl ser::Serialize for AlgorithmIdentifier {
324 fn serialize<S>(&self, serializer: S) -> Result<<S as ser::Serializer>::Ok, <S as ser::Serializer>::Error>
325 where
326 S: ser::Serializer,
327 {
328 use ser::SerializeSeq;
329 let mut seq = serializer.serialize_seq(Some(2))?;
330 seq.serialize_element(&self.algorithm)?;
331 match &self.parameters {
332 AlgorithmIdentifierParameters::None => {}
333 AlgorithmIdentifierParameters::Null => {
334 seq.serialize_element(&())?;
335 }
336 AlgorithmIdentifierParameters::Ec(ec_params) => {
337 seq.serialize_element(ec_params)?;
338 }
339 AlgorithmIdentifierParameters::Aes(aes_params) => {
340 seq.serialize_element(aes_params)?;
341 }
342 AlgorithmIdentifierParameters::RsassaPss(rsa_params) => {
343 seq.serialize_element(rsa_params)?;
344 }
345 }
346 seq.end()
347 }
348}
349
350impl<'de> de::Deserialize<'de> for AlgorithmIdentifier {
351 fn deserialize<D>(deserializer: D) -> Result<Self, <D as de::Deserializer<'de>>::Error>
352 where
353 D: de::Deserializer<'de>,
354 {
355 struct Visitor;
356
357 impl<'de> de::Visitor<'de> for Visitor {
358 type Value = AlgorithmIdentifier;
359
360 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
361 formatter.write_str("a valid DER-encoded algorithm identifier")
362 }
363
364 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
365 where
366 A: de::SeqAccess<'de>,
367 {
368 let oid: ObjectIdentifierAsn1 = seq_next_element!(seq, AlgorithmIdentifier, "algorithm oid");
369
370 let args = match Into::<String>::into(&oid.0).as_str() {
371 oids::RSA_ENCRYPTION
372 | oids::SHA1_WITH_RSA_ENCRYPTION
373 | oids::SHA224_WITH_RSA_ENCRYPTION
374 | oids::SHA256_WITH_RSA_ENCRYPTION
375 | oids::SHA384_WITH_RSA_ENCRYPTION
376 | oids::SHA512_WITH_RSA_ENCRYPTION
377 | oids::ID_RSASSA_PKCS1_V1_5_WITH_SHA3_224
378 | oids::ID_RSASSA_PKCS1_V1_5_WITH_SHA3_256
379 | oids::ID_RSASSA_PKCS1_V1_5_WITH_SHA3_384
380 | oids::ID_RSASSA_PKCS1_V1_5_WITH_SHA3_512 => {
381 let _ = seq.next_element::<()>();
386 AlgorithmIdentifierParameters::Null
387 }
388 oids::RSASSA_PSS => AlgorithmIdentifierParameters::RsassaPss(seq_next_element!(
389 seq,
390 RsassaPssParams,
391 "RSASSA-PSS parameters"
392 )),
393 oids::ECDSA_WITH_SHA384
394 | oids::ECDSA_WITH_SHA256
395 | oids::ECDSA_WITH_SHA512
396 | oids::ID_ECDSA_WITH_SHA3_224
397 | oids::ID_ECDSA_WITH_SHA3_256
398 | oids::ID_ECDSA_WITH_SHA3_384
399 | oids::ID_ECDSA_WITH_SHA3_512
400 | oids::ED25519
401 | oids::ED448
402 | oids::X25519
403 | oids::X448
404 | oids::ID_MLDSA_44
405 | oids::ID_MLDSA_65
406 | oids::ID_MLDSA_87 => AlgorithmIdentifierParameters::None,
407 oids::DSA_WITH_SHA1 => {
408 AlgorithmIdentifierParameters::None
414 }
415 oids::EC_PUBLIC_KEY => AlgorithmIdentifierParameters::Ec(seq_next_element!(
418 seq,
419 EcParameters,
420 AlgorithmIdentifier,
421 "elliptic curves parameters"
422 )),
423 x if x.starts_with("2.16.840.1.101.3.4.1.") => {
425 if let Some(aes_parameters) = seq.next_element()? {
426 AlgorithmIdentifierParameters::Aes(aes_parameters)
427 } else {
428 AlgorithmIdentifierParameters::None
429 }
430 }
431 x if x.starts_with("2.16.840.1.101.3.4.2.") || x == oids::SHA1 => {
433 type Unit = ();
434 seq_next_element!(seq, Unit, AlgorithmIdentifier, "sha algorithm identifier");
435 AlgorithmIdentifierParameters::Null
436 }
437 _ => {
438 return Err(serde_invalid_value!(
439 AlgorithmIdentifier,
440 "unsupported algorithm (unknown oid)",
441 "a supported algorithm"
442 ));
443 }
444 };
445
446 Ok(AlgorithmIdentifier {
447 algorithm: oid,
448 parameters: args,
449 })
450 }
451 }
452
453 deserializer.deserialize_seq(Visitor)
454 }
455}
456
457#[derive(Debug, PartialEq, Eq, Clone)]
458pub enum AlgorithmIdentifierParameters {
459 None,
460 Null,
461 Aes(AesParameters),
462 Ec(EcParameters),
463 RsassaPss(RsassaPssParams),
464}
465
466#[derive(Clone, Debug, Eq, PartialEq)]
482pub struct RsassaPssParams {
483 pub hash_algorithm: HashAlgorithm,
484 pub mask_gen_algorithm: MaskGenAlgorithm,
485 pub salt_length: usize,
486}
487
488impl RsassaPssParams {
489 pub fn new(hash_algorithm: HashAlgorithm) -> Self {
490 Self {
491 hash_algorithm,
492 mask_gen_algorithm: MaskGenAlgorithm::new(hash_algorithm),
493 salt_length: hash_algorithm.len(),
494 }
495 }
496}
497
498impl ser::Serialize for RsassaPssParams {
499 fn serialize<S>(&self, serializer: S) -> Result<<S as ser::Serializer>::Ok, <S as ser::Serializer>::Error>
500 where
501 S: ser::Serializer,
502 {
503 use ser::SerializeSeq;
504 let mut seq = serializer.serialize_seq(Some(3))?;
505 seq.serialize_element(&ExplicitContextTag0(&self.hash_algorithm))?;
506 seq.serialize_element(&ExplicitContextTag1(&self.mask_gen_algorithm))?;
507 seq.serialize_element(&ExplicitContextTag2(&IntegerAsn1::from_bytes_be_signed(
508 self.salt_length.to_be_bytes().to_vec(),
509 )))?;
510 seq.end()
511 }
512}
513
514fn usize_from_be_bytes(asn1: &IntegerAsn1) -> usize {
515 let bytes = asn1.as_unsigned_bytes_be();
516 match bytes.len().cmp(&8) {
517 Ordering::Greater => usize::MAX,
518 Ordering::Less => {
519 const USIZE_SIZE: usize = std::mem::size_of::<usize>();
520
521 let mut tmp = [0; USIZE_SIZE];
522 tmp[(USIZE_SIZE - bytes.len())..USIZE_SIZE].clone_from_slice(bytes);
523 usize::from_be_bytes(tmp)
524 }
525 Ordering::Equal => usize::from_be_bytes(bytes.try_into().unwrap()),
527 }
528}
529
530impl<'de> de::Deserialize<'de> for RsassaPssParams {
531 fn deserialize<D>(deserializer: D) -> Result<Self, <D as de::Deserializer<'de>>::Error>
532 where
533 D: de::Deserializer<'de>,
534 {
535 struct Visitor;
536
537 impl<'de> de::Visitor<'de> for Visitor {
538 type Value = RsassaPssParams;
539
540 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
541 formatter.write_str("a valid DER-encoded RsassaPssParams")
542 }
543
544 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
545 where
546 A: de::SeqAccess<'de>,
547 {
548 let hash = seq_next_element!(seq, ExplicitContextTag0<HashAlgorithm>, HashAlgorithm, "cont [0]");
549 let mask_gen = seq_next_element!(
550 seq,
551 ExplicitContextTag1<MaskGenAlgorithm>,
552 MaskGenAlgorithm,
553 "maskGenAlgorithm"
554 );
555 let salt = seq_next_element!(seq, ExplicitContextTag2<IntegerAsn1>, IntegerAsn1, "saltLength");
556 Ok(RsassaPssParams {
557 hash_algorithm: hash.0,
558 mask_gen_algorithm: mask_gen.0,
559 salt_length: usize_from_be_bytes(&salt.0),
560 })
561 }
562 }
563
564 deserializer.deserialize_seq(Visitor)
565 }
566}
567
568#[derive(Clone, Copy, PartialEq, Eq, Debug)]
570#[allow(non_camel_case_types)]
571pub enum HashAlgorithm {
572 SHA224,
576 SHA256,
577 SHA384,
578 SHA512,
579
580 SHA3_224,
581 SHA3_256,
582 SHA3_384,
583 SHA3_512,
584}
585
586impl HashAlgorithm {
587 pub fn len(&self) -> usize {
588 use HashAlgorithm::*;
589 match self {
590 SHA224 => 28,
591 SHA256 => 32,
592 SHA384 => 48,
593 SHA512 => 64,
594 SHA3_224 => 28,
595 SHA3_256 => 32,
596 SHA3_384 => 48,
597 SHA3_512 => 64,
598 }
599 }
600 pub fn is_empty(&self) -> bool {
601 false
602 }
603}
604impl From<&HashAlgorithm> for ObjectIdentifierAsn1 {
605 fn from(variant: &HashAlgorithm) -> Self {
606 use HashAlgorithm::*;
607 match variant {
608 SHA224 => oids::sha224().into(),
610 SHA256 => oids::sha256().into(),
611 SHA384 => oids::sha384().into(),
612 SHA512 => oids::sha512().into(),
613 SHA3_224 => oids::sha3_224().into(),
614 SHA3_256 => oids::sha3_256().into(),
615 SHA3_384 => oids::sha384().into(),
616 SHA3_512 => oids::sha512().into(),
617 }
618 }
619}
620
621impl TryFrom<ObjectIdentifierAsn1> for HashAlgorithm {
622 type Error = UnsupportedAlgorithmError;
623
624 fn try_from(oid: ObjectIdentifierAsn1) -> Result<Self, Self::Error> {
625 match Into::<String>::into(oid.0).as_str() {
626 oids::SHA224 => Ok(HashAlgorithm::SHA224),
628 oids::SHA256 => Ok(HashAlgorithm::SHA256),
629 oids::SHA384 => Ok(HashAlgorithm::SHA384),
630 oids::SHA512 => Ok(HashAlgorithm::SHA512),
631 oids::SHA3_224 => Ok(HashAlgorithm::SHA3_224),
632 oids::SHA3_256 => Ok(HashAlgorithm::SHA3_256),
633 oids::SHA3_384 => Ok(HashAlgorithm::SHA3_384),
634 oids::SHA3_512 => Ok(HashAlgorithm::SHA3_512),
635 unsupported => Err(UnsupportedAlgorithmError {
636 algorithm: unsupported.to_string(),
637 }),
638 }
639 }
640}
641
642impl ser::Serialize for HashAlgorithm {
643 fn serialize<S>(&self, serializer: S) -> Result<<S as ser::Serializer>::Ok, <S as ser::Serializer>::Error>
644 where
645 S: ser::Serializer,
646 {
647 use ser::SerializeSeq;
648 let mut seq = serializer.serialize_seq(Some(2))?;
649 seq.serialize_element(&ObjectIdentifierAsn1::from(self))?;
650 seq.serialize_element(&())?;
651 seq.end()
652 }
653}
654
655impl<'de> de::Deserialize<'de> for HashAlgorithm {
656 fn deserialize<D>(deserializer: D) -> Result<Self, <D as de::Deserializer<'de>>::Error>
657 where
658 D: de::Deserializer<'de>,
659 {
660 struct Visitor;
661
662 impl<'de> de::Visitor<'de> for Visitor {
663 type Value = HashAlgorithm;
664
665 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
666 formatter.write_str("a valid DER-encoded HashAlgorithm")
667 }
668
669 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
670 where
671 A: de::SeqAccess<'de>,
672 {
673 let oid: ObjectIdentifierAsn1 = seq_next_element!(seq, ObjectIdentifierAsn1, "oid of hashAlgorithm");
674 let _: Option<()> = seq.next_element()?;
675 oid.try_into().map_err(|_| {
676 serde_invalid_value!(
677 HashAlgorithm,
678 "unsupported or unknown hash algorithm",
679 "a supported hash algorithm"
680 )
681 })
682 }
683 }
684
685 deserializer.deserialize_seq(Visitor)
686 }
687}
688
689#[derive(Clone, Debug, Eq, PartialEq)]
690pub struct MaskGenAlgorithm {
691 pub mask_gen_algorithm: ObjectIdentifierAsn1,
692 pub hash_algorithm: HashAlgorithm,
693}
694
695impl MaskGenAlgorithm {
696 pub fn new(hash_algorithm: HashAlgorithm) -> Self {
697 Self {
698 mask_gen_algorithm: ObjectIdentifierAsn1::from(oids::id_mgf1()),
699 hash_algorithm,
700 }
701 }
702}
703
704impl ser::Serialize for MaskGenAlgorithm {
705 fn serialize<S>(&self, serializer: S) -> Result<<S as ser::Serializer>::Ok, <S as ser::Serializer>::Error>
706 where
707 S: ser::Serializer,
708 {
709 use ser::SerializeSeq;
710 let mut seq = serializer.serialize_seq(Some(2))?;
711 seq.serialize_element(&self.mask_gen_algorithm)?;
712 seq.serialize_element(&self.hash_algorithm)?;
713 seq.end()
714 }
715}
716
717impl<'de> de::Deserialize<'de> for MaskGenAlgorithm {
718 fn deserialize<D>(deserializer: D) -> Result<Self, <D as de::Deserializer<'de>>::Error>
719 where
720 D: de::Deserializer<'de>,
721 {
722 struct Visitor;
723
724 impl<'de> de::Visitor<'de> for Visitor {
725 type Value = MaskGenAlgorithm;
726
727 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
728 formatter.write_str("a valid DER-encoded MaskGenAlgorithm")
729 }
730
731 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
732 where
733 A: de::SeqAccess<'de>,
734 {
735 let mask_gen_algorithm: ObjectIdentifierAsn1 =
736 seq_next_element!(seq, ObjectIdentifierAsn1, "oid of maskGenAlgorithm");
737 let hash_algorithm: HashAlgorithm = seq_next_element!(seq, HashAlgorithm, "hashAlgorithm");
738 Ok(MaskGenAlgorithm {
739 mask_gen_algorithm,
740 hash_algorithm,
741 })
742 }
743 }
744
745 deserializer.deserialize_seq(Visitor)
746 }
747}
748
749#[derive(Debug, PartialEq, Eq, Clone)]
750pub enum EcParameters {
751 NamedCurve(ObjectIdentifierAsn1),
752 }
756
757impl EcParameters {
758 pub fn curve_oid(&self) -> &ObjectIdentifier {
759 match self {
760 EcParameters::NamedCurve(oid) => &oid.0,
761 }
762 }
763}
764
765impl From<ObjectIdentifierAsn1> for EcParameters {
766 fn from(oid: ObjectIdentifierAsn1) -> Self {
767 Self::NamedCurve(oid)
768 }
769}
770
771impl From<ObjectIdentifier> for EcParameters {
772 fn from(oid: ObjectIdentifier) -> Self {
773 Self::NamedCurve(oid.into())
774 }
775}
776
777impl ser::Serialize for EcParameters {
778 fn serialize<S>(&self, serializer: S) -> Result<<S as ser::Serializer>::Ok, <S as ser::Serializer>::Error>
779 where
780 S: ser::Serializer,
781 {
782 match &self {
783 EcParameters::NamedCurve(oid) => oid.serialize(serializer),
784 }
785 }
786}
787
788impl<'de> de::Deserialize<'de> for EcParameters {
789 fn deserialize<D>(deserializer: D) -> Result<Self, <D as de::Deserializer<'de>>::Error>
790 where
791 D: de::Deserializer<'de>,
792 {
793 struct Visitor;
794
795 impl<'de> de::Visitor<'de> for Visitor {
796 type Value = EcParameters;
797
798 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
799 formatter.write_str("a valid DER-encoded DirectoryString")
800 }
801
802 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
803 where
804 A: de::SeqAccess<'de>,
805 {
806 let tag_peeker: TagPeeker = seq_next_element!(seq, EcParameters, "choice tag");
807
808 let curve_oid = match tag_peeker.next_tag {
809 Tag::OID => seq_next_element!(seq, ObjectIdentifierAsn1, "NamedCurve object identifier"),
810 _ => {
811 return Err(serde_invalid_value!(
812 EcParameters,
813 "unsupported or unknown elliptic curve parameter",
814 "a supported elliptic curve parameter"
815 ));
816 }
817 };
818
819 Ok(EcParameters::NamedCurve(curve_oid))
820 }
821 }
822
823 deserializer.deserialize_enum("DirectoryString", &["NamedCurve", "ImplicitCurve"], Visitor)
824 }
825}
826
827#[derive(Clone, Copy, PartialEq, Eq, Debug)]
828pub enum AesMode {
829 Ecb,
830 Cbc,
831 Ofb,
832 Cfb,
833 Wrap,
834 Gcm,
835 Ccm,
836 WrapPad,
837}
838
839#[derive(Debug, PartialEq, Eq, Clone)]
840pub enum AesParameters {
841 Null,
842 InitializationVector(OctetStringAsn1),
843 AuthenticatedEncryptionParameters(AesAuthEncParams),
844}
845
846#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq, Clone)]
847pub struct AesAuthEncParams {
848 pub(crate) nonce: OctetStringAsn1,
849 pub(crate) icv_len: IntegerAsn1,
850}
851
852impl AesAuthEncParams {
853 pub fn new(nonce: Vec<u8>, icv_len: usize) -> Self {
854 Self {
855 nonce: OctetStringAsn1::from(nonce),
856 icv_len: IntegerAsn1::from(
857 icv_len
858 .to_be_bytes()
859 .into_iter()
861 .skip_while(|n| *n == 0)
862 .collect::<Vec<_>>(),
863 ),
864 }
865 }
866
867 pub fn nonce(&self) -> &[u8] {
868 &self.nonce.0
869 }
870
871 pub fn icv_len(&self) -> &[u8] {
872 &self.icv_len.0
873 }
874}
875
876impl AesMode {
877 fn to_128bit_oid(self) -> ObjectIdentifierAsn1 {
878 match self {
879 AesMode::Ecb => oids::aes128_ecb().into(),
880 AesMode::Cbc => oids::aes128_cbc().into(),
881 AesMode::Ofb => oids::aes128_ofb().into(),
882 AesMode::Cfb => oids::aes128_cfb().into(),
883 AesMode::Wrap => oids::aes128_wrap().into(),
884 AesMode::Gcm => oids::aes128_gcm().into(),
885 AesMode::Ccm => oids::aes128_ccm().into(),
886 AesMode::WrapPad => oids::aes128_wrap_pad().into(),
887 }
888 }
889
890 fn to_192bit_oid(self) -> ObjectIdentifierAsn1 {
891 match self {
892 AesMode::Ecb => oids::aes192_ecb().into(),
893 AesMode::Cbc => oids::aes192_cbc().into(),
894 AesMode::Ofb => oids::aes192_ofb().into(),
895 AesMode::Cfb => oids::aes192_cfb().into(),
896 AesMode::Wrap => oids::aes192_wrap().into(),
897 AesMode::Gcm => oids::aes192_gcm().into(),
898 AesMode::Ccm => oids::aes192_ccm().into(),
899 AesMode::WrapPad => oids::aes192_wrap_pad().into(),
900 }
901 }
902
903 fn to_256bit_oid(self) -> ObjectIdentifierAsn1 {
904 match self {
905 AesMode::Ecb => oids::aes256_ecb().into(),
906 AesMode::Cbc => oids::aes256_cbc().into(),
907 AesMode::Ofb => oids::aes256_ofb().into(),
908 AesMode::Cfb => oids::aes256_cfb().into(),
909 AesMode::Wrap => oids::aes256_wrap().into(),
910 AesMode::Gcm => oids::aes256_gcm().into(),
911 AesMode::Ccm => oids::aes256_ccm().into(),
912 AesMode::WrapPad => oids::aes256_wrap_pad().into(),
913 }
914 }
915}
916
917impl ser::Serialize for AesParameters {
918 fn serialize<S>(&self, serializer: S) -> Result<<S as ser::Serializer>::Ok, <S as ser::Serializer>::Error>
919 where
920 S: ser::Serializer,
921 {
922 match self {
923 AesParameters::Null => ().serialize(serializer),
924 AesParameters::InitializationVector(iv) => iv.serialize(serializer),
925 AesParameters::AuthenticatedEncryptionParameters(params) => params.serialize(serializer),
926 }
927 }
928}
929
930impl<'de> de::Deserialize<'de> for AesParameters {
931 fn deserialize<D>(deserializer: D) -> Result<Self, <D as de::Deserializer<'de>>::Error>
932 where
933 D: de::Deserializer<'de>,
934 {
935 struct Visitor;
936
937 impl<'de> de::Visitor<'de> for Visitor {
938 type Value = AesParameters;
939
940 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
941 formatter.write_str("a valid DER-encoded DirectoryString")
942 }
943
944 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
945 where
946 A: de::SeqAccess<'de>,
947 {
948 let tag_peeker: TagPeeker = seq_next_element!(seq, AesParameters, "choice tag");
949 match tag_peeker.next_tag {
950 Tag::OCTET_STRING => Ok(AesParameters::InitializationVector(seq_next_element!(
951 seq,
952 AesParameters,
953 "Object Identifier"
954 ))),
955 Tag::NULL => {
956 seq.next_element::<()>()?.expect("should not panic");
957 Ok(AesParameters::Null)
958 }
959 Tag::SEQUENCE => Ok(AesParameters::AuthenticatedEncryptionParameters(seq_next_element!(
960 seq,
961 AesAuthEncParams,
962 "AES Authenticated Encryption parameters"
963 ))),
964 _ => Err(serde_invalid_value!(
965 AesParameters,
966 "unsupported or unknown AES parameter",
967 "a supported AES parameter"
968 )),
969 }
970 }
971 }
972
973 deserializer.deserialize_enum(
974 "DirectoryString",
975 &["Null", "InitializationVector", "AuthenticatedEncryptionParameters"],
976 Visitor,
977 )
978 }
979}
980
981#[derive(Clone, Copy, PartialEq, Eq, Debug)]
982#[allow(non_camel_case_types)] pub enum ShaVariant {
984 MD5,
986 SHA1,
987 SHA2_224,
988 SHA2_256,
989 SHA2_384,
990 SHA2_512,
991 SHA2_512_224,
992 SHA2_512_256,
993 SHA3_224,
994 SHA3_256,
995 SHA3_384,
996 SHA3_512,
997 SHAKE128,
998 SHAKE256,
999}
1000
1001impl From<ShaVariant> for ObjectIdentifierAsn1 {
1002 fn from(variant: ShaVariant) -> Self {
1003 match variant {
1004 ShaVariant::MD5 => oids::md5().into(),
1005 ShaVariant::SHA1 => oids::sha1().into(),
1006 ShaVariant::SHA2_224 => oids::sha224().into(),
1007 ShaVariant::SHA2_256 => oids::sha256().into(),
1008 ShaVariant::SHA2_384 => oids::sha384().into(),
1009 ShaVariant::SHA2_512 => oids::sha512().into(),
1010 ShaVariant::SHA2_512_224 => oids::sha512_224().into(),
1011 ShaVariant::SHA2_512_256 => oids::sha512_256().into(),
1012 ShaVariant::SHA3_224 => oids::sha3_224().into(),
1013 ShaVariant::SHA3_256 => oids::sha3_256().into(),
1014 ShaVariant::SHA3_384 => oids::sha3_384().into(),
1015 ShaVariant::SHA3_512 => oids::sha3_512().into(),
1016 ShaVariant::SHAKE128 => oids::shake128().into(),
1017 ShaVariant::SHAKE256 => oids::shake256().into(),
1018 }
1019 }
1020}
1021
1022impl TryFrom<ObjectIdentifierAsn1> for ShaVariant {
1023 type Error = UnsupportedAlgorithmError;
1024
1025 fn try_from(oid: ObjectIdentifierAsn1) -> Result<Self, Self::Error> {
1026 match Into::<String>::into(oid.0).as_str() {
1027 oids::MD5 => Ok(ShaVariant::MD5),
1028 oids::SHA1 => Ok(ShaVariant::SHA1),
1029 oids::SHA224 => Ok(ShaVariant::SHA2_224),
1030 oids::SHA256 => Ok(ShaVariant::SHA2_256),
1031 oids::SHA384 => Ok(ShaVariant::SHA2_384),
1032 oids::SHA512 => Ok(ShaVariant::SHA2_512),
1033 oids::SHA512_224 => Ok(ShaVariant::SHA2_512_224),
1034 oids::SHA512_256 => Ok(ShaVariant::SHA2_512_256),
1035 oids::SHA3_224 => Ok(ShaVariant::SHA3_224),
1036 oids::SHA3_256 => Ok(ShaVariant::SHA3_256),
1037 oids::SHA3_384 => Ok(ShaVariant::SHA3_384),
1038 oids::SHA3_512 => Ok(ShaVariant::SHA3_512),
1039 oids::SHAKE128 => Ok(ShaVariant::SHAKE128),
1040 oids::SHAKE256 => Ok(ShaVariant::SHAKE256),
1041 unsupported => Err(UnsupportedAlgorithmError {
1042 algorithm: unsupported.to_string(),
1043 }),
1044 }
1045 }
1046}
1047
1048#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
1062pub struct DigestInfo {
1063 pub oid: AlgorithmIdentifier,
1064 pub digest: OctetStringAsn1,
1065}
1066
1067#[derive(Debug, Clone, PartialEq, Eq)]
1069pub struct RawAlgorithmIdentifier {
1070 algorithm: ObjectIdentifier,
1071 parameters: Option<Asn1RawDer>,
1077}
1078
1079impl RawAlgorithmIdentifier {
1080 pub fn from_parts(algorithm: ObjectIdentifier, parameters: Option<Asn1RawDer>) -> Self {
1082 let parameters = parameters.and_then(|raw| {
1083 if raw.0 == [0x05, 0x00] { None } else { Some(raw) }
1087 });
1088
1089 Self { algorithm, parameters }
1090 }
1091
1092 pub fn algorithm(&self) -> &ObjectIdentifier {
1093 &self.algorithm
1094 }
1095
1096 pub fn parameters(&self) -> Option<&Asn1RawDer> {
1097 self.parameters.as_ref()
1098 }
1099}
1100
1101impl ser::Serialize for RawAlgorithmIdentifier {
1102 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1103 where
1104 S: ser::Serializer,
1105 {
1106 use ser::SerializeSeq;
1107
1108 let mut seq = serializer.serialize_seq(Some(2))?;
1109 let oid = ObjectIdentifierAsn1(self.algorithm.clone());
1110 seq.serialize_element(&oid)?;
1111 if let Some(parameters) = &self.parameters {
1112 seq.serialize_element(parameters)?;
1113 } else {
1114 seq.serialize_element(&())?;
1116 }
1117 seq.end()
1118 }
1119}
1120
1121impl<'de> de::Deserialize<'de> for RawAlgorithmIdentifier {
1122 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1123 where
1124 D: de::Deserializer<'de>,
1125 {
1126 struct RawAlgorithmIdentifierVisitor;
1127
1128 impl<'de> de::Visitor<'de> for RawAlgorithmIdentifierVisitor {
1129 type Value = RawAlgorithmIdentifier;
1130
1131 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1132 formatter.write_str("a valid DER-encoded RawAlgorithmIdentifier")
1133 }
1134
1135 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
1136 where
1137 A: de::SeqAccess<'de>,
1138 {
1139 let oid: ObjectIdentifierAsn1 = seq_next_element!(seq, RawAlgorithmIdentifier, "raw algorithm oid");
1140
1141 let algorithm = oid.0;
1142 let parameters: Option<Asn1RawDer> = seq.next_element::<Asn1RawDer>()?;
1143 Ok(RawAlgorithmIdentifier::from_parts(algorithm, parameters))
1144 }
1145 }
1146
1147 deserializer.deserialize_seq(RawAlgorithmIdentifierVisitor)
1148 }
1149}
1150
1151#[cfg(test)]
1152mod tests {
1153 use super::*;
1154 use base64::Engine as _;
1155 use base64::engine::general_purpose;
1156
1157 #[test]
1158 fn aes_null_params() {
1159 let expected = [48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 1, 1, 5, 0];
1160 let aes_id = AlgorithmIdentifier::new_aes128(AesMode::Ecb, AesParameters::Null);
1161 check_serde!(aes_id: AlgorithmIdentifier in expected);
1162 }
1163
1164 #[test]
1165 fn aes_iv_params() {
1166 let expected = [
1167 48, 25, 6, 9, 96, 134, 72, 1, 101, 3, 4, 1, 1, 4, 12, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
1168 165, 165,
1169 ];
1170 let aes_id =
1171 AlgorithmIdentifier::new_aes128(AesMode::Ecb, AesParameters::InitializationVector(vec![0xA5; 12].into()));
1172 check_serde!(aes_id: AlgorithmIdentifier in expected);
1173 }
1174
1175 #[test]
1176 fn aes_ae_params() {
1177 let expected = [
1178 48, 30, 6, 9, 96, 134, 72, 1, 101, 3, 4, 1, 1, 48, 17, 4, 12, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1179 255, 255, 255, 2, 1, 12,
1180 ];
1181 let aes_id = AlgorithmIdentifier::new_aes128(
1182 AesMode::Ecb,
1183 AesParameters::AuthenticatedEncryptionParameters(AesAuthEncParams {
1184 nonce: vec![0xff; 12].into(),
1185 icv_len: vec![12].into(),
1186 }),
1187 );
1188 check_serde!(aes_id: AlgorithmIdentifier in expected);
1189 }
1190
1191 #[test]
1192 fn sha256() {
1193 let expected = [48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 5, 0];
1194 let sha = AlgorithmIdentifier::new_sha(ShaVariant::SHA2_256);
1195 check_serde!(sha: AlgorithmIdentifier in expected);
1196 }
1197
1198 #[test]
1199 fn sha3_256() {
1200 let expected = [
1201 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x08, 0x05, 0x00,
1202 ];
1203 let sha = AlgorithmIdentifier::new_sha(ShaVariant::SHA3_256);
1204 check_serde!(sha: AlgorithmIdentifier in expected);
1205 }
1206
1207 #[test]
1208 fn rsa_enc_with_sha3_256() {
1209 let expected = [
1210 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x0e, 0x05, 0x00,
1211 ];
1212 let sha = AlgorithmIdentifier::new_sha3_256_with_rsa_encryption();
1213 check_serde!(sha: AlgorithmIdentifier in expected);
1214 }
1215
1216 #[test]
1217 fn ecdsa_with_sha3_512() {
1218 let expected = [
1219 0x30, 0x0B, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x0C,
1220 ];
1221 let sha = AlgorithmIdentifier::new_ecdsa_with_sha3_512();
1222 check_serde!(sha: AlgorithmIdentifier in expected);
1223 }
1224
1225 #[test]
1226 fn ec_params() {
1227 let expected = [
1228 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 4, 3, 2,
1229 ];
1230 let ec_params =
1231 AlgorithmIdentifier::new_elliptic_curve(EcParameters::NamedCurve(oids::ecdsa_with_sha256().into()));
1232 check_serde!(ec_params: AlgorithmIdentifier in expected);
1233 }
1234
1235 #[test]
1236 fn digest_info() {
1237 let digest = picky_asn1_der::to_vec(&DigestInfo {
1238 oid: AlgorithmIdentifier::new_sha(ShaVariant::SHA2_256),
1239 digest: vec![
1241 0xf4, 0x12, 0x6b, 0x55, 0xbf, 0xcf, 0x8c, 0xc4, 0xe9, 0xe0, 0xbe, 0x5a, 0x9c, 0x16, 0x88, 0x55, 0x0f,
1242 0x26, 0x00, 0x8c, 0x2c, 0xa5, 0xf6, 0xaf, 0xbd, 0xe7, 0x9c, 0x42, 0x22, 0xe9, 0x25, 0xed,
1243 ]
1244 .into(),
1245 })
1246 .unwrap();
1247
1248 let expected = vec![
1249 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04,
1250 0x20, 0xf4, 0x12, 0x6b, 0x55, 0xbf, 0xcf, 0x8c, 0xc4, 0xe9, 0xe0, 0xbe, 0x5a, 0x9c, 0x16, 0x88, 0x55, 0x0f,
1251 0x26, 0x00, 0x8c, 0x2c, 0xa5, 0xf6, 0xaf, 0xbd, 0xe7, 0x9c, 0x42, 0x22, 0xe9, 0x25, 0xed,
1252 ];
1253
1254 assert_eq!(digest, expected);
1255 }
1256
1257 #[test]
1258 fn rsa_pss_params_sha256() {
1259 let expected = [
1260 0x30, 0x34, 0xa0, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
1261 0x00, 0xa1, 0x1c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0d,
1262 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa2, 0x03, 0x02, 0x01, 0x20,
1263 ];
1264 let structure = RsassaPssParams::new(HashAlgorithm::SHA256);
1265 check_serde!(structure: RsassaPssParams in expected);
1266 }
1267
1268 #[test]
1269 fn rsa_pss_params_sha384() {
1270 let expected = [
1271 0x30, 0x34, 0xa0, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05,
1272 0x00, 0xa1, 0x1c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0d,
1273 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0xa2, 0x03, 0x02, 0x01, 0x30,
1274 ];
1275 let structure = RsassaPssParams::new(HashAlgorithm::SHA384);
1276 check_serde!(structure: RsassaPssParams in expected);
1277 }
1278
1279 #[test]
1280 fn rsa_pss_params_sha512() {
1281 let expected = [
1282 0x30, 0x34, 0xa0, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
1283 0x00, 0xa1, 0x1c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0d,
1284 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0xa2, 0x03, 0x02, 0x01, 0x40,
1285 ];
1286 let structure = RsassaPssParams::new(HashAlgorithm::SHA512);
1287 check_serde!(structure: RsassaPssParams in expected);
1288 }
1289
1290 #[test]
1291 fn rsa_pss_encryption() {
1292 let expected = [
1293 0x30, 0x41, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0A, 0x30, 0x34, 0xa0, 0x0f, 0x30,
1294 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa1, 0x1c, 0x30, 0x1a,
1295 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
1296 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa2, 0x03, 0x02, 0x01, 0x20,
1297 ];
1298 let structure = AlgorithmIdentifier::new_rsassa_pss(RsassaPssParams::new(HashAlgorithm::SHA256));
1299 check_serde!(structure: AlgorithmIdentifier in expected);
1300 }
1301
1302 #[test]
1303 fn rsa_encryption() {
1304 let expected = [
1305 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00,
1306 ];
1307 let rsa_encryption = AlgorithmIdentifier::new_rsa_encryption();
1308 check_serde!(rsa_encryption: AlgorithmIdentifier in expected);
1309 }
1310
1311 #[test]
1312 fn rsa_encryption_with_missing_params() {
1313 let encoded = [
1314 0x30, 0x0B, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01,
1315 ];
1316 let deserialized: AlgorithmIdentifier =
1317 picky_asn1_der::from_bytes(&encoded).expect("failed AlgorithmIdentifier deserialization");
1318 pretty_assertions::assert_eq!(
1319 deserialized,
1320 AlgorithmIdentifier::new_rsa_encryption(),
1321 concat!("deserialized ", stringify!($item), " doesn't match")
1322 );
1323 }
1324
1325 #[test]
1326 fn raw_algorithm_roundtrip_no_params() {
1327 let encoded = [
1328 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x09, 0x05, 0x00,
1329 ];
1330 let decoded: RawAlgorithmIdentifier = picky_asn1_der::from_bytes(&encoded).unwrap();
1331 let expected = RawAlgorithmIdentifier::from_parts(oids::hmac_with_sha256(), None);
1332 pretty_assertions::assert_eq!(decoded, expected);
1333 check_serde!(decoded: RawAlgorithmIdentifier in encoded);
1334 }
1335
1336 #[test]
1337 fn raw_algorithm_roundtrip() {
1338 let encoded = [
1339 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x0F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x6D, 0x65, 0x64, 0x69,
1340 0x61, 0x74, 0x65, 0x5F, 0x63, 0x61,
1341 ];
1342 let decoded: RawAlgorithmIdentifier = picky_asn1_der::from_bytes(&encoded).unwrap();
1343 let oid: ObjectIdentifier = "2.5.4.3".to_string().try_into().unwrap();
1344 let params = Asn1RawDer(vec![
1345 0x0C, 0x0F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x6D, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5F, 0x63, 0x61,
1346 ]);
1347 let expected = RawAlgorithmIdentifier::from_parts(oid, Some(params));
1348 pretty_assertions::assert_eq!(decoded, expected);
1349 check_serde!(decoded: RawAlgorithmIdentifier in encoded);
1350 }
1351
1352 #[test]
1353 fn mldsa_44() {
1354 let expected = [
1355 0x30, 0x0B, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x11,
1356 ];
1357 let mldsa = AlgorithmIdentifier::new_mldsa_44();
1358 check_serde!(mldsa: AlgorithmIdentifier in expected);
1359 }
1360
1361 #[test]
1362 fn mldsa_65() {
1363 let expected = [
1364 0x30, 0x0B, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x12,
1365 ];
1366 let mldsa = AlgorithmIdentifier::new_mldsa_65();
1367 check_serde!(mldsa: AlgorithmIdentifier in expected);
1368 }
1369
1370 #[test]
1371 fn mldsa_87() {
1372 let expected = [
1373 0x30, 0x0B, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x13,
1374 ];
1375 let mldsa = AlgorithmIdentifier::new_mldsa_87();
1376 check_serde!(mldsa: AlgorithmIdentifier in expected);
1377 }
1378}