1 use crate::oids;
2 use oid::ObjectIdentifier;
3 use picky_asn1::tag::{Tag, TagPeeker};
4 use picky_asn1::wrapper::{IntegerAsn1, ObjectIdentifierAsn1, OctetStringAsn1};
5 use serde::{de, ser, Deserialize, Serialize};
6 use std::fmt;
7 
8 #[derive(Debug, PartialEq, Clone)]
9 pub struct AlgorithmIdentifier {
10     algorithm: ObjectIdentifierAsn1,
11     parameters: AlgorithmIdentifierParameters,
12 }
13 
14 impl AlgorithmIdentifier {
oid(&self) -> &ObjectIdentifier15     pub fn oid(&self) -> &ObjectIdentifier {
16         &self.algorithm.0
17     }
18 
parameters(&self) -> &AlgorithmIdentifierParameters19     pub fn parameters(&self) -> &AlgorithmIdentifierParameters {
20         &self.parameters
21     }
22 
is_a(&self, algorithm: ObjectIdentifier) -> bool23     pub fn is_a(&self, algorithm: ObjectIdentifier) -> bool {
24         algorithm.eq(&self.algorithm.0)
25     }
26 
new_sha1_with_rsa_encryption() -> Self27     pub fn new_sha1_with_rsa_encryption() -> Self {
28         Self {
29             algorithm: oids::sha1_with_rsa_encryption().into(),
30             parameters: AlgorithmIdentifierParameters::Null,
31         }
32     }
33 
new_sha224_with_rsa_encryption() -> Self34     pub fn new_sha224_with_rsa_encryption() -> Self {
35         Self {
36             algorithm: oids::sha224_with_rsa_encryption().into(),
37             parameters: AlgorithmIdentifierParameters::Null,
38         }
39     }
40 
new_sha256_with_rsa_encryption() -> Self41     pub fn new_sha256_with_rsa_encryption() -> Self {
42         Self {
43             algorithm: oids::sha256_with_rsa_encryption().into(),
44             parameters: AlgorithmIdentifierParameters::Null,
45         }
46     }
47 
new_sha384_with_rsa_encryption() -> Self48     pub fn new_sha384_with_rsa_encryption() -> Self {
49         Self {
50             algorithm: oids::sha384_with_rsa_encryption().into(),
51             parameters: AlgorithmIdentifierParameters::Null,
52         }
53     }
54 
new_sha512_with_rsa_encryption() -> Self55     pub fn new_sha512_with_rsa_encryption() -> Self {
56         Self {
57             algorithm: oids::sha512_with_rsa_encryption().into(),
58             parameters: AlgorithmIdentifierParameters::Null,
59         }
60     }
61 
new_sha3_384_with_rsa_encryption() -> Self62     pub fn new_sha3_384_with_rsa_encryption() -> Self {
63         Self {
64             algorithm: oids::id_rsassa_pkcs1_v1_5_with_sha3_384().into(),
65             parameters: AlgorithmIdentifierParameters::Null,
66         }
67     }
68 
new_sha3_512_with_rsa_encryption() -> Self69     pub fn new_sha3_512_with_rsa_encryption() -> Self {
70         Self {
71             algorithm: oids::id_rsassa_pkcs1_v1_5_with_sha3_512().into(),
72             parameters: AlgorithmIdentifierParameters::Null,
73         }
74     }
75 
new_rsa_encryption() -> Self76     pub fn new_rsa_encryption() -> Self {
77         Self {
78             algorithm: oids::rsa_encryption().into(),
79             parameters: AlgorithmIdentifierParameters::Null,
80         }
81     }
82 
new_ecdsa_with_sha384() -> Self83     pub fn new_ecdsa_with_sha384() -> Self {
84         Self {
85             algorithm: oids::ecdsa_with_sha384().into(),
86             parameters: AlgorithmIdentifierParameters::None,
87         }
88     }
89 
new_ecdsa_with_sha256() -> Self90     pub fn new_ecdsa_with_sha256() -> Self {
91         Self {
92             algorithm: oids::ecdsa_with_sha256().into(),
93             parameters: AlgorithmIdentifierParameters::None,
94         }
95     }
96 
new_elliptic_curve<P: Into<ECParameters>>(ec_params: P) -> Self97     pub fn new_elliptic_curve<P: Into<ECParameters>>(ec_params: P) -> Self {
98         Self {
99             algorithm: oids::ec_public_key().into(),
100             parameters: AlgorithmIdentifierParameters::EC(ec_params.into()),
101         }
102     }
103 
new_ed25519() -> Self104     pub fn new_ed25519() -> Self {
105         Self {
106             algorithm: oids::ed25519().into(),
107             parameters: AlgorithmIdentifierParameters::None,
108         }
109     }
110 
new_aes128(mode: AesMode, params: AESParameters) -> Self111     pub fn new_aes128(mode: AesMode, params: AESParameters) -> Self {
112         Self {
113             algorithm: mode.to_128bit_oid(),
114             parameters: AlgorithmIdentifierParameters::AES(params),
115         }
116     }
117 
new_aes192(mode: AesMode, params: AESParameters) -> Self118     pub fn new_aes192(mode: AesMode, params: AESParameters) -> Self {
119         Self {
120             algorithm: mode.to_192bit_oid(),
121             parameters: AlgorithmIdentifierParameters::AES(params),
122         }
123     }
124 
new_aes256(mode: AesMode, params: AESParameters) -> Self125     pub fn new_aes256(mode: AesMode, params: AESParameters) -> Self {
126         Self {
127             algorithm: mode.to_256bit_oid(),
128             parameters: AlgorithmIdentifierParameters::AES(params),
129         }
130     }
131 
new_sha(variant: SHAVariant) -> Self132     pub fn new_sha(variant: SHAVariant) -> Self {
133         Self {
134             algorithm: variant.into(),
135             parameters: AlgorithmIdentifierParameters::Null,
136         }
137     }
138 }
139 
140 impl ser::Serialize for AlgorithmIdentifier {
serialize<S>(&self, serializer: S) -> Result<<S as ser::Serializer>::Ok, <S as ser::Serializer>::Error> where S: ser::Serializer,141     fn serialize<S>(&self, serializer: S) -> Result<<S as ser::Serializer>::Ok, <S as ser::Serializer>::Error>
142     where
143         S: ser::Serializer,
144     {
145         use ser::SerializeSeq;
146         let mut seq = serializer.serialize_seq(Some(2))?;
147         seq.serialize_element(&self.algorithm)?;
148         match &self.parameters {
149             AlgorithmIdentifierParameters::None => {}
150             AlgorithmIdentifierParameters::Null => {
151                 seq.serialize_element(&())?;
152             }
153             AlgorithmIdentifierParameters::EC(ec_params) => {
154                 seq.serialize_element(ec_params)?;
155             }
156             AlgorithmIdentifierParameters::AES(aes_params) => {
157                 seq.serialize_element(aes_params)?;
158             }
159         }
160         seq.end()
161     }
162 }
163 
164 impl<'de> de::Deserialize<'de> for AlgorithmIdentifier {
deserialize<D>(deserializer: D) -> Result<Self, <D as de::Deserializer<'de>>::Error> where D: de::Deserializer<'de>,165     fn deserialize<D>(deserializer: D) -> Result<Self, <D as de::Deserializer<'de>>::Error>
166     where
167         D: de::Deserializer<'de>,
168     {
169         struct Visitor;
170 
171         impl<'de> de::Visitor<'de> for Visitor {
172             type Value = AlgorithmIdentifier;
173 
174             fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
175                 formatter.write_str("a valid DER-encoded algorithm identifier")
176             }
177 
178             fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
179             where
180                 A: de::SeqAccess<'de>,
181             {
182                 let oid: ObjectIdentifierAsn1 = seq_next_element!(seq, AlgorithmIdentifier, "algorithm oid");
183 
184                 let args = match Into::<String>::into(&oid.0).as_str() {
185                     oids::RSA_ENCRYPTION
186                     | oids::SHA1_WITH_RSA_ENCRYPTION
187                     | oids::SHA224_WITH_RSA_ENCRYPTION
188                     | oids::SHA256_WITH_RSA_ENCRYPTION
189                     | oids::SHA384_WITH_RSA_ENCRYPTION
190                     | oids::SHA512_WITH_RSA_ENCRYPTION => {
191                         // Try to deserialize next element in sequence.
192                         // Error is ignored because some implementations just leave no parameter at all for
193                         // RSA encryption (ie: rsa-export-0.1.1 crate) but we still want to be able
194                         // to parse their output.
195                         let _ = seq.next_element::<()>();
196                         AlgorithmIdentifierParameters::Null
197                     }
198                     oids::ECDSA_WITH_SHA384 | oids::ECDSA_WITH_SHA256 | oids::ED25519 => {
199                         AlgorithmIdentifierParameters::None
200                     }
201                     oids::EC_PUBLIC_KEY => AlgorithmIdentifierParameters::EC(seq_next_element!(
202                         seq,
203                         AlgorithmIdentifier,
204                         "elliptic curves parameters"
205                     )),
206                     // AES
207                     x if x.starts_with("2.16.840.1.101.3.4.1.") => AlgorithmIdentifierParameters::AES(
208                         seq_next_element!(seq, AlgorithmIdentifier, "aes algorithm identifier"),
209                     ),
210                     // SHA
211                     x if x.starts_with("2.16.840.1.101.3.4.2.") => {
212                         seq_next_element!(seq, AlgorithmIdentifier, "sha algorithm identifier");
213                         AlgorithmIdentifierParameters::Null
214                     }
215                     _ => {
216                         return Err(serde_invalid_value!(
217                             AlgorithmIdentifier,
218                             "unsupported algorithm (unknown oid)",
219                             "a supported algorithm"
220                         ));
221                     }
222                 };
223 
224                 Ok(AlgorithmIdentifier {
225                     algorithm: oid,
226                     parameters: args,
227                 })
228             }
229         }
230 
231         deserializer.deserialize_seq(Visitor)
232     }
233 }
234 
235 #[derive(Debug, PartialEq, Clone)]
236 pub enum AlgorithmIdentifierParameters {
237     None,
238     Null,
239     AES(AESParameters),
240     EC(ECParameters),
241 }
242 
243 #[derive(Debug, PartialEq, Clone)]
244 pub enum ECParameters {
245     NamedCurve(ObjectIdentifierAsn1),
246     ImplicitCurve,
247     //SpecifiedCurve(SpecifiedECDomain) // see [X9.62]
248 }
249 
250 impl From<ObjectIdentifierAsn1> for ECParameters {
from(oid: ObjectIdentifierAsn1) -> Self251     fn from(oid: ObjectIdentifierAsn1) -> Self {
252         Self::NamedCurve(oid)
253     }
254 }
255 
256 impl From<ObjectIdentifier> for ECParameters {
from(oid: ObjectIdentifier) -> Self257     fn from(oid: ObjectIdentifier) -> Self {
258         Self::NamedCurve(oid.into())
259     }
260 }
261 
262 impl From<()> for ECParameters {
from(_: ()) -> Self263     fn from(_: ()) -> Self {
264         Self::ImplicitCurve
265     }
266 }
267 
268 impl ser::Serialize for ECParameters {
serialize<S>(&self, serializer: S) -> Result<<S as ser::Serializer>::Ok, <S as ser::Serializer>::Error> where S: ser::Serializer,269     fn serialize<S>(&self, serializer: S) -> Result<<S as ser::Serializer>::Ok, <S as ser::Serializer>::Error>
270     where
271         S: ser::Serializer,
272     {
273         match &self {
274             ECParameters::NamedCurve(oid) => oid.serialize(serializer),
275             ECParameters::ImplicitCurve => ().serialize(serializer),
276         }
277     }
278 }
279 
280 impl<'de> de::Deserialize<'de> for ECParameters {
deserialize<D>(deserializer: D) -> Result<Self, <D as de::Deserializer<'de>>::Error> where D: de::Deserializer<'de>,281     fn deserialize<D>(deserializer: D) -> Result<Self, <D as de::Deserializer<'de>>::Error>
282     where
283         D: de::Deserializer<'de>,
284     {
285         struct Visitor;
286 
287         impl<'de> de::Visitor<'de> for Visitor {
288             type Value = ECParameters;
289 
290             fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
291                 formatter.write_str("a valid DER-encoded DirectoryString")
292             }
293 
294             fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
295             where
296                 A: de::SeqAccess<'de>,
297             {
298                 let tag_peeker: TagPeeker = seq_next_element!(seq, ECParameters, "choice tag");
299                 match tag_peeker.next_tag {
300                     Tag::OID => Ok(ECParameters::NamedCurve(seq_next_element!(
301                         seq,
302                         ECParameters,
303                         "Object Identifier"
304                     ))),
305                     Tag::NULL => {
306                         seq.next_element::<()>()?.expect("should not panic");
307                         Ok(ECParameters::ImplicitCurve)
308                     }
309                     _ => Err(serde_invalid_value!(
310                         ECParameters,
311                         "unsupported or unknown elliptic curve parameter",
312                         "a supported elliptic curve parameter"
313                     )),
314                 }
315             }
316         }
317 
318         deserializer.deserialize_enum("DirectoryString", &["NamedCurve", "ImplicitCurve"], Visitor)
319     }
320 }
321 
322 #[derive(Clone, Copy, PartialEq, Debug)]
323 pub enum AesMode {
324     ECB,
325     CBC,
326     OFB,
327     CFB,
328     Wrap,
329     GCM,
330     CCM,
331     WrapPad,
332 }
333 
334 #[derive(Debug, PartialEq, Clone)]
335 pub enum AESParameters {
336     Null,
337     InitializationVector(OctetStringAsn1),
338     AuthenticatedEncryptionParameters(AesAuthEncParams),
339 }
340 
341 #[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone)]
342 pub struct AesAuthEncParams {
343     nonce: OctetStringAsn1,
344     icv_len: IntegerAsn1,
345 }
346 
347 impl AesMode {
to_128bit_oid(self) -> ObjectIdentifierAsn1348     fn to_128bit_oid(self) -> ObjectIdentifierAsn1 {
349         match self {
350             AesMode::ECB => oids::aes128_ecb().into(),
351             AesMode::CBC => oids::aes128_cbc().into(),
352             AesMode::OFB => oids::aes128_ofb().into(),
353             AesMode::CFB => oids::aes128_cfb().into(),
354             AesMode::Wrap => oids::aes128_wrap().into(),
355             AesMode::GCM => oids::aes128_gcm().into(),
356             AesMode::CCM => oids::aes128_ccm().into(),
357             AesMode::WrapPad => oids::aes128_wrap_pad().into(),
358         }
359     }
360 
to_192bit_oid(self) -> ObjectIdentifierAsn1361     fn to_192bit_oid(self) -> ObjectIdentifierAsn1 {
362         match self {
363             AesMode::ECB => oids::aes192_ecb().into(),
364             AesMode::CBC => oids::aes192_cbc().into(),
365             AesMode::OFB => oids::aes192_ofb().into(),
366             AesMode::CFB => oids::aes192_cfb().into(),
367             AesMode::Wrap => oids::aes192_wrap().into(),
368             AesMode::GCM => oids::aes192_gcm().into(),
369             AesMode::CCM => oids::aes192_ccm().into(),
370             AesMode::WrapPad => oids::aes192_wrap_pad().into(),
371         }
372     }
373 
to_256bit_oid(self) -> ObjectIdentifierAsn1374     fn to_256bit_oid(self) -> ObjectIdentifierAsn1 {
375         match self {
376             AesMode::ECB => oids::aes256_ecb().into(),
377             AesMode::CBC => oids::aes256_cbc().into(),
378             AesMode::OFB => oids::aes256_ofb().into(),
379             AesMode::CFB => oids::aes256_cfb().into(),
380             AesMode::Wrap => oids::aes256_wrap().into(),
381             AesMode::GCM => oids::aes256_gcm().into(),
382             AesMode::CCM => oids::aes256_ccm().into(),
383             AesMode::WrapPad => oids::aes256_wrap_pad().into(),
384         }
385     }
386 }
387 
388 impl ser::Serialize for AESParameters {
serialize<S>(&self, serializer: S) -> Result<<S as ser::Serializer>::Ok, <S as ser::Serializer>::Error> where S: ser::Serializer,389     fn serialize<S>(&self, serializer: S) -> Result<<S as ser::Serializer>::Ok, <S as ser::Serializer>::Error>
390     where
391         S: ser::Serializer,
392     {
393         match self {
394             AESParameters::Null => ().serialize(serializer),
395             AESParameters::InitializationVector(iv) => iv.serialize(serializer),
396             AESParameters::AuthenticatedEncryptionParameters(params) => params.serialize(serializer),
397         }
398     }
399 }
400 
401 impl<'de> de::Deserialize<'de> for AESParameters {
deserialize<D>(deserializer: D) -> Result<Self, <D as de::Deserializer<'de>>::Error> where D: de::Deserializer<'de>,402     fn deserialize<D>(deserializer: D) -> Result<Self, <D as de::Deserializer<'de>>::Error>
403     where
404         D: de::Deserializer<'de>,
405     {
406         struct Visitor;
407 
408         impl<'de> de::Visitor<'de> for Visitor {
409             type Value = AESParameters;
410 
411             fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
412                 formatter.write_str("a valid DER-encoded DirectoryString")
413             }
414 
415             fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
416             where
417                 A: de::SeqAccess<'de>,
418             {
419                 let tag_peeker: TagPeeker = seq_next_element!(seq, AESParameters, "choice tag");
420                 match tag_peeker.next_tag {
421                     Tag::OCTET_STRING => Ok(AESParameters::InitializationVector(seq_next_element!(
422                         seq,
423                         AESParameters,
424                         "Object Identifier"
425                     ))),
426                     Tag::NULL => {
427                         seq.next_element::<()>()?.expect("should not panic");
428                         Ok(AESParameters::Null)
429                     }
430                     Tag::SEQUENCE => Ok(AESParameters::AuthenticatedEncryptionParameters(seq_next_element!(
431                         seq,
432                         AesAuthEncParams,
433                         "AES Authenticated Encryption parameters"
434                     ))),
435                     _ => Err(serde_invalid_value!(
436                         AESParameters,
437                         "unsupported or unknown AES parameter",
438                         "a supported AES parameter"
439                     )),
440                 }
441             }
442         }
443 
444         deserializer.deserialize_enum(
445             "DirectoryString",
446             &["Null", "InitializationVector", "AuthenticatedEncryptionParameters"],
447             Visitor,
448         )
449     }
450 }
451 
452 #[derive(Clone, Copy, PartialEq, Debug)]
453 #[allow(non_camel_case_types)] // 'SHA2_512_224' is clearer than 'SHA2512224' or 'Sha2512224' imo
454 pub enum SHAVariant {
455     SHA2_224,
456     SHA2_256,
457     SHA2_384,
458     SHA2_512,
459     SHA2_512_224,
460     SHA2_512_256,
461     SHA3_224,
462     SHA3_256,
463     SHA3_384,
464     SHA3_512,
465     SHAKE128,
466     SHAKE256,
467 }
468 
469 impl From<SHAVariant> for ObjectIdentifierAsn1 {
from(variant: SHAVariant) -> Self470     fn from(variant: SHAVariant) -> Self {
471         match variant {
472             SHAVariant::SHA2_224 => oids::sha224().into(),
473             SHAVariant::SHA2_256 => oids::sha256().into(),
474             SHAVariant::SHA2_384 => oids::sha384().into(),
475             SHAVariant::SHA2_512 => oids::sha512().into(),
476             SHAVariant::SHA2_512_224 => oids::sha512_224().into(),
477             SHAVariant::SHA2_512_256 => oids::sha512_256().into(),
478             SHAVariant::SHA3_224 => oids::sha3_224().into(),
479             SHAVariant::SHA3_256 => oids::sha3_256().into(),
480             SHAVariant::SHA3_384 => oids::sha3_384().into(),
481             SHAVariant::SHA3_512 => oids::sha3_512().into(),
482             SHAVariant::SHAKE128 => oids::shake128().into(),
483             SHAVariant::SHAKE256 => oids::shake256().into(),
484         }
485     }
486 }
487 
488 /// [PKCS #1: RSA Cryptography Specifications Version
489 /// 2.2](https://tools.ietf.org/html/rfc8017.html#section-9.2)
490 ///
491 /// # Section 9.2
492 ///
493 /// The type DigestInfo has the syntax:
494 ///
495 /// ```not_rust
496 ///    DigestInfo ::= SEQUENCE {
497 ///        digestAlgorithm AlgorithmIdentifier,
498 ///        digest OCTET STRING
499 ///    }
500 /// ```
501 #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
502 pub struct DigestInfo {
503     pub oid: AlgorithmIdentifier,
504     pub digest: OctetStringAsn1,
505 }
506 
507 #[cfg(test)]
508 mod tests {
509     use super::*;
510 
511     #[test]
aes_null_params()512     fn aes_null_params() {
513         let expected = [48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 1, 1, 5, 0];
514         let aes_id = AlgorithmIdentifier::new_aes128(AesMode::ECB, AESParameters::Null);
515         check_serde!(aes_id: AlgorithmIdentifier in expected);
516     }
517 
518     #[test]
aes_iv_params()519     fn aes_iv_params() {
520         let expected = [
521             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,
522             165, 165,
523         ];
524         let aes_id =
525             AlgorithmIdentifier::new_aes128(AesMode::ECB, AESParameters::InitializationVector(vec![0xA5; 12].into()));
526         check_serde!(aes_id: AlgorithmIdentifier in expected);
527     }
528 
529     #[test]
aes_ae_params()530     fn aes_ae_params() {
531         let expected = [
532             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,
533             255, 255, 255, 2, 1, 12,
534         ];
535         let aes_id = AlgorithmIdentifier::new_aes128(
536             AesMode::ECB,
537             AESParameters::AuthenticatedEncryptionParameters(AesAuthEncParams {
538                 nonce: vec![0xff; 12].into(),
539                 icv_len: vec![12].into(),
540             }),
541         );
542         check_serde!(aes_id: AlgorithmIdentifier in expected);
543     }
544 
545     #[test]
sha256()546     fn sha256() {
547         let expected = [48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 5, 0];
548         let sha = AlgorithmIdentifier::new_sha(SHAVariant::SHA2_256);
549         check_serde!(sha: AlgorithmIdentifier in expected);
550     }
551 
552     #[test]
ec_params()553     fn ec_params() {
554         let expected = [
555             48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206, 61, 4, 3, 2,
556         ];
557         let ec_params =
558             AlgorithmIdentifier::new_elliptic_curve(ECParameters::NamedCurve(oids::ecdsa_with_sha256().into()));
559         check_serde!(ec_params: AlgorithmIdentifier in expected);
560     }
561 
562     #[test]
digest_info()563     fn digest_info() {
564         let digest = picky_asn1_der::to_vec(&DigestInfo {
565             oid: AlgorithmIdentifier::new_sha(SHAVariant::SHA2_256),
566             // Random 32 bytes generated for a SHA256 hash
567             digest: vec![
568                 0xf4, 0x12, 0x6b, 0x55, 0xbf, 0xcf, 0x8c, 0xc4, 0xe9, 0xe0, 0xbe, 0x5a, 0x9c, 0x16, 0x88, 0x55, 0x0f,
569                 0x26, 0x00, 0x8c, 0x2c, 0xa5, 0xf6, 0xaf, 0xbd, 0xe7, 0x9c, 0x42, 0x22, 0xe9, 0x25, 0xed,
570             ]
571             .into(),
572         })
573         .unwrap();
574 
575         let expected = vec![
576             0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04,
577             0x20, 0xf4, 0x12, 0x6b, 0x55, 0xbf, 0xcf, 0x8c, 0xc4, 0xe9, 0xe0, 0xbe, 0x5a, 0x9c, 0x16, 0x88, 0x55, 0x0f,
578             0x26, 0x00, 0x8c, 0x2c, 0xa5, 0xf6, 0xaf, 0xbd, 0xe7, 0x9c, 0x42, 0x22, 0xe9, 0x25, 0xed,
579         ];
580 
581         assert_eq!(digest, expected);
582     }
583 
584     #[test]
rsa_encryption()585     fn rsa_encryption() {
586         let expected = [
587             0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00,
588         ];
589         let rsa_encryption = AlgorithmIdentifier::new_rsa_encryption();
590         check_serde!(rsa_encryption: AlgorithmIdentifier in expected);
591     }
592 
593     #[test]
rsa_encryption_with_missing_params()594     fn rsa_encryption_with_missing_params() {
595         let encoded = [
596             0x30, 0x0B, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01,
597         ];
598         let deserialized: AlgorithmIdentifier =
599             picky_asn1_der::from_bytes(&encoded).expect("failed AlgorithmIdentifier deserialization");
600         pretty_assertions::assert_eq!(
601             deserialized,
602             AlgorithmIdentifier::new_rsa_encryption(),
603             concat!("deserialized ", stringify!($item), " doesn't match")
604         );
605     }
606 }
607