1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/cert/x509_certificate.h"
6
7 #include "base/basictypes.h"
8 #include "base/files/file_path.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/pickle.h"
11 #include "base/sha1.h"
12 #include "base/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"
21
22 #if defined(USE_NSS)
23 #include <cert.h>
24 #endif
25
26 #if defined(OS_WIN)
27 #include "base/win/windows_version.h"
28 #endif
29
30 using base::HexEncode;
31 using base::Time;
32
33 namespace net {
34
35 // Certificates for test data. They're obtained with:
36 //
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
39 //
40 // For fingerprint
41 // $ openssl x509 -inform DER -fingerprint -noout < /tmp/host.der
42
43 // For valid_start, valid_expiry
44 // $ openssl x509 -inform DER -text -noout < /tmp/host.der |
45 // grep -A 2 Validity
46 // $ date +%s -d '<date str>'
47
48 // Google's cert.
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
52 };
53
54 // webkit.org's cert.
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
58 };
59
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
64 };
65
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
71 };
72
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
78 };
79
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
84 };
85
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;
90
CheckGoogleCert(const scoped_refptr<X509Certificate> & google_cert,uint8 * expected_fingerprint,double valid_from,double valid_to)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());
95
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());
106
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());
117
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());
121
122 const Time& valid_expiry = google_cert->valid_expiry();
123 EXPECT_EQ(valid_to, valid_expiry.ToDoubleT());
124
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]);
128
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]);
133 }
134
TEST(X509CertificateTest,GoogleCertParsing)135 TEST(X509CertificateTest, GoogleCertParsing) {
136 scoped_refptr<X509Certificate> google_cert(
137 X509Certificate::CreateFromBytes(
138 reinterpret_cast<const char*>(google_der), sizeof(google_der)));
139
140 CheckGoogleCert(google_cert, google_fingerprint,
141 1238192407, // Mar 27 22:20:07 2009 GMT
142 1269728407); // Mar 27 22:20:07 2010 GMT
143 }
144
TEST(X509CertificateTest,WebkitCertParsing)145 TEST(X509CertificateTest, WebkitCertParsing) {
146 scoped_refptr<X509Certificate> webkit_cert(X509Certificate::CreateFromBytes(
147 reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der)));
148
149 ASSERT_NE(static_cast<X509Certificate*>(NULL), webkit_cert.get());
150
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());
161
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());
174
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
178
179 const Time& valid_expiry = webkit_cert->valid_expiry();
180 EXPECT_EQ(1300491319, valid_expiry.ToDoubleT()); // Mar 18 23:35:19 2011 GMT
181
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]);
185
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]);
191
192 // Test that the wildcard cert matches properly.
193 bool unused = false;
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));
199 }
200
TEST(X509CertificateTest,ThawteCertParsing)201 TEST(X509CertificateTest, ThawteCertParsing) {
202 scoped_refptr<X509Certificate> thawte_cert(X509Certificate::CreateFromBytes(
203 reinterpret_cast<const char*>(thawte_der), sizeof(thawte_der)));
204
205 ASSERT_NE(static_cast<X509Certificate*>(NULL), thawte_cert.get());
206
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());
217
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());
230
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
234
235 const Time& valid_expiry = thawte_cert->valid_expiry();
236 EXPECT_EQ(1263772799, valid_expiry.ToDoubleT()); // Jan 17 23:59:59 2010 GMT
237
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]);
241
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]);
246 }
247
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
TEST(X509CertificateTest,MultivalueRDN)252 TEST(X509CertificateTest, MultivalueRDN) {
253 base::FilePath certs_dir = GetTestCertsDirectory();
254
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());
258
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]);
271 }
272
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
TEST(X509CertificateTest,UnescapedSpecialCharacters)276 TEST(X509CertificateTest, UnescapedSpecialCharacters) {
277 base::FilePath certs_dir = GetTestCertsDirectory();
278
279 scoped_refptr<X509Certificate> unescaped_cert =
280 ImportCertFromFile(certs_dir, "unescaped.pem");
281 ASSERT_NE(static_cast<X509Certificate*>(NULL), unescaped_cert.get());
282
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());
296 }
297
TEST(X509CertificateTest,SerialNumbers)298 TEST(X509CertificateTest, SerialNumbers) {
299 scoped_refptr<X509Certificate> google_cert(
300 X509Certificate::CreateFromBytes(
301 reinterpret_cast<const char*>(google_der), sizeof(google_der)));
302
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,
306 };
307
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);
311
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)));
318
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);
324 }
325
TEST(X509CertificateTest,CAFingerprints)326 TEST(X509CertificateTest, CAFingerprints) {
327 base::FilePath certs_dir = GetTestCertsDirectory();
328
329 scoped_refptr<X509Certificate> server_cert =
330 ImportCertFromFile(certs_dir, "salesforce_com_test.pem");
331 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert.get());
332
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());
336
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());
340
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(),
345 intermediates);
346
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(),
351 intermediates);
352
353 // No intermediate CA certicates.
354 intermediates.clear();
355 scoped_refptr<X509Certificate> cert_chain3 =
356 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
357 intermediates);
358
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
362 };
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
366 };
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
371 };
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);
378
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,
385 0xe1, 0x07
386 };
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,
391 0x2d, 0xce
392 };
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,
398 0xb8, 0x55
399 };
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);
415
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,
420 0xcc, 0x8f
421 };
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,
426 0x6f, 0x9b
427 };
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,
432 0x1a, 0x10
433 };
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);
452 }
453
TEST(X509CertificateTest,ParseSubjectAltNames)454 TEST(X509CertificateTest, ParseSubjectAltNames) {
455 base::FilePath certs_dir = GetTestCertsDirectory();
456
457 scoped_refptr<X509Certificate> san_cert =
458 ImportCertFromFile(certs_dir, "subjectAltName_sanity_check.pem");
459 ASSERT_NE(static_cast<X509Certificate*>(NULL), san_cert.get());
460
461 std::vector<std::string> dns_names;
462 std::vector<std::string> ip_addresses;
463 san_cert->GetSubjectAltName(&dns_names, &ip_addresses);
464
465 // Ensure that DNS names are correctly parsed.
466 ASSERT_EQ(1U, dns_names.size());
467 EXPECT_EQ("test.example", dns_names[0]);
468
469 // Ensure that both IPv4 and IPv6 addresses are correctly parsed.
470 ASSERT_EQ(2U, ip_addresses.size());
471
472 static const uint8 kIPv4Address[] = {
473 0x7F, 0x00, 0x00, 0x02
474 };
475 ASSERT_EQ(arraysize(kIPv4Address), ip_addresses[0].size());
476 EXPECT_EQ(0, memcmp(ip_addresses[0].data(), kIPv4Address,
477 arraysize(kIPv4Address)));
478
479 static const uint8 kIPv6Address[] = {
480 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
481 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
482 };
483 ASSERT_EQ(arraysize(kIPv6Address), ip_addresses[1].size());
484 EXPECT_EQ(0, memcmp(ip_addresses[1].data(), kIPv6Address,
485 arraysize(kIPv6Address)));
486
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);
490 }
491
TEST(X509CertificateTest,ExtractSPKIFromDERCert)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());
497
498 std::string derBytes;
499 EXPECT_TRUE(X509Certificate::GetDEREncoded(cert->os_cert_handle(),
500 &derBytes));
501
502 base::StringPiece spkiBytes;
503 EXPECT_TRUE(asn1::ExtractSPKIFromDERCert(derBytes, &spkiBytes));
504
505 uint8 hash[base::kSHA1Length];
506 base::SHA1HashBytes(reinterpret_cast<const uint8*>(spkiBytes.data()),
507 spkiBytes.size(), hash);
508
509 EXPECT_EQ(0, memcmp(hash, kNistSPKIHash, sizeof(hash)));
510 }
511
TEST(X509CertificateTest,ExtractCRLURLsFromDERCert)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());
517
518 std::string derBytes;
519 EXPECT_TRUE(X509Certificate::GetDEREncoded(cert->os_cert_handle(),
520 &derBytes));
521
522 std::vector<base::StringPiece> crl_urls;
523 EXPECT_TRUE(asn1::ExtractCRLURLsFromDERCert(derBytes, &crl_urls));
524
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());
529 }
530 }
531
532 // Tests X509CertificateCache via X509Certificate::CreateFromHandle. We
533 // call X509Certificate::CreateFromHandle several times and observe whether
534 // it returns a cached or new OSCertHandle.
TEST(X509CertificateTest,Cache)535 TEST(X509CertificateTest, Cache) {
536 X509Certificate::OSCertHandle google_cert_handle;
537 X509Certificate::OSCertHandle thawte_cert_handle;
538
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);
545
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);
552
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());
559
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);
573
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());
580 }
581
TEST(X509CertificateTest,Pickle)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));
589
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());
595
596 X509Certificate::FreeOSCertHandle(google_cert_handle);
597 X509Certificate::FreeOSCertHandle(thawte_cert_handle);
598
599 Pickle pickle;
600 cert->Persist(&pickle);
601
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]));
617 }
618 }
619
TEST(X509CertificateTest,IntermediateCertificates)620 TEST(X509CertificateTest, IntermediateCertificates) {
621 scoped_refptr<X509Certificate> webkit_cert(
622 X509Certificate::CreateFromBytes(
623 reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der)));
624
625 scoped_refptr<X509Certificate> thawte_cert(
626 X509Certificate::CreateFromBytes(
627 reinterpret_cast<const char*>(thawte_der), sizeof(thawte_der)));
628
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());
637
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);
644
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()));
653
654 // Cleanup
655 X509Certificate::FreeOSCertHandle(google_handle);
656 }
657
TEST(X509CertificateTest,IsIssuedByEncoded)658 TEST(X509CertificateTest, IsIssuedByEncoded) {
659 base::FilePath certs_dir = GetTestCertsDirectory();
660
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());
665
666 std::string mit_issuer(reinterpret_cast<const char*>(MITDN),
667 sizeof(MITDN));
668
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());
673
674 std::string thawte_issuer(reinterpret_cast<const char*>(ThawteDN),
675 sizeof(ThawteDN));
676
677 // Check that the David Ben certificate is issued by MIT, but not
678 // by Thawte.
679 std::vector<std::string> issuers;
680 issuers.clear();
681 issuers.push_back(mit_issuer);
682 EXPECT_TRUE(mit_davidben_cert->IsIssuedByEncoded(issuers));
683 EXPECT_FALSE(google_cert->IsIssuedByEncoded(issuers));
684
685 // Check that the Google certificate is issued by Thawte and not
686 // by MIT.
687 issuers.clear();
688 issuers.push_back(thawte_issuer);
689 EXPECT_FALSE(mit_davidben_cert->IsIssuedByEncoded(issuers));
690 EXPECT_TRUE(google_cert->IsIssuedByEncoded(issuers));
691
692 // Check that they both pass when given a list of the two issuers.
693 issuers.clear();
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));
698 }
699
TEST(X509CertificateTest,IsIssuedByEncodedWithIntermediates)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
705 };
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
711 };
712
713 base::FilePath certs_dir = GetTestCertsDirectory();
714
715 CertificateList policy_chain = CreateCertificateListFromFile(
716 certs_dir, "explicit-policy-chain.pem", X509Certificate::FORMAT_AUTO);
717 ASSERT_EQ(3u, policy_chain.size());
718
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));
726
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(),
731 intermediates);
732
733 std::vector<std::string> issuers;
734
735 // Check that the chain is issued by the intermediate.
736 issuers.clear();
737 issuers.push_back(policy_intermediate_dn);
738 EXPECT_TRUE(cert_chain->IsIssuedByEncoded(issuers));
739
740 // Check that the chain is also issued by the root.
741 issuers.clear();
742 issuers.push_back(policy_root_dn);
743 EXPECT_TRUE(cert_chain->IsIssuedByEncoded(issuers));
744
745 // Check that the chain is issued by either the intermediate or the root.
746 issuers.clear();
747 issuers.push_back(policy_intermediate_dn);
748 issuers.push_back(policy_root_dn);
749 EXPECT_TRUE(cert_chain->IsIssuedByEncoded(issuers));
750
751 // Check that an empty issuers list returns false.
752 issuers.clear();
753 EXPECT_FALSE(cert_chain->IsIssuedByEncoded(issuers));
754
755 // Check that the chain is not issued by Verisign
756 std::string mit_issuer(reinterpret_cast<const char*>(VerisignDN),
757 sizeof(VerisignDN));
758 issuers.clear();
759 issuers.push_back(mit_issuer);
760 EXPECT_FALSE(cert_chain->IsIssuedByEncoded(issuers));
761 }
762
763 // Tests that FreeOSCertHandle ignores NULL on each OS.
TEST(X509CertificateTest,FreeNullHandle)764 TEST(X509CertificateTest, FreeNullHandle) {
765 X509Certificate::FreeOSCertHandle(NULL);
766 }
767
768 #if defined(USE_NSS)
TEST(X509CertificateTest,GetDefaultNickname)769 TEST(X509CertificateTest, GetDefaultNickname) {
770 base::FilePath certs_dir = GetTestCertsDirectory();
771
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());
775
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);
779 }
780 #endif
781
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,
790 NULL, } },
791 // DER parsing - single certificate, PEM encoded
792 { "google.single.pem", X509Certificate::FORMAT_SINGLE_CERTIFICATE,
793 { google_parse_fingerprint,
794 NULL, } },
795 // PEM parsing - single certificate, PEM encoded with a PEB of
796 // "CERTIFICATE"
797 { "google.single.pem", X509Certificate::FORMAT_PEM_CERT_SEQUENCE,
798 { google_parse_fingerprint,
799 NULL, } },
800 // PEM parsing - sequence of certificates, PEM encoded with a PEB of
801 // "CERTIFICATE"
802 { "google.chain.pem", X509Certificate::FORMAT_PEM_CERT_SEQUENCE,
803 { google_parse_fingerprint,
804 thawte_parse_fingerprint,
805 NULL, } },
806 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, DER
807 // encoding
808 { "google.binary.p7b", X509Certificate::FORMAT_PKCS7,
809 { google_parse_fingerprint,
810 thawte_parse_fingerprint,
811 NULL, } },
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,
817 NULL, } },
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,
823 NULL, } },
824 // All of the above, this time using auto-detection
825 { "google.single.der", X509Certificate::FORMAT_AUTO,
826 { google_parse_fingerprint,
827 NULL, } },
828 { "google.single.pem", X509Certificate::FORMAT_AUTO,
829 { google_parse_fingerprint,
830 NULL, } },
831 { "google.chain.pem", X509Certificate::FORMAT_AUTO,
832 { google_parse_fingerprint,
833 thawte_parse_fingerprint,
834 NULL, } },
835 { "google.binary.p7b", X509Certificate::FORMAT_AUTO,
836 { google_parse_fingerprint,
837 thawte_parse_fingerprint,
838 NULL, } },
839 { "google.pem_cert.p7b", X509Certificate::FORMAT_AUTO,
840 { google_parse_fingerprint,
841 thawte_parse_fingerprint,
842 NULL, } },
843 { "google.pem_pkcs7.p7b", X509Certificate::FORMAT_AUTO,
844 { google_parse_fingerprint,
845 thawte_parse_fingerprint,
846 NULL, } },
847 };
848
849 class X509CertificateParseTest
850 : public testing::TestWithParam<CertificateFormatTestData> {
851 public:
~X509CertificateParseTest()852 virtual ~X509CertificateParseTest() {}
SetUp()853 virtual void SetUp() {
854 test_data_ = GetParam();
855 }
TearDown()856 virtual void TearDown() {}
857
858 protected:
859 CertificateFormatTestData test_data_;
860 };
861
TEST_P(X509CertificateParseTest,CanParseFormat)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);
870
871 size_t i;
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());
877 break;
878 }
879
880 // A cert is expected - make sure that one was parsed.
881 ASSERT_LT(i, certs.size());
882
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];
888
889 for (size_t j = 0; j < 20; ++j)
890 EXPECT_EQ(expected_fingerprint[j], actual_fingerprint.data[j]);
891 }
892 }
893
894 INSTANTIATE_TEST_CASE_P(, X509CertificateParseTest,
895 testing::ValuesIn(kFormatTestData));
896
897 struct CertificateNameVerifyTestData {
898 // true iff we expect hostname to match an entry in cert_names.
899 bool expected;
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;
910 };
911
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.
PrintTo(const CertificateNameVerifyTestData & data,std::ostream * os)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);
924 }
925
926 const CertificateNameVerifyTestData kNameVerifyTestData[] = {
927 { true, "foo.com", "foo.com" },
928 { true, "f", "f" },
929 { false, "h", "i" },
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" },
958 // IDN tests
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
980 // be present.
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
994 // domains.
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",
1052 "121.2.3.0"},
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" },
1062 };
1063
1064 class X509CertificateNameVerifyTest
1065 : public testing::TestWithParam<CertificateNameVerifyTestData> {
1066 };
1067
TEST_P(X509CertificateNameVerifyTest,VerifyHostname)1068 TEST_P(X509CertificateNameVerifyTest, VerifyHostname) {
1069 CertificateNameVerifyTestData test_data = GetParam();
1070
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');
1074
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);
1081 }
1082
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]),
1097 bytes.size()));
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) {
1105 int decimal_value;
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));
1110 }
1111 ip_addressses.push_back(addr_bytes);
1112 ASSERT_EQ(4U, ip_addressses.back().size()) << i;
1113 }
1114 }
1115 }
1116
1117 bool unused = false;
1118 EXPECT_EQ(test_data.expected, X509Certificate::VerifyHostname(
1119 test_data.hostname, common_name, dns_names, ip_addressses, &unused));
1120 }
1121
1122 INSTANTIATE_TEST_CASE_P(, X509CertificateNameVerifyTest,
1123 testing::ValuesIn(kNameVerifyTestData));
1124
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 },
1136 };
1137
1138 class X509CertificatePublicKeyInfoTest
1139 : public testing::TestWithParam<PublicKeyInfoTestData> {
1140 };
1141
TEST_P(X509CertificatePublicKeyInfoTest,GetPublicKeyInfo)1142 TEST_P(X509CertificatePublicKeyInfoTest, GetPublicKeyInfo) {
1143 PublicKeyInfoTestData data = GetParam();
1144
1145 #if defined(OS_WIN)
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.
1149 return;
1150 }
1151 #endif
1152
1153 scoped_refptr<X509Certificate> cert(
1154 ImportCertFromFile(GetTestCertsDirectory(), data.cert_file));
1155 ASSERT_TRUE(cert.get());
1156
1157 size_t actual_bits = 0;
1158 X509Certificate::PublicKeyType actual_type =
1159 X509Certificate::kPublicKeyTypeUnknown;
1160
1161 X509Certificate::GetPublicKeyInfo(cert->os_cert_handle(), &actual_bits,
1162 &actual_type);
1163
1164 EXPECT_EQ(data.expected_bits, actual_bits);
1165 EXPECT_EQ(data.expected_type, actual_type);
1166 }
1167
1168 INSTANTIATE_TEST_CASE_P(, X509CertificatePublicKeyInfoTest,
1169 testing::ValuesIn(kPublicKeyInfoTestData));
1170
1171 } // namespace net
1172