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 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 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 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 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 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 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 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 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 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 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 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. 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 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 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 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 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. 764 TEST(X509CertificateTest, FreeNullHandle) { 765 X509Certificate::FreeOSCertHandle(NULL); 766 } 767 768 #if defined(USE_NSS) 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 (at) 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: 852 virtual ~X509CertificateParseTest() {} 853 virtual void SetUp() { 854 test_data_ = GetParam(); 855 } 856 virtual void TearDown() {} 857 858 protected: 859 CertificateFormatTestData test_data_; 860 }; 861 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. 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 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 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