]> git.proxmox.com Git - cargo.git/blob - vendor/openssl/src/x509/tests.rs
New upstream version 0.63.1
[cargo.git] / vendor / openssl / src / x509 / tests.rs
1 use std::cmp::Ordering;
2
3 use crate::asn1::Asn1Time;
4 use crate::bn::{BigNum, MsbOption};
5 use crate::hash::MessageDigest;
6 use crate::nid::Nid;
7 use crate::pkey::{PKey, Private};
8 use crate::rsa::Rsa;
9 use crate::stack::Stack;
10 use crate::x509::extension::{
11 AuthorityKeyIdentifier, BasicConstraints, ExtendedKeyUsage, KeyUsage, SubjectAlternativeName,
12 SubjectKeyIdentifier,
13 };
14 use crate::x509::store::X509StoreBuilder;
15 #[cfg(any(ossl102, libressl261))]
16 use crate::x509::verify::X509VerifyFlags;
17 #[cfg(ossl110)]
18 use crate::x509::X509Builder;
19 use crate::x509::{X509Name, X509Req, X509StoreContext, X509VerifyResult, X509};
20 use hex::{self, FromHex};
21
22 fn pkey() -> PKey<Private> {
23 let rsa = Rsa::generate(2048).unwrap();
24 PKey::from_rsa(rsa).unwrap()
25 }
26
27 #[test]
28 fn test_cert_loading() {
29 let cert = include_bytes!("../../test/cert.pem");
30 let cert = X509::from_pem(cert).unwrap();
31 let fingerprint = cert.digest(MessageDigest::sha1()).unwrap();
32
33 let hash_str = "59172d9313e84459bcff27f967e79e6e9217e584";
34 let hash_vec = Vec::from_hex(hash_str).unwrap();
35
36 assert_eq!(hash_vec, &*fingerprint);
37 }
38
39 #[test]
40 fn test_debug() {
41 let cert = include_bytes!("../../test/cert.pem");
42 let cert = X509::from_pem(cert).unwrap();
43 let debugged = format!("{:#?}", cert);
44 #[cfg(boringssl)]
45 assert!(debugged.contains(r#"serial_number: "8771f7bdee982fa5""#));
46 #[cfg(not(boringssl))]
47 assert!(debugged.contains(r#"serial_number: "8771F7BDEE982FA5""#));
48 assert!(debugged.contains(r#"signature_algorithm: sha256WithRSAEncryption"#));
49 assert!(debugged.contains(r#"countryName = "AU""#));
50 assert!(debugged.contains(r#"stateOrProvinceName = "Some-State""#));
51 assert!(debugged.contains(r#"not_before: Aug 14 17:00:03 2016 GMT"#));
52 assert!(debugged.contains(r#"not_after: Aug 12 17:00:03 2026 GMT"#));
53 }
54
55 #[test]
56 fn test_cert_issue_validity() {
57 let cert = include_bytes!("../../test/cert.pem");
58 let cert = X509::from_pem(cert).unwrap();
59 let not_before = cert.not_before().to_string();
60 let not_after = cert.not_after().to_string();
61
62 assert_eq!(not_before, "Aug 14 17:00:03 2016 GMT");
63 assert_eq!(not_after, "Aug 12 17:00:03 2026 GMT");
64 }
65
66 #[test]
67 fn test_save_der() {
68 let cert = include_bytes!("../../test/cert.pem");
69 let cert = X509::from_pem(cert).unwrap();
70
71 let der = cert.to_der().unwrap();
72 assert!(!der.is_empty());
73 }
74
75 #[test]
76 fn test_subject_read_cn() {
77 let cert = include_bytes!("../../test/cert.pem");
78 let cert = X509::from_pem(cert).unwrap();
79 let subject = cert.subject_name();
80 let cn = subject.entries_by_nid(Nid::COMMONNAME).next().unwrap();
81 assert_eq!(cn.data().as_slice(), b"foobar.com")
82 }
83
84 #[test]
85 fn test_nid_values() {
86 let cert = include_bytes!("../../test/nid_test_cert.pem");
87 let cert = X509::from_pem(cert).unwrap();
88 let subject = cert.subject_name();
89
90 let cn = subject.entries_by_nid(Nid::COMMONNAME).next().unwrap();
91 assert_eq!(cn.data().as_slice(), b"example.com");
92
93 let email = subject
94 .entries_by_nid(Nid::PKCS9_EMAILADDRESS)
95 .next()
96 .unwrap();
97 assert_eq!(email.data().as_slice(), b"test@example.com");
98
99 let friendly = subject.entries_by_nid(Nid::FRIENDLYNAME).next().unwrap();
100 assert_eq!(&**friendly.data().as_utf8().unwrap(), "Example");
101 }
102
103 #[test]
104 fn test_nameref_iterator() {
105 let cert = include_bytes!("../../test/nid_test_cert.pem");
106 let cert = X509::from_pem(cert).unwrap();
107 let subject = cert.subject_name();
108 let mut all_entries = subject.entries();
109
110 let email = all_entries.next().unwrap();
111 assert_eq!(
112 email.object().nid().as_raw(),
113 Nid::PKCS9_EMAILADDRESS.as_raw()
114 );
115 assert_eq!(email.data().as_slice(), b"test@example.com");
116
117 let cn = all_entries.next().unwrap();
118 assert_eq!(cn.object().nid().as_raw(), Nid::COMMONNAME.as_raw());
119 assert_eq!(cn.data().as_slice(), b"example.com");
120
121 let friendly = all_entries.next().unwrap();
122 assert_eq!(friendly.object().nid().as_raw(), Nid::FRIENDLYNAME.as_raw());
123 assert_eq!(&**friendly.data().as_utf8().unwrap(), "Example");
124
125 if all_entries.next().is_some() {
126 panic!();
127 }
128 }
129
130 #[test]
131 fn test_nid_uid_value() {
132 let cert = include_bytes!("../../test/nid_uid_test_cert.pem");
133 let cert = X509::from_pem(cert).unwrap();
134 let subject = cert.subject_name();
135
136 let cn = subject.entries_by_nid(Nid::USERID).next().unwrap();
137 assert_eq!(cn.data().as_slice(), b"this is the userId");
138 }
139
140 #[test]
141 fn test_subject_alt_name() {
142 let cert = include_bytes!("../../test/alt_name_cert.pem");
143 let cert = X509::from_pem(cert).unwrap();
144
145 let subject_alt_names = cert.subject_alt_names().unwrap();
146 assert_eq!(5, subject_alt_names.len());
147 assert_eq!(Some("example.com"), subject_alt_names[0].dnsname());
148 assert_eq!(subject_alt_names[1].ipaddress(), Some(&[127, 0, 0, 1][..]));
149 assert_eq!(
150 subject_alt_names[2].ipaddress(),
151 Some(&b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01"[..])
152 );
153 assert_eq!(Some("test@example.com"), subject_alt_names[3].email());
154 assert_eq!(Some("http://www.example.com"), subject_alt_names[4].uri());
155 }
156
157 #[test]
158 fn test_subject_alt_name_iter() {
159 let cert = include_bytes!("../../test/alt_name_cert.pem");
160 let cert = X509::from_pem(cert).unwrap();
161
162 let subject_alt_names = cert.subject_alt_names().unwrap();
163 let mut subject_alt_names_iter = subject_alt_names.iter();
164 assert_eq!(
165 subject_alt_names_iter.next().unwrap().dnsname(),
166 Some("example.com")
167 );
168 assert_eq!(
169 subject_alt_names_iter.next().unwrap().ipaddress(),
170 Some(&[127, 0, 0, 1][..])
171 );
172 assert_eq!(
173 subject_alt_names_iter.next().unwrap().ipaddress(),
174 Some(&b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01"[..])
175 );
176 assert_eq!(
177 subject_alt_names_iter.next().unwrap().email(),
178 Some("test@example.com")
179 );
180 assert_eq!(
181 subject_alt_names_iter.next().unwrap().uri(),
182 Some("http://www.example.com")
183 );
184 assert!(subject_alt_names_iter.next().is_none());
185 }
186
187 #[test]
188 fn test_aia_ca_issuer() {
189 // With AIA
190 let cert = include_bytes!("../../test/aia_test_cert.pem");
191 let cert = X509::from_pem(cert).unwrap();
192 let authority_info = cert.authority_info().unwrap();
193 assert_eq!(authority_info.len(), 1);
194 assert_eq!(authority_info[0].method().to_string(), "CA Issuers");
195 assert_eq!(
196 authority_info[0].location().uri(),
197 Some("http://www.example.com/cert.pem")
198 );
199 // Without AIA
200 let cert = include_bytes!("../../test/cert.pem");
201 let cert = X509::from_pem(cert).unwrap();
202 assert!(cert.authority_info().is_none());
203 }
204
205 #[test]
206 fn x509_builder() {
207 let pkey = pkey();
208
209 let mut name = X509Name::builder().unwrap();
210 name.append_entry_by_nid(Nid::COMMONNAME, "foobar.com")
211 .unwrap();
212 let name = name.build();
213
214 let mut builder = X509::builder().unwrap();
215 builder.set_version(2).unwrap();
216 builder.set_subject_name(&name).unwrap();
217 builder.set_issuer_name(&name).unwrap();
218 builder
219 .set_not_before(&Asn1Time::days_from_now(0).unwrap())
220 .unwrap();
221 builder
222 .set_not_after(&Asn1Time::days_from_now(365).unwrap())
223 .unwrap();
224 builder.set_pubkey(&pkey).unwrap();
225
226 let mut serial = BigNum::new().unwrap();
227 serial.rand(128, MsbOption::MAYBE_ZERO, false).unwrap();
228 builder
229 .set_serial_number(&serial.to_asn1_integer().unwrap())
230 .unwrap();
231
232 let basic_constraints = BasicConstraints::new().critical().ca().build().unwrap();
233 builder.append_extension(basic_constraints).unwrap();
234 let key_usage = KeyUsage::new()
235 .digital_signature()
236 .key_encipherment()
237 .build()
238 .unwrap();
239 builder.append_extension(key_usage).unwrap();
240 let ext_key_usage = ExtendedKeyUsage::new()
241 .client_auth()
242 .server_auth()
243 .other("2.999.1")
244 .build()
245 .unwrap();
246 builder.append_extension(ext_key_usage).unwrap();
247 let subject_key_identifier = SubjectKeyIdentifier::new()
248 .build(&builder.x509v3_context(None, None))
249 .unwrap();
250 builder.append_extension(subject_key_identifier).unwrap();
251 let authority_key_identifier = AuthorityKeyIdentifier::new()
252 .keyid(true)
253 .build(&builder.x509v3_context(None, None))
254 .unwrap();
255 builder.append_extension(authority_key_identifier).unwrap();
256 let subject_alternative_name = SubjectAlternativeName::new()
257 .dns("example.com")
258 .build(&builder.x509v3_context(None, None))
259 .unwrap();
260 builder.append_extension(subject_alternative_name).unwrap();
261
262 builder.sign(&pkey, MessageDigest::sha256()).unwrap();
263
264 let x509 = builder.build();
265
266 assert!(pkey.public_eq(&x509.public_key().unwrap()));
267 assert!(x509.verify(&pkey).unwrap());
268
269 let cn = x509
270 .subject_name()
271 .entries_by_nid(Nid::COMMONNAME)
272 .next()
273 .unwrap();
274 assert_eq!(cn.data().as_slice(), b"foobar.com");
275 assert_eq!(serial, x509.serial_number().to_bn().unwrap());
276 }
277
278 #[test]
279 fn x509_req_builder() {
280 let pkey = pkey();
281
282 let mut name = X509Name::builder().unwrap();
283 name.append_entry_by_nid(Nid::COMMONNAME, "foobar.com")
284 .unwrap();
285 let name = name.build();
286
287 let mut builder = X509Req::builder().unwrap();
288 builder.set_version(0).unwrap();
289 builder.set_subject_name(&name).unwrap();
290 builder.set_pubkey(&pkey).unwrap();
291
292 let mut extensions = Stack::new().unwrap();
293 let key_usage = KeyUsage::new()
294 .digital_signature()
295 .key_encipherment()
296 .build()
297 .unwrap();
298 extensions.push(key_usage).unwrap();
299 let subject_alternative_name = SubjectAlternativeName::new()
300 .dns("example.com")
301 .build(&builder.x509v3_context(None))
302 .unwrap();
303 extensions.push(subject_alternative_name).unwrap();
304 builder.add_extensions(&extensions).unwrap();
305
306 builder.sign(&pkey, MessageDigest::sha256()).unwrap();
307
308 let req = builder.build();
309 assert!(req.public_key().unwrap().public_eq(&pkey));
310 assert_eq!(req.extensions().unwrap().len(), extensions.len());
311 assert!(req.verify(&pkey).unwrap());
312 }
313
314 #[test]
315 fn test_stack_from_pem() {
316 let certs = include_bytes!("../../test/certs.pem");
317 let certs = X509::stack_from_pem(certs).unwrap();
318
319 assert_eq!(certs.len(), 2);
320 assert_eq!(
321 hex::encode(certs[0].digest(MessageDigest::sha1()).unwrap()),
322 "59172d9313e84459bcff27f967e79e6e9217e584"
323 );
324 assert_eq!(
325 hex::encode(certs[1].digest(MessageDigest::sha1()).unwrap()),
326 "c0cbdf7cdd03c9773e5468e1f6d2da7d5cbb1875"
327 );
328 }
329
330 #[test]
331 fn issued() {
332 let cert = include_bytes!("../../test/cert.pem");
333 let cert = X509::from_pem(cert).unwrap();
334 let ca = include_bytes!("../../test/root-ca.pem");
335 let ca = X509::from_pem(ca).unwrap();
336
337 assert_eq!(ca.issued(&cert), X509VerifyResult::OK);
338 assert_ne!(cert.issued(&cert), X509VerifyResult::OK);
339 }
340
341 #[test]
342 fn signature() {
343 let cert = include_bytes!("../../test/cert.pem");
344 let cert = X509::from_pem(cert).unwrap();
345 let signature = cert.signature();
346 assert_eq!(
347 hex::encode(signature.as_slice()),
348 "4af607b889790b43470442cfa551cdb8b6d0b0340d2958f76b9e3ef6ad4992230cead6842587f0ecad5\
349 78e6e11a221521e940187e3d6652de14e84e82f6671f097cc47932e022add3c0cb54a26bf27fa84c107\
350 4971caa6bee2e42d34a5b066c427f2d452038082b8073993399548088429de034fdd589dcfb0dd33be7\
351 ebdfdf698a28d628a89568881d658151276bde333600969502c4e62e1d3470a683364dfb241f78d310a\
352 89c119297df093eb36b7fd7540224f488806780305d1e79ffc938fe2275441726522ab36d88348e6c51\
353 f13dcc46b5e1cdac23c974fd5ef86aa41e91c9311655090a52333bc79687c748d833595d4c5f987508f\
354 e121997410d37c"
355 );
356 let algorithm = cert.signature_algorithm();
357 assert_eq!(algorithm.object().nid(), Nid::SHA256WITHRSAENCRYPTION);
358 assert_eq!(algorithm.object().to_string(), "sha256WithRSAEncryption");
359 }
360
361 #[test]
362 #[allow(clippy::redundant_clone)]
363 fn clone_x509() {
364 let cert = include_bytes!("../../test/cert.pem");
365 let cert = X509::from_pem(cert).unwrap();
366 drop(cert.clone());
367 }
368
369 #[test]
370 fn test_verify_cert() {
371 let cert = include_bytes!("../../test/cert.pem");
372 let cert = X509::from_pem(cert).unwrap();
373 let ca = include_bytes!("../../test/root-ca.pem");
374 let ca = X509::from_pem(ca).unwrap();
375 let chain = Stack::new().unwrap();
376
377 let mut store_bldr = X509StoreBuilder::new().unwrap();
378 store_bldr.add_cert(ca).unwrap();
379 let store = store_bldr.build();
380
381 let mut context = X509StoreContext::new().unwrap();
382 assert!(context
383 .init(&store, &cert, &chain, |c| c.verify_cert())
384 .unwrap());
385 assert!(context
386 .init(&store, &cert, &chain, |c| c.verify_cert())
387 .unwrap());
388 }
389
390 #[test]
391 fn test_verify_fails() {
392 let cert = include_bytes!("../../test/cert.pem");
393 let cert = X509::from_pem(cert).unwrap();
394 let ca = include_bytes!("../../test/alt_name_cert.pem");
395 let ca = X509::from_pem(ca).unwrap();
396 let chain = Stack::new().unwrap();
397
398 let mut store_bldr = X509StoreBuilder::new().unwrap();
399 store_bldr.add_cert(ca).unwrap();
400 let store = store_bldr.build();
401
402 let mut context = X509StoreContext::new().unwrap();
403 assert!(!context
404 .init(&store, &cert, &chain, |c| c.verify_cert())
405 .unwrap());
406 }
407
408 #[test]
409 #[cfg(any(ossl102, libressl261))]
410 fn test_verify_fails_with_crl_flag_set_and_no_crl() {
411 let cert = include_bytes!("../../test/cert.pem");
412 let cert = X509::from_pem(cert).unwrap();
413 let ca = include_bytes!("../../test/root-ca.pem");
414 let ca = X509::from_pem(ca).unwrap();
415 let chain = Stack::new().unwrap();
416
417 let mut store_bldr = X509StoreBuilder::new().unwrap();
418 store_bldr.add_cert(ca).unwrap();
419 store_bldr.set_flags(X509VerifyFlags::CRL_CHECK).unwrap();
420 let store = store_bldr.build();
421
422 let mut context = X509StoreContext::new().unwrap();
423 assert_eq!(
424 context
425 .init(&store, &cert, &chain, |c| {
426 c.verify_cert()?;
427 Ok(c.error())
428 })
429 .unwrap()
430 .error_string(),
431 "unable to get certificate CRL"
432 )
433 }
434
435 #[cfg(ossl110)]
436 #[test]
437 fn x509_ref_version() {
438 let mut builder = X509Builder::new().unwrap();
439 let expected_version = 2;
440 builder
441 .set_version(expected_version)
442 .expect("Failed to set certificate version");
443 let cert = builder.build();
444 let actual_version = cert.version();
445 assert_eq!(
446 expected_version, actual_version,
447 "Obtained certificate version is incorrect",
448 );
449 }
450
451 #[cfg(ossl110)]
452 #[test]
453 fn x509_ref_version_no_version_set() {
454 let cert = X509Builder::new().unwrap().build();
455 let actual_version = cert.version();
456 assert_eq!(
457 0, actual_version,
458 "Default certificate version is incorrect",
459 );
460 }
461
462 #[test]
463 fn test_save_subject_der() {
464 let cert = include_bytes!("../../test/cert.pem");
465 let cert = X509::from_pem(cert).unwrap();
466
467 let der = cert.subject_name().to_der().unwrap();
468 println!("der: {:?}", der);
469 assert!(!der.is_empty());
470 }
471
472 #[test]
473 fn test_load_subject_der() {
474 // The subject from ../../test/cert.pem
475 const SUBJECT_DER: &[u8] = &[
476 48, 90, 49, 11, 48, 9, 6, 3, 85, 4, 6, 19, 2, 65, 85, 49, 19, 48, 17, 6, 3, 85, 4, 8, 12,
477 10, 83, 111, 109, 101, 45, 83, 116, 97, 116, 101, 49, 33, 48, 31, 6, 3, 85, 4, 10, 12, 24,
478 73, 110, 116, 101, 114, 110, 101, 116, 32, 87, 105, 100, 103, 105, 116, 115, 32, 80, 116,
479 121, 32, 76, 116, 100, 49, 19, 48, 17, 6, 3, 85, 4, 3, 12, 10, 102, 111, 111, 98, 97, 114,
480 46, 99, 111, 109,
481 ];
482 X509Name::from_der(SUBJECT_DER).unwrap();
483 }
484
485 #[test]
486 fn test_convert_to_text() {
487 let cert = include_bytes!("../../test/cert.pem");
488 let cert = X509::from_pem(cert).unwrap();
489
490 const SUBSTRINGS: &[&str] = &[
491 "Certificate:\n",
492 "Serial Number:",
493 "Signature Algorithm:",
494 "Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd\n",
495 "Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=foobar.com\n",
496 "Subject Public Key Info:",
497 ];
498
499 let text = String::from_utf8(cert.to_text().unwrap()).unwrap();
500
501 for substring in SUBSTRINGS {
502 assert!(
503 text.contains(substring),
504 "{:?} not found inside {}",
505 substring,
506 text
507 );
508 }
509 }
510
511 #[test]
512 fn test_convert_req_to_text() {
513 let csr = include_bytes!("../../test/csr.pem");
514 let csr = X509Req::from_pem(csr).unwrap();
515
516 const SUBSTRINGS: &[&str] = &[
517 "Certificate Request:\n",
518 "Version:",
519 "Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=foobar.com\n",
520 "Subject Public Key Info:",
521 "Signature Algorithm:",
522 ];
523
524 let text = String::from_utf8(csr.to_text().unwrap()).unwrap();
525
526 for substring in SUBSTRINGS {
527 assert!(
528 text.contains(substring),
529 "{:?} not found inside {}",
530 substring,
531 text
532 );
533 }
534 }
535
536 #[test]
537 fn test_name_cmp() {
538 let cert = include_bytes!("../../test/cert.pem");
539 let cert = X509::from_pem(cert).unwrap();
540
541 let subject = cert.subject_name();
542 let issuer = cert.issuer_name();
543 assert_eq!(Ordering::Equal, subject.try_cmp(subject).unwrap());
544 assert_eq!(Ordering::Greater, subject.try_cmp(issuer).unwrap());
545 }