blob: 1b95f65ec79726bda0eeea6b369776a80a24bd37 [file] [log] [blame]
[email protected]c244c5a12013-05-07 20:55:041// Copyright (c) 2013 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
rch16c74d1d2016-04-22 06:14:075#include <memory>
6
[email protected]2662ed562013-07-03 10:27:467#include "base/files/file_path.h"
rtenneti7dac4be2014-12-15 21:10:018#include "net/base/ip_endpoint.h"
[email protected]2662ed562013-07-03 10:27:469#include "net/base/net_errors.h"
10#include "net/base/test_completion_callback.h"
[email protected]a69af0522013-07-12 19:23:4711#include "net/cert/cert_status_flags.h"
12#include "net/cert/cert_verify_result.h"
[email protected]2662ed562013-07-03 10:27:4613#include "net/cert/x509_certificate.h"
[email protected]c244c5a12013-05-07 20:55:0414#include "net/quic/crypto/proof_source.h"
15#include "net/quic/crypto/proof_verifier.h"
16#include "net/quic/test_tools/crypto_test_utils.h"
[email protected]2662ed562013-07-03 10:27:4617#include "net/test/cert_test_util.h"
rsleevia69c79a2016-06-22 03:28:4318#include "net/test/test_data_directory.h"
[email protected]c244c5a12013-05-07 20:55:0419#include "testing/gtest/include/gtest/gtest.h"
20
[email protected]c244c5a12013-05-07 20:55:0421using std::string;
22using std::vector;
23
24namespace net {
25namespace test {
[email protected]6a731c92014-03-22 00:43:2426namespace {
[email protected]c244c5a12013-05-07 20:55:0427
[email protected]72e65992013-07-30 17:16:1428// TestProofVerifierCallback is a simple callback for a ProofVerifier that
29// signals a TestCompletionCallback when called and stores the results from the
30// ProofVerifier in pointers passed to the constructor.
31class TestProofVerifierCallback : public ProofVerifierCallback {
32 public:
33 TestProofVerifierCallback(TestCompletionCallback* comp_callback,
34 bool* ok,
[email protected]b9475b582014-03-20 20:04:3335 string* error_details)
rjshaded5ced072015-12-18 19:26:0236 : comp_callback_(comp_callback), ok_(ok), error_details_(error_details) {}
[email protected]72e65992013-07-30 17:16:1437
dchengb03027d2014-10-21 12:00:2038 void Run(bool ok,
39 const string& error_details,
danakjad1777e2016-04-16 00:56:4240 std::unique_ptr<ProofVerifyDetails>* details) override {
[email protected]72e65992013-07-30 17:16:1441 *ok_ = ok;
42 *error_details_ = error_details;
43
44 comp_callback_->callback().Run(0);
45 }
46
47 private:
48 TestCompletionCallback* const comp_callback_;
49 bool* const ok_;
[email protected]b9475b582014-03-20 20:04:3350 string* const error_details_;
[email protected]72e65992013-07-30 17:16:1451};
52
53// RunVerification runs |verifier->VerifyProof| and asserts that the result
54// matches |expected_ok|.
[email protected]6a731c92014-03-22 00:43:2455void RunVerification(ProofVerifier* verifier,
56 const string& hostname,
elawrence954bb5472016-04-04 22:03:1157 const uint16_t port,
[email protected]6a731c92014-03-22 00:43:2458 const string& server_config,
rch28f6469d2016-03-13 21:13:0859 QuicVersion quic_version,
60 StringPiece chlo_hash,
[email protected]6a731c92014-03-22 00:43:2461 const vector<string>& certs,
62 const string& proof,
63 bool expected_ok) {
danakjad1777e2016-04-16 00:56:4264 std::unique_ptr<ProofVerifyDetails> details;
[email protected]72e65992013-07-30 17:16:1465 TestCompletionCallback comp_callback;
66 bool ok;
[email protected]b9475b582014-03-20 20:04:3367 string error_details;
danakjad1777e2016-04-16 00:56:4268 std::unique_ptr<ProofVerifyContext> verify_context(
[email protected]c817c672014-03-21 22:25:3469 CryptoTestUtils::ProofVerifyContextForTesting());
ckrasic6567aa52016-07-08 09:24:3570 std::unique_ptr<TestProofVerifierCallback> callback(
71 new TestProofVerifierCallback(&comp_callback, &ok, &error_details));
[email protected]72e65992013-07-30 17:16:1472
[email protected]730b35d72014-06-05 03:23:2273 QuicAsyncStatus status = verifier->VerifyProof(
elawrence954bb5472016-04-04 22:03:1174 hostname, port, server_config, quic_version, chlo_hash, certs, "", proof,
ckrasic6567aa52016-07-08 09:24:3575 verify_context.get(), &error_details, &details, std::move(callback));
[email protected]72e65992013-07-30 17:16:1476
77 switch (status) {
[email protected]730b35d72014-06-05 03:23:2278 case QUIC_FAILURE:
[email protected]72e65992013-07-30 17:16:1479 ASSERT_FALSE(expected_ok);
80 ASSERT_NE("", error_details);
81 return;
[email protected]730b35d72014-06-05 03:23:2282 case QUIC_SUCCESS:
[email protected]72e65992013-07-30 17:16:1483 ASSERT_TRUE(expected_ok);
84 ASSERT_EQ("", error_details);
85 return;
[email protected]730b35d72014-06-05 03:23:2286 case QUIC_PENDING:
[email protected]72e65992013-07-30 17:16:1487 comp_callback.WaitForResult();
88 ASSERT_EQ(expected_ok, ok);
89 break;
90 }
91}
92
[email protected]6a731c92014-03-22 00:43:2493// Reads the certificate named "quic_" + |file_name| in the test data directory.
94// The certificate must be PEM encoded. Returns the DER-encoded certificate.
95string LoadTestCert(const string& file_name) {
[email protected]2662ed562013-07-03 10:27:4696 base::FilePath certs_dir = GetTestCertsDirectory();
97 scoped_refptr<X509Certificate> cert =
[email protected]6a731c92014-03-22 00:43:2498 ImportCertFromFile(certs_dir, "quic_" + file_name);
rtennetibe635732014-10-02 22:51:4299 CHECK_NE(static_cast<X509Certificate*>(nullptr), cert.get());
[email protected]2662ed562013-07-03 10:27:46100
101 string der_bytes;
102 CHECK(X509Certificate::GetDEREncoded(cert->os_cert_handle(), &der_bytes));
103 return der_bytes;
104}
105
ckrasic6567aa52016-07-08 09:24:35106class TestCallback : public ProofSource::Callback {
107 public:
108 explicit TestCallback(bool* called,
109 bool* ok,
110 scoped_refptr<ProofSource::Chain>* chain,
111 string* signature,
112 string* leaf_cert_sct)
113 : called_(called),
114 ok_(ok),
115 chain_(chain),
116 signature_(signature),
117 leaf_cert_sct_(leaf_cert_sct) {}
118
119 void Run(bool ok,
120 const scoped_refptr<ProofSource::Chain>& chain,
121 const string& signature,
122 const string& leaf_cert_sct) override {
123 *ok_ = ok;
124 *chain_ = chain;
125 *signature_ = signature;
126 *leaf_cert_sct_ = leaf_cert_sct;
127 *called_ = true;
128 }
129
130 private:
131 bool* called_;
132 bool* ok_;
133 scoped_refptr<ProofSource::Chain>* chain_;
134 string* signature_;
135 string* leaf_cert_sct_;
136};
137
rch28f6469d2016-03-13 21:13:08138class ProofTest : public ::testing::TestWithParam<QuicVersion> {};
139
[email protected]6a731c92014-03-22 00:43:24140} // namespace
141
rch28f6469d2016-03-13 21:13:08142INSTANTIATE_TEST_CASE_P(QuicVersion,
143 ProofTest,
144 ::testing::ValuesIn(QuicSupportedVersions()));
145
rtenneti0b073d02015-07-28 04:27:56146// TODO(rtenneti): Enable testing of ProofVerifier. See http://crbug.com/514468.
rch28f6469d2016-03-13 21:13:08147TEST_P(ProofTest, DISABLED_Verify) {
danakjad1777e2016-04-16 00:56:42148 std::unique_ptr<ProofSource> source(CryptoTestUtils::ProofSourceForTesting());
149 std::unique_ptr<ProofVerifier> verifier(
[email protected]6a731c92014-03-22 00:43:24150 CryptoTestUtils::ProofVerifierForTesting());
151
152 const string server_config = "server config bytes";
153 const string hostname = "test.example.com";
elawrence954bb5472016-04-04 22:03:11154 const uint16_t port = 8443;
rch28f6469d2016-03-13 21:13:08155 const string first_chlo_hash = "first chlo hash bytes";
156 const string second_chlo_hash = "first chlo hash bytes";
157 const QuicVersion quic_version = GetParam();
elawrence954bb5472016-04-04 22:03:11158
fayanga64c1a92016-02-13 01:55:58159 scoped_refptr<ProofSource::Chain> chain;
160 scoped_refptr<ProofSource::Chain> first_chain;
rch99b644c2015-11-04 05:25:28161 string error_details, signature, first_signature, first_cert_sct, cert_sct;
martijncc5402d2016-02-16 19:08:58162 IPAddress server_ip;
[email protected]6a731c92014-03-22 00:43:24163
rch28f6469d2016-03-13 21:13:08164 ASSERT_TRUE(source->GetProof(
165 server_ip, hostname, server_config, quic_version, first_chlo_hash,
166 false /* no ECDSA */, &first_chain, &first_signature, &first_cert_sct));
167 ASSERT_TRUE(source->GetProof(server_ip, hostname, server_config, quic_version,
168 second_chlo_hash, false /* no ECDSA */, &chain,
169 &signature, &cert_sct));
[email protected]6a731c92014-03-22 00:43:24170
171 // Check that the proof source is caching correctly:
fayanga64c1a92016-02-13 01:55:58172 ASSERT_EQ(first_chain->certs, chain->certs);
rch28f6469d2016-03-13 21:13:08173 if (GetParam() < QUIC_VERSION_31) {
174 ASSERT_EQ(signature, first_signature);
175 } else {
176 // QUIC 31 includes the CHLO hash.
177 ASSERT_NE(signature, first_signature);
178 }
rch99b644c2015-11-04 05:25:28179 ASSERT_EQ(first_cert_sct, cert_sct);
[email protected]6a731c92014-03-22 00:43:24180
elawrence954bb5472016-04-04 22:03:11181 RunVerification(verifier.get(), hostname, port, server_config, quic_version,
rch28f6469d2016-03-13 21:13:08182 first_chlo_hash, chain->certs, signature, true);
[email protected]6a731c92014-03-22 00:43:24183
elawrence954bb5472016-04-04 22:03:11184 RunVerification(verifier.get(), "foo.com", port, server_config, quic_version,
rch28f6469d2016-03-13 21:13:08185 first_chlo_hash, chain->certs, signature, false);
[email protected]6a731c92014-03-22 00:43:24186
elawrence954bb5472016-04-04 22:03:11187 RunVerification(verifier.get(), server_config.substr(1, string::npos), port,
rch28f6469d2016-03-13 21:13:08188 server_config, quic_version, first_chlo_hash, chain->certs,
189 signature, false);
[email protected]6a731c92014-03-22 00:43:24190
191 const string corrupt_signature = "1" + signature;
elawrence954bb5472016-04-04 22:03:11192 RunVerification(verifier.get(), hostname, port, server_config, quic_version,
rch28f6469d2016-03-13 21:13:08193 first_chlo_hash, chain->certs, corrupt_signature, false);
[email protected]6a731c92014-03-22 00:43:24194
195 vector<string> wrong_certs;
fayanga64c1a92016-02-13 01:55:58196 for (size_t i = 1; i < chain->certs.size(); i++) {
197 wrong_certs.push_back(chain->certs[i]);
[email protected]6a731c92014-03-22 00:43:24198 }
elawrence954bb5472016-04-04 22:03:11199
200 RunVerification(verifier.get(), "foo.com", port, server_config, quic_version,
rch28f6469d2016-03-13 21:13:08201 first_chlo_hash, wrong_certs, corrupt_signature, false);
[email protected]6a731c92014-03-22 00:43:24202}
203
ckrasic6567aa52016-07-08 09:24:35204TEST_P(ProofTest, VerifySourceAsync) {
205 std::unique_ptr<ProofSource> source(CryptoTestUtils::ProofSourceForTesting());
206
207 const string server_config = "server config bytes";
208 const string hostname = "test.example.com";
209 const string first_chlo_hash = "first chlo hash bytes";
210 const string second_chlo_hash = "first chlo hash bytes";
211 const QuicVersion quic_version = GetParam();
212 IPAddress server_ip;
213
214 // Call synchronous version
215 scoped_refptr<ProofSource::Chain> expected_chain;
216 string expected_signature;
217 string expected_leaf_cert_sct;
218 ASSERT_TRUE(source->GetProof(server_ip, hostname, server_config, quic_version,
219 first_chlo_hash, false /* no ECDSA */,
220 &expected_chain, &expected_signature,
221 &expected_leaf_cert_sct));
222
223 // Call asynchronous version and compare results
224 bool called = false;
225 bool ok;
226 scoped_refptr<ProofSource::Chain> chain;
227 string signature;
228 string leaf_cert_sct;
229 std::unique_ptr<ProofSource::Callback> cb(
230 new TestCallback(&called, &ok, &chain, &signature, &leaf_cert_sct));
231 source->GetProof(server_ip, hostname, server_config, quic_version,
232 first_chlo_hash, false /* no ECDSA */, std::move(cb));
233 // TODO(gredner): whan GetProof really invokes the callback asynchronously,
234 // figure out what to do here.
235 ASSERT_TRUE(called);
236 ASSERT_TRUE(ok);
237 EXPECT_THAT(chain->certs, ::testing::ContainerEq(expected_chain->certs));
238 EXPECT_EQ(leaf_cert_sct, expected_leaf_cert_sct);
239}
240
rch28f6469d2016-03-13 21:13:08241TEST_P(ProofTest, UseAfterFree) {
fayanga64c1a92016-02-13 01:55:58242 ProofSource* source = CryptoTestUtils::ProofSourceForTesting();
243
244 const string server_config = "server config bytes";
245 const string hostname = "test.example.com";
rch28f6469d2016-03-13 21:13:08246 const string chlo_hash = "proof nonce bytes";
fayanga64c1a92016-02-13 01:55:58247 scoped_refptr<ProofSource::Chain> chain;
248 string error_details, signature, cert_sct;
martijncc5402d2016-02-16 19:08:58249 IPAddress server_ip;
fayanga64c1a92016-02-13 01:55:58250
rch28f6469d2016-03-13 21:13:08251 ASSERT_TRUE(source->GetProof(server_ip, hostname, server_config, GetParam(),
252 chlo_hash, false /* no ECDSA */, &chain,
253 &signature, &cert_sct));
fayanga64c1a92016-02-13 01:55:58254
255 // Make sure we can safely access results after deleting where they came from.
256 EXPECT_FALSE(chain->HasOneRef());
257 delete source;
258 EXPECT_TRUE(chain->HasOneRef());
259
260 EXPECT_FALSE(chain->certs.empty());
261 for (const string& cert : chain->certs) {
262 EXPECT_FALSE(cert.empty());
263 }
264}
265
[email protected]2662ed562013-07-03 10:27:46266// A known answer test that allows us to test ProofVerifier without a working
267// ProofSource.
rch28f6469d2016-03-13 21:13:08268TEST_P(ProofTest, VerifyRSAKnownAnswerTest) {
269 if (GetParam() > QUIC_VERSION_30) {
270 return;
271 }
[email protected]2662ed562013-07-03 10:27:46272 // These sample signatures were generated by running the Proof.Verify test
273 // and dumping the bytes of the |signature| output of ProofSource::GetProof().
[email protected]2662ed562013-07-03 10:27:46274 static const unsigned char signature_data_0[] = {
rjshaded5ced072015-12-18 19:26:02275 0x31, 0xd5, 0xfb, 0x40, 0x30, 0x75, 0xd2, 0x7d, 0x61, 0xf9, 0xd7, 0x54,
276 0x30, 0x06, 0xaf, 0x54, 0x0d, 0xb0, 0x0a, 0xda, 0x63, 0xca, 0x7e, 0x9e,
277 0xce, 0xba, 0x10, 0x05, 0x1b, 0xa6, 0x7f, 0xef, 0x2b, 0xa3, 0xff, 0x3c,
278 0xbb, 0x9a, 0xe4, 0xbf, 0xb8, 0x0c, 0xc1, 0xbd, 0xed, 0xc2, 0x90, 0x68,
279 0xeb, 0x45, 0x48, 0xea, 0x3c, 0x95, 0xf8, 0xa2, 0xb9, 0xe7, 0x62, 0x29,
280 0x00, 0xc3, 0x18, 0xb4, 0x16, 0x6f, 0x5e, 0xb0, 0xc1, 0x26, 0xc0, 0x4b,
281 0x84, 0xf5, 0x97, 0xfc, 0x17, 0xf9, 0x1c, 0x43, 0xb8, 0xf2, 0x3f, 0x38,
282 0x32, 0xad, 0x36, 0x52, 0x2c, 0x26, 0x92, 0x7a, 0xea, 0x2c, 0xa2, 0xf4,
283 0x28, 0x2f, 0x19, 0x4d, 0x1f, 0x11, 0x46, 0x82, 0xd0, 0xc4, 0x86, 0x56,
284 0x5c, 0x97, 0x9e, 0xc6, 0x37, 0x8e, 0xaf, 0x9d, 0x69, 0xe9, 0x4f, 0x5a,
285 0x6d, 0x70, 0x75, 0xc7, 0x41, 0x95, 0x68, 0x53, 0x94, 0xca, 0x31, 0x63,
286 0x61, 0x9f, 0xb8, 0x8c, 0x3b, 0x75, 0x36, 0x8b, 0x69, 0xa2, 0x35, 0xc0,
287 0x4b, 0x77, 0x55, 0x08, 0xc2, 0xb4, 0x56, 0xd2, 0x81, 0xce, 0x9e, 0x25,
288 0xdb, 0x50, 0x74, 0xb3, 0x8a, 0xd9, 0x20, 0x42, 0x3f, 0x85, 0x2d, 0xaa,
289 0xfd, 0x66, 0xfa, 0xd6, 0x95, 0x55, 0x6b, 0x63, 0x63, 0x04, 0xf8, 0x6c,
290 0x3e, 0x08, 0x22, 0x39, 0xb9, 0x9a, 0xe0, 0xd7, 0x01, 0xff, 0xeb, 0x8a,
291 0xb9, 0xe2, 0x34, 0xa5, 0xa0, 0x51, 0xe9, 0xbe, 0x15, 0x12, 0xbf, 0xbe,
292 0x64, 0x3d, 0x3f, 0x98, 0xce, 0xc1, 0xa6, 0x33, 0x32, 0xd3, 0x5c, 0xa8,
293 0x39, 0x93, 0xdc, 0x1c, 0xb9, 0xab, 0x3c, 0x80, 0x62, 0xb3, 0x76, 0x21,
294 0xdf, 0x47, 0x1e, 0xa9, 0x0e, 0x5e, 0x8a, 0xbe, 0x66, 0x5b, 0x7c, 0x21,
295 0xfa, 0x78, 0x2d, 0xd1, 0x1d, 0x5c, 0x35, 0x8a, 0x34, 0xb2, 0x1a, 0xc2,
296 0xc4, 0x4b, 0x53, 0x54,
[email protected]8bbfaeb72013-08-09 06:38:26297 };
[email protected]d5c9e4ba2013-09-14 05:25:58298 static const unsigned char signature_data_1[] = {
rjshaded5ced072015-12-18 19:26:02299 0x01, 0x7b, 0x52, 0x35, 0xe3, 0x51, 0xdd, 0xf1, 0x67, 0x8d, 0x31, 0x5e,
300 0xa3, 0x75, 0x1f, 0x68, 0x6c, 0xdd, 0x41, 0x7a, 0x18, 0x25, 0xe0, 0x12,
301 0x6e, 0x84, 0x46, 0x5e, 0xb2, 0x98, 0xd7, 0x84, 0xe1, 0x62, 0xe0, 0xc1,
302 0xc4, 0xd7, 0x4f, 0x4f, 0x80, 0xc1, 0x92, 0xd6, 0x02, 0xaf, 0xca, 0x28,
303 0x9f, 0xe0, 0xf3, 0x74, 0xd7, 0xf1, 0x44, 0x67, 0x59, 0x27, 0xc8, 0xc2,
304 0x8b, 0xd4, 0xe5, 0x4a, 0x07, 0xfd, 0x00, 0xd6, 0x8a, 0xbf, 0x8b, 0xcd,
305 0x6a, 0xe0, 0x1d, 0xf6, 0x4b, 0x68, 0x0f, 0xcf, 0xb9, 0xd0, 0xa1, 0xbc,
306 0x2e, 0xcf, 0x7c, 0x03, 0x47, 0x11, 0xe4, 0x4c, 0xbc, 0x1b, 0x6b, 0xa5,
307 0x2a, 0x82, 0x86, 0xa4, 0x7f, 0x1d, 0x85, 0x64, 0x21, 0x10, 0xd2, 0xb2,
308 0xa0, 0x31, 0xa2, 0x78, 0xe6, 0xf2, 0xea, 0x96, 0x38, 0x8c, 0x9a, 0xe1,
309 0x01, 0xab, 0x8e, 0x95, 0x66, 0xc8, 0xe5, 0xcc, 0x80, 0xa3, 0xbd, 0x16,
310 0xa7, 0x79, 0x19, 0x39, 0x61, 0x3d, 0xff, 0x37, 0xca, 0x9f, 0x97, 0x05,
311 0xc7, 0xcb, 0xf0, 0xea, 0xaf, 0x64, 0x07, 0xc0, 0xed, 0x2a, 0x98, 0xa4,
312 0xaf, 0x04, 0x6f, 0xf2, 0xc9, 0xb2, 0x73, 0x9a, 0x56, 0x85, 0x43, 0x64,
313 0x5f, 0xaa, 0xb7, 0xff, 0x31, 0x4c, 0x2e, 0x6c, 0x17, 0xcf, 0xe5, 0xbe,
314 0x7f, 0x7e, 0xad, 0xf5, 0x6f, 0x84, 0x50, 0x20, 0x29, 0xb3, 0x57, 0xe7,
315 0xb1, 0xdc, 0x2c, 0x95, 0x48, 0xfe, 0xb0, 0xc1, 0x92, 0xda, 0xc5, 0x58,
316 0x95, 0xb0, 0x1a, 0x3a, 0x05, 0x71, 0x3c, 0x6d, 0x20, 0x01, 0x4c, 0xa9,
317 0xe4, 0x38, 0x08, 0x65, 0xb4, 0xbd, 0x86, 0x76, 0xbd, 0xad, 0x25, 0x06,
318 0x74, 0x0b, 0xca, 0x95, 0x27, 0x0c, 0x13, 0x08, 0x7e, 0x30, 0xcf, 0xf6,
319 0xb5, 0xc1, 0x2a, 0x08, 0xfc, 0x4b, 0xc6, 0xb5, 0x2f, 0x23, 0x27, 0x32,
320 0x89, 0xdb, 0x0e, 0x4a,
[email protected]8bbfaeb72013-08-09 06:38:26321 };
[email protected]d5c9e4ba2013-09-14 05:25:58322 static const unsigned char signature_data_2[] = {
rjshaded5ced072015-12-18 19:26:02323 0x6d, 0x7d, 0x22, 0x8c, 0x85, 0xc4, 0x8a, 0x80, 0x05, 0xe4, 0x3c, 0xaf,
324 0x10, 0x3b, 0xe3, 0x51, 0xb1, 0x86, 0x52, 0x63, 0xb6, 0x17, 0x33, 0xbd,
325 0x1b, 0x1e, 0xc4, 0x50, 0x10, 0xfc, 0xcc, 0xea, 0x6b, 0x11, 0xeb, 0x6d,
326 0x5e, 0x00, 0xe7, 0xf3, 0x67, 0x99, 0x74, 0x53, 0x12, 0x8f, 0xe4, 0x3e,
327 0x20, 0x17, 0x8e, 0x83, 0xe6, 0xdc, 0x83, 0x91, 0x0e, 0xf3, 0x69, 0x22,
328 0x95, 0x14, 0xdf, 0xc1, 0xda, 0xb5, 0xdb, 0x6a, 0x1a, 0xb4, 0x4f, 0x26,
329 0xd0, 0x32, 0x1d, 0x73, 0x95, 0x1f, 0x39, 0x1d, 0x00, 0xcb, 0xc3, 0x92,
330 0x49, 0x53, 0xcb, 0x5c, 0x36, 0x70, 0x19, 0xd9, 0x64, 0x36, 0xda, 0xfb,
331 0x20, 0xe5, 0x47, 0xd9, 0x08, 0xc6, 0x5a, 0x9e, 0x87, 0x1a, 0xdb, 0x11,
332 0x7b, 0x17, 0xfc, 0x53, 0x7b, 0xc1, 0xa0, 0xc0, 0x33, 0xcf, 0x96, 0xba,
333 0x03, 0x79, 0x8e, 0xc6, 0x05, 0xd2, 0xb7, 0xa2, 0xe2, 0xc1, 0x67, 0xb7,
334 0x6a, 0xeb, 0xb1, 0x40, 0xbb, 0x7d, 0x57, 0xcb, 0xc2, 0x60, 0x9f, 0xf1,
335 0x72, 0xe5, 0xad, 0xce, 0x95, 0x45, 0x7c, 0xbc, 0x75, 0x81, 0x45, 0x19,
336 0xe1, 0xa7, 0x2f, 0x05, 0x52, 0xeb, 0xed, 0xdd, 0x19, 0xd9, 0x1a, 0xc9,
337 0x5a, 0x06, 0x8e, 0x29, 0x54, 0xb5, 0x4f, 0x80, 0xaa, 0x36, 0x36, 0xc0,
338 0xff, 0x64, 0xac, 0xe8, 0x0f, 0x99, 0x35, 0x5e, 0xc6, 0x72, 0x1f, 0x8c,
339 0xc4, 0x2b, 0x7d, 0xc1, 0xfb, 0xf0, 0x12, 0x61, 0xb1, 0x18, 0x65, 0xdd,
340 0xc2, 0x38, 0x92, 0xba, 0x84, 0xf8, 0xc8, 0x5e, 0x17, 0x63, 0xe0, 0x9c,
341 0x2c, 0xe6, 0x70, 0x71, 0xdc, 0xe5, 0xc1, 0xea, 0xb3, 0x9a, 0xb6, 0x91,
342 0xdc, 0xc5, 0x56, 0x84, 0x8a, 0x31, 0x31, 0x23, 0x61, 0x94, 0x7e, 0x01,
343 0x22, 0x49, 0xf3, 0xcb, 0x0e, 0x31, 0x03, 0x04, 0x1b, 0x14, 0x43, 0x7c,
344 0xad, 0x42, 0xe5, 0x55,
[email protected]8bbfaeb72013-08-09 06:38:26345 };
[email protected]2662ed562013-07-03 10:27:46346
danakjad1777e2016-04-16 00:56:42347 std::unique_ptr<ProofVerifier> verifier(
rtennetiac06c2f2015-11-05 18:12:35348 CryptoTestUtils::RealProofVerifierForTesting());
[email protected]2662ed562013-07-03 10:27:46349
350 const string server_config = "server config bytes";
351 const string hostname = "test.example.com";
elawrence954bb5472016-04-04 22:03:11352 const uint16_t port = 8443;
rch28f6469d2016-03-13 21:13:08353 const string chlo_hash = "proof nonce bytes";
354 const QuicVersion quic_version = GetParam();
[email protected]2662ed562013-07-03 10:27:46355
356 vector<string> certs(2);
[email protected]6a731c92014-03-22 00:43:24357 certs[0] = LoadTestCert("test.example.com.crt");
358 certs[1] = LoadTestCert("intermediate.crt");
[email protected]2662ed562013-07-03 10:27:46359
360 // Signatures are nondeterministic, so we test multiple signatures on the
361 // same server_config.
362 vector<string> signatures(3);
[email protected]d5c9e4ba2013-09-14 05:25:58363 signatures[0].assign(reinterpret_cast<const char*>(signature_data_0),
364 sizeof(signature_data_0));
365 signatures[1].assign(reinterpret_cast<const char*>(signature_data_1),
366 sizeof(signature_data_1));
367 signatures[2].assign(reinterpret_cast<const char*>(signature_data_2),
368 sizeof(signature_data_2));
[email protected]2662ed562013-07-03 10:27:46369
370 for (size_t i = 0; i < signatures.size(); i++) {
371 const string& signature = signatures[i];
[email protected]2662ed562013-07-03 10:27:46372
elawrence954bb5472016-04-04 22:03:11373 RunVerification(verifier.get(), hostname, port, server_config, quic_version,
rch28f6469d2016-03-13 21:13:08374 chlo_hash, certs, signature, true);
elawrence954bb5472016-04-04 22:03:11375 RunVerification(verifier.get(), "foo.com", port, server_config,
376 quic_version, chlo_hash, certs, signature, false);
377 RunVerification(verifier.get(), hostname, port,
rch28f6469d2016-03-13 21:13:08378 server_config.substr(1, string::npos), quic_version,
379 chlo_hash, certs, signature, false);
[email protected]2662ed562013-07-03 10:27:46380
381 const string corrupt_signature = "1" + signature;
elawrence954bb5472016-04-04 22:03:11382 RunVerification(verifier.get(), hostname, port, server_config, quic_version,
rch28f6469d2016-03-13 21:13:08383 chlo_hash, certs, corrupt_signature, false);
[email protected]2662ed562013-07-03 10:27:46384
385 vector<string> wrong_certs;
386 for (size_t i = 1; i < certs.size(); i++) {
387 wrong_certs.push_back(certs[i]);
388 }
elawrence954bb5472016-04-04 22:03:11389 RunVerification(verifier.get(), hostname, port, server_config, quic_version,
rch28f6469d2016-03-13 21:13:08390 chlo_hash, wrong_certs, signature, false);
[email protected]2662ed562013-07-03 10:27:46391 }
392}
393
394// A known answer test that allows us to test ProofVerifier without a working
395// ProofSource.
rch28f6469d2016-03-13 21:13:08396TEST_P(ProofTest, VerifyECDSAKnownAnswerTest) {
397 if (GetParam() > QUIC_VERSION_30) {
398 return;
399 }
[email protected]5bfce8a2013-07-31 08:21:55400
[email protected]2662ed562013-07-03 10:27:46401 // These sample signatures were generated by running the Proof.Verify test
402 // (modified to use ECDSA for signing proofs) and dumping the bytes of the
403 // |signature| output of ProofSource::GetProof().
404 static const unsigned char signature_data_0[] = {
rjshaded5ced072015-12-18 19:26:02405 0x30, 0x45, 0x02, 0x21, 0x00, 0x89, 0xc4, 0x7d, 0x08, 0xd1, 0x49, 0x19,
406 0x6c, 0xd1, 0x7c, 0xb9, 0x25, 0xe0, 0xe3, 0xbd, 0x6a, 0x5c, 0xd7, 0xaa,
407 0x0c, 0xdc, 0x4f, 0x8e, 0xeb, 0xde, 0xbf, 0x32, 0xf8, 0xd1, 0x84, 0x95,
408 0x97, 0x02, 0x20, 0x29, 0x3d, 0x49, 0x22, 0x73, 0xed, 0x8b, 0xde, 0x3d,
409 0xc2, 0xa4, 0x20, 0xcc, 0xe7, 0xc8, 0x2a, 0x85, 0x20, 0x9b, 0x5b, 0xda,
410 0xcd, 0x58, 0x23, 0xbe, 0x89, 0x73, 0x31, 0x87, 0x51, 0xd1, 0x01,
[email protected]2662ed562013-07-03 10:27:46411 };
412 static const unsigned char signature_data_1[] = {
rjshaded5ced072015-12-18 19:26:02413 0x30, 0x46, 0x02, 0x21, 0x00, 0xec, 0xdf, 0x69, 0xc8, 0x24, 0x59, 0x93,
414 0xda, 0x49, 0xee, 0x37, 0x28, 0xaf, 0xeb, 0x0e, 0x2f, 0x80, 0x17, 0x4b,
415 0x3b, 0xf6, 0x54, 0xcd, 0x3b, 0x86, 0xc5, 0x98, 0x0d, 0xff, 0xc6, 0xb1,
416 0xe7, 0x02, 0x21, 0x00, 0xe1, 0x36, 0x8c, 0xc0, 0xf4, 0x50, 0x5f, 0xba,
417 0xfb, 0xe2, 0xff, 0x1d, 0x5d, 0x64, 0xe4, 0x07, 0xbb, 0x5a, 0x4b, 0x19,
418 0xb6, 0x39, 0x7a, 0xc4, 0x12, 0xc6, 0xe5, 0x42, 0xc8, 0x78, 0x33, 0xcd,
[email protected]2662ed562013-07-03 10:27:46419 };
420 static const unsigned char signature_data_2[] = {
rjshaded5ced072015-12-18 19:26:02421 0x30, 0x45, 0x02, 0x20, 0x09, 0x51, 0xe9, 0xde, 0xdb, 0x01, 0xfd, 0xb4,
422 0xd8, 0x20, 0xbb, 0xad, 0x41, 0xe3, 0xaa, 0xe7, 0xa3, 0xc3, 0x32, 0x10,
423 0x9d, 0xfa, 0x37, 0xce, 0x17, 0xd1, 0x29, 0xf9, 0xd4, 0x1d, 0x0d, 0x19,
424 0x02, 0x21, 0x00, 0xc6, 0x20, 0xd4, 0x28, 0xf9, 0x70, 0xb5, 0xb4, 0xff,
425 0x4a, 0x35, 0xba, 0xa0, 0xf2, 0x8e, 0x00, 0xf7, 0xcb, 0x43, 0xaf, 0x2d,
426 0x1f, 0xce, 0x92, 0x05, 0xca, 0x29, 0xfe, 0xd2, 0x8f, 0xd9, 0x31,
[email protected]2662ed562013-07-03 10:27:46427 };
428
danakjad1777e2016-04-16 00:56:42429 std::unique_ptr<ProofVerifier> verifier(
rtennetiac06c2f2015-11-05 18:12:35430 CryptoTestUtils::RealProofVerifierForTesting());
[email protected]2662ed562013-07-03 10:27:46431
432 const string server_config = "server config bytes";
433 const string hostname = "test.example.com";
elawrence954bb5472016-04-04 22:03:11434 const uint16_t port = 8443;
rch28f6469d2016-03-13 21:13:08435 const string chlo_hash = "chlo_hash nonce bytes";
436 const QuicVersion quic_version = GetParam();
[email protected]2662ed562013-07-03 10:27:46437
438 vector<string> certs(2);
[email protected]6a731c92014-03-22 00:43:24439 certs[0] = LoadTestCert("test_ecc.example.com.crt");
440 certs[1] = LoadTestCert("intermediate.crt");
[email protected]2662ed562013-07-03 10:27:46441
442 // Signatures are nondeterministic, so we test multiple signatures on the
443 // same server_config.
444 vector<string> signatures(3);
445 signatures[0].assign(reinterpret_cast<const char*>(signature_data_0),
446 sizeof(signature_data_0));
447 signatures[1].assign(reinterpret_cast<const char*>(signature_data_1),
448 sizeof(signature_data_1));
449 signatures[2].assign(reinterpret_cast<const char*>(signature_data_2),
450 sizeof(signature_data_2));
451
452 for (size_t i = 0; i < signatures.size(); i++) {
453 const string& signature = signatures[i];
[email protected]2662ed562013-07-03 10:27:46454
elawrence954bb5472016-04-04 22:03:11455 RunVerification(verifier.get(), hostname, port, server_config, quic_version,
rch28f6469d2016-03-13 21:13:08456 chlo_hash, certs, signature, true);
elawrence954bb5472016-04-04 22:03:11457 RunVerification(verifier.get(), "foo.com", port, server_config,
458 quic_version, chlo_hash, certs, signature, false);
elawrence954bb5472016-04-04 22:03:11459 RunVerification(verifier.get(), hostname, port,
rch28f6469d2016-03-13 21:13:08460 server_config.substr(1, string::npos), quic_version,
461 chlo_hash, certs, signature, false);
[email protected]2662ed562013-07-03 10:27:46462
463 // An ECDSA signature is DER-encoded. Corrupt the last byte so that the
464 // signature can still be DER-decoded correctly.
465 string corrupt_signature = signature;
466 corrupt_signature[corrupt_signature.size() - 1] += 1;
elawrence954bb5472016-04-04 22:03:11467 RunVerification(verifier.get(), hostname, port, server_config, quic_version,
rch28f6469d2016-03-13 21:13:08468 chlo_hash, certs, corrupt_signature, false);
[email protected]2662ed562013-07-03 10:27:46469
470 // Prepending a "1" makes the DER invalid.
471 const string bad_der_signature1 = "1" + signature;
elawrence954bb5472016-04-04 22:03:11472 RunVerification(verifier.get(), hostname, port, server_config, quic_version,
rch28f6469d2016-03-13 21:13:08473 chlo_hash, certs, bad_der_signature1, false);
[email protected]2662ed562013-07-03 10:27:46474
475 vector<string> wrong_certs;
476 for (size_t i = 1; i < certs.size(); i++) {
477 wrong_certs.push_back(certs[i]);
478 }
elawrence954bb5472016-04-04 22:03:11479 RunVerification(verifier.get(), hostname, port, server_config, quic_version,
rch28f6469d2016-03-13 21:13:08480 chlo_hash, wrong_certs, signature, false);
[email protected]2662ed562013-07-03 10:27:46481 }
482}
483
[email protected]c244c5a12013-05-07 20:55:04484} // namespace test
485} // namespace net