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
.get());
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
.get());
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
.get());
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
.get());
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
.get());
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
.get());
333 scoped_refptr
<X509Certificate
> intermediate_cert1
=
334 ImportCertFromFile(certs_dir
, "verisign_intermediate_ca_2011.pem");
335 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), intermediate_cert1
.get());
337 scoped_refptr
<X509Certificate
> intermediate_cert2
=
338 ImportCertFromFile(certs_dir
, "verisign_intermediate_ca_2016.pem");
339 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), intermediate_cert2
.get());
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);
379 // Test the SHA-256 hash calculation functions explicitly since they are not
380 // used by X509Certificate internally.
381 static const uint8 cert_chain1_ca_fingerprint_256
[32] = {
382 0x51, 0x15, 0x30, 0x49, 0x97, 0x54, 0xf8, 0xb4, 0x17, 0x41,
383 0x6b, 0x58, 0x78, 0xb0, 0x89, 0xd2, 0xc3, 0xae, 0x66, 0xc1,
384 0x16, 0x80, 0xa0, 0x78, 0xe7, 0x53, 0x45, 0xa2, 0xfb, 0x80,
387 static const uint8 cert_chain2_ca_fingerprint_256
[32] = {
388 0x00, 0xbd, 0x2b, 0x0e, 0xdd, 0x83, 0x40, 0xb1, 0x74, 0x6c,
389 0xc3, 0x95, 0xc0, 0xe3, 0x55, 0xb2, 0x16, 0x58, 0x53, 0xfd,
390 0xb9, 0x3c, 0x52, 0xda, 0xdd, 0xa8, 0x22, 0x8b, 0x07, 0x00,
393 // The SHA-256 hash of nothing.
394 static const uint8 cert_chain3_ca_fingerprint_256
[32] = {
395 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb,
396 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4,
397 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52,
400 SHA256HashValue ca_fingerprint_256_1
=
401 X509Certificate::CalculateCAFingerprint256(
402 cert_chain1
->GetIntermediateCertificates());
403 SHA256HashValue ca_fingerprint_256_2
=
404 X509Certificate::CalculateCAFingerprint256(
405 cert_chain2
->GetIntermediateCertificates());
406 SHA256HashValue ca_fingerprint_256_3
=
407 X509Certificate::CalculateCAFingerprint256(
408 cert_chain3
->GetIntermediateCertificates());
409 EXPECT_TRUE(memcmp(ca_fingerprint_256_1
.data
,
410 cert_chain1_ca_fingerprint_256
, 32) == 0);
411 EXPECT_TRUE(memcmp(ca_fingerprint_256_2
.data
,
412 cert_chain2_ca_fingerprint_256
, 32) == 0);
413 EXPECT_TRUE(memcmp(ca_fingerprint_256_3
.data
,
414 cert_chain3_ca_fingerprint_256
, 32) == 0);
416 static const uint8 cert_chain1_chain_fingerprint_256
[32] = {
417 0xac, 0xff, 0xcc, 0x63, 0x0d, 0xd0, 0xa7, 0x19, 0x78, 0xb5,
418 0x8a, 0x47, 0x8b, 0x67, 0x97, 0xcb, 0x8d, 0xe1, 0x6a, 0x8a,
419 0x57, 0x70, 0xda, 0x9a, 0x53, 0x72, 0xe2, 0xa0, 0x08, 0xab,
422 static const uint8 cert_chain2_chain_fingerprint_256
[32] = {
423 0x67, 0x3a, 0x11, 0x20, 0xd6, 0x94, 0x14, 0xe4, 0x16, 0x9f,
424 0x58, 0xe2, 0x8b, 0xf7, 0x27, 0xed, 0xbb, 0xe8, 0xa7, 0xff,
425 0x1c, 0x8c, 0x0f, 0x21, 0x38, 0x16, 0x7c, 0xad, 0x1f, 0x22,
428 static const uint8 cert_chain3_chain_fingerprint_256
[32] = {
429 0x16, 0x7a, 0xbd, 0xb4, 0x57, 0x04, 0x65, 0x3c, 0x3b, 0xef,
430 0x6e, 0x6a, 0xa6, 0x02, 0x73, 0x30, 0x3e, 0x34, 0x1b, 0x43,
431 0xc2, 0x7c, 0x98, 0x52, 0x9f, 0x34, 0x7f, 0x55, 0x97, 0xe9,
434 SHA256HashValue chain_fingerprint_256_1
=
435 X509Certificate::CalculateChainFingerprint256(
436 cert_chain1
->os_cert_handle(),
437 cert_chain1
->GetIntermediateCertificates());
438 SHA256HashValue chain_fingerprint_256_2
=
439 X509Certificate::CalculateChainFingerprint256(
440 cert_chain2
->os_cert_handle(),
441 cert_chain2
->GetIntermediateCertificates());
442 SHA256HashValue chain_fingerprint_256_3
=
443 X509Certificate::CalculateChainFingerprint256(
444 cert_chain3
->os_cert_handle(),
445 cert_chain3
->GetIntermediateCertificates());
446 EXPECT_TRUE(memcmp(chain_fingerprint_256_1
.data
,
447 cert_chain1_chain_fingerprint_256
, 32) == 0);
448 EXPECT_TRUE(memcmp(chain_fingerprint_256_2
.data
,
449 cert_chain2_chain_fingerprint_256
, 32) == 0);
450 EXPECT_TRUE(memcmp(chain_fingerprint_256_3
.data
,
451 cert_chain3_chain_fingerprint_256
, 32) == 0);
454 TEST(X509CertificateTest
, ParseSubjectAltNames
) {
455 base::FilePath certs_dir
= GetTestCertsDirectory();
457 scoped_refptr
<X509Certificate
> san_cert
=
458 ImportCertFromFile(certs_dir
, "subjectAltName_sanity_check.pem");
459 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), san_cert
.get());
461 std::vector
<std::string
> dns_names
;
462 std::vector
<std::string
> ip_addresses
;
463 san_cert
->GetSubjectAltName(&dns_names
, &ip_addresses
);
465 // Ensure that DNS names are correctly parsed.
466 ASSERT_EQ(1U, dns_names
.size());
467 EXPECT_EQ("test.example", dns_names
[0]);
469 // Ensure that both IPv4 and IPv6 addresses are correctly parsed.
470 ASSERT_EQ(2U, ip_addresses
.size());
472 static const uint8 kIPv4Address
[] = {
473 0x7F, 0x00, 0x00, 0x02
475 ASSERT_EQ(arraysize(kIPv4Address
), ip_addresses
[0].size());
476 EXPECT_EQ(0, memcmp(ip_addresses
[0].data(), kIPv4Address
,
477 arraysize(kIPv4Address
)));
479 static const uint8 kIPv6Address
[] = {
480 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
481 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
483 ASSERT_EQ(arraysize(kIPv6Address
), ip_addresses
[1].size());
484 EXPECT_EQ(0, memcmp(ip_addresses
[1].data(), kIPv6Address
,
485 arraysize(kIPv6Address
)));
487 // Ensure the subjectAltName dirName has not influenced the handling of
488 // the subject commonName.
489 EXPECT_EQ("127.0.0.1", san_cert
->subject().common_name
);
492 TEST(X509CertificateTest
, ExtractSPKIFromDERCert
) {
493 base::FilePath certs_dir
= GetTestCertsDirectory();
494 scoped_refptr
<X509Certificate
> cert
=
495 ImportCertFromFile(certs_dir
, "nist.der");
496 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), cert
.get());
498 std::string derBytes
;
499 EXPECT_TRUE(X509Certificate::GetDEREncoded(cert
->os_cert_handle(),
502 base::StringPiece spkiBytes
;
503 EXPECT_TRUE(asn1::ExtractSPKIFromDERCert(derBytes
, &spkiBytes
));
505 uint8 hash
[base::kSHA1Length
];
506 base::SHA1HashBytes(reinterpret_cast<const uint8
*>(spkiBytes
.data()),
507 spkiBytes
.size(), hash
);
509 EXPECT_EQ(0, memcmp(hash
, kNistSPKIHash
, sizeof(hash
)));
512 TEST(X509CertificateTest
, ExtractCRLURLsFromDERCert
) {
513 base::FilePath certs_dir
= GetTestCertsDirectory();
514 scoped_refptr
<X509Certificate
> cert
=
515 ImportCertFromFile(certs_dir
, "nist.der");
516 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), cert
.get());
518 std::string derBytes
;
519 EXPECT_TRUE(X509Certificate::GetDEREncoded(cert
->os_cert_handle(),
522 std::vector
<base::StringPiece
> crl_urls
;
523 EXPECT_TRUE(asn1::ExtractCRLURLsFromDERCert(derBytes
, &crl_urls
));
525 EXPECT_EQ(1u, crl_urls
.size());
526 if (crl_urls
.size() > 0) {
527 EXPECT_EQ("http://SVRSecure-G3-crl.verisign.com/SVRSecureG3.crl",
528 crl_urls
[0].as_string());
532 // Tests X509CertificateCache via X509Certificate::CreateFromHandle. We
533 // call X509Certificate::CreateFromHandle several times and observe whether
534 // it returns a cached or new OSCertHandle.
535 TEST(X509CertificateTest
, Cache
) {
536 X509Certificate::OSCertHandle google_cert_handle
;
537 X509Certificate::OSCertHandle thawte_cert_handle
;
539 // Add a single certificate to the certificate cache.
540 google_cert_handle
= X509Certificate::CreateOSCertHandleFromBytes(
541 reinterpret_cast<const char*>(google_der
), sizeof(google_der
));
542 scoped_refptr
<X509Certificate
> cert1(X509Certificate::CreateFromHandle(
543 google_cert_handle
, X509Certificate::OSCertHandles()));
544 X509Certificate::FreeOSCertHandle(google_cert_handle
);
546 // Add the same certificate, but as a new handle.
547 google_cert_handle
= X509Certificate::CreateOSCertHandleFromBytes(
548 reinterpret_cast<const char*>(google_der
), sizeof(google_der
));
549 scoped_refptr
<X509Certificate
> cert2(X509Certificate::CreateFromHandle(
550 google_cert_handle
, X509Certificate::OSCertHandles()));
551 X509Certificate::FreeOSCertHandle(google_cert_handle
);
553 // A new X509Certificate should be returned.
554 EXPECT_NE(cert1
.get(), cert2
.get());
555 // But both instances should share the underlying OS certificate handle.
556 EXPECT_EQ(cert1
->os_cert_handle(), cert2
->os_cert_handle());
557 EXPECT_EQ(0u, cert1
->GetIntermediateCertificates().size());
558 EXPECT_EQ(0u, cert2
->GetIntermediateCertificates().size());
560 // Add the same certificate, but this time with an intermediate. This
561 // should result in the intermediate being cached. Note that this is not
562 // a legitimate chain, but is suitable for testing.
563 google_cert_handle
= X509Certificate::CreateOSCertHandleFromBytes(
564 reinterpret_cast<const char*>(google_der
), sizeof(google_der
));
565 thawte_cert_handle
= X509Certificate::CreateOSCertHandleFromBytes(
566 reinterpret_cast<const char*>(thawte_der
), sizeof(thawte_der
));
567 X509Certificate::OSCertHandles intermediates
;
568 intermediates
.push_back(thawte_cert_handle
);
569 scoped_refptr
<X509Certificate
> cert3(X509Certificate::CreateFromHandle(
570 google_cert_handle
, intermediates
));
571 X509Certificate::FreeOSCertHandle(google_cert_handle
);
572 X509Certificate::FreeOSCertHandle(thawte_cert_handle
);
574 // Test that the new certificate, even with intermediates, results in the
575 // same underlying handle being used.
576 EXPECT_EQ(cert1
->os_cert_handle(), cert3
->os_cert_handle());
577 // Though they use the same OS handle, the intermediates should be different.
578 EXPECT_NE(cert1
->GetIntermediateCertificates().size(),
579 cert3
->GetIntermediateCertificates().size());
582 TEST(X509CertificateTest
, Pickle
) {
583 X509Certificate::OSCertHandle google_cert_handle
=
584 X509Certificate::CreateOSCertHandleFromBytes(
585 reinterpret_cast<const char*>(google_der
), sizeof(google_der
));
586 X509Certificate::OSCertHandle thawte_cert_handle
=
587 X509Certificate::CreateOSCertHandleFromBytes(
588 reinterpret_cast<const char*>(thawte_der
), sizeof(thawte_der
));
590 X509Certificate::OSCertHandles intermediates
;
591 intermediates
.push_back(thawte_cert_handle
);
592 scoped_refptr
<X509Certificate
> cert
= X509Certificate::CreateFromHandle(
593 google_cert_handle
, intermediates
);
594 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), cert
.get());
596 X509Certificate::FreeOSCertHandle(google_cert_handle
);
597 X509Certificate::FreeOSCertHandle(thawte_cert_handle
);
600 cert
->Persist(&pickle
);
602 PickleIterator
iter(pickle
);
603 scoped_refptr
<X509Certificate
> cert_from_pickle
=
604 X509Certificate::CreateFromPickle(
605 pickle
, &iter
, X509Certificate::PICKLETYPE_CERTIFICATE_CHAIN_V3
);
606 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), cert_from_pickle
.get());
607 EXPECT_TRUE(X509Certificate::IsSameOSCert(
608 cert
->os_cert_handle(), cert_from_pickle
->os_cert_handle()));
609 const X509Certificate::OSCertHandles
& cert_intermediates
=
610 cert
->GetIntermediateCertificates();
611 const X509Certificate::OSCertHandles
& pickle_intermediates
=
612 cert_from_pickle
->GetIntermediateCertificates();
613 ASSERT_EQ(cert_intermediates
.size(), pickle_intermediates
.size());
614 for (size_t i
= 0; i
< cert_intermediates
.size(); ++i
) {
615 EXPECT_TRUE(X509Certificate::IsSameOSCert(cert_intermediates
[i
],
616 pickle_intermediates
[i
]));
620 TEST(X509CertificateTest
, IntermediateCertificates
) {
621 scoped_refptr
<X509Certificate
> webkit_cert(
622 X509Certificate::CreateFromBytes(
623 reinterpret_cast<const char*>(webkit_der
), sizeof(webkit_der
)));
625 scoped_refptr
<X509Certificate
> thawte_cert(
626 X509Certificate::CreateFromBytes(
627 reinterpret_cast<const char*>(thawte_der
), sizeof(thawte_der
)));
629 X509Certificate::OSCertHandle google_handle
;
630 // Create object with no intermediates:
631 google_handle
= X509Certificate::CreateOSCertHandleFromBytes(
632 reinterpret_cast<const char*>(google_der
), sizeof(google_der
));
633 X509Certificate::OSCertHandles intermediates1
;
634 scoped_refptr
<X509Certificate
> cert1
;
635 cert1
= X509Certificate::CreateFromHandle(google_handle
, intermediates1
);
636 EXPECT_EQ(0u, cert1
->GetIntermediateCertificates().size());
638 // Create object with 2 intermediates:
639 X509Certificate::OSCertHandles intermediates2
;
640 intermediates2
.push_back(webkit_cert
->os_cert_handle());
641 intermediates2
.push_back(thawte_cert
->os_cert_handle());
642 scoped_refptr
<X509Certificate
> cert2
;
643 cert2
= X509Certificate::CreateFromHandle(google_handle
, intermediates2
);
645 // Verify it has all the intermediates:
646 const X509Certificate::OSCertHandles
& cert2_intermediates
=
647 cert2
->GetIntermediateCertificates();
648 ASSERT_EQ(2u, cert2_intermediates
.size());
649 EXPECT_TRUE(X509Certificate::IsSameOSCert(cert2_intermediates
[0],
650 webkit_cert
->os_cert_handle()));
651 EXPECT_TRUE(X509Certificate::IsSameOSCert(cert2_intermediates
[1],
652 thawte_cert
->os_cert_handle()));
655 X509Certificate::FreeOSCertHandle(google_handle
);
658 TEST(X509CertificateTest
, IsIssuedByEncoded
) {
659 base::FilePath certs_dir
= GetTestCertsDirectory();
661 // Test a client certificate from MIT.
662 scoped_refptr
<X509Certificate
> mit_davidben_cert(
663 ImportCertFromFile(certs_dir
, "mit.davidben.der"));
664 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), mit_davidben_cert
.get());
666 std::string
mit_issuer(reinterpret_cast<const char*>(MITDN
),
669 // Test a certificate from Google, issued by Thawte
670 scoped_refptr
<X509Certificate
> google_cert(
671 ImportCertFromFile(certs_dir
, "google.single.der"));
672 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), google_cert
.get());
674 std::string
thawte_issuer(reinterpret_cast<const char*>(ThawteDN
),
677 // Check that the David Ben certificate is issued by MIT, but not
679 std::vector
<std::string
> issuers
;
681 issuers
.push_back(mit_issuer
);
682 EXPECT_TRUE(mit_davidben_cert
->IsIssuedByEncoded(issuers
));
683 EXPECT_FALSE(google_cert
->IsIssuedByEncoded(issuers
));
685 // Check that the Google certificate is issued by Thawte and not
688 issuers
.push_back(thawte_issuer
);
689 EXPECT_FALSE(mit_davidben_cert
->IsIssuedByEncoded(issuers
));
690 EXPECT_TRUE(google_cert
->IsIssuedByEncoded(issuers
));
692 // Check that they both pass when given a list of the two issuers.
694 issuers
.push_back(mit_issuer
);
695 issuers
.push_back(thawte_issuer
);
696 EXPECT_TRUE(mit_davidben_cert
->IsIssuedByEncoded(issuers
));
697 EXPECT_TRUE(google_cert
->IsIssuedByEncoded(issuers
));
700 TEST(X509CertificateTest
, IsIssuedByEncodedWithIntermediates
) {
701 static const unsigned char kPolicyRootDN
[] = {
702 0x30, 0x1e, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
703 0x13, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x54, 0x65, 0x73, 0x74,
704 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41
706 static const unsigned char kPolicyIntermediateDN
[] = {
707 0x30, 0x26, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
708 0x1b, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x54, 0x65, 0x73, 0x74,
709 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74,
710 0x65, 0x20, 0x43, 0x41
713 base::FilePath certs_dir
= GetTestCertsDirectory();
715 CertificateList policy_chain
= CreateCertificateListFromFile(
716 certs_dir
, "explicit-policy-chain.pem", X509Certificate::FORMAT_AUTO
);
717 ASSERT_EQ(3u, policy_chain
.size());
719 // The intermediate CA certificate's policyConstraints extension has a
720 // requireExplicitPolicy field with SkipCerts=0.
721 std::string
policy_intermediate_dn(
722 reinterpret_cast<const char*>(kPolicyIntermediateDN
),
723 sizeof(kPolicyIntermediateDN
));
724 std::string
policy_root_dn(reinterpret_cast<const char*>(kPolicyRootDN
),
725 sizeof(kPolicyRootDN
));
727 X509Certificate::OSCertHandles intermediates
;
728 intermediates
.push_back(policy_chain
[1]->os_cert_handle());
729 scoped_refptr
<X509Certificate
> cert_chain
=
730 X509Certificate::CreateFromHandle(policy_chain
[0]->os_cert_handle(),
733 std::vector
<std::string
> issuers
;
735 // Check that the chain is issued by the intermediate.
737 issuers
.push_back(policy_intermediate_dn
);
738 EXPECT_TRUE(cert_chain
->IsIssuedByEncoded(issuers
));
740 // Check that the chain is also issued by the root.
742 issuers
.push_back(policy_root_dn
);
743 EXPECT_TRUE(cert_chain
->IsIssuedByEncoded(issuers
));
745 // Check that the chain is issued by either the intermediate or the root.
747 issuers
.push_back(policy_intermediate_dn
);
748 issuers
.push_back(policy_root_dn
);
749 EXPECT_TRUE(cert_chain
->IsIssuedByEncoded(issuers
));
751 // Check that an empty issuers list returns false.
753 EXPECT_FALSE(cert_chain
->IsIssuedByEncoded(issuers
));
755 // Check that the chain is not issued by Verisign
756 std::string
mit_issuer(reinterpret_cast<const char*>(VerisignDN
),
759 issuers
.push_back(mit_issuer
);
760 EXPECT_FALSE(cert_chain
->IsIssuedByEncoded(issuers
));
763 // Tests that FreeOSCertHandle ignores NULL on each OS.
764 TEST(X509CertificateTest
, FreeNullHandle
) {
765 X509Certificate::FreeOSCertHandle(NULL
);
769 TEST(X509CertificateTest
, GetDefaultNickname
) {
770 base::FilePath certs_dir
= GetTestCertsDirectory();
772 scoped_refptr
<X509Certificate
> test_cert(
773 ImportCertFromFile(certs_dir
, "no_subject_common_name_cert.pem"));
774 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), test_cert
.get());
776 std::string nickname
= test_cert
->GetDefaultNickname(USER_CERT
);
777 EXPECT_EQ("wtc@google.com's COMODO Client Authentication and "
778 "Secure Email CA ID", nickname
);
782 const struct CertificateFormatTestData
{
783 const char* file_name
;
784 X509Certificate::Format format
;
785 uint8
* chain_fingerprints
[3];
786 } kFormatTestData
[] = {
787 // DER Parsing - single certificate, DER encoded
788 { "google.single.der", X509Certificate::FORMAT_SINGLE_CERTIFICATE
,
789 { google_parse_fingerprint
,
791 // DER parsing - single certificate, PEM encoded
792 { "google.single.pem", X509Certificate::FORMAT_SINGLE_CERTIFICATE
,
793 { google_parse_fingerprint
,
795 // PEM parsing - single certificate, PEM encoded with a PEB of
797 { "google.single.pem", X509Certificate::FORMAT_PEM_CERT_SEQUENCE
,
798 { google_parse_fingerprint
,
800 // PEM parsing - sequence of certificates, PEM encoded with a PEB of
802 { "google.chain.pem", X509Certificate::FORMAT_PEM_CERT_SEQUENCE
,
803 { google_parse_fingerprint
,
804 thawte_parse_fingerprint
,
806 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, DER
808 { "google.binary.p7b", X509Certificate::FORMAT_PKCS7
,
809 { google_parse_fingerprint
,
810 thawte_parse_fingerprint
,
812 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, PEM
813 // encoded with a PEM PEB of "CERTIFICATE"
814 { "google.pem_cert.p7b", X509Certificate::FORMAT_PKCS7
,
815 { google_parse_fingerprint
,
816 thawte_parse_fingerprint
,
818 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, PEM
819 // encoded with a PEM PEB of "PKCS7"
820 { "google.pem_pkcs7.p7b", X509Certificate::FORMAT_PKCS7
,
821 { google_parse_fingerprint
,
822 thawte_parse_fingerprint
,
824 // All of the above, this time using auto-detection
825 { "google.single.der", X509Certificate::FORMAT_AUTO
,
826 { google_parse_fingerprint
,
828 { "google.single.pem", X509Certificate::FORMAT_AUTO
,
829 { google_parse_fingerprint
,
831 { "google.chain.pem", X509Certificate::FORMAT_AUTO
,
832 { google_parse_fingerprint
,
833 thawte_parse_fingerprint
,
835 { "google.binary.p7b", X509Certificate::FORMAT_AUTO
,
836 { google_parse_fingerprint
,
837 thawte_parse_fingerprint
,
839 { "google.pem_cert.p7b", X509Certificate::FORMAT_AUTO
,
840 { google_parse_fingerprint
,
841 thawte_parse_fingerprint
,
843 { "google.pem_pkcs7.p7b", X509Certificate::FORMAT_AUTO
,
844 { google_parse_fingerprint
,
845 thawte_parse_fingerprint
,
849 class X509CertificateParseTest
850 : public testing::TestWithParam
<CertificateFormatTestData
> {
852 virtual ~X509CertificateParseTest() {}
853 virtual void SetUp() {
854 test_data_
= GetParam();
856 virtual void TearDown() {}
859 CertificateFormatTestData test_data_
;
862 TEST_P(X509CertificateParseTest
, CanParseFormat
) {
863 base::FilePath certs_dir
= GetTestCertsDirectory();
864 CertificateList certs
= CreateCertificateListFromFile(
865 certs_dir
, test_data_
.file_name
, test_data_
.format
);
866 ASSERT_FALSE(certs
.empty());
867 ASSERT_LE(certs
.size(), arraysize(test_data_
.chain_fingerprints
));
868 CheckGoogleCert(certs
.front(), google_parse_fingerprint
,
869 kGoogleParseValidFrom
, kGoogleParseValidTo
);
872 for (i
= 0; i
< arraysize(test_data_
.chain_fingerprints
); ++i
) {
873 if (test_data_
.chain_fingerprints
[i
] == NULL
) {
874 // No more test certificates expected - make sure no more were
875 // returned before marking this test a success.
876 EXPECT_EQ(i
, certs
.size());
880 // A cert is expected - make sure that one was parsed.
881 ASSERT_LT(i
, certs
.size());
883 // Compare the parsed certificate with the expected certificate, by
884 // comparing fingerprints.
885 const X509Certificate
* cert
= certs
[i
].get();
886 const SHA1HashValue
& actual_fingerprint
= cert
->fingerprint();
887 uint8
* expected_fingerprint
= test_data_
.chain_fingerprints
[i
];
889 for (size_t j
= 0; j
< 20; ++j
)
890 EXPECT_EQ(expected_fingerprint
[j
], actual_fingerprint
.data
[j
]);
894 INSTANTIATE_TEST_CASE_P(, X509CertificateParseTest
,
895 testing::ValuesIn(kFormatTestData
));
897 struct CertificateNameVerifyTestData
{
898 // true iff we expect hostname to match an entry in cert_names.
900 // The hostname to match.
901 const char* hostname
;
902 // Common name, may be used if |dns_names| or |ip_addrs| are empty.
903 const char* common_name
;
904 // Comma separated list of certificate names to match against. Any occurrence
905 // of '#' will be replaced with a null character before processing.
906 const char* dns_names
;
907 // Comma separated list of certificate IP Addresses to match against. Each
908 // address is x prefixed 16 byte hex code for v6 or dotted-decimals for v4.
909 const char* ip_addrs
;
912 // GTest 'magic' pretty-printer, so that if/when a test fails, it knows how
913 // to output the parameter that was passed. Without this, it will simply
914 // attempt to print out the first twenty bytes of the object, which depending
915 // on platform and alignment, may result in an invalid read.
916 void PrintTo(const CertificateNameVerifyTestData
& data
, std::ostream
* os
) {
917 ASSERT_TRUE(data
.hostname
&& data
.common_name
);
918 // Using StringPiece to allow for optional fields being NULL.
919 *os
<< " expected: " << data
.expected
920 << "; hostname: " << data
.hostname
921 << "; common_name: " << data
.common_name
922 << "; dns_names: " << base::StringPiece(data
.dns_names
)
923 << "; ip_addrs: " << base::StringPiece(data
.ip_addrs
);
926 const CertificateNameVerifyTestData kNameVerifyTestData
[] = {
927 { true, "foo.com", "foo.com" },
930 { true, "bar.foo.com", "*.foo.com" },
931 { true, "www.test.fr", "common.name",
932 "*.test.com,*.test.co.uk,*.test.de,*.test.fr" },
933 { true, "wwW.tESt.fr", "common.name",
934 ",*.*,*.test.de,*.test.FR,www" },
935 { false, "f.uk", ".uk" },
936 { false, "w.bar.foo.com", "?.bar.foo.com" },
937 { false, "www.foo.com", "(www|ftp).foo.com" },
938 { false, "www.foo.com", "www.foo.com#" }, // # = null char.
939 { false, "www.foo.com", "", "www.foo.com#*.foo.com,#,#" },
940 { false, "www.house.example", "ww.house.example" },
941 { false, "test.org", "", "www.test.org,*.test.org,*.org" },
942 { false, "w.bar.foo.com", "w*.bar.foo.com" },
943 { false, "www.bar.foo.com", "ww*ww.bar.foo.com" },
944 { false, "wwww.bar.foo.com", "ww*ww.bar.foo.com" },
945 { true, "wwww.bar.foo.com", "w*w.bar.foo.com" },
946 { false, "wwww.bar.foo.com", "w*w.bar.foo.c0m" },
947 { true, "WALLY.bar.foo.com", "wa*.bar.foo.com" },
948 { true, "wally.bar.foo.com", "*Ly.bar.foo.com" },
949 { true, "ww%57.foo.com", "", "www.foo.com" },
950 { true, "www&.foo.com", "www%26.foo.com" },
951 // Common name must not be used if subject alternative name was provided.
952 { false, "www.test.co.jp", "www.test.co.jp",
953 "*.test.de,*.jp,www.test.co.uk,www.*.co.jp" },
954 { false, "www.bar.foo.com", "www.bar.foo.com",
955 "*.foo.com,*.*.foo.com,*.*.bar.foo.com,*..bar.foo.com," },
956 { false, "www.bath.org", "www.bath.org", "", "20.30.40.50" },
957 { false, "66.77.88.99", "www.bath.org", "www.bath.org" },
959 { true, "xn--poema-9qae5a.com.br", "xn--poema-9qae5a.com.br" },
960 { true, "www.xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br" },
961 { false, "xn--poema-9qae5a.com.br", "", "*.xn--poema-9qae5a.com.br,"
962 "xn--poema-*.com.br,"
963 "xn--*-9qae5a.com.br,"
964 "*--poema-9qae5a.com.br" },
965 // The following are adapted from the examples quoted from
966 // http://tools.ietf.org/html/rfc6125#section-6.4.3
967 // (e.g., *.example.com would match foo.example.com but
968 // not bar.foo.example.com or example.com).
969 { true, "foo.example.com", "*.example.com" },
970 { false, "bar.foo.example.com", "*.example.com" },
971 { false, "example.com", "*.example.com" },
972 // (e.g., baz*.example.net and *baz.example.net and b*z.example.net would
973 // be taken to match baz1.example.net and foobaz.example.net and
974 // buzz.example.net, respectively
975 { true, "baz1.example.net", "baz*.example.net" },
976 { true, "foobaz.example.net", "*baz.example.net" },
977 { true, "buzz.example.net", "b*z.example.net" },
978 // Wildcards should not be valid for public registry controlled domains,
979 // and unknown/unrecognized domains, at least three domain components must
981 { true, "www.test.example", "*.test.example" },
982 { true, "test.example.co.uk", "*.example.co.uk" },
983 { false, "test.example", "*.exmaple" },
984 { false, "example.co.uk", "*.co.uk" },
985 { false, "foo.com", "*.com" },
986 { false, "foo.us", "*.us" },
987 { false, "foo", "*" },
988 // IDN variants of wildcards and registry controlled domains.
989 { true, "www.xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br" },
990 { true, "test.example.xn--mgbaam7a8h", "*.example.xn--mgbaam7a8h" },
991 { false, "xn--poema-9qae5a.com.br", "*.com.br" },
992 { false, "example.xn--mgbaam7a8h", "*.xn--mgbaam7a8h" },
993 // Wildcards should be permissible for 'private' registry controlled
995 { true, "www.appspot.com", "*.appspot.com" },
996 { true, "foo.s3.amazonaws.com", "*.s3.amazonaws.com" },
997 // Multiple wildcards are not valid.
998 { false, "foo.example.com", "*.*.com" },
999 { false, "foo.bar.example.com", "*.bar.*.com" },
1000 // Absolute vs relative DNS name tests. Although not explicitly specified
1001 // in RFC 6125, absolute reference names (those ending in a .) should
1002 // match either absolute or relative presented names.
1003 { true, "foo.com", "foo.com." },
1004 { true, "foo.com.", "foo.com" },
1005 { true, "foo.com.", "foo.com." },
1006 { true, "f", "f." },
1007 { true, "f.", "f" },
1008 { true, "f.", "f." },
1009 { true, "www-3.bar.foo.com", "*.bar.foo.com." },
1010 { true, "www-3.bar.foo.com.", "*.bar.foo.com" },
1011 { true, "www-3.bar.foo.com.", "*.bar.foo.com." },
1012 { false, ".", "." },
1013 { false, "example.com", "*.com." },
1014 { false, "example.com.", "*.com" },
1015 { false, "example.com.", "*.com." },
1016 { false, "foo.", "*." },
1017 { false, "foo", "*." },
1018 { false, "foo.co.uk", "*.co.uk." },
1019 { false, "foo.co.uk.", "*.co.uk." },
1020 // IP addresses in common name; IPv4 only.
1021 { true, "127.0.0.1", "127.0.0.1" },
1022 { true, "192.168.1.1", "192.168.1.1" },
1023 { true, "676768", "0.10.83.160" },
1024 { true, "1.2.3", "1.2.0.3" },
1025 { false, "192.169.1.1", "192.168.1.1" },
1026 { false, "12.19.1.1", "12.19.1.1/255.255.255.0" },
1027 { false, "FEDC:ba98:7654:3210:FEDC:BA98:7654:3210",
1028 "FEDC:BA98:7654:3210:FEDC:ba98:7654:3210" },
1029 { false, "1111:2222:3333:4444:5555:6666:7777:8888",
1030 "1111:2222:3333:4444:5555:6666:7777:8888" },
1031 { false, "::192.9.5.5", "[::192.9.5.5]" },
1032 // No wildcard matching in valid IP addresses
1033 { false, "::192.9.5.5", "*.9.5.5" },
1034 { false, "2010:836B:4179::836B:4179", "*:836B:4179::836B:4179" },
1035 { false, "192.168.1.11", "*.168.1.11" },
1036 { false, "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210", "*.]" },
1037 // IP addresses in subject alternative name (common name ignored)
1038 { true, "10.1.2.3", "", "", "10.1.2.3" },
1039 { true, "14.15", "", "", "14.0.0.15" },
1040 { false, "10.1.2.7", "10.1.2.7", "", "10.1.2.6,10.1.2.8" },
1041 { false, "10.1.2.8", "10.20.2.8", "foo" },
1042 { true, "::4.5.6.7", "", "", "x00000000000000000000000004050607" },
1043 { false, "::6.7.8.9", "::6.7.8.9", "::6.7.8.9",
1044 "x00000000000000000000000006070808,x0000000000000000000000000607080a,"
1045 "xff000000000000000000000006070809,6.7.8.9" },
1046 { true, "FE80::200:f8ff:fe21:67cf", "no.common.name", "",
1047 "x00000000000000000000000006070808,xfe800000000000000200f8fffe2167cf,"
1048 "xff0000000000000000000000060708ff,10.0.0.1" },
1049 // Numeric only hostnames (none of these are considered valid IP addresses).
1050 { false, "12345.6", "12345.6" },
1051 { false, "121.2.3.512", "", "1*1.2.3.512,*1.2.3.512,1*.2.3.512,*.2.3.512",
1053 { false, "1.2.3.4.5.6", "*.2.3.4.5.6" },
1054 { true, "1.2.3.4.5", "", "1.2.3.4.5" },
1055 // Invalid host names.
1056 { false, "junk)(£)$*!@~#", "junk)(£)$*!@~#" },
1057 { false, "www.*.com", "www.*.com" },
1058 { false, "w$w.f.com", "w$w.f.com" },
1059 { false, "nocolonallowed:example", "", "nocolonallowed:example" },
1060 { false, "www-1.[::FFFF:129.144.52.38]", "*.[::FFFF:129.144.52.38]" },
1061 { false, "[::4.5.6.9]", "", "", "x00000000000000000000000004050609" },
1064 class X509CertificateNameVerifyTest
1065 : public testing::TestWithParam
<CertificateNameVerifyTestData
> {
1068 TEST_P(X509CertificateNameVerifyTest
, VerifyHostname
) {
1069 CertificateNameVerifyTestData test_data
= GetParam();
1071 std::string
common_name(test_data
.common_name
);
1072 ASSERT_EQ(std::string::npos
, common_name
.find(','));
1073 std::replace(common_name
.begin(), common_name
.end(), '#', '\0');
1075 std::vector
<std::string
> dns_names
, ip_addressses
;
1076 if (test_data
.dns_names
) {
1077 // Build up the certificate DNS names list.
1078 std::string
dns_name_line(test_data
.dns_names
);
1079 std::replace(dns_name_line
.begin(), dns_name_line
.end(), '#', '\0');
1080 base::SplitString(dns_name_line
, ',', &dns_names
);
1083 if (test_data
.ip_addrs
) {
1084 // Build up the certificate IP address list.
1085 std::string
ip_addrs_line(test_data
.ip_addrs
);
1086 std::vector
<std::string
> ip_addressses_ascii
;
1087 base::SplitString(ip_addrs_line
, ',', &ip_addressses_ascii
);
1088 for (size_t i
= 0; i
< ip_addressses_ascii
.size(); ++i
) {
1089 std::string
& addr_ascii
= ip_addressses_ascii
[i
];
1090 ASSERT_NE(0U, addr_ascii
.length());
1091 if (addr_ascii
[0] == 'x') { // Hex encoded address
1092 addr_ascii
.erase(0, 1);
1093 std::vector
<uint8
> bytes
;
1094 EXPECT_TRUE(base::HexStringToBytes(addr_ascii
, &bytes
))
1095 << "Could not parse hex address " << addr_ascii
<< " i = " << i
;
1096 ip_addressses
.push_back(std::string(reinterpret_cast<char*>(&bytes
[0]),
1098 ASSERT_EQ(16U, ip_addressses
.back().size()) << i
;
1099 } else { // Decimal groups
1100 std::vector
<std::string
> decimals_ascii
;
1101 base::SplitString(addr_ascii
, '.', &decimals_ascii
);
1102 EXPECT_EQ(4U, decimals_ascii
.size()) << i
;
1103 std::string addr_bytes
;
1104 for (size_t j
= 0; j
< decimals_ascii
.size(); ++j
) {
1106 EXPECT_TRUE(base::StringToInt(decimals_ascii
[j
], &decimal_value
));
1107 EXPECT_GE(decimal_value
, 0);
1108 EXPECT_LE(decimal_value
, 255);
1109 addr_bytes
.push_back(static_cast<char>(decimal_value
));
1111 ip_addressses
.push_back(addr_bytes
);
1112 ASSERT_EQ(4U, ip_addressses
.back().size()) << i
;
1117 bool unused
= false;
1118 EXPECT_EQ(test_data
.expected
, X509Certificate::VerifyHostname(
1119 test_data
.hostname
, common_name
, dns_names
, ip_addressses
, &unused
));
1122 INSTANTIATE_TEST_CASE_P(, X509CertificateNameVerifyTest
,
1123 testing::ValuesIn(kNameVerifyTestData
));
1125 const struct PublicKeyInfoTestData
{
1126 const char* cert_file
;
1127 size_t expected_bits
;
1128 X509Certificate::PublicKeyType expected_type
;
1129 } kPublicKeyInfoTestData
[] = {
1130 { "768-rsa-ee-by-768-rsa-intermediate.pem", 768,
1131 X509Certificate::kPublicKeyTypeRSA
},
1132 { "1024-rsa-ee-by-768-rsa-intermediate.pem", 1024,
1133 X509Certificate::kPublicKeyTypeRSA
},
1134 { "prime256v1-ecdsa-ee-by-1024-rsa-intermediate.pem", 256,
1135 X509Certificate::kPublicKeyTypeECDSA
},
1138 class X509CertificatePublicKeyInfoTest
1139 : public testing::TestWithParam
<PublicKeyInfoTestData
> {
1142 TEST_P(X509CertificatePublicKeyInfoTest
, GetPublicKeyInfo
) {
1143 PublicKeyInfoTestData data
= GetParam();
1146 if (base::win::GetVersion() < base::win::VERSION_VISTA
&&
1147 data
.expected_type
== X509Certificate::kPublicKeyTypeECDSA
) {
1148 // ECC is only supported on Vista+. Skip the test.
1153 scoped_refptr
<X509Certificate
> cert(
1154 ImportCertFromFile(GetTestCertsDirectory(), data
.cert_file
));
1155 ASSERT_TRUE(cert
.get());
1157 size_t actual_bits
= 0;
1158 X509Certificate::PublicKeyType actual_type
=
1159 X509Certificate::kPublicKeyTypeUnknown
;
1161 X509Certificate::GetPublicKeyInfo(cert
->os_cert_handle(), &actual_bits
,
1164 EXPECT_EQ(data
.expected_bits
, actual_bits
);
1165 EXPECT_EQ(data
.expected_type
, actual_type
);
1168 INSTANTIATE_TEST_CASE_P(, X509CertificatePublicKeyInfoTest
,
1169 testing::ValuesIn(kPublicKeyInfoTestData
));