1 use std::cmp::Ordering;
2
3 use crate::asn1::{Asn1Object, Asn1OctetString, 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 #[cfg(not(boringssl))]
10 use crate::ssl::SslFiletype;
11 use crate::stack::Stack;
12 use crate::x509::extension::{
13 AuthorityKeyIdentifier, BasicConstraints, ExtendedKeyUsage, KeyUsage, SubjectAlternativeName,
14 SubjectKeyIdentifier,
15 };
16 #[cfg(not(boringssl))]
17 use crate::x509::store::X509Lookup;
18 use crate::x509::store::X509StoreBuilder;
19 #[cfg(any(ossl102, boringssl, libressl261))]
20 use crate::x509::verify::{X509VerifyFlags, X509VerifyParam};
21 #[cfg(any(ossl102, boringssl))]
22 use crate::x509::X509PurposeId;
23 #[cfg(any(ossl102, boringssl, libressl261))]
24 use crate::x509::X509PurposeRef;
25 #[cfg(ossl110)]
26 use crate::x509::{CrlReason, X509Builder};
27 use crate::x509::{
28 CrlStatus, X509Crl, X509Extension, X509Name, X509Req, X509StoreContext, X509VerifyResult, X509,
29 };
30
31 #[cfg(ossl110)]
32 use foreign_types::ForeignType;
33 use hex::{self, FromHex};
34 #[cfg(any(ossl102, boringssl, libressl261))]
35 use libc::time_t;
36
37 use super::{AuthorityInformationAccess, CertificateIssuer, ReasonCode};
38
pkey() -> PKey<Private>39 fn pkey() -> PKey<Private> {
40 let rsa = Rsa::generate(2048).unwrap();
41 PKey::from_rsa(rsa).unwrap()
42 }
43
44 #[test]
test_cert_loading()45 fn test_cert_loading() {
46 let cert = include_bytes!("../../test/cert.pem");
47 let cert = X509::from_pem(cert).unwrap();
48 let fingerprint = cert.digest(MessageDigest::sha1()).unwrap();
49
50 let hash_str = "59172d9313e84459bcff27f967e79e6e9217e584";
51 let hash_vec = Vec::from_hex(hash_str).unwrap();
52
53 assert_eq!(hash_vec, &*fingerprint);
54 }
55
56 #[test]
test_debug()57 fn test_debug() {
58 let cert = include_bytes!("../../test/cert.pem");
59 let cert = X509::from_pem(cert).unwrap();
60 let debugged = format!("{:#?}", cert);
61 #[cfg(boringssl)]
62 assert!(debugged.contains(r#"serial_number: "8771f7bdee982fa5""#));
63 #[cfg(not(boringssl))]
64 assert!(debugged.contains(r#"serial_number: "8771F7BDEE982FA5""#));
65 assert!(debugged.contains(r#"signature_algorithm: sha256WithRSAEncryption"#));
66 assert!(debugged.contains(r#"countryName = "AU""#));
67 assert!(debugged.contains(r#"stateOrProvinceName = "Some-State""#));
68 assert!(debugged.contains(r#"not_before: Aug 14 17:00:03 2016 GMT"#));
69 assert!(debugged.contains(r#"not_after: Aug 12 17:00:03 2026 GMT"#));
70 }
71
72 #[test]
test_cert_issue_validity()73 fn test_cert_issue_validity() {
74 let cert = include_bytes!("../../test/cert.pem");
75 let cert = X509::from_pem(cert).unwrap();
76 let not_before = cert.not_before().to_string();
77 let not_after = cert.not_after().to_string();
78
79 assert_eq!(not_before, "Aug 14 17:00:03 2016 GMT");
80 assert_eq!(not_after, "Aug 12 17:00:03 2026 GMT");
81 }
82
83 #[test]
test_save_der()84 fn test_save_der() {
85 let cert = include_bytes!("../../test/cert.pem");
86 let cert = X509::from_pem(cert).unwrap();
87
88 let der = cert.to_der().unwrap();
89 assert!(!der.is_empty());
90 }
91
92 #[test]
test_subject_read_cn()93 fn test_subject_read_cn() {
94 let cert = include_bytes!("../../test/cert.pem");
95 let cert = X509::from_pem(cert).unwrap();
96 let subject = cert.subject_name();
97 let cn = subject.entries_by_nid(Nid::COMMONNAME).next().unwrap();
98 assert_eq!(cn.data().as_slice(), b"foobar.com")
99 }
100
101 #[test]
test_nid_values()102 fn test_nid_values() {
103 let cert = include_bytes!("../../test/nid_test_cert.pem");
104 let cert = X509::from_pem(cert).unwrap();
105 let subject = cert.subject_name();
106
107 let cn = subject.entries_by_nid(Nid::COMMONNAME).next().unwrap();
108 assert_eq!(cn.data().as_slice(), b"example.com");
109
110 let email = subject
111 .entries_by_nid(Nid::PKCS9_EMAILADDRESS)
112 .next()
113 .unwrap();
114 assert_eq!(email.data().as_slice(), b"[email protected]");
115
116 let friendly = subject.entries_by_nid(Nid::FRIENDLYNAME).next().unwrap();
117 assert_eq!(&**friendly.data().as_utf8().unwrap(), "Example");
118 }
119
120 #[test]
test_nameref_iterator()121 fn test_nameref_iterator() {
122 let cert = include_bytes!("../../test/nid_test_cert.pem");
123 let cert = X509::from_pem(cert).unwrap();
124 let subject = cert.subject_name();
125 let mut all_entries = subject.entries();
126
127 let email = all_entries.next().unwrap();
128 assert_eq!(
129 email.object().nid().as_raw(),
130 Nid::PKCS9_EMAILADDRESS.as_raw()
131 );
132 assert_eq!(email.data().as_slice(), b"[email protected]");
133
134 let cn = all_entries.next().unwrap();
135 assert_eq!(cn.object().nid().as_raw(), Nid::COMMONNAME.as_raw());
136 assert_eq!(cn.data().as_slice(), b"example.com");
137
138 let friendly = all_entries.next().unwrap();
139 assert_eq!(friendly.object().nid().as_raw(), Nid::FRIENDLYNAME.as_raw());
140 assert_eq!(&**friendly.data().as_utf8().unwrap(), "Example");
141
142 if all_entries.next().is_some() {
143 panic!();
144 }
145 }
146
147 #[test]
test_nid_uid_value()148 fn test_nid_uid_value() {
149 let cert = include_bytes!("../../test/nid_uid_test_cert.pem");
150 let cert = X509::from_pem(cert).unwrap();
151 let subject = cert.subject_name();
152
153 let cn = subject.entries_by_nid(Nid::USERID).next().unwrap();
154 assert_eq!(cn.data().as_slice(), b"this is the userId");
155 }
156
157 #[test]
test_subject_alt_name()158 fn test_subject_alt_name() {
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 assert_eq!(5, subject_alt_names.len());
164 assert_eq!(Some("example.com"), subject_alt_names[0].dnsname());
165 assert_eq!(subject_alt_names[1].ipaddress(), Some(&[127, 0, 0, 1][..]));
166 assert_eq!(
167 subject_alt_names[2].ipaddress(),
168 Some(&b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01"[..])
169 );
170 assert_eq!(Some("[email protected]"), subject_alt_names[3].email());
171 assert_eq!(Some("http://www.example.com"), subject_alt_names[4].uri());
172 }
173
174 #[test]
175 #[cfg(any(ossl110, boringssl))]
test_retrieve_pathlen()176 fn test_retrieve_pathlen() {
177 let cert = include_bytes!("../../test/root-ca.pem");
178 let cert = X509::from_pem(cert).unwrap();
179 assert_eq!(cert.pathlen(), None);
180
181 let cert = include_bytes!("../../test/intermediate-ca.pem");
182 let cert = X509::from_pem(cert).unwrap();
183 assert_eq!(cert.pathlen(), Some(0));
184
185 let cert = include_bytes!("../../test/alt_name_cert.pem");
186 let cert = X509::from_pem(cert).unwrap();
187 assert_eq!(cert.pathlen(), None);
188 }
189
190 #[test]
191 #[cfg(any(ossl110, boringssl))]
test_subject_key_id()192 fn test_subject_key_id() {
193 let cert = include_bytes!("../../test/certv3.pem");
194 let cert = X509::from_pem(cert).unwrap();
195
196 let subject_key_id = cert.subject_key_id().unwrap();
197 assert_eq!(
198 subject_key_id.as_slice(),
199 &b"\xB6\x73\x2F\x61\xA5\x4B\xA1\xEF\x48\x2C\x15\xB1\x9F\xF3\xDC\x34\x2F\xBC\xAC\x30"[..]
200 );
201 }
202
203 #[test]
204 #[cfg(any(ossl110, boringssl))]
test_authority_key_id()205 fn test_authority_key_id() {
206 let cert = include_bytes!("../../test/certv3.pem");
207 let cert = X509::from_pem(cert).unwrap();
208
209 let authority_key_id = cert.authority_key_id().unwrap();
210 assert_eq!(
211 authority_key_id.as_slice(),
212 &b"\x6C\xD3\xA5\x03\xAB\x0D\x5F\x2C\xC9\x8D\x8A\x9C\x88\xA7\x88\x77\xB8\x37\xFD\x9A"[..]
213 );
214 }
215
216 #[test]
217 #[cfg(ossl111d)]
test_authority_issuer_and_serial()218 fn test_authority_issuer_and_serial() {
219 let cert = include_bytes!("../../test/authority_key_identifier.pem");
220 let cert = X509::from_pem(cert).unwrap();
221
222 let authority_issuer = cert.authority_issuer().unwrap();
223 assert_eq!(1, authority_issuer.len());
224 let dn = authority_issuer[0].directory_name().unwrap();
225 let mut o = dn.entries_by_nid(Nid::ORGANIZATIONNAME);
226 let o = o.next().unwrap().data().as_utf8().unwrap();
227 assert_eq!(o.as_bytes(), b"PyCA");
228 let mut cn = dn.entries_by_nid(Nid::COMMONNAME);
229 let cn = cn.next().unwrap().data().as_utf8().unwrap();
230 assert_eq!(cn.as_bytes(), b"cryptography.io");
231
232 let authority_serial = cert.authority_serial().unwrap();
233 let serial = authority_serial.to_bn().unwrap();
234 let expected = BigNum::from_u32(3).unwrap();
235 assert_eq!(serial, expected);
236 }
237
238 #[test]
test_subject_alt_name_iter()239 fn test_subject_alt_name_iter() {
240 let cert = include_bytes!("../../test/alt_name_cert.pem");
241 let cert = X509::from_pem(cert).unwrap();
242
243 let subject_alt_names = cert.subject_alt_names().unwrap();
244 let mut subject_alt_names_iter = subject_alt_names.iter();
245 assert_eq!(
246 subject_alt_names_iter.next().unwrap().dnsname(),
247 Some("example.com")
248 );
249 assert_eq!(
250 subject_alt_names_iter.next().unwrap().ipaddress(),
251 Some(&[127, 0, 0, 1][..])
252 );
253 assert_eq!(
254 subject_alt_names_iter.next().unwrap().ipaddress(),
255 Some(&b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01"[..])
256 );
257 assert_eq!(
258 subject_alt_names_iter.next().unwrap().email(),
259 Some("[email protected]")
260 );
261 assert_eq!(
262 subject_alt_names_iter.next().unwrap().uri(),
263 Some("http://www.example.com")
264 );
265 assert!(subject_alt_names_iter.next().is_none());
266 }
267
268 #[test]
test_aia_ca_issuer()269 fn test_aia_ca_issuer() {
270 // With AIA
271 let cert = include_bytes!("../../test/aia_test_cert.pem");
272 let cert = X509::from_pem(cert).unwrap();
273 let authority_info = cert.authority_info().unwrap();
274 assert_eq!(authority_info.len(), 1);
275 assert_eq!(authority_info[0].method().to_string(), "CA Issuers");
276 assert_eq!(
277 authority_info[0].location().uri(),
278 Some("http://www.example.com/cert.pem")
279 );
280 // Without AIA
281 let cert = include_bytes!("../../test/cert.pem");
282 let cert = X509::from_pem(cert).unwrap();
283 assert!(cert.authority_info().is_none());
284 }
285
286 #[test]
x509_builder()287 fn x509_builder() {
288 let pkey = pkey();
289
290 let mut name = X509Name::builder().unwrap();
291 name.append_entry_by_nid(Nid::COMMONNAME, "foobar.com")
292 .unwrap();
293 let name = name.build();
294
295 let mut builder = X509::builder().unwrap();
296 builder.set_version(2).unwrap();
297 builder.set_subject_name(&name).unwrap();
298 builder.set_issuer_name(&name).unwrap();
299 builder
300 .set_not_before(&Asn1Time::days_from_now(0).unwrap())
301 .unwrap();
302 builder
303 .set_not_after(&Asn1Time::days_from_now(365).unwrap())
304 .unwrap();
305 builder.set_pubkey(&pkey).unwrap();
306
307 let mut serial = BigNum::new().unwrap();
308 serial.rand(128, MsbOption::MAYBE_ZERO, false).unwrap();
309 builder
310 .set_serial_number(&serial.to_asn1_integer().unwrap())
311 .unwrap();
312
313 let basic_constraints = BasicConstraints::new().critical().ca().build().unwrap();
314 builder.append_extension(basic_constraints).unwrap();
315 let key_usage = KeyUsage::new()
316 .digital_signature()
317 .key_encipherment()
318 .build()
319 .unwrap();
320 builder.append_extension(key_usage).unwrap();
321 let ext_key_usage = ExtendedKeyUsage::new()
322 .client_auth()
323 .server_auth()
324 .other("2.999.1")
325 .build()
326 .unwrap();
327 builder.append_extension(ext_key_usage).unwrap();
328 let subject_key_identifier = SubjectKeyIdentifier::new()
329 .build(&builder.x509v3_context(None, None))
330 .unwrap();
331 builder.append_extension(subject_key_identifier).unwrap();
332 let authority_key_identifier = AuthorityKeyIdentifier::new()
333 .keyid(true)
334 .build(&builder.x509v3_context(None, None))
335 .unwrap();
336 builder.append_extension(authority_key_identifier).unwrap();
337 let subject_alternative_name = SubjectAlternativeName::new()
338 .dns("example.com")
339 .build(&builder.x509v3_context(None, None))
340 .unwrap();
341 builder.append_extension(subject_alternative_name).unwrap();
342
343 builder.sign(&pkey, MessageDigest::sha256()).unwrap();
344
345 let x509 = builder.build();
346
347 assert!(pkey.public_eq(&x509.public_key().unwrap()));
348 assert!(x509.verify(&pkey).unwrap());
349
350 let cn = x509
351 .subject_name()
352 .entries_by_nid(Nid::COMMONNAME)
353 .next()
354 .unwrap();
355 assert_eq!(cn.data().as_slice(), b"foobar.com");
356 assert_eq!(serial, x509.serial_number().to_bn().unwrap());
357 }
358
359 #[test]
360 // This tests `X509Extension::new`, even though its deprecated.
361 #[allow(deprecated)]
x509_extension_new()362 fn x509_extension_new() {
363 assert!(X509Extension::new(None, None, "crlDistributionPoints", "section").is_err());
364 assert!(X509Extension::new(None, None, "proxyCertInfo", "").is_err());
365 assert!(X509Extension::new(None, None, "certificatePolicies", "").is_err());
366 assert!(X509Extension::new(None, None, "subjectAltName", "dirName:section").is_err());
367 }
368
369 #[test]
x509_extension_new_from_der()370 fn x509_extension_new_from_der() {
371 let ext = X509Extension::new_from_der(
372 &Asn1Object::from_str("2.5.29.19").unwrap(),
373 true,
374 &Asn1OctetString::new_from_bytes(b"\x30\x03\x01\x01\xff").unwrap(),
375 )
376 .unwrap();
377 assert_eq!(
378 ext.to_der().unwrap(),
379 b"0\x0f\x06\x03U\x1d\x13\x01\x01\xff\x04\x050\x03\x01\x01\xff"
380 );
381 }
382
383 #[test]
x509_extension_to_der()384 fn x509_extension_to_der() {
385 let builder = X509::builder().unwrap();
386
387 for (ext, expected) in [
388 (
389 BasicConstraints::new().critical().ca().build().unwrap(),
390 b"0\x0f\x06\x03U\x1d\x13\x01\x01\xff\x04\x050\x03\x01\x01\xff" as &[u8],
391 ),
392 (
393 SubjectAlternativeName::new()
394 .dns("example.com,DNS:example2.com")
395 .build(&builder.x509v3_context(None, None))
396 .unwrap(),
397 b"0'\x06\x03U\x1d\x11\x04 0\x1e\x82\x1cexample.com,DNS:example2.com",
398 ),
399 (
400 SubjectAlternativeName::new()
401 .rid("1.2.3.4")
402 .uri("https://example.com")
403 .build(&builder.x509v3_context(None, None))
404 .unwrap(),
405 b"0#\x06\x03U\x1d\x11\x04\x1c0\x1a\x88\x03*\x03\x04\x86\x13https://example.com",
406 ),
407 (
408 ExtendedKeyUsage::new()
409 .server_auth()
410 .other("2.999.1")
411 .other("clientAuth")
412 .build()
413 .unwrap(),
414 b"0\x22\x06\x03U\x1d%\x04\x1b0\x19\x06\x08+\x06\x01\x05\x05\x07\x03\x01\x06\x03\x887\x01\x06\x08+\x06\x01\x05\x05\x07\x03\x02",
415 ),
416 ] {
417 assert_eq!(&ext.to_der().unwrap(), expected);
418 }
419 }
420
421 #[test]
eku_invalid_other()422 fn eku_invalid_other() {
423 assert!(ExtendedKeyUsage::new()
424 .other("1.1.1.1.1,2.2.2.2.2")
425 .build()
426 .is_err());
427 }
428
429 #[test]
x509_req_builder()430 fn x509_req_builder() {
431 let pkey = pkey();
432
433 let mut name = X509Name::builder().unwrap();
434 name.append_entry_by_nid(Nid::COMMONNAME, "foobar.com")
435 .unwrap();
436 let name = name.build();
437
438 let mut builder = X509Req::builder().unwrap();
439 builder.set_version(0).unwrap();
440 builder.set_subject_name(&name).unwrap();
441 builder.set_pubkey(&pkey).unwrap();
442
443 let mut extensions = Stack::new().unwrap();
444 let key_usage = KeyUsage::new()
445 .digital_signature()
446 .key_encipherment()
447 .build()
448 .unwrap();
449 extensions.push(key_usage).unwrap();
450 let subject_alternative_name = SubjectAlternativeName::new()
451 .dns("example.com")
452 .build(&builder.x509v3_context(None))
453 .unwrap();
454 extensions.push(subject_alternative_name).unwrap();
455 builder.add_extensions(&extensions).unwrap();
456
457 builder.sign(&pkey, MessageDigest::sha256()).unwrap();
458
459 let req = builder.build();
460 assert!(req.public_key().unwrap().public_eq(&pkey));
461 assert_eq!(req.extensions().unwrap().len(), extensions.len());
462 assert!(req.verify(&pkey).unwrap());
463 }
464
465 #[test]
test_stack_from_pem()466 fn test_stack_from_pem() {
467 let certs = include_bytes!("../../test/certs.pem");
468 let certs = X509::stack_from_pem(certs).unwrap();
469
470 assert_eq!(certs.len(), 2);
471 assert_eq!(
472 hex::encode(certs[0].digest(MessageDigest::sha1()).unwrap()),
473 "59172d9313e84459bcff27f967e79e6e9217e584"
474 );
475 assert_eq!(
476 hex::encode(certs[1].digest(MessageDigest::sha1()).unwrap()),
477 "c0cbdf7cdd03c9773e5468e1f6d2da7d5cbb1875"
478 );
479 }
480
481 #[test]
issued()482 fn issued() {
483 let cert = include_bytes!("../../test/cert.pem");
484 let cert = X509::from_pem(cert).unwrap();
485 let ca = include_bytes!("../../test/root-ca.pem");
486 let ca = X509::from_pem(ca).unwrap();
487
488 assert_eq!(ca.issued(&cert), X509VerifyResult::OK);
489 assert_ne!(cert.issued(&cert), X509VerifyResult::OK);
490 }
491
492 #[test]
signature()493 fn signature() {
494 let cert = include_bytes!("../../test/cert.pem");
495 let cert = X509::from_pem(cert).unwrap();
496 let signature = cert.signature();
497 assert_eq!(
498 hex::encode(signature.as_slice()),
499 "4af607b889790b43470442cfa551cdb8b6d0b0340d2958f76b9e3ef6ad4992230cead6842587f0ecad5\
500 78e6e11a221521e940187e3d6652de14e84e82f6671f097cc47932e022add3c0cb54a26bf27fa84c107\
501 4971caa6bee2e42d34a5b066c427f2d452038082b8073993399548088429de034fdd589dcfb0dd33be7\
502 ebdfdf698a28d628a89568881d658151276bde333600969502c4e62e1d3470a683364dfb241f78d310a\
503 89c119297df093eb36b7fd7540224f488806780305d1e79ffc938fe2275441726522ab36d88348e6c51\
504 f13dcc46b5e1cdac23c974fd5ef86aa41e91c9311655090a52333bc79687c748d833595d4c5f987508f\
505 e121997410d37c"
506 );
507 let algorithm = cert.signature_algorithm();
508 assert_eq!(algorithm.object().nid(), Nid::SHA256WITHRSAENCRYPTION);
509 assert_eq!(algorithm.object().to_string(), "sha256WithRSAEncryption");
510 }
511
512 #[test]
513 #[allow(clippy::redundant_clone)]
clone_x509()514 fn clone_x509() {
515 let cert = include_bytes!("../../test/cert.pem");
516 let cert = X509::from_pem(cert).unwrap();
517 drop(cert.clone());
518 }
519
520 #[test]
test_verify_cert()521 fn test_verify_cert() {
522 let cert = include_bytes!("../../test/cert.pem");
523 let cert = X509::from_pem(cert).unwrap();
524 let ca = include_bytes!("../../test/root-ca.pem");
525 let ca = X509::from_pem(ca).unwrap();
526 let chain = Stack::new().unwrap();
527
528 let mut store_bldr = X509StoreBuilder::new().unwrap();
529 store_bldr.add_cert(ca).unwrap();
530 let store = store_bldr.build();
531
532 let mut context = X509StoreContext::new().unwrap();
533 assert!(context
534 .init(&store, &cert, &chain, |c| c.verify_cert())
535 .unwrap());
536 assert!(context
537 .init(&store, &cert, &chain, |c| c.verify_cert())
538 .unwrap());
539 }
540
541 #[test]
test_verify_fails()542 fn test_verify_fails() {
543 let cert = include_bytes!("../../test/cert.pem");
544 let cert = X509::from_pem(cert).unwrap();
545 let ca = include_bytes!("../../test/alt_name_cert.pem");
546 let ca = X509::from_pem(ca).unwrap();
547 let chain = Stack::new().unwrap();
548
549 let mut store_bldr = X509StoreBuilder::new().unwrap();
550 store_bldr.add_cert(ca).unwrap();
551 let store = store_bldr.build();
552
553 let mut context = X509StoreContext::new().unwrap();
554 assert!(!context
555 .init(&store, &cert, &chain, |c| c.verify_cert())
556 .unwrap());
557 }
558
559 #[test]
560 #[cfg(any(ossl102, boringssl, libressl261))]
test_verify_fails_with_crl_flag_set_and_no_crl()561 fn test_verify_fails_with_crl_flag_set_and_no_crl() {
562 let cert = include_bytes!("../../test/cert.pem");
563 let cert = X509::from_pem(cert).unwrap();
564 let ca = include_bytes!("../../test/root-ca.pem");
565 let ca = X509::from_pem(ca).unwrap();
566 let chain = Stack::new().unwrap();
567
568 let mut store_bldr = X509StoreBuilder::new().unwrap();
569 store_bldr.add_cert(ca).unwrap();
570 store_bldr.set_flags(X509VerifyFlags::CRL_CHECK).unwrap();
571 let store = store_bldr.build();
572
573 let mut context = X509StoreContext::new().unwrap();
574 assert_eq!(
575 context
576 .init(&store, &cert, &chain, |c| {
577 c.verify_cert()?;
578 Ok(c.error())
579 })
580 .unwrap()
581 .error_string(),
582 "unable to get certificate CRL"
583 )
584 }
585
586 #[test]
587 #[cfg(any(ossl102, boringssl, libressl261))]
test_verify_cert_with_purpose()588 fn test_verify_cert_with_purpose() {
589 let cert = include_bytes!("../../test/cert.pem");
590 let cert = X509::from_pem(cert).unwrap();
591 let ca = include_bytes!("../../test/root-ca.pem");
592 let ca = X509::from_pem(ca).unwrap();
593 let chain = Stack::new().unwrap();
594
595 let mut store_bldr = X509StoreBuilder::new().unwrap();
596 let purpose_idx = X509PurposeRef::get_by_sname("sslserver")
597 .expect("Getting certificate purpose 'sslserver' failed");
598 let x509_purposeref =
599 X509PurposeRef::from_idx(purpose_idx).expect("Getting certificate purpose failed");
600 store_bldr
601 .set_purpose(x509_purposeref.purpose())
602 .expect("Setting certificate purpose failed");
603 store_bldr.add_cert(ca).unwrap();
604
605 let store = store_bldr.build();
606
607 let mut context = X509StoreContext::new().unwrap();
608 assert!(context
609 .init(&store, &cert, &chain, |c| c.verify_cert())
610 .unwrap());
611 }
612
613 #[test]
614 #[cfg(any(ossl102, boringssl, libressl261))]
test_verify_cert_with_wrong_purpose_fails()615 fn test_verify_cert_with_wrong_purpose_fails() {
616 let cert = include_bytes!("../../test/cert.pem");
617 let cert = X509::from_pem(cert).unwrap();
618 let ca = include_bytes!("../../test/root-ca.pem");
619 let ca = X509::from_pem(ca).unwrap();
620 let chain = Stack::new().unwrap();
621
622 let mut store_bldr = X509StoreBuilder::new().unwrap();
623 let purpose_idx = X509PurposeRef::get_by_sname("timestampsign")
624 .expect("Getting certificate purpose 'timestampsign' failed");
625 let x509_purpose =
626 X509PurposeRef::from_idx(purpose_idx).expect("Getting certificate purpose failed");
627 store_bldr
628 .set_purpose(x509_purpose.purpose())
629 .expect("Setting certificate purpose failed");
630 store_bldr.add_cert(ca).unwrap();
631
632 let store = store_bldr.build();
633
634 let expected_error = ffi::X509_V_ERR_INVALID_PURPOSE;
635 let mut context = X509StoreContext::new().unwrap();
636 assert_eq!(
637 context
638 .init(&store, &cert, &chain, |c| {
639 c.verify_cert()?;
640 Ok(c.error())
641 })
642 .unwrap()
643 .as_raw(),
644 expected_error
645 )
646 }
647
648 #[cfg(ossl110)]
649 #[test]
x509_ref_version()650 fn x509_ref_version() {
651 let mut builder = X509Builder::new().unwrap();
652 let expected_version = 2;
653 builder
654 .set_version(expected_version)
655 .expect("Failed to set certificate version");
656 let cert = builder.build();
657 let actual_version = cert.version();
658 assert_eq!(
659 expected_version, actual_version,
660 "Obtained certificate version is incorrect",
661 );
662 }
663
664 #[cfg(ossl110)]
665 #[test]
x509_ref_version_no_version_set()666 fn x509_ref_version_no_version_set() {
667 let cert = X509Builder::new().unwrap().build();
668 let actual_version = cert.version();
669 assert_eq!(
670 0, actual_version,
671 "Default certificate version is incorrect",
672 );
673 }
674
675 #[test]
test_load_crl()676 fn test_load_crl() {
677 let ca = include_bytes!("../../test/crl-ca.crt");
678 let ca = X509::from_pem(ca).unwrap();
679
680 let crl = include_bytes!("../../test/test.crl");
681 let crl = X509Crl::from_der(crl).unwrap();
682 assert!(crl.verify(&ca.public_key().unwrap()).unwrap());
683
684 let cert = include_bytes!("../../test/subca.crt");
685 let cert = X509::from_pem(cert).unwrap();
686
687 let revoked = match crl.get_by_cert(&cert) {
688 CrlStatus::Revoked(revoked) => revoked,
689 _ => panic!("cert should be revoked"),
690 };
691
692 assert_eq!(
693 revoked.serial_number().to_bn().unwrap(),
694 cert.serial_number().to_bn().unwrap(),
695 "revoked and cert serial numbers should match"
696 );
697 }
698
699 #[test]
test_crl_entry_extensions()700 fn test_crl_entry_extensions() {
701 let crl = include_bytes!("../../test/entry_extensions.crl");
702 let crl = X509Crl::from_pem(crl).unwrap();
703
704 let (critical, access_info) = crl
705 .extension::<AuthorityInformationAccess>()
706 .unwrap()
707 .expect("Authority Information Access extension should be present");
708 assert!(
709 !critical,
710 "Authority Information Access extension is not critical"
711 );
712 assert_eq!(
713 access_info.len(),
714 1,
715 "Authority Information Access should have one entry"
716 );
717 assert_eq!(access_info[0].method().to_string(), "CA Issuers");
718 assert_eq!(
719 access_info[0].location().uri(),
720 Some("http://www.example.com/ca.crt")
721 );
722 let revoked_certs = crl.get_revoked().unwrap();
723 let entry = &revoked_certs[0];
724
725 let (critical, issuer) = entry
726 .extension::<CertificateIssuer>()
727 .unwrap()
728 .expect("Certificate issuer extension should be present");
729 assert!(critical, "Certificate issuer extension is critical");
730 assert_eq!(issuer.len(), 1, "Certificate issuer should have one entry");
731 let issuer = issuer[0]
732 .directory_name()
733 .expect("Issuer should be a directory name");
734 assert_eq!(
735 format!("{:?}", issuer),
736 r#"[countryName = "GB", commonName = "Test CA"]"#
737 );
738
739 // reason_code can't be inspected without ossl110
740 #[allow(unused_variables)]
741 let (critical, reason_code) = entry
742 .extension::<ReasonCode>()
743 .unwrap()
744 .expect("Reason code extension should be present");
745 assert!(!critical, "Reason code extension is not critical");
746 #[cfg(ossl110)]
747 assert_eq!(
748 CrlReason::KEY_COMPROMISE,
749 CrlReason::from_raw(reason_code.get_i64().unwrap() as ffi::c_int)
750 );
751 }
752
753 #[test]
test_save_subject_der()754 fn test_save_subject_der() {
755 let cert = include_bytes!("../../test/cert.pem");
756 let cert = X509::from_pem(cert).unwrap();
757
758 let der = cert.subject_name().to_der().unwrap();
759 println!("der: {:?}", der);
760 assert!(!der.is_empty());
761 }
762
763 #[test]
test_load_subject_der()764 fn test_load_subject_der() {
765 // The subject from ../../test/cert.pem
766 const SUBJECT_DER: &[u8] = &[
767 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,
768 10, 83, 111, 109, 101, 45, 83, 116, 97, 116, 101, 49, 33, 48, 31, 6, 3, 85, 4, 10, 12, 24,
769 73, 110, 116, 101, 114, 110, 101, 116, 32, 87, 105, 100, 103, 105, 116, 115, 32, 80, 116,
770 121, 32, 76, 116, 100, 49, 19, 48, 17, 6, 3, 85, 4, 3, 12, 10, 102, 111, 111, 98, 97, 114,
771 46, 99, 111, 109,
772 ];
773 X509Name::from_der(SUBJECT_DER).unwrap();
774 }
775
776 #[test]
test_convert_to_text()777 fn test_convert_to_text() {
778 let cert = include_bytes!("../../test/cert.pem");
779 let cert = X509::from_pem(cert).unwrap();
780
781 const SUBSTRINGS: &[&str] = &[
782 "Certificate:\n",
783 "Serial Number:",
784 "Signature Algorithm:",
785 "Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd\n",
786 "Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=foobar.com\n",
787 "Subject Public Key Info:",
788 ];
789
790 let text = String::from_utf8(cert.to_text().unwrap()).unwrap();
791
792 for substring in SUBSTRINGS {
793 assert!(
794 text.contains(substring),
795 "{:?} not found inside {}",
796 substring,
797 text
798 );
799 }
800 }
801
802 #[test]
test_convert_req_to_text()803 fn test_convert_req_to_text() {
804 let csr = include_bytes!("../../test/csr.pem");
805 let csr = X509Req::from_pem(csr).unwrap();
806
807 const SUBSTRINGS: &[&str] = &[
808 "Certificate Request:\n",
809 "Version:",
810 "Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=foobar.com\n",
811 "Subject Public Key Info:",
812 "Signature Algorithm:",
813 ];
814
815 let text = String::from_utf8(csr.to_text().unwrap()).unwrap();
816
817 for substring in SUBSTRINGS {
818 assert!(
819 text.contains(substring),
820 "{:?} not found inside {}",
821 substring,
822 text
823 );
824 }
825 }
826
827 #[test]
test_name_cmp()828 fn test_name_cmp() {
829 let cert = include_bytes!("../../test/cert.pem");
830 let cert = X509::from_pem(cert).unwrap();
831
832 let subject = cert.subject_name();
833 let issuer = cert.issuer_name();
834 assert_eq!(Ordering::Equal, subject.try_cmp(subject).unwrap());
835 assert_eq!(Ordering::Greater, subject.try_cmp(issuer).unwrap());
836 }
837
838 #[test]
839 #[cfg(any(boringssl, ossl110, libressl270))]
test_name_to_owned()840 fn test_name_to_owned() {
841 let cert = include_bytes!("../../test/cert.pem");
842 let cert = X509::from_pem(cert).unwrap();
843 let name = cert.subject_name();
844 let copied_name = name.to_owned().unwrap();
845 assert_eq!(Ordering::Equal, name.try_cmp(&copied_name).unwrap());
846 }
847
848 #[test]
849 #[cfg(any(ossl102, boringssl, libressl261))]
test_verify_param_set_time_fails_verification()850 fn test_verify_param_set_time_fails_verification() {
851 const TEST_T_2030: time_t = 1893456000;
852
853 let cert = include_bytes!("../../test/cert.pem");
854 let cert = X509::from_pem(cert).unwrap();
855 let ca = include_bytes!("../../test/root-ca.pem");
856 let ca = X509::from_pem(ca).unwrap();
857 let chain = Stack::new().unwrap();
858
859 let mut store_bldr = X509StoreBuilder::new().unwrap();
860 store_bldr.add_cert(ca).unwrap();
861 let mut verify_params = X509VerifyParam::new().unwrap();
862 verify_params.set_time(TEST_T_2030);
863 store_bldr.set_param(&verify_params).unwrap();
864 let store = store_bldr.build();
865
866 let mut context = X509StoreContext::new().unwrap();
867 assert_eq!(
868 context
869 .init(&store, &cert, &chain, |c| {
870 c.verify_cert()?;
871 Ok(c.error())
872 })
873 .unwrap()
874 .error_string(),
875 "certificate has expired"
876 )
877 }
878
879 #[test]
880 #[cfg(any(ossl102, boringssl, libressl261))]
test_verify_param_set_time()881 fn test_verify_param_set_time() {
882 const TEST_T_2020: time_t = 1577836800;
883
884 let cert = include_bytes!("../../test/cert.pem");
885 let cert = X509::from_pem(cert).unwrap();
886 let ca = include_bytes!("../../test/root-ca.pem");
887 let ca = X509::from_pem(ca).unwrap();
888 let chain = Stack::new().unwrap();
889
890 let mut store_bldr = X509StoreBuilder::new().unwrap();
891 store_bldr.add_cert(ca).unwrap();
892 let mut verify_params = X509VerifyParam::new().unwrap();
893 verify_params.set_time(TEST_T_2020);
894 store_bldr.set_param(&verify_params).unwrap();
895 let store = store_bldr.build();
896
897 let mut context = X509StoreContext::new().unwrap();
898 assert!(context
899 .init(&store, &cert, &chain, |c| c.verify_cert())
900 .unwrap());
901 }
902
903 #[test]
904 #[cfg(any(ossl102, boringssl, libressl261))]
test_verify_param_set_depth()905 fn test_verify_param_set_depth() {
906 let cert = include_bytes!("../../test/leaf.pem");
907 let cert = X509::from_pem(cert).unwrap();
908 let intermediate_ca = include_bytes!("../../test/intermediate-ca.pem");
909 let intermediate_ca = X509::from_pem(intermediate_ca).unwrap();
910 let ca = include_bytes!("../../test/root-ca.pem");
911 let ca = X509::from_pem(ca).unwrap();
912 let mut chain = Stack::new().unwrap();
913 chain.push(intermediate_ca).unwrap();
914
915 let mut store_bldr = X509StoreBuilder::new().unwrap();
916 store_bldr.add_cert(ca).unwrap();
917 let mut verify_params = X509VerifyParam::new().unwrap();
918 // OpenSSL 1.1.0+ considers the root certificate to not be part of the chain, while 1.0.2 and LibreSSL do
919 let expected_depth = if cfg!(any(ossl110)) { 1 } else { 2 };
920 verify_params.set_depth(expected_depth);
921 store_bldr.set_param(&verify_params).unwrap();
922 let store = store_bldr.build();
923
924 let mut context = X509StoreContext::new().unwrap();
925 assert!(context
926 .init(&store, &cert, &chain, |c| c.verify_cert())
927 .unwrap());
928 }
929
930 #[test]
931 #[cfg(any(ossl102, boringssl, libressl261))]
932 #[allow(clippy::bool_to_int_with_if)]
test_verify_param_set_depth_fails_verification()933 fn test_verify_param_set_depth_fails_verification() {
934 let cert = include_bytes!("../../test/leaf.pem");
935 let cert = X509::from_pem(cert).unwrap();
936 let intermediate_ca = include_bytes!("../../test/intermediate-ca.pem");
937 let intermediate_ca = X509::from_pem(intermediate_ca).unwrap();
938 let ca = include_bytes!("../../test/root-ca.pem");
939 let ca = X509::from_pem(ca).unwrap();
940 let mut chain = Stack::new().unwrap();
941 chain.push(intermediate_ca).unwrap();
942
943 let mut store_bldr = X509StoreBuilder::new().unwrap();
944 store_bldr.add_cert(ca).unwrap();
945 let mut verify_params = X509VerifyParam::new().unwrap();
946 // OpenSSL 1.1.0+ considers the root certificate to not be part of the chain, while 1.0.2 and LibreSSL do
947 let expected_depth = if cfg!(any(ossl110)) { 0 } else { 1 };
948 verify_params.set_depth(expected_depth);
949 store_bldr.set_param(&verify_params).unwrap();
950 let store = store_bldr.build();
951
952 // OpenSSL 1.1.0+ added support for X509_V_ERR_CERT_CHAIN_TOO_LONG, while 1.0.2 simply ignores the intermediate
953 let expected_error = if cfg!(any(ossl110, libressl261)) {
954 "certificate chain too long"
955 } else {
956 "unable to get local issuer certificate"
957 };
958
959 let mut context = X509StoreContext::new().unwrap();
960 assert_eq!(
961 context
962 .init(&store, &cert, &chain, |c| {
963 c.verify_cert()?;
964 Ok(c.error())
965 })
966 .unwrap()
967 .error_string(),
968 expected_error
969 )
970 }
971
972 #[test]
973 #[cfg(not(boringssl))]
test_load_cert_file()974 fn test_load_cert_file() {
975 let cert = include_bytes!("../../test/cert.pem");
976 let cert = X509::from_pem(cert).unwrap();
977 let chain = Stack::new().unwrap();
978
979 let mut store_bldr = X509StoreBuilder::new().unwrap();
980 let lookup = store_bldr.add_lookup(X509Lookup::file()).unwrap();
981 lookup
982 .load_cert_file("test/root-ca.pem", SslFiletype::PEM)
983 .unwrap();
984 let store = store_bldr.build();
985
986 let mut context = X509StoreContext::new().unwrap();
987 assert!(context
988 .init(&store, &cert, &chain, |c| c.verify_cert())
989 .unwrap());
990 }
991
992 #[test]
993 #[cfg(ossl110)]
test_verify_param_auth_level()994 fn test_verify_param_auth_level() {
995 let mut param = X509VerifyParam::new().unwrap();
996 let auth_lvl = 2;
997 let auth_lvl_default = -1;
998
999 assert_eq!(param.auth_level(), auth_lvl_default);
1000
1001 param.set_auth_level(auth_lvl);
1002 assert_eq!(param.auth_level(), auth_lvl);
1003 }
1004
1005 #[test]
1006 #[cfg(any(ossl102, boringssl))]
test_set_purpose()1007 fn test_set_purpose() {
1008 let cert = include_bytes!("../../test/leaf.pem");
1009 let cert = X509::from_pem(cert).unwrap();
1010 let intermediate_ca = include_bytes!("../../test/intermediate-ca.pem");
1011 let intermediate_ca = X509::from_pem(intermediate_ca).unwrap();
1012 let ca = include_bytes!("../../test/root-ca.pem");
1013 let ca = X509::from_pem(ca).unwrap();
1014 let mut chain = Stack::new().unwrap();
1015 chain.push(intermediate_ca).unwrap();
1016
1017 let mut store_bldr = X509StoreBuilder::new().unwrap();
1018 store_bldr.add_cert(ca).unwrap();
1019 let mut verify_params = X509VerifyParam::new().unwrap();
1020 verify_params.set_purpose(X509PurposeId::ANY).unwrap();
1021 store_bldr.set_param(&verify_params).unwrap();
1022 let store = store_bldr.build();
1023 let mut context = X509StoreContext::new().unwrap();
1024
1025 assert!(context
1026 .init(&store, &cert, &chain, |c| c.verify_cert())
1027 .unwrap());
1028 }
1029
1030 #[test]
1031 #[cfg(any(ossl102, boringssl))]
test_set_purpose_fails_verification()1032 fn test_set_purpose_fails_verification() {
1033 let cert = include_bytes!("../../test/leaf.pem");
1034 let cert = X509::from_pem(cert).unwrap();
1035 let intermediate_ca = include_bytes!("../../test/intermediate-ca.pem");
1036 let intermediate_ca = X509::from_pem(intermediate_ca).unwrap();
1037 let ca = include_bytes!("../../test/root-ca.pem");
1038 let ca = X509::from_pem(ca).unwrap();
1039 let mut chain = Stack::new().unwrap();
1040 chain.push(intermediate_ca).unwrap();
1041
1042 let mut store_bldr = X509StoreBuilder::new().unwrap();
1043 store_bldr.add_cert(ca).unwrap();
1044 let mut verify_params = X509VerifyParam::new().unwrap();
1045 verify_params
1046 .set_purpose(X509PurposeId::TIMESTAMP_SIGN)
1047 .unwrap();
1048 store_bldr.set_param(&verify_params).unwrap();
1049 let store = store_bldr.build();
1050
1051 let expected_error = ffi::X509_V_ERR_INVALID_PURPOSE;
1052 let mut context = X509StoreContext::new().unwrap();
1053 assert_eq!(
1054 context
1055 .init(&store, &cert, &chain, |c| {
1056 c.verify_cert()?;
1057 Ok(c.error())
1058 })
1059 .unwrap()
1060 .as_raw(),
1061 expected_error
1062 )
1063 }
1064
1065 #[test]
1066 #[cfg(any(ossl101, libressl350))]
test_add_name_entry()1067 fn test_add_name_entry() {
1068 let cert = include_bytes!("../../test/cert.pem");
1069 let cert = X509::from_pem(cert).unwrap();
1070 let inp_name = cert.subject_name().entries().next().unwrap();
1071
1072 let mut names = X509Name::builder().unwrap();
1073 names.append_entry(inp_name).unwrap();
1074 let names = names.build();
1075
1076 let mut entries = names.entries();
1077 let outp_name = entries.next().unwrap();
1078 assert_eq!(outp_name.object().nid(), inp_name.object().nid());
1079 assert_eq!(outp_name.data().as_slice(), inp_name.data().as_slice());
1080 assert!(entries.next().is_none());
1081 }
1082
1083 #[test]
1084 #[cfg(not(boringssl))]
test_load_crl_file_fail()1085 fn test_load_crl_file_fail() {
1086 let mut store_bldr = X509StoreBuilder::new().unwrap();
1087 let lookup = store_bldr.add_lookup(X509Lookup::file()).unwrap();
1088 let res = lookup.load_crl_file("test/root-ca.pem", SslFiletype::PEM);
1089 assert!(res.is_err());
1090 }
1091
1092 #[cfg(ossl110)]
ipaddress_as_subject_alternative_name_is_formatted_in_debug<T>(expected_ip: T) where T: Into<std::net::IpAddr>,1093 fn ipaddress_as_subject_alternative_name_is_formatted_in_debug<T>(expected_ip: T)
1094 where
1095 T: Into<std::net::IpAddr>,
1096 {
1097 let expected_ip = format!("{:?}", expected_ip.into());
1098 let mut builder = X509Builder::new().unwrap();
1099 let san = SubjectAlternativeName::new()
1100 .ip(&expected_ip)
1101 .build(&builder.x509v3_context(None, None))
1102 .unwrap();
1103 builder.append_extension(san).unwrap();
1104 let cert = builder.build();
1105 let actual_ip = cert
1106 .subject_alt_names()
1107 .into_iter()
1108 .flatten()
1109 .map(|n| format!("{:?}", *n))
1110 .next()
1111 .unwrap();
1112 assert_eq!(actual_ip, expected_ip);
1113 }
1114
1115 #[cfg(ossl110)]
1116 #[test]
ipv4_as_subject_alternative_name_is_formatted_in_debug()1117 fn ipv4_as_subject_alternative_name_is_formatted_in_debug() {
1118 ipaddress_as_subject_alternative_name_is_formatted_in_debug([8u8, 8, 8, 128]);
1119 }
1120
1121 #[cfg(ossl110)]
1122 #[test]
ipv6_as_subject_alternative_name_is_formatted_in_debug()1123 fn ipv6_as_subject_alternative_name_is_formatted_in_debug() {
1124 ipaddress_as_subject_alternative_name_is_formatted_in_debug([
1125 8u8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 128,
1126 ]);
1127 }
1128
1129 #[cfg(ossl110)]
1130 #[test]
other_name_as_subject_alternative_name()1131 fn other_name_as_subject_alternative_name() {
1132 let oid = Asn1Object::from_str("1.3.6.1.5.5.7.8.11").unwrap();
1133 // this is the hex representation of "test" encoded as a ia5string
1134 let content = [0x16, 0x04, 0x74, 0x65, 0x73, 0x74];
1135
1136 let mut builder = X509Builder::new().unwrap();
1137 let san = SubjectAlternativeName::new()
1138 .other_name2(oid, &content)
1139 .build(&builder.x509v3_context(None, None))
1140 .unwrap();
1141 builder.append_extension(san).unwrap();
1142 let cert = builder.build();
1143 let general_name = cert
1144 .subject_alt_names()
1145 .into_iter()
1146 .flatten()
1147 .next()
1148 .unwrap();
1149 unsafe {
1150 assert_eq!((*general_name.as_ptr()).type_, 0);
1151 }
1152 }
1153
1154 #[test]
test_dist_point()1155 fn test_dist_point() {
1156 let cert = include_bytes!("../../test/certv3.pem");
1157 let cert = X509::from_pem(cert).unwrap();
1158
1159 let dps = cert.crl_distribution_points().unwrap();
1160 let dp = dps.get(0).unwrap();
1161 let dp_nm = dp.distpoint().unwrap();
1162 let dp_gns = dp_nm.fullname().unwrap();
1163 let dp_gn = dp_gns.get(0).unwrap();
1164 assert_eq!(dp_gn.uri().unwrap(), "http://example.com/crl.pem");
1165
1166 let dp = dps.get(1).unwrap();
1167 let dp_nm = dp.distpoint().unwrap();
1168 let dp_gns = dp_nm.fullname().unwrap();
1169 let dp_gn = dp_gns.get(0).unwrap();
1170 assert_eq!(dp_gn.uri().unwrap(), "http://example.com/crl2.pem");
1171 assert!(dps.get(2).is_none())
1172 }
1173
1174 #[test]
test_dist_point_null()1175 fn test_dist_point_null() {
1176 let cert = include_bytes!("../../test/cert.pem");
1177 let cert = X509::from_pem(cert).unwrap();
1178 assert!(cert.crl_distribution_points().is_none());
1179 }
1180
1181 #[test]
1182 #[cfg(ossl300)]
test_store_all_certificates()1183 fn test_store_all_certificates() {
1184 let cert = include_bytes!("../../test/cert.pem");
1185 let cert = X509::from_pem(cert).unwrap();
1186
1187 let store = {
1188 let mut b = X509StoreBuilder::new().unwrap();
1189 b.add_cert(cert).unwrap();
1190 b.build()
1191 };
1192
1193 assert_eq!(store.all_certificates().len(), 1);
1194 }
1195