1 // 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.
5 #include "base/files/file_path.h"
6 #include "net/base/ip_endpoint.h"
7 #include "net/base/net_errors.h"
8 #include "net/base/test_completion_callback.h"
9 #include "net/base/test_data_directory.h"
10 #include "net/cert/cert_status_flags.h"
11 #include "net/cert/cert_verify_result.h"
12 #include "net/cert/x509_certificate.h"
13 #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"
16 #include "net/test/cert_test_util.h"
17 #include "testing/gtest/include/gtest/gtest.h"
20 #include "base/win/windows_version.h"
30 // 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.
33 class TestProofVerifierCallback
: public ProofVerifierCallback
{
35 TestProofVerifierCallback(TestCompletionCallback
* comp_callback
,
37 string
* error_details
)
38 : comp_callback_(comp_callback
),
40 error_details_(error_details
) {}
43 const string
& error_details
,
44 scoped_ptr
<ProofVerifyDetails
>* details
) override
{
46 *error_details_
= error_details
;
48 comp_callback_
->callback().Run(0);
52 TestCompletionCallback
* const comp_callback_
;
54 string
* const error_details_
;
57 // RunVerification runs |verifier->VerifyProof| and asserts that the result
58 // matches |expected_ok|.
59 void RunVerification(ProofVerifier
* verifier
,
60 const string
& hostname
,
61 const string
& server_config
,
62 const vector
<string
>& certs
,
65 scoped_ptr
<ProofVerifyDetails
> details
;
66 TestCompletionCallback comp_callback
;
69 scoped_ptr
<ProofVerifyContext
> verify_context(
70 CryptoTestUtils::ProofVerifyContextForTesting());
71 TestProofVerifierCallback
* callback
=
72 new TestProofVerifierCallback(&comp_callback
, &ok
, &error_details
);
74 QuicAsyncStatus status
= verifier
->VerifyProof(
75 hostname
, server_config
, certs
, proof
, verify_context
.get(),
76 &error_details
, &details
, callback
);
81 ASSERT_FALSE(expected_ok
);
82 ASSERT_NE("", error_details
);
86 ASSERT_TRUE(expected_ok
);
87 ASSERT_EQ("", error_details
);
90 comp_callback
.WaitForResult();
91 ASSERT_EQ(expected_ok
, ok
);
96 // Reads the certificate named "quic_" + |file_name| in the test data directory.
97 // The certificate must be PEM encoded. Returns the DER-encoded certificate.
98 string
LoadTestCert(const string
& file_name
) {
99 base::FilePath certs_dir
= GetTestCertsDirectory();
100 scoped_refptr
<X509Certificate
> cert
=
101 ImportCertFromFile(certs_dir
, "quic_" + file_name
);
102 CHECK_NE(static_cast<X509Certificate
*>(nullptr), cert
.get());
105 CHECK(X509Certificate::GetDEREncoded(cert
->os_cert_handle(), &der_bytes
));
111 // TODO(rtenneti): Enable testing of ProofVerifier.
112 TEST(ProofTest
, DISABLED_Verify
) {
113 scoped_ptr
<ProofSource
> source(CryptoTestUtils::ProofSourceForTesting());
114 scoped_ptr
<ProofVerifier
> verifier(
115 CryptoTestUtils::ProofVerifierForTesting());
117 const string server_config
= "server config bytes";
118 const string hostname
= "test.example.com";
119 const vector
<string
>* certs
;
120 const vector
<string
>* first_certs
;
121 string error_details
, signature
, first_signature
;
122 IPAddressNumber server_ip
;
124 ASSERT_TRUE(source
->GetProof(server_ip
, hostname
, server_config
,
125 false /* no ECDSA */, &first_certs
,
127 ASSERT_TRUE(source
->GetProof(server_ip
, hostname
, server_config
,
128 false /* no ECDSA */, &certs
, &signature
));
130 // Check that the proof source is caching correctly:
131 ASSERT_EQ(first_certs
, certs
);
132 ASSERT_EQ(signature
, first_signature
);
135 verifier
.get(), hostname
, server_config
, *certs
, signature
, true);
138 verifier
.get(), "foo.com", server_config
, *certs
, signature
, false);
141 verifier
.get(), server_config
.substr(1, string::npos
), server_config
,
142 *certs
, signature
, false);
144 const string corrupt_signature
= "1" + signature
;
146 verifier
.get(), hostname
, server_config
, *certs
, corrupt_signature
,
149 vector
<string
> wrong_certs
;
150 for (size_t i
= 1; i
< certs
->size(); i
++) {
151 wrong_certs
.push_back((*certs
)[i
]);
154 verifier
.get(), "foo.com", server_config
, wrong_certs
, corrupt_signature
,
158 // A known answer test that allows us to test ProofVerifier without a working
160 TEST(ProofTest
, VerifyRSAKnownAnswerTest
) {
161 // These sample signatures were generated by running the Proof.Verify test
162 // and dumping the bytes of the |signature| output of ProofSource::GetProof().
163 static const unsigned char signature_data_0
[] = {
164 0x31, 0xd5, 0xfb, 0x40, 0x30, 0x75, 0xd2, 0x7d, 0x61, 0xf9, 0xd7, 0x54,
165 0x30, 0x06, 0xaf, 0x54, 0x0d, 0xb0, 0x0a, 0xda, 0x63, 0xca, 0x7e, 0x9e,
166 0xce, 0xba, 0x10, 0x05, 0x1b, 0xa6, 0x7f, 0xef, 0x2b, 0xa3, 0xff, 0x3c,
167 0xbb, 0x9a, 0xe4, 0xbf, 0xb8, 0x0c, 0xc1, 0xbd, 0xed, 0xc2, 0x90, 0x68,
168 0xeb, 0x45, 0x48, 0xea, 0x3c, 0x95, 0xf8, 0xa2, 0xb9, 0xe7, 0x62, 0x29,
169 0x00, 0xc3, 0x18, 0xb4, 0x16, 0x6f, 0x5e, 0xb0, 0xc1, 0x26, 0xc0, 0x4b,
170 0x84, 0xf5, 0x97, 0xfc, 0x17, 0xf9, 0x1c, 0x43, 0xb8, 0xf2, 0x3f, 0x38,
171 0x32, 0xad, 0x36, 0x52, 0x2c, 0x26, 0x92, 0x7a, 0xea, 0x2c, 0xa2, 0xf4,
172 0x28, 0x2f, 0x19, 0x4d, 0x1f, 0x11, 0x46, 0x82, 0xd0, 0xc4, 0x86, 0x56,
173 0x5c, 0x97, 0x9e, 0xc6, 0x37, 0x8e, 0xaf, 0x9d, 0x69, 0xe9, 0x4f, 0x5a,
174 0x6d, 0x70, 0x75, 0xc7, 0x41, 0x95, 0x68, 0x53, 0x94, 0xca, 0x31, 0x63,
175 0x61, 0x9f, 0xb8, 0x8c, 0x3b, 0x75, 0x36, 0x8b, 0x69, 0xa2, 0x35, 0xc0,
176 0x4b, 0x77, 0x55, 0x08, 0xc2, 0xb4, 0x56, 0xd2, 0x81, 0xce, 0x9e, 0x25,
177 0xdb, 0x50, 0x74, 0xb3, 0x8a, 0xd9, 0x20, 0x42, 0x3f, 0x85, 0x2d, 0xaa,
178 0xfd, 0x66, 0xfa, 0xd6, 0x95, 0x55, 0x6b, 0x63, 0x63, 0x04, 0xf8, 0x6c,
179 0x3e, 0x08, 0x22, 0x39, 0xb9, 0x9a, 0xe0, 0xd7, 0x01, 0xff, 0xeb, 0x8a,
180 0xb9, 0xe2, 0x34, 0xa5, 0xa0, 0x51, 0xe9, 0xbe, 0x15, 0x12, 0xbf, 0xbe,
181 0x64, 0x3d, 0x3f, 0x98, 0xce, 0xc1, 0xa6, 0x33, 0x32, 0xd3, 0x5c, 0xa8,
182 0x39, 0x93, 0xdc, 0x1c, 0xb9, 0xab, 0x3c, 0x80, 0x62, 0xb3, 0x76, 0x21,
183 0xdf, 0x47, 0x1e, 0xa9, 0x0e, 0x5e, 0x8a, 0xbe, 0x66, 0x5b, 0x7c, 0x21,
184 0xfa, 0x78, 0x2d, 0xd1, 0x1d, 0x5c, 0x35, 0x8a, 0x34, 0xb2, 0x1a, 0xc2,
185 0xc4, 0x4b, 0x53, 0x54,
187 static const unsigned char signature_data_1
[] = {
188 0x01, 0x7b, 0x52, 0x35, 0xe3, 0x51, 0xdd, 0xf1, 0x67, 0x8d, 0x31, 0x5e,
189 0xa3, 0x75, 0x1f, 0x68, 0x6c, 0xdd, 0x41, 0x7a, 0x18, 0x25, 0xe0, 0x12,
190 0x6e, 0x84, 0x46, 0x5e, 0xb2, 0x98, 0xd7, 0x84, 0xe1, 0x62, 0xe0, 0xc1,
191 0xc4, 0xd7, 0x4f, 0x4f, 0x80, 0xc1, 0x92, 0xd6, 0x02, 0xaf, 0xca, 0x28,
192 0x9f, 0xe0, 0xf3, 0x74, 0xd7, 0xf1, 0x44, 0x67, 0x59, 0x27, 0xc8, 0xc2,
193 0x8b, 0xd4, 0xe5, 0x4a, 0x07, 0xfd, 0x00, 0xd6, 0x8a, 0xbf, 0x8b, 0xcd,
194 0x6a, 0xe0, 0x1d, 0xf6, 0x4b, 0x68, 0x0f, 0xcf, 0xb9, 0xd0, 0xa1, 0xbc,
195 0x2e, 0xcf, 0x7c, 0x03, 0x47, 0x11, 0xe4, 0x4c, 0xbc, 0x1b, 0x6b, 0xa5,
196 0x2a, 0x82, 0x86, 0xa4, 0x7f, 0x1d, 0x85, 0x64, 0x21, 0x10, 0xd2, 0xb2,
197 0xa0, 0x31, 0xa2, 0x78, 0xe6, 0xf2, 0xea, 0x96, 0x38, 0x8c, 0x9a, 0xe1,
198 0x01, 0xab, 0x8e, 0x95, 0x66, 0xc8, 0xe5, 0xcc, 0x80, 0xa3, 0xbd, 0x16,
199 0xa7, 0x79, 0x19, 0x39, 0x61, 0x3d, 0xff, 0x37, 0xca, 0x9f, 0x97, 0x05,
200 0xc7, 0xcb, 0xf0, 0xea, 0xaf, 0x64, 0x07, 0xc0, 0xed, 0x2a, 0x98, 0xa4,
201 0xaf, 0x04, 0x6f, 0xf2, 0xc9, 0xb2, 0x73, 0x9a, 0x56, 0x85, 0x43, 0x64,
202 0x5f, 0xaa, 0xb7, 0xff, 0x31, 0x4c, 0x2e, 0x6c, 0x17, 0xcf, 0xe5, 0xbe,
203 0x7f, 0x7e, 0xad, 0xf5, 0x6f, 0x84, 0x50, 0x20, 0x29, 0xb3, 0x57, 0xe7,
204 0xb1, 0xdc, 0x2c, 0x95, 0x48, 0xfe, 0xb0, 0xc1, 0x92, 0xda, 0xc5, 0x58,
205 0x95, 0xb0, 0x1a, 0x3a, 0x05, 0x71, 0x3c, 0x6d, 0x20, 0x01, 0x4c, 0xa9,
206 0xe4, 0x38, 0x08, 0x65, 0xb4, 0xbd, 0x86, 0x76, 0xbd, 0xad, 0x25, 0x06,
207 0x74, 0x0b, 0xca, 0x95, 0x27, 0x0c, 0x13, 0x08, 0x7e, 0x30, 0xcf, 0xf6,
208 0xb5, 0xc1, 0x2a, 0x08, 0xfc, 0x4b, 0xc6, 0xb5, 0x2f, 0x23, 0x27, 0x32,
209 0x89, 0xdb, 0x0e, 0x4a,
211 static const unsigned char signature_data_2
[] = {
212 0x6d, 0x7d, 0x22, 0x8c, 0x85, 0xc4, 0x8a, 0x80, 0x05, 0xe4, 0x3c, 0xaf,
213 0x10, 0x3b, 0xe3, 0x51, 0xb1, 0x86, 0x52, 0x63, 0xb6, 0x17, 0x33, 0xbd,
214 0x1b, 0x1e, 0xc4, 0x50, 0x10, 0xfc, 0xcc, 0xea, 0x6b, 0x11, 0xeb, 0x6d,
215 0x5e, 0x00, 0xe7, 0xf3, 0x67, 0x99, 0x74, 0x53, 0x12, 0x8f, 0xe4, 0x3e,
216 0x20, 0x17, 0x8e, 0x83, 0xe6, 0xdc, 0x83, 0x91, 0x0e, 0xf3, 0x69, 0x22,
217 0x95, 0x14, 0xdf, 0xc1, 0xda, 0xb5, 0xdb, 0x6a, 0x1a, 0xb4, 0x4f, 0x26,
218 0xd0, 0x32, 0x1d, 0x73, 0x95, 0x1f, 0x39, 0x1d, 0x00, 0xcb, 0xc3, 0x92,
219 0x49, 0x53, 0xcb, 0x5c, 0x36, 0x70, 0x19, 0xd9, 0x64, 0x36, 0xda, 0xfb,
220 0x20, 0xe5, 0x47, 0xd9, 0x08, 0xc6, 0x5a, 0x9e, 0x87, 0x1a, 0xdb, 0x11,
221 0x7b, 0x17, 0xfc, 0x53, 0x7b, 0xc1, 0xa0, 0xc0, 0x33, 0xcf, 0x96, 0xba,
222 0x03, 0x79, 0x8e, 0xc6, 0x05, 0xd2, 0xb7, 0xa2, 0xe2, 0xc1, 0x67, 0xb7,
223 0x6a, 0xeb, 0xb1, 0x40, 0xbb, 0x7d, 0x57, 0xcb, 0xc2, 0x60, 0x9f, 0xf1,
224 0x72, 0xe5, 0xad, 0xce, 0x95, 0x45, 0x7c, 0xbc, 0x75, 0x81, 0x45, 0x19,
225 0xe1, 0xa7, 0x2f, 0x05, 0x52, 0xeb, 0xed, 0xdd, 0x19, 0xd9, 0x1a, 0xc9,
226 0x5a, 0x06, 0x8e, 0x29, 0x54, 0xb5, 0x4f, 0x80, 0xaa, 0x36, 0x36, 0xc0,
227 0xff, 0x64, 0xac, 0xe8, 0x0f, 0x99, 0x35, 0x5e, 0xc6, 0x72, 0x1f, 0x8c,
228 0xc4, 0x2b, 0x7d, 0xc1, 0xfb, 0xf0, 0x12, 0x61, 0xb1, 0x18, 0x65, 0xdd,
229 0xc2, 0x38, 0x92, 0xba, 0x84, 0xf8, 0xc8, 0x5e, 0x17, 0x63, 0xe0, 0x9c,
230 0x2c, 0xe6, 0x70, 0x71, 0xdc, 0xe5, 0xc1, 0xea, 0xb3, 0x9a, 0xb6, 0x91,
231 0xdc, 0xc5, 0x56, 0x84, 0x8a, 0x31, 0x31, 0x23, 0x61, 0x94, 0x7e, 0x01,
232 0x22, 0x49, 0xf3, 0xcb, 0x0e, 0x31, 0x03, 0x04, 0x1b, 0x14, 0x43, 0x7c,
233 0xad, 0x42, 0xe5, 0x55,
236 scoped_ptr
<ProofVerifier
> verifier(
237 CryptoTestUtils::ProofVerifierForTesting());
239 const string server_config
= "server config bytes";
240 const string hostname
= "test.example.com";
242 vector
<string
> certs(2);
243 certs
[0] = LoadTestCert("test.example.com.crt");
244 certs
[1] = LoadTestCert("intermediate.crt");
246 // Signatures are nondeterministic, so we test multiple signatures on the
247 // same server_config.
248 vector
<string
> signatures(3);
249 signatures
[0].assign(reinterpret_cast<const char*>(signature_data_0
),
250 sizeof(signature_data_0
));
251 signatures
[1].assign(reinterpret_cast<const char*>(signature_data_1
),
252 sizeof(signature_data_1
));
253 signatures
[2].assign(reinterpret_cast<const char*>(signature_data_2
),
254 sizeof(signature_data_2
));
256 for (size_t i
= 0; i
< signatures
.size(); i
++) {
257 const string
& signature
= signatures
[i
];
260 verifier
.get(), hostname
, server_config
, certs
, signature
, true);
262 verifier
.get(), "foo.com", server_config
, certs
, signature
, false);
264 verifier
.get(), hostname
, server_config
.substr(1, string::npos
),
265 certs
, signature
, false);
267 const string corrupt_signature
= "1" + signature
;
269 verifier
.get(), hostname
, server_config
, certs
, corrupt_signature
,
272 vector
<string
> wrong_certs
;
273 for (size_t i
= 1; i
< certs
.size(); i
++) {
274 wrong_certs
.push_back(certs
[i
]);
276 RunVerification(verifier
.get(), hostname
, server_config
, wrong_certs
,
281 // A known answer test that allows us to test ProofVerifier without a working
283 TEST(ProofTest
, VerifyECDSAKnownAnswerTest
) {
284 // Disable this test on platforms that do not support ECDSA certificates.
286 if (base::win::GetVersion() < base::win::VERSION_VISTA
)
290 // These sample signatures were generated by running the Proof.Verify test
291 // (modified to use ECDSA for signing proofs) and dumping the bytes of the
292 // |signature| output of ProofSource::GetProof().
293 static const unsigned char signature_data_0
[] = {
294 0x30, 0x45, 0x02, 0x21, 0x00, 0x89, 0xc4, 0x7d, 0x08, 0xd1, 0x49, 0x19,
295 0x6c, 0xd1, 0x7c, 0xb9, 0x25, 0xe0, 0xe3, 0xbd, 0x6a, 0x5c, 0xd7, 0xaa,
296 0x0c, 0xdc, 0x4f, 0x8e, 0xeb, 0xde, 0xbf, 0x32, 0xf8, 0xd1, 0x84, 0x95,
297 0x97, 0x02, 0x20, 0x29, 0x3d, 0x49, 0x22, 0x73, 0xed, 0x8b, 0xde, 0x3d,
298 0xc2, 0xa4, 0x20, 0xcc, 0xe7, 0xc8, 0x2a, 0x85, 0x20, 0x9b, 0x5b, 0xda,
299 0xcd, 0x58, 0x23, 0xbe, 0x89, 0x73, 0x31, 0x87, 0x51, 0xd1, 0x01,
301 static const unsigned char signature_data_1
[] = {
302 0x30, 0x46, 0x02, 0x21, 0x00, 0xec, 0xdf, 0x69, 0xc8, 0x24, 0x59, 0x93,
303 0xda, 0x49, 0xee, 0x37, 0x28, 0xaf, 0xeb, 0x0e, 0x2f, 0x80, 0x17, 0x4b,
304 0x3b, 0xf6, 0x54, 0xcd, 0x3b, 0x86, 0xc5, 0x98, 0x0d, 0xff, 0xc6, 0xb1,
305 0xe7, 0x02, 0x21, 0x00, 0xe1, 0x36, 0x8c, 0xc0, 0xf4, 0x50, 0x5f, 0xba,
306 0xfb, 0xe2, 0xff, 0x1d, 0x5d, 0x64, 0xe4, 0x07, 0xbb, 0x5a, 0x4b, 0x19,
307 0xb6, 0x39, 0x7a, 0xc4, 0x12, 0xc6, 0xe5, 0x42, 0xc8, 0x78, 0x33, 0xcd,
309 static const unsigned char signature_data_2
[] = {
310 0x30, 0x45, 0x02, 0x20, 0x09, 0x51, 0xe9, 0xde, 0xdb, 0x01, 0xfd, 0xb4,
311 0xd8, 0x20, 0xbb, 0xad, 0x41, 0xe3, 0xaa, 0xe7, 0xa3, 0xc3, 0x32, 0x10,
312 0x9d, 0xfa, 0x37, 0xce, 0x17, 0xd1, 0x29, 0xf9, 0xd4, 0x1d, 0x0d, 0x19,
313 0x02, 0x21, 0x00, 0xc6, 0x20, 0xd4, 0x28, 0xf9, 0x70, 0xb5, 0xb4, 0xff,
314 0x4a, 0x35, 0xba, 0xa0, 0xf2, 0x8e, 0x00, 0xf7, 0xcb, 0x43, 0xaf, 0x2d,
315 0x1f, 0xce, 0x92, 0x05, 0xca, 0x29, 0xfe, 0xd2, 0x8f, 0xd9, 0x31,
318 scoped_ptr
<ProofVerifier
> verifier(
319 CryptoTestUtils::ProofVerifierForTesting());
321 const string server_config
= "server config bytes";
322 const string hostname
= "test.example.com";
324 vector
<string
> certs(2);
325 certs
[0] = LoadTestCert("test_ecc.example.com.crt");
326 certs
[1] = LoadTestCert("intermediate.crt");
328 // Signatures are nondeterministic, so we test multiple signatures on the
329 // same server_config.
330 vector
<string
> signatures(3);
331 signatures
[0].assign(reinterpret_cast<const char*>(signature_data_0
),
332 sizeof(signature_data_0
));
333 signatures
[1].assign(reinterpret_cast<const char*>(signature_data_1
),
334 sizeof(signature_data_1
));
335 signatures
[2].assign(reinterpret_cast<const char*>(signature_data_2
),
336 sizeof(signature_data_2
));
338 for (size_t i
= 0; i
< signatures
.size(); i
++) {
339 const string
& signature
= signatures
[i
];
342 verifier
.get(), hostname
, server_config
, certs
, signature
, true);
344 verifier
.get(), "foo.com", server_config
, certs
, signature
, false);
346 verifier
.get(), hostname
, server_config
.substr(1, string::npos
),
347 certs
, signature
, false);
349 // An ECDSA signature is DER-encoded. Corrupt the last byte so that the
350 // signature can still be DER-decoded correctly.
351 string corrupt_signature
= signature
;
352 corrupt_signature
[corrupt_signature
.size() - 1] += 1;
354 verifier
.get(), hostname
, server_config
, certs
, corrupt_signature
,
357 // Prepending a "1" makes the DER invalid.
358 const string bad_der_signature1
= "1" + signature
;
360 verifier
.get(), hostname
, server_config
, certs
, bad_der_signature1
,
363 vector
<string
> wrong_certs
;
364 for (size_t i
= 1; i
< certs
.size(); i
++) {
365 wrong_certs
.push_back(certs
[i
]);
368 verifier
.get(), hostname
, server_config
, wrong_certs
, signature
,