Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(537)

Side by Side Diff: net/base/x509_certificate_unittest.cc

Issue 13006020: net: extract net/cert out of net/base (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/base/x509_certificate_openssl.cc ('k') | net/base/x509_certificate_win.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/base/x509_certificate.h"
6
7 #include "base/basictypes.h"
8 #include "base/files/file_path.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/pickle.h"
11 #include "base/sha1.h"
12 #include "base/string_number_conversions.h"
13 #include "base/strings/string_split.h"
14 #include "crypto/rsa_private_key.h"
15 #include "net/base/asn1_util.h"
16 #include "net/base/cert_test_util.h"
17 #include "net/base/net_errors.h"
18 #include "net/base/test_certificate_data.h"
19 #include "net/base/test_data_directory.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 #if defined(USE_NSS)
23 #include <cert.h>
24 #endif
25
26 using base::HexEncode;
27 using base::Time;
28
29 namespace net {
30
31 // Certificates for test data. They're obtained with:
32 //
33 // $ openssl s_client -connect [host]:443 -showcerts > /tmp/host.pem < /dev/null
34 // $ openssl x509 -inform PEM -outform DER < /tmp/host.pem > /tmp/host.der
35 //
36 // For fingerprint
37 // $ openssl x509 -inform DER -fingerprint -noout < /tmp/host.der
38
39 // For valid_start, valid_expiry
40 // $ openssl x509 -inform DER -text -noout < /tmp/host.der |
41 // grep -A 2 Validity
42 // $ date +%s -d '<date str>'
43
44 // Google's cert.
45 uint8 google_fingerprint[] = {
46 0xab, 0xbe, 0x5e, 0xb4, 0x93, 0x88, 0x4e, 0xe4, 0x60, 0xc6, 0xef, 0xf8,
47 0xea, 0xd4, 0xb1, 0x55, 0x4b, 0xc9, 0x59, 0x3c
48 };
49
50 // webkit.org's cert.
51 uint8 webkit_fingerprint[] = {
52 0xa1, 0x4a, 0x94, 0x46, 0x22, 0x8e, 0x70, 0x66, 0x2b, 0x94, 0xf9, 0xf8,
53 0x57, 0x83, 0x2d, 0xa2, 0xff, 0xbc, 0x84, 0xc2
54 };
55
56 // thawte.com's cert (it's EV-licious!).
57 uint8 thawte_fingerprint[] = {
58 0x85, 0x04, 0x2d, 0xfd, 0x2b, 0x0e, 0xc6, 0xc8, 0xaf, 0x2d, 0x77, 0xd6,
59 0xa1, 0x3a, 0x64, 0x04, 0x27, 0x90, 0x97, 0x37
60 };
61
62 // A certificate for https://www.unosoft.hu/, whose AIA extension contains
63 // an LDAP URL without a host name.
64 uint8 unosoft_hu_fingerprint[] = {
65 0x32, 0xff, 0xe3, 0xbe, 0x2c, 0x3b, 0xc7, 0xca, 0xbf, 0x2d, 0x64, 0xbd,
66 0x25, 0x66, 0xf2, 0xec, 0x8b, 0x0f, 0xbf, 0xd8
67 };
68
69 // The fingerprint of the Google certificate used in the parsing tests,
70 // which is newer than the one included in the x509_certificate_data.h
71 uint8 google_parse_fingerprint[] = {
72 0x40, 0x50, 0x62, 0xe5, 0xbe, 0xfd, 0xe4, 0xaf, 0x97, 0xe9, 0x38, 0x2a,
73 0xf1, 0x6c, 0xc8, 0x7c, 0x8f, 0xb7, 0xc4, 0xe2
74 };
75
76 // The fingerprint for the Thawte SGC certificate
77 uint8 thawte_parse_fingerprint[] = {
78 0xec, 0x07, 0x10, 0x03, 0xd8, 0xf5, 0xa3, 0x7f, 0x42, 0xc4, 0x55, 0x7f,
79 0x65, 0x6a, 0xae, 0x86, 0x65, 0xfa, 0x4b, 0x02
80 };
81
82 // Dec 18 00:00:00 2009 GMT
83 const double kGoogleParseValidFrom = 1261094400;
84 // Dec 18 23:59:59 2011 GMT
85 const double kGoogleParseValidTo = 1324252799;
86
87 struct CertificateFormatTestData {
88 const char* file_name;
89 X509Certificate::Format format;
90 uint8* chain_fingerprints[3];
91 };
92
93 const CertificateFormatTestData FormatTestData[] = {
94 // DER Parsing - single certificate, DER encoded
95 { "google.single.der", X509Certificate::FORMAT_SINGLE_CERTIFICATE,
96 { google_parse_fingerprint,
97 NULL, } },
98 // DER parsing - single certificate, PEM encoded
99 { "google.single.pem", X509Certificate::FORMAT_SINGLE_CERTIFICATE,
100 { google_parse_fingerprint,
101 NULL, } },
102 // PEM parsing - single certificate, PEM encoded with a PEB of
103 // "CERTIFICATE"
104 { "google.single.pem", X509Certificate::FORMAT_PEM_CERT_SEQUENCE,
105 { google_parse_fingerprint,
106 NULL, } },
107 // PEM parsing - sequence of certificates, PEM encoded with a PEB of
108 // "CERTIFICATE"
109 { "google.chain.pem", X509Certificate::FORMAT_PEM_CERT_SEQUENCE,
110 { google_parse_fingerprint,
111 thawte_parse_fingerprint,
112 NULL, } },
113 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, DER
114 // encoding
115 { "google.binary.p7b", X509Certificate::FORMAT_PKCS7,
116 { google_parse_fingerprint,
117 thawte_parse_fingerprint,
118 NULL, } },
119 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, PEM
120 // encoded with a PEM PEB of "CERTIFICATE"
121 { "google.pem_cert.p7b", X509Certificate::FORMAT_PKCS7,
122 { google_parse_fingerprint,
123 thawte_parse_fingerprint,
124 NULL, } },
125 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, PEM
126 // encoded with a PEM PEB of "PKCS7"
127 { "google.pem_pkcs7.p7b", X509Certificate::FORMAT_PKCS7,
128 { google_parse_fingerprint,
129 thawte_parse_fingerprint,
130 NULL, } },
131 // All of the above, this time using auto-detection
132 { "google.single.der", X509Certificate::FORMAT_AUTO,
133 { google_parse_fingerprint,
134 NULL, } },
135 { "google.single.pem", X509Certificate::FORMAT_AUTO,
136 { google_parse_fingerprint,
137 NULL, } },
138 { "google.chain.pem", X509Certificate::FORMAT_AUTO,
139 { google_parse_fingerprint,
140 thawte_parse_fingerprint,
141 NULL, } },
142 { "google.binary.p7b", X509Certificate::FORMAT_AUTO,
143 { google_parse_fingerprint,
144 thawte_parse_fingerprint,
145 NULL, } },
146 { "google.pem_cert.p7b", X509Certificate::FORMAT_AUTO,
147 { google_parse_fingerprint,
148 thawte_parse_fingerprint,
149 NULL, } },
150 { "google.pem_pkcs7.p7b", X509Certificate::FORMAT_AUTO,
151 { google_parse_fingerprint,
152 thawte_parse_fingerprint,
153 NULL, } },
154 };
155
156 void CheckGoogleCert(const scoped_refptr<X509Certificate>& google_cert,
157 uint8* expected_fingerprint,
158 double valid_from, double valid_to) {
159 ASSERT_NE(static_cast<X509Certificate*>(NULL), google_cert);
160
161 const CertPrincipal& subject = google_cert->subject();
162 EXPECT_EQ("www.google.com", subject.common_name);
163 EXPECT_EQ("Mountain View", subject.locality_name);
164 EXPECT_EQ("California", subject.state_or_province_name);
165 EXPECT_EQ("US", subject.country_name);
166 EXPECT_EQ(0U, subject.street_addresses.size());
167 ASSERT_EQ(1U, subject.organization_names.size());
168 EXPECT_EQ("Google Inc", subject.organization_names[0]);
169 EXPECT_EQ(0U, subject.organization_unit_names.size());
170 EXPECT_EQ(0U, subject.domain_components.size());
171
172 const CertPrincipal& issuer = google_cert->issuer();
173 EXPECT_EQ("Thawte SGC CA", issuer.common_name);
174 EXPECT_EQ("", issuer.locality_name);
175 EXPECT_EQ("", issuer.state_or_province_name);
176 EXPECT_EQ("ZA", issuer.country_name);
177 EXPECT_EQ(0U, issuer.street_addresses.size());
178 ASSERT_EQ(1U, issuer.organization_names.size());
179 EXPECT_EQ("Thawte Consulting (Pty) Ltd.", issuer.organization_names[0]);
180 EXPECT_EQ(0U, issuer.organization_unit_names.size());
181 EXPECT_EQ(0U, issuer.domain_components.size());
182
183 // Use DoubleT because its epoch is the same on all platforms
184 const Time& valid_start = google_cert->valid_start();
185 EXPECT_EQ(valid_from, valid_start.ToDoubleT());
186
187 const Time& valid_expiry = google_cert->valid_expiry();
188 EXPECT_EQ(valid_to, valid_expiry.ToDoubleT());
189
190 const SHA1HashValue& fingerprint = google_cert->fingerprint();
191 for (size_t i = 0; i < 20; ++i)
192 EXPECT_EQ(expected_fingerprint[i], fingerprint.data[i]);
193
194 std::vector<std::string> dns_names;
195 google_cert->GetDNSNames(&dns_names);
196 ASSERT_EQ(1U, dns_names.size());
197 EXPECT_EQ("www.google.com", dns_names[0]);
198 }
199
200 TEST(X509CertificateTest, GoogleCertParsing) {
201 scoped_refptr<X509Certificate> google_cert(
202 X509Certificate::CreateFromBytes(
203 reinterpret_cast<const char*>(google_der), sizeof(google_der)));
204
205 CheckGoogleCert(google_cert, google_fingerprint,
206 1238192407, // Mar 27 22:20:07 2009 GMT
207 1269728407); // Mar 27 22:20:07 2010 GMT
208 }
209
210 TEST(X509CertificateTest, WebkitCertParsing) {
211 scoped_refptr<X509Certificate> webkit_cert(X509Certificate::CreateFromBytes(
212 reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der)));
213
214 ASSERT_NE(static_cast<X509Certificate*>(NULL), webkit_cert);
215
216 const CertPrincipal& subject = webkit_cert->subject();
217 EXPECT_EQ("Cupertino", subject.locality_name);
218 EXPECT_EQ("California", subject.state_or_province_name);
219 EXPECT_EQ("US", subject.country_name);
220 EXPECT_EQ(0U, subject.street_addresses.size());
221 ASSERT_EQ(1U, subject.organization_names.size());
222 EXPECT_EQ("Apple Inc.", subject.organization_names[0]);
223 ASSERT_EQ(1U, subject.organization_unit_names.size());
224 EXPECT_EQ("Mac OS Forge", subject.organization_unit_names[0]);
225 EXPECT_EQ(0U, subject.domain_components.size());
226
227 const CertPrincipal& issuer = webkit_cert->issuer();
228 EXPECT_EQ("Go Daddy Secure Certification Authority", issuer.common_name);
229 EXPECT_EQ("Scottsdale", issuer.locality_name);
230 EXPECT_EQ("Arizona", issuer.state_or_province_name);
231 EXPECT_EQ("US", issuer.country_name);
232 EXPECT_EQ(0U, issuer.street_addresses.size());
233 ASSERT_EQ(1U, issuer.organization_names.size());
234 EXPECT_EQ("GoDaddy.com, Inc.", issuer.organization_names[0]);
235 ASSERT_EQ(1U, issuer.organization_unit_names.size());
236 EXPECT_EQ("http://certificates.godaddy.com/repository",
237 issuer.organization_unit_names[0]);
238 EXPECT_EQ(0U, issuer.domain_components.size());
239
240 // Use DoubleT because its epoch is the same on all platforms
241 const Time& valid_start = webkit_cert->valid_start();
242 EXPECT_EQ(1205883319, valid_start.ToDoubleT()); // Mar 18 23:35:19 2008 GMT
243
244 const Time& valid_expiry = webkit_cert->valid_expiry();
245 EXPECT_EQ(1300491319, valid_expiry.ToDoubleT()); // Mar 18 23:35:19 2011 GMT
246
247 const SHA1HashValue& fingerprint = webkit_cert->fingerprint();
248 for (size_t i = 0; i < 20; ++i)
249 EXPECT_EQ(webkit_fingerprint[i], fingerprint.data[i]);
250
251 std::vector<std::string> dns_names;
252 webkit_cert->GetDNSNames(&dns_names);
253 ASSERT_EQ(2U, dns_names.size());
254 EXPECT_EQ("*.webkit.org", dns_names[0]);
255 EXPECT_EQ("webkit.org", dns_names[1]);
256
257 // Test that the wildcard cert matches properly.
258 EXPECT_TRUE(webkit_cert->VerifyNameMatch("www.webkit.org"));
259 EXPECT_TRUE(webkit_cert->VerifyNameMatch("foo.webkit.org"));
260 EXPECT_TRUE(webkit_cert->VerifyNameMatch("webkit.org"));
261 EXPECT_FALSE(webkit_cert->VerifyNameMatch("www.webkit.com"));
262 EXPECT_FALSE(webkit_cert->VerifyNameMatch("www.foo.webkit.com"));
263 }
264
265 TEST(X509CertificateTest, ThawteCertParsing) {
266 scoped_refptr<X509Certificate> thawte_cert(X509Certificate::CreateFromBytes(
267 reinterpret_cast<const char*>(thawte_der), sizeof(thawte_der)));
268
269 ASSERT_NE(static_cast<X509Certificate*>(NULL), thawte_cert);
270
271 const CertPrincipal& subject = thawte_cert->subject();
272 EXPECT_EQ("www.thawte.com", subject.common_name);
273 EXPECT_EQ("Mountain View", subject.locality_name);
274 EXPECT_EQ("California", subject.state_or_province_name);
275 EXPECT_EQ("US", subject.country_name);
276 EXPECT_EQ(0U, subject.street_addresses.size());
277 ASSERT_EQ(1U, subject.organization_names.size());
278 EXPECT_EQ("Thawte Inc", subject.organization_names[0]);
279 EXPECT_EQ(0U, subject.organization_unit_names.size());
280 EXPECT_EQ(0U, subject.domain_components.size());
281
282 const CertPrincipal& issuer = thawte_cert->issuer();
283 EXPECT_EQ("thawte Extended Validation SSL CA", issuer.common_name);
284 EXPECT_EQ("", issuer.locality_name);
285 EXPECT_EQ("", issuer.state_or_province_name);
286 EXPECT_EQ("US", issuer.country_name);
287 EXPECT_EQ(0U, issuer.street_addresses.size());
288 ASSERT_EQ(1U, issuer.organization_names.size());
289 EXPECT_EQ("thawte, Inc.", issuer.organization_names[0]);
290 ASSERT_EQ(1U, issuer.organization_unit_names.size());
291 EXPECT_EQ("Terms of use at https://www.thawte.com/cps (c)06",
292 issuer.organization_unit_names[0]);
293 EXPECT_EQ(0U, issuer.domain_components.size());
294
295 // Use DoubleT because its epoch is the same on all platforms
296 const Time& valid_start = thawte_cert->valid_start();
297 EXPECT_EQ(1227052800, valid_start.ToDoubleT()); // Nov 19 00:00:00 2008 GMT
298
299 const Time& valid_expiry = thawte_cert->valid_expiry();
300 EXPECT_EQ(1263772799, valid_expiry.ToDoubleT()); // Jan 17 23:59:59 2010 GMT
301
302 const SHA1HashValue& fingerprint = thawte_cert->fingerprint();
303 for (size_t i = 0; i < 20; ++i)
304 EXPECT_EQ(thawte_fingerprint[i], fingerprint.data[i]);
305
306 std::vector<std::string> dns_names;
307 thawte_cert->GetDNSNames(&dns_names);
308 ASSERT_EQ(1U, dns_names.size());
309 EXPECT_EQ("www.thawte.com", dns_names[0]);
310 }
311
312 // Test that all desired AttributeAndValue pairs can be extracted when only
313 // a single RelativeDistinguishedName is present. "Normally" there is only
314 // one AVA per RDN, but some CAs place all AVAs within a single RDN.
315 // This is a regression test for http://crbug.com/101009
316 TEST(X509CertificateTest, MultivalueRDN) {
317 base::FilePath certs_dir = GetTestCertsDirectory();
318
319 scoped_refptr<X509Certificate> multivalue_rdn_cert =
320 ImportCertFromFile(certs_dir, "multivalue_rdn.pem");
321 ASSERT_NE(static_cast<X509Certificate*>(NULL), multivalue_rdn_cert);
322
323 const CertPrincipal& subject = multivalue_rdn_cert->subject();
324 EXPECT_EQ("Multivalue RDN Test", subject.common_name);
325 EXPECT_EQ("", subject.locality_name);
326 EXPECT_EQ("", subject.state_or_province_name);
327 EXPECT_EQ("US", subject.country_name);
328 EXPECT_EQ(0U, subject.street_addresses.size());
329 ASSERT_EQ(1U, subject.organization_names.size());
330 EXPECT_EQ("Chromium", subject.organization_names[0]);
331 ASSERT_EQ(1U, subject.organization_unit_names.size());
332 EXPECT_EQ("Chromium net_unittests", subject.organization_unit_names[0]);
333 ASSERT_EQ(1U, subject.domain_components.size());
334 EXPECT_EQ("Chromium", subject.domain_components[0]);
335 }
336
337 // Test that characters which would normally be escaped in the string form,
338 // such as '=' or '"', are not escaped when parsed as individual components.
339 // This is a regression test for http://crbug.com/102839
340 TEST(X509CertificateTest, UnescapedSpecialCharacters) {
341 base::FilePath certs_dir = GetTestCertsDirectory();
342
343 scoped_refptr<X509Certificate> unescaped_cert =
344 ImportCertFromFile(certs_dir, "unescaped.pem");
345 ASSERT_NE(static_cast<X509Certificate*>(NULL), unescaped_cert);
346
347 const CertPrincipal& subject = unescaped_cert->subject();
348 EXPECT_EQ("127.0.0.1", subject.common_name);
349 EXPECT_EQ("Mountain View", subject.locality_name);
350 EXPECT_EQ("California", subject.state_or_province_name);
351 EXPECT_EQ("US", subject.country_name);
352 ASSERT_EQ(1U, subject.street_addresses.size());
353 EXPECT_EQ("1600 Amphitheatre Parkway", subject.street_addresses[0]);
354 ASSERT_EQ(1U, subject.organization_names.size());
355 EXPECT_EQ("Chromium = \"net_unittests\"", subject.organization_names[0]);
356 ASSERT_EQ(2U, subject.organization_unit_names.size());
357 EXPECT_EQ("net_unittests", subject.organization_unit_names[0]);
358 EXPECT_EQ("Chromium", subject.organization_unit_names[1]);
359 EXPECT_EQ(0U, subject.domain_components.size());
360 }
361
362 TEST(X509CertificateTest, SerialNumbers) {
363 scoped_refptr<X509Certificate> google_cert(
364 X509Certificate::CreateFromBytes(
365 reinterpret_cast<const char*>(google_der), sizeof(google_der)));
366
367 static const uint8 google_serial[16] = {
368 0x01,0x2a,0x39,0x76,0x0d,0x3f,0x4f,0xc9,
369 0x0b,0xe7,0xbd,0x2b,0xcf,0x95,0x2e,0x7a,
370 };
371
372 ASSERT_EQ(sizeof(google_serial), google_cert->serial_number().size());
373 EXPECT_TRUE(memcmp(google_cert->serial_number().data(), google_serial,
374 sizeof(google_serial)) == 0);
375
376 // We also want to check a serial number where the first byte is >= 0x80 in
377 // case the underlying library tries to pad it.
378 scoped_refptr<X509Certificate> paypal_null_cert(
379 X509Certificate::CreateFromBytes(
380 reinterpret_cast<const char*>(paypal_null_der),
381 sizeof(paypal_null_der)));
382
383 static const uint8 paypal_null_serial[3] = {0x00, 0xf0, 0x9b};
384 ASSERT_EQ(sizeof(paypal_null_serial),
385 paypal_null_cert->serial_number().size());
386 EXPECT_TRUE(memcmp(paypal_null_cert->serial_number().data(),
387 paypal_null_serial, sizeof(paypal_null_serial)) == 0);
388 }
389
390 TEST(X509CertificateTest, CAFingerprints) {
391 base::FilePath certs_dir = GetTestCertsDirectory();
392
393 scoped_refptr<X509Certificate> server_cert =
394 ImportCertFromFile(certs_dir, "salesforce_com_test.pem");
395 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
396
397 scoped_refptr<X509Certificate> intermediate_cert1 =
398 ImportCertFromFile(certs_dir, "verisign_intermediate_ca_2011.pem");
399 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert1);
400
401 scoped_refptr<X509Certificate> intermediate_cert2 =
402 ImportCertFromFile(certs_dir, "verisign_intermediate_ca_2016.pem");
403 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert2);
404
405 X509Certificate::OSCertHandles intermediates;
406 intermediates.push_back(intermediate_cert1->os_cert_handle());
407 scoped_refptr<X509Certificate> cert_chain1 =
408 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
409 intermediates);
410
411 intermediates.clear();
412 intermediates.push_back(intermediate_cert2->os_cert_handle());
413 scoped_refptr<X509Certificate> cert_chain2 =
414 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
415 intermediates);
416
417 // No intermediate CA certicates.
418 intermediates.clear();
419 scoped_refptr<X509Certificate> cert_chain3 =
420 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
421 intermediates);
422
423 static const uint8 cert_chain1_ca_fingerprint[20] = {
424 0xc2, 0xf0, 0x08, 0x7d, 0x01, 0xe6, 0x86, 0x05, 0x3a, 0x4d,
425 0x63, 0x3e, 0x7e, 0x70, 0xd4, 0xef, 0x65, 0xc2, 0xcc, 0x4f
426 };
427 static const uint8 cert_chain2_ca_fingerprint[20] = {
428 0xd5, 0x59, 0xa5, 0x86, 0x66, 0x9b, 0x08, 0xf4, 0x6a, 0x30,
429 0xa1, 0x33, 0xf8, 0xa9, 0xed, 0x3d, 0x03, 0x8e, 0x2e, 0xa8
430 };
431 // The SHA-1 hash of nothing.
432 static const uint8 cert_chain3_ca_fingerprint[20] = {
433 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55,
434 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09
435 };
436 EXPECT_TRUE(memcmp(cert_chain1->ca_fingerprint().data,
437 cert_chain1_ca_fingerprint, 20) == 0);
438 EXPECT_TRUE(memcmp(cert_chain2->ca_fingerprint().data,
439 cert_chain2_ca_fingerprint, 20) == 0);
440 EXPECT_TRUE(memcmp(cert_chain3->ca_fingerprint().data,
441 cert_chain3_ca_fingerprint, 20) == 0);
442 }
443
444 TEST(X509CertificateTest, ParseSubjectAltNames) {
445 base::FilePath certs_dir = GetTestCertsDirectory();
446
447 scoped_refptr<X509Certificate> san_cert =
448 ImportCertFromFile(certs_dir, "subjectAltName_sanity_check.pem");
449 ASSERT_NE(static_cast<X509Certificate*>(NULL), san_cert);
450
451 std::vector<std::string> dns_names;
452 std::vector<std::string> ip_addresses;
453 san_cert->GetSubjectAltName(&dns_names, &ip_addresses);
454
455 // Ensure that DNS names are correctly parsed.
456 ASSERT_EQ(1U, dns_names.size());
457 EXPECT_EQ("test.example", dns_names[0]);
458
459 // Ensure that both IPv4 and IPv6 addresses are correctly parsed.
460 ASSERT_EQ(2U, ip_addresses.size());
461
462 static const uint8 kIPv4Address[] = {
463 0x7F, 0x00, 0x00, 0x02
464 };
465 ASSERT_EQ(arraysize(kIPv4Address), ip_addresses[0].size());
466 EXPECT_EQ(0, memcmp(ip_addresses[0].data(), kIPv4Address,
467 arraysize(kIPv4Address)));
468
469 static const uint8 kIPv6Address[] = {
470 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
471 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
472 };
473 ASSERT_EQ(arraysize(kIPv6Address), ip_addresses[1].size());
474 EXPECT_EQ(0, memcmp(ip_addresses[1].data(), kIPv6Address,
475 arraysize(kIPv6Address)));
476
477 // Ensure the subjectAltName dirName has not influenced the handling of
478 // the subject commonName.
479 EXPECT_EQ("127.0.0.1", san_cert->subject().common_name);
480 }
481
482 TEST(X509CertificateTest, ExtractSPKIFromDERCert) {
483 base::FilePath certs_dir = GetTestCertsDirectory();
484 scoped_refptr<X509Certificate> cert =
485 ImportCertFromFile(certs_dir, "nist.der");
486 ASSERT_NE(static_cast<X509Certificate*>(NULL), cert);
487
488 std::string derBytes;
489 EXPECT_TRUE(X509Certificate::GetDEREncoded(cert->os_cert_handle(),
490 &derBytes));
491
492 base::StringPiece spkiBytes;
493 EXPECT_TRUE(asn1::ExtractSPKIFromDERCert(derBytes, &spkiBytes));
494
495 uint8 hash[base::kSHA1Length];
496 base::SHA1HashBytes(reinterpret_cast<const uint8*>(spkiBytes.data()),
497 spkiBytes.size(), hash);
498
499 EXPECT_EQ(0, memcmp(hash, kNistSPKIHash, sizeof(hash)));
500 }
501
502 TEST(X509CertificateTest, ExtractCRLURLsFromDERCert) {
503 base::FilePath certs_dir = GetTestCertsDirectory();
504 scoped_refptr<X509Certificate> cert =
505 ImportCertFromFile(certs_dir, "nist.der");
506 ASSERT_NE(static_cast<X509Certificate*>(NULL), cert);
507
508 std::string derBytes;
509 EXPECT_TRUE(X509Certificate::GetDEREncoded(cert->os_cert_handle(),
510 &derBytes));
511
512 std::vector<base::StringPiece> crl_urls;
513 EXPECT_TRUE(asn1::ExtractCRLURLsFromDERCert(derBytes, &crl_urls));
514
515 EXPECT_EQ(1u, crl_urls.size());
516 if (crl_urls.size() > 0) {
517 EXPECT_EQ("http://SVRSecure-G3-crl.verisign.com/SVRSecureG3.crl",
518 crl_urls[0].as_string());
519 }
520 }
521
522 // Tests X509CertificateCache via X509Certificate::CreateFromHandle. We
523 // call X509Certificate::CreateFromHandle several times and observe whether
524 // it returns a cached or new OSCertHandle.
525 TEST(X509CertificateTest, Cache) {
526 X509Certificate::OSCertHandle google_cert_handle;
527 X509Certificate::OSCertHandle thawte_cert_handle;
528
529 // Add a single certificate to the certificate cache.
530 google_cert_handle = X509Certificate::CreateOSCertHandleFromBytes(
531 reinterpret_cast<const char*>(google_der), sizeof(google_der));
532 scoped_refptr<X509Certificate> cert1(X509Certificate::CreateFromHandle(
533 google_cert_handle, X509Certificate::OSCertHandles()));
534 X509Certificate::FreeOSCertHandle(google_cert_handle);
535
536 // Add the same certificate, but as a new handle.
537 google_cert_handle = X509Certificate::CreateOSCertHandleFromBytes(
538 reinterpret_cast<const char*>(google_der), sizeof(google_der));
539 scoped_refptr<X509Certificate> cert2(X509Certificate::CreateFromHandle(
540 google_cert_handle, X509Certificate::OSCertHandles()));
541 X509Certificate::FreeOSCertHandle(google_cert_handle);
542
543 // A new X509Certificate should be returned.
544 EXPECT_NE(cert1.get(), cert2.get());
545 // But both instances should share the underlying OS certificate handle.
546 EXPECT_EQ(cert1->os_cert_handle(), cert2->os_cert_handle());
547 EXPECT_EQ(0u, cert1->GetIntermediateCertificates().size());
548 EXPECT_EQ(0u, cert2->GetIntermediateCertificates().size());
549
550 // Add the same certificate, but this time with an intermediate. This
551 // should result in the intermediate being cached. Note that this is not
552 // a legitimate chain, but is suitable for testing.
553 google_cert_handle = X509Certificate::CreateOSCertHandleFromBytes(
554 reinterpret_cast<const char*>(google_der), sizeof(google_der));
555 thawte_cert_handle = X509Certificate::CreateOSCertHandleFromBytes(
556 reinterpret_cast<const char*>(thawte_der), sizeof(thawte_der));
557 X509Certificate::OSCertHandles intermediates;
558 intermediates.push_back(thawte_cert_handle);
559 scoped_refptr<X509Certificate> cert3(X509Certificate::CreateFromHandle(
560 google_cert_handle, intermediates));
561 X509Certificate::FreeOSCertHandle(google_cert_handle);
562 X509Certificate::FreeOSCertHandle(thawte_cert_handle);
563
564 // Test that the new certificate, even with intermediates, results in the
565 // same underlying handle being used.
566 EXPECT_EQ(cert1->os_cert_handle(), cert3->os_cert_handle());
567 // Though they use the same OS handle, the intermediates should be different.
568 EXPECT_NE(cert1->GetIntermediateCertificates().size(),
569 cert3->GetIntermediateCertificates().size());
570 }
571
572 TEST(X509CertificateTest, Pickle) {
573 X509Certificate::OSCertHandle google_cert_handle =
574 X509Certificate::CreateOSCertHandleFromBytes(
575 reinterpret_cast<const char*>(google_der), sizeof(google_der));
576 X509Certificate::OSCertHandle thawte_cert_handle =
577 X509Certificate::CreateOSCertHandleFromBytes(
578 reinterpret_cast<const char*>(thawte_der), sizeof(thawte_der));
579
580 X509Certificate::OSCertHandles intermediates;
581 intermediates.push_back(thawte_cert_handle);
582 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle(
583 google_cert_handle, intermediates);
584 ASSERT_NE(static_cast<X509Certificate*>(NULL), cert.get());
585
586 X509Certificate::FreeOSCertHandle(google_cert_handle);
587 X509Certificate::FreeOSCertHandle(thawte_cert_handle);
588
589 Pickle pickle;
590 cert->Persist(&pickle);
591
592 PickleIterator iter(pickle);
593 scoped_refptr<X509Certificate> cert_from_pickle =
594 X509Certificate::CreateFromPickle(
595 pickle, &iter, X509Certificate::PICKLETYPE_CERTIFICATE_CHAIN_V3);
596 ASSERT_NE(static_cast<X509Certificate*>(NULL), cert_from_pickle);
597 EXPECT_TRUE(X509Certificate::IsSameOSCert(
598 cert->os_cert_handle(), cert_from_pickle->os_cert_handle()));
599 const X509Certificate::OSCertHandles& cert_intermediates =
600 cert->GetIntermediateCertificates();
601 const X509Certificate::OSCertHandles& pickle_intermediates =
602 cert_from_pickle->GetIntermediateCertificates();
603 ASSERT_EQ(cert_intermediates.size(), pickle_intermediates.size());
604 for (size_t i = 0; i < cert_intermediates.size(); ++i) {
605 EXPECT_TRUE(X509Certificate::IsSameOSCert(cert_intermediates[i],
606 pickle_intermediates[i]));
607 }
608 }
609
610 TEST(X509CertificateTest, Policy) {
611 scoped_refptr<X509Certificate> google_cert(X509Certificate::CreateFromBytes(
612 reinterpret_cast<const char*>(google_der), sizeof(google_der)));
613
614 scoped_refptr<X509Certificate> webkit_cert(X509Certificate::CreateFromBytes(
615 reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der)));
616
617 CertPolicy policy;
618
619 EXPECT_EQ(policy.Check(google_cert.get()), CertPolicy::UNKNOWN);
620 EXPECT_EQ(policy.Check(webkit_cert.get()), CertPolicy::UNKNOWN);
621 EXPECT_FALSE(policy.HasAllowedCert());
622 EXPECT_FALSE(policy.HasDeniedCert());
623
624 policy.Allow(google_cert.get());
625
626 EXPECT_EQ(policy.Check(google_cert.get()), CertPolicy::ALLOWED);
627 EXPECT_EQ(policy.Check(webkit_cert.get()), CertPolicy::UNKNOWN);
628 EXPECT_TRUE(policy.HasAllowedCert());
629 EXPECT_FALSE(policy.HasDeniedCert());
630
631 policy.Deny(google_cert.get());
632
633 EXPECT_EQ(policy.Check(google_cert.get()), CertPolicy::DENIED);
634 EXPECT_EQ(policy.Check(webkit_cert.get()), CertPolicy::UNKNOWN);
635 EXPECT_FALSE(policy.HasAllowedCert());
636 EXPECT_TRUE(policy.HasDeniedCert());
637
638 policy.Allow(webkit_cert.get());
639
640 EXPECT_EQ(policy.Check(google_cert.get()), CertPolicy::DENIED);
641 EXPECT_EQ(policy.Check(webkit_cert.get()), CertPolicy::ALLOWED);
642 EXPECT_TRUE(policy.HasAllowedCert());
643 EXPECT_TRUE(policy.HasDeniedCert());
644 }
645
646 TEST(X509CertificateTest, IntermediateCertificates) {
647 scoped_refptr<X509Certificate> webkit_cert(
648 X509Certificate::CreateFromBytes(
649 reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der)));
650
651 scoped_refptr<X509Certificate> thawte_cert(
652 X509Certificate::CreateFromBytes(
653 reinterpret_cast<const char*>(thawte_der), sizeof(thawte_der)));
654
655 X509Certificate::OSCertHandle google_handle;
656 // Create object with no intermediates:
657 google_handle = X509Certificate::CreateOSCertHandleFromBytes(
658 reinterpret_cast<const char*>(google_der), sizeof(google_der));
659 X509Certificate::OSCertHandles intermediates1;
660 scoped_refptr<X509Certificate> cert1;
661 cert1 = X509Certificate::CreateFromHandle(google_handle, intermediates1);
662 EXPECT_EQ(0u, cert1->GetIntermediateCertificates().size());
663
664 // Create object with 2 intermediates:
665 X509Certificate::OSCertHandles intermediates2;
666 intermediates2.push_back(webkit_cert->os_cert_handle());
667 intermediates2.push_back(thawte_cert->os_cert_handle());
668 scoped_refptr<X509Certificate> cert2;
669 cert2 = X509Certificate::CreateFromHandle(google_handle, intermediates2);
670
671 // Verify it has all the intermediates:
672 const X509Certificate::OSCertHandles& cert2_intermediates =
673 cert2->GetIntermediateCertificates();
674 ASSERT_EQ(2u, cert2_intermediates.size());
675 EXPECT_TRUE(X509Certificate::IsSameOSCert(cert2_intermediates[0],
676 webkit_cert->os_cert_handle()));
677 EXPECT_TRUE(X509Certificate::IsSameOSCert(cert2_intermediates[1],
678 thawte_cert->os_cert_handle()));
679
680 // Cleanup
681 X509Certificate::FreeOSCertHandle(google_handle);
682 }
683
684 TEST(X509CertificateTest, IsIssuedByEncoded) {
685 base::FilePath certs_dir = GetTestCertsDirectory();
686
687 // Test a client certificate from MIT.
688 scoped_refptr<X509Certificate> mit_davidben_cert(
689 ImportCertFromFile(certs_dir, "mit.davidben.der"));
690 ASSERT_NE(static_cast<X509Certificate*>(NULL), mit_davidben_cert);
691
692 std::string mit_issuer(reinterpret_cast<const char*>(MITDN),
693 sizeof(MITDN));
694
695 // Test a certificate from Google, issued by Thawte
696 scoped_refptr<X509Certificate> google_cert(
697 ImportCertFromFile(certs_dir, "google.single.der"));
698 ASSERT_NE(static_cast<X509Certificate*>(NULL), google_cert);
699
700 std::string thawte_issuer(reinterpret_cast<const char*>(ThawteDN),
701 sizeof(ThawteDN));
702
703 // Check that the David Ben certificate is issued by MIT, but not
704 // by Thawte.
705 std::vector<std::string> issuers;
706 issuers.clear();
707 issuers.push_back(mit_issuer);
708 EXPECT_TRUE(mit_davidben_cert->IsIssuedByEncoded(issuers));
709 EXPECT_FALSE(google_cert->IsIssuedByEncoded(issuers));
710
711 // Check that the Google certificate is issued by Thawte and not
712 // by MIT.
713 issuers.clear();
714 issuers.push_back(thawte_issuer);
715 EXPECT_FALSE(mit_davidben_cert->IsIssuedByEncoded(issuers));
716 EXPECT_TRUE(google_cert->IsIssuedByEncoded(issuers));
717
718 // Check that they both pass when given a list of the two issuers.
719 issuers.clear();
720 issuers.push_back(mit_issuer);
721 issuers.push_back(thawte_issuer);
722 EXPECT_TRUE(mit_davidben_cert->IsIssuedByEncoded(issuers));
723 EXPECT_TRUE(google_cert->IsIssuedByEncoded(issuers));
724 }
725
726 TEST(X509CertificateTest, IsIssuedByEncodedWithIntermediates) {
727 base::FilePath certs_dir = GetTestCertsDirectory();
728
729 scoped_refptr<X509Certificate> server_cert =
730 ImportCertFromFile(certs_dir, "www_us_army_mil_cert.der");
731 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
732
733 // The intermediate CA certificate's policyConstraints extension has a
734 // requireExplicitPolicy field with SkipCerts=0.
735 scoped_refptr<X509Certificate> intermediate_cert =
736 ImportCertFromFile(certs_dir, "dod_ca_17_cert.der");
737 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert);
738
739 std::string dod_ca_17_issuer(reinterpret_cast<const char*>(DodCA17DN),
740 sizeof(DodCA17DN));
741
742 scoped_refptr<X509Certificate> root_cert =
743 ImportCertFromFile(certs_dir, "dod_root_ca_2_cert.der");
744
745 std::string dod_root_ca_2_issuer(
746 reinterpret_cast<const char*>(DodRootCA2DN), sizeof(DodRootCA2DN));
747
748 X509Certificate::OSCertHandles intermediates;
749 intermediates.push_back(intermediate_cert->os_cert_handle());
750 scoped_refptr<X509Certificate> cert_chain =
751 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
752 intermediates);
753
754 std::vector<std::string> issuers;
755
756 // Check that the chain is issued by DOD CA-17.
757 issuers.clear();
758 issuers.push_back(dod_ca_17_issuer);
759 EXPECT_TRUE(cert_chain->IsIssuedByEncoded(issuers));
760
761 // Check that the chain is also issued by DoD Root CA 2.
762 issuers.clear();
763 issuers.push_back(dod_root_ca_2_issuer);
764 EXPECT_TRUE(cert_chain->IsIssuedByEncoded(issuers));
765
766 // Check that the chain is issued by either one of the two DOD issuers.
767 issuers.clear();
768 issuers.push_back(dod_ca_17_issuer);
769 issuers.push_back(dod_root_ca_2_issuer);
770 EXPECT_TRUE(cert_chain->IsIssuedByEncoded(issuers));
771
772 // Check that an empty issuers list returns false.
773 issuers.clear();
774 EXPECT_FALSE(cert_chain->IsIssuedByEncoded(issuers));
775
776 // Check that the chain is not issued by MIT
777 std::string mit_issuer(reinterpret_cast<const char*>(MITDN),
778 sizeof(MITDN));
779 issuers.clear();
780 issuers.push_back(mit_issuer);
781 EXPECT_FALSE(cert_chain->IsIssuedByEncoded(issuers));
782 }
783
784 #if !defined(OS_IOS) // TODO(ios): Unable to create certificates.
785 #if defined(USE_NSS) || defined(OS_WIN) || defined(OS_MACOSX)
786 // This test creates a self-signed cert from a private key and then verify the
787 // content of the certificate.
788 TEST(X509CertificateTest, CreateSelfSigned) {
789 scoped_ptr<crypto::RSAPrivateKey> private_key(
790 crypto::RSAPrivateKey::Create(1024));
791 scoped_refptr<X509Certificate> cert =
792 X509Certificate::CreateSelfSigned(
793 private_key.get(), "CN=subject", 1, base::TimeDelta::FromDays(1));
794
795 EXPECT_EQ("subject", cert->subject().GetDisplayName());
796 EXPECT_FALSE(cert->HasExpired());
797
798 const uint8 private_key_info[] = {
799 0x30, 0x82, 0x02, 0x78, 0x02, 0x01, 0x00, 0x30,
800 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
801 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
802 0x02, 0x62, 0x30, 0x82, 0x02, 0x5e, 0x02, 0x01,
803 0x00, 0x02, 0x81, 0x81, 0x00, 0xb8, 0x7f, 0x2b,
804 0x20, 0xdc, 0x7c, 0x9b, 0x0c, 0xdc, 0x51, 0x61,
805 0x99, 0x0d, 0x36, 0x0f, 0xd4, 0x66, 0x88, 0x08,
806 0x55, 0x84, 0xd5, 0x3a, 0xbf, 0x2b, 0xa4, 0x64,
807 0x85, 0x7b, 0x0c, 0x04, 0x13, 0x3f, 0x8d, 0xf4,
808 0xbc, 0x38, 0x0d, 0x49, 0xfe, 0x6b, 0xc4, 0x5a,
809 0xb0, 0x40, 0x53, 0x3a, 0xd7, 0x66, 0x09, 0x0f,
810 0x9e, 0x36, 0x74, 0x30, 0xda, 0x8a, 0x31, 0x4f,
811 0x1f, 0x14, 0x50, 0xd7, 0xc7, 0x20, 0x94, 0x17,
812 0xde, 0x4e, 0xb9, 0x57, 0x5e, 0x7e, 0x0a, 0xe5,
813 0xb2, 0x65, 0x7a, 0x89, 0x4e, 0xb6, 0x47, 0xff,
814 0x1c, 0xbd, 0xb7, 0x38, 0x13, 0xaf, 0x47, 0x85,
815 0x84, 0x32, 0x33, 0xf3, 0x17, 0x49, 0xbf, 0xe9,
816 0x96, 0xd0, 0xd6, 0x14, 0x6f, 0x13, 0x8d, 0xc5,
817 0xfc, 0x2c, 0x72, 0xba, 0xac, 0xea, 0x7e, 0x18,
818 0x53, 0x56, 0xa6, 0x83, 0xa2, 0xce, 0x93, 0x93,
819 0xe7, 0x1f, 0x0f, 0xe6, 0x0f, 0x02, 0x03, 0x01,
820 0x00, 0x01, 0x02, 0x81, 0x80, 0x03, 0x61, 0x89,
821 0x37, 0xcb, 0xf2, 0x98, 0xa0, 0xce, 0xb4, 0xcb,
822 0x16, 0x13, 0xf0, 0xe6, 0xaf, 0x5c, 0xc5, 0xa7,
823 0x69, 0x71, 0xca, 0xba, 0x8d, 0xe0, 0x4d, 0xdd,
824 0xed, 0xb8, 0x48, 0x8b, 0x16, 0x93, 0x36, 0x95,
825 0xc2, 0x91, 0x40, 0x65, 0x17, 0xbd, 0x7f, 0xd6,
826 0xad, 0x9e, 0x30, 0x28, 0x46, 0xe4, 0x3e, 0xcc,
827 0x43, 0x78, 0xf9, 0xfe, 0x1f, 0x33, 0x23, 0x1e,
828 0x31, 0x12, 0x9d, 0x3c, 0xa7, 0x08, 0x82, 0x7b,
829 0x7d, 0x25, 0x4e, 0x5e, 0x19, 0xa8, 0x9b, 0xed,
830 0x86, 0xb2, 0xcb, 0x3c, 0xfe, 0x4e, 0xa1, 0xfa,
831 0x62, 0x87, 0x3a, 0x17, 0xf7, 0x60, 0xec, 0x38,
832 0x29, 0xe8, 0x4f, 0x34, 0x9f, 0x76, 0x9d, 0xee,
833 0xa3, 0xf6, 0x85, 0x6b, 0x84, 0x43, 0xc9, 0x1e,
834 0x01, 0xff, 0xfd, 0xd0, 0x29, 0x4c, 0xfa, 0x8e,
835 0x57, 0x0c, 0xc0, 0x71, 0xa5, 0xbb, 0x88, 0x46,
836 0x29, 0x5c, 0xc0, 0x4f, 0x01, 0x02, 0x41, 0x00,
837 0xf5, 0x83, 0xa4, 0x64, 0x4a, 0xf2, 0xdd, 0x8c,
838 0x2c, 0xed, 0xa8, 0xd5, 0x60, 0x5a, 0xe4, 0xc7,
839 0xcc, 0x61, 0xcd, 0x38, 0x42, 0x20, 0xd3, 0x82,
840 0x18, 0xf2, 0x35, 0x00, 0x72, 0x2d, 0xf7, 0x89,
841 0x80, 0x67, 0xb5, 0x93, 0x05, 0x5f, 0xdd, 0x42,
842 0xba, 0x16, 0x1a, 0xea, 0x15, 0xc6, 0xf0, 0xb8,
843 0x8c, 0xbc, 0xbf, 0x54, 0x9e, 0xf1, 0xc1, 0xb2,
844 0xb3, 0x8b, 0xb6, 0x26, 0x02, 0x30, 0xc4, 0x81,
845 0x02, 0x41, 0x00, 0xc0, 0x60, 0x62, 0x80, 0xe1,
846 0x22, 0x78, 0xf6, 0x9d, 0x83, 0x18, 0xeb, 0x72,
847 0x45, 0xd7, 0xc8, 0x01, 0x7f, 0xa9, 0xca, 0x8f,
848 0x7d, 0xd6, 0xb8, 0x31, 0x2b, 0x84, 0x7f, 0x62,
849 0xd9, 0xa9, 0x22, 0x17, 0x7d, 0x06, 0x35, 0x6c,
850 0xf3, 0xc1, 0x94, 0x17, 0x85, 0x5a, 0xaf, 0x9c,
851 0x5c, 0x09, 0x3c, 0xcf, 0x2f, 0x44, 0x9d, 0xb6,
852 0x52, 0x68, 0x5f, 0xf9, 0x59, 0xc8, 0x84, 0x2b,
853 0x39, 0x22, 0x8f, 0x02, 0x41, 0x00, 0xb2, 0x04,
854 0xe2, 0x0e, 0x56, 0xca, 0x03, 0x1a, 0xc0, 0xf9,
855 0x12, 0x92, 0xa5, 0x6b, 0x42, 0xb8, 0x1c, 0xda,
856 0x4d, 0x93, 0x9d, 0x5f, 0x6f, 0xfd, 0xc5, 0x58,
857 0xda, 0x55, 0x98, 0x74, 0xfc, 0x28, 0x17, 0x93,
858 0x1b, 0x75, 0x9f, 0x50, 0x03, 0x7f, 0x7e, 0xae,
859 0xc8, 0x95, 0x33, 0x75, 0x2c, 0xd6, 0xa4, 0x35,
860 0xb8, 0x06, 0x03, 0xba, 0x08, 0x59, 0x2b, 0x17,
861 0x02, 0xdc, 0x4c, 0x7a, 0x50, 0x01, 0x02, 0x41,
862 0x00, 0x9d, 0xdb, 0x39, 0x59, 0x09, 0xe4, 0x30,
863 0xa0, 0x24, 0xf5, 0xdb, 0x2f, 0xf0, 0x2f, 0xf1,
864 0x75, 0x74, 0x0d, 0x5e, 0xb5, 0x11, 0x73, 0xb0,
865 0x0a, 0xaa, 0x86, 0x4c, 0x0d, 0xff, 0x7e, 0x1d,
866 0xb4, 0x14, 0xd4, 0x09, 0x91, 0x33, 0x5a, 0xfd,
867 0xa0, 0x58, 0x80, 0x9b, 0xbe, 0x78, 0x2e, 0x69,
868 0x82, 0x15, 0x7c, 0x72, 0xf0, 0x7b, 0x18, 0x39,
869 0xff, 0x6e, 0xeb, 0xc6, 0x86, 0xf5, 0xb4, 0xc7,
870 0x6f, 0x02, 0x41, 0x00, 0x8d, 0x1a, 0x37, 0x0f,
871 0x76, 0xc4, 0x82, 0xfa, 0x5c, 0xc3, 0x79, 0x35,
872 0x3e, 0x70, 0x8a, 0xbf, 0x27, 0x49, 0xb0, 0x99,
873 0x63, 0xcb, 0x77, 0x5f, 0xa8, 0x82, 0x65, 0xf6,
874 0x03, 0x52, 0x51, 0xf1, 0xae, 0x2e, 0x05, 0xb3,
875 0xc6, 0xa4, 0x92, 0xd1, 0xce, 0x6c, 0x72, 0xfb,
876 0x21, 0xb3, 0x02, 0x87, 0xe4, 0xfd, 0x61, 0xca,
877 0x00, 0x42, 0x19, 0xf0, 0xda, 0x5a, 0x53, 0xe3,
878 0xb1, 0xc5, 0x15, 0xf3
879 };
880
881 std::vector<uint8> input;
882 input.resize(sizeof(private_key_info));
883 memcpy(&input.front(), private_key_info, sizeof(private_key_info));
884
885 private_key.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(input));
886 ASSERT_TRUE(private_key.get());
887
888 cert = X509Certificate::CreateSelfSigned(
889 private_key.get(), "CN=subject", 1, base::TimeDelta::FromDays(1));
890
891 EXPECT_EQ("subject", cert->subject().GetDisplayName());
892 EXPECT_FALSE(cert->HasExpired());
893 }
894
895 TEST(X509CertificateTest, GetDEREncoded) {
896 scoped_ptr<crypto::RSAPrivateKey> private_key(
897 crypto::RSAPrivateKey::Create(1024));
898 scoped_refptr<X509Certificate> cert =
899 X509Certificate::CreateSelfSigned(
900 private_key.get(), "CN=subject", 0, base::TimeDelta::FromDays(1));
901
902 std::string der_cert;
903 EXPECT_TRUE(X509Certificate::GetDEREncoded(cert->os_cert_handle(),
904 &der_cert));
905 EXPECT_FALSE(der_cert.empty());
906 }
907 #endif
908 #endif // !defined(OS_IOS)
909
910 class X509CertificateParseTest
911 : public testing::TestWithParam<CertificateFormatTestData> {
912 public:
913 virtual ~X509CertificateParseTest() {}
914 virtual void SetUp() {
915 test_data_ = GetParam();
916 }
917 virtual void TearDown() {}
918
919 protected:
920 CertificateFormatTestData test_data_;
921 };
922
923 TEST_P(X509CertificateParseTest, CanParseFormat) {
924 base::FilePath certs_dir = GetTestCertsDirectory();
925 CertificateList certs = CreateCertificateListFromFile(
926 certs_dir, test_data_.file_name, test_data_.format);
927 ASSERT_FALSE(certs.empty());
928 ASSERT_LE(certs.size(), arraysize(test_data_.chain_fingerprints));
929 CheckGoogleCert(certs.front(), google_parse_fingerprint,
930 kGoogleParseValidFrom, kGoogleParseValidTo);
931
932 size_t i;
933 for (i = 0; i < arraysize(test_data_.chain_fingerprints); ++i) {
934 if (test_data_.chain_fingerprints[i] == NULL) {
935 // No more test certificates expected - make sure no more were
936 // returned before marking this test a success.
937 EXPECT_EQ(i, certs.size());
938 break;
939 }
940
941 // A cert is expected - make sure that one was parsed.
942 ASSERT_LT(i, certs.size());
943
944 // Compare the parsed certificate with the expected certificate, by
945 // comparing fingerprints.
946 const X509Certificate* cert = certs[i];
947 const SHA1HashValue& actual_fingerprint = cert->fingerprint();
948 uint8* expected_fingerprint = test_data_.chain_fingerprints[i];
949
950 for (size_t j = 0; j < 20; ++j)
951 EXPECT_EQ(expected_fingerprint[j], actual_fingerprint.data[j]);
952 }
953 }
954
955 INSTANTIATE_TEST_CASE_P(, X509CertificateParseTest,
956 testing::ValuesIn(FormatTestData));
957
958 struct CertificateNameVerifyTestData {
959 // true iff we expect hostname to match an entry in cert_names.
960 bool expected;
961 // The hostname to match.
962 const char* hostname;
963 // Common name, may be used if |dns_names| or |ip_addrs| are empty.
964 const char* common_name;
965 // Comma separated list of certificate names to match against. Any occurrence
966 // of '#' will be replaced with a null character before processing.
967 const char* dns_names;
968 // Comma separated list of certificate IP Addresses to match against. Each
969 // address is x prefixed 16 byte hex code for v6 or dotted-decimals for v4.
970 const char* ip_addrs;
971 };
972
973 // GTest 'magic' pretty-printer, so that if/when a test fails, it knows how
974 // to output the parameter that was passed. Without this, it will simply
975 // attempt to print out the first twenty bytes of the object, which depending
976 // on platform and alignment, may result in an invalid read.
977 void PrintTo(const CertificateNameVerifyTestData& data, std::ostream* os) {
978 ASSERT_TRUE(data.hostname && data.common_name);
979 // Using StringPiece to allow for optional fields being NULL.
980 *os << " expected: " << data.expected
981 << "; hostname: " << data.hostname
982 << "; common_name: " << data.common_name
983 << "; dns_names: " << base::StringPiece(data.dns_names)
984 << "; ip_addrs: " << base::StringPiece(data.ip_addrs);
985 }
986
987 const CertificateNameVerifyTestData kNameVerifyTestData[] = {
988 { true, "foo.com", "foo.com" },
989 { true, "f", "f" },
990 { false, "h", "i" },
991 { true, "bar.foo.com", "*.foo.com" },
992 { true, "www.test.fr", "common.name",
993 "*.test.com,*.test.co.uk,*.test.de,*.test.fr" },
994 { true, "wwW.tESt.fr", "common.name",
995 ",*.*,*.test.de,*.test.FR,www" },
996 { false, "f.uk", ".uk" },
997 { false, "w.bar.foo.com", "?.bar.foo.com" },
998 { false, "www.foo.com", "(www|ftp).foo.com" },
999 { false, "www.foo.com", "www.foo.com#" }, // # = null char.
1000 { false, "www.foo.com", "", "www.foo.com#*.foo.com,#,#" },
1001 { false, "www.house.example", "ww.house.example" },
1002 { false, "test.org", "", "www.test.org,*.test.org,*.org" },
1003 { false, "w.bar.foo.com", "w*.bar.foo.com" },
1004 { false, "www.bar.foo.com", "ww*ww.bar.foo.com" },
1005 { false, "wwww.bar.foo.com", "ww*ww.bar.foo.com" },
1006 { true, "wwww.bar.foo.com", "w*w.bar.foo.com" },
1007 { false, "wwww.bar.foo.com", "w*w.bar.foo.c0m" },
1008 { true, "WALLY.bar.foo.com", "wa*.bar.foo.com" },
1009 { true, "wally.bar.foo.com", "*Ly.bar.foo.com" },
1010 { true, "ww%57.foo.com", "", "www.foo.com" },
1011 { true, "www&.foo.com", "www%26.foo.com" },
1012 // Common name must not be used if subject alternative name was provided.
1013 { false, "www.test.co.jp", "www.test.co.jp",
1014 "*.test.de,*.jp,www.test.co.uk,www.*.co.jp" },
1015 { false, "www.bar.foo.com", "www.bar.foo.com",
1016 "*.foo.com,*.*.foo.com,*.*.bar.foo.com,*..bar.foo.com," },
1017 { false, "www.bath.org", "www.bath.org", "", "20.30.40.50" },
1018 { false, "66.77.88.99", "www.bath.org", "www.bath.org" },
1019 // IDN tests
1020 { true, "xn--poema-9qae5a.com.br", "xn--poema-9qae5a.com.br" },
1021 { true, "www.xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br" },
1022 { false, "xn--poema-9qae5a.com.br", "", "*.xn--poema-9qae5a.com.br,"
1023 "xn--poema-*.com.br,"
1024 "xn--*-9qae5a.com.br,"
1025 "*--poema-9qae5a.com.br" },
1026 { true, "xn--poema-9qae5a.com.br", "*.com.br" },
1027 // The following are adapted from the examples quoted from
1028 // http://tools.ietf.org/html/rfc6125#section-6.4.3
1029 // (e.g., *.example.com would match foo.example.com but
1030 // not bar.foo.example.com or example.com).
1031 { true, "foo.example.com", "*.example.com" },
1032 { false, "bar.foo.example.com", "*.example.com" },
1033 { false, "example.com", "*.example.com" },
1034 // (e.g., baz*.example.net and *baz.example.net and b*z.example.net would
1035 // be taken to match baz1.example.net and foobaz.example.net and
1036 // buzz.example.net, respectively
1037 { true, "baz1.example.net", "baz*.example.net" },
1038 { true, "foobaz.example.net", "*baz.example.net" },
1039 { true, "buzz.example.net", "b*z.example.net" },
1040 // Wildcards should not be valid unless there are at least three name
1041 // components.
1042 { true, "h.co.uk", "*.co.uk" },
1043 { false, "foo.com", "*.com" },
1044 { false, "foo.us", "*.us" },
1045 { false, "foo", "*" },
1046 // Multiple wildcards are not valid.
1047 { false, "foo.example.com", "*.*.com" },
1048 { false, "foo.bar.example.com", "*.bar.*.com" },
1049 // Absolute vs relative DNS name tests. Although not explicitly specified
1050 // in RFC 6125, absolute reference names (those ending in a .) should
1051 // match either absolute or relative presented names.
1052 { true, "foo.com", "foo.com." },
1053 { true, "foo.com.", "foo.com" },
1054 { true, "foo.com.", "foo.com." },
1055 { true, "f", "f." },
1056 { true, "f.", "f" },
1057 { true, "f.", "f." },
1058 { true, "www-3.bar.foo.com", "*.bar.foo.com." },
1059 { true, "www-3.bar.foo.com.", "*.bar.foo.com" },
1060 { true, "www-3.bar.foo.com.", "*.bar.foo.com." },
1061 { false, ".", "." },
1062 { false, "example.com", "*.com." },
1063 { false, "example.com.", "*.com" },
1064 { false, "example.com.", "*.com." },
1065 { false, "foo.", "*." },
1066 // IP addresses in common name; IPv4 only.
1067 { true, "127.0.0.1", "127.0.0.1" },
1068 { true, "192.168.1.1", "192.168.1.1" },
1069 { true, "676768", "0.10.83.160" },
1070 { true, "1.2.3", "1.2.0.3" },
1071 { false, "192.169.1.1", "192.168.1.1" },
1072 { false, "12.19.1.1", "12.19.1.1/255.255.255.0" },
1073 { false, "FEDC:ba98:7654:3210:FEDC:BA98:7654:3210",
1074 "FEDC:BA98:7654:3210:FEDC:ba98:7654:3210" },
1075 { false, "1111:2222:3333:4444:5555:6666:7777:8888",
1076 "1111:2222:3333:4444:5555:6666:7777:8888" },
1077 { false, "::192.9.5.5", "[::192.9.5.5]" },
1078 // No wildcard matching in valid IP addresses
1079 { false, "::192.9.5.5", "*.9.5.5" },
1080 { false, "2010:836B:4179::836B:4179", "*:836B:4179::836B:4179" },
1081 { false, "192.168.1.11", "*.168.1.11" },
1082 { false, "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210", "*.]" },
1083 // IP addresses in subject alternative name (common name ignored)
1084 { true, "10.1.2.3", "", "", "10.1.2.3" },
1085 { true, "14.15", "", "", "14.0.0.15" },
1086 { false, "10.1.2.7", "10.1.2.7", "", "10.1.2.6,10.1.2.8" },
1087 { false, "10.1.2.8", "10.20.2.8", "foo" },
1088 { true, "::4.5.6.7", "", "", "x00000000000000000000000004050607" },
1089 { false, "::6.7.8.9", "::6.7.8.9", "::6.7.8.9",
1090 "x00000000000000000000000006070808,x0000000000000000000000000607080a,"
1091 "xff000000000000000000000006070809,6.7.8.9" },
1092 { true, "FE80::200:f8ff:fe21:67cf", "no.common.name", "",
1093 "x00000000000000000000000006070808,xfe800000000000000200f8fffe2167cf,"
1094 "xff0000000000000000000000060708ff,10.0.0.1" },
1095 // Numeric only hostnames (none of these are considered valid IP addresses).
1096 { false, "12345.6", "12345.6" },
1097 { false, "121.2.3.512", "", "1*1.2.3.512,*1.2.3.512,1*.2.3.512,*.2.3.512",
1098 "121.2.3.0"},
1099 { false, "1.2.3.4.5.6", "*.2.3.4.5.6" },
1100 { true, "1.2.3.4.5", "", "1.2.3.4.5" },
1101 // Invalid host names.
1102 { false, "junk)(£)$*!@~#", "junk)(£)$*!@~#" },
1103 { false, "www.*.com", "www.*.com" },
1104 { false, "w$w.f.com", "w$w.f.com" },
1105 { false, "nocolonallowed:example", "", "nocolonallowed:example" },
1106 { false, "www-1.[::FFFF:129.144.52.38]", "*.[::FFFF:129.144.52.38]" },
1107 { false, "[::4.5.6.9]", "", "", "x00000000000000000000000004050609" },
1108 };
1109
1110 class X509CertificateNameVerifyTest
1111 : public testing::TestWithParam<CertificateNameVerifyTestData> {
1112 };
1113
1114 TEST_P(X509CertificateNameVerifyTest, VerifyHostname) {
1115 CertificateNameVerifyTestData test_data = GetParam();
1116
1117 std::string common_name(test_data.common_name);
1118 ASSERT_EQ(std::string::npos, common_name.find(','));
1119 std::replace(common_name.begin(), common_name.end(), '#', '\0');
1120
1121 std::vector<std::string> dns_names, ip_addressses;
1122 if (test_data.dns_names) {
1123 // Build up the certificate DNS names list.
1124 std::string dns_name_line(test_data.dns_names);
1125 std::replace(dns_name_line.begin(), dns_name_line.end(), '#', '\0');
1126 base::SplitString(dns_name_line, ',', &dns_names);
1127 }
1128
1129 if (test_data.ip_addrs) {
1130 // Build up the certificate IP address list.
1131 std::string ip_addrs_line(test_data.ip_addrs);
1132 std::vector<std::string> ip_addressses_ascii;
1133 base::SplitString(ip_addrs_line, ',', &ip_addressses_ascii);
1134 for (size_t i = 0; i < ip_addressses_ascii.size(); ++i) {
1135 std::string& addr_ascii = ip_addressses_ascii[i];
1136 ASSERT_NE(0U, addr_ascii.length());
1137 if (addr_ascii[0] == 'x') { // Hex encoded address
1138 addr_ascii.erase(0, 1);
1139 std::vector<uint8> bytes;
1140 EXPECT_TRUE(base::HexStringToBytes(addr_ascii, &bytes))
1141 << "Could not parse hex address " << addr_ascii << " i = " << i;
1142 ip_addressses.push_back(std::string(reinterpret_cast<char*>(&bytes[0]),
1143 bytes.size()));
1144 ASSERT_EQ(16U, ip_addressses.back().size()) << i;
1145 } else { // Decimal groups
1146 std::vector<std::string> decimals_ascii;
1147 base::SplitString(addr_ascii, '.', &decimals_ascii);
1148 EXPECT_EQ(4U, decimals_ascii.size()) << i;
1149 std::string addr_bytes;
1150 for (size_t j = 0; j < decimals_ascii.size(); ++j) {
1151 int decimal_value;
1152 EXPECT_TRUE(base::StringToInt(decimals_ascii[j], &decimal_value));
1153 EXPECT_GE(decimal_value, 0);
1154 EXPECT_LE(decimal_value, 255);
1155 addr_bytes.push_back(static_cast<char>(decimal_value));
1156 }
1157 ip_addressses.push_back(addr_bytes);
1158 ASSERT_EQ(4U, ip_addressses.back().size()) << i;
1159 }
1160 }
1161 }
1162
1163 EXPECT_EQ(test_data.expected, X509Certificate::VerifyHostname(
1164 test_data.hostname, common_name, dns_names, ip_addressses));
1165 }
1166
1167 INSTANTIATE_TEST_CASE_P(, X509CertificateNameVerifyTest,
1168 testing::ValuesIn(kNameVerifyTestData));
1169
1170 } // namespace net
OLDNEW
« no previous file with comments | « net/base/x509_certificate_openssl.cc ('k') | net/base/x509_certificate_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698