blob: 67af4127d4c61bf761e46f463876f7156fa0e6ae [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
[email protected]2662ed562013-07-03 10:27:465#include "base/files/file_path.h"
rtenneti7dac4be2014-12-15 21:10:016#include "net/base/ip_endpoint.h"
[email protected]2662ed562013-07-03 10:27:467#include "net/base/net_errors.h"
8#include "net/base/test_completion_callback.h"
9#include "net/base/test_data_directory.h"
[email protected]a69af0522013-07-12 19:23:4710#include "net/cert/cert_status_flags.h"
11#include "net/cert/cert_verify_result.h"
[email protected]2662ed562013-07-03 10:27:4612#include "net/cert/x509_certificate.h"
[email protected]c244c5a12013-05-07 20:55:0413#include "net/quic/crypto/proof_source.h"
14#include "net/quic/crypto/proof_verifier.h"
15#include "net/quic/test_tools/crypto_test_utils.h"
[email protected]2662ed562013-07-03 10:27:4616#include "net/test/cert_test_util.h"
[email protected]c244c5a12013-05-07 20:55:0417#include "testing/gtest/include/gtest/gtest.h"
18
[email protected]5bfce8a2013-07-31 08:21:5519#if defined(OS_WIN)
20#include "base/win/windows_version.h"
21#endif
22
[email protected]c244c5a12013-05-07 20:55:0423using std::string;
24using std::vector;
25
26namespace net {
27namespace test {
[email protected]6a731c92014-03-22 00:43:2428namespace {
[email protected]c244c5a12013-05-07 20:55:0429
[email protected]72e65992013-07-30 17:16:1430// TestProofVerifierCallback is a simple callback for a ProofVerifier that
31// signals a TestCompletionCallback when called and stores the results from the
32// ProofVerifier in pointers passed to the constructor.
33class TestProofVerifierCallback : public ProofVerifierCallback {
34 public:
35 TestProofVerifierCallback(TestCompletionCallback* comp_callback,
36 bool* ok,
[email protected]b9475b582014-03-20 20:04:3337 string* error_details)
rjshaded5ced072015-12-18 19:26:0238 : comp_callback_(comp_callback), ok_(ok), error_details_(error_details) {}
[email protected]72e65992013-07-30 17:16:1439
dchengb03027d2014-10-21 12:00:2040 void Run(bool ok,
41 const string& error_details,
danakjad1777e2016-04-16 00:56:4242 std::unique_ptr<ProofVerifyDetails>* details) override {
[email protected]72e65992013-07-30 17:16:1443 *ok_ = ok;
44 *error_details_ = error_details;
45
46 comp_callback_->callback().Run(0);
47 }
48
49 private:
50 TestCompletionCallback* const comp_callback_;
51 bool* const ok_;
[email protected]b9475b582014-03-20 20:04:3352 string* const error_details_;
[email protected]72e65992013-07-30 17:16:1453};
54
55// RunVerification runs |verifier->VerifyProof| and asserts that the result
56// matches |expected_ok|.
[email protected]6a731c92014-03-22 00:43:2457void RunVerification(ProofVerifier* verifier,
58 const string& hostname,
elawrence954bb5472016-04-04 22:03:1159 const uint16_t port,
[email protected]6a731c92014-03-22 00:43:2460 const string& server_config,
rch28f6469d2016-03-13 21:13:0861 QuicVersion quic_version,
62 StringPiece chlo_hash,
[email protected]6a731c92014-03-22 00:43:2463 const vector<string>& certs,
64 const string& proof,
65 bool expected_ok) {
danakjad1777e2016-04-16 00:56:4266 std::unique_ptr<ProofVerifyDetails> details;
[email protected]72e65992013-07-30 17:16:1467 TestCompletionCallback comp_callback;
68 bool ok;
[email protected]b9475b582014-03-20 20:04:3369 string error_details;
danakjad1777e2016-04-16 00:56:4270 std::unique_ptr<ProofVerifyContext> verify_context(
[email protected]c817c672014-03-21 22:25:3471 CryptoTestUtils::ProofVerifyContextForTesting());
[email protected]72e65992013-07-30 17:16:1472 TestProofVerifierCallback* callback =
73 new TestProofVerifierCallback(&comp_callback, &ok, &error_details);
74
[email protected]730b35d72014-06-05 03:23:2275 QuicAsyncStatus status = verifier->VerifyProof(
elawrence954bb5472016-04-04 22:03:1176 hostname, port, server_config, quic_version, chlo_hash, certs, "", proof,
rch28f6469d2016-03-13 21:13:0877 verify_context.get(), &error_details, &details, callback);
[email protected]72e65992013-07-30 17:16:1478
79 switch (status) {
[email protected]730b35d72014-06-05 03:23:2280 case QUIC_FAILURE:
[email protected]3ce3bf22014-04-03 08:02:0181 delete callback;
[email protected]72e65992013-07-30 17:16:1482 ASSERT_FALSE(expected_ok);
83 ASSERT_NE("", error_details);
84 return;
[email protected]730b35d72014-06-05 03:23:2285 case QUIC_SUCCESS:
[email protected]3ce3bf22014-04-03 08:02:0186 delete callback;
[email protected]72e65992013-07-30 17:16:1487 ASSERT_TRUE(expected_ok);
88 ASSERT_EQ("", error_details);
89 return;
[email protected]730b35d72014-06-05 03:23:2290 case QUIC_PENDING:
[email protected]72e65992013-07-30 17:16:1491 comp_callback.WaitForResult();
92 ASSERT_EQ(expected_ok, ok);
93 break;
94 }
95}
96
[email protected]6a731c92014-03-22 00:43:2497// Reads the certificate named "quic_" + |file_name| in the test data directory.
98// The certificate must be PEM encoded. Returns the DER-encoded certificate.
99string LoadTestCert(const string& file_name) {
[email protected]2662ed562013-07-03 10:27:46100 base::FilePath certs_dir = GetTestCertsDirectory();
101 scoped_refptr<X509Certificate> cert =
[email protected]6a731c92014-03-22 00:43:24102 ImportCertFromFile(certs_dir, "quic_" + file_name);
rtennetibe635732014-10-02 22:51:42103 CHECK_NE(static_cast<X509Certificate*>(nullptr), cert.get());
[email protected]2662ed562013-07-03 10:27:46104
105 string der_bytes;
106 CHECK(X509Certificate::GetDEREncoded(cert->os_cert_handle(), &der_bytes));
107 return der_bytes;
108}
109
rch28f6469d2016-03-13 21:13:08110class ProofTest : public ::testing::TestWithParam<QuicVersion> {};
111
[email protected]6a731c92014-03-22 00:43:24112} // namespace
113
rch28f6469d2016-03-13 21:13:08114INSTANTIATE_TEST_CASE_P(QuicVersion,
115 ProofTest,
116 ::testing::ValuesIn(QuicSupportedVersions()));
117
rtenneti0b073d02015-07-28 04:27:56118// TODO(rtenneti): Enable testing of ProofVerifier. See http://crbug.com/514468.
rch28f6469d2016-03-13 21:13:08119TEST_P(ProofTest, DISABLED_Verify) {
danakjad1777e2016-04-16 00:56:42120 std::unique_ptr<ProofSource> source(CryptoTestUtils::ProofSourceForTesting());
121 std::unique_ptr<ProofVerifier> verifier(
[email protected]6a731c92014-03-22 00:43:24122 CryptoTestUtils::ProofVerifierForTesting());
123
124 const string server_config = "server config bytes";
125 const string hostname = "test.example.com";
elawrence954bb5472016-04-04 22:03:11126 const uint16_t port = 8443;
rch28f6469d2016-03-13 21:13:08127 const string first_chlo_hash = "first chlo hash bytes";
128 const string second_chlo_hash = "first chlo hash bytes";
129 const QuicVersion quic_version = GetParam();
elawrence954bb5472016-04-04 22:03:11130
fayanga64c1a92016-02-13 01:55:58131 scoped_refptr<ProofSource::Chain> chain;
132 scoped_refptr<ProofSource::Chain> first_chain;
rch99b644c2015-11-04 05:25:28133 string error_details, signature, first_signature, first_cert_sct, cert_sct;
martijncc5402d2016-02-16 19:08:58134 IPAddress server_ip;
[email protected]6a731c92014-03-22 00:43:24135
rch28f6469d2016-03-13 21:13:08136 ASSERT_TRUE(source->GetProof(
137 server_ip, hostname, server_config, quic_version, first_chlo_hash,
138 false /* no ECDSA */, &first_chain, &first_signature, &first_cert_sct));
139 ASSERT_TRUE(source->GetProof(server_ip, hostname, server_config, quic_version,
140 second_chlo_hash, false /* no ECDSA */, &chain,
141 &signature, &cert_sct));
[email protected]6a731c92014-03-22 00:43:24142
143 // Check that the proof source is caching correctly:
fayanga64c1a92016-02-13 01:55:58144 ASSERT_EQ(first_chain->certs, chain->certs);
rch28f6469d2016-03-13 21:13:08145 if (GetParam() < QUIC_VERSION_31) {
146 ASSERT_EQ(signature, first_signature);
147 } else {
148 // QUIC 31 includes the CHLO hash.
149 ASSERT_NE(signature, first_signature);
150 }
rch99b644c2015-11-04 05:25:28151 ASSERT_EQ(first_cert_sct, cert_sct);
[email protected]6a731c92014-03-22 00:43:24152
elawrence954bb5472016-04-04 22:03:11153 RunVerification(verifier.get(), hostname, port, server_config, quic_version,
rch28f6469d2016-03-13 21:13:08154 first_chlo_hash, chain->certs, signature, true);
[email protected]6a731c92014-03-22 00:43:24155
elawrence954bb5472016-04-04 22:03:11156 RunVerification(verifier.get(), "foo.com", port, server_config, quic_version,
rch28f6469d2016-03-13 21:13:08157 first_chlo_hash, chain->certs, signature, false);
[email protected]6a731c92014-03-22 00:43:24158
elawrence954bb5472016-04-04 22:03:11159 RunVerification(verifier.get(), server_config.substr(1, string::npos), port,
rch28f6469d2016-03-13 21:13:08160 server_config, quic_version, first_chlo_hash, chain->certs,
161 signature, false);
[email protected]6a731c92014-03-22 00:43:24162
163 const string corrupt_signature = "1" + signature;
elawrence954bb5472016-04-04 22:03:11164 RunVerification(verifier.get(), hostname, port, server_config, quic_version,
rch28f6469d2016-03-13 21:13:08165 first_chlo_hash, chain->certs, corrupt_signature, false);
[email protected]6a731c92014-03-22 00:43:24166
167 vector<string> wrong_certs;
fayanga64c1a92016-02-13 01:55:58168 for (size_t i = 1; i < chain->certs.size(); i++) {
169 wrong_certs.push_back(chain->certs[i]);
[email protected]6a731c92014-03-22 00:43:24170 }
elawrence954bb5472016-04-04 22:03:11171
172 RunVerification(verifier.get(), "foo.com", port, server_config, quic_version,
rch28f6469d2016-03-13 21:13:08173 first_chlo_hash, wrong_certs, corrupt_signature, false);
[email protected]6a731c92014-03-22 00:43:24174}
175
rch28f6469d2016-03-13 21:13:08176TEST_P(ProofTest, UseAfterFree) {
fayanga64c1a92016-02-13 01:55:58177 ProofSource* source = CryptoTestUtils::ProofSourceForTesting();
178
179 const string server_config = "server config bytes";
180 const string hostname = "test.example.com";
rch28f6469d2016-03-13 21:13:08181 const string chlo_hash = "proof nonce bytes";
fayanga64c1a92016-02-13 01:55:58182 scoped_refptr<ProofSource::Chain> chain;
183 string error_details, signature, cert_sct;
martijncc5402d2016-02-16 19:08:58184 IPAddress server_ip;
fayanga64c1a92016-02-13 01:55:58185
rch28f6469d2016-03-13 21:13:08186 ASSERT_TRUE(source->GetProof(server_ip, hostname, server_config, GetParam(),
187 chlo_hash, false /* no ECDSA */, &chain,
188 &signature, &cert_sct));
fayanga64c1a92016-02-13 01:55:58189
190 // Make sure we can safely access results after deleting where they came from.
191 EXPECT_FALSE(chain->HasOneRef());
192 delete source;
193 EXPECT_TRUE(chain->HasOneRef());
194
195 EXPECT_FALSE(chain->certs.empty());
196 for (const string& cert : chain->certs) {
197 EXPECT_FALSE(cert.empty());
198 }
199}
200
[email protected]2662ed562013-07-03 10:27:46201// A known answer test that allows us to test ProofVerifier without a working
202// ProofSource.
rch28f6469d2016-03-13 21:13:08203TEST_P(ProofTest, VerifyRSAKnownAnswerTest) {
204 if (GetParam() > QUIC_VERSION_30) {
205 return;
206 }
[email protected]2662ed562013-07-03 10:27:46207 // These sample signatures were generated by running the Proof.Verify test
208 // and dumping the bytes of the |signature| output of ProofSource::GetProof().
[email protected]2662ed562013-07-03 10:27:46209 static const unsigned char signature_data_0[] = {
rjshaded5ced072015-12-18 19:26:02210 0x31, 0xd5, 0xfb, 0x40, 0x30, 0x75, 0xd2, 0x7d, 0x61, 0xf9, 0xd7, 0x54,
211 0x30, 0x06, 0xaf, 0x54, 0x0d, 0xb0, 0x0a, 0xda, 0x63, 0xca, 0x7e, 0x9e,
212 0xce, 0xba, 0x10, 0x05, 0x1b, 0xa6, 0x7f, 0xef, 0x2b, 0xa3, 0xff, 0x3c,
213 0xbb, 0x9a, 0xe4, 0xbf, 0xb8, 0x0c, 0xc1, 0xbd, 0xed, 0xc2, 0x90, 0x68,
214 0xeb, 0x45, 0x48, 0xea, 0x3c, 0x95, 0xf8, 0xa2, 0xb9, 0xe7, 0x62, 0x29,
215 0x00, 0xc3, 0x18, 0xb4, 0x16, 0x6f, 0x5e, 0xb0, 0xc1, 0x26, 0xc0, 0x4b,
216 0x84, 0xf5, 0x97, 0xfc, 0x17, 0xf9, 0x1c, 0x43, 0xb8, 0xf2, 0x3f, 0x38,
217 0x32, 0xad, 0x36, 0x52, 0x2c, 0x26, 0x92, 0x7a, 0xea, 0x2c, 0xa2, 0xf4,
218 0x28, 0x2f, 0x19, 0x4d, 0x1f, 0x11, 0x46, 0x82, 0xd0, 0xc4, 0x86, 0x56,
219 0x5c, 0x97, 0x9e, 0xc6, 0x37, 0x8e, 0xaf, 0x9d, 0x69, 0xe9, 0x4f, 0x5a,
220 0x6d, 0x70, 0x75, 0xc7, 0x41, 0x95, 0x68, 0x53, 0x94, 0xca, 0x31, 0x63,
221 0x61, 0x9f, 0xb8, 0x8c, 0x3b, 0x75, 0x36, 0x8b, 0x69, 0xa2, 0x35, 0xc0,
222 0x4b, 0x77, 0x55, 0x08, 0xc2, 0xb4, 0x56, 0xd2, 0x81, 0xce, 0x9e, 0x25,
223 0xdb, 0x50, 0x74, 0xb3, 0x8a, 0xd9, 0x20, 0x42, 0x3f, 0x85, 0x2d, 0xaa,
224 0xfd, 0x66, 0xfa, 0xd6, 0x95, 0x55, 0x6b, 0x63, 0x63, 0x04, 0xf8, 0x6c,
225 0x3e, 0x08, 0x22, 0x39, 0xb9, 0x9a, 0xe0, 0xd7, 0x01, 0xff, 0xeb, 0x8a,
226 0xb9, 0xe2, 0x34, 0xa5, 0xa0, 0x51, 0xe9, 0xbe, 0x15, 0x12, 0xbf, 0xbe,
227 0x64, 0x3d, 0x3f, 0x98, 0xce, 0xc1, 0xa6, 0x33, 0x32, 0xd3, 0x5c, 0xa8,
228 0x39, 0x93, 0xdc, 0x1c, 0xb9, 0xab, 0x3c, 0x80, 0x62, 0xb3, 0x76, 0x21,
229 0xdf, 0x47, 0x1e, 0xa9, 0x0e, 0x5e, 0x8a, 0xbe, 0x66, 0x5b, 0x7c, 0x21,
230 0xfa, 0x78, 0x2d, 0xd1, 0x1d, 0x5c, 0x35, 0x8a, 0x34, 0xb2, 0x1a, 0xc2,
231 0xc4, 0x4b, 0x53, 0x54,
[email protected]8bbfaeb72013-08-09 06:38:26232 };
[email protected]d5c9e4ba2013-09-14 05:25:58233 static const unsigned char signature_data_1[] = {
rjshaded5ced072015-12-18 19:26:02234 0x01, 0x7b, 0x52, 0x35, 0xe3, 0x51, 0xdd, 0xf1, 0x67, 0x8d, 0x31, 0x5e,
235 0xa3, 0x75, 0x1f, 0x68, 0x6c, 0xdd, 0x41, 0x7a, 0x18, 0x25, 0xe0, 0x12,
236 0x6e, 0x84, 0x46, 0x5e, 0xb2, 0x98, 0xd7, 0x84, 0xe1, 0x62, 0xe0, 0xc1,
237 0xc4, 0xd7, 0x4f, 0x4f, 0x80, 0xc1, 0x92, 0xd6, 0x02, 0xaf, 0xca, 0x28,
238 0x9f, 0xe0, 0xf3, 0x74, 0xd7, 0xf1, 0x44, 0x67, 0x59, 0x27, 0xc8, 0xc2,
239 0x8b, 0xd4, 0xe5, 0x4a, 0x07, 0xfd, 0x00, 0xd6, 0x8a, 0xbf, 0x8b, 0xcd,
240 0x6a, 0xe0, 0x1d, 0xf6, 0x4b, 0x68, 0x0f, 0xcf, 0xb9, 0xd0, 0xa1, 0xbc,
241 0x2e, 0xcf, 0x7c, 0x03, 0x47, 0x11, 0xe4, 0x4c, 0xbc, 0x1b, 0x6b, 0xa5,
242 0x2a, 0x82, 0x86, 0xa4, 0x7f, 0x1d, 0x85, 0x64, 0x21, 0x10, 0xd2, 0xb2,
243 0xa0, 0x31, 0xa2, 0x78, 0xe6, 0xf2, 0xea, 0x96, 0x38, 0x8c, 0x9a, 0xe1,
244 0x01, 0xab, 0x8e, 0x95, 0x66, 0xc8, 0xe5, 0xcc, 0x80, 0xa3, 0xbd, 0x16,
245 0xa7, 0x79, 0x19, 0x39, 0x61, 0x3d, 0xff, 0x37, 0xca, 0x9f, 0x97, 0x05,
246 0xc7, 0xcb, 0xf0, 0xea, 0xaf, 0x64, 0x07, 0xc0, 0xed, 0x2a, 0x98, 0xa4,
247 0xaf, 0x04, 0x6f, 0xf2, 0xc9, 0xb2, 0x73, 0x9a, 0x56, 0x85, 0x43, 0x64,
248 0x5f, 0xaa, 0xb7, 0xff, 0x31, 0x4c, 0x2e, 0x6c, 0x17, 0xcf, 0xe5, 0xbe,
249 0x7f, 0x7e, 0xad, 0xf5, 0x6f, 0x84, 0x50, 0x20, 0x29, 0xb3, 0x57, 0xe7,
250 0xb1, 0xdc, 0x2c, 0x95, 0x48, 0xfe, 0xb0, 0xc1, 0x92, 0xda, 0xc5, 0x58,
251 0x95, 0xb0, 0x1a, 0x3a, 0x05, 0x71, 0x3c, 0x6d, 0x20, 0x01, 0x4c, 0xa9,
252 0xe4, 0x38, 0x08, 0x65, 0xb4, 0xbd, 0x86, 0x76, 0xbd, 0xad, 0x25, 0x06,
253 0x74, 0x0b, 0xca, 0x95, 0x27, 0x0c, 0x13, 0x08, 0x7e, 0x30, 0xcf, 0xf6,
254 0xb5, 0xc1, 0x2a, 0x08, 0xfc, 0x4b, 0xc6, 0xb5, 0x2f, 0x23, 0x27, 0x32,
255 0x89, 0xdb, 0x0e, 0x4a,
[email protected]8bbfaeb72013-08-09 06:38:26256 };
[email protected]d5c9e4ba2013-09-14 05:25:58257 static const unsigned char signature_data_2[] = {
rjshaded5ced072015-12-18 19:26:02258 0x6d, 0x7d, 0x22, 0x8c, 0x85, 0xc4, 0x8a, 0x80, 0x05, 0xe4, 0x3c, 0xaf,
259 0x10, 0x3b, 0xe3, 0x51, 0xb1, 0x86, 0x52, 0x63, 0xb6, 0x17, 0x33, 0xbd,
260 0x1b, 0x1e, 0xc4, 0x50, 0x10, 0xfc, 0xcc, 0xea, 0x6b, 0x11, 0xeb, 0x6d,
261 0x5e, 0x00, 0xe7, 0xf3, 0x67, 0x99, 0x74, 0x53, 0x12, 0x8f, 0xe4, 0x3e,
262 0x20, 0x17, 0x8e, 0x83, 0xe6, 0xdc, 0x83, 0x91, 0x0e, 0xf3, 0x69, 0x22,
263 0x95, 0x14, 0xdf, 0xc1, 0xda, 0xb5, 0xdb, 0x6a, 0x1a, 0xb4, 0x4f, 0x26,
264 0xd0, 0x32, 0x1d, 0x73, 0x95, 0x1f, 0x39, 0x1d, 0x00, 0xcb, 0xc3, 0x92,
265 0x49, 0x53, 0xcb, 0x5c, 0x36, 0x70, 0x19, 0xd9, 0x64, 0x36, 0xda, 0xfb,
266 0x20, 0xe5, 0x47, 0xd9, 0x08, 0xc6, 0x5a, 0x9e, 0x87, 0x1a, 0xdb, 0x11,
267 0x7b, 0x17, 0xfc, 0x53, 0x7b, 0xc1, 0xa0, 0xc0, 0x33, 0xcf, 0x96, 0xba,
268 0x03, 0x79, 0x8e, 0xc6, 0x05, 0xd2, 0xb7, 0xa2, 0xe2, 0xc1, 0x67, 0xb7,
269 0x6a, 0xeb, 0xb1, 0x40, 0xbb, 0x7d, 0x57, 0xcb, 0xc2, 0x60, 0x9f, 0xf1,
270 0x72, 0xe5, 0xad, 0xce, 0x95, 0x45, 0x7c, 0xbc, 0x75, 0x81, 0x45, 0x19,
271 0xe1, 0xa7, 0x2f, 0x05, 0x52, 0xeb, 0xed, 0xdd, 0x19, 0xd9, 0x1a, 0xc9,
272 0x5a, 0x06, 0x8e, 0x29, 0x54, 0xb5, 0x4f, 0x80, 0xaa, 0x36, 0x36, 0xc0,
273 0xff, 0x64, 0xac, 0xe8, 0x0f, 0x99, 0x35, 0x5e, 0xc6, 0x72, 0x1f, 0x8c,
274 0xc4, 0x2b, 0x7d, 0xc1, 0xfb, 0xf0, 0x12, 0x61, 0xb1, 0x18, 0x65, 0xdd,
275 0xc2, 0x38, 0x92, 0xba, 0x84, 0xf8, 0xc8, 0x5e, 0x17, 0x63, 0xe0, 0x9c,
276 0x2c, 0xe6, 0x70, 0x71, 0xdc, 0xe5, 0xc1, 0xea, 0xb3, 0x9a, 0xb6, 0x91,
277 0xdc, 0xc5, 0x56, 0x84, 0x8a, 0x31, 0x31, 0x23, 0x61, 0x94, 0x7e, 0x01,
278 0x22, 0x49, 0xf3, 0xcb, 0x0e, 0x31, 0x03, 0x04, 0x1b, 0x14, 0x43, 0x7c,
279 0xad, 0x42, 0xe5, 0x55,
[email protected]8bbfaeb72013-08-09 06:38:26280 };
[email protected]2662ed562013-07-03 10:27:46281
danakjad1777e2016-04-16 00:56:42282 std::unique_ptr<ProofVerifier> verifier(
rtennetiac06c2f2015-11-05 18:12:35283 CryptoTestUtils::RealProofVerifierForTesting());
[email protected]2662ed562013-07-03 10:27:46284
285 const string server_config = "server config bytes";
286 const string hostname = "test.example.com";
elawrence954bb5472016-04-04 22:03:11287 const uint16_t port = 8443;
rch28f6469d2016-03-13 21:13:08288 const string chlo_hash = "proof nonce bytes";
289 const QuicVersion quic_version = GetParam();
[email protected]2662ed562013-07-03 10:27:46290
291 vector<string> certs(2);
[email protected]6a731c92014-03-22 00:43:24292 certs[0] = LoadTestCert("test.example.com.crt");
293 certs[1] = LoadTestCert("intermediate.crt");
[email protected]2662ed562013-07-03 10:27:46294
295 // Signatures are nondeterministic, so we test multiple signatures on the
296 // same server_config.
297 vector<string> signatures(3);
[email protected]d5c9e4ba2013-09-14 05:25:58298 signatures[0].assign(reinterpret_cast<const char*>(signature_data_0),
299 sizeof(signature_data_0));
300 signatures[1].assign(reinterpret_cast<const char*>(signature_data_1),
301 sizeof(signature_data_1));
302 signatures[2].assign(reinterpret_cast<const char*>(signature_data_2),
303 sizeof(signature_data_2));
[email protected]2662ed562013-07-03 10:27:46304
305 for (size_t i = 0; i < signatures.size(); i++) {
306 const string& signature = signatures[i];
[email protected]2662ed562013-07-03 10:27:46307
elawrence954bb5472016-04-04 22:03:11308 RunVerification(verifier.get(), hostname, port, server_config, quic_version,
rch28f6469d2016-03-13 21:13:08309 chlo_hash, certs, signature, true);
elawrence954bb5472016-04-04 22:03:11310 RunVerification(verifier.get(), "foo.com", port, server_config,
311 quic_version, chlo_hash, certs, signature, false);
312 RunVerification(verifier.get(), hostname, port,
rch28f6469d2016-03-13 21:13:08313 server_config.substr(1, string::npos), quic_version,
314 chlo_hash, certs, signature, false);
[email protected]2662ed562013-07-03 10:27:46315
316 const string corrupt_signature = "1" + signature;
elawrence954bb5472016-04-04 22:03:11317 RunVerification(verifier.get(), hostname, port, server_config, quic_version,
rch28f6469d2016-03-13 21:13:08318 chlo_hash, certs, corrupt_signature, false);
[email protected]2662ed562013-07-03 10:27:46319
320 vector<string> wrong_certs;
321 for (size_t i = 1; i < certs.size(); i++) {
322 wrong_certs.push_back(certs[i]);
323 }
elawrence954bb5472016-04-04 22:03:11324 RunVerification(verifier.get(), hostname, port, server_config, quic_version,
rch28f6469d2016-03-13 21:13:08325 chlo_hash, wrong_certs, signature, false);
[email protected]2662ed562013-07-03 10:27:46326 }
327}
328
329// A known answer test that allows us to test ProofVerifier without a working
330// ProofSource.
rch28f6469d2016-03-13 21:13:08331TEST_P(ProofTest, VerifyECDSAKnownAnswerTest) {
332 if (GetParam() > QUIC_VERSION_30) {
333 return;
334 }
335// These sample signatures were generated by running the Proof.Verify test
336// (modified to use ECDSA for signing proofs) and dumping the bytes of the
337// |signature| output of ProofSource::GetProof().
338
rjshaded5ced072015-12-18 19:26:02339// Disable this test on platforms that do not support ECDSA certificates.
[email protected]2662ed562013-07-03 10:27:46340#if defined(OS_WIN)
[email protected]5bfce8a2013-07-31 08:21:55341 if (base::win::GetVersion() < base::win::VERSION_VISTA)
342 return;
[email protected]2662ed562013-07-03 10:27:46343#endif
[email protected]5bfce8a2013-07-31 08:21:55344
[email protected]2662ed562013-07-03 10:27:46345 // These sample signatures were generated by running the Proof.Verify test
346 // (modified to use ECDSA for signing proofs) and dumping the bytes of the
347 // |signature| output of ProofSource::GetProof().
348 static const unsigned char signature_data_0[] = {
rjshaded5ced072015-12-18 19:26:02349 0x30, 0x45, 0x02, 0x21, 0x00, 0x89, 0xc4, 0x7d, 0x08, 0xd1, 0x49, 0x19,
350 0x6c, 0xd1, 0x7c, 0xb9, 0x25, 0xe0, 0xe3, 0xbd, 0x6a, 0x5c, 0xd7, 0xaa,
351 0x0c, 0xdc, 0x4f, 0x8e, 0xeb, 0xde, 0xbf, 0x32, 0xf8, 0xd1, 0x84, 0x95,
352 0x97, 0x02, 0x20, 0x29, 0x3d, 0x49, 0x22, 0x73, 0xed, 0x8b, 0xde, 0x3d,
353 0xc2, 0xa4, 0x20, 0xcc, 0xe7, 0xc8, 0x2a, 0x85, 0x20, 0x9b, 0x5b, 0xda,
354 0xcd, 0x58, 0x23, 0xbe, 0x89, 0x73, 0x31, 0x87, 0x51, 0xd1, 0x01,
[email protected]2662ed562013-07-03 10:27:46355 };
356 static const unsigned char signature_data_1[] = {
rjshaded5ced072015-12-18 19:26:02357 0x30, 0x46, 0x02, 0x21, 0x00, 0xec, 0xdf, 0x69, 0xc8, 0x24, 0x59, 0x93,
358 0xda, 0x49, 0xee, 0x37, 0x28, 0xaf, 0xeb, 0x0e, 0x2f, 0x80, 0x17, 0x4b,
359 0x3b, 0xf6, 0x54, 0xcd, 0x3b, 0x86, 0xc5, 0x98, 0x0d, 0xff, 0xc6, 0xb1,
360 0xe7, 0x02, 0x21, 0x00, 0xe1, 0x36, 0x8c, 0xc0, 0xf4, 0x50, 0x5f, 0xba,
361 0xfb, 0xe2, 0xff, 0x1d, 0x5d, 0x64, 0xe4, 0x07, 0xbb, 0x5a, 0x4b, 0x19,
362 0xb6, 0x39, 0x7a, 0xc4, 0x12, 0xc6, 0xe5, 0x42, 0xc8, 0x78, 0x33, 0xcd,
[email protected]2662ed562013-07-03 10:27:46363 };
364 static const unsigned char signature_data_2[] = {
rjshaded5ced072015-12-18 19:26:02365 0x30, 0x45, 0x02, 0x20, 0x09, 0x51, 0xe9, 0xde, 0xdb, 0x01, 0xfd, 0xb4,
366 0xd8, 0x20, 0xbb, 0xad, 0x41, 0xe3, 0xaa, 0xe7, 0xa3, 0xc3, 0x32, 0x10,
367 0x9d, 0xfa, 0x37, 0xce, 0x17, 0xd1, 0x29, 0xf9, 0xd4, 0x1d, 0x0d, 0x19,
368 0x02, 0x21, 0x00, 0xc6, 0x20, 0xd4, 0x28, 0xf9, 0x70, 0xb5, 0xb4, 0xff,
369 0x4a, 0x35, 0xba, 0xa0, 0xf2, 0x8e, 0x00, 0xf7, 0xcb, 0x43, 0xaf, 0x2d,
370 0x1f, 0xce, 0x92, 0x05, 0xca, 0x29, 0xfe, 0xd2, 0x8f, 0xd9, 0x31,
[email protected]2662ed562013-07-03 10:27:46371 };
372
danakjad1777e2016-04-16 00:56:42373 std::unique_ptr<ProofVerifier> verifier(
rtennetiac06c2f2015-11-05 18:12:35374 CryptoTestUtils::RealProofVerifierForTesting());
[email protected]2662ed562013-07-03 10:27:46375
376 const string server_config = "server config bytes";
377 const string hostname = "test.example.com";
elawrence954bb5472016-04-04 22:03:11378 const uint16_t port = 8443;
rch28f6469d2016-03-13 21:13:08379 const string chlo_hash = "chlo_hash nonce bytes";
380 const QuicVersion quic_version = GetParam();
[email protected]2662ed562013-07-03 10:27:46381
382 vector<string> certs(2);
[email protected]6a731c92014-03-22 00:43:24383 certs[0] = LoadTestCert("test_ecc.example.com.crt");
384 certs[1] = LoadTestCert("intermediate.crt");
[email protected]2662ed562013-07-03 10:27:46385
386 // Signatures are nondeterministic, so we test multiple signatures on the
387 // same server_config.
388 vector<string> signatures(3);
389 signatures[0].assign(reinterpret_cast<const char*>(signature_data_0),
390 sizeof(signature_data_0));
391 signatures[1].assign(reinterpret_cast<const char*>(signature_data_1),
392 sizeof(signature_data_1));
393 signatures[2].assign(reinterpret_cast<const char*>(signature_data_2),
394 sizeof(signature_data_2));
395
396 for (size_t i = 0; i < signatures.size(); i++) {
[email protected]2662ed562013-07-03 10:27:46397 const string& signature = signatures[i];
[email protected]2662ed562013-07-03 10:27:46398
elawrence954bb5472016-04-04 22:03:11399 RunVerification(verifier.get(), hostname, port, server_config, quic_version,
rch28f6469d2016-03-13 21:13:08400 chlo_hash, certs, signature, true);
elawrence954bb5472016-04-04 22:03:11401 RunVerification(verifier.get(), "foo.com", port, server_config,
402 quic_version, chlo_hash, certs, signature, false);
elawrence954bb5472016-04-04 22:03:11403 RunVerification(verifier.get(), hostname, port,
rch28f6469d2016-03-13 21:13:08404 server_config.substr(1, string::npos), quic_version,
405 chlo_hash, certs, signature, false);
[email protected]2662ed562013-07-03 10:27:46406
407 // An ECDSA signature is DER-encoded. Corrupt the last byte so that the
408 // signature can still be DER-decoded correctly.
409 string corrupt_signature = signature;
410 corrupt_signature[corrupt_signature.size() - 1] += 1;
elawrence954bb5472016-04-04 22:03:11411 RunVerification(verifier.get(), hostname, port, server_config, quic_version,
rch28f6469d2016-03-13 21:13:08412 chlo_hash, certs, corrupt_signature, false);
[email protected]2662ed562013-07-03 10:27:46413
414 // Prepending a "1" makes the DER invalid.
415 const string bad_der_signature1 = "1" + signature;
elawrence954bb5472016-04-04 22:03:11416 RunVerification(verifier.get(), hostname, port, server_config, quic_version,
rch28f6469d2016-03-13 21:13:08417 chlo_hash, certs, bad_der_signature1, false);
[email protected]2662ed562013-07-03 10:27:46418
419 vector<string> wrong_certs;
420 for (size_t i = 1; i < certs.size(); i++) {
421 wrong_certs.push_back(certs[i]);
422 }
elawrence954bb5472016-04-04 22:03:11423 RunVerification(verifier.get(), hostname, port, server_config, quic_version,
rch28f6469d2016-03-13 21:13:08424 chlo_hash, wrong_certs, signature, false);
[email protected]2662ed562013-07-03 10:27:46425 }
426}
427
[email protected]c244c5a12013-05-07 20:55:04428} // namespace test
429} // namespace net