| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/quic/test_tools/crypto_test_utils.h" | 5 #include "net/quic/test_tools/crypto_test_utils.h" |
| 6 | 6 |
| 7 #include "base/callback_helpers.h" |
| 8 #include "base/logging.h" |
| 7 #include "base/memory/ref_counted.h" | 9 #include "base/memory/ref_counted.h" |
| 8 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| 11 #include "base/stl_util.h" |
| 12 #include "base/strings/stringprintf.h" |
| 9 #include "net/base/net_errors.h" | 13 #include "net/base/net_errors.h" |
| 14 #include "net/base/test_completion_callback.h" |
| 10 #include "net/base/test_data_directory.h" | 15 #include "net/base/test_data_directory.h" |
| 16 #include "net/cert/cert_status_flags.h" |
| 11 #include "net/cert/cert_verifier.h" | 17 #include "net/cert/cert_verifier.h" |
| 18 #include "net/cert/cert_verify_result.h" |
| 12 #include "net/cert/mock_cert_verifier.h" | 19 #include "net/cert/mock_cert_verifier.h" |
| 13 #include "net/cert/test_root_certs.h" | 20 #include "net/cert/test_root_certs.h" |
| 14 #include "net/cert/x509_certificate.h" | 21 #include "net/cert/x509_certificate.h" |
| 22 #include "net/cert/x509_util.h" |
| 15 #include "net/http/transport_security_state.h" | 23 #include "net/http/transport_security_state.h" |
| 24 #include "net/log/net_log.h" |
| 25 #include "net/quic/crypto/crypto_utils.h" |
| 16 #include "net/quic/crypto/proof_source_chromium.h" | 26 #include "net/quic/crypto/proof_source_chromium.h" |
| 17 #include "net/quic/crypto/proof_verifier_chromium.h" | 27 #include "net/quic/crypto/proof_verifier_chromium.h" |
| 28 #include "net/ssl/ssl_config_service.h" |
| 18 #include "net/test/cert_test_util.h" | 29 #include "net/test/cert_test_util.h" |
| 19 | 30 |
| 31 using base::StringPiece; |
| 32 using base::StringPrintf; |
| 33 using std::string; |
| 34 using std::vector; |
| 35 |
| 20 namespace net { | 36 namespace net { |
| 21 | 37 |
| 22 namespace test { | 38 namespace test { |
| 23 | 39 |
| 24 namespace { | 40 namespace { |
| 25 | 41 |
| 26 class TestProofVerifierChromium : public ProofVerifierChromium { | 42 class TestProofVerifierChromium : public ProofVerifierChromium { |
| 27 public: | 43 public: |
| 28 TestProofVerifierChromium( | 44 TestProofVerifierChromium( |
| 29 scoped_ptr<CertVerifier> cert_verifier, | 45 scoped_ptr<CertVerifier> cert_verifier, |
| 30 scoped_ptr<TransportSecurityState> transport_security_state, | 46 scoped_ptr<TransportSecurityState> transport_security_state, |
| 31 const std::string& cert_file) | 47 const std::string& cert_file) |
| 32 : ProofVerifierChromium(cert_verifier.get(), | 48 : ProofVerifierChromium(cert_verifier.get(), |
| 33 nullptr, | 49 nullptr, |
| 34 transport_security_state.get()), | 50 transport_security_state.get()), |
| 35 cert_verifier_(cert_verifier.Pass()), | 51 cert_verifier_(cert_verifier.Pass()), |
| 36 transport_security_state_(transport_security_state.Pass()) { | 52 transport_security_state_(transport_security_state.Pass()) { |
| 37 // Load and install the root for the validated chain. | 53 // Load and install the root for the validated chain. |
| 38 scoped_refptr<X509Certificate> root_cert = | 54 scoped_refptr<X509Certificate> root_cert = |
| 39 ImportCertFromFile(GetTestCertsDirectory(), cert_file); | 55 ImportCertFromFile(GetTestCertsDirectory(), cert_file); |
| 40 scoped_root_.Reset(root_cert.get()); | 56 scoped_root_.Reset(root_cert.get()); |
| 41 } | 57 } |
| 58 |
| 42 ~TestProofVerifierChromium() override {} | 59 ~TestProofVerifierChromium() override {} |
| 43 | 60 |
| 61 CertVerifier* cert_verifier() { return cert_verifier_.get(); } |
| 62 |
| 44 private: | 63 private: |
| 45 ScopedTestRoot scoped_root_; | 64 ScopedTestRoot scoped_root_; |
| 46 scoped_ptr<CertVerifier> cert_verifier_; | 65 scoped_ptr<CertVerifier> cert_verifier_; |
| 47 scoped_ptr<TransportSecurityState> transport_security_state_; | 66 scoped_ptr<TransportSecurityState> transport_security_state_; |
| 48 }; | 67 }; |
| 49 | 68 |
| 50 const char kLeafCert[] = "leaf"; | |
| 51 const char kIntermediateCert[] = "intermediate"; | |
| 52 const char kSignature[] = "signature"; | 69 const char kSignature[] = "signature"; |
| 53 const char kSCT[] = "CryptoServerTests"; | 70 const char kSCT[] = "CryptoServerTests"; |
| 54 | 71 |
| 55 class FakeProofSource : public ProofSource { | 72 class FakeProofSource : public ProofSource { |
| 56 public: | 73 public: |
| 57 FakeProofSource() : certs_(2) { | 74 FakeProofSource() {} |
| 58 certs_[0] = kLeafCert; | |
| 59 certs_[1] = kIntermediateCert; | |
| 60 } | |
| 61 ~FakeProofSource() override {} | 75 ~FakeProofSource() override {} |
| 62 | 76 |
| 63 // ProofSource interface | 77 // ProofSource interface |
| 78 bool Initialize(const base::FilePath& cert_path, |
| 79 const base::FilePath& key_path, |
| 80 const base::FilePath& sct_path) { |
| 81 std::string cert_data; |
| 82 if (!base::ReadFileToString(cert_path, &cert_data)) { |
| 83 DLOG(FATAL) << "Unable to read certificates."; |
| 84 return false; |
| 85 } |
| 86 |
| 87 CertificateList certs_in_file = |
| 88 X509Certificate::CreateCertificateListFromBytes( |
| 89 cert_data.data(), cert_data.size(), X509Certificate::FORMAT_AUTO); |
| 90 |
| 91 if (certs_in_file.empty()) { |
| 92 DLOG(FATAL) << "No certificates."; |
| 93 return false; |
| 94 } |
| 95 |
| 96 for (const scoped_refptr<X509Certificate>& cert : certs_in_file) { |
| 97 std::string der_encoded_cert; |
| 98 if (!X509Certificate::GetDEREncoded(cert->os_cert_handle(), |
| 99 &der_encoded_cert)) { |
| 100 return false; |
| 101 } |
| 102 certificates_.push_back(der_encoded_cert); |
| 103 } |
| 104 return true; |
| 105 } |
| 106 |
| 64 bool GetProof(const IPAddressNumber& server_ip, | 107 bool GetProof(const IPAddressNumber& server_ip, |
| 65 const std::string& hostname, | 108 const std::string& hostname, |
| 66 const std::string& server_config, | 109 const std::string& server_config, |
| 67 bool ecdsa_ok, | 110 bool ecdsa_ok, |
| 68 const std::vector<std::string>** out_certs, | 111 const std::vector<std::string>** out_certs, |
| 69 std::string* out_signature, | 112 std::string* out_signature, |
| 70 std::string* out_leaf_cert_sct) override { | 113 std::string* out_leaf_cert_sct) override { |
| 71 *out_certs = &certs_; | 114 out_signature->assign(kSignature); |
| 72 *out_signature = kSignature; | 115 *out_certs = &certificates_; |
| 73 *out_leaf_cert_sct = kSCT; | 116 *out_leaf_cert_sct = kSCT; |
| 74 return true; | 117 return true; |
| 75 } | 118 } |
| 76 | 119 |
| 77 private: | 120 private: |
| 78 std::vector<std::string> certs_; | 121 std::vector<std::string> certificates_; |
| 122 |
| 79 DISALLOW_COPY_AND_ASSIGN(FakeProofSource); | 123 DISALLOW_COPY_AND_ASSIGN(FakeProofSource); |
| 80 }; | 124 }; |
| 81 | 125 |
| 82 class FakeProofVerifier : public ProofVerifier { | 126 class FakeProofVerifier : public TestProofVerifierChromium { |
| 83 public: | 127 public: |
| 84 FakeProofVerifier() {} | 128 FakeProofVerifier(scoped_ptr<CertVerifier> cert_verifier, |
| 129 scoped_ptr<TransportSecurityState> transport_security_state, |
| 130 const std::string& cert_file) |
| 131 : TestProofVerifierChromium(cert_verifier.Pass(), |
| 132 transport_security_state.Pass(), |
| 133 cert_file) {} |
| 85 ~FakeProofVerifier() override {} | 134 ~FakeProofVerifier() override {} |
| 86 | 135 |
| 87 // ProofVerifier interface | 136 // ProofVerifier interface |
| 88 QuicAsyncStatus VerifyProof(const std::string& hostname, | 137 QuicAsyncStatus VerifyProof(const std::string& hostname, |
| 89 const std::string& server_config, | 138 const std::string& server_config, |
| 90 const std::vector<std::string>& certs, | 139 const std::vector<std::string>& certs, |
| 91 const std::string& signature, | 140 const std::string& signature, |
| 92 const ProofVerifyContext* verify_context, | 141 const ProofVerifyContext* verify_context, |
| 93 std::string* error_details, | 142 std::string* error_details, |
| 94 scoped_ptr<ProofVerifyDetails>* verify_details, | 143 scoped_ptr<ProofVerifyDetails>* verify_details, |
| 95 ProofVerifierCallback* callback) override { | 144 ProofVerifierCallback* callback) override { |
| 96 error_details->clear(); | 145 error_details->clear(); |
| 97 scoped_ptr<ProofVerifyDetailsChromium> verify_details_chromium( | 146 scoped_ptr<ProofVerifyDetailsChromium> verify_details_chromium( |
| 98 new ProofVerifyDetailsChromium); | 147 new ProofVerifyDetailsChromium); |
| 99 if (certs.size() != 2 || certs[0] != kLeafCert || | 148 DCHECK(!certs.empty()); |
| 100 certs[1] != kIntermediateCert || signature != kSignature) { | 149 // Convert certs to X509Certificate. |
| 150 vector<StringPiece> cert_pieces(certs.size()); |
| 151 for (unsigned i = 0; i < certs.size(); i++) { |
| 152 cert_pieces[i] = base::StringPiece(certs[i]); |
| 153 } |
| 154 scoped_refptr<X509Certificate> x509_cert = |
| 155 X509Certificate::CreateFromDERCertChain(cert_pieces); |
| 156 |
| 157 if (!x509_cert.get()) { |
| 158 *error_details = "Failed to create certificate chain"; |
| 159 verify_details_chromium->cert_verify_result.cert_status = |
| 160 CERT_STATUS_INVALID; |
| 161 *verify_details = verify_details_chromium.Pass(); |
| 162 return QUIC_FAILURE; |
| 163 } |
| 164 |
| 165 const ProofVerifyContextChromium* chromium_context = |
| 166 reinterpret_cast<const ProofVerifyContextChromium*>(verify_context); |
| 167 scoped_ptr<CertVerifier::Request> cert_verifier_request_; |
| 168 TestCompletionCallback test_callback; |
| 169 int result = cert_verifier()->Verify( |
| 170 x509_cert.get(), hostname, std::string(), |
| 171 chromium_context->cert_verify_flags, |
| 172 SSLConfigService::GetCRLSet().get(), |
| 173 &verify_details_chromium->cert_verify_result, test_callback.callback(), |
| 174 &cert_verifier_request_, chromium_context->net_log); |
| 175 if (result != OK) { |
| 176 std::string error_string = ErrorToString(result); |
| 177 *error_details = StringPrintf("Failed to verify certificate chain: %s", |
| 178 error_string.c_str()); |
| 179 verify_details_chromium->cert_verify_result.cert_status = |
| 180 CERT_STATUS_INVALID; |
| 181 *verify_details = verify_details_chromium.Pass(); |
| 182 return QUIC_FAILURE; |
| 183 } |
| 184 if (signature != kSignature) { |
| 101 *error_details = "Invalid proof"; | 185 *error_details = "Invalid proof"; |
| 102 verify_details_chromium->cert_verify_result.cert_status = | 186 verify_details_chromium->cert_verify_result.cert_status = |
| 103 CERT_STATUS_INVALID; | 187 CERT_STATUS_INVALID; |
| 104 *verify_details = verify_details_chromium.Pass(); | 188 *verify_details = verify_details_chromium.Pass(); |
| 105 return QUIC_FAILURE; | 189 return QUIC_FAILURE; |
| 106 } | 190 } |
| 107 *verify_details = verify_details_chromium.Pass(); | 191 *verify_details = verify_details_chromium.Pass(); |
| 108 return QUIC_SUCCESS; | 192 return QUIC_SUCCESS; |
| 109 } | 193 } |
| 110 | 194 |
| 111 private: | 195 private: |
| 112 DISALLOW_COPY_AND_ASSIGN(FakeProofVerifier); | 196 DISALLOW_COPY_AND_ASSIGN(FakeProofVerifier); |
| 113 }; | 197 }; |
| 114 | 198 |
| 115 } // namespace | 199 } // namespace |
| 116 | 200 |
| 117 // static | 201 // static |
| 118 ProofSource* CryptoTestUtils::ProofSourceForTesting() { | 202 ProofSource* CryptoTestUtils::ProofSourceForTesting() { |
| 203 #if defined(USE_OPENSSL) |
| 119 ProofSourceChromium* source = new ProofSourceChromium(); | 204 ProofSourceChromium* source = new ProofSourceChromium(); |
| 205 #else |
| 206 FakeProofSource* source = new FakeProofSource(); |
| 207 #endif |
| 120 base::FilePath certs_dir = GetTestCertsDirectory(); | 208 base::FilePath certs_dir = GetTestCertsDirectory(); |
| 121 CHECK(source->Initialize( | 209 CHECK(source->Initialize( |
| 122 certs_dir.AppendASCII("quic_test.example.com.crt"), | 210 certs_dir.AppendASCII("quic_test.example.com.crt"), |
| 123 certs_dir.AppendASCII("quic_test.example.com.key.pkcs8"), | 211 certs_dir.AppendASCII("quic_test.example.com.key.pkcs8"), |
| 124 certs_dir.AppendASCII("quic_test.example.com.key.sct"))); | 212 certs_dir.AppendASCII("quic_test.example.com.key.sct"))); |
| 125 return source; | 213 return source; |
| 126 } | 214 } |
| 127 | 215 |
| 128 // static | 216 // static |
| 129 ProofVerifier* CryptoTestUtils::ProofVerifierForTesting() { | 217 ProofVerifier* ProofVerifierForTestingInternal(bool use_real_proof_verifier) { |
| 130 // TODO(rch): use a real cert verifier? | 218 // TODO(rch): use a real cert verifier? |
| 131 scoped_ptr<MockCertVerifier> cert_verifier(new MockCertVerifier()); | 219 scoped_ptr<MockCertVerifier> cert_verifier(new MockCertVerifier()); |
| 132 net::CertVerifyResult verify_result; | 220 net::CertVerifyResult verify_result; |
| 133 verify_result.verified_cert = | 221 verify_result.verified_cert = |
| 134 ImportCertFromFile(GetTestCertsDirectory(), "quic_test.example.com.crt"); | 222 ImportCertFromFile(GetTestCertsDirectory(), "quic_test.example.com.crt"); |
| 135 cert_verifier->AddResultForCertAndHost(verify_result.verified_cert.get(), | 223 cert_verifier->AddResultForCertAndHost(verify_result.verified_cert.get(), |
| 136 "test.example.com", verify_result, OK); | 224 "test.example.com", verify_result, OK); |
| 137 verify_result.verified_cert = ImportCertFromFile( | 225 verify_result.verified_cert = ImportCertFromFile( |
| 138 GetTestCertsDirectory(), "quic_test_ecc.example.com.crt"); | 226 GetTestCertsDirectory(), "quic_test_ecc.example.com.crt"); |
| 139 cert_verifier->AddResultForCertAndHost(verify_result.verified_cert.get(), | 227 cert_verifier->AddResultForCertAndHost(verify_result.verified_cert.get(), |
| 140 "test.example.com", verify_result, OK); | 228 "test.example.com", verify_result, OK); |
| 229 if (use_real_proof_verifier) { |
| 230 return new TestProofVerifierChromium( |
| 231 cert_verifier.Pass(), make_scoped_ptr(new TransportSecurityState), |
| 232 "quic_root.crt"); |
| 233 } |
| 234 #if defined(USE_OPENSSL) |
| 141 return new TestProofVerifierChromium( | 235 return new TestProofVerifierChromium( |
| 142 cert_verifier.Pass(), make_scoped_ptr(new TransportSecurityState), | 236 cert_verifier.Pass(), make_scoped_ptr(new TransportSecurityState), |
| 143 "quic_root.crt"); | 237 "quic_root.crt"); |
| 238 #else |
| 239 return new FakeProofVerifier(cert_verifier.Pass(), |
| 240 make_scoped_ptr(new TransportSecurityState), |
| 241 "quic_root.crt"); |
| 242 #endif |
| 243 } |
| 244 |
| 245 // static |
| 246 ProofVerifier* CryptoTestUtils::ProofVerifierForTesting() { |
| 247 return ProofVerifierForTestingInternal(/*use_real_proof_verifier=*/false); |
| 248 } |
| 249 |
| 250 // static |
| 251 ProofVerifier* CryptoTestUtils::RealProofVerifierForTesting() { |
| 252 return ProofVerifierForTestingInternal(/*use_real_proof_verifier=*/true); |
| 144 } | 253 } |
| 145 | 254 |
| 146 // static | 255 // static |
| 147 ProofVerifyContext* CryptoTestUtils::ProofVerifyContextForTesting() { | 256 ProofVerifyContext* CryptoTestUtils::ProofVerifyContextForTesting() { |
| 148 return new ProofVerifyContextChromium(/*cert_verify_flags=*/0, BoundNetLog()); | 257 return new ProofVerifyContextChromium(/*cert_verify_flags=*/0, BoundNetLog()); |
| 149 } | 258 } |
| 150 | 259 |
| 151 // static | |
| 152 ProofSource* CryptoTestUtils::FakeProofSourceForTesting() { | |
| 153 return new FakeProofSource(); | |
| 154 } | |
| 155 | |
| 156 // static | |
| 157 ProofVerifier* CryptoTestUtils::FakeProofVerifierForTesting() { | |
| 158 return new FakeProofVerifier(); | |
| 159 } | |
| 160 | |
| 161 // static | |
| 162 ProofVerifyContext* CryptoTestUtils::FakeProofVerifyContextForTesting() { | |
| 163 return nullptr; | |
| 164 } | |
| 165 | |
| 166 } // namespace test | 260 } // namespace test |
| 167 | 261 |
| 168 } // namespace net | 262 } // namespace net |
| OLD | NEW |