| Index: net/quic/test_tools/crypto_test_utils_chromium.cc
|
| diff --git a/net/quic/test_tools/crypto_test_utils_chromium.cc b/net/quic/test_tools/crypto_test_utils_chromium.cc
|
| index 8ff3c97753300f0b081f792d6be99e4d8311a3f4..9978d72c264d64bd4f9c8918c4c4d2b3f590ad22 100644
|
| --- a/net/quic/test_tools/crypto_test_utils_chromium.cc
|
| +++ b/net/quic/test_tools/crypto_test_utils_chromium.cc
|
| @@ -4,19 +4,35 @@
|
|
|
| #include "net/quic/test_tools/crypto_test_utils.h"
|
|
|
| +#include "base/callback_helpers.h"
|
| +#include "base/logging.h"
|
| #include "base/memory/ref_counted.h"
|
| #include "base/memory/scoped_ptr.h"
|
| +#include "base/stl_util.h"
|
| +#include "base/strings/stringprintf.h"
|
| #include "net/base/net_errors.h"
|
| +#include "net/base/test_completion_callback.h"
|
| #include "net/base/test_data_directory.h"
|
| +#include "net/cert/cert_status_flags.h"
|
| #include "net/cert/cert_verifier.h"
|
| +#include "net/cert/cert_verify_result.h"
|
| #include "net/cert/mock_cert_verifier.h"
|
| #include "net/cert/test_root_certs.h"
|
| #include "net/cert/x509_certificate.h"
|
| +#include "net/cert/x509_util.h"
|
| #include "net/http/transport_security_state.h"
|
| +#include "net/log/net_log.h"
|
| +#include "net/quic/crypto/crypto_utils.h"
|
| #include "net/quic/crypto/proof_source_chromium.h"
|
| #include "net/quic/crypto/proof_verifier_chromium.h"
|
| +#include "net/ssl/ssl_config_service.h"
|
| #include "net/test/cert_test_util.h"
|
|
|
| +using base::StringPiece;
|
| +using base::StringPrintf;
|
| +using std::string;
|
| +using std::vector;
|
| +
|
| namespace net {
|
|
|
| namespace test {
|
| @@ -39,28 +55,55 @@ class TestProofVerifierChromium : public ProofVerifierChromium {
|
| ImportCertFromFile(GetTestCertsDirectory(), cert_file);
|
| scoped_root_.Reset(root_cert.get());
|
| }
|
| +
|
| ~TestProofVerifierChromium() override {}
|
|
|
| + CertVerifier* cert_verifier() { return cert_verifier_.get(); }
|
| +
|
| private:
|
| ScopedTestRoot scoped_root_;
|
| scoped_ptr<CertVerifier> cert_verifier_;
|
| scoped_ptr<TransportSecurityState> transport_security_state_;
|
| };
|
|
|
| -const char kLeafCert[] = "leaf";
|
| -const char kIntermediateCert[] = "intermediate";
|
| const char kSignature[] = "signature";
|
| const char kSCT[] = "CryptoServerTests";
|
|
|
| class FakeProofSource : public ProofSource {
|
| public:
|
| - FakeProofSource() : certs_(2) {
|
| - certs_[0] = kLeafCert;
|
| - certs_[1] = kIntermediateCert;
|
| - }
|
| + FakeProofSource() {}
|
| ~FakeProofSource() override {}
|
|
|
| // ProofSource interface
|
| + bool Initialize(const base::FilePath& cert_path,
|
| + const base::FilePath& key_path,
|
| + const base::FilePath& sct_path) {
|
| + std::string cert_data;
|
| + if (!base::ReadFileToString(cert_path, &cert_data)) {
|
| + DLOG(FATAL) << "Unable to read certificates.";
|
| + return false;
|
| + }
|
| +
|
| + CertificateList certs_in_file =
|
| + X509Certificate::CreateCertificateListFromBytes(
|
| + cert_data.data(), cert_data.size(), X509Certificate::FORMAT_AUTO);
|
| +
|
| + if (certs_in_file.empty()) {
|
| + DLOG(FATAL) << "No certificates.";
|
| + return false;
|
| + }
|
| +
|
| + for (const scoped_refptr<X509Certificate>& cert : certs_in_file) {
|
| + std::string der_encoded_cert;
|
| + if (!X509Certificate::GetDEREncoded(cert->os_cert_handle(),
|
| + &der_encoded_cert)) {
|
| + return false;
|
| + }
|
| + certificates_.push_back(der_encoded_cert);
|
| + }
|
| + return true;
|
| + }
|
| +
|
| bool GetProof(const IPAddressNumber& server_ip,
|
| const std::string& hostname,
|
| const std::string& server_config,
|
| @@ -68,20 +111,26 @@ class FakeProofSource : public ProofSource {
|
| const std::vector<std::string>** out_certs,
|
| std::string* out_signature,
|
| std::string* out_leaf_cert_sct) override {
|
| - *out_certs = &certs_;
|
| - *out_signature = kSignature;
|
| + out_signature->assign(kSignature);
|
| + *out_certs = &certificates_;
|
| *out_leaf_cert_sct = kSCT;
|
| return true;
|
| }
|
|
|
| private:
|
| - std::vector<std::string> certs_;
|
| + std::vector<std::string> certificates_;
|
| +
|
| DISALLOW_COPY_AND_ASSIGN(FakeProofSource);
|
| };
|
|
|
| -class FakeProofVerifier : public ProofVerifier {
|
| +class FakeProofVerifier : public TestProofVerifierChromium {
|
| public:
|
| - FakeProofVerifier() {}
|
| + FakeProofVerifier(scoped_ptr<CertVerifier> cert_verifier,
|
| + scoped_ptr<TransportSecurityState> transport_security_state,
|
| + const std::string& cert_file)
|
| + : TestProofVerifierChromium(cert_verifier.Pass(),
|
| + transport_security_state.Pass(),
|
| + cert_file) {}
|
| ~FakeProofVerifier() override {}
|
|
|
| // ProofVerifier interface
|
| @@ -96,8 +145,43 @@ class FakeProofVerifier : public ProofVerifier {
|
| error_details->clear();
|
| scoped_ptr<ProofVerifyDetailsChromium> verify_details_chromium(
|
| new ProofVerifyDetailsChromium);
|
| - if (certs.size() != 2 || certs[0] != kLeafCert ||
|
| - certs[1] != kIntermediateCert || signature != kSignature) {
|
| + DCHECK(!certs.empty());
|
| + // Convert certs to X509Certificate.
|
| + vector<StringPiece> cert_pieces(certs.size());
|
| + for (unsigned i = 0; i < certs.size(); i++) {
|
| + cert_pieces[i] = base::StringPiece(certs[i]);
|
| + }
|
| + scoped_refptr<X509Certificate> x509_cert =
|
| + X509Certificate::CreateFromDERCertChain(cert_pieces);
|
| +
|
| + if (!x509_cert.get()) {
|
| + *error_details = "Failed to create certificate chain";
|
| + verify_details_chromium->cert_verify_result.cert_status =
|
| + CERT_STATUS_INVALID;
|
| + *verify_details = verify_details_chromium.Pass();
|
| + return QUIC_FAILURE;
|
| + }
|
| +
|
| + const ProofVerifyContextChromium* chromium_context =
|
| + reinterpret_cast<const ProofVerifyContextChromium*>(verify_context);
|
| + scoped_ptr<CertVerifier::Request> cert_verifier_request_;
|
| + TestCompletionCallback test_callback;
|
| + int result = cert_verifier()->Verify(
|
| + x509_cert.get(), hostname, std::string(),
|
| + chromium_context->cert_verify_flags,
|
| + SSLConfigService::GetCRLSet().get(),
|
| + &verify_details_chromium->cert_verify_result, test_callback.callback(),
|
| + &cert_verifier_request_, chromium_context->net_log);
|
| + if (result != OK) {
|
| + std::string error_string = ErrorToString(result);
|
| + *error_details = StringPrintf("Failed to verify certificate chain: %s",
|
| + error_string.c_str());
|
| + verify_details_chromium->cert_verify_result.cert_status =
|
| + CERT_STATUS_INVALID;
|
| + *verify_details = verify_details_chromium.Pass();
|
| + return QUIC_FAILURE;
|
| + }
|
| + if (signature != kSignature) {
|
| *error_details = "Invalid proof";
|
| verify_details_chromium->cert_verify_result.cert_status =
|
| CERT_STATUS_INVALID;
|
| @@ -116,7 +200,11 @@ class FakeProofVerifier : public ProofVerifier {
|
|
|
| // static
|
| ProofSource* CryptoTestUtils::ProofSourceForTesting() {
|
| +#if defined(USE_OPENSSL)
|
| ProofSourceChromium* source = new ProofSourceChromium();
|
| +#else
|
| + FakeProofSource* source = new FakeProofSource();
|
| +#endif
|
| base::FilePath certs_dir = GetTestCertsDirectory();
|
| CHECK(source->Initialize(
|
| certs_dir.AppendASCII("quic_test.example.com.crt"),
|
| @@ -126,7 +214,7 @@ ProofSource* CryptoTestUtils::ProofSourceForTesting() {
|
| }
|
|
|
| // static
|
| -ProofVerifier* CryptoTestUtils::ProofVerifierForTesting() {
|
| +ProofVerifier* ProofVerifierForTestingInternal(bool use_real_proof_verifier) {
|
| // TODO(rch): use a real cert verifier?
|
| scoped_ptr<MockCertVerifier> cert_verifier(new MockCertVerifier());
|
| net::CertVerifyResult verify_result;
|
| @@ -138,29 +226,35 @@ ProofVerifier* CryptoTestUtils::ProofVerifierForTesting() {
|
| GetTestCertsDirectory(), "quic_test_ecc.example.com.crt");
|
| cert_verifier->AddResultForCertAndHost(verify_result.verified_cert.get(),
|
| "test.example.com", verify_result, OK);
|
| + if (use_real_proof_verifier) {
|
| + return new TestProofVerifierChromium(
|
| + cert_verifier.Pass(), make_scoped_ptr(new TransportSecurityState),
|
| + "quic_root.crt");
|
| + }
|
| +#if defined(USE_OPENSSL)
|
| return new TestProofVerifierChromium(
|
| cert_verifier.Pass(), make_scoped_ptr(new TransportSecurityState),
|
| "quic_root.crt");
|
| +#else
|
| + return new FakeProofVerifier(cert_verifier.Pass(),
|
| + make_scoped_ptr(new TransportSecurityState),
|
| + "quic_root.crt");
|
| +#endif
|
| }
|
|
|
| // static
|
| -ProofVerifyContext* CryptoTestUtils::ProofVerifyContextForTesting() {
|
| - return new ProofVerifyContextChromium(/*cert_verify_flags=*/0, BoundNetLog());
|
| -}
|
| -
|
| -// static
|
| -ProofSource* CryptoTestUtils::FakeProofSourceForTesting() {
|
| - return new FakeProofSource();
|
| +ProofVerifier* CryptoTestUtils::ProofVerifierForTesting() {
|
| + return ProofVerifierForTestingInternal(/*use_real_proof_verifier=*/false);
|
| }
|
|
|
| // static
|
| -ProofVerifier* CryptoTestUtils::FakeProofVerifierForTesting() {
|
| - return new FakeProofVerifier();
|
| +ProofVerifier* CryptoTestUtils::RealProofVerifierForTesting() {
|
| + return ProofVerifierForTestingInternal(/*use_real_proof_verifier=*/true);
|
| }
|
|
|
| // static
|
| -ProofVerifyContext* CryptoTestUtils::FakeProofVerifyContextForTesting() {
|
| - return nullptr;
|
| +ProofVerifyContext* CryptoTestUtils::ProofVerifyContextForTesting() {
|
| + return new ProofVerifyContextChromium(/*cert_verify_flags=*/0, BoundNetLog());
|
| }
|
|
|
| } // namespace test
|
|
|