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 "base/strings/string_util.h"
15 #include "crypto/rsa_private_key.h"
16 #include "net/base/net_errors.h"
17 #include "net/base/test_data_directory.h"
18 #include "net/cert/asn1_util.h"
19 #include "net/test/cert_test_util.h"
20 #include "net/test/test_certificate_data.h"
21 #include "testing/gtest/include/gtest/gtest.h"
28 #include "base/win/windows_version.h"
31 using base::HexEncode
;
36 // Certificates for test data. They're obtained with:
38 // $ openssl s_client -connect [host]:443 -showcerts > /tmp/host.pem < /dev/null
39 // $ openssl x509 -inform PEM -outform DER < /tmp/host.pem > /tmp/host.der
42 // $ openssl x509 -inform DER -fingerprint -noout < /tmp/host.der
44 // For valid_start, valid_expiry
45 // $ openssl x509 -inform DER -text -noout < /tmp/host.der |
47 // $ date +%s -d '<date str>'
50 uint8 google_fingerprint
[] = {
51 0xab, 0xbe, 0x5e, 0xb4, 0x93, 0x88, 0x4e, 0xe4, 0x60, 0xc6, 0xef, 0xf8,
52 0xea, 0xd4, 0xb1, 0x55, 0x4b, 0xc9, 0x59, 0x3c
56 uint8 webkit_fingerprint
[] = {
57 0xa1, 0x4a, 0x94, 0x46, 0x22, 0x8e, 0x70, 0x66, 0x2b, 0x94, 0xf9, 0xf8,
58 0x57, 0x83, 0x2d, 0xa2, 0xff, 0xbc, 0x84, 0xc2
61 // thawte.com's cert (it's EV-licious!).
62 uint8 thawte_fingerprint
[] = {
63 0x85, 0x04, 0x2d, 0xfd, 0x2b, 0x0e, 0xc6, 0xc8, 0xaf, 0x2d, 0x77, 0xd6,
64 0xa1, 0x3a, 0x64, 0x04, 0x27, 0x90, 0x97, 0x37
67 // A certificate for https://www.unosoft.hu/, whose AIA extension contains
68 // an LDAP URL without a host name.
69 uint8 unosoft_hu_fingerprint
[] = {
70 0x32, 0xff, 0xe3, 0xbe, 0x2c, 0x3b, 0xc7, 0xca, 0xbf, 0x2d, 0x64, 0xbd,
71 0x25, 0x66, 0xf2, 0xec, 0x8b, 0x0f, 0xbf, 0xd8
74 // The fingerprint of the Google certificate used in the parsing tests,
75 // which is newer than the one included in the x509_certificate_data.h
76 uint8 google_parse_fingerprint
[] = {
77 0x40, 0x50, 0x62, 0xe5, 0xbe, 0xfd, 0xe4, 0xaf, 0x97, 0xe9, 0x38, 0x2a,
78 0xf1, 0x6c, 0xc8, 0x7c, 0x8f, 0xb7, 0xc4, 0xe2
81 // The fingerprint for the Thawte SGC certificate
82 uint8 thawte_parse_fingerprint
[] = {
83 0xec, 0x07, 0x10, 0x03, 0xd8, 0xf5, 0xa3, 0x7f, 0x42, 0xc4, 0x55, 0x7f,
84 0x65, 0x6a, 0xae, 0x86, 0x65, 0xfa, 0x4b, 0x02
87 // Dec 18 00:00:00 2009 GMT
88 const double kGoogleParseValidFrom
= 1261094400;
89 // Dec 18 23:59:59 2011 GMT
90 const double kGoogleParseValidTo
= 1324252799;
92 void CheckGoogleCert(const scoped_refptr
<X509Certificate
>& google_cert
,
93 uint8
* expected_fingerprint
,
94 double valid_from
, double valid_to
) {
95 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), google_cert
.get());
97 const CertPrincipal
& subject
= google_cert
->subject();
98 EXPECT_EQ("www.google.com", subject
.common_name
);
99 EXPECT_EQ("Mountain View", subject
.locality_name
);
100 EXPECT_EQ("California", subject
.state_or_province_name
);
101 EXPECT_EQ("US", subject
.country_name
);
102 EXPECT_EQ(0U, subject
.street_addresses
.size());
103 ASSERT_EQ(1U, subject
.organization_names
.size());
104 EXPECT_EQ("Google Inc", subject
.organization_names
[0]);
105 EXPECT_EQ(0U, subject
.organization_unit_names
.size());
106 EXPECT_EQ(0U, subject
.domain_components
.size());
108 const CertPrincipal
& issuer
= google_cert
->issuer();
109 EXPECT_EQ("Thawte SGC CA", issuer
.common_name
);
110 EXPECT_EQ("", issuer
.locality_name
);
111 EXPECT_EQ("", issuer
.state_or_province_name
);
112 EXPECT_EQ("ZA", issuer
.country_name
);
113 EXPECT_EQ(0U, issuer
.street_addresses
.size());
114 ASSERT_EQ(1U, issuer
.organization_names
.size());
115 EXPECT_EQ("Thawte Consulting (Pty) Ltd.", issuer
.organization_names
[0]);
116 EXPECT_EQ(0U, issuer
.organization_unit_names
.size());
117 EXPECT_EQ(0U, issuer
.domain_components
.size());
119 // Use DoubleT because its epoch is the same on all platforms
120 const Time
& valid_start
= google_cert
->valid_start();
121 EXPECT_EQ(valid_from
, valid_start
.ToDoubleT());
123 const Time
& valid_expiry
= google_cert
->valid_expiry();
124 EXPECT_EQ(valid_to
, valid_expiry
.ToDoubleT());
126 const SHA1HashValue
& fingerprint
= google_cert
->fingerprint();
127 for (size_t i
= 0; i
< 20; ++i
)
128 EXPECT_EQ(expected_fingerprint
[i
], fingerprint
.data
[i
]);
130 std::vector
<std::string
> dns_names
;
131 google_cert
->GetDNSNames(&dns_names
);
132 ASSERT_EQ(1U, dns_names
.size());
133 EXPECT_EQ("www.google.com", dns_names
[0]);
136 TEST(X509CertificateTest
, GoogleCertParsing
) {
137 scoped_refptr
<X509Certificate
> google_cert(
138 X509Certificate::CreateFromBytes(
139 reinterpret_cast<const char*>(google_der
), sizeof(google_der
)));
141 CheckGoogleCert(google_cert
, google_fingerprint
,
142 1238192407, // Mar 27 22:20:07 2009 GMT
143 1269728407); // Mar 27 22:20:07 2010 GMT
146 TEST(X509CertificateTest
, WebkitCertParsing
) {
147 scoped_refptr
<X509Certificate
> webkit_cert(X509Certificate::CreateFromBytes(
148 reinterpret_cast<const char*>(webkit_der
), sizeof(webkit_der
)));
150 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), webkit_cert
.get());
152 const CertPrincipal
& subject
= webkit_cert
->subject();
153 EXPECT_EQ("Cupertino", subject
.locality_name
);
154 EXPECT_EQ("California", subject
.state_or_province_name
);
155 EXPECT_EQ("US", subject
.country_name
);
156 EXPECT_EQ(0U, subject
.street_addresses
.size());
157 ASSERT_EQ(1U, subject
.organization_names
.size());
158 EXPECT_EQ("Apple Inc.", subject
.organization_names
[0]);
159 ASSERT_EQ(1U, subject
.organization_unit_names
.size());
160 EXPECT_EQ("Mac OS Forge", subject
.organization_unit_names
[0]);
161 EXPECT_EQ(0U, subject
.domain_components
.size());
163 const CertPrincipal
& issuer
= webkit_cert
->issuer();
164 EXPECT_EQ("Go Daddy Secure Certification Authority", issuer
.common_name
);
165 EXPECT_EQ("Scottsdale", issuer
.locality_name
);
166 EXPECT_EQ("Arizona", issuer
.state_or_province_name
);
167 EXPECT_EQ("US", issuer
.country_name
);
168 EXPECT_EQ(0U, issuer
.street_addresses
.size());
169 ASSERT_EQ(1U, issuer
.organization_names
.size());
170 EXPECT_EQ("GoDaddy.com, Inc.", issuer
.organization_names
[0]);
171 ASSERT_EQ(1U, issuer
.organization_unit_names
.size());
172 EXPECT_EQ("http://certificates.godaddy.com/repository",
173 issuer
.organization_unit_names
[0]);
174 EXPECT_EQ(0U, issuer
.domain_components
.size());
176 // Use DoubleT because its epoch is the same on all platforms
177 const Time
& valid_start
= webkit_cert
->valid_start();
178 EXPECT_EQ(1205883319, valid_start
.ToDoubleT()); // Mar 18 23:35:19 2008 GMT
180 const Time
& valid_expiry
= webkit_cert
->valid_expiry();
181 EXPECT_EQ(1300491319, valid_expiry
.ToDoubleT()); // Mar 18 23:35:19 2011 GMT
183 const SHA1HashValue
& fingerprint
= webkit_cert
->fingerprint();
184 for (size_t i
= 0; i
< 20; ++i
)
185 EXPECT_EQ(webkit_fingerprint
[i
], fingerprint
.data
[i
]);
187 std::vector
<std::string
> dns_names
;
188 webkit_cert
->GetDNSNames(&dns_names
);
189 ASSERT_EQ(2U, dns_names
.size());
190 EXPECT_EQ("*.webkit.org", dns_names
[0]);
191 EXPECT_EQ("webkit.org", dns_names
[1]);
193 // Test that the wildcard cert matches properly.
195 EXPECT_TRUE(webkit_cert
->VerifyNameMatch("www.webkit.org", &unused
));
196 EXPECT_TRUE(webkit_cert
->VerifyNameMatch("foo.webkit.org", &unused
));
197 EXPECT_TRUE(webkit_cert
->VerifyNameMatch("webkit.org", &unused
));
198 EXPECT_FALSE(webkit_cert
->VerifyNameMatch("www.webkit.com", &unused
));
199 EXPECT_FALSE(webkit_cert
->VerifyNameMatch("www.foo.webkit.com", &unused
));
202 TEST(X509CertificateTest
, ThawteCertParsing
) {
203 scoped_refptr
<X509Certificate
> thawte_cert(X509Certificate::CreateFromBytes(
204 reinterpret_cast<const char*>(thawte_der
), sizeof(thawte_der
)));
206 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), thawte_cert
.get());
208 const CertPrincipal
& subject
= thawte_cert
->subject();
209 EXPECT_EQ("www.thawte.com", subject
.common_name
);
210 EXPECT_EQ("Mountain View", subject
.locality_name
);
211 EXPECT_EQ("California", subject
.state_or_province_name
);
212 EXPECT_EQ("US", subject
.country_name
);
213 EXPECT_EQ(0U, subject
.street_addresses
.size());
214 ASSERT_EQ(1U, subject
.organization_names
.size());
215 EXPECT_EQ("Thawte Inc", subject
.organization_names
[0]);
216 EXPECT_EQ(0U, subject
.organization_unit_names
.size());
217 EXPECT_EQ(0U, subject
.domain_components
.size());
219 const CertPrincipal
& issuer
= thawte_cert
->issuer();
220 EXPECT_EQ("thawte Extended Validation SSL CA", issuer
.common_name
);
221 EXPECT_EQ("", issuer
.locality_name
);
222 EXPECT_EQ("", issuer
.state_or_province_name
);
223 EXPECT_EQ("US", issuer
.country_name
);
224 EXPECT_EQ(0U, issuer
.street_addresses
.size());
225 ASSERT_EQ(1U, issuer
.organization_names
.size());
226 EXPECT_EQ("thawte, Inc.", issuer
.organization_names
[0]);
227 ASSERT_EQ(1U, issuer
.organization_unit_names
.size());
228 EXPECT_EQ("Terms of use at https://www.thawte.com/cps (c)06",
229 issuer
.organization_unit_names
[0]);
230 EXPECT_EQ(0U, issuer
.domain_components
.size());
232 // Use DoubleT because its epoch is the same on all platforms
233 const Time
& valid_start
= thawte_cert
->valid_start();
234 EXPECT_EQ(1227052800, valid_start
.ToDoubleT()); // Nov 19 00:00:00 2008 GMT
236 const Time
& valid_expiry
= thawte_cert
->valid_expiry();
237 EXPECT_EQ(1263772799, valid_expiry
.ToDoubleT()); // Jan 17 23:59:59 2010 GMT
239 const SHA1HashValue
& fingerprint
= thawte_cert
->fingerprint();
240 for (size_t i
= 0; i
< 20; ++i
)
241 EXPECT_EQ(thawte_fingerprint
[i
], fingerprint
.data
[i
]);
243 std::vector
<std::string
> dns_names
;
244 thawte_cert
->GetDNSNames(&dns_names
);
245 ASSERT_EQ(1U, dns_names
.size());
246 EXPECT_EQ("www.thawte.com", dns_names
[0]);
249 // Test that all desired AttributeAndValue pairs can be extracted when only
250 // a single RelativeDistinguishedName is present. "Normally" there is only
251 // one AVA per RDN, but some CAs place all AVAs within a single RDN.
252 // This is a regression test for http://crbug.com/101009
253 TEST(X509CertificateTest
, MultivalueRDN
) {
254 base::FilePath certs_dir
= GetTestCertsDirectory();
256 scoped_refptr
<X509Certificate
> multivalue_rdn_cert
=
257 ImportCertFromFile(certs_dir
, "multivalue_rdn.pem");
258 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), multivalue_rdn_cert
.get());
260 const CertPrincipal
& subject
= multivalue_rdn_cert
->subject();
261 EXPECT_EQ("Multivalue RDN Test", subject
.common_name
);
262 EXPECT_EQ("", subject
.locality_name
);
263 EXPECT_EQ("", subject
.state_or_province_name
);
264 EXPECT_EQ("US", subject
.country_name
);
265 EXPECT_EQ(0U, subject
.street_addresses
.size());
266 ASSERT_EQ(1U, subject
.organization_names
.size());
267 EXPECT_EQ("Chromium", subject
.organization_names
[0]);
268 ASSERT_EQ(1U, subject
.organization_unit_names
.size());
269 EXPECT_EQ("Chromium net_unittests", subject
.organization_unit_names
[0]);
270 ASSERT_EQ(1U, subject
.domain_components
.size());
271 EXPECT_EQ("Chromium", subject
.domain_components
[0]);
274 // Test that characters which would normally be escaped in the string form,
275 // such as '=' or '"', are not escaped when parsed as individual components.
276 // This is a regression test for http://crbug.com/102839
277 TEST(X509CertificateTest
, UnescapedSpecialCharacters
) {
278 base::FilePath certs_dir
= GetTestCertsDirectory();
280 scoped_refptr
<X509Certificate
> unescaped_cert
=
281 ImportCertFromFile(certs_dir
, "unescaped.pem");
282 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), unescaped_cert
.get());
284 const CertPrincipal
& subject
= unescaped_cert
->subject();
285 EXPECT_EQ("127.0.0.1", subject
.common_name
);
286 EXPECT_EQ("Mountain View", subject
.locality_name
);
287 EXPECT_EQ("California", subject
.state_or_province_name
);
288 EXPECT_EQ("US", subject
.country_name
);
289 ASSERT_EQ(1U, subject
.street_addresses
.size());
290 EXPECT_EQ("1600 Amphitheatre Parkway", subject
.street_addresses
[0]);
291 ASSERT_EQ(1U, subject
.organization_names
.size());
292 EXPECT_EQ("Chromium = \"net_unittests\"", subject
.organization_names
[0]);
293 ASSERT_EQ(2U, subject
.organization_unit_names
.size());
294 EXPECT_EQ("net_unittests", subject
.organization_unit_names
[0]);
295 EXPECT_EQ("Chromium", subject
.organization_unit_names
[1]);
296 EXPECT_EQ(0U, subject
.domain_components
.size());
299 TEST(X509CertificateTest
, SerialNumbers
) {
300 scoped_refptr
<X509Certificate
> google_cert(
301 X509Certificate::CreateFromBytes(
302 reinterpret_cast<const char*>(google_der
), sizeof(google_der
)));
304 static const uint8 google_serial
[16] = {
305 0x01,0x2a,0x39,0x76,0x0d,0x3f,0x4f,0xc9,
306 0x0b,0xe7,0xbd,0x2b,0xcf,0x95,0x2e,0x7a,
309 ASSERT_EQ(sizeof(google_serial
), google_cert
->serial_number().size());
310 EXPECT_TRUE(memcmp(google_cert
->serial_number().data(), google_serial
,
311 sizeof(google_serial
)) == 0);
313 // We also want to check a serial number where the first byte is >= 0x80 in
314 // case the underlying library tries to pad it.
315 scoped_refptr
<X509Certificate
> paypal_null_cert(
316 X509Certificate::CreateFromBytes(
317 reinterpret_cast<const char*>(paypal_null_der
),
318 sizeof(paypal_null_der
)));
320 static const uint8 paypal_null_serial
[3] = {0x00, 0xf0, 0x9b};
321 ASSERT_EQ(sizeof(paypal_null_serial
),
322 paypal_null_cert
->serial_number().size());
323 EXPECT_TRUE(memcmp(paypal_null_cert
->serial_number().data(),
324 paypal_null_serial
, sizeof(paypal_null_serial
)) == 0);
327 TEST(X509CertificateTest
, SHA256FingerprintsCorrectly
) {
328 scoped_refptr
<X509Certificate
> google_cert(X509Certificate::CreateFromBytes(
329 reinterpret_cast<const char*>(google_der
), sizeof(google_der
)));
331 static const uint8 google_sha256_fingerprint
[32] = {
332 0x21, 0xaf, 0x58, 0x74, 0xea, 0x6b, 0xad, 0xbd, 0xe4, 0xb3, 0xb1,
333 0xaa, 0x53, 0x32, 0x80, 0x8f, 0xbf, 0x8a, 0x24, 0x7d, 0x98, 0xec,
334 0x7f, 0x77, 0x49, 0x38, 0x42, 0x81, 0x26, 0x7f, 0xed, 0x38};
336 SHA256HashValue fingerprint
=
337 X509Certificate::CalculateFingerprint256(google_cert
->os_cert_handle());
339 for (size_t i
= 0; i
< 32; ++i
)
340 EXPECT_EQ(google_sha256_fingerprint
[i
], fingerprint
.data
[i
]);
343 TEST(X509CertificateTest
, CAFingerprints
) {
344 base::FilePath certs_dir
= GetTestCertsDirectory();
346 scoped_refptr
<X509Certificate
> server_cert
=
347 ImportCertFromFile(certs_dir
, "salesforce_com_test.pem");
348 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), server_cert
.get());
350 scoped_refptr
<X509Certificate
> intermediate_cert1
=
351 ImportCertFromFile(certs_dir
, "verisign_intermediate_ca_2011.pem");
352 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), intermediate_cert1
.get());
354 scoped_refptr
<X509Certificate
> intermediate_cert2
=
355 ImportCertFromFile(certs_dir
, "verisign_intermediate_ca_2016.pem");
356 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), intermediate_cert2
.get());
358 X509Certificate::OSCertHandles intermediates
;
359 intermediates
.push_back(intermediate_cert1
->os_cert_handle());
360 scoped_refptr
<X509Certificate
> cert_chain1
=
361 X509Certificate::CreateFromHandle(server_cert
->os_cert_handle(),
364 intermediates
.clear();
365 intermediates
.push_back(intermediate_cert2
->os_cert_handle());
366 scoped_refptr
<X509Certificate
> cert_chain2
=
367 X509Certificate::CreateFromHandle(server_cert
->os_cert_handle(),
370 // No intermediate CA certicates.
371 intermediates
.clear();
372 scoped_refptr
<X509Certificate
> cert_chain3
=
373 X509Certificate::CreateFromHandle(server_cert
->os_cert_handle(),
376 static const uint8 cert_chain1_ca_fingerprint
[20] = {
377 0xc2, 0xf0, 0x08, 0x7d, 0x01, 0xe6, 0x86, 0x05, 0x3a, 0x4d,
378 0x63, 0x3e, 0x7e, 0x70, 0xd4, 0xef, 0x65, 0xc2, 0xcc, 0x4f
380 static const uint8 cert_chain2_ca_fingerprint
[20] = {
381 0xd5, 0x59, 0xa5, 0x86, 0x66, 0x9b, 0x08, 0xf4, 0x6a, 0x30,
382 0xa1, 0x33, 0xf8, 0xa9, 0xed, 0x3d, 0x03, 0x8e, 0x2e, 0xa8
384 // The SHA-1 hash of nothing.
385 static const uint8 cert_chain3_ca_fingerprint
[20] = {
386 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55,
387 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09
389 EXPECT_TRUE(memcmp(cert_chain1
->ca_fingerprint().data
,
390 cert_chain1_ca_fingerprint
, 20) == 0);
391 EXPECT_TRUE(memcmp(cert_chain2
->ca_fingerprint().data
,
392 cert_chain2_ca_fingerprint
, 20) == 0);
393 EXPECT_TRUE(memcmp(cert_chain3
->ca_fingerprint().data
,
394 cert_chain3_ca_fingerprint
, 20) == 0);
396 // Test the SHA-256 hash calculation functions explicitly since they are not
397 // used by X509Certificate internally.
398 static const uint8 cert_chain1_ca_fingerprint_256
[32] = {
399 0x51, 0x15, 0x30, 0x49, 0x97, 0x54, 0xf8, 0xb4, 0x17, 0x41,
400 0x6b, 0x58, 0x78, 0xb0, 0x89, 0xd2, 0xc3, 0xae, 0x66, 0xc1,
401 0x16, 0x80, 0xa0, 0x78, 0xe7, 0x53, 0x45, 0xa2, 0xfb, 0x80,
404 static const uint8 cert_chain2_ca_fingerprint_256
[32] = {
405 0x00, 0xbd, 0x2b, 0x0e, 0xdd, 0x83, 0x40, 0xb1, 0x74, 0x6c,
406 0xc3, 0x95, 0xc0, 0xe3, 0x55, 0xb2, 0x16, 0x58, 0x53, 0xfd,
407 0xb9, 0x3c, 0x52, 0xda, 0xdd, 0xa8, 0x22, 0x8b, 0x07, 0x00,
410 // The SHA-256 hash of nothing.
411 static const uint8 cert_chain3_ca_fingerprint_256
[32] = {
412 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb,
413 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4,
414 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52,
417 SHA256HashValue ca_fingerprint_256_1
=
418 X509Certificate::CalculateCAFingerprint256(
419 cert_chain1
->GetIntermediateCertificates());
420 SHA256HashValue ca_fingerprint_256_2
=
421 X509Certificate::CalculateCAFingerprint256(
422 cert_chain2
->GetIntermediateCertificates());
423 SHA256HashValue ca_fingerprint_256_3
=
424 X509Certificate::CalculateCAFingerprint256(
425 cert_chain3
->GetIntermediateCertificates());
426 EXPECT_TRUE(memcmp(ca_fingerprint_256_1
.data
,
427 cert_chain1_ca_fingerprint_256
, 32) == 0);
428 EXPECT_TRUE(memcmp(ca_fingerprint_256_2
.data
,
429 cert_chain2_ca_fingerprint_256
, 32) == 0);
430 EXPECT_TRUE(memcmp(ca_fingerprint_256_3
.data
,
431 cert_chain3_ca_fingerprint_256
, 32) == 0);
433 static const uint8 cert_chain1_chain_fingerprint_256
[32] = {
434 0xac, 0xff, 0xcc, 0x63, 0x0d, 0xd0, 0xa7, 0x19, 0x78, 0xb5,
435 0x8a, 0x47, 0x8b, 0x67, 0x97, 0xcb, 0x8d, 0xe1, 0x6a, 0x8a,
436 0x57, 0x70, 0xda, 0x9a, 0x53, 0x72, 0xe2, 0xa0, 0x08, 0xab,
439 static const uint8 cert_chain2_chain_fingerprint_256
[32] = {
440 0x67, 0x3a, 0x11, 0x20, 0xd6, 0x94, 0x14, 0xe4, 0x16, 0x9f,
441 0x58, 0xe2, 0x8b, 0xf7, 0x27, 0xed, 0xbb, 0xe8, 0xa7, 0xff,
442 0x1c, 0x8c, 0x0f, 0x21, 0x38, 0x16, 0x7c, 0xad, 0x1f, 0x22,
445 static const uint8 cert_chain3_chain_fingerprint_256
[32] = {
446 0x16, 0x7a, 0xbd, 0xb4, 0x57, 0x04, 0x65, 0x3c, 0x3b, 0xef,
447 0x6e, 0x6a, 0xa6, 0x02, 0x73, 0x30, 0x3e, 0x34, 0x1b, 0x43,
448 0xc2, 0x7c, 0x98, 0x52, 0x9f, 0x34, 0x7f, 0x55, 0x97, 0xe9,
451 SHA256HashValue chain_fingerprint_256_1
=
452 X509Certificate::CalculateChainFingerprint256(
453 cert_chain1
->os_cert_handle(),
454 cert_chain1
->GetIntermediateCertificates());
455 SHA256HashValue chain_fingerprint_256_2
=
456 X509Certificate::CalculateChainFingerprint256(
457 cert_chain2
->os_cert_handle(),
458 cert_chain2
->GetIntermediateCertificates());
459 SHA256HashValue chain_fingerprint_256_3
=
460 X509Certificate::CalculateChainFingerprint256(
461 cert_chain3
->os_cert_handle(),
462 cert_chain3
->GetIntermediateCertificates());
463 EXPECT_TRUE(memcmp(chain_fingerprint_256_1
.data
,
464 cert_chain1_chain_fingerprint_256
, 32) == 0);
465 EXPECT_TRUE(memcmp(chain_fingerprint_256_2
.data
,
466 cert_chain2_chain_fingerprint_256
, 32) == 0);
467 EXPECT_TRUE(memcmp(chain_fingerprint_256_3
.data
,
468 cert_chain3_chain_fingerprint_256
, 32) == 0);
471 TEST(X509CertificateTest
, ParseSubjectAltNames
) {
472 base::FilePath certs_dir
= GetTestCertsDirectory();
474 scoped_refptr
<X509Certificate
> san_cert
=
475 ImportCertFromFile(certs_dir
, "subjectAltName_sanity_check.pem");
476 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), san_cert
.get());
478 std::vector
<std::string
> dns_names
;
479 std::vector
<std::string
> ip_addresses
;
480 san_cert
->GetSubjectAltName(&dns_names
, &ip_addresses
);
482 // Ensure that DNS names are correctly parsed.
483 ASSERT_EQ(1U, dns_names
.size());
484 EXPECT_EQ("test.example", dns_names
[0]);
486 // Ensure that both IPv4 and IPv6 addresses are correctly parsed.
487 ASSERT_EQ(2U, ip_addresses
.size());
489 static const uint8 kIPv4Address
[] = {
490 0x7F, 0x00, 0x00, 0x02
492 ASSERT_EQ(arraysize(kIPv4Address
), ip_addresses
[0].size());
493 EXPECT_EQ(0, memcmp(ip_addresses
[0].data(), kIPv4Address
,
494 arraysize(kIPv4Address
)));
496 static const uint8 kIPv6Address
[] = {
497 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
498 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
500 ASSERT_EQ(arraysize(kIPv6Address
), ip_addresses
[1].size());
501 EXPECT_EQ(0, memcmp(ip_addresses
[1].data(), kIPv6Address
,
502 arraysize(kIPv6Address
)));
504 // Ensure the subjectAltName dirName has not influenced the handling of
505 // the subject commonName.
506 EXPECT_EQ("127.0.0.1", san_cert
->subject().common_name
);
509 TEST(X509CertificateTest
, ExtractSPKIFromDERCert
) {
510 base::FilePath certs_dir
= GetTestCertsDirectory();
511 scoped_refptr
<X509Certificate
> cert
=
512 ImportCertFromFile(certs_dir
, "nist.der");
513 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), cert
.get());
515 std::string derBytes
;
516 EXPECT_TRUE(X509Certificate::GetDEREncoded(cert
->os_cert_handle(),
519 base::StringPiece spkiBytes
;
520 EXPECT_TRUE(asn1::ExtractSPKIFromDERCert(derBytes
, &spkiBytes
));
522 uint8 hash
[base::kSHA1Length
];
523 base::SHA1HashBytes(reinterpret_cast<const uint8
*>(spkiBytes
.data()),
524 spkiBytes
.size(), hash
);
526 EXPECT_EQ(0, memcmp(hash
, kNistSPKIHash
, sizeof(hash
)));
529 TEST(X509CertificateTest
, ExtractCRLURLsFromDERCert
) {
530 base::FilePath certs_dir
= GetTestCertsDirectory();
531 scoped_refptr
<X509Certificate
> cert
=
532 ImportCertFromFile(certs_dir
, "nist.der");
533 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), cert
.get());
535 std::string derBytes
;
536 EXPECT_TRUE(X509Certificate::GetDEREncoded(cert
->os_cert_handle(),
539 std::vector
<base::StringPiece
> crl_urls
;
540 EXPECT_TRUE(asn1::ExtractCRLURLsFromDERCert(derBytes
, &crl_urls
));
542 EXPECT_EQ(1u, crl_urls
.size());
543 if (crl_urls
.size() > 0) {
544 EXPECT_EQ("http://SVRSecure-G3-crl.verisign.com/SVRSecureG3.crl",
545 crl_urls
[0].as_string());
549 // Tests X509CertificateCache via X509Certificate::CreateFromHandle. We
550 // call X509Certificate::CreateFromHandle several times and observe whether
551 // it returns a cached or new OSCertHandle.
552 TEST(X509CertificateTest
, Cache
) {
553 X509Certificate::OSCertHandle google_cert_handle
;
554 X509Certificate::OSCertHandle thawte_cert_handle
;
556 // Add a single certificate to the certificate cache.
557 google_cert_handle
= X509Certificate::CreateOSCertHandleFromBytes(
558 reinterpret_cast<const char*>(google_der
), sizeof(google_der
));
559 scoped_refptr
<X509Certificate
> cert1(X509Certificate::CreateFromHandle(
560 google_cert_handle
, X509Certificate::OSCertHandles()));
561 X509Certificate::FreeOSCertHandle(google_cert_handle
);
563 // Add the same certificate, but as a new handle.
564 google_cert_handle
= X509Certificate::CreateOSCertHandleFromBytes(
565 reinterpret_cast<const char*>(google_der
), sizeof(google_der
));
566 scoped_refptr
<X509Certificate
> cert2(X509Certificate::CreateFromHandle(
567 google_cert_handle
, X509Certificate::OSCertHandles()));
568 X509Certificate::FreeOSCertHandle(google_cert_handle
);
570 // A new X509Certificate should be returned.
571 EXPECT_NE(cert1
.get(), cert2
.get());
572 // But both instances should share the underlying OS certificate handle.
573 EXPECT_EQ(cert1
->os_cert_handle(), cert2
->os_cert_handle());
574 EXPECT_EQ(0u, cert1
->GetIntermediateCertificates().size());
575 EXPECT_EQ(0u, cert2
->GetIntermediateCertificates().size());
577 // Add the same certificate, but this time with an intermediate. This
578 // should result in the intermediate being cached. Note that this is not
579 // a legitimate chain, but is suitable for testing.
580 google_cert_handle
= X509Certificate::CreateOSCertHandleFromBytes(
581 reinterpret_cast<const char*>(google_der
), sizeof(google_der
));
582 thawte_cert_handle
= X509Certificate::CreateOSCertHandleFromBytes(
583 reinterpret_cast<const char*>(thawte_der
), sizeof(thawte_der
));
584 X509Certificate::OSCertHandles intermediates
;
585 intermediates
.push_back(thawte_cert_handle
);
586 scoped_refptr
<X509Certificate
> cert3(X509Certificate::CreateFromHandle(
587 google_cert_handle
, intermediates
));
588 X509Certificate::FreeOSCertHandle(google_cert_handle
);
589 X509Certificate::FreeOSCertHandle(thawte_cert_handle
);
591 // Test that the new certificate, even with intermediates, results in the
592 // same underlying handle being used.
593 EXPECT_EQ(cert1
->os_cert_handle(), cert3
->os_cert_handle());
594 // Though they use the same OS handle, the intermediates should be different.
595 EXPECT_NE(cert1
->GetIntermediateCertificates().size(),
596 cert3
->GetIntermediateCertificates().size());
599 TEST(X509CertificateTest
, Pickle
) {
600 X509Certificate::OSCertHandle google_cert_handle
=
601 X509Certificate::CreateOSCertHandleFromBytes(
602 reinterpret_cast<const char*>(google_der
), sizeof(google_der
));
603 X509Certificate::OSCertHandle thawte_cert_handle
=
604 X509Certificate::CreateOSCertHandleFromBytes(
605 reinterpret_cast<const char*>(thawte_der
), sizeof(thawte_der
));
607 X509Certificate::OSCertHandles intermediates
;
608 intermediates
.push_back(thawte_cert_handle
);
609 scoped_refptr
<X509Certificate
> cert
= X509Certificate::CreateFromHandle(
610 google_cert_handle
, intermediates
);
611 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), cert
.get());
613 X509Certificate::FreeOSCertHandle(google_cert_handle
);
614 X509Certificate::FreeOSCertHandle(thawte_cert_handle
);
617 cert
->Persist(&pickle
);
619 PickleIterator
iter(pickle
);
620 scoped_refptr
<X509Certificate
> cert_from_pickle
=
621 X509Certificate::CreateFromPickle(
622 pickle
, &iter
, X509Certificate::PICKLETYPE_CERTIFICATE_CHAIN_V3
);
623 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), cert_from_pickle
.get());
624 EXPECT_TRUE(X509Certificate::IsSameOSCert(
625 cert
->os_cert_handle(), cert_from_pickle
->os_cert_handle()));
626 const X509Certificate::OSCertHandles
& cert_intermediates
=
627 cert
->GetIntermediateCertificates();
628 const X509Certificate::OSCertHandles
& pickle_intermediates
=
629 cert_from_pickle
->GetIntermediateCertificates();
630 ASSERT_EQ(cert_intermediates
.size(), pickle_intermediates
.size());
631 for (size_t i
= 0; i
< cert_intermediates
.size(); ++i
) {
632 EXPECT_TRUE(X509Certificate::IsSameOSCert(cert_intermediates
[i
],
633 pickle_intermediates
[i
]));
637 TEST(X509CertificateTest
, IntermediateCertificates
) {
638 scoped_refptr
<X509Certificate
> webkit_cert(
639 X509Certificate::CreateFromBytes(
640 reinterpret_cast<const char*>(webkit_der
), sizeof(webkit_der
)));
642 scoped_refptr
<X509Certificate
> thawte_cert(
643 X509Certificate::CreateFromBytes(
644 reinterpret_cast<const char*>(thawte_der
), sizeof(thawte_der
)));
646 X509Certificate::OSCertHandle google_handle
;
647 // Create object with no intermediates:
648 google_handle
= X509Certificate::CreateOSCertHandleFromBytes(
649 reinterpret_cast<const char*>(google_der
), sizeof(google_der
));
650 X509Certificate::OSCertHandles intermediates1
;
651 scoped_refptr
<X509Certificate
> cert1
;
652 cert1
= X509Certificate::CreateFromHandle(google_handle
, intermediates1
);
653 EXPECT_EQ(0u, cert1
->GetIntermediateCertificates().size());
655 // Create object with 2 intermediates:
656 X509Certificate::OSCertHandles intermediates2
;
657 intermediates2
.push_back(webkit_cert
->os_cert_handle());
658 intermediates2
.push_back(thawte_cert
->os_cert_handle());
659 scoped_refptr
<X509Certificate
> cert2
;
660 cert2
= X509Certificate::CreateFromHandle(google_handle
, intermediates2
);
662 // Verify it has all the intermediates:
663 const X509Certificate::OSCertHandles
& cert2_intermediates
=
664 cert2
->GetIntermediateCertificates();
665 ASSERT_EQ(2u, cert2_intermediates
.size());
666 EXPECT_TRUE(X509Certificate::IsSameOSCert(cert2_intermediates
[0],
667 webkit_cert
->os_cert_handle()));
668 EXPECT_TRUE(X509Certificate::IsSameOSCert(cert2_intermediates
[1],
669 thawte_cert
->os_cert_handle()));
672 X509Certificate::FreeOSCertHandle(google_handle
);
675 TEST(X509CertificateTest
, IsIssuedByEncoded
) {
676 base::FilePath certs_dir
= GetTestCertsDirectory();
678 // Test a client certificate from MIT.
679 scoped_refptr
<X509Certificate
> mit_davidben_cert(
680 ImportCertFromFile(certs_dir
, "mit.davidben.der"));
681 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), mit_davidben_cert
.get());
683 std::string
mit_issuer(reinterpret_cast<const char*>(MITDN
),
686 // Test a certificate from Google, issued by Thawte
687 scoped_refptr
<X509Certificate
> google_cert(
688 ImportCertFromFile(certs_dir
, "google.single.der"));
689 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), google_cert
.get());
691 std::string
thawte_issuer(reinterpret_cast<const char*>(ThawteDN
),
694 // Check that the David Ben certificate is issued by MIT, but not
696 std::vector
<std::string
> issuers
;
698 issuers
.push_back(mit_issuer
);
699 EXPECT_TRUE(mit_davidben_cert
->IsIssuedByEncoded(issuers
));
700 EXPECT_FALSE(google_cert
->IsIssuedByEncoded(issuers
));
702 // Check that the Google certificate is issued by Thawte and not
705 issuers
.push_back(thawte_issuer
);
706 EXPECT_FALSE(mit_davidben_cert
->IsIssuedByEncoded(issuers
));
707 EXPECT_TRUE(google_cert
->IsIssuedByEncoded(issuers
));
709 // Check that they both pass when given a list of the two issuers.
711 issuers
.push_back(mit_issuer
);
712 issuers
.push_back(thawte_issuer
);
713 EXPECT_TRUE(mit_davidben_cert
->IsIssuedByEncoded(issuers
));
714 EXPECT_TRUE(google_cert
->IsIssuedByEncoded(issuers
));
717 TEST(X509CertificateTest
, IsIssuedByEncodedWithIntermediates
) {
718 static const unsigned char kPolicyRootDN
[] = {
719 0x30, 0x1e, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
720 0x13, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x54, 0x65, 0x73, 0x74,
721 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41
723 static const unsigned char kPolicyIntermediateDN
[] = {
724 0x30, 0x26, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
725 0x1b, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x54, 0x65, 0x73, 0x74,
726 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74,
727 0x65, 0x20, 0x43, 0x41
730 base::FilePath certs_dir
= GetTestCertsDirectory();
732 CertificateList policy_chain
= CreateCertificateListFromFile(
733 certs_dir
, "explicit-policy-chain.pem", X509Certificate::FORMAT_AUTO
);
734 ASSERT_EQ(3u, policy_chain
.size());
736 // The intermediate CA certificate's policyConstraints extension has a
737 // requireExplicitPolicy field with SkipCerts=0.
738 std::string
policy_intermediate_dn(
739 reinterpret_cast<const char*>(kPolicyIntermediateDN
),
740 sizeof(kPolicyIntermediateDN
));
741 std::string
policy_root_dn(reinterpret_cast<const char*>(kPolicyRootDN
),
742 sizeof(kPolicyRootDN
));
744 X509Certificate::OSCertHandles intermediates
;
745 intermediates
.push_back(policy_chain
[1]->os_cert_handle());
746 scoped_refptr
<X509Certificate
> cert_chain
=
747 X509Certificate::CreateFromHandle(policy_chain
[0]->os_cert_handle(),
750 std::vector
<std::string
> issuers
;
752 // Check that the chain is issued by the intermediate.
754 issuers
.push_back(policy_intermediate_dn
);
755 EXPECT_TRUE(cert_chain
->IsIssuedByEncoded(issuers
));
757 // Check that the chain is also issued by the root.
759 issuers
.push_back(policy_root_dn
);
760 EXPECT_TRUE(cert_chain
->IsIssuedByEncoded(issuers
));
762 // Check that the chain is issued by either the intermediate or the root.
764 issuers
.push_back(policy_intermediate_dn
);
765 issuers
.push_back(policy_root_dn
);
766 EXPECT_TRUE(cert_chain
->IsIssuedByEncoded(issuers
));
768 // Check that an empty issuers list returns false.
770 EXPECT_FALSE(cert_chain
->IsIssuedByEncoded(issuers
));
772 // Check that the chain is not issued by Verisign
773 std::string
mit_issuer(reinterpret_cast<const char*>(VerisignDN
),
776 issuers
.push_back(mit_issuer
);
777 EXPECT_FALSE(cert_chain
->IsIssuedByEncoded(issuers
));
780 // Tests that FreeOSCertHandle ignores NULL on each OS.
781 TEST(X509CertificateTest
, FreeNullHandle
) {
782 X509Certificate::FreeOSCertHandle(NULL
);
786 TEST(X509CertificateTest
, GetDefaultNickname
) {
787 base::FilePath certs_dir
= GetTestCertsDirectory();
789 scoped_refptr
<X509Certificate
> test_cert(
790 ImportCertFromFile(certs_dir
, "no_subject_common_name_cert.pem"));
791 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), test_cert
.get());
793 std::string nickname
= test_cert
->GetDefaultNickname(USER_CERT
);
794 EXPECT_EQ("wtc@google.com's COMODO Client Authentication and "
795 "Secure Email CA ID", nickname
);
799 const struct CertificateFormatTestData
{
800 const char* file_name
;
801 X509Certificate::Format format
;
802 uint8
* chain_fingerprints
[3];
803 } kFormatTestData
[] = {
804 // DER Parsing - single certificate, DER encoded
805 { "google.single.der", X509Certificate::FORMAT_SINGLE_CERTIFICATE
,
806 { google_parse_fingerprint
,
808 // DER parsing - single certificate, PEM encoded
809 { "google.single.pem", X509Certificate::FORMAT_SINGLE_CERTIFICATE
,
810 { google_parse_fingerprint
,
812 // PEM parsing - single certificate, PEM encoded with a PEB of
814 { "google.single.pem", X509Certificate::FORMAT_PEM_CERT_SEQUENCE
,
815 { google_parse_fingerprint
,
817 // PEM parsing - sequence of certificates, PEM encoded with a PEB of
819 { "google.chain.pem", X509Certificate::FORMAT_PEM_CERT_SEQUENCE
,
820 { google_parse_fingerprint
,
821 thawte_parse_fingerprint
,
823 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, DER
825 { "google.binary.p7b", X509Certificate::FORMAT_PKCS7
,
826 { google_parse_fingerprint
,
827 thawte_parse_fingerprint
,
829 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, PEM
830 // encoded with a PEM PEB of "CERTIFICATE"
831 { "google.pem_cert.p7b", X509Certificate::FORMAT_PKCS7
,
832 { google_parse_fingerprint
,
833 thawte_parse_fingerprint
,
835 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, PEM
836 // encoded with a PEM PEB of "PKCS7"
837 { "google.pem_pkcs7.p7b", X509Certificate::FORMAT_PKCS7
,
838 { google_parse_fingerprint
,
839 thawte_parse_fingerprint
,
841 // All of the above, this time using auto-detection
842 { "google.single.der", X509Certificate::FORMAT_AUTO
,
843 { google_parse_fingerprint
,
845 { "google.single.pem", X509Certificate::FORMAT_AUTO
,
846 { google_parse_fingerprint
,
848 { "google.chain.pem", X509Certificate::FORMAT_AUTO
,
849 { google_parse_fingerprint
,
850 thawte_parse_fingerprint
,
852 { "google.binary.p7b", X509Certificate::FORMAT_AUTO
,
853 { google_parse_fingerprint
,
854 thawte_parse_fingerprint
,
856 { "google.pem_cert.p7b", X509Certificate::FORMAT_AUTO
,
857 { google_parse_fingerprint
,
858 thawte_parse_fingerprint
,
860 { "google.pem_pkcs7.p7b", X509Certificate::FORMAT_AUTO
,
861 { google_parse_fingerprint
,
862 thawte_parse_fingerprint
,
866 class X509CertificateParseTest
867 : public testing::TestWithParam
<CertificateFormatTestData
> {
869 virtual ~X509CertificateParseTest() {}
870 void SetUp() override
{ test_data_
= GetParam(); }
871 void TearDown() override
{}
874 CertificateFormatTestData test_data_
;
877 TEST_P(X509CertificateParseTest
, CanParseFormat
) {
878 base::FilePath certs_dir
= GetTestCertsDirectory();
879 CertificateList certs
= CreateCertificateListFromFile(
880 certs_dir
, test_data_
.file_name
, test_data_
.format
);
881 ASSERT_FALSE(certs
.empty());
882 ASSERT_LE(certs
.size(), arraysize(test_data_
.chain_fingerprints
));
883 CheckGoogleCert(certs
.front(), google_parse_fingerprint
,
884 kGoogleParseValidFrom
, kGoogleParseValidTo
);
887 for (i
= 0; i
< arraysize(test_data_
.chain_fingerprints
); ++i
) {
888 if (test_data_
.chain_fingerprints
[i
] == NULL
) {
889 // No more test certificates expected - make sure no more were
890 // returned before marking this test a success.
891 EXPECT_EQ(i
, certs
.size());
895 // A cert is expected - make sure that one was parsed.
896 ASSERT_LT(i
, certs
.size());
898 // Compare the parsed certificate with the expected certificate, by
899 // comparing fingerprints.
900 const X509Certificate
* cert
= certs
[i
].get();
901 const SHA1HashValue
& actual_fingerprint
= cert
->fingerprint();
902 uint8
* expected_fingerprint
= test_data_
.chain_fingerprints
[i
];
904 for (size_t j
= 0; j
< 20; ++j
)
905 EXPECT_EQ(expected_fingerprint
[j
], actual_fingerprint
.data
[j
]);
909 INSTANTIATE_TEST_CASE_P(, X509CertificateParseTest
,
910 testing::ValuesIn(kFormatTestData
));
912 struct CertificateNameVerifyTestData
{
913 // true iff we expect hostname to match an entry in cert_names.
915 // The hostname to match.
916 const char* hostname
;
917 // Common name, may be used if |dns_names| or |ip_addrs| are empty.
918 const char* common_name
;
919 // Comma separated list of certificate names to match against. Any occurrence
920 // of '#' will be replaced with a null character before processing.
921 const char* dns_names
;
922 // Comma separated list of certificate IP Addresses to match against. Each
923 // address is x prefixed 16 byte hex code for v6 or dotted-decimals for v4.
924 const char* ip_addrs
;
927 // GTest 'magic' pretty-printer, so that if/when a test fails, it knows how
928 // to output the parameter that was passed. Without this, it will simply
929 // attempt to print out the first twenty bytes of the object, which depending
930 // on platform and alignment, may result in an invalid read.
931 void PrintTo(const CertificateNameVerifyTestData
& data
, std::ostream
* os
) {
932 ASSERT_TRUE(data
.hostname
&& data
.common_name
);
933 // Using StringPiece to allow for optional fields being NULL.
934 *os
<< " expected: " << data
.expected
935 << "; hostname: " << data
.hostname
936 << "; common_name: " << data
.common_name
937 << "; dns_names: " << base::StringPiece(data
.dns_names
)
938 << "; ip_addrs: " << base::StringPiece(data
.ip_addrs
);
941 const CertificateNameVerifyTestData kNameVerifyTestData
[] = {
942 { true, "foo.com", "foo.com" },
945 { true, "bar.foo.com", "*.foo.com" },
946 { true, "www.test.fr", "common.name",
947 "*.test.com,*.test.co.uk,*.test.de,*.test.fr" },
948 { true, "wwW.tESt.fr", "common.name",
949 ",*.*,*.test.de,*.test.FR,www" },
950 { false, "f.uk", ".uk" },
951 { false, "w.bar.foo.com", "?.bar.foo.com" },
952 { false, "www.foo.com", "(www|ftp).foo.com" },
953 { false, "www.foo.com", "www.foo.com#" }, // # = null char.
954 { false, "www.foo.com", "", "www.foo.com#*.foo.com,#,#" },
955 { false, "www.house.example", "ww.house.example" },
956 { false, "test.org", "", "www.test.org,*.test.org,*.org" },
957 { false, "w.bar.foo.com", "w*.bar.foo.com" },
958 { false, "www.bar.foo.com", "ww*ww.bar.foo.com" },
959 { false, "wwww.bar.foo.com", "ww*ww.bar.foo.com" },
960 { true, "wwww.bar.foo.com", "w*w.bar.foo.com" },
961 { false, "wwww.bar.foo.com", "w*w.bar.foo.c0m" },
962 { true, "WALLY.bar.foo.com", "wa*.bar.foo.com" },
963 { true, "wally.bar.foo.com", "*Ly.bar.foo.com" },
964 { true, "ww%57.foo.com", "", "www.foo.com" },
965 { true, "www&.foo.com", "www%26.foo.com" },
966 // Common name must not be used if subject alternative name was provided.
967 { false, "www.test.co.jp", "www.test.co.jp",
968 "*.test.de,*.jp,www.test.co.uk,www.*.co.jp" },
969 { false, "www.bar.foo.com", "www.bar.foo.com",
970 "*.foo.com,*.*.foo.com,*.*.bar.foo.com,*..bar.foo.com," },
971 { false, "www.bath.org", "www.bath.org", "", "20.30.40.50" },
972 { false, "66.77.88.99", "www.bath.org", "www.bath.org" },
974 { true, "xn--poema-9qae5a.com.br", "xn--poema-9qae5a.com.br" },
975 { true, "www.xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br" },
976 { false, "xn--poema-9qae5a.com.br", "", "*.xn--poema-9qae5a.com.br,"
977 "xn--poema-*.com.br,"
978 "xn--*-9qae5a.com.br,"
979 "*--poema-9qae5a.com.br" },
980 // The following are adapted from the examples quoted from
981 // http://tools.ietf.org/html/rfc6125#section-6.4.3
982 // (e.g., *.example.com would match foo.example.com but
983 // not bar.foo.example.com or example.com).
984 { true, "foo.example.com", "*.example.com" },
985 { false, "bar.foo.example.com", "*.example.com" },
986 { false, "example.com", "*.example.com" },
987 // (e.g., baz*.example.net and *baz.example.net and b*z.example.net would
988 // be taken to match baz1.example.net and foobaz.example.net and
989 // buzz.example.net, respectively
990 { true, "baz1.example.net", "baz*.example.net" },
991 { true, "foobaz.example.net", "*baz.example.net" },
992 { true, "buzz.example.net", "b*z.example.net" },
993 // Wildcards should not be valid for public registry controlled domains,
994 // and unknown/unrecognized domains, at least three domain components must
996 { true, "www.test.example", "*.test.example" },
997 { true, "test.example.co.uk", "*.example.co.uk" },
998 { false, "test.example", "*.exmaple" },
999 { false, "example.co.uk", "*.co.uk" },
1000 { false, "foo.com", "*.com" },
1001 { false, "foo.us", "*.us" },
1002 { false, "foo", "*" },
1003 // IDN variants of wildcards and registry controlled domains.
1004 { true, "www.xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br" },
1005 { true, "test.example.xn--mgbaam7a8h", "*.example.xn--mgbaam7a8h" },
1006 { false, "xn--poema-9qae5a.com.br", "*.com.br" },
1007 { false, "example.xn--mgbaam7a8h", "*.xn--mgbaam7a8h" },
1008 // Wildcards should be permissible for 'private' registry controlled
1010 { true, "www.appspot.com", "*.appspot.com" },
1011 { true, "foo.s3.amazonaws.com", "*.s3.amazonaws.com" },
1012 // Multiple wildcards are not valid.
1013 { false, "foo.example.com", "*.*.com" },
1014 { false, "foo.bar.example.com", "*.bar.*.com" },
1015 // Absolute vs relative DNS name tests. Although not explicitly specified
1016 // in RFC 6125, absolute reference names (those ending in a .) should
1017 // match either absolute or relative presented names.
1018 { true, "foo.com", "foo.com." },
1019 { true, "foo.com.", "foo.com" },
1020 { true, "foo.com.", "foo.com." },
1021 { true, "f", "f." },
1022 { true, "f.", "f" },
1023 { true, "f.", "f." },
1024 { true, "www-3.bar.foo.com", "*.bar.foo.com." },
1025 { true, "www-3.bar.foo.com.", "*.bar.foo.com" },
1026 { true, "www-3.bar.foo.com.", "*.bar.foo.com." },
1027 { false, ".", "." },
1028 { false, "example.com", "*.com." },
1029 { false, "example.com.", "*.com" },
1030 { false, "example.com.", "*.com." },
1031 { false, "foo.", "*." },
1032 { false, "foo", "*." },
1033 { false, "foo.co.uk", "*.co.uk." },
1034 { false, "foo.co.uk.", "*.co.uk." },
1035 // IP addresses in common name; IPv4 only.
1036 { true, "127.0.0.1", "127.0.0.1" },
1037 { true, "192.168.1.1", "192.168.1.1" },
1038 { true, "676768", "0.10.83.160" },
1039 { true, "1.2.3", "1.2.0.3" },
1040 { false, "192.169.1.1", "192.168.1.1" },
1041 { false, "12.19.1.1", "12.19.1.1/255.255.255.0" },
1042 { false, "FEDC:ba98:7654:3210:FEDC:BA98:7654:3210",
1043 "FEDC:BA98:7654:3210:FEDC:ba98:7654:3210" },
1044 { false, "1111:2222:3333:4444:5555:6666:7777:8888",
1045 "1111:2222:3333:4444:5555:6666:7777:8888" },
1046 { false, "::192.9.5.5", "[::192.9.5.5]" },
1047 // No wildcard matching in valid IP addresses
1048 { false, "::192.9.5.5", "*.9.5.5" },
1049 { false, "2010:836B:4179::836B:4179", "*:836B:4179::836B:4179" },
1050 { false, "192.168.1.11", "*.168.1.11" },
1051 { false, "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210", "*.]" },
1052 // IP addresses in subject alternative name (common name ignored)
1053 { true, "10.1.2.3", "", "", "10.1.2.3" },
1054 { true, "14.15", "", "", "14.0.0.15" },
1055 { false, "10.1.2.7", "10.1.2.7", "", "10.1.2.6,10.1.2.8" },
1056 { false, "10.1.2.8", "10.20.2.8", "foo" },
1057 { true, "::4.5.6.7", "", "", "x00000000000000000000000004050607" },
1058 { false, "::6.7.8.9", "::6.7.8.9", "::6.7.8.9",
1059 "x00000000000000000000000006070808,x0000000000000000000000000607080a,"
1060 "xff000000000000000000000006070809,6.7.8.9" },
1061 { true, "FE80::200:f8ff:fe21:67cf", "no.common.name", "",
1062 "x00000000000000000000000006070808,xfe800000000000000200f8fffe2167cf,"
1063 "xff0000000000000000000000060708ff,10.0.0.1" },
1064 // Numeric only hostnames (none of these are considered valid IP addresses).
1065 { false, "12345.6", "12345.6" },
1066 { false, "121.2.3.512", "", "1*1.2.3.512,*1.2.3.512,1*.2.3.512,*.2.3.512",
1068 { false, "1.2.3.4.5.6", "*.2.3.4.5.6" },
1069 { true, "1.2.3.4.5", "", "1.2.3.4.5" },
1070 // Invalid host names.
1071 { false, "junk)(£)$*!@~#", "junk)(£)$*!@~#" },
1072 { false, "www.*.com", "www.*.com" },
1073 { false, "w$w.f.com", "w$w.f.com" },
1074 { false, "nocolonallowed:example", "", "nocolonallowed:example" },
1075 { false, "www-1.[::FFFF:129.144.52.38]", "*.[::FFFF:129.144.52.38]" },
1076 { false, "[::4.5.6.9]", "", "", "x00000000000000000000000004050609" },
1079 class X509CertificateNameVerifyTest
1080 : public testing::TestWithParam
<CertificateNameVerifyTestData
> {
1083 TEST_P(X509CertificateNameVerifyTest
, VerifyHostname
) {
1084 CertificateNameVerifyTestData test_data
= GetParam();
1086 std::string
common_name(test_data
.common_name
);
1087 ASSERT_EQ(std::string::npos
, common_name
.find(','));
1088 std::replace(common_name
.begin(), common_name
.end(), '#', '\0');
1090 std::vector
<std::string
> dns_names
, ip_addressses
;
1091 if (test_data
.dns_names
) {
1092 // Build up the certificate DNS names list.
1093 std::string
dns_name_line(test_data
.dns_names
);
1094 std::replace(dns_name_line
.begin(), dns_name_line
.end(), '#', '\0');
1095 base::SplitString(dns_name_line
, ',', &dns_names
);
1098 if (test_data
.ip_addrs
) {
1099 // Build up the certificate IP address list.
1100 std::string
ip_addrs_line(test_data
.ip_addrs
);
1101 std::vector
<std::string
> ip_addressses_ascii
;
1102 base::SplitString(ip_addrs_line
, ',', &ip_addressses_ascii
);
1103 for (size_t i
= 0; i
< ip_addressses_ascii
.size(); ++i
) {
1104 std::string
& addr_ascii
= ip_addressses_ascii
[i
];
1105 ASSERT_NE(0U, addr_ascii
.length());
1106 if (addr_ascii
[0] == 'x') { // Hex encoded address
1107 addr_ascii
.erase(0, 1);
1108 std::vector
<uint8
> bytes
;
1109 EXPECT_TRUE(base::HexStringToBytes(addr_ascii
, &bytes
))
1110 << "Could not parse hex address " << addr_ascii
<< " i = " << i
;
1111 ip_addressses
.push_back(std::string(reinterpret_cast<char*>(&bytes
[0]),
1113 ASSERT_EQ(16U, ip_addressses
.back().size()) << i
;
1114 } else { // Decimal groups
1115 std::vector
<std::string
> decimals_ascii
;
1116 base::SplitString(addr_ascii
, '.', &decimals_ascii
);
1117 EXPECT_EQ(4U, decimals_ascii
.size()) << i
;
1118 std::string addr_bytes
;
1119 for (size_t j
= 0; j
< decimals_ascii
.size(); ++j
) {
1121 EXPECT_TRUE(base::StringToInt(decimals_ascii
[j
], &decimal_value
));
1122 EXPECT_GE(decimal_value
, 0);
1123 EXPECT_LE(decimal_value
, 255);
1124 addr_bytes
.push_back(static_cast<char>(decimal_value
));
1126 ip_addressses
.push_back(addr_bytes
);
1127 ASSERT_EQ(4U, ip_addressses
.back().size()) << i
;
1132 bool unused
= false;
1133 EXPECT_EQ(test_data
.expected
, X509Certificate::VerifyHostname(
1134 test_data
.hostname
, common_name
, dns_names
, ip_addressses
, &unused
));
1137 INSTANTIATE_TEST_CASE_P(, X509CertificateNameVerifyTest
,
1138 testing::ValuesIn(kNameVerifyTestData
));
1140 const struct PublicKeyInfoTestData
{
1141 const char* cert_file
;
1142 size_t expected_bits
;
1143 X509Certificate::PublicKeyType expected_type
;
1144 } kPublicKeyInfoTestData
[] = {
1145 { "768-rsa-ee-by-768-rsa-intermediate.pem", 768,
1146 X509Certificate::kPublicKeyTypeRSA
},
1147 { "1024-rsa-ee-by-768-rsa-intermediate.pem", 1024,
1148 X509Certificate::kPublicKeyTypeRSA
},
1149 { "prime256v1-ecdsa-ee-by-1024-rsa-intermediate.pem", 256,
1150 X509Certificate::kPublicKeyTypeECDSA
},
1153 class X509CertificatePublicKeyInfoTest
1154 : public testing::TestWithParam
<PublicKeyInfoTestData
> {
1157 TEST_P(X509CertificatePublicKeyInfoTest
, GetPublicKeyInfo
) {
1158 PublicKeyInfoTestData data
= GetParam();
1161 if (base::win::GetVersion() < base::win::VERSION_VISTA
&&
1162 data
.expected_type
== X509Certificate::kPublicKeyTypeECDSA
) {
1163 // ECC is only supported on Vista+. Skip the test.
1168 scoped_refptr
<X509Certificate
> cert(
1169 ImportCertFromFile(GetTestCertsDirectory(), data
.cert_file
));
1170 ASSERT_TRUE(cert
.get());
1172 size_t actual_bits
= 0;
1173 X509Certificate::PublicKeyType actual_type
=
1174 X509Certificate::kPublicKeyTypeUnknown
;
1176 X509Certificate::GetPublicKeyInfo(cert
->os_cert_handle(), &actual_bits
,
1179 EXPECT_EQ(data
.expected_bits
, actual_bits
);
1180 EXPECT_EQ(data
.expected_type
, actual_type
);
1183 INSTANTIATE_TEST_CASE_P(, X509CertificatePublicKeyInfoTest
,
1184 testing::ValuesIn(kPublicKeyInfoTestData
));