1 // Copyright (c) 2011 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 "base/file_path.h" 6 #include "base/file_util.h" 7 #include "base/path_service.h" 8 #include "base/pickle.h" 9 #include "base/sha1.h" 10 #include "base/string_number_conversions.h" 11 #include "base/string_split.h" 12 #include "crypto/rsa_private_key.h" 13 #include "net/base/asn1_util.h" 14 #include "net/base/cert_status_flags.h" 15 #include "net/base/cert_test_util.h" 16 #include "net/base/cert_verify_result.h" 17 #include "net/base/net_errors.h" 18 #include "net/base/test_certificate_data.h" 19 #include "net/base/test_root_certs.h" 20 #include "net/base/x509_certificate.h" 21 #include "testing/gtest/include/gtest/gtest.h" 22 23 // Unit tests aren't allowed to access external resources. Unfortunately, to 24 // properly verify the EV-ness of a cert, we need to check for its revocation 25 // through online servers. If you're manually running unit tests, feel free to 26 // turn this on to test EV certs. But leave it turned off for the automated 27 // testing. 28 #define ALLOW_EXTERNAL_ACCESS 0 29 30 #if ALLOW_EXTERNAL_ACCESS && defined(OS_WIN) 31 #define TEST_EV 1 // Test CERT_STATUS_IS_EV 32 #endif 33 34 using base::HexEncode; 35 using base::SHA1_LENGTH; 36 using base::Time; 37 38 namespace net { 39 40 // Certificates for test data. They're obtained with: 41 // 42 // $ openssl s_client -connect [host]:443 -showcerts > /tmp/host.pem < /dev/null 43 // $ openssl x509 -inform PEM -outform DER < /tmp/host.pem > /tmp/host.der 44 // 45 // For fingerprint 46 // $ openssl x509 -inform DER -fingerprint -noout < /tmp/host.der 47 48 // For valid_start, valid_expiry 49 // $ openssl x509 -inform DER -text -noout < /tmp/host.der | 50 // grep -A 2 Validity 51 // $ date +%s -d '<date str>' 52 53 // Google's cert. 54 unsigned char google_fingerprint[] = { 55 0xab, 0xbe, 0x5e, 0xb4, 0x93, 0x88, 0x4e, 0xe4, 0x60, 0xc6, 0xef, 0xf8, 56 0xea, 0xd4, 0xb1, 0x55, 0x4b, 0xc9, 0x59, 0x3c 57 }; 58 59 // webkit.org's cert. 60 unsigned char webkit_fingerprint[] = { 61 0xa1, 0x4a, 0x94, 0x46, 0x22, 0x8e, 0x70, 0x66, 0x2b, 0x94, 0xf9, 0xf8, 62 0x57, 0x83, 0x2d, 0xa2, 0xff, 0xbc, 0x84, 0xc2 63 }; 64 65 // thawte.com's cert (it's EV-licious!). 66 unsigned char thawte_fingerprint[] = { 67 0x85, 0x04, 0x2d, 0xfd, 0x2b, 0x0e, 0xc6, 0xc8, 0xaf, 0x2d, 0x77, 0xd6, 68 0xa1, 0x3a, 0x64, 0x04, 0x27, 0x90, 0x97, 0x37 69 }; 70 71 // A certificate for www.paypal.com with a NULL byte in the common name. 72 // From http://www.gossamer-threads.com/lists/fulldisc/full-disclosure/70363 73 unsigned char paypal_null_fingerprint[] = { 74 0x4c, 0x88, 0x9e, 0x28, 0xd7, 0x7a, 0x44, 0x1e, 0x13, 0xf2, 0x6a, 0xba, 75 0x1f, 0xe8, 0x1b, 0xd6, 0xab, 0x7b, 0xe8, 0xd7 76 }; 77 78 // A certificate for https://www.unosoft.hu/, whose AIA extension contains 79 // an LDAP URL without a host name. 80 unsigned char unosoft_hu_fingerprint[] = { 81 0x32, 0xff, 0xe3, 0xbe, 0x2c, 0x3b, 0xc7, 0xca, 0xbf, 0x2d, 0x64, 0xbd, 82 0x25, 0x66, 0xf2, 0xec, 0x8b, 0x0f, 0xbf, 0xd8 83 }; 84 85 // The fingerprint of the Google certificate used in the parsing tests, 86 // which is newer than the one included in the x509_certificate_data.h 87 unsigned char google_parse_fingerprint[] = { 88 0x40, 0x50, 0x62, 0xe5, 0xbe, 0xfd, 0xe4, 0xaf, 0x97, 0xe9, 0x38, 0x2a, 89 0xf1, 0x6c, 0xc8, 0x7c, 0x8f, 0xb7, 0xc4, 0xe2 90 }; 91 92 // The fingerprint for the Thawte SGC certificate 93 unsigned char thawte_parse_fingerprint[] = { 94 0xec, 0x07, 0x10, 0x03, 0xd8, 0xf5, 0xa3, 0x7f, 0x42, 0xc4, 0x55, 0x7f, 95 0x65, 0x6a, 0xae, 0x86, 0x65, 0xfa, 0x4b, 0x02 96 }; 97 98 // Dec 18 00:00:00 2009 GMT 99 const double kGoogleParseValidFrom = 1261094400; 100 // Dec 18 23:59:59 2011 GMT 101 const double kGoogleParseValidTo = 1324252799; 102 103 struct CertificateFormatTestData { 104 const char* file_name; 105 X509Certificate::Format format; 106 unsigned char* chain_fingerprints[3]; 107 }; 108 109 const CertificateFormatTestData FormatTestData[] = { 110 // DER Parsing - single certificate, DER encoded 111 { "google.single.der", X509Certificate::FORMAT_SINGLE_CERTIFICATE, 112 { google_parse_fingerprint, 113 NULL, } }, 114 // DER parsing - single certificate, PEM encoded 115 { "google.single.pem", X509Certificate::FORMAT_SINGLE_CERTIFICATE, 116 { google_parse_fingerprint, 117 NULL, } }, 118 // PEM parsing - single certificate, PEM encoded with a PEB of 119 // "CERTIFICATE" 120 { "google.single.pem", X509Certificate::FORMAT_PEM_CERT_SEQUENCE, 121 { google_parse_fingerprint, 122 NULL, } }, 123 // PEM parsing - sequence of certificates, PEM encoded with a PEB of 124 // "CERTIFICATE" 125 { "google.chain.pem", X509Certificate::FORMAT_PEM_CERT_SEQUENCE, 126 { google_parse_fingerprint, 127 thawte_parse_fingerprint, 128 NULL, } }, 129 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, DER 130 // encoding 131 { "google.binary.p7b", X509Certificate::FORMAT_PKCS7, 132 { google_parse_fingerprint, 133 thawte_parse_fingerprint, 134 NULL, } }, 135 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, PEM 136 // encoded with a PEM PEB of "CERTIFICATE" 137 { "google.pem_cert.p7b", X509Certificate::FORMAT_PKCS7, 138 { google_parse_fingerprint, 139 thawte_parse_fingerprint, 140 NULL, } }, 141 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, PEM 142 // encoded with a PEM PEB of "PKCS7" 143 { "google.pem_pkcs7.p7b", X509Certificate::FORMAT_PKCS7, 144 { google_parse_fingerprint, 145 thawte_parse_fingerprint, 146 NULL, } }, 147 // All of the above, this time using auto-detection 148 { "google.single.der", X509Certificate::FORMAT_AUTO, 149 { google_parse_fingerprint, 150 NULL, } }, 151 { "google.single.pem", X509Certificate::FORMAT_AUTO, 152 { google_parse_fingerprint, 153 NULL, } }, 154 { "google.chain.pem", X509Certificate::FORMAT_AUTO, 155 { google_parse_fingerprint, 156 thawte_parse_fingerprint, 157 NULL, } }, 158 { "google.binary.p7b", X509Certificate::FORMAT_AUTO, 159 { google_parse_fingerprint, 160 thawte_parse_fingerprint, 161 NULL, } }, 162 { "google.pem_cert.p7b", X509Certificate::FORMAT_AUTO, 163 { google_parse_fingerprint, 164 thawte_parse_fingerprint, 165 NULL, } }, 166 { "google.pem_pkcs7.p7b", X509Certificate::FORMAT_AUTO, 167 { google_parse_fingerprint, 168 thawte_parse_fingerprint, 169 NULL, } }, 170 }; 171 172 CertificateList CreateCertificateListFromFile( 173 const FilePath& certs_dir, 174 const std::string& cert_file, 175 int format) { 176 FilePath cert_path = certs_dir.AppendASCII(cert_file); 177 std::string cert_data; 178 if (!file_util::ReadFileToString(cert_path, &cert_data)) 179 return CertificateList(); 180 return X509Certificate::CreateCertificateListFromBytes(cert_data.data(), 181 cert_data.size(), 182 format); 183 } 184 185 void CheckGoogleCert(const scoped_refptr<X509Certificate>& google_cert, 186 unsigned char* expected_fingerprint, 187 double valid_from, double valid_to) { 188 ASSERT_NE(static_cast<X509Certificate*>(NULL), google_cert); 189 190 const CertPrincipal& subject = google_cert->subject(); 191 EXPECT_EQ("www.google.com", subject.common_name); 192 EXPECT_EQ("Mountain View", subject.locality_name); 193 EXPECT_EQ("California", subject.state_or_province_name); 194 EXPECT_EQ("US", subject.country_name); 195 EXPECT_EQ(0U, subject.street_addresses.size()); 196 ASSERT_EQ(1U, subject.organization_names.size()); 197 EXPECT_EQ("Google Inc", subject.organization_names[0]); 198 EXPECT_EQ(0U, subject.organization_unit_names.size()); 199 EXPECT_EQ(0U, subject.domain_components.size()); 200 201 const CertPrincipal& issuer = google_cert->issuer(); 202 EXPECT_EQ("Thawte SGC CA", issuer.common_name); 203 EXPECT_EQ("", issuer.locality_name); 204 EXPECT_EQ("", issuer.state_or_province_name); 205 EXPECT_EQ("ZA", issuer.country_name); 206 EXPECT_EQ(0U, issuer.street_addresses.size()); 207 ASSERT_EQ(1U, issuer.organization_names.size()); 208 EXPECT_EQ("Thawte Consulting (Pty) Ltd.", issuer.organization_names[0]); 209 EXPECT_EQ(0U, issuer.organization_unit_names.size()); 210 EXPECT_EQ(0U, issuer.domain_components.size()); 211 212 // Use DoubleT because its epoch is the same on all platforms 213 const Time& valid_start = google_cert->valid_start(); 214 EXPECT_EQ(valid_from, valid_start.ToDoubleT()); 215 216 const Time& valid_expiry = google_cert->valid_expiry(); 217 EXPECT_EQ(valid_to, valid_expiry.ToDoubleT()); 218 219 const SHA1Fingerprint& fingerprint = google_cert->fingerprint(); 220 for (size_t i = 0; i < 20; ++i) 221 EXPECT_EQ(expected_fingerprint[i], fingerprint.data[i]); 222 223 std::vector<std::string> dns_names; 224 google_cert->GetDNSNames(&dns_names); 225 ASSERT_EQ(1U, dns_names.size()); 226 EXPECT_EQ("www.google.com", dns_names[0]); 227 228 #if TEST_EV 229 // TODO(avi): turn this on for the Mac once EV checking is implemented. 230 CertVerifyResult verify_result; 231 int flags = X509Certificate::VERIFY_REV_CHECKING_ENABLED | 232 X509Certificate::VERIFY_EV_CERT; 233 EXPECT_EQ(OK, google_cert->Verify("www.google.com", flags, &verify_result)); 234 EXPECT_EQ(0, verify_result.cert_status & CERT_STATUS_IS_EV); 235 #endif 236 } 237 238 TEST(X509CertificateTest, GoogleCertParsing) { 239 scoped_refptr<X509Certificate> google_cert( 240 X509Certificate::CreateFromBytes( 241 reinterpret_cast<const char*>(google_der), sizeof(google_der))); 242 243 CheckGoogleCert(google_cert, google_fingerprint, 244 1238192407, // Mar 27 22:20:07 2009 GMT 245 1269728407); // Mar 27 22:20:07 2010 GMT 246 } 247 248 TEST(X509CertificateTest, WebkitCertParsing) { 249 scoped_refptr<X509Certificate> webkit_cert(X509Certificate::CreateFromBytes( 250 reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der))); 251 252 ASSERT_NE(static_cast<X509Certificate*>(NULL), webkit_cert); 253 254 const CertPrincipal& subject = webkit_cert->subject(); 255 EXPECT_EQ("Cupertino", subject.locality_name); 256 EXPECT_EQ("California", subject.state_or_province_name); 257 EXPECT_EQ("US", subject.country_name); 258 EXPECT_EQ(0U, subject.street_addresses.size()); 259 ASSERT_EQ(1U, subject.organization_names.size()); 260 EXPECT_EQ("Apple Inc.", subject.organization_names[0]); 261 ASSERT_EQ(1U, subject.organization_unit_names.size()); 262 EXPECT_EQ("Mac OS Forge", subject.organization_unit_names[0]); 263 EXPECT_EQ(0U, subject.domain_components.size()); 264 265 const CertPrincipal& issuer = webkit_cert->issuer(); 266 EXPECT_EQ("Go Daddy Secure Certification Authority", issuer.common_name); 267 EXPECT_EQ("Scottsdale", issuer.locality_name); 268 EXPECT_EQ("Arizona", issuer.state_or_province_name); 269 EXPECT_EQ("US", issuer.country_name); 270 EXPECT_EQ(0U, issuer.street_addresses.size()); 271 ASSERT_EQ(1U, issuer.organization_names.size()); 272 EXPECT_EQ("GoDaddy.com, Inc.", issuer.organization_names[0]); 273 ASSERT_EQ(1U, issuer.organization_unit_names.size()); 274 EXPECT_EQ("http://certificates.godaddy.com/repository", 275 issuer.organization_unit_names[0]); 276 EXPECT_EQ(0U, issuer.domain_components.size()); 277 278 // Use DoubleT because its epoch is the same on all platforms 279 const Time& valid_start = webkit_cert->valid_start(); 280 EXPECT_EQ(1205883319, valid_start.ToDoubleT()); // Mar 18 23:35:19 2008 GMT 281 282 const Time& valid_expiry = webkit_cert->valid_expiry(); 283 EXPECT_EQ(1300491319, valid_expiry.ToDoubleT()); // Mar 18 23:35:19 2011 GMT 284 285 const SHA1Fingerprint& fingerprint = webkit_cert->fingerprint(); 286 for (size_t i = 0; i < 20; ++i) 287 EXPECT_EQ(webkit_fingerprint[i], fingerprint.data[i]); 288 289 std::vector<std::string> dns_names; 290 webkit_cert->GetDNSNames(&dns_names); 291 ASSERT_EQ(2U, dns_names.size()); 292 EXPECT_EQ("*.webkit.org", dns_names[0]); 293 EXPECT_EQ("webkit.org", dns_names[1]); 294 295 #if TEST_EV 296 int flags = X509Certificate::VERIFY_REV_CHECKING_ENABLED | 297 X509Certificate::VERIFY_EV_CERT; 298 CertVerifyResult verify_result; 299 EXPECT_EQ(OK, webkit_cert->Verify("webkit.org", flags, &verify_result)); 300 EXPECT_EQ(0, verify_result.cert_status & CERT_STATUS_IS_EV); 301 #endif 302 303 // Test that the wildcard cert matches properly. 304 EXPECT_TRUE(webkit_cert->VerifyNameMatch("www.webkit.org")); 305 EXPECT_TRUE(webkit_cert->VerifyNameMatch("foo.webkit.org")); 306 EXPECT_TRUE(webkit_cert->VerifyNameMatch("webkit.org")); 307 EXPECT_FALSE(webkit_cert->VerifyNameMatch("www.webkit.com")); 308 EXPECT_FALSE(webkit_cert->VerifyNameMatch("www.foo.webkit.com")); 309 } 310 311 TEST(X509CertificateTest, ThawteCertParsing) { 312 scoped_refptr<X509Certificate> thawte_cert(X509Certificate::CreateFromBytes( 313 reinterpret_cast<const char*>(thawte_der), sizeof(thawte_der))); 314 315 ASSERT_NE(static_cast<X509Certificate*>(NULL), thawte_cert); 316 317 const CertPrincipal& subject = thawte_cert->subject(); 318 EXPECT_EQ("www.thawte.com", subject.common_name); 319 EXPECT_EQ("Mountain View", subject.locality_name); 320 EXPECT_EQ("California", subject.state_or_province_name); 321 EXPECT_EQ("US", subject.country_name); 322 EXPECT_EQ(0U, subject.street_addresses.size()); 323 ASSERT_EQ(1U, subject.organization_names.size()); 324 EXPECT_EQ("Thawte Inc", subject.organization_names[0]); 325 EXPECT_EQ(0U, subject.organization_unit_names.size()); 326 EXPECT_EQ(0U, subject.domain_components.size()); 327 328 const CertPrincipal& issuer = thawte_cert->issuer(); 329 EXPECT_EQ("thawte Extended Validation SSL CA", issuer.common_name); 330 EXPECT_EQ("", issuer.locality_name); 331 EXPECT_EQ("", issuer.state_or_province_name); 332 EXPECT_EQ("US", issuer.country_name); 333 EXPECT_EQ(0U, issuer.street_addresses.size()); 334 ASSERT_EQ(1U, issuer.organization_names.size()); 335 EXPECT_EQ("thawte, Inc.", issuer.organization_names[0]); 336 ASSERT_EQ(1U, issuer.organization_unit_names.size()); 337 EXPECT_EQ("Terms of use at https://www.thawte.com/cps (c)06", 338 issuer.organization_unit_names[0]); 339 EXPECT_EQ(0U, issuer.domain_components.size()); 340 341 // Use DoubleT because its epoch is the same on all platforms 342 const Time& valid_start = thawte_cert->valid_start(); 343 EXPECT_EQ(1227052800, valid_start.ToDoubleT()); // Nov 19 00:00:00 2008 GMT 344 345 const Time& valid_expiry = thawte_cert->valid_expiry(); 346 EXPECT_EQ(1263772799, valid_expiry.ToDoubleT()); // Jan 17 23:59:59 2010 GMT 347 348 const SHA1Fingerprint& fingerprint = thawte_cert->fingerprint(); 349 for (size_t i = 0; i < 20; ++i) 350 EXPECT_EQ(thawte_fingerprint[i], fingerprint.data[i]); 351 352 std::vector<std::string> dns_names; 353 thawte_cert->GetDNSNames(&dns_names); 354 ASSERT_EQ(1U, dns_names.size()); 355 EXPECT_EQ("www.thawte.com", dns_names[0]); 356 357 #if TEST_EV 358 int flags = X509Certificate::VERIFY_REV_CHECKING_ENABLED | 359 X509Certificate::VERIFY_EV_CERT; 360 CertVerifyResult verify_result; 361 // EV cert verification requires revocation checking. 362 EXPECT_EQ(OK, thawte_cert->Verify("www.thawte.com", flags, &verify_result)); 363 EXPECT_NE(0, verify_result.cert_status & CERT_STATUS_IS_EV); 364 // Consequently, if we don't have revocation checking enabled, we can't claim 365 // any cert is EV. 366 flags = X509Certificate::VERIFY_EV_CERT; 367 EXPECT_EQ(OK, thawte_cert->Verify("www.thawte.com", flags, &verify_result)); 368 EXPECT_EQ(0, verify_result.cert_status & CERT_STATUS_IS_EV); 369 #endif 370 } 371 372 TEST(X509CertificateTest, PaypalNullCertParsing) { 373 scoped_refptr<X509Certificate> paypal_null_cert( 374 X509Certificate::CreateFromBytes( 375 reinterpret_cast<const char*>(paypal_null_der), 376 sizeof(paypal_null_der))); 377 378 ASSERT_NE(static_cast<X509Certificate*>(NULL), paypal_null_cert); 379 380 const SHA1Fingerprint& fingerprint = 381 paypal_null_cert->fingerprint(); 382 for (size_t i = 0; i < 20; ++i) 383 EXPECT_EQ(paypal_null_fingerprint[i], fingerprint.data[i]); 384 385 int flags = 0; 386 CertVerifyResult verify_result; 387 int error = paypal_null_cert->Verify("www.paypal.com", flags, 388 &verify_result); 389 #if defined(USE_OPENSSL) || defined(OS_MACOSX) || defined(OS_WIN) 390 // TOOD(bulach): investigate why macosx and win aren't returning 391 // ERR_CERT_INVALID or ERR_CERT_COMMON_NAME_INVALID. 392 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error); 393 #else 394 EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, error); 395 #endif 396 // Either the system crypto library should correctly report a certificate 397 // name mismatch, or our certificate blacklist should cause us to report an 398 // invalid certificate. 399 #if !defined(OS_MACOSX) && !defined(USE_OPENSSL) 400 EXPECT_NE(0, verify_result.cert_status & 401 (CERT_STATUS_COMMON_NAME_INVALID | CERT_STATUS_INVALID)); 402 #endif 403 } 404 405 // A certificate whose AIA extension contains an LDAP URL without a host name. 406 // This certificate will expire on 2011-09-08. 407 TEST(X509CertificateTest, UnoSoftCertParsing) { 408 FilePath certs_dir = GetTestCertsDirectory(); 409 scoped_refptr<X509Certificate> unosoft_hu_cert( 410 ImportCertFromFile(certs_dir, "unosoft_hu_cert.der")); 411 412 ASSERT_NE(static_cast<X509Certificate*>(NULL), unosoft_hu_cert); 413 414 const SHA1Fingerprint& fingerprint = 415 unosoft_hu_cert->fingerprint(); 416 for (size_t i = 0; i < 20; ++i) 417 EXPECT_EQ(unosoft_hu_fingerprint[i], fingerprint.data[i]); 418 419 int flags = 0; 420 CertVerifyResult verify_result; 421 int error = unosoft_hu_cert->Verify("www.unosoft.hu", flags, 422 &verify_result); 423 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error); 424 EXPECT_NE(0, verify_result.cert_status & CERT_STATUS_AUTHORITY_INVALID); 425 } 426 427 TEST(X509CertificateTest, SerialNumbers) { 428 scoped_refptr<X509Certificate> google_cert( 429 X509Certificate::CreateFromBytes( 430 reinterpret_cast<const char*>(google_der), sizeof(google_der))); 431 432 static const uint8 google_serial[16] = { 433 0x01,0x2a,0x39,0x76,0x0d,0x3f,0x4f,0xc9, 434 0x0b,0xe7,0xbd,0x2b,0xcf,0x95,0x2e,0x7a, 435 }; 436 437 ASSERT_EQ(sizeof(google_serial), google_cert->serial_number().size()); 438 EXPECT_TRUE(memcmp(google_cert->serial_number().data(), google_serial, 439 sizeof(google_serial)) == 0); 440 441 // We also want to check a serial number where the first byte is >= 0x80 in 442 // case the underlying library tries to pad it. 443 scoped_refptr<X509Certificate> paypal_null_cert( 444 X509Certificate::CreateFromBytes( 445 reinterpret_cast<const char*>(paypal_null_der), 446 sizeof(paypal_null_der))); 447 448 static const uint8 paypal_null_serial[2] = {0xf0, 0x9b}; 449 ASSERT_EQ(sizeof(paypal_null_serial), 450 paypal_null_cert->serial_number().size()); 451 EXPECT_TRUE(memcmp(paypal_null_cert->serial_number().data(), 452 paypal_null_serial, sizeof(paypal_null_serial)) == 0); 453 } 454 455 // A regression test for http://crbug.com/31497. 456 // This certificate will expire on 2012-04-08. 457 TEST(X509CertificateTest, IntermediateCARequireExplicitPolicy) { 458 FilePath certs_dir = GetTestCertsDirectory(); 459 460 scoped_refptr<X509Certificate> server_cert = 461 ImportCertFromFile(certs_dir, "www_us_army_mil_cert.der"); 462 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert); 463 464 // The intermediate CA certificate's policyConstraints extension has a 465 // requireExplicitPolicy field with SkipCerts=0. 466 scoped_refptr<X509Certificate> intermediate_cert = 467 ImportCertFromFile(certs_dir, "dod_ca_17_cert.der"); 468 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert); 469 470 FilePath root_cert_path = certs_dir.AppendASCII("dod_root_ca_2_cert.der"); 471 TestRootCerts* root_certs = TestRootCerts::GetInstance(); 472 ASSERT_TRUE(root_certs->AddFromFile(root_cert_path)); 473 474 X509Certificate::OSCertHandles intermediates; 475 intermediates.push_back(intermediate_cert->os_cert_handle()); 476 scoped_refptr<X509Certificate> cert_chain = 477 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(), 478 X509Certificate::SOURCE_FROM_NETWORK, 479 intermediates); 480 481 int flags = 0; 482 CertVerifyResult verify_result; 483 int error = cert_chain->Verify("www.us.army.mil", flags, &verify_result); 484 EXPECT_EQ(OK, error); 485 EXPECT_EQ(0, verify_result.cert_status); 486 root_certs->Clear(); 487 } 488 489 TEST(X509CertificateTest, TestKnownRoot) { 490 FilePath certs_dir = GetTestCertsDirectory(); 491 scoped_refptr<X509Certificate> cert = 492 ImportCertFromFile(certs_dir, "nist.der"); 493 ASSERT_NE(static_cast<X509Certificate*>(NULL), cert); 494 495 // This intermediate is only needed for old Linux machines. Modern NSS 496 // includes it as a root already. 497 scoped_refptr<X509Certificate> intermediate_cert = 498 ImportCertFromFile(certs_dir, "nist_intermediate.der"); 499 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert); 500 501 X509Certificate::OSCertHandles intermediates; 502 intermediates.push_back(intermediate_cert->os_cert_handle()); 503 scoped_refptr<X509Certificate> cert_chain = 504 X509Certificate::CreateFromHandle(cert->os_cert_handle(), 505 X509Certificate::SOURCE_FROM_NETWORK, 506 intermediates); 507 508 int flags = 0; 509 CertVerifyResult verify_result; 510 // This is going to blow up in Feb 2012. Sorry! Disable and file a bug 511 // against agl. Also see PublicKeyHashes in this file. 512 int error = cert_chain->Verify("www.nist.gov", flags, &verify_result); 513 EXPECT_EQ(OK, error); 514 EXPECT_EQ(0, verify_result.cert_status); 515 EXPECT_TRUE(verify_result.is_issued_by_known_root); 516 } 517 518 // This is the SHA1 hash of the SubjectPublicKeyInfo of nist.der. 519 static const char nistSPKIHash[] = 520 "\x15\x60\xde\x65\x4e\x03\x9f\xd0\x08\x82" 521 "\xa9\x6a\xc4\x65\x8e\x6f\x92\x06\x84\x35"; 522 523 TEST(X509CertificateTest, ExtractSPKIFromDERCert) { 524 FilePath certs_dir = GetTestCertsDirectory(); 525 scoped_refptr<X509Certificate> cert = 526 ImportCertFromFile(certs_dir, "nist.der"); 527 ASSERT_NE(static_cast<X509Certificate*>(NULL), cert); 528 529 std::string derBytes; 530 EXPECT_TRUE(cert->GetDEREncoded(&derBytes)); 531 532 base::StringPiece spkiBytes; 533 EXPECT_TRUE(asn1::ExtractSPKIFromDERCert(derBytes, &spkiBytes)); 534 535 uint8 hash[base::SHA1_LENGTH]; 536 base::SHA1HashBytes(reinterpret_cast<const uint8*>(spkiBytes.data()), 537 spkiBytes.size(), hash); 538 539 EXPECT_TRUE(0 == memcmp(hash, nistSPKIHash, sizeof(hash))); 540 } 541 542 TEST(X509CertificateTest, PublicKeyHashes) { 543 FilePath certs_dir = GetTestCertsDirectory(); 544 // This is going to blow up in Feb 2012. Sorry! Disable and file a bug 545 // against agl. Also see TestKnownRoot in this file. 546 scoped_refptr<X509Certificate> cert = 547 ImportCertFromFile(certs_dir, "nist.der"); 548 ASSERT_NE(static_cast<X509Certificate*>(NULL), cert); 549 550 // This intermediate is only needed for old Linux machines. Modern NSS 551 // includes it as a root already. 552 scoped_refptr<X509Certificate> intermediate_cert = 553 ImportCertFromFile(certs_dir, "nist_intermediate.der"); 554 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert); 555 556 TestRootCerts::GetInstance()->Add(intermediate_cert.get()); 557 558 X509Certificate::OSCertHandles intermediates; 559 intermediates.push_back(intermediate_cert->os_cert_handle()); 560 scoped_refptr<X509Certificate> cert_chain = 561 X509Certificate::CreateFromHandle(cert->os_cert_handle(), 562 X509Certificate::SOURCE_FROM_NETWORK, 563 intermediates); 564 565 int flags = 0; 566 CertVerifyResult verify_result; 567 568 int error = cert_chain->Verify("www.nist.gov", flags, &verify_result); 569 EXPECT_EQ(OK, error); 570 EXPECT_EQ(0, verify_result.cert_status); 571 ASSERT_LE(2u, verify_result.public_key_hashes.size()); 572 EXPECT_EQ(HexEncode(nistSPKIHash, base::SHA1_LENGTH), 573 HexEncode(verify_result.public_key_hashes[0].data, SHA1_LENGTH)); 574 EXPECT_EQ("83244223D6CBF0A26FC7DE27CEBCA4BDA32612AD", 575 HexEncode(verify_result.public_key_hashes[1].data, SHA1_LENGTH)); 576 577 TestRootCerts::GetInstance()->Clear(); 578 } 579 580 // A regression test for http://crbug.com/70293. 581 // The Key Usage extension in this RSA SSL server certificate does not have 582 // the keyEncipherment bit. 583 TEST(X509CertificateTest, InvalidKeyUsage) { 584 FilePath certs_dir = GetTestCertsDirectory(); 585 586 scoped_refptr<X509Certificate> server_cert = 587 ImportCertFromFile(certs_dir, "invalid_key_usage_cert.der"); 588 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert); 589 590 int flags = 0; 591 CertVerifyResult verify_result; 592 int error = server_cert->Verify("jira.aquameta.com", flags, &verify_result); 593 #if defined(USE_OPENSSL) 594 // This certificate has two errors: "invalid key usage" and "untrusted CA". 595 // However, OpenSSL returns only one (the latter), and we can't detect 596 // the other errors. 597 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error); 598 #else 599 EXPECT_EQ(ERR_CERT_INVALID, error); 600 EXPECT_NE(0, verify_result.cert_status & CERT_STATUS_INVALID); 601 #endif 602 // TODO(wtc): fix http://crbug.com/75520 to get all the certificate errors 603 // from NSS. 604 #if !defined(USE_NSS) 605 // The certificate is issued by an unknown CA. 606 EXPECT_NE(0, verify_result.cert_status & CERT_STATUS_AUTHORITY_INVALID); 607 #endif 608 } 609 610 // Tests X509Certificate::Cache via X509Certificate::CreateFromHandle. We 611 // call X509Certificate::CreateFromHandle several times and observe whether 612 // it returns a cached or new X509Certificate object. 613 // 614 // All the OS certificate handles in this test are actually from the same 615 // source (the bytes of a lone certificate), but we pretend that some of them 616 // come from the network. 617 TEST(X509CertificateTest, Cache) { 618 X509Certificate::OSCertHandle google_cert_handle; 619 620 // Add a certificate from the source SOURCE_LONE_CERT_IMPORT to our 621 // certificate cache. 622 google_cert_handle = X509Certificate::CreateOSCertHandleFromBytes( 623 reinterpret_cast<const char*>(google_der), sizeof(google_der)); 624 scoped_refptr<X509Certificate> cert1(X509Certificate::CreateFromHandle( 625 google_cert_handle, X509Certificate::SOURCE_LONE_CERT_IMPORT, 626 X509Certificate::OSCertHandles())); 627 X509Certificate::FreeOSCertHandle(google_cert_handle); 628 629 // Add a certificate from the same source (SOURCE_LONE_CERT_IMPORT). This 630 // should return the cached certificate (cert1). 631 google_cert_handle = X509Certificate::CreateOSCertHandleFromBytes( 632 reinterpret_cast<const char*>(google_der), sizeof(google_der)); 633 scoped_refptr<X509Certificate> cert2(X509Certificate::CreateFromHandle( 634 google_cert_handle, X509Certificate::SOURCE_LONE_CERT_IMPORT, 635 X509Certificate::OSCertHandles())); 636 X509Certificate::FreeOSCertHandle(google_cert_handle); 637 638 EXPECT_EQ(cert1, cert2); 639 640 // Add a certificate from the network. This should kick out the original 641 // cached certificate (cert1) and return a new certificate. 642 google_cert_handle = X509Certificate::CreateOSCertHandleFromBytes( 643 reinterpret_cast<const char*>(google_der), sizeof(google_der)); 644 scoped_refptr<X509Certificate> cert3(X509Certificate::CreateFromHandle( 645 google_cert_handle, X509Certificate::SOURCE_FROM_NETWORK, 646 X509Certificate::OSCertHandles())); 647 X509Certificate::FreeOSCertHandle(google_cert_handle); 648 649 EXPECT_NE(cert1, cert3); 650 651 // Add one certificate from each source. Both should return the new cached 652 // certificate (cert3). 653 google_cert_handle = X509Certificate::CreateOSCertHandleFromBytes( 654 reinterpret_cast<const char*>(google_der), sizeof(google_der)); 655 scoped_refptr<X509Certificate> cert4(X509Certificate::CreateFromHandle( 656 google_cert_handle, X509Certificate::SOURCE_FROM_NETWORK, 657 X509Certificate::OSCertHandles())); 658 X509Certificate::FreeOSCertHandle(google_cert_handle); 659 660 EXPECT_EQ(cert3, cert4); 661 662 google_cert_handle = X509Certificate::CreateOSCertHandleFromBytes( 663 reinterpret_cast<const char*>(google_der), sizeof(google_der)); 664 scoped_refptr<X509Certificate> cert5(X509Certificate::CreateFromHandle( 665 google_cert_handle, X509Certificate::SOURCE_FROM_NETWORK, 666 X509Certificate::OSCertHandles())); 667 X509Certificate::FreeOSCertHandle(google_cert_handle); 668 669 EXPECT_EQ(cert3, cert5); 670 } 671 672 TEST(X509CertificateTest, Pickle) { 673 X509Certificate::OSCertHandle google_cert_handle = 674 X509Certificate::CreateOSCertHandleFromBytes( 675 reinterpret_cast<const char*>(google_der), sizeof(google_der)); 676 X509Certificate::OSCertHandle thawte_cert_handle = 677 X509Certificate::CreateOSCertHandleFromBytes( 678 reinterpret_cast<const char*>(thawte_der), sizeof(thawte_der)); 679 680 X509Certificate::OSCertHandles intermediates; 681 intermediates.push_back(thawte_cert_handle); 682 // Faking SOURCE_LONE_CERT_IMPORT so that when the pickled certificate is 683 // read, it successfully evicts |cert| from the X509Certificate::Cache. 684 // This will be fixed when http://crbug.com/49377 is fixed. 685 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle( 686 google_cert_handle, 687 X509Certificate::SOURCE_LONE_CERT_IMPORT, 688 intermediates); 689 ASSERT_NE(static_cast<X509Certificate*>(NULL), cert.get()); 690 691 X509Certificate::FreeOSCertHandle(google_cert_handle); 692 X509Certificate::FreeOSCertHandle(thawte_cert_handle); 693 694 Pickle pickle; 695 cert->Persist(&pickle); 696 697 void* iter = NULL; 698 scoped_refptr<X509Certificate> cert_from_pickle = 699 X509Certificate::CreateFromPickle( 700 pickle, &iter, X509Certificate::PICKLETYPE_CERTIFICATE_CHAIN); 701 ASSERT_NE(static_cast<X509Certificate*>(NULL), cert_from_pickle); 702 EXPECT_NE(cert.get(), cert_from_pickle.get()); 703 EXPECT_TRUE(X509Certificate::IsSameOSCert( 704 cert->os_cert_handle(), cert_from_pickle->os_cert_handle())); 705 EXPECT_TRUE(cert->HasIntermediateCertificates( 706 cert_from_pickle->GetIntermediateCertificates())); 707 } 708 709 TEST(X509CertificateTest, Policy) { 710 scoped_refptr<X509Certificate> google_cert(X509Certificate::CreateFromBytes( 711 reinterpret_cast<const char*>(google_der), sizeof(google_der))); 712 713 scoped_refptr<X509Certificate> webkit_cert(X509Certificate::CreateFromBytes( 714 reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der))); 715 716 CertPolicy policy; 717 718 EXPECT_EQ(policy.Check(google_cert.get()), CertPolicy::UNKNOWN); 719 EXPECT_EQ(policy.Check(webkit_cert.get()), CertPolicy::UNKNOWN); 720 EXPECT_FALSE(policy.HasAllowedCert()); 721 EXPECT_FALSE(policy.HasDeniedCert()); 722 723 policy.Allow(google_cert.get()); 724 725 EXPECT_EQ(policy.Check(google_cert.get()), CertPolicy::ALLOWED); 726 EXPECT_EQ(policy.Check(webkit_cert.get()), CertPolicy::UNKNOWN); 727 EXPECT_TRUE(policy.HasAllowedCert()); 728 EXPECT_FALSE(policy.HasDeniedCert()); 729 730 policy.Deny(google_cert.get()); 731 732 EXPECT_EQ(policy.Check(google_cert.get()), CertPolicy::DENIED); 733 EXPECT_EQ(policy.Check(webkit_cert.get()), CertPolicy::UNKNOWN); 734 EXPECT_FALSE(policy.HasAllowedCert()); 735 EXPECT_TRUE(policy.HasDeniedCert()); 736 737 policy.Allow(webkit_cert.get()); 738 739 EXPECT_EQ(policy.Check(google_cert.get()), CertPolicy::DENIED); 740 EXPECT_EQ(policy.Check(webkit_cert.get()), CertPolicy::ALLOWED); 741 EXPECT_TRUE(policy.HasAllowedCert()); 742 EXPECT_TRUE(policy.HasDeniedCert()); 743 } 744 745 #if defined(OS_MACOSX) || defined(OS_WIN) 746 TEST(X509CertificateTest, IntermediateCertificates) { 747 scoped_refptr<X509Certificate> webkit_cert( 748 X509Certificate::CreateFromBytes( 749 reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der))); 750 751 scoped_refptr<X509Certificate> thawte_cert( 752 X509Certificate::CreateFromBytes( 753 reinterpret_cast<const char*>(thawte_der), sizeof(thawte_der))); 754 755 scoped_refptr<X509Certificate> paypal_cert( 756 X509Certificate::CreateFromBytes( 757 reinterpret_cast<const char*>(paypal_null_der), 758 sizeof(paypal_null_der))); 759 760 X509Certificate::OSCertHandle google_handle; 761 // Create object with no intermediates: 762 google_handle = X509Certificate::CreateOSCertHandleFromBytes( 763 reinterpret_cast<const char*>(google_der), sizeof(google_der)); 764 X509Certificate::OSCertHandles intermediates1; 765 scoped_refptr<X509Certificate> cert1; 766 cert1 = X509Certificate::CreateFromHandle( 767 google_handle, X509Certificate::SOURCE_FROM_NETWORK, intermediates1); 768 EXPECT_TRUE(cert1->HasIntermediateCertificates(intermediates1)); 769 EXPECT_FALSE(cert1->HasIntermediateCertificate( 770 webkit_cert->os_cert_handle())); 771 772 // Create object with 2 intermediates: 773 X509Certificate::OSCertHandles intermediates2; 774 intermediates2.push_back(webkit_cert->os_cert_handle()); 775 intermediates2.push_back(thawte_cert->os_cert_handle()); 776 scoped_refptr<X509Certificate> cert2; 777 cert2 = X509Certificate::CreateFromHandle( 778 google_handle, X509Certificate::SOURCE_FROM_NETWORK, intermediates2); 779 780 // The cache should have stored cert2 'cause it has more intermediates: 781 EXPECT_NE(cert1, cert2); 782 783 // Verify it has all the intermediates: 784 EXPECT_TRUE(cert2->HasIntermediateCertificate( 785 webkit_cert->os_cert_handle())); 786 EXPECT_TRUE(cert2->HasIntermediateCertificate( 787 thawte_cert->os_cert_handle())); 788 EXPECT_FALSE(cert2->HasIntermediateCertificate( 789 paypal_cert->os_cert_handle())); 790 791 // Create object with 1 intermediate: 792 X509Certificate::OSCertHandles intermediates3; 793 intermediates2.push_back(thawte_cert->os_cert_handle()); 794 scoped_refptr<X509Certificate> cert3; 795 cert3 = X509Certificate::CreateFromHandle( 796 google_handle, X509Certificate::SOURCE_FROM_NETWORK, intermediates3); 797 798 // The cache should have returned cert2 'cause it has more intermediates: 799 EXPECT_EQ(cert3, cert2); 800 801 // Cleanup 802 X509Certificate::FreeOSCertHandle(google_handle); 803 } 804 #endif 805 806 #if defined(OS_MACOSX) 807 TEST(X509CertificateTest, IsIssuedBy) { 808 FilePath certs_dir = GetTestCertsDirectory(); 809 810 // Test a client certificate from MIT. 811 scoped_refptr<X509Certificate> mit_davidben_cert( 812 ImportCertFromFile(certs_dir, "mit.davidben.der")); 813 ASSERT_NE(static_cast<X509Certificate*>(NULL), mit_davidben_cert); 814 815 CertPrincipal mit_issuer; 816 mit_issuer.country_name = "US"; 817 mit_issuer.state_or_province_name = "Massachusetts"; 818 mit_issuer.organization_names.push_back( 819 "Massachusetts Institute of Technology"); 820 mit_issuer.organization_unit_names.push_back("Client CA v1"); 821 822 // IsIssuedBy should return true even if it cannot build a chain 823 // with that principal. 824 std::vector<CertPrincipal> mit_issuers(1, mit_issuer); 825 EXPECT_TRUE(mit_davidben_cert->IsIssuedBy(mit_issuers)); 826 827 // Test a client certificate from FOAF.ME. 828 scoped_refptr<X509Certificate> foaf_me_chromium_test_cert( 829 ImportCertFromFile(certs_dir, "foaf.me.chromium-test-cert.der")); 830 ASSERT_NE(static_cast<X509Certificate*>(NULL), foaf_me_chromium_test_cert); 831 832 CertPrincipal foaf_issuer; 833 foaf_issuer.common_name = "FOAF.ME"; 834 foaf_issuer.locality_name = "Wimbledon"; 835 foaf_issuer.state_or_province_name = "LONDON"; 836 foaf_issuer.country_name = "GB"; 837 foaf_issuer.organization_names.push_back("FOAF.ME"); 838 839 std::vector<CertPrincipal> foaf_issuers(1, foaf_issuer); 840 EXPECT_TRUE(foaf_me_chromium_test_cert->IsIssuedBy(foaf_issuers)); 841 842 // And test some combinations and mismatches. 843 std::vector<CertPrincipal> both_issuers; 844 both_issuers.push_back(mit_issuer); 845 both_issuers.push_back(foaf_issuer); 846 EXPECT_TRUE(foaf_me_chromium_test_cert->IsIssuedBy(both_issuers)); 847 EXPECT_TRUE(mit_davidben_cert->IsIssuedBy(both_issuers)); 848 EXPECT_FALSE(foaf_me_chromium_test_cert->IsIssuedBy(mit_issuers)); 849 EXPECT_FALSE(mit_davidben_cert->IsIssuedBy(foaf_issuers)); 850 } 851 #endif // defined(OS_MACOSX) 852 853 #if defined(USE_NSS) || defined(OS_WIN) || defined(OS_MACOSX) 854 // This test creates a self-signed cert from a private key and then verify the 855 // content of the certificate. 856 TEST(X509CertificateTest, CreateSelfSigned) { 857 scoped_ptr<crypto::RSAPrivateKey> private_key( 858 crypto::RSAPrivateKey::Create(1024)); 859 scoped_refptr<X509Certificate> cert = 860 X509Certificate::CreateSelfSigned( 861 private_key.get(), "CN=subject", 1, base::TimeDelta::FromDays(1)); 862 863 EXPECT_EQ("subject", cert->subject().GetDisplayName()); 864 EXPECT_FALSE(cert->HasExpired()); 865 866 const uint8 private_key_info[] = { 867 0x30, 0x82, 0x02, 0x78, 0x02, 0x01, 0x00, 0x30, 868 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 869 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 870 0x02, 0x62, 0x30, 0x82, 0x02, 0x5e, 0x02, 0x01, 871 0x00, 0x02, 0x81, 0x81, 0x00, 0xb8, 0x7f, 0x2b, 872 0x20, 0xdc, 0x7c, 0x9b, 0x0c, 0xdc, 0x51, 0x61, 873 0x99, 0x0d, 0x36, 0x0f, 0xd4, 0x66, 0x88, 0x08, 874 0x55, 0x84, 0xd5, 0x3a, 0xbf, 0x2b, 0xa4, 0x64, 875 0x85, 0x7b, 0x0c, 0x04, 0x13, 0x3f, 0x8d, 0xf4, 876 0xbc, 0x38, 0x0d, 0x49, 0xfe, 0x6b, 0xc4, 0x5a, 877 0xb0, 0x40, 0x53, 0x3a, 0xd7, 0x66, 0x09, 0x0f, 878 0x9e, 0x36, 0x74, 0x30, 0xda, 0x8a, 0x31, 0x4f, 879 0x1f, 0x14, 0x50, 0xd7, 0xc7, 0x20, 0x94, 0x17, 880 0xde, 0x4e, 0xb9, 0x57, 0x5e, 0x7e, 0x0a, 0xe5, 881 0xb2, 0x65, 0x7a, 0x89, 0x4e, 0xb6, 0x47, 0xff, 882 0x1c, 0xbd, 0xb7, 0x38, 0x13, 0xaf, 0x47, 0x85, 883 0x84, 0x32, 0x33, 0xf3, 0x17, 0x49, 0xbf, 0xe9, 884 0x96, 0xd0, 0xd6, 0x14, 0x6f, 0x13, 0x8d, 0xc5, 885 0xfc, 0x2c, 0x72, 0xba, 0xac, 0xea, 0x7e, 0x18, 886 0x53, 0x56, 0xa6, 0x83, 0xa2, 0xce, 0x93, 0x93, 887 0xe7, 0x1f, 0x0f, 0xe6, 0x0f, 0x02, 0x03, 0x01, 888 0x00, 0x01, 0x02, 0x81, 0x80, 0x03, 0x61, 0x89, 889 0x37, 0xcb, 0xf2, 0x98, 0xa0, 0xce, 0xb4, 0xcb, 890 0x16, 0x13, 0xf0, 0xe6, 0xaf, 0x5c, 0xc5, 0xa7, 891 0x69, 0x71, 0xca, 0xba, 0x8d, 0xe0, 0x4d, 0xdd, 892 0xed, 0xb8, 0x48, 0x8b, 0x16, 0x93, 0x36, 0x95, 893 0xc2, 0x91, 0x40, 0x65, 0x17, 0xbd, 0x7f, 0xd6, 894 0xad, 0x9e, 0x30, 0x28, 0x46, 0xe4, 0x3e, 0xcc, 895 0x43, 0x78, 0xf9, 0xfe, 0x1f, 0x33, 0x23, 0x1e, 896 0x31, 0x12, 0x9d, 0x3c, 0xa7, 0x08, 0x82, 0x7b, 897 0x7d, 0x25, 0x4e, 0x5e, 0x19, 0xa8, 0x9b, 0xed, 898 0x86, 0xb2, 0xcb, 0x3c, 0xfe, 0x4e, 0xa1, 0xfa, 899 0x62, 0x87, 0x3a, 0x17, 0xf7, 0x60, 0xec, 0x38, 900 0x29, 0xe8, 0x4f, 0x34, 0x9f, 0x76, 0x9d, 0xee, 901 0xa3, 0xf6, 0x85, 0x6b, 0x84, 0x43, 0xc9, 0x1e, 902 0x01, 0xff, 0xfd, 0xd0, 0x29, 0x4c, 0xfa, 0x8e, 903 0x57, 0x0c, 0xc0, 0x71, 0xa5, 0xbb, 0x88, 0x46, 904 0x29, 0x5c, 0xc0, 0x4f, 0x01, 0x02, 0x41, 0x00, 905 0xf5, 0x83, 0xa4, 0x64, 0x4a, 0xf2, 0xdd, 0x8c, 906 0x2c, 0xed, 0xa8, 0xd5, 0x60, 0x5a, 0xe4, 0xc7, 907 0xcc, 0x61, 0xcd, 0x38, 0x42, 0x20, 0xd3, 0x82, 908 0x18, 0xf2, 0x35, 0x00, 0x72, 0x2d, 0xf7, 0x89, 909 0x80, 0x67, 0xb5, 0x93, 0x05, 0x5f, 0xdd, 0x42, 910 0xba, 0x16, 0x1a, 0xea, 0x15, 0xc6, 0xf0, 0xb8, 911 0x8c, 0xbc, 0xbf, 0x54, 0x9e, 0xf1, 0xc1, 0xb2, 912 0xb3, 0x8b, 0xb6, 0x26, 0x02, 0x30, 0xc4, 0x81, 913 0x02, 0x41, 0x00, 0xc0, 0x60, 0x62, 0x80, 0xe1, 914 0x22, 0x78, 0xf6, 0x9d, 0x83, 0x18, 0xeb, 0x72, 915 0x45, 0xd7, 0xc8, 0x01, 0x7f, 0xa9, 0xca, 0x8f, 916 0x7d, 0xd6, 0xb8, 0x31, 0x2b, 0x84, 0x7f, 0x62, 917 0xd9, 0xa9, 0x22, 0x17, 0x7d, 0x06, 0x35, 0x6c, 918 0xf3, 0xc1, 0x94, 0x17, 0x85, 0x5a, 0xaf, 0x9c, 919 0x5c, 0x09, 0x3c, 0xcf, 0x2f, 0x44, 0x9d, 0xb6, 920 0x52, 0x68, 0x5f, 0xf9, 0x59, 0xc8, 0x84, 0x2b, 921 0x39, 0x22, 0x8f, 0x02, 0x41, 0x00, 0xb2, 0x04, 922 0xe2, 0x0e, 0x56, 0xca, 0x03, 0x1a, 0xc0, 0xf9, 923 0x12, 0x92, 0xa5, 0x6b, 0x42, 0xb8, 0x1c, 0xda, 924 0x4d, 0x93, 0x9d, 0x5f, 0x6f, 0xfd, 0xc5, 0x58, 925 0xda, 0x55, 0x98, 0x74, 0xfc, 0x28, 0x17, 0x93, 926 0x1b, 0x75, 0x9f, 0x50, 0x03, 0x7f, 0x7e, 0xae, 927 0xc8, 0x95, 0x33, 0x75, 0x2c, 0xd6, 0xa4, 0x35, 928 0xb8, 0x06, 0x03, 0xba, 0x08, 0x59, 0x2b, 0x17, 929 0x02, 0xdc, 0x4c, 0x7a, 0x50, 0x01, 0x02, 0x41, 930 0x00, 0x9d, 0xdb, 0x39, 0x59, 0x09, 0xe4, 0x30, 931 0xa0, 0x24, 0xf5, 0xdb, 0x2f, 0xf0, 0x2f, 0xf1, 932 0x75, 0x74, 0x0d, 0x5e, 0xb5, 0x11, 0x73, 0xb0, 933 0x0a, 0xaa, 0x86, 0x4c, 0x0d, 0xff, 0x7e, 0x1d, 934 0xb4, 0x14, 0xd4, 0x09, 0x91, 0x33, 0x5a, 0xfd, 935 0xa0, 0x58, 0x80, 0x9b, 0xbe, 0x78, 0x2e, 0x69, 936 0x82, 0x15, 0x7c, 0x72, 0xf0, 0x7b, 0x18, 0x39, 937 0xff, 0x6e, 0xeb, 0xc6, 0x86, 0xf5, 0xb4, 0xc7, 938 0x6f, 0x02, 0x41, 0x00, 0x8d, 0x1a, 0x37, 0x0f, 939 0x76, 0xc4, 0x82, 0xfa, 0x5c, 0xc3, 0x79, 0x35, 940 0x3e, 0x70, 0x8a, 0xbf, 0x27, 0x49, 0xb0, 0x99, 941 0x63, 0xcb, 0x77, 0x5f, 0xa8, 0x82, 0x65, 0xf6, 942 0x03, 0x52, 0x51, 0xf1, 0xae, 0x2e, 0x05, 0xb3, 943 0xc6, 0xa4, 0x92, 0xd1, 0xce, 0x6c, 0x72, 0xfb, 944 0x21, 0xb3, 0x02, 0x87, 0xe4, 0xfd, 0x61, 0xca, 945 0x00, 0x42, 0x19, 0xf0, 0xda, 0x5a, 0x53, 0xe3, 946 0xb1, 0xc5, 0x15, 0xf3 947 }; 948 949 std::vector<uint8> input; 950 input.resize(sizeof(private_key_info)); 951 memcpy(&input.front(), private_key_info, sizeof(private_key_info)); 952 953 private_key.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(input)); 954 ASSERT_TRUE(private_key.get()); 955 956 cert = X509Certificate::CreateSelfSigned( 957 private_key.get(), "CN=subject", 1, base::TimeDelta::FromDays(1)); 958 959 EXPECT_EQ("subject", cert->subject().GetDisplayName()); 960 EXPECT_FALSE(cert->HasExpired()); 961 } 962 963 TEST(X509CertificateTest, GetDEREncoded) { 964 scoped_ptr<crypto::RSAPrivateKey> private_key( 965 crypto::RSAPrivateKey::Create(1024)); 966 scoped_refptr<X509Certificate> cert = 967 X509Certificate::CreateSelfSigned( 968 private_key.get(), "CN=subject", 0, base::TimeDelta::FromDays(1)); 969 970 std::string der_cert; 971 EXPECT_TRUE(cert->GetDEREncoded(&der_cert)); 972 EXPECT_FALSE(der_cert.empty()); 973 } 974 #endif 975 976 class X509CertificateParseTest 977 : public testing::TestWithParam<CertificateFormatTestData> { 978 public: 979 virtual ~X509CertificateParseTest() {} 980 virtual void SetUp() { 981 test_data_ = GetParam(); 982 } 983 virtual void TearDown() {} 984 985 protected: 986 CertificateFormatTestData test_data_; 987 }; 988 989 TEST_P(X509CertificateParseTest, CanParseFormat) { 990 FilePath certs_dir = GetTestCertsDirectory(); 991 CertificateList certs = CreateCertificateListFromFile( 992 certs_dir, test_data_.file_name, test_data_.format); 993 ASSERT_FALSE(certs.empty()); 994 ASSERT_LE(certs.size(), arraysize(test_data_.chain_fingerprints)); 995 CheckGoogleCert(certs.front(), google_parse_fingerprint, 996 kGoogleParseValidFrom, kGoogleParseValidTo); 997 998 size_t i; 999 for (i = 0; i < arraysize(test_data_.chain_fingerprints); ++i) { 1000 if (test_data_.chain_fingerprints[i] == NULL) { 1001 // No more test certificates expected - make sure no more were 1002 // returned before marking this test a success. 1003 EXPECT_EQ(i, certs.size()); 1004 break; 1005 } 1006 1007 // A cert is expected - make sure that one was parsed. 1008 ASSERT_LT(i, certs.size()); 1009 1010 // Compare the parsed certificate with the expected certificate, by 1011 // comparing fingerprints. 1012 const X509Certificate* cert = certs[i]; 1013 const SHA1Fingerprint& actual_fingerprint = cert->fingerprint(); 1014 unsigned char* expected_fingerprint = test_data_.chain_fingerprints[i]; 1015 1016 for (size_t j = 0; j < 20; ++j) 1017 EXPECT_EQ(expected_fingerprint[j], actual_fingerprint.data[j]); 1018 } 1019 } 1020 1021 INSTANTIATE_TEST_CASE_P(, X509CertificateParseTest, 1022 testing::ValuesIn(FormatTestData)); 1023 1024 struct CertificateNameVerifyTestData { 1025 // true iff we expect hostname to match an entry in cert_names. 1026 bool expected; 1027 // The hostname to match. 1028 const char* hostname; 1029 // '/' separated list of certificate names to match against. Any occurrence 1030 // of '#' will be replaced with a null character before processing. 1031 const char* cert_names; 1032 }; 1033 1034 // Required by valgrind on mac, otherwise it complains when using its default 1035 // printer: 1036 // UninitCondition 1037 // Conditional jump or move depends on uninitialised value(s) 1038 // ... 1039 // snprintf 1040 // testing::(anonymous namespace)::PrintByteSegmentInObjectTo 1041 // testing::internal2::TypeWithoutFormatter 1042 // ... 1043 void PrintTo(const CertificateNameVerifyTestData& data, std::ostream* os) { 1044 *os << " expected: " << data.expected << ", hostname: " 1045 << data.hostname << ", cert_names: " << data.cert_names; 1046 } 1047 1048 const CertificateNameVerifyTestData kNameVerifyTestData[] = { 1049 { true, "foo.com", "foo.com" }, 1050 { true, "foo.com", "foo.com." }, 1051 { true, "f", "f" }, 1052 { true, "f", "f." }, 1053 { true, "bar.foo.com", "*.foo.com" }, 1054 { true, "www-3.bar.foo.com", "*.bar.foo.com." }, 1055 { true, "www.test.fr", "*.test.com/*.test.co.uk/*.test.de/*.test.fr" }, 1056 { true, "wwW.tESt.fr", "//*.*/*.test.de/*.test.FR/www" }, 1057 { false, "foo.com", "*.com" }, 1058 { false, "f.uk", ".uk" }, 1059 { true, "h.co.uk", "*.co.uk" }, 1060 { false, "192.168.1.11", "*.168.1.11" }, 1061 { false, "foo.us", "*.us" }, 1062 { false, "www.bar.foo.com", 1063 "*.foo.com/*.*.foo.com/*.*.bar.foo.com/*w*.bar.foo.com/*..bar.foo.com" }, 1064 { false, "w.bar.foo.com", "?.bar.foo.com" }, 1065 { false, "www.foo.com", "(www|ftp).foo.com" }, 1066 { false, "www.foo.com", "www.foo.com#*.foo.com/#" }, // # = null char. 1067 { false, "foo", "*" }, 1068 { false, "foo.", "*." }, 1069 { false, "test.org", "www.test.org/*.test.org/*.org" }, 1070 { false, "1.2.3.4.5.6", "*.2.3.4.5.6" }, 1071 // IDN tests 1072 { true, "xn--poema-9qae5a.com.br", "xn--poema-9qae5a.com.br" }, 1073 { true, "www.xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br" }, 1074 { false, "xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br" }, 1075 // The following are adapted from the examples in 1076 // http://tools.ietf.org/html/draft-saintandre-tls-server-id-check-09#section-4.4.3 1077 { true, "foo.example.com", "*.example.com" }, 1078 { false, "bar.foo.example.com", "*.example.com" }, 1079 { false, "example.com", "*.example.com" }, 1080 { false, "baz1.example.net", "baz*.example.net" }, 1081 { false, "baz2.example.net", "baz*.example.net" }, 1082 { false, "bar.*.example.net", "bar.*.example.net" }, 1083 { false, "bar.f*o.example.net", "bar.f*o.example.net" }, 1084 // IP addresses currently not supported, except for the localhost. 1085 { true, "127.0.0.1", "127.0.0.1" }, 1086 { false, "192.168.1.1", "192.168.1.1" }, 1087 { false, "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210", 1088 "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210" }, 1089 { false, "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210", "*.]" }, 1090 { false, "::192.9.5.5", "::192.9.5.5" }, 1091 { false, "::192.9.5.5", "*.9.5.5" }, 1092 { false, "2010:836B:4179::836B:4179", "*:836B:4179::836B:4179" }, 1093 // Invalid host names. 1094 { false, "www%26.foo.com", "www%26.foo.com" }, 1095 { false, "www.*.com", "www.*.com" }, 1096 { false, "w$w.f.com", "w$w.f.com" }, 1097 { false, "www-1.[::FFFF:129.144.52.38]", "*.[::FFFF:129.144.52.38]" }, 1098 }; 1099 1100 class X509CertificateNameVerifyTest 1101 : public testing::TestWithParam<CertificateNameVerifyTestData> { 1102 }; 1103 1104 TEST_P(X509CertificateNameVerifyTest, VerifyHostname) { 1105 CertificateNameVerifyTestData test_data = GetParam(); 1106 1107 std::string cert_name_line(test_data.cert_names); 1108 std::replace(cert_name_line.begin(), cert_name_line.end(), '#', '\0'); 1109 std::vector<std::string> cert_names; 1110 base::SplitString(cert_name_line, '/', &cert_names); 1111 1112 EXPECT_EQ(test_data.expected, 1113 X509Certificate::VerifyHostname(test_data.hostname, cert_names)) 1114 << "Host [" << test_data.hostname 1115 << "], cert name [" << test_data.cert_names << "]"; 1116 } 1117 1118 INSTANTIATE_TEST_CASE_P(, X509CertificateNameVerifyTest, 1119 testing::ValuesIn(kNameVerifyTestData)); 1120 1121 } // namespace net 1122