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