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/cert/x509_certificate.h"
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/strings/string_number_conversions.h"
13 #include "base/strings/string_split.h"
14 #include "crypto/rsa_private_key.h"
15 #include "net/base/net_errors.h"
16 #include "net/base/test_data_directory.h"
17 #include "net/cert/asn1_util.h"
18 #include "net/test/cert_test_util.h"
19 #include "net/test/test_certificate_data.h"
20 #include "testing/gtest/include/gtest/gtest.h"
27 #include "base/win/windows_version.h"
30 using base::HexEncode
;
35 // Certificates for test data. They're obtained with:
37 // $ openssl s_client -connect [host]:443 -showcerts > /tmp/host.pem < /dev/null
38 // $ openssl x509 -inform PEM -outform DER < /tmp/host.pem > /tmp/host.der
41 // $ openssl x509 -inform DER -fingerprint -noout < /tmp/host.der
43 // For valid_start, valid_expiry
44 // $ openssl x509 -inform DER -text -noout < /tmp/host.der |
46 // $ date +%s -d '<date str>'
49 uint8 google_fingerprint
[] = {
50 0xab, 0xbe, 0x5e, 0xb4, 0x93, 0x88, 0x4e, 0xe4, 0x60, 0xc6, 0xef, 0xf8,
51 0xea, 0xd4, 0xb1, 0x55, 0x4b, 0xc9, 0x59, 0x3c
55 uint8 webkit_fingerprint
[] = {
56 0xa1, 0x4a, 0x94, 0x46, 0x22, 0x8e, 0x70, 0x66, 0x2b, 0x94, 0xf9, 0xf8,
57 0x57, 0x83, 0x2d, 0xa2, 0xff, 0xbc, 0x84, 0xc2
60 // thawte.com's cert (it's EV-licious!).
61 uint8 thawte_fingerprint
[] = {
62 0x85, 0x04, 0x2d, 0xfd, 0x2b, 0x0e, 0xc6, 0xc8, 0xaf, 0x2d, 0x77, 0xd6,
63 0xa1, 0x3a, 0x64, 0x04, 0x27, 0x90, 0x97, 0x37
66 // A certificate for https://www.unosoft.hu/, whose AIA extension contains
67 // an LDAP URL without a host name.
68 uint8 unosoft_hu_fingerprint
[] = {
69 0x32, 0xff, 0xe3, 0xbe, 0x2c, 0x3b, 0xc7, 0xca, 0xbf, 0x2d, 0x64, 0xbd,
70 0x25, 0x66, 0xf2, 0xec, 0x8b, 0x0f, 0xbf, 0xd8
73 // The fingerprint of the Google certificate used in the parsing tests,
74 // which is newer than the one included in the x509_certificate_data.h
75 uint8 google_parse_fingerprint
[] = {
76 0x40, 0x50, 0x62, 0xe5, 0xbe, 0xfd, 0xe4, 0xaf, 0x97, 0xe9, 0x38, 0x2a,
77 0xf1, 0x6c, 0xc8, 0x7c, 0x8f, 0xb7, 0xc4, 0xe2
80 // The fingerprint for the Thawte SGC certificate
81 uint8 thawte_parse_fingerprint
[] = {
82 0xec, 0x07, 0x10, 0x03, 0xd8, 0xf5, 0xa3, 0x7f, 0x42, 0xc4, 0x55, 0x7f,
83 0x65, 0x6a, 0xae, 0x86, 0x65, 0xfa, 0x4b, 0x02
86 // Dec 18 00:00:00 2009 GMT
87 const double kGoogleParseValidFrom
= 1261094400;
88 // Dec 18 23:59:59 2011 GMT
89 const double kGoogleParseValidTo
= 1324252799;
91 void CheckGoogleCert(const scoped_refptr
<X509Certificate
>& google_cert
,
92 uint8
* expected_fingerprint
,
93 double valid_from
, double valid_to
) {
94 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), google_cert
);
96 const CertPrincipal
& subject
= google_cert
->subject();
97 EXPECT_EQ("www.google.com", subject
.common_name
);
98 EXPECT_EQ("Mountain View", subject
.locality_name
);
99 EXPECT_EQ("California", subject
.state_or_province_name
);
100 EXPECT_EQ("US", subject
.country_name
);
101 EXPECT_EQ(0U, subject
.street_addresses
.size());
102 ASSERT_EQ(1U, subject
.organization_names
.size());
103 EXPECT_EQ("Google Inc", subject
.organization_names
[0]);
104 EXPECT_EQ(0U, subject
.organization_unit_names
.size());
105 EXPECT_EQ(0U, subject
.domain_components
.size());
107 const CertPrincipal
& issuer
= google_cert
->issuer();
108 EXPECT_EQ("Thawte SGC CA", issuer
.common_name
);
109 EXPECT_EQ("", issuer
.locality_name
);
110 EXPECT_EQ("", issuer
.state_or_province_name
);
111 EXPECT_EQ("ZA", issuer
.country_name
);
112 EXPECT_EQ(0U, issuer
.street_addresses
.size());
113 ASSERT_EQ(1U, issuer
.organization_names
.size());
114 EXPECT_EQ("Thawte Consulting (Pty) Ltd.", issuer
.organization_names
[0]);
115 EXPECT_EQ(0U, issuer
.organization_unit_names
.size());
116 EXPECT_EQ(0U, issuer
.domain_components
.size());
118 // Use DoubleT because its epoch is the same on all platforms
119 const Time
& valid_start
= google_cert
->valid_start();
120 EXPECT_EQ(valid_from
, valid_start
.ToDoubleT());
122 const Time
& valid_expiry
= google_cert
->valid_expiry();
123 EXPECT_EQ(valid_to
, valid_expiry
.ToDoubleT());
125 const SHA1HashValue
& fingerprint
= google_cert
->fingerprint();
126 for (size_t i
= 0; i
< 20; ++i
)
127 EXPECT_EQ(expected_fingerprint
[i
], fingerprint
.data
[i
]);
129 std::vector
<std::string
> dns_names
;
130 google_cert
->GetDNSNames(&dns_names
);
131 ASSERT_EQ(1U, dns_names
.size());
132 EXPECT_EQ("www.google.com", dns_names
[0]);
135 TEST(X509CertificateTest
, GoogleCertParsing
) {
136 scoped_refptr
<X509Certificate
> google_cert(
137 X509Certificate::CreateFromBytes(
138 reinterpret_cast<const char*>(google_der
), sizeof(google_der
)));
140 CheckGoogleCert(google_cert
, google_fingerprint
,
141 1238192407, // Mar 27 22:20:07 2009 GMT
142 1269728407); // Mar 27 22:20:07 2010 GMT
145 TEST(X509CertificateTest
, WebkitCertParsing
) {
146 scoped_refptr
<X509Certificate
> webkit_cert(X509Certificate::CreateFromBytes(
147 reinterpret_cast<const char*>(webkit_der
), sizeof(webkit_der
)));
149 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), webkit_cert
);
151 const CertPrincipal
& subject
= webkit_cert
->subject();
152 EXPECT_EQ("Cupertino", subject
.locality_name
);
153 EXPECT_EQ("California", subject
.state_or_province_name
);
154 EXPECT_EQ("US", subject
.country_name
);
155 EXPECT_EQ(0U, subject
.street_addresses
.size());
156 ASSERT_EQ(1U, subject
.organization_names
.size());
157 EXPECT_EQ("Apple Inc.", subject
.organization_names
[0]);
158 ASSERT_EQ(1U, subject
.organization_unit_names
.size());
159 EXPECT_EQ("Mac OS Forge", subject
.organization_unit_names
[0]);
160 EXPECT_EQ(0U, subject
.domain_components
.size());
162 const CertPrincipal
& issuer
= webkit_cert
->issuer();
163 EXPECT_EQ("Go Daddy Secure Certification Authority", issuer
.common_name
);
164 EXPECT_EQ("Scottsdale", issuer
.locality_name
);
165 EXPECT_EQ("Arizona", issuer
.state_or_province_name
);
166 EXPECT_EQ("US", issuer
.country_name
);
167 EXPECT_EQ(0U, issuer
.street_addresses
.size());
168 ASSERT_EQ(1U, issuer
.organization_names
.size());
169 EXPECT_EQ("GoDaddy.com, Inc.", issuer
.organization_names
[0]);
170 ASSERT_EQ(1U, issuer
.organization_unit_names
.size());
171 EXPECT_EQ("http://certificates.godaddy.com/repository",
172 issuer
.organization_unit_names
[0]);
173 EXPECT_EQ(0U, issuer
.domain_components
.size());
175 // Use DoubleT because its epoch is the same on all platforms
176 const Time
& valid_start
= webkit_cert
->valid_start();
177 EXPECT_EQ(1205883319, valid_start
.ToDoubleT()); // Mar 18 23:35:19 2008 GMT
179 const Time
& valid_expiry
= webkit_cert
->valid_expiry();
180 EXPECT_EQ(1300491319, valid_expiry
.ToDoubleT()); // Mar 18 23:35:19 2011 GMT
182 const SHA1HashValue
& fingerprint
= webkit_cert
->fingerprint();
183 for (size_t i
= 0; i
< 20; ++i
)
184 EXPECT_EQ(webkit_fingerprint
[i
], fingerprint
.data
[i
]);
186 std::vector
<std::string
> dns_names
;
187 webkit_cert
->GetDNSNames(&dns_names
);
188 ASSERT_EQ(2U, dns_names
.size());
189 EXPECT_EQ("*.webkit.org", dns_names
[0]);
190 EXPECT_EQ("webkit.org", dns_names
[1]);
192 // Test that the wildcard cert matches properly.
194 EXPECT_TRUE(webkit_cert
->VerifyNameMatch("www.webkit.org", &unused
));
195 EXPECT_TRUE(webkit_cert
->VerifyNameMatch("foo.webkit.org", &unused
));
196 EXPECT_TRUE(webkit_cert
->VerifyNameMatch("webkit.org", &unused
));
197 EXPECT_FALSE(webkit_cert
->VerifyNameMatch("www.webkit.com", &unused
));
198 EXPECT_FALSE(webkit_cert
->VerifyNameMatch("www.foo.webkit.com", &unused
));
201 TEST(X509CertificateTest
, ThawteCertParsing
) {
202 scoped_refptr
<X509Certificate
> thawte_cert(X509Certificate::CreateFromBytes(
203 reinterpret_cast<const char*>(thawte_der
), sizeof(thawte_der
)));
205 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), thawte_cert
);
207 const CertPrincipal
& subject
= thawte_cert
->subject();
208 EXPECT_EQ("www.thawte.com", subject
.common_name
);
209 EXPECT_EQ("Mountain View", subject
.locality_name
);
210 EXPECT_EQ("California", subject
.state_or_province_name
);
211 EXPECT_EQ("US", subject
.country_name
);
212 EXPECT_EQ(0U, subject
.street_addresses
.size());
213 ASSERT_EQ(1U, subject
.organization_names
.size());
214 EXPECT_EQ("Thawte Inc", subject
.organization_names
[0]);
215 EXPECT_EQ(0U, subject
.organization_unit_names
.size());
216 EXPECT_EQ(0U, subject
.domain_components
.size());
218 const CertPrincipal
& issuer
= thawte_cert
->issuer();
219 EXPECT_EQ("thawte Extended Validation SSL CA", issuer
.common_name
);
220 EXPECT_EQ("", issuer
.locality_name
);
221 EXPECT_EQ("", issuer
.state_or_province_name
);
222 EXPECT_EQ("US", issuer
.country_name
);
223 EXPECT_EQ(0U, issuer
.street_addresses
.size());
224 ASSERT_EQ(1U, issuer
.organization_names
.size());
225 EXPECT_EQ("thawte, Inc.", issuer
.organization_names
[0]);
226 ASSERT_EQ(1U, issuer
.organization_unit_names
.size());
227 EXPECT_EQ("Terms of use at https://www.thawte.com/cps (c)06",
228 issuer
.organization_unit_names
[0]);
229 EXPECT_EQ(0U, issuer
.domain_components
.size());
231 // Use DoubleT because its epoch is the same on all platforms
232 const Time
& valid_start
= thawte_cert
->valid_start();
233 EXPECT_EQ(1227052800, valid_start
.ToDoubleT()); // Nov 19 00:00:00 2008 GMT
235 const Time
& valid_expiry
= thawte_cert
->valid_expiry();
236 EXPECT_EQ(1263772799, valid_expiry
.ToDoubleT()); // Jan 17 23:59:59 2010 GMT
238 const SHA1HashValue
& fingerprint
= thawte_cert
->fingerprint();
239 for (size_t i
= 0; i
< 20; ++i
)
240 EXPECT_EQ(thawte_fingerprint
[i
], fingerprint
.data
[i
]);
242 std::vector
<std::string
> dns_names
;
243 thawte_cert
->GetDNSNames(&dns_names
);
244 ASSERT_EQ(1U, dns_names
.size());
245 EXPECT_EQ("www.thawte.com", dns_names
[0]);
248 // Test that all desired AttributeAndValue pairs can be extracted when only
249 // a single RelativeDistinguishedName is present. "Normally" there is only
250 // one AVA per RDN, but some CAs place all AVAs within a single RDN.
251 // This is a regression test for http://crbug.com/101009
252 TEST(X509CertificateTest
, MultivalueRDN
) {
253 base::FilePath certs_dir
= GetTestCertsDirectory();
255 scoped_refptr
<X509Certificate
> multivalue_rdn_cert
=
256 ImportCertFromFile(certs_dir
, "multivalue_rdn.pem");
257 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), multivalue_rdn_cert
);
259 const CertPrincipal
& subject
= multivalue_rdn_cert
->subject();
260 EXPECT_EQ("Multivalue RDN Test", subject
.common_name
);
261 EXPECT_EQ("", subject
.locality_name
);
262 EXPECT_EQ("", subject
.state_or_province_name
);
263 EXPECT_EQ("US", subject
.country_name
);
264 EXPECT_EQ(0U, subject
.street_addresses
.size());
265 ASSERT_EQ(1U, subject
.organization_names
.size());
266 EXPECT_EQ("Chromium", subject
.organization_names
[0]);
267 ASSERT_EQ(1U, subject
.organization_unit_names
.size());
268 EXPECT_EQ("Chromium net_unittests", subject
.organization_unit_names
[0]);
269 ASSERT_EQ(1U, subject
.domain_components
.size());
270 EXPECT_EQ("Chromium", subject
.domain_components
[0]);
273 // Test that characters which would normally be escaped in the string form,
274 // such as '=' or '"', are not escaped when parsed as individual components.
275 // This is a regression test for http://crbug.com/102839
276 TEST(X509CertificateTest
, UnescapedSpecialCharacters
) {
277 base::FilePath certs_dir
= GetTestCertsDirectory();
279 scoped_refptr
<X509Certificate
> unescaped_cert
=
280 ImportCertFromFile(certs_dir
, "unescaped.pem");
281 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), unescaped_cert
);
283 const CertPrincipal
& subject
= unescaped_cert
->subject();
284 EXPECT_EQ("127.0.0.1", subject
.common_name
);
285 EXPECT_EQ("Mountain View", subject
.locality_name
);
286 EXPECT_EQ("California", subject
.state_or_province_name
);
287 EXPECT_EQ("US", subject
.country_name
);
288 ASSERT_EQ(1U, subject
.street_addresses
.size());
289 EXPECT_EQ("1600 Amphitheatre Parkway", subject
.street_addresses
[0]);
290 ASSERT_EQ(1U, subject
.organization_names
.size());
291 EXPECT_EQ("Chromium = \"net_unittests\"", subject
.organization_names
[0]);
292 ASSERT_EQ(2U, subject
.organization_unit_names
.size());
293 EXPECT_EQ("net_unittests", subject
.organization_unit_names
[0]);
294 EXPECT_EQ("Chromium", subject
.organization_unit_names
[1]);
295 EXPECT_EQ(0U, subject
.domain_components
.size());
298 TEST(X509CertificateTest
, SerialNumbers
) {
299 scoped_refptr
<X509Certificate
> google_cert(
300 X509Certificate::CreateFromBytes(
301 reinterpret_cast<const char*>(google_der
), sizeof(google_der
)));
303 static const uint8 google_serial
[16] = {
304 0x01,0x2a,0x39,0x76,0x0d,0x3f,0x4f,0xc9,
305 0x0b,0xe7,0xbd,0x2b,0xcf,0x95,0x2e,0x7a,
308 ASSERT_EQ(sizeof(google_serial
), google_cert
->serial_number().size());
309 EXPECT_TRUE(memcmp(google_cert
->serial_number().data(), google_serial
,
310 sizeof(google_serial
)) == 0);
312 // We also want to check a serial number where the first byte is >= 0x80 in
313 // case the underlying library tries to pad it.
314 scoped_refptr
<X509Certificate
> paypal_null_cert(
315 X509Certificate::CreateFromBytes(
316 reinterpret_cast<const char*>(paypal_null_der
),
317 sizeof(paypal_null_der
)));
319 static const uint8 paypal_null_serial
[3] = {0x00, 0xf0, 0x9b};
320 ASSERT_EQ(sizeof(paypal_null_serial
),
321 paypal_null_cert
->serial_number().size());
322 EXPECT_TRUE(memcmp(paypal_null_cert
->serial_number().data(),
323 paypal_null_serial
, sizeof(paypal_null_serial
)) == 0);
326 TEST(X509CertificateTest
, CAFingerprints
) {
327 base::FilePath certs_dir
= GetTestCertsDirectory();
329 scoped_refptr
<X509Certificate
> server_cert
=
330 ImportCertFromFile(certs_dir
, "salesforce_com_test.pem");
331 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), server_cert
);
333 scoped_refptr
<X509Certificate
> intermediate_cert1
=
334 ImportCertFromFile(certs_dir
, "verisign_intermediate_ca_2011.pem");
335 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), intermediate_cert1
);
337 scoped_refptr
<X509Certificate
> intermediate_cert2
=
338 ImportCertFromFile(certs_dir
, "verisign_intermediate_ca_2016.pem");
339 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), intermediate_cert2
);
341 X509Certificate::OSCertHandles intermediates
;
342 intermediates
.push_back(intermediate_cert1
->os_cert_handle());
343 scoped_refptr
<X509Certificate
> cert_chain1
=
344 X509Certificate::CreateFromHandle(server_cert
->os_cert_handle(),
347 intermediates
.clear();
348 intermediates
.push_back(intermediate_cert2
->os_cert_handle());
349 scoped_refptr
<X509Certificate
> cert_chain2
=
350 X509Certificate::CreateFromHandle(server_cert
->os_cert_handle(),
353 // No intermediate CA certicates.
354 intermediates
.clear();
355 scoped_refptr
<X509Certificate
> cert_chain3
=
356 X509Certificate::CreateFromHandle(server_cert
->os_cert_handle(),
359 static const uint8 cert_chain1_ca_fingerprint
[20] = {
360 0xc2, 0xf0, 0x08, 0x7d, 0x01, 0xe6, 0x86, 0x05, 0x3a, 0x4d,
361 0x63, 0x3e, 0x7e, 0x70, 0xd4, 0xef, 0x65, 0xc2, 0xcc, 0x4f
363 static const uint8 cert_chain2_ca_fingerprint
[20] = {
364 0xd5, 0x59, 0xa5, 0x86, 0x66, 0x9b, 0x08, 0xf4, 0x6a, 0x30,
365 0xa1, 0x33, 0xf8, 0xa9, 0xed, 0x3d, 0x03, 0x8e, 0x2e, 0xa8
367 // The SHA-1 hash of nothing.
368 static const uint8 cert_chain3_ca_fingerprint
[20] = {
369 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55,
370 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09
372 EXPECT_TRUE(memcmp(cert_chain1
->ca_fingerprint().data
,
373 cert_chain1_ca_fingerprint
, 20) == 0);
374 EXPECT_TRUE(memcmp(cert_chain2
->ca_fingerprint().data
,
375 cert_chain2_ca_fingerprint
, 20) == 0);
376 EXPECT_TRUE(memcmp(cert_chain3
->ca_fingerprint().data
,
377 cert_chain3_ca_fingerprint
, 20) == 0);
380 TEST(X509CertificateTest
, ParseSubjectAltNames
) {
381 base::FilePath certs_dir
= GetTestCertsDirectory();
383 scoped_refptr
<X509Certificate
> san_cert
=
384 ImportCertFromFile(certs_dir
, "subjectAltName_sanity_check.pem");
385 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), san_cert
);
387 std::vector
<std::string
> dns_names
;
388 std::vector
<std::string
> ip_addresses
;
389 san_cert
->GetSubjectAltName(&dns_names
, &ip_addresses
);
391 // Ensure that DNS names are correctly parsed.
392 ASSERT_EQ(1U, dns_names
.size());
393 EXPECT_EQ("test.example", dns_names
[0]);
395 // Ensure that both IPv4 and IPv6 addresses are correctly parsed.
396 ASSERT_EQ(2U, ip_addresses
.size());
398 static const uint8 kIPv4Address
[] = {
399 0x7F, 0x00, 0x00, 0x02
401 ASSERT_EQ(arraysize(kIPv4Address
), ip_addresses
[0].size());
402 EXPECT_EQ(0, memcmp(ip_addresses
[0].data(), kIPv4Address
,
403 arraysize(kIPv4Address
)));
405 static const uint8 kIPv6Address
[] = {
406 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
407 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
409 ASSERT_EQ(arraysize(kIPv6Address
), ip_addresses
[1].size());
410 EXPECT_EQ(0, memcmp(ip_addresses
[1].data(), kIPv6Address
,
411 arraysize(kIPv6Address
)));
413 // Ensure the subjectAltName dirName has not influenced the handling of
414 // the subject commonName.
415 EXPECT_EQ("127.0.0.1", san_cert
->subject().common_name
);
418 TEST(X509CertificateTest
, ExtractSPKIFromDERCert
) {
419 base::FilePath certs_dir
= GetTestCertsDirectory();
420 scoped_refptr
<X509Certificate
> cert
=
421 ImportCertFromFile(certs_dir
, "nist.der");
422 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), cert
);
424 std::string derBytes
;
425 EXPECT_TRUE(X509Certificate::GetDEREncoded(cert
->os_cert_handle(),
428 base::StringPiece spkiBytes
;
429 EXPECT_TRUE(asn1::ExtractSPKIFromDERCert(derBytes
, &spkiBytes
));
431 uint8 hash
[base::kSHA1Length
];
432 base::SHA1HashBytes(reinterpret_cast<const uint8
*>(spkiBytes
.data()),
433 spkiBytes
.size(), hash
);
435 EXPECT_EQ(0, memcmp(hash
, kNistSPKIHash
, sizeof(hash
)));
438 TEST(X509CertificateTest
, ExtractCRLURLsFromDERCert
) {
439 base::FilePath certs_dir
= GetTestCertsDirectory();
440 scoped_refptr
<X509Certificate
> cert
=
441 ImportCertFromFile(certs_dir
, "nist.der");
442 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), cert
);
444 std::string derBytes
;
445 EXPECT_TRUE(X509Certificate::GetDEREncoded(cert
->os_cert_handle(),
448 std::vector
<base::StringPiece
> crl_urls
;
449 EXPECT_TRUE(asn1::ExtractCRLURLsFromDERCert(derBytes
, &crl_urls
));
451 EXPECT_EQ(1u, crl_urls
.size());
452 if (crl_urls
.size() > 0) {
453 EXPECT_EQ("http://SVRSecure-G3-crl.verisign.com/SVRSecureG3.crl",
454 crl_urls
[0].as_string());
458 // Tests X509CertificateCache via X509Certificate::CreateFromHandle. We
459 // call X509Certificate::CreateFromHandle several times and observe whether
460 // it returns a cached or new OSCertHandle.
461 TEST(X509CertificateTest
, Cache
) {
462 X509Certificate::OSCertHandle google_cert_handle
;
463 X509Certificate::OSCertHandle thawte_cert_handle
;
465 // Add a single certificate to the certificate cache.
466 google_cert_handle
= X509Certificate::CreateOSCertHandleFromBytes(
467 reinterpret_cast<const char*>(google_der
), sizeof(google_der
));
468 scoped_refptr
<X509Certificate
> cert1(X509Certificate::CreateFromHandle(
469 google_cert_handle
, X509Certificate::OSCertHandles()));
470 X509Certificate::FreeOSCertHandle(google_cert_handle
);
472 // Add the same certificate, but as a new handle.
473 google_cert_handle
= X509Certificate::CreateOSCertHandleFromBytes(
474 reinterpret_cast<const char*>(google_der
), sizeof(google_der
));
475 scoped_refptr
<X509Certificate
> cert2(X509Certificate::CreateFromHandle(
476 google_cert_handle
, X509Certificate::OSCertHandles()));
477 X509Certificate::FreeOSCertHandle(google_cert_handle
);
479 // A new X509Certificate should be returned.
480 EXPECT_NE(cert1
.get(), cert2
.get());
481 // But both instances should share the underlying OS certificate handle.
482 EXPECT_EQ(cert1
->os_cert_handle(), cert2
->os_cert_handle());
483 EXPECT_EQ(0u, cert1
->GetIntermediateCertificates().size());
484 EXPECT_EQ(0u, cert2
->GetIntermediateCertificates().size());
486 // Add the same certificate, but this time with an intermediate. This
487 // should result in the intermediate being cached. Note that this is not
488 // a legitimate chain, but is suitable for testing.
489 google_cert_handle
= X509Certificate::CreateOSCertHandleFromBytes(
490 reinterpret_cast<const char*>(google_der
), sizeof(google_der
));
491 thawte_cert_handle
= X509Certificate::CreateOSCertHandleFromBytes(
492 reinterpret_cast<const char*>(thawte_der
), sizeof(thawte_der
));
493 X509Certificate::OSCertHandles intermediates
;
494 intermediates
.push_back(thawte_cert_handle
);
495 scoped_refptr
<X509Certificate
> cert3(X509Certificate::CreateFromHandle(
496 google_cert_handle
, intermediates
));
497 X509Certificate::FreeOSCertHandle(google_cert_handle
);
498 X509Certificate::FreeOSCertHandle(thawte_cert_handle
);
500 // Test that the new certificate, even with intermediates, results in the
501 // same underlying handle being used.
502 EXPECT_EQ(cert1
->os_cert_handle(), cert3
->os_cert_handle());
503 // Though they use the same OS handle, the intermediates should be different.
504 EXPECT_NE(cert1
->GetIntermediateCertificates().size(),
505 cert3
->GetIntermediateCertificates().size());
508 TEST(X509CertificateTest
, Pickle
) {
509 X509Certificate::OSCertHandle google_cert_handle
=
510 X509Certificate::CreateOSCertHandleFromBytes(
511 reinterpret_cast<const char*>(google_der
), sizeof(google_der
));
512 X509Certificate::OSCertHandle thawte_cert_handle
=
513 X509Certificate::CreateOSCertHandleFromBytes(
514 reinterpret_cast<const char*>(thawte_der
), sizeof(thawte_der
));
516 X509Certificate::OSCertHandles intermediates
;
517 intermediates
.push_back(thawte_cert_handle
);
518 scoped_refptr
<X509Certificate
> cert
= X509Certificate::CreateFromHandle(
519 google_cert_handle
, intermediates
);
520 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), cert
.get());
522 X509Certificate::FreeOSCertHandle(google_cert_handle
);
523 X509Certificate::FreeOSCertHandle(thawte_cert_handle
);
526 cert
->Persist(&pickle
);
528 PickleIterator
iter(pickle
);
529 scoped_refptr
<X509Certificate
> cert_from_pickle
=
530 X509Certificate::CreateFromPickle(
531 pickle
, &iter
, X509Certificate::PICKLETYPE_CERTIFICATE_CHAIN_V3
);
532 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), cert_from_pickle
);
533 EXPECT_TRUE(X509Certificate::IsSameOSCert(
534 cert
->os_cert_handle(), cert_from_pickle
->os_cert_handle()));
535 const X509Certificate::OSCertHandles
& cert_intermediates
=
536 cert
->GetIntermediateCertificates();
537 const X509Certificate::OSCertHandles
& pickle_intermediates
=
538 cert_from_pickle
->GetIntermediateCertificates();
539 ASSERT_EQ(cert_intermediates
.size(), pickle_intermediates
.size());
540 for (size_t i
= 0; i
< cert_intermediates
.size(); ++i
) {
541 EXPECT_TRUE(X509Certificate::IsSameOSCert(cert_intermediates
[i
],
542 pickle_intermediates
[i
]));
546 TEST(X509CertificateTest
, Policy
) {
547 scoped_refptr
<X509Certificate
> google_cert(X509Certificate::CreateFromBytes(
548 reinterpret_cast<const char*>(google_der
), sizeof(google_der
)));
550 scoped_refptr
<X509Certificate
> webkit_cert(X509Certificate::CreateFromBytes(
551 reinterpret_cast<const char*>(webkit_der
), sizeof(webkit_der
)));
555 // To begin with, everything should be unknown.
556 EXPECT_EQ(CertPolicy::UNKNOWN
,
557 policy
.Check(google_cert
.get(), CERT_STATUS_DATE_INVALID
));
558 EXPECT_EQ(CertPolicy::UNKNOWN
,
559 policy
.Check(webkit_cert
.get(), CERT_STATUS_COMMON_NAME_INVALID
));
560 EXPECT_FALSE(policy
.HasAllowedCert());
561 EXPECT_FALSE(policy
.HasDeniedCert());
563 // Test adding one certificate with one error.
564 policy
.Allow(google_cert
.get(), CERT_STATUS_DATE_INVALID
);
565 EXPECT_EQ(CertPolicy::ALLOWED
,
566 policy
.Check(google_cert
.get(), CERT_STATUS_DATE_INVALID
));
567 EXPECT_EQ(CertPolicy::UNKNOWN
,
568 policy
.Check(google_cert
.get(), CERT_STATUS_COMMON_NAME_INVALID
));
569 EXPECT_EQ(CertPolicy::UNKNOWN
,
570 policy
.Check(google_cert
.get(),
571 CERT_STATUS_DATE_INVALID
| CERT_STATUS_COMMON_NAME_INVALID
));
572 EXPECT_EQ(CertPolicy::UNKNOWN
,
573 policy
.Check(webkit_cert
.get(), CERT_STATUS_COMMON_NAME_INVALID
));
574 EXPECT_TRUE(policy
.HasAllowedCert());
575 EXPECT_FALSE(policy
.HasDeniedCert());
577 // Test saving the same certificate with a new error.
578 policy
.Allow(google_cert
.get(), CERT_STATUS_AUTHORITY_INVALID
);
579 EXPECT_EQ(CertPolicy::UNKNOWN
,
580 policy
.Check(google_cert
.get(), CERT_STATUS_DATE_INVALID
));
581 EXPECT_EQ(CertPolicy::ALLOWED
,
582 policy
.Check(google_cert
.get(), CERT_STATUS_AUTHORITY_INVALID
));
583 EXPECT_EQ(CertPolicy::UNKNOWN
,
584 policy
.Check(webkit_cert
.get(), CERT_STATUS_COMMON_NAME_INVALID
));
585 EXPECT_TRUE(policy
.HasAllowedCert());
586 EXPECT_FALSE(policy
.HasDeniedCert());
588 // Test adding one certificate with two errors.
589 policy
.Allow(google_cert
.get(),
590 CERT_STATUS_DATE_INVALID
| CERT_STATUS_AUTHORITY_INVALID
);
591 EXPECT_EQ(CertPolicy::ALLOWED
,
592 policy
.Check(google_cert
.get(), CERT_STATUS_DATE_INVALID
));
593 EXPECT_EQ(CertPolicy::ALLOWED
,
594 policy
.Check(google_cert
.get(), CERT_STATUS_AUTHORITY_INVALID
));
595 EXPECT_EQ(CertPolicy::UNKNOWN
,
596 policy
.Check(google_cert
.get(), CERT_STATUS_COMMON_NAME_INVALID
));
597 EXPECT_EQ(CertPolicy::UNKNOWN
,
598 policy
.Check(webkit_cert
.get(), CERT_STATUS_COMMON_NAME_INVALID
));
599 EXPECT_TRUE(policy
.HasAllowedCert());
600 EXPECT_FALSE(policy
.HasDeniedCert());
602 // Test removing a certificate that was previously allowed.
603 policy
.Deny(google_cert
.get(), CERT_STATUS_DATE_INVALID
);
604 EXPECT_EQ(CertPolicy::DENIED
,
605 policy
.Check(google_cert
.get(), CERT_STATUS_DATE_INVALID
));
606 EXPECT_EQ(CertPolicy::UNKNOWN
,
607 policy
.Check(webkit_cert
.get(), CERT_STATUS_COMMON_NAME_INVALID
));
608 EXPECT_FALSE(policy
.HasAllowedCert());
609 EXPECT_TRUE(policy
.HasDeniedCert());
611 // Test removing a certificate that was previously unknown.
612 policy
.Deny(webkit_cert
.get(), CERT_STATUS_COMMON_NAME_INVALID
);
613 EXPECT_EQ(CertPolicy::DENIED
,
614 policy
.Check(google_cert
.get(), CERT_STATUS_DATE_INVALID
));
615 EXPECT_EQ(CertPolicy::DENIED
,
616 policy
.Check(webkit_cert
.get(), CERT_STATUS_COMMON_NAME_INVALID
));
617 EXPECT_FALSE(policy
.HasAllowedCert());
618 EXPECT_TRUE(policy
.HasDeniedCert());
620 // Test saving a certificate that was previously denied.
621 policy
.Allow(webkit_cert
.get(), CERT_STATUS_COMMON_NAME_INVALID
);
622 EXPECT_EQ(CertPolicy::DENIED
,
623 policy
.Check(google_cert
.get(), CERT_STATUS_DATE_INVALID
));
624 EXPECT_EQ(CertPolicy::ALLOWED
,
625 policy
.Check(webkit_cert
.get(), CERT_STATUS_COMMON_NAME_INVALID
));
626 EXPECT_TRUE(policy
.HasAllowedCert());
627 EXPECT_TRUE(policy
.HasDeniedCert());
629 // Test denying an overlapping certificate.
630 policy
.Allow(google_cert
.get(),
631 CERT_STATUS_COMMON_NAME_INVALID
| CERT_STATUS_DATE_INVALID
);
632 policy
.Deny(google_cert
.get(), CERT_STATUS_DATE_INVALID
);
633 EXPECT_EQ(CertPolicy::DENIED
,
634 policy
.Check(google_cert
.get(), CERT_STATUS_DATE_INVALID
));
635 EXPECT_EQ(CertPolicy::UNKNOWN
,
636 policy
.Check(google_cert
.get(), CERT_STATUS_COMMON_NAME_INVALID
));
637 EXPECT_EQ(CertPolicy::DENIED
,
638 policy
.Check(google_cert
.get(),
639 CERT_STATUS_COMMON_NAME_INVALID
| CERT_STATUS_DATE_INVALID
));
641 // Test denying an overlapping certificate (other direction).
642 policy
.Allow(webkit_cert
.get(), CERT_STATUS_COMMON_NAME_INVALID
);
643 policy
.Deny(webkit_cert
.get(), CERT_STATUS_COMMON_NAME_INVALID
);
644 policy
.Deny(webkit_cert
.get(), CERT_STATUS_DATE_INVALID
);
645 EXPECT_EQ(CertPolicy::DENIED
,
646 policy
.Check(webkit_cert
.get(), CERT_STATUS_COMMON_NAME_INVALID
));
647 EXPECT_EQ(CertPolicy::DENIED
,
648 policy
.Check(webkit_cert
.get(), CERT_STATUS_DATE_INVALID
));
651 TEST(X509CertificateTest
, IntermediateCertificates
) {
652 scoped_refptr
<X509Certificate
> webkit_cert(
653 X509Certificate::CreateFromBytes(
654 reinterpret_cast<const char*>(webkit_der
), sizeof(webkit_der
)));
656 scoped_refptr
<X509Certificate
> thawte_cert(
657 X509Certificate::CreateFromBytes(
658 reinterpret_cast<const char*>(thawte_der
), sizeof(thawte_der
)));
660 X509Certificate::OSCertHandle google_handle
;
661 // Create object with no intermediates:
662 google_handle
= X509Certificate::CreateOSCertHandleFromBytes(
663 reinterpret_cast<const char*>(google_der
), sizeof(google_der
));
664 X509Certificate::OSCertHandles intermediates1
;
665 scoped_refptr
<X509Certificate
> cert1
;
666 cert1
= X509Certificate::CreateFromHandle(google_handle
, intermediates1
);
667 EXPECT_EQ(0u, cert1
->GetIntermediateCertificates().size());
669 // Create object with 2 intermediates:
670 X509Certificate::OSCertHandles intermediates2
;
671 intermediates2
.push_back(webkit_cert
->os_cert_handle());
672 intermediates2
.push_back(thawte_cert
->os_cert_handle());
673 scoped_refptr
<X509Certificate
> cert2
;
674 cert2
= X509Certificate::CreateFromHandle(google_handle
, intermediates2
);
676 // Verify it has all the intermediates:
677 const X509Certificate::OSCertHandles
& cert2_intermediates
=
678 cert2
->GetIntermediateCertificates();
679 ASSERT_EQ(2u, cert2_intermediates
.size());
680 EXPECT_TRUE(X509Certificate::IsSameOSCert(cert2_intermediates
[0],
681 webkit_cert
->os_cert_handle()));
682 EXPECT_TRUE(X509Certificate::IsSameOSCert(cert2_intermediates
[1],
683 thawte_cert
->os_cert_handle()));
686 X509Certificate::FreeOSCertHandle(google_handle
);
689 TEST(X509CertificateTest
, IsIssuedByEncoded
) {
690 base::FilePath certs_dir
= GetTestCertsDirectory();
692 // Test a client certificate from MIT.
693 scoped_refptr
<X509Certificate
> mit_davidben_cert(
694 ImportCertFromFile(certs_dir
, "mit.davidben.der"));
695 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), mit_davidben_cert
);
697 std::string
mit_issuer(reinterpret_cast<const char*>(MITDN
),
700 // Test a certificate from Google, issued by Thawte
701 scoped_refptr
<X509Certificate
> google_cert(
702 ImportCertFromFile(certs_dir
, "google.single.der"));
703 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), google_cert
);
705 std::string
thawte_issuer(reinterpret_cast<const char*>(ThawteDN
),
708 // Check that the David Ben certificate is issued by MIT, but not
710 std::vector
<std::string
> issuers
;
712 issuers
.push_back(mit_issuer
);
713 EXPECT_TRUE(mit_davidben_cert
->IsIssuedByEncoded(issuers
));
714 EXPECT_FALSE(google_cert
->IsIssuedByEncoded(issuers
));
716 // Check that the Google certificate is issued by Thawte and not
719 issuers
.push_back(thawte_issuer
);
720 EXPECT_FALSE(mit_davidben_cert
->IsIssuedByEncoded(issuers
));
721 EXPECT_TRUE(google_cert
->IsIssuedByEncoded(issuers
));
723 // Check that they both pass when given a list of the two issuers.
725 issuers
.push_back(mit_issuer
);
726 issuers
.push_back(thawte_issuer
);
727 EXPECT_TRUE(mit_davidben_cert
->IsIssuedByEncoded(issuers
));
728 EXPECT_TRUE(google_cert
->IsIssuedByEncoded(issuers
));
731 TEST(X509CertificateTest
, IsIssuedByEncodedWithIntermediates
) {
732 static const unsigned char kPolicyRootDN
[] = {
733 0x30, 0x1e, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
734 0x13, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x54, 0x65, 0x73, 0x74,
735 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41
737 static const unsigned char kPolicyIntermediateDN
[] = {
738 0x30, 0x26, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
739 0x1b, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x54, 0x65, 0x73, 0x74,
740 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74,
741 0x65, 0x20, 0x43, 0x41
744 base::FilePath certs_dir
= GetTestCertsDirectory();
746 CertificateList policy_chain
= CreateCertificateListFromFile(
747 certs_dir
, "explicit-policy-chain.pem", X509Certificate::FORMAT_AUTO
);
748 ASSERT_EQ(3u, policy_chain
.size());
750 // The intermediate CA certificate's policyConstraints extension has a
751 // requireExplicitPolicy field with SkipCerts=0.
752 std::string
policy_intermediate_dn(
753 reinterpret_cast<const char*>(kPolicyIntermediateDN
),
754 sizeof(kPolicyIntermediateDN
));
755 std::string
policy_root_dn(reinterpret_cast<const char*>(kPolicyRootDN
),
756 sizeof(kPolicyRootDN
));
758 X509Certificate::OSCertHandles intermediates
;
759 intermediates
.push_back(policy_chain
[1]->os_cert_handle());
760 scoped_refptr
<X509Certificate
> cert_chain
=
761 X509Certificate::CreateFromHandle(policy_chain
[0]->os_cert_handle(),
764 std::vector
<std::string
> issuers
;
766 // Check that the chain is issued by the intermediate.
768 issuers
.push_back(policy_intermediate_dn
);
769 EXPECT_TRUE(cert_chain
->IsIssuedByEncoded(issuers
));
771 // Check that the chain is also issued by the root.
773 issuers
.push_back(policy_root_dn
);
774 EXPECT_TRUE(cert_chain
->IsIssuedByEncoded(issuers
));
776 // Check that the chain is issued by either the intermediate or the root.
778 issuers
.push_back(policy_intermediate_dn
);
779 issuers
.push_back(policy_root_dn
);
780 EXPECT_TRUE(cert_chain
->IsIssuedByEncoded(issuers
));
782 // Check that an empty issuers list returns false.
784 EXPECT_FALSE(cert_chain
->IsIssuedByEncoded(issuers
));
786 // Check that the chain is not issued by Verisign
787 std::string
mit_issuer(reinterpret_cast<const char*>(VerisignDN
),
790 issuers
.push_back(mit_issuer
);
791 EXPECT_FALSE(cert_chain
->IsIssuedByEncoded(issuers
));
795 TEST(X509CertificateTest
, GetDefaultNickname
) {
796 base::FilePath certs_dir
= GetTestCertsDirectory();
798 scoped_refptr
<X509Certificate
> test_cert(
799 ImportCertFromFile(certs_dir
, "no_subject_common_name_cert.pem"));
800 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), test_cert
);
802 std::string nickname
= test_cert
->GetDefaultNickname(USER_CERT
);
803 EXPECT_EQ("wtc@google.com's COMODO Client Authentication and "
804 "Secure Email CA ID", nickname
);
808 const struct CertificateFormatTestData
{
809 const char* file_name
;
810 X509Certificate::Format format
;
811 uint8
* chain_fingerprints
[3];
812 } kFormatTestData
[] = {
813 // DER Parsing - single certificate, DER encoded
814 { "google.single.der", X509Certificate::FORMAT_SINGLE_CERTIFICATE
,
815 { google_parse_fingerprint
,
817 // DER parsing - single certificate, PEM encoded
818 { "google.single.pem", X509Certificate::FORMAT_SINGLE_CERTIFICATE
,
819 { google_parse_fingerprint
,
821 // PEM parsing - single certificate, PEM encoded with a PEB of
823 { "google.single.pem", X509Certificate::FORMAT_PEM_CERT_SEQUENCE
,
824 { google_parse_fingerprint
,
826 // PEM parsing - sequence of certificates, PEM encoded with a PEB of
828 { "google.chain.pem", X509Certificate::FORMAT_PEM_CERT_SEQUENCE
,
829 { google_parse_fingerprint
,
830 thawte_parse_fingerprint
,
832 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, DER
834 { "google.binary.p7b", X509Certificate::FORMAT_PKCS7
,
835 { google_parse_fingerprint
,
836 thawte_parse_fingerprint
,
838 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, PEM
839 // encoded with a PEM PEB of "CERTIFICATE"
840 { "google.pem_cert.p7b", X509Certificate::FORMAT_PKCS7
,
841 { google_parse_fingerprint
,
842 thawte_parse_fingerprint
,
844 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, PEM
845 // encoded with a PEM PEB of "PKCS7"
846 { "google.pem_pkcs7.p7b", X509Certificate::FORMAT_PKCS7
,
847 { google_parse_fingerprint
,
848 thawte_parse_fingerprint
,
850 // All of the above, this time using auto-detection
851 { "google.single.der", X509Certificate::FORMAT_AUTO
,
852 { google_parse_fingerprint
,
854 { "google.single.pem", X509Certificate::FORMAT_AUTO
,
855 { google_parse_fingerprint
,
857 { "google.chain.pem", X509Certificate::FORMAT_AUTO
,
858 { google_parse_fingerprint
,
859 thawte_parse_fingerprint
,
861 { "google.binary.p7b", X509Certificate::FORMAT_AUTO
,
862 { google_parse_fingerprint
,
863 thawte_parse_fingerprint
,
865 { "google.pem_cert.p7b", X509Certificate::FORMAT_AUTO
,
866 { google_parse_fingerprint
,
867 thawte_parse_fingerprint
,
869 { "google.pem_pkcs7.p7b", X509Certificate::FORMAT_AUTO
,
870 { google_parse_fingerprint
,
871 thawte_parse_fingerprint
,
875 class X509CertificateParseTest
876 : public testing::TestWithParam
<CertificateFormatTestData
> {
878 virtual ~X509CertificateParseTest() {}
879 virtual void SetUp() {
880 test_data_
= GetParam();
882 virtual void TearDown() {}
885 CertificateFormatTestData test_data_
;
888 TEST_P(X509CertificateParseTest
, CanParseFormat
) {
889 base::FilePath certs_dir
= GetTestCertsDirectory();
890 CertificateList certs
= CreateCertificateListFromFile(
891 certs_dir
, test_data_
.file_name
, test_data_
.format
);
892 ASSERT_FALSE(certs
.empty());
893 ASSERT_LE(certs
.size(), arraysize(test_data_
.chain_fingerprints
));
894 CheckGoogleCert(certs
.front(), google_parse_fingerprint
,
895 kGoogleParseValidFrom
, kGoogleParseValidTo
);
898 for (i
= 0; i
< arraysize(test_data_
.chain_fingerprints
); ++i
) {
899 if (test_data_
.chain_fingerprints
[i
] == NULL
) {
900 // No more test certificates expected - make sure no more were
901 // returned before marking this test a success.
902 EXPECT_EQ(i
, certs
.size());
906 // A cert is expected - make sure that one was parsed.
907 ASSERT_LT(i
, certs
.size());
909 // Compare the parsed certificate with the expected certificate, by
910 // comparing fingerprints.
911 const X509Certificate
* cert
= certs
[i
].get();
912 const SHA1HashValue
& actual_fingerprint
= cert
->fingerprint();
913 uint8
* expected_fingerprint
= test_data_
.chain_fingerprints
[i
];
915 for (size_t j
= 0; j
< 20; ++j
)
916 EXPECT_EQ(expected_fingerprint
[j
], actual_fingerprint
.data
[j
]);
920 INSTANTIATE_TEST_CASE_P(, X509CertificateParseTest
,
921 testing::ValuesIn(kFormatTestData
));
923 struct CertificateNameVerifyTestData
{
924 // true iff we expect hostname to match an entry in cert_names.
926 // The hostname to match.
927 const char* hostname
;
928 // Common name, may be used if |dns_names| or |ip_addrs| are empty.
929 const char* common_name
;
930 // Comma separated list of certificate names to match against. Any occurrence
931 // of '#' will be replaced with a null character before processing.
932 const char* dns_names
;
933 // Comma separated list of certificate IP Addresses to match against. Each
934 // address is x prefixed 16 byte hex code for v6 or dotted-decimals for v4.
935 const char* ip_addrs
;
938 // GTest 'magic' pretty-printer, so that if/when a test fails, it knows how
939 // to output the parameter that was passed. Without this, it will simply
940 // attempt to print out the first twenty bytes of the object, which depending
941 // on platform and alignment, may result in an invalid read.
942 void PrintTo(const CertificateNameVerifyTestData
& data
, std::ostream
* os
) {
943 ASSERT_TRUE(data
.hostname
&& data
.common_name
);
944 // Using StringPiece to allow for optional fields being NULL.
945 *os
<< " expected: " << data
.expected
946 << "; hostname: " << data
.hostname
947 << "; common_name: " << data
.common_name
948 << "; dns_names: " << base::StringPiece(data
.dns_names
)
949 << "; ip_addrs: " << base::StringPiece(data
.ip_addrs
);
952 const CertificateNameVerifyTestData kNameVerifyTestData
[] = {
953 { true, "foo.com", "foo.com" },
956 { true, "bar.foo.com", "*.foo.com" },
957 { true, "www.test.fr", "common.name",
958 "*.test.com,*.test.co.uk,*.test.de,*.test.fr" },
959 { true, "wwW.tESt.fr", "common.name",
960 ",*.*,*.test.de,*.test.FR,www" },
961 { false, "f.uk", ".uk" },
962 { false, "w.bar.foo.com", "?.bar.foo.com" },
963 { false, "www.foo.com", "(www|ftp).foo.com" },
964 { false, "www.foo.com", "www.foo.com#" }, // # = null char.
965 { false, "www.foo.com", "", "www.foo.com#*.foo.com,#,#" },
966 { false, "www.house.example", "ww.house.example" },
967 { false, "test.org", "", "www.test.org,*.test.org,*.org" },
968 { false, "w.bar.foo.com", "w*.bar.foo.com" },
969 { false, "www.bar.foo.com", "ww*ww.bar.foo.com" },
970 { false, "wwww.bar.foo.com", "ww*ww.bar.foo.com" },
971 { true, "wwww.bar.foo.com", "w*w.bar.foo.com" },
972 { false, "wwww.bar.foo.com", "w*w.bar.foo.c0m" },
973 { true, "WALLY.bar.foo.com", "wa*.bar.foo.com" },
974 { true, "wally.bar.foo.com", "*Ly.bar.foo.com" },
975 { true, "ww%57.foo.com", "", "www.foo.com" },
976 { true, "www&.foo.com", "www%26.foo.com" },
977 // Common name must not be used if subject alternative name was provided.
978 { false, "www.test.co.jp", "www.test.co.jp",
979 "*.test.de,*.jp,www.test.co.uk,www.*.co.jp" },
980 { false, "www.bar.foo.com", "www.bar.foo.com",
981 "*.foo.com,*.*.foo.com,*.*.bar.foo.com,*..bar.foo.com," },
982 { false, "www.bath.org", "www.bath.org", "", "20.30.40.50" },
983 { false, "66.77.88.99", "www.bath.org", "www.bath.org" },
985 { true, "xn--poema-9qae5a.com.br", "xn--poema-9qae5a.com.br" },
986 { true, "www.xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br" },
987 { false, "xn--poema-9qae5a.com.br", "", "*.xn--poema-9qae5a.com.br,"
988 "xn--poema-*.com.br,"
989 "xn--*-9qae5a.com.br,"
990 "*--poema-9qae5a.com.br" },
991 // The following are adapted from the examples quoted from
992 // http://tools.ietf.org/html/rfc6125#section-6.4.3
993 // (e.g., *.example.com would match foo.example.com but
994 // not bar.foo.example.com or example.com).
995 { true, "foo.example.com", "*.example.com" },
996 { false, "bar.foo.example.com", "*.example.com" },
997 { false, "example.com", "*.example.com" },
998 // (e.g., baz*.example.net and *baz.example.net and b*z.example.net would
999 // be taken to match baz1.example.net and foobaz.example.net and
1000 // buzz.example.net, respectively
1001 { true, "baz1.example.net", "baz*.example.net" },
1002 { true, "foobaz.example.net", "*baz.example.net" },
1003 { true, "buzz.example.net", "b*z.example.net" },
1004 // Wildcards should not be valid for public registry controlled domains,
1005 // and unknown/unrecognized domains, at least three domain components must
1007 { true, "www.test.example", "*.test.example" },
1008 { true, "test.example.co.uk", "*.example.co.uk" },
1009 { false, "test.example", "*.exmaple" },
1010 { false, "example.co.uk", "*.co.uk" },
1011 { false, "foo.com", "*.com" },
1012 { false, "foo.us", "*.us" },
1013 { false, "foo", "*" },
1014 // IDN variants of wildcards and registry controlled domains.
1015 { true, "www.xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br" },
1016 { true, "test.example.xn--mgbaam7a8h", "*.example.xn--mgbaam7a8h" },
1017 { false, "xn--poema-9qae5a.com.br", "*.com.br" },
1018 { false, "example.xn--mgbaam7a8h", "*.xn--mgbaam7a8h" },
1019 // Wildcards should be permissible for 'private' registry controlled
1021 { true, "www.appspot.com", "*.appspot.com" },
1022 { true, "foo.s3.amazonaws.com", "*.s3.amazonaws.com" },
1023 // Multiple wildcards are not valid.
1024 { false, "foo.example.com", "*.*.com" },
1025 { false, "foo.bar.example.com", "*.bar.*.com" },
1026 // Absolute vs relative DNS name tests. Although not explicitly specified
1027 // in RFC 6125, absolute reference names (those ending in a .) should
1028 // match either absolute or relative presented names.
1029 { true, "foo.com", "foo.com." },
1030 { true, "foo.com.", "foo.com" },
1031 { true, "foo.com.", "foo.com." },
1032 { true, "f", "f." },
1033 { true, "f.", "f" },
1034 { true, "f.", "f." },
1035 { true, "www-3.bar.foo.com", "*.bar.foo.com." },
1036 { true, "www-3.bar.foo.com.", "*.bar.foo.com" },
1037 { true, "www-3.bar.foo.com.", "*.bar.foo.com." },
1038 { false, ".", "." },
1039 { false, "example.com", "*.com." },
1040 { false, "example.com.", "*.com" },
1041 { false, "example.com.", "*.com." },
1042 { false, "foo.", "*." },
1043 { false, "foo", "*." },
1044 { false, "foo.co.uk", "*.co.uk." },
1045 { false, "foo.co.uk.", "*.co.uk." },
1046 // IP addresses in common name; IPv4 only.
1047 { true, "127.0.0.1", "127.0.0.1" },
1048 { true, "192.168.1.1", "192.168.1.1" },
1049 { true, "676768", "0.10.83.160" },
1050 { true, "1.2.3", "1.2.0.3" },
1051 { false, "192.169.1.1", "192.168.1.1" },
1052 { false, "12.19.1.1", "12.19.1.1/255.255.255.0" },
1053 { false, "FEDC:ba98:7654:3210:FEDC:BA98:7654:3210",
1054 "FEDC:BA98:7654:3210:FEDC:ba98:7654:3210" },
1055 { false, "1111:2222:3333:4444:5555:6666:7777:8888",
1056 "1111:2222:3333:4444:5555:6666:7777:8888" },
1057 { false, "::192.9.5.5", "[::192.9.5.5]" },
1058 // No wildcard matching in valid IP addresses
1059 { false, "::192.9.5.5", "*.9.5.5" },
1060 { false, "2010:836B:4179::836B:4179", "*:836B:4179::836B:4179" },
1061 { false, "192.168.1.11", "*.168.1.11" },
1062 { false, "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210", "*.]" },
1063 // IP addresses in subject alternative name (common name ignored)
1064 { true, "10.1.2.3", "", "", "10.1.2.3" },
1065 { true, "14.15", "", "", "14.0.0.15" },
1066 { false, "10.1.2.7", "10.1.2.7", "", "10.1.2.6,10.1.2.8" },
1067 { false, "10.1.2.8", "10.20.2.8", "foo" },
1068 { true, "::4.5.6.7", "", "", "x00000000000000000000000004050607" },
1069 { false, "::6.7.8.9", "::6.7.8.9", "::6.7.8.9",
1070 "x00000000000000000000000006070808,x0000000000000000000000000607080a,"
1071 "xff000000000000000000000006070809,6.7.8.9" },
1072 { true, "FE80::200:f8ff:fe21:67cf", "no.common.name", "",
1073 "x00000000000000000000000006070808,xfe800000000000000200f8fffe2167cf,"
1074 "xff0000000000000000000000060708ff,10.0.0.1" },
1075 // Numeric only hostnames (none of these are considered valid IP addresses).
1076 { false, "12345.6", "12345.6" },
1077 { false, "121.2.3.512", "", "1*1.2.3.512,*1.2.3.512,1*.2.3.512,*.2.3.512",
1079 { false, "1.2.3.4.5.6", "*.2.3.4.5.6" },
1080 { true, "1.2.3.4.5", "", "1.2.3.4.5" },
1081 // Invalid host names.
1082 { false, "junk)(£)$*!@~#", "junk)(£)$*!@~#" },
1083 { false, "www.*.com", "www.*.com" },
1084 { false, "w$w.f.com", "w$w.f.com" },
1085 { false, "nocolonallowed:example", "", "nocolonallowed:example" },
1086 { false, "www-1.[::FFFF:129.144.52.38]", "*.[::FFFF:129.144.52.38]" },
1087 { false, "[::4.5.6.9]", "", "", "x00000000000000000000000004050609" },
1090 class X509CertificateNameVerifyTest
1091 : public testing::TestWithParam
<CertificateNameVerifyTestData
> {
1094 TEST_P(X509CertificateNameVerifyTest
, VerifyHostname
) {
1095 CertificateNameVerifyTestData test_data
= GetParam();
1097 std::string
common_name(test_data
.common_name
);
1098 ASSERT_EQ(std::string::npos
, common_name
.find(','));
1099 std::replace(common_name
.begin(), common_name
.end(), '#', '\0');
1101 std::vector
<std::string
> dns_names
, ip_addressses
;
1102 if (test_data
.dns_names
) {
1103 // Build up the certificate DNS names list.
1104 std::string
dns_name_line(test_data
.dns_names
);
1105 std::replace(dns_name_line
.begin(), dns_name_line
.end(), '#', '\0');
1106 base::SplitString(dns_name_line
, ',', &dns_names
);
1109 if (test_data
.ip_addrs
) {
1110 // Build up the certificate IP address list.
1111 std::string
ip_addrs_line(test_data
.ip_addrs
);
1112 std::vector
<std::string
> ip_addressses_ascii
;
1113 base::SplitString(ip_addrs_line
, ',', &ip_addressses_ascii
);
1114 for (size_t i
= 0; i
< ip_addressses_ascii
.size(); ++i
) {
1115 std::string
& addr_ascii
= ip_addressses_ascii
[i
];
1116 ASSERT_NE(0U, addr_ascii
.length());
1117 if (addr_ascii
[0] == 'x') { // Hex encoded address
1118 addr_ascii
.erase(0, 1);
1119 std::vector
<uint8
> bytes
;
1120 EXPECT_TRUE(base::HexStringToBytes(addr_ascii
, &bytes
))
1121 << "Could not parse hex address " << addr_ascii
<< " i = " << i
;
1122 ip_addressses
.push_back(std::string(reinterpret_cast<char*>(&bytes
[0]),
1124 ASSERT_EQ(16U, ip_addressses
.back().size()) << i
;
1125 } else { // Decimal groups
1126 std::vector
<std::string
> decimals_ascii
;
1127 base::SplitString(addr_ascii
, '.', &decimals_ascii
);
1128 EXPECT_EQ(4U, decimals_ascii
.size()) << i
;
1129 std::string addr_bytes
;
1130 for (size_t j
= 0; j
< decimals_ascii
.size(); ++j
) {
1132 EXPECT_TRUE(base::StringToInt(decimals_ascii
[j
], &decimal_value
));
1133 EXPECT_GE(decimal_value
, 0);
1134 EXPECT_LE(decimal_value
, 255);
1135 addr_bytes
.push_back(static_cast<char>(decimal_value
));
1137 ip_addressses
.push_back(addr_bytes
);
1138 ASSERT_EQ(4U, ip_addressses
.back().size()) << i
;
1143 bool unused
= false;
1144 EXPECT_EQ(test_data
.expected
, X509Certificate::VerifyHostname(
1145 test_data
.hostname
, common_name
, dns_names
, ip_addressses
, &unused
));
1148 INSTANTIATE_TEST_CASE_P(, X509CertificateNameVerifyTest
,
1149 testing::ValuesIn(kNameVerifyTestData
));
1151 const struct PublicKeyInfoTestData
{
1152 const char* cert_file
;
1153 size_t expected_bits
;
1154 X509Certificate::PublicKeyType expected_type
;
1155 } kPublicKeyInfoTestData
[] = {
1156 { "768-rsa-ee-by-768-rsa-intermediate.pem", 768,
1157 X509Certificate::kPublicKeyTypeRSA
},
1158 { "1024-rsa-ee-by-768-rsa-intermediate.pem", 1024,
1159 X509Certificate::kPublicKeyTypeRSA
},
1160 { "prime256v1-ecdsa-ee-by-1024-rsa-intermediate.pem", 256,
1161 X509Certificate::kPublicKeyTypeECDSA
},
1164 class X509CertificatePublicKeyInfoTest
1165 : public testing::TestWithParam
<PublicKeyInfoTestData
> {
1168 TEST_P(X509CertificatePublicKeyInfoTest
, GetPublicKeyInfo
) {
1169 PublicKeyInfoTestData data
= GetParam();
1172 if (base::win::GetVersion() < base::win::VERSION_VISTA
&&
1173 data
.expected_type
== X509Certificate::kPublicKeyTypeECDSA
) {
1174 // ECC is only supported on Vista+. Skip the test.
1179 scoped_refptr
<X509Certificate
> cert(
1180 ImportCertFromFile(GetTestCertsDirectory(), data
.cert_file
));
1181 ASSERT_TRUE(cert
.get());
1183 size_t actual_bits
= 0;
1184 X509Certificate::PublicKeyType actual_type
=
1185 X509Certificate::kPublicKeyTypeUnknown
;
1187 X509Certificate::GetPublicKeyInfo(cert
->os_cert_handle(), &actual_bits
,
1190 EXPECT_EQ(data
.expected_bits
, actual_bits
);
1191 EXPECT_EQ(data
.expected_type
, actual_type
);
1194 INSTANTIATE_TEST_CASE_P(, X509CertificatePublicKeyInfoTest
,
1195 testing::ValuesIn(kPublicKeyInfoTestData
));