• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use chrono::offset::{TimeZone, Utc};
2 use chrono::Datelike;
3 use der_parser::oid;
4 use nom::Parser;
5 use oid_registry::*;
6 use std::collections::HashMap;
7 use x509_parser::prelude::*;
8 
9 static IGCA_DER: &[u8] = include_bytes!("../assets/IGC_A.der");
10 static NO_EXTENSIONS_DER: &[u8] = include_bytes!("../assets/no_extensions.der");
11 static V1: &[u8] = include_bytes!("../assets/v1.der");
12 static CRL_DER: &[u8] = include_bytes!("../assets/example.crl");
13 static EMPTY_CRL_DER: &[u8] = include_bytes!("../assets/empty.crl");
14 static MINIMAL_CRL_DER: &[u8] = include_bytes!("../assets/minimal.crl");
15 static DUPLICATE_VALUE_IN_AIA: &[u8] =
16     include_bytes!("../assets/duplicate_value_in_authority_info_access.der");
17 
18 #[test]
test_x509_parser()19 fn test_x509_parser() {
20     let empty = &b""[..];
21     //assert_eq!(x509_parser(IGCA_DER), IResult::Done(empty, (1)));
22     let res = parse_x509_certificate(IGCA_DER);
23     // println!("res: {:?}", res);
24     match res {
25         Ok((e, cert)) => {
26             assert_eq!(e, empty);
27             //
28             let tbs_cert = &cert.tbs_certificate;
29             assert_eq!(tbs_cert.version, X509Version::V3);
30             //
31             let s = tbs_cert.raw_serial_as_string();
32             assert_eq!(&s, "39:11:45:10:94");
33             //
34             let expected_subject = "C=FR, ST=France, L=Paris, O=PM/SGDN, OU=DCSSI, CN=IGC/A, Email=igca@sgdn.pm.gouv.fr";
35             assert_eq!(format!("{}", tbs_cert.subject), expected_subject);
36             //
37             let cn_list: Result<Vec<_>, X509Error> = cert
38                 .subject()
39                 .iter_common_name()
40                 .map(|attr| attr.as_str())
41                 .collect();
42             assert_eq!(cn_list, Ok(vec!["IGC/A"]));
43             //
44             let sig = &tbs_cert.signature;
45             assert_eq!(sig.algorithm, oid!(1.2.840 .113549 .1 .1 .5));
46             //
47             let expected_issuer = "C=FR, ST=France, L=Paris, O=PM/SGDN, OU=DCSSI, CN=IGC/A, Email=igca@sgdn.pm.gouv.fr";
48             assert_eq!(format!("{}", tbs_cert.issuer), expected_issuer);
49             let expected_issuer_der = &IGCA_DER[35..171];
50             assert_eq!(tbs_cert.issuer.as_raw(), expected_issuer_der);
51             //
52             let sig_alg = &cert.signature_algorithm;
53             assert_eq!(sig_alg.algorithm, OID_PKCS1_SHA1WITHRSA);
54             //
55             let not_before = tbs_cert.validity.not_before;
56             let not_after = tbs_cert.validity.not_after;
57             let nb = Utc.timestamp(not_before.timestamp(), 0);
58             let na = Utc.timestamp(not_after.timestamp(), 0);
59             assert_eq!(nb.year(), 2002);
60             assert_eq!(nb.month(), 12);
61             assert_eq!(nb.day(), 13);
62             assert_eq!(na.year(), 2020);
63             assert_eq!(na.month(), 10);
64             assert_eq!(na.day(), 17);
65             let policies = vec![PolicyInformation {
66                 policy_id: oid!(1.2.250 .1 .121 .1 .1 .1),
67                 policy_qualifiers: None,
68             }];
69             let expected_extensions = vec![
70                 X509Extension::new(
71                     oid!(2.5.29 .19),
72                     true,
73                     &[48, 3, 1, 1, 255],
74                     ParsedExtension::BasicConstraints(BasicConstraints {
75                         ca: true,
76                         path_len_constraint: None,
77                     }),
78                 ),
79                 X509Extension::new(
80                     oid!(2.5.29 .15),
81                     false,
82                     &[3, 2, 1, 70],
83                     ParsedExtension::KeyUsage(KeyUsage { flags: 98 }),
84                 ),
85                 X509Extension::new(
86                     oid!(2.5.29 .32),
87                     false,
88                     &[48, 12, 48, 10, 6, 8, 42, 129, 122, 1, 121, 1, 1, 1],
89                     ParsedExtension::CertificatePolicies(policies),
90                 ),
91                 X509Extension::new(
92                     oid!(2.5.29 .14),
93                     false,
94                     &[
95                         4, 20, 163, 5, 47, 24, 96, 80, 194, 137, 10, 221, 43, 33, 79, 255, 142, 78,
96                         168, 48, 49, 54,
97                     ],
98                     ParsedExtension::SubjectKeyIdentifier(KeyIdentifier(&[
99                         163, 5, 47, 24, 96, 80, 194, 137, 10, 221, 43, 33, 79, 255, 142, 78, 168,
100                         48, 49, 54,
101                     ])),
102                 ),
103                 X509Extension::new(
104                     oid!(2.5.29 .35),
105                     false,
106                     &[
107                         48, 22, 128, 20, 163, 5, 47, 24, 96, 80, 194, 137, 10, 221, 43, 33, 79,
108                         255, 142, 78, 168, 48, 49, 54,
109                     ],
110                     ParsedExtension::AuthorityKeyIdentifier(AuthorityKeyIdentifier {
111                         key_identifier: Some(KeyIdentifier(&[
112                             163, 5, 47, 24, 96, 80, 194, 137, 10, 221, 43, 33, 79, 255, 142, 78,
113                             168, 48, 49, 54,
114                         ])),
115                         authority_cert_issuer: None,
116                         authority_cert_serial: None,
117                     }),
118                 ),
119             ];
120             assert_eq!(tbs_cert.extensions(), &expected_extensions as &[_]);
121             //
122             assert!(tbs_cert.is_ca());
123             //
124             assert_eq!(tbs_cert.as_ref(), &IGCA_DER[4..(8 + 746)]);
125         }
126         _ => panic!("x509 parsing failed: {:?}", res),
127     }
128 }
129 
130 #[test]
test_x509_no_extensions()131 fn test_x509_no_extensions() {
132     let empty = &b""[..];
133     let res = parse_x509_certificate(NO_EXTENSIONS_DER);
134     match res {
135         Ok((e, cert)) => {
136             assert_eq!(e, empty);
137 
138             let tbs_cert = cert.tbs_certificate;
139             assert_eq!(tbs_cert.version, X509Version::V3);
140             assert_eq!(tbs_cert.extensions().len(), 0);
141         }
142         _ => panic!("x509 parsing failed: {:?}", res),
143     }
144 }
145 
146 #[test]
test_parse_subject_public_key_info()147 fn test_parse_subject_public_key_info() {
148     let res = SubjectPublicKeyInfo::from_der(&IGCA_DER[339..])
149         .expect("Parse public key info")
150         .1;
151     assert_eq!(res.algorithm.algorithm, OID_PKCS1_RSAENCRYPTION);
152     let params = res.algorithm.parameters.expect("algorithm parameters");
153     assert_eq!(params.header.tag.0, 5);
154     let spk = res.subject_public_key;
155     println!("spk.data.len {}", spk.data.len());
156     assert_eq!(spk.data.len(), 270);
157 }
158 
159 #[test]
test_version_v1()160 fn test_version_v1() {
161     let (rem, cert) = parse_x509_certificate(V1).expect("Could not parse v1 certificate");
162     assert!(rem.is_empty());
163     assert_eq!(cert.version(), X509Version::V1);
164     let tbs_cert = cert.tbs_certificate;
165     assert_eq!(format!("{}", tbs_cert.subject), "CN=marquee");
166     assert_eq!(format!("{}", tbs_cert.issuer), "CN=marquee");
167 }
168 
169 #[test]
test_crl_parse()170 fn test_crl_parse() {
171     match parse_x509_crl(CRL_DER) {
172         Ok((e, cert)) => {
173             assert!(e.is_empty());
174 
175             let tbs_cert_list = cert.tbs_cert_list;
176             assert_eq!(tbs_cert_list.version, Some(X509Version::V2));
177 
178             let sig = &tbs_cert_list.signature;
179             assert_eq!(sig.algorithm, OID_PKCS1_SHA1WITHRSA);
180 
181             let expected_issuer =
182                 "O=Sample Signer Organization, OU=Sample Signer Unit, CN=Sample Signer Cert";
183             assert_eq!(format!("{}", tbs_cert_list.issuer), expected_issuer);
184 
185             let sig_alg = &cert.signature_algorithm;
186             assert_eq!(sig_alg.algorithm, OID_PKCS1_SHA1WITHRSA);
187 
188             let this_update = tbs_cert_list.this_update;
189             let next_update = tbs_cert_list.next_update.unwrap();
190             let tu = Utc.timestamp(this_update.timestamp(), 0);
191             let nu = Utc.timestamp(next_update.timestamp(), 0);
192             assert_eq!(tu.year(), 2013);
193             assert_eq!(tu.month(), 2);
194             assert_eq!(tu.day(), 18);
195             assert_eq!(nu.year(), 2013);
196             assert_eq!(nu.month(), 2);
197             assert_eq!(nu.day(), 18);
198 
199             let revocation_date =
200                 ASN1Time::from_timestamp(Utc.ymd(2013, 2, 18).and_hms(10, 22, 12).timestamp());
201             let invalidity_date =
202                 ASN1Time::from_timestamp(Utc.ymd(2013, 2, 18).and_hms(10, 22, 00).timestamp());
203 
204             let revoked_certs = &tbs_cert_list.revoked_certificates;
205             let revoked_cert_0 = &revoked_certs[0];
206             assert_eq!(*revoked_cert_0.serial(), 0x147947u32.into());
207             assert_eq!(revoked_cert_0.revocation_date, revocation_date);
208             let expected_extensions = vec![
209                 X509Extension::new(
210                     oid!(2.5.29 .21),
211                     false,
212                     &[10, 1, 3],
213                     ParsedExtension::ReasonCode(ReasonCode::AffiliationChanged),
214                 ),
215                 X509Extension::new(
216                     oid!(2.5.29 .24),
217                     false,
218                     &[
219                         24, 15, 50, 48, 49, 51, 48, 50, 49, 56, 49, 48, 50, 50, 48, 48, 90,
220                     ],
221                     ParsedExtension::InvalidityDate(invalidity_date),
222                 ),
223             ];
224             assert_eq!(revoked_cert_0.extensions(), &expected_extensions as &[_]);
225 
226             assert_eq!(revoked_certs.len(), 5);
227             assert_eq!(revoked_certs[4].user_certificate, 1_341_771_u32.into());
228 
229             let expected_extensions = vec![
230                 X509Extension::new(
231                     oid!(2.5.29 .35),
232                     false,
233                     &[
234                         48, 22, 128, 20, 190, 18, 1, 204, 170, 234, 17, 128, 218, 46, 173, 178,
235                         234, 199, 181, 251, 159, 249, 173, 52,
236                     ],
237                     ParsedExtension::AuthorityKeyIdentifier(AuthorityKeyIdentifier {
238                         key_identifier: Some(KeyIdentifier(&[
239                             190, 18, 1, 204, 170, 234, 17, 128, 218, 46, 173, 178, 234, 199, 181,
240                             251, 159, 249, 173, 52,
241                         ])),
242                         authority_cert_issuer: None,
243                         authority_cert_serial: None,
244                     }),
245                 ),
246                 X509Extension::new(
247                     oid!(2.5.29 .20),
248                     false,
249                     &[2, 1, 3],
250                     ParsedExtension::CRLNumber(3u32.into()),
251                 ),
252             ];
253             assert_eq!(tbs_cert_list.extensions(), &expected_extensions as &[_]);
254 
255             assert_eq!(tbs_cert_list.as_ref(), &CRL_DER[4..(4 + 4 + 508)]);
256         }
257         err => panic!("x509 parsing failed: {:?}", err),
258     }
259 }
260 
261 #[test]
test_crl_parse_empty()262 fn test_crl_parse_empty() {
263     match parse_x509_crl(EMPTY_CRL_DER) {
264         Ok((e, cert)) => {
265             assert!(e.is_empty());
266             assert!(cert.tbs_cert_list.revoked_certificates.is_empty());
267 
268             let expected_extensions = vec![
269                 X509Extension::new(
270                     oid!(2.5.29 .20),
271                     false,
272                     &[2, 1, 2],
273                     ParsedExtension::CRLNumber(2u32.into()),
274                 ),
275                 X509Extension::new(
276                     OID_X509_EXT_AUTHORITY_KEY_IDENTIFIER,
277                     false,
278                     &[
279                         48, 22, 128, 20, 34, 101, 12, 214, 90, 157, 52, 137, 243, 131, 180, 149,
280                         82, 191, 80, 27, 57, 39, 6, 172,
281                     ],
282                     ParsedExtension::AuthorityKeyIdentifier(AuthorityKeyIdentifier {
283                         key_identifier: Some(KeyIdentifier(&[
284                             34, 101, 12, 214, 90, 157, 52, 137, 243, 131, 180, 149, 82, 191, 80,
285                             27, 57, 39, 6, 172,
286                         ])),
287                         authority_cert_issuer: None,
288                         authority_cert_serial: None,
289                     }),
290                 ),
291             ];
292             assert_eq!(cert.extensions(), &expected_extensions as &[_]);
293             assert_eq!(
294                 cert.tbs_cert_list.as_ref(),
295                 &EMPTY_CRL_DER[4..(4 + 3 + 200)]
296             );
297         }
298         err => panic!("x509 parsing failed: {:?}", err),
299     }
300 }
301 
302 #[test]
test_crl_parse_minimal()303 fn test_crl_parse_minimal() {
304     match parse_x509_crl(MINIMAL_CRL_DER) {
305         Ok((e, crl)) => {
306             assert!(e.is_empty());
307             let revocation_date =
308                 ASN1Time::from_timestamp(Utc.ymd(1970, 1, 1).and_hms(0, 0, 0).timestamp());
309             let revoked_certificates = &crl.tbs_cert_list.revoked_certificates;
310             assert_eq!(revoked_certificates.len(), 1);
311             let revoked_cert_0 = &revoked_certificates[0];
312             assert_eq!(*revoked_cert_0.serial(), 42u32.into());
313             assert_eq!(revoked_cert_0.revocation_date, revocation_date);
314             assert!(revoked_cert_0.extensions().is_empty());
315             assert!(crl.tbs_cert_list.extensions().is_empty());
316             assert_eq!(crl.tbs_cert_list.as_ref(), &MINIMAL_CRL_DER[4..(4 + 79)]);
317         }
318         err => panic!("x509 parsing failed: {:?}", err),
319     }
320 }
321 
322 #[test]
test_duplicate_authority_info_access()323 fn test_duplicate_authority_info_access() {
324     match parse_x509_certificate(DUPLICATE_VALUE_IN_AIA) {
325         Ok((_, cert)) => {
326             let extension = cert
327                 .tbs_certificate
328                 .find_extension(&OID_PKIX_AUTHORITY_INFO_ACCESS)
329                 .unwrap();
330             let mut accessdescs = HashMap::new();
331             let ca_issuers = vec![
332                 &GeneralName::URI("http://cdp1.pca.dfn.de/dfn-ca-global-g2/pub/cacert/cacert.crt"),
333                 &GeneralName::URI("http://cdp2.pca.dfn.de/dfn-ca-global-g2/pub/cacert/cacert.crt"),
334             ];
335             let ocsp = vec![&GeneralName::URI("http://ocsp.pca.dfn.de/OCSP-Server/OCSP")];
336             accessdescs.insert(OID_PKIX_ACCESS_DESCRIPTOR_CA_ISSUERS, ca_issuers);
337             accessdescs.insert(OID_PKIX_ACCESS_DESCRIPTOR_OCSP, ocsp);
338             if let ParsedExtension::AuthorityInfoAccess(aia) = extension.parsed_extension() {
339                 let h = aia.as_hashmap();
340                 assert_eq!(h, accessdescs);
341             } else {
342                 panic!("Wrong extension type parsed");
343             }
344         }
345         err => panic!("x509 parsing failed: {:?}", err),
346     }
347 }
348 
349 #[test]
test_x509_parser_no_ext()350 fn test_x509_parser_no_ext() {
351     let mut parser = X509CertificateParser::new().with_deep_parse_extensions(false);
352     let (_, x509) = parser.parse(IGCA_DER).expect("parsing failed");
353     for ext in x509.extensions() {
354         assert_eq!(ext.parsed_extension(), &ParsedExtension::Unparsed);
355     }
356 }
357