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