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 |