Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 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 "base/files/file_path.h" | 5 #include "base/files/file_path.h" |
| 6 #include "net/base/ip_endpoint.h" | 6 #include "net/base/ip_endpoint.h" |
| 7 #include "net/base/net_errors.h" | 7 #include "net/base/net_errors.h" |
| 8 #include "net/base/test_completion_callback.h" | 8 #include "net/base/test_completion_callback.h" |
| 9 #include "net/base/test_data_directory.h" | 9 #include "net/base/test_data_directory.h" |
| 10 #include "net/cert/cert_status_flags.h" | 10 #include "net/cert/cert_status_flags.h" |
| 11 #include "net/cert/cert_verify_result.h" | 11 #include "net/cert/cert_verify_result.h" |
| 12 #include "net/cert/x509_certificate.h" | 12 #include "net/cert/x509_certificate.h" |
| 13 #include "net/quic/crypto/proof_source.h" | 13 #include "net/quic/crypto/proof_source.h" |
| 14 #include "net/quic/crypto/proof_verifier.h" | 14 #include "net/quic/crypto/proof_verifier.h" |
| 15 #include "net/quic/test_tools/crypto_test_utils.h" | 15 #include "net/quic/test_tools/crypto_test_utils.h" |
| 16 #include "net/test/cert_test_util.h" | 16 #include "net/test/cert_test_util.h" |
| 17 #include "net/test/ct_test_util.h" | |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
| 18 | 19 |
| 19 #if defined(OS_WIN) | 20 #if defined(OS_WIN) |
| 20 #include "base/win/windows_version.h" | 21 #include "base/win/windows_version.h" |
| 21 #endif | 22 #endif |
| 22 | 23 |
| 23 using std::string; | 24 using std::string; |
| 24 using std::vector; | 25 using std::vector; |
| 25 | 26 |
| 26 namespace net { | 27 namespace net { |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 53 bool* const ok_; | 54 bool* const ok_; |
| 54 string* const error_details_; | 55 string* const error_details_; |
| 55 }; | 56 }; |
| 56 | 57 |
| 57 // RunVerification runs |verifier->VerifyProof| and asserts that the result | 58 // RunVerification runs |verifier->VerifyProof| and asserts that the result |
| 58 // matches |expected_ok|. | 59 // matches |expected_ok|. |
| 59 void RunVerification(ProofVerifier* verifier, | 60 void RunVerification(ProofVerifier* verifier, |
| 60 const string& hostname, | 61 const string& hostname, |
| 61 const string& server_config, | 62 const string& server_config, |
| 62 const vector<string>& certs, | 63 const vector<string>& certs, |
| 64 const string& cert_sct, | |
| 63 const string& proof, | 65 const string& proof, |
| 64 bool expected_ok) { | 66 bool expected_ok) { |
| 65 scoped_ptr<ProofVerifyDetails> details; | 67 scoped_ptr<ProofVerifyDetails> details; |
| 66 TestCompletionCallback comp_callback; | 68 TestCompletionCallback comp_callback; |
| 67 bool ok; | 69 bool ok; |
| 68 string error_details; | 70 string error_details; |
| 69 scoped_ptr<ProofVerifyContext> verify_context( | 71 scoped_ptr<ProofVerifyContext> verify_context( |
| 70 CryptoTestUtils::ProofVerifyContextForTesting()); | 72 CryptoTestUtils::ProofVerifyContextForTesting()); |
| 71 TestProofVerifierCallback* callback = | 73 TestProofVerifierCallback* callback = |
| 72 new TestProofVerifierCallback(&comp_callback, &ok, &error_details); | 74 new TestProofVerifierCallback(&comp_callback, &ok, &error_details); |
| 73 | 75 |
| 74 QuicAsyncStatus status = verifier->VerifyProof( | 76 QuicAsyncStatus status = verifier->VerifyProof( |
| 75 hostname, server_config, certs, "", proof, verify_context.get(), | 77 hostname, server_config, certs, cert_sct, proof, verify_context.get(), |
| 76 &error_details, &details, callback); | 78 &error_details, &details, callback); |
| 77 | 79 |
| 78 switch (status) { | 80 switch (status) { |
| 79 case QUIC_FAILURE: | 81 case QUIC_FAILURE: |
| 80 delete callback; | 82 delete callback; |
| 81 ASSERT_FALSE(expected_ok); | 83 ASSERT_FALSE(expected_ok); |
| 82 ASSERT_NE("", error_details); | 84 ASSERT_NE("", error_details); |
| 83 return; | 85 return; |
| 84 case QUIC_SUCCESS: | 86 case QUIC_SUCCESS: |
| 85 delete callback; | 87 delete callback; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 126 &first_signature, &first_cert_sct)); | 128 &first_signature, &first_cert_sct)); |
| 127 ASSERT_TRUE(source->GetProof(server_ip, hostname, server_config, | 129 ASSERT_TRUE(source->GetProof(server_ip, hostname, server_config, |
| 128 false /* no ECDSA */, &certs, &signature, | 130 false /* no ECDSA */, &certs, &signature, |
| 129 &cert_sct)); | 131 &cert_sct)); |
| 130 | 132 |
| 131 // Check that the proof source is caching correctly: | 133 // Check that the proof source is caching correctly: |
| 132 ASSERT_EQ(first_certs, certs); | 134 ASSERT_EQ(first_certs, certs); |
| 133 ASSERT_EQ(signature, first_signature); | 135 ASSERT_EQ(signature, first_signature); |
| 134 ASSERT_EQ(first_cert_sct, cert_sct); | 136 ASSERT_EQ(first_cert_sct, cert_sct); |
| 135 | 137 |
| 136 RunVerification( | 138 RunVerification(verifier.get(), hostname, server_config, *certs, cert_sct, |
| 137 verifier.get(), hostname, server_config, *certs, signature, true); | 139 signature, true); |
| 138 | 140 |
| 139 RunVerification( | 141 RunVerification(verifier.get(), "foo.com", server_config, *certs, cert_sct, |
| 140 verifier.get(), "foo.com", server_config, *certs, signature, false); | 142 signature, false); |
| 141 | 143 |
| 142 RunVerification( | 144 RunVerification(verifier.get(), server_config.substr(1, string::npos), |
| 143 verifier.get(), server_config.substr(1, string::npos), server_config, | 145 server_config, *certs, cert_sct, signature, false); |
| 144 *certs, signature, false); | 146 |
| 147 // We don't generate errors for corrupt SCT. | |
|
Eran Messeri
2015/11/18 11:14:00
Can you / should you dig into the ProofVerifyDetai
ramant (doing other things)
2015/11/21 00:27:02
Hi Eran,
This is shared code with internal serve
| |
| 148 const string corrupt_cert_sct = "1" + cert_sct; | |
| 149 RunVerification(verifier.get(), "foo.com", server_config, *certs, | |
| 150 corrupt_cert_sct, signature, true); | |
| 145 | 151 |
| 146 const string corrupt_signature = "1" + signature; | 152 const string corrupt_signature = "1" + signature; |
| 147 RunVerification( | 153 RunVerification(verifier.get(), hostname, server_config, *certs, cert_sct, |
| 148 verifier.get(), hostname, server_config, *certs, corrupt_signature, | 154 corrupt_signature, false); |
| 149 false); | |
| 150 | 155 |
| 151 vector<string> wrong_certs; | 156 vector<string> wrong_certs; |
| 152 for (size_t i = 1; i < certs->size(); i++) { | 157 for (size_t i = 1; i < certs->size(); i++) { |
| 153 wrong_certs.push_back((*certs)[i]); | 158 wrong_certs.push_back((*certs)[i]); |
| 154 } | 159 } |
| 155 RunVerification( | 160 RunVerification(verifier.get(), "foo.com", server_config, wrong_certs, |
| 156 verifier.get(), "foo.com", server_config, wrong_certs, corrupt_signature, | 161 corrupt_cert_sct, corrupt_signature, false); |
| 157 false); | |
| 158 } | 162 } |
| 159 | 163 |
| 160 // A known answer test that allows us to test ProofVerifier without a working | 164 // A known answer test that allows us to test ProofVerifier without a working |
| 161 // ProofSource. | 165 // ProofSource. |
| 162 TEST(ProofTest, VerifyRSAKnownAnswerTest) { | 166 TEST(ProofTest, VerifyRSAKnownAnswerTest) { |
| 163 // These sample signatures were generated by running the Proof.Verify test | 167 // These sample signatures were generated by running the Proof.Verify test |
| 164 // and dumping the bytes of the |signature| output of ProofSource::GetProof(). | 168 // and dumping the bytes of the |signature| output of ProofSource::GetProof(). |
| 165 static const unsigned char signature_data_0[] = { | 169 static const unsigned char signature_data_0[] = { |
| 166 0x31, 0xd5, 0xfb, 0x40, 0x30, 0x75, 0xd2, 0x7d, 0x61, 0xf9, 0xd7, 0x54, | 170 0x31, 0xd5, 0xfb, 0x40, 0x30, 0x75, 0xd2, 0x7d, 0x61, 0xf9, 0xd7, 0x54, |
| 167 0x30, 0x06, 0xaf, 0x54, 0x0d, 0xb0, 0x0a, 0xda, 0x63, 0xca, 0x7e, 0x9e, | 171 0x30, 0x06, 0xaf, 0x54, 0x0d, 0xb0, 0x0a, 0xda, 0x63, 0xca, 0x7e, 0x9e, |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 238 scoped_ptr<ProofVerifier> verifier( | 242 scoped_ptr<ProofVerifier> verifier( |
| 239 CryptoTestUtils::RealProofVerifierForTesting()); | 243 CryptoTestUtils::RealProofVerifierForTesting()); |
| 240 | 244 |
| 241 const string server_config = "server config bytes"; | 245 const string server_config = "server config bytes"; |
| 242 const string hostname = "test.example.com"; | 246 const string hostname = "test.example.com"; |
| 243 | 247 |
| 244 vector<string> certs(2); | 248 vector<string> certs(2); |
| 245 certs[0] = LoadTestCert("test.example.com.crt"); | 249 certs[0] = LoadTestCert("test.example.com.crt"); |
| 246 certs[1] = LoadTestCert("intermediate.crt"); | 250 certs[1] = LoadTestCert("intermediate.crt"); |
| 247 | 251 |
| 252 const string cert_sct = ct::GetTestSignedCertificateTimestamp(); | |
| 253 | |
| 248 // Signatures are nondeterministic, so we test multiple signatures on the | 254 // Signatures are nondeterministic, so we test multiple signatures on the |
| 249 // same server_config. | 255 // same server_config. |
| 250 vector<string> signatures(3); | 256 vector<string> signatures(3); |
| 251 signatures[0].assign(reinterpret_cast<const char*>(signature_data_0), | 257 signatures[0].assign(reinterpret_cast<const char*>(signature_data_0), |
| 252 sizeof(signature_data_0)); | 258 sizeof(signature_data_0)); |
| 253 signatures[1].assign(reinterpret_cast<const char*>(signature_data_1), | 259 signatures[1].assign(reinterpret_cast<const char*>(signature_data_1), |
| 254 sizeof(signature_data_1)); | 260 sizeof(signature_data_1)); |
| 255 signatures[2].assign(reinterpret_cast<const char*>(signature_data_2), | 261 signatures[2].assign(reinterpret_cast<const char*>(signature_data_2), |
| 256 sizeof(signature_data_2)); | 262 sizeof(signature_data_2)); |
| 257 | 263 |
| 258 for (size_t i = 0; i < signatures.size(); i++) { | 264 for (size_t i = 0; i < signatures.size(); i++) { |
| 259 const string& signature = signatures[i]; | 265 const string& signature = signatures[i]; |
| 260 | 266 |
| 261 RunVerification( | 267 RunVerification(verifier.get(), hostname, server_config, certs, cert_sct, |
| 262 verifier.get(), hostname, server_config, certs, signature, true); | 268 signature, true); |
| 263 RunVerification( | 269 RunVerification(verifier.get(), "foo.com", server_config, certs, cert_sct, |
| 264 verifier.get(), "foo.com", server_config, certs, signature, false); | 270 signature, false); |
| 265 RunVerification( | 271 RunVerification(verifier.get(), hostname, |
| 266 verifier.get(), hostname, server_config.substr(1, string::npos), | 272 server_config.substr(1, string::npos), certs, cert_sct, |
| 267 certs, signature, false); | 273 signature, false); |
| 274 | |
| 275 // We don't generate errors for corrupt SCT. | |
| 276 const string corrupt_cert_sct = "1" + cert_sct; | |
| 277 RunVerification(verifier.get(), hostname, server_config, certs, | |
| 278 corrupt_cert_sct, signature, true); | |
| 268 | 279 |
| 269 const string corrupt_signature = "1" + signature; | 280 const string corrupt_signature = "1" + signature; |
| 270 RunVerification( | 281 RunVerification(verifier.get(), hostname, server_config, certs, cert_sct, |
| 271 verifier.get(), hostname, server_config, certs, corrupt_signature, | 282 corrupt_signature, false); |
| 272 false); | |
| 273 | 283 |
| 274 vector<string> wrong_certs; | 284 vector<string> wrong_certs; |
| 275 for (size_t i = 1; i < certs.size(); i++) { | 285 for (size_t i = 1; i < certs.size(); i++) { |
| 276 wrong_certs.push_back(certs[i]); | 286 wrong_certs.push_back(certs[i]); |
| 277 } | 287 } |
| 278 RunVerification(verifier.get(), hostname, server_config, wrong_certs, | 288 RunVerification(verifier.get(), hostname, server_config, wrong_certs, |
| 279 signature, false); | 289 cert_sct, signature, false); |
| 280 } | 290 } |
| 281 } | 291 } |
| 282 | 292 |
| 283 // A known answer test that allows us to test ProofVerifier without a working | 293 // A known answer test that allows us to test ProofVerifier without a working |
| 284 // ProofSource. | 294 // ProofSource. |
| 285 TEST(ProofTest, VerifyECDSAKnownAnswerTest) { | 295 TEST(ProofTest, VerifyECDSAKnownAnswerTest) { |
| 286 // Disable this test on platforms that do not support ECDSA certificates. | 296 // Disable this test on platforms that do not support ECDSA certificates. |
| 287 #if defined(OS_WIN) | 297 #if defined(OS_WIN) |
| 288 if (base::win::GetVersion() < base::win::VERSION_VISTA) | 298 if (base::win::GetVersion() < base::win::VERSION_VISTA) |
| 289 return; | 299 return; |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 320 scoped_ptr<ProofVerifier> verifier( | 330 scoped_ptr<ProofVerifier> verifier( |
| 321 CryptoTestUtils::RealProofVerifierForTesting()); | 331 CryptoTestUtils::RealProofVerifierForTesting()); |
| 322 | 332 |
| 323 const string server_config = "server config bytes"; | 333 const string server_config = "server config bytes"; |
| 324 const string hostname = "test.example.com"; | 334 const string hostname = "test.example.com"; |
| 325 | 335 |
| 326 vector<string> certs(2); | 336 vector<string> certs(2); |
| 327 certs[0] = LoadTestCert("test_ecc.example.com.crt"); | 337 certs[0] = LoadTestCert("test_ecc.example.com.crt"); |
| 328 certs[1] = LoadTestCert("intermediate.crt"); | 338 certs[1] = LoadTestCert("intermediate.crt"); |
| 329 | 339 |
| 340 const string cert_sct = ct::GetTestSignedCertificateTimestamp(); | |
| 341 | |
| 330 // Signatures are nondeterministic, so we test multiple signatures on the | 342 // Signatures are nondeterministic, so we test multiple signatures on the |
| 331 // same server_config. | 343 // same server_config. |
| 332 vector<string> signatures(3); | 344 vector<string> signatures(3); |
| 333 signatures[0].assign(reinterpret_cast<const char*>(signature_data_0), | 345 signatures[0].assign(reinterpret_cast<const char*>(signature_data_0), |
| 334 sizeof(signature_data_0)); | 346 sizeof(signature_data_0)); |
| 335 signatures[1].assign(reinterpret_cast<const char*>(signature_data_1), | 347 signatures[1].assign(reinterpret_cast<const char*>(signature_data_1), |
| 336 sizeof(signature_data_1)); | 348 sizeof(signature_data_1)); |
| 337 signatures[2].assign(reinterpret_cast<const char*>(signature_data_2), | 349 signatures[2].assign(reinterpret_cast<const char*>(signature_data_2), |
| 338 sizeof(signature_data_2)); | 350 sizeof(signature_data_2)); |
| 339 | 351 |
| 340 for (size_t i = 0; i < signatures.size(); i++) { | 352 for (size_t i = 0; i < signatures.size(); i++) { |
| 341 const string& signature = signatures[i]; | 353 const string& signature = signatures[i]; |
| 342 | 354 |
| 343 RunVerification( | 355 RunVerification(verifier.get(), hostname, server_config, certs, cert_sct, |
| 344 verifier.get(), hostname, server_config, certs, signature, true); | 356 signature, true); |
| 345 RunVerification( | 357 RunVerification(verifier.get(), "foo.com", server_config, certs, cert_sct, |
| 346 verifier.get(), "foo.com", server_config, certs, signature, false); | 358 signature, false); |
| 347 RunVerification( | 359 RunVerification(verifier.get(), hostname, |
| 348 verifier.get(), hostname, server_config.substr(1, string::npos), | 360 server_config.substr(1, string::npos), certs, cert_sct, |
| 349 certs, signature, false); | 361 signature, false); |
| 362 | |
| 363 // We don't generate errors for corrupt SCT. | |
| 364 const string corrupt_cert_sct = "1" + cert_sct; | |
| 365 RunVerification(verifier.get(), hostname, server_config, certs, | |
| 366 corrupt_cert_sct, signature, true); | |
| 350 | 367 |
| 351 // An ECDSA signature is DER-encoded. Corrupt the last byte so that the | 368 // An ECDSA signature is DER-encoded. Corrupt the last byte so that the |
| 352 // signature can still be DER-decoded correctly. | 369 // signature can still be DER-decoded correctly. |
| 353 string corrupt_signature = signature; | 370 string corrupt_signature = signature; |
| 354 corrupt_signature[corrupt_signature.size() - 1] += 1; | 371 corrupt_signature[corrupt_signature.size() - 1] += 1; |
| 355 RunVerification( | 372 RunVerification(verifier.get(), hostname, server_config, certs, cert_sct, |
| 356 verifier.get(), hostname, server_config, certs, corrupt_signature, | 373 corrupt_signature, false); |
| 357 false); | |
| 358 | 374 |
| 359 // Prepending a "1" makes the DER invalid. | 375 // Prepending a "1" makes the DER invalid. |
| 360 const string bad_der_signature1 = "1" + signature; | 376 const string bad_der_signature1 = "1" + signature; |
| 361 RunVerification( | 377 RunVerification(verifier.get(), hostname, server_config, certs, cert_sct, |
| 362 verifier.get(), hostname, server_config, certs, bad_der_signature1, | 378 bad_der_signature1, false); |
| 363 false); | |
| 364 | 379 |
| 365 vector<string> wrong_certs; | 380 vector<string> wrong_certs; |
| 366 for (size_t i = 1; i < certs.size(); i++) { | 381 for (size_t i = 1; i < certs.size(); i++) { |
| 367 wrong_certs.push_back(certs[i]); | 382 wrong_certs.push_back(certs[i]); |
| 368 } | 383 } |
| 369 RunVerification( | 384 RunVerification(verifier.get(), hostname, server_config, wrong_certs, |
| 370 verifier.get(), hostname, server_config, wrong_certs, signature, | 385 cert_sct, signature, false); |
| 371 false); | |
| 372 } | 386 } |
| 373 } | 387 } |
| 374 | 388 |
| 375 } // namespace test | 389 } // namespace test |
| 376 } // namespace net | 390 } // namespace net |
| OLD | NEW |