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