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/cert_verify_proc.h" 6 7 #include <vector> 8 9 #include "base/files/file_path.h" 10 #include "base/logging.h" 11 #include "base/sha1.h" 12 #include "base/strings/string_number_conversions.h" 13 #include "crypto/sha2.h" 14 #include "net/base/net_errors.h" 15 #include "net/base/test_data_directory.h" 16 #include "net/cert/asn1_util.h" 17 #include "net/cert/cert_status_flags.h" 18 #include "net/cert/cert_verifier.h" 19 #include "net/cert/cert_verify_result.h" 20 #include "net/cert/crl_set.h" 21 #include "net/cert/test_root_certs.h" 22 #include "net/cert/x509_certificate.h" 23 #include "net/test/cert_test_util.h" 24 #include "net/test/test_certificate_data.h" 25 #include "testing/gtest/include/gtest/gtest.h" 26 27 #if defined(OS_WIN) 28 #include "base/win/windows_version.h" 29 #elif defined(OS_MACOSX) && !defined(OS_IOS) 30 #include "base/mac/mac_util.h" 31 #endif 32 33 using base::HexEncode; 34 35 namespace net { 36 37 namespace { 38 39 // A certificate for www.paypal.com with a NULL byte in the common name. 40 // From http://www.gossamer-threads.com/lists/fulldisc/full-disclosure/70363 41 unsigned char paypal_null_fingerprint[] = { 42 0x4c, 0x88, 0x9e, 0x28, 0xd7, 0x7a, 0x44, 0x1e, 0x13, 0xf2, 0x6a, 0xba, 43 0x1f, 0xe8, 0x1b, 0xd6, 0xab, 0x7b, 0xe8, 0xd7 44 }; 45 46 // Mock CertVerifyProc that will set |verify_result->is_issued_by_known_root| 47 // for all certificates that are Verified. 48 class WellKnownCaCertVerifyProc : public CertVerifyProc { 49 public: 50 // Initialize a CertVerifyProc that will set 51 // |verify_result->is_issued_by_known_root| to |is_well_known|. 52 explicit WellKnownCaCertVerifyProc(bool is_well_known) 53 : is_well_known_(is_well_known) {} 54 55 // CertVerifyProc implementation: 56 virtual bool SupportsAdditionalTrustAnchors() const OVERRIDE { return false; } 57 58 protected: 59 virtual ~WellKnownCaCertVerifyProc() {} 60 61 private: 62 virtual int VerifyInternal(X509Certificate* cert, 63 const std::string& hostname, 64 int flags, 65 CRLSet* crl_set, 66 const CertificateList& additional_trust_anchors, 67 CertVerifyResult* verify_result) OVERRIDE; 68 69 const bool is_well_known_; 70 71 DISALLOW_COPY_AND_ASSIGN(WellKnownCaCertVerifyProc); 72 }; 73 74 int WellKnownCaCertVerifyProc::VerifyInternal( 75 X509Certificate* cert, 76 const std::string& hostname, 77 int flags, 78 CRLSet* crl_set, 79 const CertificateList& additional_trust_anchors, 80 CertVerifyResult* verify_result) { 81 verify_result->is_issued_by_known_root = is_well_known_; 82 return OK; 83 } 84 85 } // namespace 86 87 class CertVerifyProcTest : public testing::Test { 88 public: 89 CertVerifyProcTest() 90 : verify_proc_(CertVerifyProc::CreateDefault()) { 91 } 92 virtual ~CertVerifyProcTest() {} 93 94 protected: 95 bool SupportsAdditionalTrustAnchors() { 96 return verify_proc_->SupportsAdditionalTrustAnchors(); 97 } 98 99 int Verify(X509Certificate* cert, 100 const std::string& hostname, 101 int flags, 102 CRLSet* crl_set, 103 const CertificateList& additional_trust_anchors, 104 CertVerifyResult* verify_result) { 105 return verify_proc_->Verify(cert, hostname, flags, crl_set, 106 additional_trust_anchors, verify_result); 107 } 108 109 const CertificateList empty_cert_list_; 110 scoped_refptr<CertVerifyProc> verify_proc_; 111 }; 112 113 TEST_F(CertVerifyProcTest, WithoutRevocationChecking) { 114 // Check that verification without revocation checking works. 115 CertificateList certs = CreateCertificateListFromFile( 116 GetTestCertsDirectory(), 117 "googlenew.chain.pem", 118 X509Certificate::FORMAT_PEM_CERT_SEQUENCE); 119 120 X509Certificate::OSCertHandles intermediates; 121 intermediates.push_back(certs[1]->os_cert_handle()); 122 123 scoped_refptr<X509Certificate> google_full_chain = 124 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(), 125 intermediates); 126 127 CertVerifyResult verify_result; 128 EXPECT_EQ(OK, 129 Verify(google_full_chain.get(), 130 "www.google.com", 131 0 /* flags */, 132 NULL, 133 empty_cert_list_, 134 &verify_result)); 135 } 136 137 #if defined(OS_ANDROID) || defined(USE_OPENSSL) 138 // TODO(jnd): http://crbug.com/117478 - EV verification is not yet supported. 139 #define MAYBE_EVVerification DISABLED_EVVerification 140 #else 141 #define MAYBE_EVVerification EVVerification 142 #endif 143 TEST_F(CertVerifyProcTest, MAYBE_EVVerification) { 144 CertificateList certs = CreateCertificateListFromFile( 145 GetTestCertsDirectory(), 146 "comodo.chain.pem", 147 X509Certificate::FORMAT_PEM_CERT_SEQUENCE); 148 ASSERT_EQ(3U, certs.size()); 149 150 X509Certificate::OSCertHandles intermediates; 151 intermediates.push_back(certs[1]->os_cert_handle()); 152 intermediates.push_back(certs[2]->os_cert_handle()); 153 154 scoped_refptr<X509Certificate> comodo_chain = 155 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(), 156 intermediates); 157 158 scoped_refptr<CRLSet> crl_set(CRLSet::ForTesting(false, NULL, "")); 159 CertVerifyResult verify_result; 160 int flags = CertVerifier::VERIFY_EV_CERT; 161 int error = Verify(comodo_chain.get(), 162 "comodo.com", 163 flags, 164 crl_set.get(), 165 empty_cert_list_, 166 &verify_result); 167 EXPECT_EQ(OK, error); 168 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV); 169 } 170 171 TEST_F(CertVerifyProcTest, PaypalNullCertParsing) { 172 scoped_refptr<X509Certificate> paypal_null_cert( 173 X509Certificate::CreateFromBytes( 174 reinterpret_cast<const char*>(paypal_null_der), 175 sizeof(paypal_null_der))); 176 177 ASSERT_NE(static_cast<X509Certificate*>(NULL), paypal_null_cert); 178 179 const SHA1HashValue& fingerprint = 180 paypal_null_cert->fingerprint(); 181 for (size_t i = 0; i < 20; ++i) 182 EXPECT_EQ(paypal_null_fingerprint[i], fingerprint.data[i]); 183 184 int flags = 0; 185 CertVerifyResult verify_result; 186 int error = Verify(paypal_null_cert.get(), 187 "www.paypal.com", 188 flags, 189 NULL, 190 empty_cert_list_, 191 &verify_result); 192 #if defined(USE_NSS) || defined(OS_IOS) || defined(OS_ANDROID) 193 EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, error); 194 #else 195 // TOOD(bulach): investigate why macosx and win aren't returning 196 // ERR_CERT_INVALID or ERR_CERT_COMMON_NAME_INVALID. 197 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error); 198 #endif 199 // Either the system crypto library should correctly report a certificate 200 // name mismatch, or our certificate blacklist should cause us to report an 201 // invalid certificate. 202 #if defined(USE_NSS) || defined(OS_WIN) || defined(OS_IOS) 203 EXPECT_TRUE(verify_result.cert_status & 204 (CERT_STATUS_COMMON_NAME_INVALID | CERT_STATUS_INVALID)); 205 #endif 206 } 207 208 // A regression test for http://crbug.com/31497. 209 #if defined(OS_ANDROID) 210 // Disabled on Android, as the Android verification libraries require an 211 // explicit policy to be specified, even when anyPolicy is permitted. 212 #define MAYBE_IntermediateCARequireExplicitPolicy \ 213 DISABLED_IntermediateCARequireExplicitPolicy 214 #else 215 #define MAYBE_IntermediateCARequireExplicitPolicy \ 216 IntermediateCARequireExplicitPolicy 217 #endif 218 TEST_F(CertVerifyProcTest, MAYBE_IntermediateCARequireExplicitPolicy) { 219 base::FilePath certs_dir = GetTestCertsDirectory(); 220 221 CertificateList certs = CreateCertificateListFromFile( 222 certs_dir, "explicit-policy-chain.pem", 223 X509Certificate::FORMAT_AUTO); 224 ASSERT_EQ(3U, certs.size()); 225 226 X509Certificate::OSCertHandles intermediates; 227 intermediates.push_back(certs[1]->os_cert_handle()); 228 229 scoped_refptr<X509Certificate> cert = 230 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(), 231 intermediates); 232 ASSERT_TRUE(cert.get()); 233 234 ScopedTestRoot scoped_root(certs[2].get()); 235 236 int flags = 0; 237 CertVerifyResult verify_result; 238 int error = Verify(cert.get(), 239 "policy_test.example", 240 flags, 241 NULL, 242 empty_cert_list_, 243 &verify_result); 244 EXPECT_EQ(OK, error); 245 EXPECT_EQ(0u, verify_result.cert_status); 246 } 247 248 249 // Test for bug 58437. 250 // This certificate will expire on 2011-12-21. The test will still 251 // pass if error == ERR_CERT_DATE_INVALID. 252 // This test is DISABLED because it appears that we cannot do 253 // certificate revocation checking when running all of the net unit tests. 254 // This test passes when run individually, but when run with all of the net 255 // unit tests, the call to PKIXVerifyCert returns the NSS error -8180, which is 256 // SEC_ERROR_REVOKED_CERTIFICATE. This indicates a lack of revocation 257 // status, i.e. that the revocation check is failing for some reason. 258 TEST_F(CertVerifyProcTest, DISABLED_GlobalSignR3EVTest) { 259 base::FilePath certs_dir = GetTestCertsDirectory(); 260 261 scoped_refptr<X509Certificate> server_cert = 262 ImportCertFromFile(certs_dir, "2029_globalsign_com_cert.pem"); 263 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert); 264 265 scoped_refptr<X509Certificate> intermediate_cert = 266 ImportCertFromFile(certs_dir, "globalsign_ev_sha256_ca_cert.pem"); 267 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert); 268 269 X509Certificate::OSCertHandles intermediates; 270 intermediates.push_back(intermediate_cert->os_cert_handle()); 271 scoped_refptr<X509Certificate> cert_chain = 272 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(), 273 intermediates); 274 275 CertVerifyResult verify_result; 276 int flags = CertVerifier::VERIFY_REV_CHECKING_ENABLED | 277 CertVerifier::VERIFY_EV_CERT; 278 int error = Verify(cert_chain.get(), 279 "2029.globalsign.com", 280 flags, 281 NULL, 282 empty_cert_list_, 283 &verify_result); 284 if (error == OK) 285 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV); 286 else 287 EXPECT_EQ(ERR_CERT_DATE_INVALID, error); 288 } 289 290 // Test that verifying an ECDSA certificate doesn't crash on XP. (See 291 // crbug.com/144466). 292 TEST_F(CertVerifyProcTest, ECDSA_RSA) { 293 base::FilePath certs_dir = GetTestCertsDirectory(); 294 295 scoped_refptr<X509Certificate> cert = 296 ImportCertFromFile(certs_dir, 297 "prime256v1-ecdsa-ee-by-1024-rsa-intermediate.pem"); 298 299 CertVerifyResult verify_result; 300 Verify(cert.get(), "127.0.0.1", 0, NULL, empty_cert_list_, &verify_result); 301 302 // We don't check verify_result because the certificate is signed by an 303 // unknown CA and will be considered invalid on XP because of the ECDSA 304 // public key. 305 } 306 307 // Currently, only RSA and DSA keys are checked for weakness, and our example 308 // weak size is 768. These could change in the future. 309 // 310 // Note that this means there may be false negatives: keys for other 311 // algorithms and which are weak will pass this test. 312 static bool IsWeakKeyType(const std::string& key_type) { 313 size_t pos = key_type.find("-"); 314 std::string size = key_type.substr(0, pos); 315 std::string type = key_type.substr(pos + 1); 316 317 if (type == "rsa" || type == "dsa") 318 return size == "768"; 319 320 return false; 321 } 322 323 TEST_F(CertVerifyProcTest, RejectWeakKeys) { 324 base::FilePath certs_dir = GetTestCertsDirectory(); 325 typedef std::vector<std::string> Strings; 326 Strings key_types; 327 328 // generate-weak-test-chains.sh currently has: 329 // key_types="768-rsa 1024-rsa 2048-rsa prime256v1-ecdsa" 330 // We must use the same key types here. The filenames generated look like: 331 // 2048-rsa-ee-by-768-rsa-intermediate.pem 332 key_types.push_back("768-rsa"); 333 key_types.push_back("1024-rsa"); 334 key_types.push_back("2048-rsa"); 335 336 bool use_ecdsa = true; 337 #if defined(OS_WIN) 338 use_ecdsa = base::win::GetVersion() > base::win::VERSION_XP; 339 #endif 340 341 if (use_ecdsa) 342 key_types.push_back("prime256v1-ecdsa"); 343 344 // Add the root that signed the intermediates for this test. 345 scoped_refptr<X509Certificate> root_cert = 346 ImportCertFromFile(certs_dir, "2048-rsa-root.pem"); 347 ASSERT_NE(static_cast<X509Certificate*>(NULL), root_cert); 348 ScopedTestRoot scoped_root(root_cert.get()); 349 350 // Now test each chain. 351 for (Strings::const_iterator ee_type = key_types.begin(); 352 ee_type != key_types.end(); ++ee_type) { 353 for (Strings::const_iterator signer_type = key_types.begin(); 354 signer_type != key_types.end(); ++signer_type) { 355 std::string basename = *ee_type + "-ee-by-" + *signer_type + 356 "-intermediate.pem"; 357 SCOPED_TRACE(basename); 358 scoped_refptr<X509Certificate> ee_cert = 359 ImportCertFromFile(certs_dir, basename); 360 ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_cert); 361 362 basename = *signer_type + "-intermediate.pem"; 363 scoped_refptr<X509Certificate> intermediate = 364 ImportCertFromFile(certs_dir, basename); 365 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate); 366 367 X509Certificate::OSCertHandles intermediates; 368 intermediates.push_back(intermediate->os_cert_handle()); 369 scoped_refptr<X509Certificate> cert_chain = 370 X509Certificate::CreateFromHandle(ee_cert->os_cert_handle(), 371 intermediates); 372 373 CertVerifyResult verify_result; 374 int error = Verify(cert_chain.get(), 375 "127.0.0.1", 376 0, 377 NULL, 378 empty_cert_list_, 379 &verify_result); 380 381 if (IsWeakKeyType(*ee_type) || IsWeakKeyType(*signer_type)) { 382 EXPECT_NE(OK, error); 383 EXPECT_EQ(CERT_STATUS_WEAK_KEY, 384 verify_result.cert_status & CERT_STATUS_WEAK_KEY); 385 EXPECT_NE(CERT_STATUS_INVALID, 386 verify_result.cert_status & CERT_STATUS_INVALID); 387 } else { 388 EXPECT_EQ(OK, error); 389 EXPECT_EQ(0U, verify_result.cert_status & CERT_STATUS_WEAK_KEY); 390 } 391 } 392 } 393 } 394 395 // Regression test for http://crbug.com/108514. 396 #if defined(OS_MACOSX) && !defined(OS_IOS) 397 // Disabled on OS X - Security.framework doesn't ignore superflous certificates 398 // provided by servers. See CertVerifyProcTest.CybertrustGTERoot for further 399 // details. 400 #define MAYBE_ExtraneousMD5RootCert DISABLED_ExtraneousMD5RootCert 401 #elif defined(USE_OPENSSL) || defined(OS_ANDROID) 402 // Disabled for OpenSSL / Android - Android and OpenSSL do not attempt to find 403 // a minimal certificate chain, thus prefer the MD5 root over the SHA-1 root. 404 #define MAYBE_ExtraneousMD5RootCert DISABLED_ExtraneousMD5RootCert 405 #else 406 #define MAYBE_ExtraneousMD5RootCert ExtraneousMD5RootCert 407 #endif 408 TEST_F(CertVerifyProcTest, MAYBE_ExtraneousMD5RootCert) { 409 base::FilePath certs_dir = GetTestCertsDirectory(); 410 411 scoped_refptr<X509Certificate> server_cert = 412 ImportCertFromFile(certs_dir, "cross-signed-leaf.pem"); 413 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert.get()); 414 415 scoped_refptr<X509Certificate> extra_cert = 416 ImportCertFromFile(certs_dir, "cross-signed-root-md5.pem"); 417 ASSERT_NE(static_cast<X509Certificate*>(NULL), extra_cert.get()); 418 419 scoped_refptr<X509Certificate> root_cert = 420 ImportCertFromFile(certs_dir, "cross-signed-root-sha1.pem"); 421 ASSERT_NE(static_cast<X509Certificate*>(NULL), root_cert.get()); 422 423 ScopedTestRoot scoped_root(root_cert.get()); 424 425 X509Certificate::OSCertHandles intermediates; 426 intermediates.push_back(extra_cert->os_cert_handle()); 427 scoped_refptr<X509Certificate> cert_chain = 428 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(), 429 intermediates); 430 431 CertVerifyResult verify_result; 432 int flags = 0; 433 int error = Verify(cert_chain.get(), 434 "127.0.0.1", 435 flags, 436 NULL, 437 empty_cert_list_, 438 &verify_result); 439 EXPECT_EQ(OK, error); 440 441 // The extra MD5 root should be discarded 442 ASSERT_TRUE(verify_result.verified_cert.get()); 443 ASSERT_EQ(1u, 444 verify_result.verified_cert->GetIntermediateCertificates().size()); 445 EXPECT_TRUE(X509Certificate::IsSameOSCert( 446 verify_result.verified_cert->GetIntermediateCertificates().front(), 447 root_cert->os_cert_handle())); 448 449 EXPECT_FALSE(verify_result.has_md5); 450 } 451 452 // Test for bug 94673. 453 TEST_F(CertVerifyProcTest, GoogleDigiNotarTest) { 454 base::FilePath certs_dir = GetTestCertsDirectory(); 455 456 scoped_refptr<X509Certificate> server_cert = 457 ImportCertFromFile(certs_dir, "google_diginotar.pem"); 458 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert); 459 460 scoped_refptr<X509Certificate> intermediate_cert = 461 ImportCertFromFile(certs_dir, "diginotar_public_ca_2025.pem"); 462 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert); 463 464 X509Certificate::OSCertHandles intermediates; 465 intermediates.push_back(intermediate_cert->os_cert_handle()); 466 scoped_refptr<X509Certificate> cert_chain = 467 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(), 468 intermediates); 469 470 CertVerifyResult verify_result; 471 int flags = CertVerifier::VERIFY_REV_CHECKING_ENABLED; 472 int error = Verify(cert_chain.get(), 473 "mail.google.com", 474 flags, 475 NULL, 476 empty_cert_list_, 477 &verify_result); 478 EXPECT_NE(OK, error); 479 480 // Now turn off revocation checking. Certificate verification should still 481 // fail. 482 flags = 0; 483 error = Verify(cert_chain.get(), 484 "mail.google.com", 485 flags, 486 NULL, 487 empty_cert_list_, 488 &verify_result); 489 EXPECT_NE(OK, error); 490 } 491 492 TEST_F(CertVerifyProcTest, DigiNotarCerts) { 493 static const char* const kDigiNotarFilenames[] = { 494 "diginotar_root_ca.pem", 495 "diginotar_cyber_ca.pem", 496 "diginotar_services_1024_ca.pem", 497 "diginotar_pkioverheid.pem", 498 "diginotar_pkioverheid_g2.pem", 499 NULL, 500 }; 501 502 base::FilePath certs_dir = GetTestCertsDirectory(); 503 504 for (size_t i = 0; kDigiNotarFilenames[i]; i++) { 505 scoped_refptr<X509Certificate> diginotar_cert = 506 ImportCertFromFile(certs_dir, kDigiNotarFilenames[i]); 507 std::string der_bytes; 508 ASSERT_TRUE(X509Certificate::GetDEREncoded( 509 diginotar_cert->os_cert_handle(), &der_bytes)); 510 511 base::StringPiece spki; 512 ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(der_bytes, &spki)); 513 514 std::string spki_sha1 = base::SHA1HashString(spki.as_string()); 515 516 HashValueVector public_keys; 517 HashValue hash(HASH_VALUE_SHA1); 518 ASSERT_EQ(hash.size(), spki_sha1.size()); 519 memcpy(hash.data(), spki_sha1.data(), spki_sha1.size()); 520 public_keys.push_back(hash); 521 522 EXPECT_TRUE(CertVerifyProc::IsPublicKeyBlacklisted(public_keys)) << 523 "Public key not blocked for " << kDigiNotarFilenames[i]; 524 } 525 } 526 527 // The certse.pem certificate has been revoked. crbug.com/259723. 528 TEST_F(CertVerifyProcTest, TestKnownRoot) { 529 base::FilePath certs_dir = GetTestCertsDirectory(); 530 CertificateList certs = CreateCertificateListFromFile( 531 certs_dir, "satveda.pem", X509Certificate::FORMAT_AUTO); 532 ASSERT_EQ(2U, certs.size()); 533 534 X509Certificate::OSCertHandles intermediates; 535 intermediates.push_back(certs[1]->os_cert_handle()); 536 537 scoped_refptr<X509Certificate> cert_chain = 538 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(), 539 intermediates); 540 541 int flags = 0; 542 CertVerifyResult verify_result; 543 // This will blow up, May 24th, 2019. Sorry! Please disable and file a bug 544 // against agl. See also PublicKeyHashes. 545 int error = Verify(cert_chain.get(), 546 "satveda.com", 547 flags, 548 NULL, 549 empty_cert_list_, 550 &verify_result); 551 EXPECT_EQ(OK, error); 552 EXPECT_EQ(0U, verify_result.cert_status); 553 EXPECT_TRUE(verify_result.is_issued_by_known_root); 554 } 555 556 // The certse.pem certificate has been revoked. crbug.com/259723. 557 TEST_F(CertVerifyProcTest, PublicKeyHashes) { 558 base::FilePath certs_dir = GetTestCertsDirectory(); 559 CertificateList certs = CreateCertificateListFromFile( 560 certs_dir, "satveda.pem", X509Certificate::FORMAT_AUTO); 561 ASSERT_EQ(2U, certs.size()); 562 563 X509Certificate::OSCertHandles intermediates; 564 intermediates.push_back(certs[1]->os_cert_handle()); 565 566 scoped_refptr<X509Certificate> cert_chain = 567 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(), 568 intermediates); 569 int flags = 0; 570 CertVerifyResult verify_result; 571 572 // This will blow up, May 24th, 2019. Sorry! Please disable and file a bug 573 // against agl. See also TestKnownRoot. 574 int error = Verify(cert_chain.get(), 575 "satveda.com", 576 flags, 577 NULL, 578 empty_cert_list_, 579 &verify_result); 580 EXPECT_EQ(OK, error); 581 EXPECT_EQ(0U, verify_result.cert_status); 582 ASSERT_LE(2U, verify_result.public_key_hashes.size()); 583 584 HashValueVector sha1_hashes; 585 for (size_t i = 0; i < verify_result.public_key_hashes.size(); ++i) { 586 if (verify_result.public_key_hashes[i].tag != HASH_VALUE_SHA1) 587 continue; 588 sha1_hashes.push_back(verify_result.public_key_hashes[i]); 589 } 590 ASSERT_LE(2u, sha1_hashes.size()); 591 592 for (size_t i = 0; i < 2; ++i) { 593 EXPECT_EQ(HexEncode(kSatvedaSPKIs[i], base::kSHA1Length), 594 HexEncode(sha1_hashes[i].data(), base::kSHA1Length)); 595 } 596 597 HashValueVector sha256_hashes; 598 for (size_t i = 0; i < verify_result.public_key_hashes.size(); ++i) { 599 if (verify_result.public_key_hashes[i].tag != HASH_VALUE_SHA256) 600 continue; 601 sha256_hashes.push_back(verify_result.public_key_hashes[i]); 602 } 603 ASSERT_LE(2u, sha256_hashes.size()); 604 605 for (size_t i = 0; i < 2; ++i) { 606 EXPECT_EQ(HexEncode(kSatvedaSPKIsSHA256[i], crypto::kSHA256Length), 607 HexEncode(sha256_hashes[i].data(), crypto::kSHA256Length)); 608 } 609 } 610 611 // A regression test for http://crbug.com/70293. 612 // The Key Usage extension in this RSA SSL server certificate does not have 613 // the keyEncipherment bit. 614 TEST_F(CertVerifyProcTest, InvalidKeyUsage) { 615 base::FilePath certs_dir = GetTestCertsDirectory(); 616 617 scoped_refptr<X509Certificate> server_cert = 618 ImportCertFromFile(certs_dir, "invalid_key_usage_cert.der"); 619 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert); 620 621 int flags = 0; 622 CertVerifyResult verify_result; 623 int error = Verify(server_cert.get(), 624 "jira.aquameta.com", 625 flags, 626 NULL, 627 empty_cert_list_, 628 &verify_result); 629 #if defined(USE_OPENSSL) && !defined(OS_ANDROID) 630 // This certificate has two errors: "invalid key usage" and "untrusted CA". 631 // However, OpenSSL returns only one (the latter), and we can't detect 632 // the other errors. 633 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error); 634 #else 635 EXPECT_EQ(ERR_CERT_INVALID, error); 636 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID); 637 #endif 638 // TODO(wtc): fix http://crbug.com/75520 to get all the certificate errors 639 // from NSS. 640 #if !defined(USE_NSS) && !defined(OS_IOS) && !defined(OS_ANDROID) 641 // The certificate is issued by an unknown CA. 642 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_AUTHORITY_INVALID); 643 #endif 644 } 645 646 // Basic test for returning the chain in CertVerifyResult. Note that the 647 // returned chain may just be a reflection of the originally supplied chain; 648 // that is, if any errors occur, the default chain returned is an exact copy 649 // of the certificate to be verified. The remaining VerifyReturn* tests are 650 // used to ensure that the actual, verified chain is being returned by 651 // Verify(). 652 TEST_F(CertVerifyProcTest, VerifyReturnChainBasic) { 653 base::FilePath certs_dir = GetTestCertsDirectory(); 654 CertificateList certs = CreateCertificateListFromFile( 655 certs_dir, "x509_verify_results.chain.pem", 656 X509Certificate::FORMAT_AUTO); 657 ASSERT_EQ(3U, certs.size()); 658 659 X509Certificate::OSCertHandles intermediates; 660 intermediates.push_back(certs[1]->os_cert_handle()); 661 intermediates.push_back(certs[2]->os_cert_handle()); 662 663 ScopedTestRoot scoped_root(certs[2].get()); 664 665 scoped_refptr<X509Certificate> google_full_chain = 666 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(), 667 intermediates); 668 ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain); 669 ASSERT_EQ(2U, google_full_chain->GetIntermediateCertificates().size()); 670 671 CertVerifyResult verify_result; 672 EXPECT_EQ(static_cast<X509Certificate*>(NULL), verify_result.verified_cert); 673 int error = Verify(google_full_chain.get(), 674 "127.0.0.1", 675 0, 676 NULL, 677 empty_cert_list_, 678 &verify_result); 679 EXPECT_EQ(OK, error); 680 ASSERT_NE(static_cast<X509Certificate*>(NULL), verify_result.verified_cert); 681 682 EXPECT_NE(google_full_chain, verify_result.verified_cert); 683 EXPECT_TRUE(X509Certificate::IsSameOSCert( 684 google_full_chain->os_cert_handle(), 685 verify_result.verified_cert->os_cert_handle())); 686 const X509Certificate::OSCertHandles& return_intermediates = 687 verify_result.verified_cert->GetIntermediateCertificates(); 688 ASSERT_EQ(2U, return_intermediates.size()); 689 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0], 690 certs[1]->os_cert_handle())); 691 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1], 692 certs[2]->os_cert_handle())); 693 } 694 695 // Test that certificates issued for 'intranet' names (that is, containing no 696 // known public registry controlled domain information) issued by well-known 697 // CAs are flagged appropriately, while certificates that are issued by 698 // internal CAs are not flagged. 699 TEST_F(CertVerifyProcTest, IntranetHostsRejected) { 700 CertificateList cert_list = CreateCertificateListFromFile( 701 GetTestCertsDirectory(), "ok_cert.pem", 702 X509Certificate::FORMAT_AUTO); 703 ASSERT_EQ(1U, cert_list.size()); 704 scoped_refptr<X509Certificate> cert(cert_list[0]); 705 706 CertVerifyResult verify_result; 707 int error = 0; 708 709 // Intranet names for public CAs should be flagged: 710 verify_proc_ = new WellKnownCaCertVerifyProc(true); 711 error = 712 Verify(cert.get(), "intranet", 0, NULL, empty_cert_list_, &verify_result); 713 EXPECT_EQ(OK, error); 714 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_NON_UNIQUE_NAME); 715 716 // However, if the CA is not well known, these should not be flagged: 717 verify_proc_ = new WellKnownCaCertVerifyProc(false); 718 error = 719 Verify(cert.get(), "intranet", 0, NULL, empty_cert_list_, &verify_result); 720 EXPECT_EQ(OK, error); 721 EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_NON_UNIQUE_NAME); 722 } 723 724 // Test that the certificate returned in CertVerifyResult is able to reorder 725 // certificates that are not ordered from end-entity to root. While this is 726 // a protocol violation if sent during a TLS handshake, if multiple sources 727 // of intermediate certificates are combined, it's possible that order may 728 // not be maintained. 729 TEST_F(CertVerifyProcTest, VerifyReturnChainProperlyOrdered) { 730 base::FilePath certs_dir = GetTestCertsDirectory(); 731 CertificateList certs = CreateCertificateListFromFile( 732 certs_dir, "x509_verify_results.chain.pem", 733 X509Certificate::FORMAT_AUTO); 734 ASSERT_EQ(3U, certs.size()); 735 736 // Construct the chain out of order. 737 X509Certificate::OSCertHandles intermediates; 738 intermediates.push_back(certs[2]->os_cert_handle()); 739 intermediates.push_back(certs[1]->os_cert_handle()); 740 741 ScopedTestRoot scoped_root(certs[2].get()); 742 743 scoped_refptr<X509Certificate> google_full_chain = 744 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(), 745 intermediates); 746 ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain); 747 ASSERT_EQ(2U, google_full_chain->GetIntermediateCertificates().size()); 748 749 CertVerifyResult verify_result; 750 EXPECT_EQ(static_cast<X509Certificate*>(NULL), verify_result.verified_cert); 751 int error = Verify(google_full_chain.get(), 752 "127.0.0.1", 753 0, 754 NULL, 755 empty_cert_list_, 756 &verify_result); 757 EXPECT_EQ(OK, error); 758 ASSERT_NE(static_cast<X509Certificate*>(NULL), verify_result.verified_cert); 759 760 EXPECT_NE(google_full_chain, verify_result.verified_cert); 761 EXPECT_TRUE(X509Certificate::IsSameOSCert( 762 google_full_chain->os_cert_handle(), 763 verify_result.verified_cert->os_cert_handle())); 764 const X509Certificate::OSCertHandles& return_intermediates = 765 verify_result.verified_cert->GetIntermediateCertificates(); 766 ASSERT_EQ(2U, return_intermediates.size()); 767 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0], 768 certs[1]->os_cert_handle())); 769 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1], 770 certs[2]->os_cert_handle())); 771 } 772 773 // Test that Verify() filters out certificates which are not related to 774 // or part of the certificate chain being verified. 775 TEST_F(CertVerifyProcTest, VerifyReturnChainFiltersUnrelatedCerts) { 776 base::FilePath certs_dir = GetTestCertsDirectory(); 777 CertificateList certs = CreateCertificateListFromFile( 778 certs_dir, "x509_verify_results.chain.pem", 779 X509Certificate::FORMAT_AUTO); 780 ASSERT_EQ(3U, certs.size()); 781 ScopedTestRoot scoped_root(certs[2].get()); 782 783 scoped_refptr<X509Certificate> unrelated_certificate = 784 ImportCertFromFile(certs_dir, "duplicate_cn_1.pem"); 785 scoped_refptr<X509Certificate> unrelated_certificate2 = 786 ImportCertFromFile(certs_dir, "aia-cert.pem"); 787 ASSERT_NE(static_cast<X509Certificate*>(NULL), unrelated_certificate); 788 ASSERT_NE(static_cast<X509Certificate*>(NULL), unrelated_certificate2); 789 790 // Interject unrelated certificates into the list of intermediates. 791 X509Certificate::OSCertHandles intermediates; 792 intermediates.push_back(unrelated_certificate->os_cert_handle()); 793 intermediates.push_back(certs[1]->os_cert_handle()); 794 intermediates.push_back(unrelated_certificate2->os_cert_handle()); 795 intermediates.push_back(certs[2]->os_cert_handle()); 796 797 scoped_refptr<X509Certificate> google_full_chain = 798 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(), 799 intermediates); 800 ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain); 801 ASSERT_EQ(4U, google_full_chain->GetIntermediateCertificates().size()); 802 803 CertVerifyResult verify_result; 804 EXPECT_EQ(static_cast<X509Certificate*>(NULL), verify_result.verified_cert); 805 int error = Verify(google_full_chain.get(), 806 "127.0.0.1", 807 0, 808 NULL, 809 empty_cert_list_, 810 &verify_result); 811 EXPECT_EQ(OK, error); 812 ASSERT_NE(static_cast<X509Certificate*>(NULL), verify_result.verified_cert); 813 814 EXPECT_NE(google_full_chain, verify_result.verified_cert); 815 EXPECT_TRUE(X509Certificate::IsSameOSCert( 816 google_full_chain->os_cert_handle(), 817 verify_result.verified_cert->os_cert_handle())); 818 const X509Certificate::OSCertHandles& return_intermediates = 819 verify_result.verified_cert->GetIntermediateCertificates(); 820 ASSERT_EQ(2U, return_intermediates.size()); 821 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0], 822 certs[1]->os_cert_handle())); 823 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1], 824 certs[2]->os_cert_handle())); 825 } 826 827 TEST_F(CertVerifyProcTest, AdditionalTrustAnchors) { 828 if (!SupportsAdditionalTrustAnchors()) { 829 LOG(INFO) << "Skipping this test in this platform."; 830 return; 831 } 832 833 // |ca_cert| is the issuer of |cert|. 834 CertificateList ca_cert_list = CreateCertificateListFromFile( 835 GetTestCertsDirectory(), "root_ca_cert.pem", 836 X509Certificate::FORMAT_AUTO); 837 ASSERT_EQ(1U, ca_cert_list.size()); 838 scoped_refptr<X509Certificate> ca_cert(ca_cert_list[0]); 839 840 CertificateList cert_list = CreateCertificateListFromFile( 841 GetTestCertsDirectory(), "ok_cert.pem", 842 X509Certificate::FORMAT_AUTO); 843 ASSERT_EQ(1U, cert_list.size()); 844 scoped_refptr<X509Certificate> cert(cert_list[0]); 845 846 // Verification of |cert| fails when |ca_cert| is not in the trust anchors 847 // list. 848 int flags = 0; 849 CertVerifyResult verify_result; 850 int error = Verify( 851 cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_, &verify_result); 852 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error); 853 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result.cert_status); 854 EXPECT_FALSE(verify_result.is_issued_by_additional_trust_anchor); 855 856 // Now add the |ca_cert| to the |trust_anchors|, and verification should pass. 857 CertificateList trust_anchors; 858 trust_anchors.push_back(ca_cert); 859 error = Verify( 860 cert.get(), "127.0.0.1", flags, NULL, trust_anchors, &verify_result); 861 EXPECT_EQ(OK, error); 862 EXPECT_EQ(0U, verify_result.cert_status); 863 EXPECT_TRUE(verify_result.is_issued_by_additional_trust_anchor); 864 865 // Clearing the |trust_anchors| makes verification fail again (the cache 866 // should be skipped). 867 error = Verify( 868 cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_, &verify_result); 869 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error); 870 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result.cert_status); 871 EXPECT_FALSE(verify_result.is_issued_by_additional_trust_anchor); 872 } 873 874 #if defined(OS_MACOSX) && !defined(OS_IOS) 875 // Tests that, on OS X, issues with a cross-certified Baltimore CyberTrust 876 // Root can be successfully worked around once Apple completes removing the 877 // older GTE CyberTrust Root from its trusted root store. 878 // 879 // The issue is caused by servers supplying the cross-certified intermediate 880 // (necessary for certain mobile platforms), which OS X does not recognize 881 // as already existing within its trust store. 882 TEST_F(CertVerifyProcTest, CybertrustGTERoot) { 883 CertificateList certs = CreateCertificateListFromFile( 884 GetTestCertsDirectory(), 885 "cybertrust_omniroot_chain.pem", 886 X509Certificate::FORMAT_PEM_CERT_SEQUENCE); 887 ASSERT_EQ(2U, certs.size()); 888 889 X509Certificate::OSCertHandles intermediates; 890 intermediates.push_back(certs[1]->os_cert_handle()); 891 892 scoped_refptr<X509Certificate> cybertrust_basic = 893 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(), 894 intermediates); 895 ASSERT_TRUE(cybertrust_basic.get()); 896 897 scoped_refptr<X509Certificate> baltimore_root = 898 ImportCertFromFile(GetTestCertsDirectory(), 899 "cybertrust_baltimore_root.pem"); 900 ASSERT_TRUE(baltimore_root.get()); 901 902 ScopedTestRoot scoped_root(baltimore_root.get()); 903 904 // Ensure that ONLY the Baltimore CyberTrust Root is trusted. This 905 // simulates Keychain removing support for the GTE CyberTrust Root. 906 TestRootCerts::GetInstance()->SetAllowSystemTrust(false); 907 base::ScopedClosureRunner reset_system_trust( 908 base::Bind(&TestRootCerts::SetAllowSystemTrust, 909 base::Unretained(TestRootCerts::GetInstance()), 910 true)); 911 912 // First, make sure a simple certificate chain from 913 // EE -> Public SureServer SV -> Baltimore CyberTrust 914 // works. Only the first two certificates are included in the chain. 915 int flags = 0; 916 CertVerifyResult verify_result; 917 int error = Verify(cybertrust_basic.get(), 918 "cacert.omniroot.com", 919 flags, 920 NULL, 921 empty_cert_list_, 922 &verify_result); 923 EXPECT_EQ(OK, error); 924 EXPECT_EQ(0U, verify_result.cert_status); 925 926 // Attempt to verify with the first known cross-certified intermediate 927 // provided. 928 scoped_refptr<X509Certificate> baltimore_intermediate_1 = 929 ImportCertFromFile(GetTestCertsDirectory(), 930 "cybertrust_baltimore_cross_certified_1.pem"); 931 ASSERT_TRUE(baltimore_intermediate_1.get()); 932 933 X509Certificate::OSCertHandles intermediate_chain_1 = 934 cybertrust_basic->GetIntermediateCertificates(); 935 intermediate_chain_1.push_back(baltimore_intermediate_1->os_cert_handle()); 936 937 scoped_refptr<X509Certificate> baltimore_chain_1 = 938 X509Certificate::CreateFromHandle(cybertrust_basic->os_cert_handle(), 939 intermediate_chain_1); 940 error = Verify(baltimore_chain_1.get(), 941 "cacert.omniroot.com", 942 flags, 943 NULL, 944 empty_cert_list_, 945 &verify_result); 946 EXPECT_EQ(OK, error); 947 EXPECT_EQ(0U, verify_result.cert_status); 948 949 // Attempt to verify with the second known cross-certified intermediate 950 // provided. 951 scoped_refptr<X509Certificate> baltimore_intermediate_2 = 952 ImportCertFromFile(GetTestCertsDirectory(), 953 "cybertrust_baltimore_cross_certified_2.pem"); 954 ASSERT_TRUE(baltimore_intermediate_2.get()); 955 956 X509Certificate::OSCertHandles intermediate_chain_2 = 957 cybertrust_basic->GetIntermediateCertificates(); 958 intermediate_chain_2.push_back(baltimore_intermediate_2->os_cert_handle()); 959 960 scoped_refptr<X509Certificate> baltimore_chain_2 = 961 X509Certificate::CreateFromHandle(cybertrust_basic->os_cert_handle(), 962 intermediate_chain_2); 963 error = Verify(baltimore_chain_2.get(), 964 "cacert.omniroot.com", 965 flags, 966 NULL, 967 empty_cert_list_, 968 &verify_result); 969 EXPECT_EQ(OK, error); 970 EXPECT_EQ(0U, verify_result.cert_status); 971 972 // Attempt to verify when both a cross-certified intermediate AND 973 // the legacy GTE root are provided. 974 scoped_refptr<X509Certificate> cybertrust_root = 975 ImportCertFromFile(GetTestCertsDirectory(), 976 "cybertrust_gte_root.pem"); 977 ASSERT_TRUE(cybertrust_root.get()); 978 979 intermediate_chain_2.push_back(cybertrust_root->os_cert_handle()); 980 scoped_refptr<X509Certificate> baltimore_chain_with_root = 981 X509Certificate::CreateFromHandle(cybertrust_basic->os_cert_handle(), 982 intermediate_chain_2); 983 error = Verify(baltimore_chain_with_root.get(), 984 "cacert.omniroot.com", 985 flags, 986 NULL, 987 empty_cert_list_, 988 &verify_result); 989 EXPECT_EQ(OK, error); 990 EXPECT_EQ(0U, verify_result.cert_status); 991 992 } 993 #endif 994 995 #if defined(USE_NSS) || defined(OS_IOS) || defined(OS_WIN) || defined(OS_MACOSX) 996 static const uint8 kCRLSetThawteSPKIBlocked[] = { 997 0x8e, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 998 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 999 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x22, 0x2c, 0x22, 1000 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x30, 0x2c, 0x22, 1001 0x44, 0x65, 0x6c, 0x74, 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c, 1002 0x22, 0x4e, 0x75, 0x6d, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a, 1003 0x30, 0x2c, 0x22, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x50, 0x4b, 1004 0x49, 0x73, 0x22, 0x3a, 0x5b, 0x22, 0x36, 0x58, 0x36, 0x4d, 0x78, 0x52, 0x37, 1005 0x58, 0x70, 0x4d, 0x51, 0x4b, 0x78, 0x49, 0x41, 0x39, 0x50, 0x6a, 0x36, 0x37, 1006 0x36, 0x38, 0x76, 0x74, 0x55, 0x6b, 0x6b, 0x7a, 0x48, 0x79, 0x7a, 0x41, 0x6f, 1007 0x6d, 0x6f, 0x4f, 0x68, 0x4b, 0x55, 0x6e, 0x7a, 0x73, 0x55, 0x3d, 0x22, 0x5d, 1008 0x7d, 1009 }; 1010 1011 static const uint8 kCRLSetThawteSerialBlocked[] = { 1012 0x60, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 1013 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 1014 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x22, 0x2c, 0x22, 1015 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x30, 0x2c, 0x22, 1016 0x44, 0x65, 0x6c, 0x74, 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c, 1017 0x22, 0x4e, 0x75, 0x6d, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a, 1018 0x31, 0x2c, 0x22, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x50, 0x4b, 1019 0x49, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0xb1, 0x12, 0x41, 0x42, 0xa5, 0xa1, 1020 0xa5, 0xa2, 0x88, 0x19, 0xc7, 0x35, 0x34, 0x0e, 0xff, 0x8c, 0x9e, 0x2f, 0x81, 1021 0x68, 0xfe, 0xe3, 0xba, 0x18, 0x7f, 0x25, 0x3b, 0xc1, 0xa3, 0x92, 0xd7, 0xe2, 1022 // Note that this is actually blocking two serial numbers because on XP and 1023 // Vista, CryptoAPI finds a different Thawte certificate. 1024 0x02, 0x00, 0x00, 0x00, 1025 0x04, 0x30, 0x00, 0x00, 0x02, 1026 0x04, 0x30, 0x00, 0x00, 0x06, 1027 }; 1028 1029 static const uint8 kCRLSetGoogleSerialBlocked[] = { 1030 0x60, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 1031 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 1032 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x22, 0x2c, 0x22, 1033 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x30, 0x2c, 0x22, 1034 0x44, 0x65, 0x6c, 0x74, 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c, 1035 0x22, 0x4e, 0x75, 0x6d, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a, 1036 0x31, 0x2c, 0x22, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x50, 0x4b, 1037 0x49, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0xe9, 0x7e, 0x8c, 0xc5, 0x1e, 0xd7, 1038 0xa4, 0xc4, 0x0a, 0xc4, 0x80, 0x3d, 0x3e, 0x3e, 0xbb, 0xeb, 0xcb, 0xed, 0x52, 1039 0x49, 0x33, 0x1f, 0x2c, 0xc0, 0xa2, 0x6a, 0x0e, 0x84, 0xa5, 0x27, 0xce, 0xc5, 1040 0x01, 0x00, 0x00, 0x00, 0x10, 0x4f, 0x9d, 0x96, 0xd9, 0x66, 0xb0, 0x99, 0x2b, 1041 0x54, 0xc2, 0x95, 0x7c, 0xb4, 0x15, 0x7d, 0x4d, 1042 }; 1043 1044 // Test that CRLSets are effective in making a certificate appear to be 1045 // revoked. 1046 TEST_F(CertVerifyProcTest, CRLSet) { 1047 CertificateList certs = CreateCertificateListFromFile( 1048 GetTestCertsDirectory(), 1049 "googlenew.chain.pem", 1050 X509Certificate::FORMAT_PEM_CERT_SEQUENCE); 1051 1052 X509Certificate::OSCertHandles intermediates; 1053 intermediates.push_back(certs[1]->os_cert_handle()); 1054 1055 scoped_refptr<X509Certificate> google_full_chain = 1056 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(), 1057 intermediates); 1058 1059 CertVerifyResult verify_result; 1060 int error = Verify(google_full_chain.get(), 1061 "www.google.com", 1062 0, 1063 NULL, 1064 empty_cert_list_, 1065 &verify_result); 1066 EXPECT_EQ(OK, error); 1067 1068 // First test blocking by SPKI. 1069 base::StringPiece crl_set_bytes( 1070 reinterpret_cast<const char*>(kCRLSetThawteSPKIBlocked), 1071 sizeof(kCRLSetThawteSPKIBlocked)); 1072 scoped_refptr<CRLSet> crl_set; 1073 ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set)); 1074 1075 error = Verify(google_full_chain.get(), 1076 "www.google.com", 1077 0, 1078 crl_set.get(), 1079 empty_cert_list_, 1080 &verify_result); 1081 EXPECT_EQ(ERR_CERT_REVOKED, error); 1082 1083 // Second, test revocation by serial number of a cert directly under the 1084 // root. 1085 crl_set_bytes = base::StringPiece( 1086 reinterpret_cast<const char*>(kCRLSetThawteSerialBlocked), 1087 sizeof(kCRLSetThawteSerialBlocked)); 1088 ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set)); 1089 1090 error = Verify(google_full_chain.get(), 1091 "www.google.com", 1092 0, 1093 crl_set.get(), 1094 empty_cert_list_, 1095 &verify_result); 1096 EXPECT_EQ(ERR_CERT_REVOKED, error); 1097 1098 // Lastly, test revocation by serial number of a certificate not under the 1099 // root. 1100 crl_set_bytes = base::StringPiece( 1101 reinterpret_cast<const char*>(kCRLSetGoogleSerialBlocked), 1102 sizeof(kCRLSetGoogleSerialBlocked)); 1103 ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set)); 1104 1105 error = Verify(google_full_chain.get(), 1106 "www.google.com", 1107 0, 1108 crl_set.get(), 1109 empty_cert_list_, 1110 &verify_result); 1111 EXPECT_EQ(ERR_CERT_REVOKED, error); 1112 } 1113 #endif 1114 1115 struct WeakDigestTestData { 1116 const char* root_cert_filename; 1117 const char* intermediate_cert_filename; 1118 const char* ee_cert_filename; 1119 bool expected_has_md5; 1120 bool expected_has_md4; 1121 bool expected_has_md2; 1122 }; 1123 1124 // GTest 'magic' pretty-printer, so that if/when a test fails, it knows how 1125 // to output the parameter that was passed. Without this, it will simply 1126 // attempt to print out the first twenty bytes of the object, which depending 1127 // on platform and alignment, may result in an invalid read. 1128 void PrintTo(const WeakDigestTestData& data, std::ostream* os) { 1129 *os << "root: " 1130 << (data.root_cert_filename ? data.root_cert_filename : "none") 1131 << "; intermediate: " << data.intermediate_cert_filename 1132 << "; end-entity: " << data.ee_cert_filename; 1133 } 1134 1135 class CertVerifyProcWeakDigestTest 1136 : public CertVerifyProcTest, 1137 public testing::WithParamInterface<WeakDigestTestData> { 1138 public: 1139 CertVerifyProcWeakDigestTest() {} 1140 virtual ~CertVerifyProcWeakDigestTest() {} 1141 }; 1142 1143 TEST_P(CertVerifyProcWeakDigestTest, Verify) { 1144 WeakDigestTestData data = GetParam(); 1145 base::FilePath certs_dir = GetTestCertsDirectory(); 1146 1147 ScopedTestRoot test_root; 1148 if (data.root_cert_filename) { 1149 scoped_refptr<X509Certificate> root_cert = 1150 ImportCertFromFile(certs_dir, data.root_cert_filename); 1151 ASSERT_NE(static_cast<X509Certificate*>(NULL), root_cert); 1152 test_root.Reset(root_cert.get()); 1153 } 1154 1155 scoped_refptr<X509Certificate> intermediate_cert = 1156 ImportCertFromFile(certs_dir, data.intermediate_cert_filename); 1157 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert); 1158 scoped_refptr<X509Certificate> ee_cert = 1159 ImportCertFromFile(certs_dir, data.ee_cert_filename); 1160 ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_cert); 1161 1162 X509Certificate::OSCertHandles intermediates; 1163 intermediates.push_back(intermediate_cert->os_cert_handle()); 1164 1165 scoped_refptr<X509Certificate> ee_chain = 1166 X509Certificate::CreateFromHandle(ee_cert->os_cert_handle(), 1167 intermediates); 1168 ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_chain); 1169 1170 int flags = 0; 1171 CertVerifyResult verify_result; 1172 int rv = Verify(ee_chain.get(), 1173 "127.0.0.1", 1174 flags, 1175 NULL, 1176 empty_cert_list_, 1177 &verify_result); 1178 EXPECT_EQ(data.expected_has_md5, verify_result.has_md5); 1179 EXPECT_EQ(data.expected_has_md4, verify_result.has_md4); 1180 EXPECT_EQ(data.expected_has_md2, verify_result.has_md2); 1181 EXPECT_FALSE(verify_result.is_issued_by_additional_trust_anchor); 1182 1183 // Ensure that MD4 and MD2 are tagged as invalid. 1184 if (data.expected_has_md4 || data.expected_has_md2) { 1185 EXPECT_EQ(CERT_STATUS_INVALID, 1186 verify_result.cert_status & CERT_STATUS_INVALID); 1187 } 1188 1189 // Ensure that MD5 is flagged as weak. 1190 if (data.expected_has_md5) { 1191 EXPECT_EQ( 1192 CERT_STATUS_WEAK_SIGNATURE_ALGORITHM, 1193 verify_result.cert_status & CERT_STATUS_WEAK_SIGNATURE_ALGORITHM); 1194 } 1195 1196 // If a root cert is present, then check that the chain was rejected if any 1197 // weak algorithms are present. This is only checked when a root cert is 1198 // present because the error reported for incomplete chains with weak 1199 // algorithms depends on which implementation was used to validate (NSS, 1200 // OpenSSL, CryptoAPI, Security.framework) and upon which weak algorithm 1201 // present (MD2, MD4, MD5). 1202 if (data.root_cert_filename) { 1203 if (data.expected_has_md4 || data.expected_has_md2) { 1204 EXPECT_EQ(ERR_CERT_INVALID, rv); 1205 } else if (data.expected_has_md5) { 1206 EXPECT_EQ(ERR_CERT_WEAK_SIGNATURE_ALGORITHM, rv); 1207 } else { 1208 EXPECT_EQ(OK, rv); 1209 } 1210 } 1211 } 1212 1213 // Unlike TEST/TEST_F, which are macros that expand to further macros, 1214 // INSTANTIATE_TEST_CASE_P is a macro that expands directly to code that 1215 // stringizes the arguments. As a result, macros passed as parameters (such as 1216 // prefix or test_case_name) will not be expanded by the preprocessor. To work 1217 // around this, indirect the macro for INSTANTIATE_TEST_CASE_P, so that the 1218 // pre-processor will expand macros such as MAYBE_test_name before 1219 // instantiating the test. 1220 #define WRAPPED_INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ 1221 INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) 1222 1223 // The signature algorithm of the root CA should not matter. 1224 const WeakDigestTestData kVerifyRootCATestData[] = { 1225 { "weak_digest_md5_root.pem", "weak_digest_sha1_intermediate.pem", 1226 "weak_digest_sha1_ee.pem", false, false, false }, 1227 #if defined(USE_OPENSSL) || defined(OS_WIN) 1228 // MD4 is not supported by OS X / NSS 1229 { "weak_digest_md4_root.pem", "weak_digest_sha1_intermediate.pem", 1230 "weak_digest_sha1_ee.pem", false, false, false }, 1231 #endif 1232 { "weak_digest_md2_root.pem", "weak_digest_sha1_intermediate.pem", 1233 "weak_digest_sha1_ee.pem", false, false, false }, 1234 }; 1235 INSTANTIATE_TEST_CASE_P(VerifyRoot, CertVerifyProcWeakDigestTest, 1236 testing::ValuesIn(kVerifyRootCATestData)); 1237 1238 // The signature algorithm of intermediates should be properly detected. 1239 const WeakDigestTestData kVerifyIntermediateCATestData[] = { 1240 { "weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem", 1241 "weak_digest_sha1_ee.pem", true, false, false }, 1242 #if defined(USE_OPENSSL) || defined(OS_WIN) 1243 // MD4 is not supported by OS X / NSS 1244 { "weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem", 1245 "weak_digest_sha1_ee.pem", false, true, false }, 1246 #endif 1247 { "weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem", 1248 "weak_digest_sha1_ee.pem", false, false, true }, 1249 }; 1250 // Disabled on NSS - MD4 is not supported, and MD2 and MD5 are disabled. 1251 #if defined(USE_NSS) || defined(OS_IOS) 1252 #define MAYBE_VerifyIntermediate DISABLED_VerifyIntermediate 1253 #else 1254 #define MAYBE_VerifyIntermediate VerifyIntermediate 1255 #endif 1256 WRAPPED_INSTANTIATE_TEST_CASE_P( 1257 MAYBE_VerifyIntermediate, 1258 CertVerifyProcWeakDigestTest, 1259 testing::ValuesIn(kVerifyIntermediateCATestData)); 1260 1261 // The signature algorithm of end-entity should be properly detected. 1262 const WeakDigestTestData kVerifyEndEntityTestData[] = { 1263 { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem", 1264 "weak_digest_md5_ee.pem", true, false, false }, 1265 #if defined(USE_OPENSSL) || defined(OS_WIN) 1266 // MD4 is not supported by OS X / NSS 1267 { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem", 1268 "weak_digest_md4_ee.pem", false, true, false }, 1269 #endif 1270 { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem", 1271 "weak_digest_md2_ee.pem", false, false, true }, 1272 }; 1273 // Disabled on NSS - NSS caches chains/signatures in such a way that cannot 1274 // be cleared until NSS is cleanly shutdown, which is not presently supported 1275 // in Chromium. 1276 #if defined(USE_NSS) || defined(OS_IOS) 1277 #define MAYBE_VerifyEndEntity DISABLED_VerifyEndEntity 1278 #else 1279 #define MAYBE_VerifyEndEntity VerifyEndEntity 1280 #endif 1281 WRAPPED_INSTANTIATE_TEST_CASE_P(MAYBE_VerifyEndEntity, 1282 CertVerifyProcWeakDigestTest, 1283 testing::ValuesIn(kVerifyEndEntityTestData)); 1284 1285 // Incomplete chains should still report the status of the intermediate. 1286 const WeakDigestTestData kVerifyIncompleteIntermediateTestData[] = { 1287 { NULL, "weak_digest_md5_intermediate.pem", "weak_digest_sha1_ee.pem", 1288 true, false, false }, 1289 #if defined(USE_OPENSSL) || defined(OS_WIN) 1290 // MD4 is not supported by OS X / NSS 1291 { NULL, "weak_digest_md4_intermediate.pem", "weak_digest_sha1_ee.pem", 1292 false, true, false }, 1293 #endif 1294 { NULL, "weak_digest_md2_intermediate.pem", "weak_digest_sha1_ee.pem", 1295 false, false, true }, 1296 }; 1297 // Disabled on NSS - libpkix does not return constructed chains on error, 1298 // preventing us from detecting/inspecting the verified chain. 1299 #if defined(USE_NSS) || defined(OS_IOS) 1300 #define MAYBE_VerifyIncompleteIntermediate \ 1301 DISABLED_VerifyIncompleteIntermediate 1302 #else 1303 #define MAYBE_VerifyIncompleteIntermediate VerifyIncompleteIntermediate 1304 #endif 1305 WRAPPED_INSTANTIATE_TEST_CASE_P( 1306 MAYBE_VerifyIncompleteIntermediate, 1307 CertVerifyProcWeakDigestTest, 1308 testing::ValuesIn(kVerifyIncompleteIntermediateTestData)); 1309 1310 // Incomplete chains should still report the status of the end-entity. 1311 const WeakDigestTestData kVerifyIncompleteEETestData[] = { 1312 { NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md5_ee.pem", 1313 true, false, false }, 1314 #if defined(USE_OPENSSL) || defined(OS_WIN) 1315 // MD4 is not supported by OS X / NSS 1316 { NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md4_ee.pem", 1317 false, true, false }, 1318 #endif 1319 { NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md2_ee.pem", 1320 false, false, true }, 1321 }; 1322 // Disabled on NSS - libpkix does not return constructed chains on error, 1323 // preventing us from detecting/inspecting the verified chain. 1324 #if defined(USE_NSS) || defined(OS_IOS) 1325 #define MAYBE_VerifyIncompleteEndEntity DISABLED_VerifyIncompleteEndEntity 1326 #else 1327 #define MAYBE_VerifyIncompleteEndEntity VerifyIncompleteEndEntity 1328 #endif 1329 WRAPPED_INSTANTIATE_TEST_CASE_P( 1330 MAYBE_VerifyIncompleteEndEntity, 1331 CertVerifyProcWeakDigestTest, 1332 testing::ValuesIn(kVerifyIncompleteEETestData)); 1333 1334 // Differing algorithms between the intermediate and the EE should still be 1335 // reported. 1336 const WeakDigestTestData kVerifyMixedTestData[] = { 1337 { "weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem", 1338 "weak_digest_md2_ee.pem", true, false, true }, 1339 { "weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem", 1340 "weak_digest_md5_ee.pem", true, false, true }, 1341 #if defined(USE_OPENSSL) || defined(OS_WIN) 1342 // MD4 is not supported by OS X / NSS 1343 { "weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem", 1344 "weak_digest_md2_ee.pem", false, true, true }, 1345 #endif 1346 }; 1347 // NSS does not support MD4 and does not enable MD2 by default, making all 1348 // permutations invalid. 1349 #if defined(USE_NSS) || defined(OS_IOS) 1350 #define MAYBE_VerifyMixed DISABLED_VerifyMixed 1351 #else 1352 #define MAYBE_VerifyMixed VerifyMixed 1353 #endif 1354 WRAPPED_INSTANTIATE_TEST_CASE_P( 1355 MAYBE_VerifyMixed, 1356 CertVerifyProcWeakDigestTest, 1357 testing::ValuesIn(kVerifyMixedTestData)); 1358 1359 } // namespace net 1360