OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/cert/multi_threaded_cert_verifier.h" | 5 #include "net/cert/multi_threaded_cert_verifier.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/debug/leak_annotations.h" | 10 #include "base/debug/leak_annotations.h" |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
60 }; | 60 }; |
61 | 61 |
62 class MockCertTrustAnchorProvider : public CertTrustAnchorProvider { | 62 class MockCertTrustAnchorProvider : public CertTrustAnchorProvider { |
63 public: | 63 public: |
64 MockCertTrustAnchorProvider() {} | 64 MockCertTrustAnchorProvider() {} |
65 virtual ~MockCertTrustAnchorProvider() {} | 65 virtual ~MockCertTrustAnchorProvider() {} |
66 | 66 |
67 MOCK_METHOD0(GetAdditionalTrustAnchors, const CertificateList&()); | 67 MOCK_METHOD0(GetAdditionalTrustAnchors, const CertificateList&()); |
68 }; | 68 }; |
69 | 69 |
70 bool HashValueVectorEqual(const HashValueVector& a, const HashValueVector& b) { | |
71 size_t size = a.size(); | |
72 | |
73 if (size != b.size()) | |
74 return false; | |
75 | |
76 for (size_t i = 0; i < size; ++i) { | |
Ryan Sleevi
2016/05/13 20:18:13
alternative: return std::equal(a.begin(), a.end(),
| |
77 if (!a[i].Equals(b[i])) | |
78 return false; | |
79 } | |
80 | |
81 return true; | |
82 } | |
83 | |
70 } // namespace | 84 } // namespace |
71 | 85 |
72 class MultiThreadedCertVerifierTest : public ::testing::Test { | 86 class MultiThreadedCertVerifierTest : public ::testing::Test { |
73 public: | 87 public: |
74 MultiThreadedCertVerifierTest() : verifier_(new MockCertVerifyProc()) {} | 88 MultiThreadedCertVerifierTest() : verifier_(new MockCertVerifyProc()) {} |
75 ~MultiThreadedCertVerifierTest() override {} | 89 ~MultiThreadedCertVerifierTest() override {} |
76 | 90 |
77 protected: | 91 protected: |
78 MultiThreadedCertVerifier verifier_; | 92 MultiThreadedCertVerifier verifier_; |
79 }; | 93 }; |
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
507 ASSERT_TRUE(IsCertificateError(error)); | 521 ASSERT_TRUE(IsCertificateError(error)); |
508 error = callback4.WaitForResult(); | 522 error = callback4.WaitForResult(); |
509 ASSERT_TRUE(IsCertificateError(error)); | 523 ASSERT_TRUE(IsCertificateError(error)); |
510 | 524 |
511 // Let the other requests automatically cancel. | 525 // Let the other requests automatically cancel. |
512 ASSERT_EQ(5u, verifier_.requests()); | 526 ASSERT_EQ(5u, verifier_.requests()); |
513 ASSERT_EQ(0u, verifier_.cache_hits()); | 527 ASSERT_EQ(0u, verifier_.cache_hits()); |
514 ASSERT_EQ(2u, verifier_.inflight_joins()); | 528 ASSERT_EQ(2u, verifier_.inflight_joins()); |
515 } | 529 } |
516 | 530 |
531 TEST_F(MultiThreadedCertVerifierTest, CacheHitIterator) { | |
532 base::FilePath certs_dir = GetTestCertsDirectory(); | |
533 scoped_refptr<X509Certificate> test_cert( | |
534 ImportCertFromFile(certs_dir, "ok_cert.pem")); | |
535 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get()); | |
536 | |
537 std::string example_hostname("www.example.com"); | |
538 std::string ocsp_response; | |
539 int flags = 0; | |
540 base::Time start_time = base::Time::Now(); | |
541 int error; | |
542 CertVerifyResult verify_result; | |
543 TestCompletionCallback callback; | |
544 std::unique_ptr<CertVerifier::Request> request; | |
545 | |
546 error = verifier_.Verify(test_cert.get(), example_hostname, ocsp_response, | |
547 flags, NULL, &verify_result, callback.callback(), | |
548 &request, BoundNetLog()); | |
549 ASSERT_EQ(ERR_IO_PENDING, error); | |
550 EXPECT_TRUE(request); | |
551 error = callback.WaitForResult(); | |
552 ASSERT_TRUE(IsCertificateError(error)); | |
553 ASSERT_EQ(1u, verifier_.requests()); | |
554 ASSERT_EQ(0u, verifier_.cache_hits()); | |
555 ASSERT_EQ(0u, verifier_.inflight_joins()); | |
556 ASSERT_EQ(1u, verifier_.GetCacheSize()); | |
557 | |
558 // Verify Iterator returns the correct data. | |
559 base::Time curr_time = base::Time::Now(); | |
560 MultiThreadedCertVerifier::Iterator iterator(verifier_); | |
561 EXPECT_TRUE(iterator.HasNext()); | |
562 ASSERT_EQ(example_hostname, iterator.hostname()); | |
563 ASSERT_EQ(flags, iterator.flags()); | |
564 ASSERT_LE(start_time, iterator.start_time()); | |
565 ASSERT_GE(curr_time, iterator.start_time()); | |
566 ASSERT_EQ(error, iterator.error()); | |
567 const CertVerifyResult& result = iterator.result(); | |
568 ASSERT_EQ(verify_result.cert_status, result.cert_status); | |
569 ASSERT_EQ(verify_result.has_md2, result.has_md2); | |
570 ASSERT_EQ(verify_result.has_md4, result.has_md4); | |
571 ASSERT_EQ(verify_result.has_md5, result.has_md5); | |
572 ASSERT_EQ(verify_result.has_sha1, result.has_sha1); | |
573 ASSERT_EQ(verify_result.has_sha1_leaf, result.has_sha1_leaf); | |
574 ASSERT_EQ(verify_result.is_issued_by_known_root, | |
575 result.is_issued_by_known_root); | |
576 ASSERT_EQ(verify_result.is_issued_by_additional_trust_anchor, | |
577 result.is_issued_by_additional_trust_anchor); | |
578 ASSERT_EQ(verify_result.has_md2, result.has_md2); | |
579 ASSERT_EQ(verify_result.common_name_fallback_used, | |
580 result.common_name_fallback_used); | |
581 EXPECT_TRUE(HashValueVectorEqual(verify_result.public_key_hashes, | |
582 result.public_key_hashes)); | |
583 EXPECT_TRUE( | |
584 verify_result.verified_cert.get()->Equals(result.verified_cert.get())); | |
585 | |
586 ASSERT_LE(start_time, iterator.verification_time()); | |
587 ASSERT_GE(curr_time, iterator.verification_time()); | |
588 | |
589 // TODO(rtenneti): use |kTTLSecs| instead of hardcoded 1800ms. | |
590 base::Time expected_expiration_time = | |
591 curr_time + base::TimeDelta::FromSeconds(3600); | |
592 ASSERT_LE(start_time, iterator.expiration_time()); | |
593 ASSERT_GE(expected_expiration_time, iterator.expiration_time()); | |
594 | |
595 iterator.Advance(); | |
596 EXPECT_FALSE(iterator.HasNext()); | |
597 } | |
598 | |
599 TEST_F(MultiThreadedCertVerifierTest, AddCertResult) { | |
600 base::FilePath certs_dir = GetTestCertsDirectory(); | |
601 scoped_refptr<X509Certificate> test_cert( | |
602 ImportCertFromFile(certs_dir, "ok_cert.pem")); | |
603 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get()); | |
604 | |
605 std::string example_hostname("www.example.com"); | |
606 std::string ocsp_response; | |
607 int flags = 0; | |
608 CRLSet* crl_set = NULL; | |
609 int error; | |
610 CertVerifyResult verify_result; | |
611 TestCompletionCallback callback; | |
612 std::unique_ptr<CertVerifier::Request> request; | |
613 | |
614 error = verifier_.Verify(test_cert.get(), example_hostname, ocsp_response, | |
615 flags, crl_set, &verify_result, callback.callback(), | |
616 &request, BoundNetLog()); | |
617 ASSERT_EQ(ERR_IO_PENDING, error); | |
618 EXPECT_TRUE(request); | |
619 error = callback.WaitForResult(); | |
620 ASSERT_TRUE(IsCertificateError(error)); | |
621 ASSERT_EQ(1u, verifier_.requests()); | |
622 ASSERT_EQ(0u, verifier_.cache_hits()); | |
623 ASSERT_EQ(0u, verifier_.inflight_joins()); | |
624 ASSERT_EQ(1u, verifier_.GetCacheSize()); | |
625 | |
626 error = verifier_.Verify(test_cert.get(), example_hostname, ocsp_response, | |
627 flags, crl_set, &verify_result, callback.callback(), | |
628 &request, BoundNetLog()); | |
629 // Synchronous completion. | |
630 ASSERT_NE(ERR_IO_PENDING, error); | |
631 ASSERT_TRUE(IsCertificateError(error)); | |
632 ASSERT_FALSE(request); | |
633 ASSERT_EQ(2u, verifier_.requests()); | |
634 ASSERT_EQ(1u, verifier_.cache_hits()); | |
635 ASSERT_EQ(0u, verifier_.inflight_joins()); | |
636 ASSERT_EQ(1u, verifier_.GetCacheSize()); | |
637 | |
638 MultiThreadedCertVerifier::Iterator iterator(verifier_); | |
639 EXPECT_TRUE(iterator.HasNext()); | |
640 ASSERT_EQ(example_hostname, iterator.hostname()); | |
641 | |
642 std::vector<SHA1HashValue> dummp_hash_values; | |
643 // Invalid hostname. | |
Ryan Sleevi
2016/05/13 20:18:13
Separate
| |
644 bool cert_result = verifier_.AddCertResult( | |
645 std::string(), iterator.flags(), iterator.hash_values(), | |
646 iterator.start_time(), iterator.error(), iterator.result(), | |
647 iterator.verification_time(), iterator.expiration_time()); | |
648 EXPECT_FALSE(cert_result); | |
649 // Invalid hash_values. | |
Ryan Sleevi
2016/05/13 20:18:13
Separate
| |
650 cert_result = verifier_.AddCertResult( | |
651 iterator.hostname(), iterator.flags(), dummp_hash_values, | |
652 iterator.start_time(), iterator.error(), iterator.result(), | |
653 iterator.verification_time(), iterator.expiration_time()); | |
654 EXPECT_FALSE(cert_result); | |
655 // Invalid start_time. | |
Ryan Sleevi
2016/05/13 20:18:13
Separate
| |
656 cert_result = verifier_.AddCertResult( | |
657 iterator.hostname(), iterator.flags(), iterator.hash_values(), | |
658 base::Time::Now(), iterator.error(), iterator.result(), | |
659 iterator.verification_time(), iterator.expiration_time()); | |
660 EXPECT_FALSE(cert_result); | |
661 // Corrupted start_time. | |
Ryan Sleevi
2016/05/13 20:18:13
Separate
| |
662 cert_result = verifier_.AddCertResult( | |
663 iterator.hostname(), iterator.flags(), iterator.hash_values(), | |
664 iterator.start_time() + base::TimeDelta::FromSeconds(1), iterator.error(), | |
665 iterator.result(), iterator.verification_time(), | |
666 iterator.expiration_time()); | |
667 EXPECT_FALSE(cert_result); | |
668 // Corrupted verification_time. | |
Ryan Sleevi
2016/05/13 20:18:13
Separate
| |
669 cert_result = verifier_.AddCertResult( | |
670 iterator.hostname(), iterator.flags(), iterator.hash_values(), | |
671 iterator.start_time(), iterator.error(), iterator.result(), | |
672 iterator.verification_time() + base::TimeDelta::FromSeconds(10), | |
673 iterator.expiration_time()); | |
674 EXPECT_FALSE(cert_result); | |
675 // Corrupted expired entry. | |
Ryan Sleevi
2016/05/13 20:18:13
Separate
| |
676 cert_result = verifier_.AddCertResult( | |
677 iterator.hostname(), iterator.flags(), iterator.hash_values(), | |
678 iterator.start_time(), iterator.error(), iterator.result(), | |
679 iterator.verification_time(), | |
680 iterator.expiration_time() - base::TimeDelta::FromSeconds(10)); | |
681 EXPECT_FALSE(cert_result); | |
682 // Expired entry. | |
Ryan Sleevi
2016/05/13 20:18:13
Separate
| |
683 cert_result = verifier_.AddCertResult( | |
684 iterator.hostname(), iterator.flags(), iterator.hash_values(), | |
685 iterator.start_time(), iterator.error(), iterator.result(), | |
686 iterator.verification_time(), base::Time::Now()); | |
687 EXPECT_FALSE(cert_result); | |
688 // Adding a duplicate entry. | |
Ryan Sleevi
2016/05/13 20:18:13
Separate
| |
689 cert_result = verifier_.AddCertResult( | |
690 iterator.hostname(), iterator.flags(), iterator.hash_values(), | |
691 iterator.start_time(), iterator.error(), iterator.result(), | |
692 iterator.verification_time(), iterator.expiration_time()); | |
693 EXPECT_FALSE(cert_result); | |
694 | |
695 // Save the data before clearing the cache. | |
Ryan Sleevi
2016/05/13 20:18:13
Separate
| |
696 std::string hostname = iterator.hostname(); | |
697 flags = iterator.flags(); | |
698 std::vector<SHA1HashValue> hash_values = iterator.hash_values(); | |
699 base::Time start_time = iterator.start_time(); | |
700 error = iterator.error(); | |
701 CertVerifyResult result = iterator.result(); | |
702 base::Time verification_time = iterator.verification_time(); | |
703 base::Time expiration_time = iterator.expiration_time(); | |
704 | |
705 verifier_.ClearCache(); | |
706 ASSERT_EQ(0u, verifier_.GetCacheSize()); | |
707 | |
708 cert_result = | |
709 verifier_.AddCertResult(hostname, flags, hash_values, start_time, error, | |
710 result, verification_time, expiration_time); | |
711 EXPECT_TRUE(cert_result); | |
712 ASSERT_EQ(1u, verifier_.GetCacheSize()); | |
713 | |
714 error = verifier_.Verify(test_cert.get(), example_hostname, ocsp_response, | |
715 flags, crl_set, &verify_result, callback.callback(), | |
716 &request, BoundNetLog()); | |
717 // Synchronous completion and verify that there is a cache hit. | |
718 ASSERT_NE(ERR_IO_PENDING, error); | |
719 ASSERT_TRUE(IsCertificateError(error)); | |
720 ASSERT_FALSE(request); | |
721 ASSERT_EQ(3u, verifier_.requests()); | |
722 ASSERT_EQ(2u, verifier_.cache_hits()); | |
723 ASSERT_EQ(0u, verifier_.inflight_joins()); | |
724 ASSERT_EQ(1u, verifier_.GetCacheSize()); | |
725 } | |
726 | |
517 } // namespace net | 727 } // namespace net |
OLD | NEW |