1 use asn1::Asn1Time;
2 use bn::{BigNum, MsbOption};
3 use hash::MessageDigest;
4 use hex::{self, FromHex};
5 use nid::Nid;
6 use pkey::{PKey, Private};
7 use rsa::Rsa;
8 use stack::Stack;
9 use x509::extension::{
10     AuthorityKeyIdentifier, BasicConstraints, ExtendedKeyUsage, KeyUsage, SubjectAlternativeName,
11     SubjectKeyIdentifier,
12 };
13 use x509::store::X509StoreBuilder;
14 #[cfg(ossl110)]
15 use x509::X509Builder;
16 use x509::{X509Name, X509Req, X509StoreContext, X509VerifyResult, X509};
17 
pkey() -> PKey<Private>18 fn pkey() -> PKey<Private> {
19     let rsa = Rsa::generate(2048).unwrap();
20     PKey::from_rsa(rsa).unwrap()
21 }
22 
23 #[test]
test_cert_loading()24 fn test_cert_loading() {
25     let cert = include_bytes!("../../test/cert.pem");
26     let cert = X509::from_pem(cert).unwrap();
27     let fingerprint = cert.digest(MessageDigest::sha1()).unwrap();
28 
29     let hash_str = "59172d9313e84459bcff27f967e79e6e9217e584";
30     let hash_vec = Vec::from_hex(hash_str).unwrap();
31 
32     assert_eq!(hash_vec, &*fingerprint);
33 }
34 
35 #[test]
test_debug()36 fn test_debug() {
37     let cert = include_bytes!("../../test/cert.pem");
38     let cert = X509::from_pem(cert).unwrap();
39     let debugged = format!("{:#?}", cert);
40     assert!(debugged.contains(r#"serial_number: "8771F7BDEE982FA5""#));
41     assert!(debugged.contains(r#"signature_algorithm: sha256WithRSAEncryption"#));
42     assert!(debugged.contains(r#"countryName = "AU""#));
43     assert!(debugged.contains(r#"stateOrProvinceName = "Some-State""#));
44     assert!(debugged.contains(r#"not_before: Aug 14 17:00:03 2016 GMT"#));
45     assert!(debugged.contains(r#"not_after: Aug 12 17:00:03 2026 GMT"#));
46 }
47 
48 #[test]
test_cert_issue_validity()49 fn test_cert_issue_validity() {
50     let cert = include_bytes!("../../test/cert.pem");
51     let cert = X509::from_pem(cert).unwrap();
52     let not_before = cert.not_before().to_string();
53     let not_after = cert.not_after().to_string();
54 
55     assert_eq!(not_before, "Aug 14 17:00:03 2016 GMT");
56     assert_eq!(not_after, "Aug 12 17:00:03 2026 GMT");
57 }
58 
59 #[test]
test_save_der()60 fn test_save_der() {
61     let cert = include_bytes!("../../test/cert.pem");
62     let cert = X509::from_pem(cert).unwrap();
63 
64     let der = cert.to_der().unwrap();
65     assert!(!der.is_empty());
66 }
67 
68 #[test]
test_subject_read_cn()69 fn test_subject_read_cn() {
70     let cert = include_bytes!("../../test/cert.pem");
71     let cert = X509::from_pem(cert).unwrap();
72     let subject = cert.subject_name();
73     let cn = subject.entries_by_nid(Nid::COMMONNAME).next().unwrap();
74     assert_eq!(cn.data().as_slice(), b"foobar.com")
75 }
76 
77 #[test]
test_nid_values()78 fn test_nid_values() {
79     let cert = include_bytes!("../../test/nid_test_cert.pem");
80     let cert = X509::from_pem(cert).unwrap();
81     let subject = cert.subject_name();
82 
83     let cn = subject.entries_by_nid(Nid::COMMONNAME).next().unwrap();
84     assert_eq!(cn.data().as_slice(), b"example.com");
85 
86     let email = subject
87         .entries_by_nid(Nid::PKCS9_EMAILADDRESS)
88         .next()
89         .unwrap();
90     assert_eq!(email.data().as_slice(), b"test@example.com");
91 
92     let friendly = subject.entries_by_nid(Nid::FRIENDLYNAME).next().unwrap();
93     assert_eq!(&**friendly.data().as_utf8().unwrap(), "Example");
94 }
95 
96 #[test]
test_nameref_iterator()97 fn test_nameref_iterator() {
98     let cert = include_bytes!("../../test/nid_test_cert.pem");
99     let cert = X509::from_pem(cert).unwrap();
100     let subject = cert.subject_name();
101     let mut all_entries = subject.entries();
102 
103     let email = all_entries.next().unwrap();
104     assert_eq!(
105         email.object().nid().as_raw(),
106         Nid::PKCS9_EMAILADDRESS.as_raw()
107     );
108     assert_eq!(email.data().as_slice(), b"test@example.com");
109 
110     let cn = all_entries.next().unwrap();
111     assert_eq!(cn.object().nid().as_raw(), Nid::COMMONNAME.as_raw());
112     assert_eq!(cn.data().as_slice(), b"example.com");
113 
114     let friendly = all_entries.next().unwrap();
115     assert_eq!(friendly.object().nid().as_raw(), Nid::FRIENDLYNAME.as_raw());
116     assert_eq!(&**friendly.data().as_utf8().unwrap(), "Example");
117 
118     if all_entries.next().is_some() {
119         panic!();
120     }
121 }
122 
123 #[test]
test_nid_uid_value()124 fn test_nid_uid_value() {
125     let cert = include_bytes!("../../test/nid_uid_test_cert.pem");
126     let cert = X509::from_pem(cert).unwrap();
127     let subject = cert.subject_name();
128 
129     let cn = subject.entries_by_nid(Nid::USERID).next().unwrap();
130     assert_eq!(cn.data().as_slice(), b"this is the userId");
131 }
132 
133 #[test]
test_subject_alt_name()134 fn test_subject_alt_name() {
135     let cert = include_bytes!("../../test/alt_name_cert.pem");
136     let cert = X509::from_pem(cert).unwrap();
137 
138     let subject_alt_names = cert.subject_alt_names().unwrap();
139     assert_eq!(5, subject_alt_names.len());
140     assert_eq!(Some("example.com"), subject_alt_names[0].dnsname());
141     assert_eq!(subject_alt_names[1].ipaddress(), Some(&[127, 0, 0, 1][..]));
142     assert_eq!(
143         subject_alt_names[2].ipaddress(),
144         Some(&b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01"[..])
145     );
146     assert_eq!(Some("test@example.com"), subject_alt_names[3].email());
147     assert_eq!(Some("http://www.example.com"), subject_alt_names[4].uri());
148 }
149 
150 #[test]
test_subject_alt_name_iter()151 fn test_subject_alt_name_iter() {
152     let cert = include_bytes!("../../test/alt_name_cert.pem");
153     let cert = X509::from_pem(cert).unwrap();
154 
155     let subject_alt_names = cert.subject_alt_names().unwrap();
156     let mut subject_alt_names_iter = subject_alt_names.iter();
157     assert_eq!(
158         subject_alt_names_iter.next().unwrap().dnsname(),
159         Some("example.com")
160     );
161     assert_eq!(
162         subject_alt_names_iter.next().unwrap().ipaddress(),
163         Some(&[127, 0, 0, 1][..])
164     );
165     assert_eq!(
166         subject_alt_names_iter.next().unwrap().ipaddress(),
167         Some(&b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01"[..])
168     );
169     assert_eq!(
170         subject_alt_names_iter.next().unwrap().email(),
171         Some("test@example.com")
172     );
173     assert_eq!(
174         subject_alt_names_iter.next().unwrap().uri(),
175         Some("http://www.example.com")
176     );
177     assert!(subject_alt_names_iter.next().is_none());
178 }
179 
180 #[test]
x509_builder()181 fn x509_builder() {
182     let pkey = pkey();
183 
184     let mut name = X509Name::builder().unwrap();
185     name.append_entry_by_nid(Nid::COMMONNAME, "foobar.com")
186         .unwrap();
187     let name = name.build();
188 
189     let mut builder = X509::builder().unwrap();
190     builder.set_version(2).unwrap();
191     builder.set_subject_name(&name).unwrap();
192     builder.set_issuer_name(&name).unwrap();
193     builder
194         .set_not_before(&Asn1Time::days_from_now(0).unwrap())
195         .unwrap();
196     builder
197         .set_not_after(&Asn1Time::days_from_now(365).unwrap())
198         .unwrap();
199     builder.set_pubkey(&pkey).unwrap();
200 
201     let mut serial = BigNum::new().unwrap();
202     serial.rand(128, MsbOption::MAYBE_ZERO, false).unwrap();
203     builder
204         .set_serial_number(&serial.to_asn1_integer().unwrap())
205         .unwrap();
206 
207     let basic_constraints = BasicConstraints::new().critical().ca().build().unwrap();
208     builder.append_extension(basic_constraints).unwrap();
209     let key_usage = KeyUsage::new()
210         .digital_signature()
211         .key_encipherment()
212         .build()
213         .unwrap();
214     builder.append_extension(key_usage).unwrap();
215     let ext_key_usage = ExtendedKeyUsage::new()
216         .client_auth()
217         .server_auth()
218         .other("2.999.1")
219         .build()
220         .unwrap();
221     builder.append_extension(ext_key_usage).unwrap();
222     let subject_key_identifier = SubjectKeyIdentifier::new()
223         .build(&builder.x509v3_context(None, None))
224         .unwrap();
225     builder.append_extension(subject_key_identifier).unwrap();
226     let authority_key_identifier = AuthorityKeyIdentifier::new()
227         .keyid(true)
228         .build(&builder.x509v3_context(None, None))
229         .unwrap();
230     builder.append_extension(authority_key_identifier).unwrap();
231     let subject_alternative_name = SubjectAlternativeName::new()
232         .dns("example.com")
233         .build(&builder.x509v3_context(None, None))
234         .unwrap();
235     builder.append_extension(subject_alternative_name).unwrap();
236 
237     builder.sign(&pkey, MessageDigest::sha256()).unwrap();
238 
239     let x509 = builder.build();
240 
241     assert!(pkey.public_eq(&x509.public_key().unwrap()));
242     assert!(x509.verify(&pkey).unwrap());
243 
244     let cn = x509
245         .subject_name()
246         .entries_by_nid(Nid::COMMONNAME)
247         .next()
248         .unwrap();
249     assert_eq!(cn.data().as_slice(), b"foobar.com");
250     assert_eq!(serial, x509.serial_number().to_bn().unwrap());
251 }
252 
253 #[test]
x509_req_builder()254 fn x509_req_builder() {
255     let pkey = pkey();
256 
257     let mut name = X509Name::builder().unwrap();
258     name.append_entry_by_nid(Nid::COMMONNAME, "foobar.com")
259         .unwrap();
260     let name = name.build();
261 
262     let mut builder = X509Req::builder().unwrap();
263     builder.set_version(2).unwrap();
264     builder.set_subject_name(&name).unwrap();
265     builder.set_pubkey(&pkey).unwrap();
266 
267     let mut extensions = Stack::new().unwrap();
268     let key_usage = KeyUsage::new()
269         .digital_signature()
270         .key_encipherment()
271         .build()
272         .unwrap();
273     extensions.push(key_usage).unwrap();
274     let subject_alternative_name = SubjectAlternativeName::new()
275         .dns("example.com")
276         .build(&builder.x509v3_context(None))
277         .unwrap();
278     extensions.push(subject_alternative_name).unwrap();
279     builder.add_extensions(&extensions).unwrap();
280 
281     builder.sign(&pkey, MessageDigest::sha256()).unwrap();
282 
283     let req = builder.build();
284     assert!(req.public_key().unwrap().public_eq(&pkey));
285     assert_eq!(req.extensions().unwrap().len(), extensions.len());
286     assert!(req.verify(&pkey).unwrap());
287 }
288 
289 #[test]
test_stack_from_pem()290 fn test_stack_from_pem() {
291     let certs = include_bytes!("../../test/certs.pem");
292     let certs = X509::stack_from_pem(certs).unwrap();
293 
294     assert_eq!(certs.len(), 2);
295     assert_eq!(
296         hex::encode(certs[0].digest(MessageDigest::sha1()).unwrap()),
297         "59172d9313e84459bcff27f967e79e6e9217e584"
298     );
299     assert_eq!(
300         hex::encode(certs[1].digest(MessageDigest::sha1()).unwrap()),
301         "c0cbdf7cdd03c9773e5468e1f6d2da7d5cbb1875"
302     );
303 }
304 
305 #[test]
issued()306 fn issued() {
307     let cert = include_bytes!("../../test/cert.pem");
308     let cert = X509::from_pem(cert).unwrap();
309     let ca = include_bytes!("../../test/root-ca.pem");
310     let ca = X509::from_pem(ca).unwrap();
311 
312     assert_eq!(ca.issued(&cert), X509VerifyResult::OK);
313     assert_ne!(cert.issued(&cert), X509VerifyResult::OK);
314 }
315 
316 #[test]
signature()317 fn signature() {
318     let cert = include_bytes!("../../test/cert.pem");
319     let cert = X509::from_pem(cert).unwrap();
320     let signature = cert.signature();
321     assert_eq!(
322         hex::encode(signature.as_slice()),
323         "4af607b889790b43470442cfa551cdb8b6d0b0340d2958f76b9e3ef6ad4992230cead6842587f0ecad5\
324          78e6e11a221521e940187e3d6652de14e84e82f6671f097cc47932e022add3c0cb54a26bf27fa84c107\
325          4971caa6bee2e42d34a5b066c427f2d452038082b8073993399548088429de034fdd589dcfb0dd33be7\
326          ebdfdf698a28d628a89568881d658151276bde333600969502c4e62e1d3470a683364dfb241f78d310a\
327          89c119297df093eb36b7fd7540224f488806780305d1e79ffc938fe2275441726522ab36d88348e6c51\
328          f13dcc46b5e1cdac23c974fd5ef86aa41e91c9311655090a52333bc79687c748d833595d4c5f987508f\
329          e121997410d37c"
330     );
331     let algorithm = cert.signature_algorithm();
332     assert_eq!(algorithm.object().nid(), Nid::SHA256WITHRSAENCRYPTION);
333     assert_eq!(algorithm.object().to_string(), "sha256WithRSAEncryption");
334 }
335 
336 #[test]
337 #[allow(clippy::redundant_clone)]
clone_x509()338 fn clone_x509() {
339     let cert = include_bytes!("../../test/cert.pem");
340     let cert = X509::from_pem(cert).unwrap();
341     drop(cert.clone());
342 }
343 
344 #[test]
test_verify_cert()345 fn test_verify_cert() {
346     let cert = include_bytes!("../../test/cert.pem");
347     let cert = X509::from_pem(cert).unwrap();
348     let ca = include_bytes!("../../test/root-ca.pem");
349     let ca = X509::from_pem(ca).unwrap();
350     let chain = Stack::new().unwrap();
351 
352     let mut store_bldr = X509StoreBuilder::new().unwrap();
353     store_bldr.add_cert(ca).unwrap();
354     let store = store_bldr.build();
355 
356     let mut context = X509StoreContext::new().unwrap();
357     assert!(context
358         .init(&store, &cert, &chain, |c| c.verify_cert())
359         .unwrap());
360     assert!(context
361         .init(&store, &cert, &chain, |c| c.verify_cert())
362         .unwrap());
363 }
364 
365 #[test]
test_verify_fails()366 fn test_verify_fails() {
367     let cert = include_bytes!("../../test/cert.pem");
368     let cert = X509::from_pem(cert).unwrap();
369     let ca = include_bytes!("../../test/alt_name_cert.pem");
370     let ca = X509::from_pem(ca).unwrap();
371     let chain = Stack::new().unwrap();
372 
373     let mut store_bldr = X509StoreBuilder::new().unwrap();
374     store_bldr.add_cert(ca).unwrap();
375     let store = store_bldr.build();
376 
377     let mut context = X509StoreContext::new().unwrap();
378     assert!(!context
379         .init(&store, &cert, &chain, |c| c.verify_cert())
380         .unwrap());
381 }
382 
383 #[cfg(ossl110)]
384 #[test]
x509_ref_version()385 fn x509_ref_version() {
386     let mut builder = X509Builder::new().unwrap();
387     let expected_version = 2;
388     builder
389         .set_version(expected_version)
390         .expect("Failed to set certificate version");
391     let cert = builder.build();
392     let actual_version = cert.version();
393     assert_eq!(
394         expected_version, actual_version,
395         "Obtained certificate version is incorrect",
396     );
397 }
398 
399 #[cfg(ossl110)]
400 #[test]
x509_ref_version_no_version_set()401 fn x509_ref_version_no_version_set() {
402     let cert = X509Builder::new().unwrap().build();
403     let actual_version = cert.version();
404     assert_eq!(
405         0, actual_version,
406         "Default certificate version is incorrect",
407     );
408 }
409