[email protected] | c244c5a1 | 2013-05-07 20:55:04 | [diff] [blame] | 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. |
| 4 | |
rch | 16c74d1d | 2016-04-22 06:14:07 | [diff] [blame] | 5 | #include <memory> |
| 6 | |
[email protected] | 2662ed56 | 2013-07-03 10:27:46 | [diff] [blame] | 7 | #include "base/files/file_path.h" |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 8 | #include "base/memory/raw_ptr.h" |
rtenneti | 7dac4be | 2014-12-15 21:10:01 | [diff] [blame] | 9 | #include "net/base/ip_endpoint.h" |
[email protected] | 2662ed56 | 2013-07-03 10:27:46 | [diff] [blame] | 10 | #include "net/base/net_errors.h" |
| 11 | #include "net/base/test_completion_callback.h" |
[email protected] | a69af052 | 2013-07-12 19:23:47 | [diff] [blame] | 12 | #include "net/cert/cert_status_flags.h" |
| 13 | #include "net/cert/cert_verify_result.h" |
[email protected] | 2662ed56 | 2013-07-03 10:27:46 | [diff] [blame] | 14 | #include "net/cert/x509_certificate.h" |
[email protected] | 2662ed56 | 2013-07-03 10:27:46 | [diff] [blame] | 15 | #include "net/test/cert_test_util.h" |
rsleevi | a69c79a | 2016-06-22 03:28:43 | [diff] [blame] | 16 | #include "net/test/test_data_directory.h" |
Ryan Hamilton | ea4fa19 | 2022-04-12 18:30:49 | [diff] [blame] | 17 | #include "net/third_party/quiche/src/quiche/quic/core/crypto/proof_source.h" |
| 18 | #include "net/third_party/quiche/src/quiche/quic/core/crypto/proof_verifier.h" |
| 19 | #include "net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.h" |
[email protected] | c244c5a1 | 2013-05-07 20:55:04 | [diff] [blame] | 20 | #include "testing/gtest/include/gtest/gtest.h" |
Nick Harper | b42e4e7d | 2017-08-31 00:18:11 | [diff] [blame] | 21 | #include "third_party/boringssl/src/include/openssl/ssl.h" |
[email protected] | c244c5a1 | 2013-05-07 20:55:04 | [diff] [blame] | 22 | |
| 23 | using std::string; |
[email protected] | c244c5a1 | 2013-05-07 20:55:04 | [diff] [blame] | 24 | |
Tsuyoshi Horo | 4f516be | 2022-06-14 11:53:13 | [diff] [blame] | 25 | namespace net::test { |
[email protected] | 6a731c9 | 2014-03-22 00:43:24 | [diff] [blame] | 26 | namespace { |
[email protected] | c244c5a1 | 2013-05-07 20:55:04 | [diff] [blame] | 27 | |
Ryan Hamilton | 8d9ee76e | 2018-05-29 23:52:52 | [diff] [blame] | 28 | // TestProofVerifierCallback is a simple callback for a quic::ProofVerifier that |
[email protected] | 72e6599 | 2013-07-30 17:16:14 | [diff] [blame] | 29 | // signals a TestCompletionCallback when called and stores the results from the |
Ryan Hamilton | 8d9ee76e | 2018-05-29 23:52:52 | [diff] [blame] | 30 | // quic::ProofVerifier in pointers passed to the constructor. |
| 31 | class TestProofVerifierCallback : public quic::ProofVerifierCallback { |
[email protected] | 72e6599 | 2013-07-30 17:16:14 | [diff] [blame] | 32 | public: |
| 33 | TestProofVerifierCallback(TestCompletionCallback* comp_callback, |
| 34 | bool* ok, |
[email protected] | b9475b58 | 2014-03-20 20:04:33 | [diff] [blame] | 35 | string* error_details) |
rjshade | d5ced07 | 2015-12-18 19:26:02 | [diff] [blame] | 36 | : comp_callback_(comp_callback), ok_(ok), error_details_(error_details) {} |
[email protected] | 72e6599 | 2013-07-30 17:16:14 | [diff] [blame] | 37 | |
dcheng | b03027d | 2014-10-21 12:00:20 | [diff] [blame] | 38 | void Run(bool ok, |
| 39 | const string& error_details, |
Ryan Hamilton | 8d9ee76e | 2018-05-29 23:52:52 | [diff] [blame] | 40 | std::unique_ptr<quic::ProofVerifyDetails>* details) override { |
[email protected] | 72e6599 | 2013-07-30 17:16:14 | [diff] [blame] | 41 | *ok_ = ok; |
| 42 | *error_details_ = error_details; |
| 43 | |
| 44 | comp_callback_->callback().Run(0); |
| 45 | } |
| 46 | |
| 47 | private: |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 48 | const raw_ptr<TestCompletionCallback> comp_callback_; |
| 49 | const raw_ptr<bool> ok_; |
| 50 | const raw_ptr<string> error_details_; |
[email protected] | 72e6599 | 2013-07-30 17:16:14 | [diff] [blame] | 51 | }; |
| 52 | |
| 53 | // RunVerification runs |verifier->VerifyProof| and asserts that the result |
| 54 | // matches |expected_ok|. |
Ryan Hamilton | 8d9ee76e | 2018-05-29 23:52:52 | [diff] [blame] | 55 | void RunVerification(quic::ProofVerifier* verifier, |
[email protected] | 6a731c9 | 2014-03-22 00:43:24 | [diff] [blame] | 56 | const string& hostname, |
elawrence | 954bb547 | 2016-04-04 22:03:11 | [diff] [blame] | 57 | const uint16_t port, |
[email protected] | 6a731c9 | 2014-03-22 00:43:24 | [diff] [blame] | 58 | const string& server_config, |
Ryan Hamilton | 8d9ee76e | 2018-05-29 23:52:52 | [diff] [blame] | 59 | quic::QuicTransportVersion quic_version, |
Victor Vasiliev | 47ecb6a | 2020-10-14 17:22:10 | [diff] [blame] | 60 | absl::string_view chlo_hash, |
rch | 872e00e | 2016-12-02 02:48:18 | [diff] [blame] | 61 | const std::vector<string>& certs, |
[email protected] | 6a731c9 | 2014-03-22 00:43:24 | [diff] [blame] | 62 | const string& proof, |
| 63 | bool expected_ok) { |
Ryan Hamilton | 8d9ee76e | 2018-05-29 23:52:52 | [diff] [blame] | 64 | std::unique_ptr<quic::ProofVerifyDetails> details; |
[email protected] | 72e6599 | 2013-07-30 17:16:14 | [diff] [blame] | 65 | TestCompletionCallback comp_callback; |
| 66 | bool ok; |
[email protected] | b9475b58 | 2014-03-20 20:04:33 | [diff] [blame] | 67 | string error_details; |
Ryan Hamilton | 8d9ee76e | 2018-05-29 23:52:52 | [diff] [blame] | 68 | std::unique_ptr<quic::ProofVerifyContext> verify_context( |
| 69 | quic::test::crypto_test_utils::ProofVerifyContextForTesting()); |
Tsuyoshi Horo | f8861cb | 2022-07-05 23:50:20 | [diff] [blame] | 70 | auto callback = std::make_unique<TestProofVerifierCallback>( |
| 71 | &comp_callback, &ok, &error_details); |
[email protected] | 72e6599 | 2013-07-30 17:16:14 | [diff] [blame] | 72 | |
Ryan Hamilton | 8d9ee76e | 2018-05-29 23:52:52 | [diff] [blame] | 73 | quic::QuicAsyncStatus status = verifier->VerifyProof( |
elawrence | 954bb547 | 2016-04-04 22:03:11 | [diff] [blame] | 74 | hostname, port, server_config, quic_version, chlo_hash, certs, "", proof, |
ckrasic | 6567aa5 | 2016-07-08 09:24:35 | [diff] [blame] | 75 | verify_context.get(), &error_details, &details, std::move(callback)); |
[email protected] | 72e6599 | 2013-07-30 17:16:14 | [diff] [blame] | 76 | |
| 77 | switch (status) { |
Ryan Hamilton | 8d9ee76e | 2018-05-29 23:52:52 | [diff] [blame] | 78 | case quic::QUIC_FAILURE: |
[email protected] | 72e6599 | 2013-07-30 17:16:14 | [diff] [blame] | 79 | ASSERT_FALSE(expected_ok); |
| 80 | ASSERT_NE("", error_details); |
| 81 | return; |
Ryan Hamilton | 8d9ee76e | 2018-05-29 23:52:52 | [diff] [blame] | 82 | case quic::QUIC_SUCCESS: |
[email protected] | 72e6599 | 2013-07-30 17:16:14 | [diff] [blame] | 83 | ASSERT_TRUE(expected_ok); |
| 84 | ASSERT_EQ("", error_details); |
| 85 | return; |
Ryan Hamilton | 8d9ee76e | 2018-05-29 23:52:52 | [diff] [blame] | 86 | case quic::QUIC_PENDING: |
[email protected] | 72e6599 | 2013-07-30 17:16:14 | [diff] [blame] | 87 | comp_callback.WaitForResult(); |
| 88 | ASSERT_EQ(expected_ok, ok); |
| 89 | break; |
| 90 | } |
| 91 | } |
| 92 | |
Ryan Hamilton | 8d9ee76e | 2018-05-29 23:52:52 | [diff] [blame] | 93 | class TestCallback : public quic::ProofSource::Callback { |
ckrasic | 6567aa5 | 2016-07-08 09:24:35 | [diff] [blame] | 94 | public: |
Ryan Hamilton | 8d9ee76e | 2018-05-29 23:52:52 | [diff] [blame] | 95 | explicit TestCallback( |
| 96 | bool* called, |
| 97 | bool* ok, |
Victor Vasiliev | 5b04a6b | 2022-03-15 14:24:25 | [diff] [blame] | 98 | quiche::QuicheReferenceCountedPointer<quic::ProofSource::Chain>* chain, |
Ryan Hamilton | 8d9ee76e | 2018-05-29 23:52:52 | [diff] [blame] | 99 | quic::QuicCryptoProof* proof) |
mpw | 94250b8 | 2016-11-19 18:13:30 | [diff] [blame] | 100 | : called_(called), ok_(ok), chain_(chain), proof_(proof) {} |
ckrasic | 6567aa5 | 2016-07-08 09:24:35 | [diff] [blame] | 101 | |
Ryan Hamilton | 8d9ee76e | 2018-05-29 23:52:52 | [diff] [blame] | 102 | void Run( |
| 103 | bool ok, |
Victor Vasiliev | 5b04a6b | 2022-03-15 14:24:25 | [diff] [blame] | 104 | const quiche::QuicheReferenceCountedPointer<quic::ProofSource::Chain>& |
| 105 | chain, |
Ryan Hamilton | 8d9ee76e | 2018-05-29 23:52:52 | [diff] [blame] | 106 | const quic::QuicCryptoProof& proof, |
| 107 | std::unique_ptr<quic::ProofSource::Details> /* details */) override { |
ckrasic | 6567aa5 | 2016-07-08 09:24:35 | [diff] [blame] | 108 | *ok_ = ok; |
| 109 | *chain_ = chain; |
mpw | 94250b8 | 2016-11-19 18:13:30 | [diff] [blame] | 110 | *proof_ = proof; |
ckrasic | 6567aa5 | 2016-07-08 09:24:35 | [diff] [blame] | 111 | *called_ = true; |
| 112 | } |
| 113 | |
| 114 | private: |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 115 | raw_ptr<bool> called_; |
| 116 | raw_ptr<bool> ok_; |
Victor Vasiliev | 5b04a6b | 2022-03-15 14:24:25 | [diff] [blame] | 117 | raw_ptr<quiche::QuicheReferenceCountedPointer<quic::ProofSource::Chain>> |
| 118 | chain_; |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 119 | raw_ptr<quic::QuicCryptoProof> proof_; |
ckrasic | 6567aa5 | 2016-07-08 09:24:35 | [diff] [blame] | 120 | }; |
| 121 | |
Renjie Tang | 1085bf5 | 2019-11-20 00:10:53 | [diff] [blame] | 122 | class ProofTest : public ::testing::TestWithParam<quic::ParsedQuicVersion> {}; |
rch | 28f6469d | 2016-03-13 21:13:08 | [diff] [blame] | 123 | |
[email protected] | 6a731c9 | 2014-03-22 00:43:24 | [diff] [blame] | 124 | } // namespace |
| 125 | |
Renjie Tang | 1085bf5 | 2019-11-20 00:10:53 | [diff] [blame] | 126 | INSTANTIATE_TEST_SUITE_P(QuicTransportVersion, |
| 127 | ProofTest, |
| 128 | ::testing::ValuesIn(quic::AllSupportedVersions()), |
| 129 | ::testing::PrintToStringParamName()); |
rch | 28f6469d | 2016-03-13 21:13:08 | [diff] [blame] | 130 | |
David Benjamin | b28c476f | 2018-12-15 04:47:15 | [diff] [blame] | 131 | TEST_P(ProofTest, Verify) { |
Ryan Hamilton | 8d9ee76e | 2018-05-29 23:52:52 | [diff] [blame] | 132 | std::unique_ptr<quic::ProofSource> source( |
| 133 | quic::test::crypto_test_utils::ProofSourceForTesting()); |
| 134 | std::unique_ptr<quic::ProofVerifier> verifier( |
| 135 | quic::test::crypto_test_utils::ProofVerifierForTesting()); |
[email protected] | 6a731c9 | 2014-03-22 00:43:24 | [diff] [blame] | 136 | |
| 137 | const string server_config = "server config bytes"; |
| 138 | const string hostname = "test.example.com"; |
elawrence | 954bb547 | 2016-04-04 22:03:11 | [diff] [blame] | 139 | const uint16_t port = 8443; |
rch | 28f6469d | 2016-03-13 21:13:08 | [diff] [blame] | 140 | const string first_chlo_hash = "first chlo hash bytes"; |
| 141 | const string second_chlo_hash = "first chlo hash bytes"; |
Renjie Tang | 1085bf5 | 2019-11-20 00:10:53 | [diff] [blame] | 142 | const quic::QuicTransportVersion quic_version = GetParam().transport_version; |
elawrence | 954bb547 | 2016-04-04 22:03:11 | [diff] [blame] | 143 | |
fayang | f5f4cd51 | 2017-02-07 16:57:11 | [diff] [blame] | 144 | bool called = false; |
| 145 | bool first_called = false; |
| 146 | bool ok, first_ok; |
Victor Vasiliev | 5b04a6b | 2022-03-15 14:24:25 | [diff] [blame] | 147 | quiche::QuicheReferenceCountedPointer<quic::ProofSource::Chain> chain; |
| 148 | quiche::QuicheReferenceCountedPointer<quic::ProofSource::Chain> first_chain; |
mpw | 94250b8 | 2016-11-19 18:13:30 | [diff] [blame] | 149 | string error_details; |
Ryan Hamilton | 8d9ee76e | 2018-05-29 23:52:52 | [diff] [blame] | 150 | quic::QuicCryptoProof proof, first_proof; |
| 151 | quic::QuicSocketAddress server_addr; |
Zhongyi Shi | 43a8f224 | 2020-05-04 23:34:31 | [diff] [blame] | 152 | quic::QuicSocketAddress client_addr; |
[email protected] | 6a731c9 | 2014-03-22 00:43:24 | [diff] [blame] | 153 | |
Tsuyoshi Horo | f8861cb | 2022-07-05 23:50:20 | [diff] [blame] | 154 | auto cb = std::make_unique<TestCallback>(&called, &ok, &chain, &proof); |
| 155 | auto first_cb = std::make_unique<TestCallback>(&first_called, &first_ok, |
| 156 | &first_chain, &first_proof); |
fayang | f5f4cd51 | 2017-02-07 16:57:11 | [diff] [blame] | 157 | |
| 158 | // GetProof here expects the async method to invoke the callback |
| 159 | // synchronously. |
Zhongyi Shi | 43a8f224 | 2020-05-04 23:34:31 | [diff] [blame] | 160 | source->GetProof(server_addr, client_addr, hostname, server_config, |
| 161 | quic_version, first_chlo_hash, std::move(first_cb)); |
| 162 | source->GetProof(server_addr, client_addr, hostname, server_config, |
| 163 | quic_version, second_chlo_hash, std::move(cb)); |
fayang | f5f4cd51 | 2017-02-07 16:57:11 | [diff] [blame] | 164 | ASSERT_TRUE(called); |
| 165 | ASSERT_TRUE(first_called); |
| 166 | ASSERT_TRUE(ok); |
| 167 | ASSERT_TRUE(first_ok); |
[email protected] | 6a731c9 | 2014-03-22 00:43:24 | [diff] [blame] | 168 | |
| 169 | // Check that the proof source is caching correctly: |
fayang | a64c1a9 | 2016-02-13 01:55:58 | [diff] [blame] | 170 | ASSERT_EQ(first_chain->certs, chain->certs); |
mpw | 94250b8 | 2016-11-19 18:13:30 | [diff] [blame] | 171 | ASSERT_NE(proof.signature, first_proof.signature); |
| 172 | ASSERT_EQ(first_proof.leaf_cert_scts, proof.leaf_cert_scts); |
[email protected] | 6a731c9 | 2014-03-22 00:43:24 | [diff] [blame] | 173 | |
elawrence | 954bb547 | 2016-04-04 22:03:11 | [diff] [blame] | 174 | RunVerification(verifier.get(), hostname, port, server_config, quic_version, |
mpw | 94250b8 | 2016-11-19 18:13:30 | [diff] [blame] | 175 | first_chlo_hash, chain->certs, proof.signature, true); |
[email protected] | 6a731c9 | 2014-03-22 00:43:24 | [diff] [blame] | 176 | |
elawrence | 954bb547 | 2016-04-04 22:03:11 | [diff] [blame] | 177 | RunVerification(verifier.get(), "foo.com", port, server_config, quic_version, |
mpw | 94250b8 | 2016-11-19 18:13:30 | [diff] [blame] | 178 | first_chlo_hash, chain->certs, proof.signature, false); |
[email protected] | 6a731c9 | 2014-03-22 00:43:24 | [diff] [blame] | 179 | |
elawrence | 954bb547 | 2016-04-04 22:03:11 | [diff] [blame] | 180 | RunVerification(verifier.get(), server_config.substr(1, string::npos), port, |
rch | 28f6469d | 2016-03-13 21:13:08 | [diff] [blame] | 181 | server_config, quic_version, first_chlo_hash, chain->certs, |
mpw | 94250b8 | 2016-11-19 18:13:30 | [diff] [blame] | 182 | proof.signature, false); |
[email protected] | 6a731c9 | 2014-03-22 00:43:24 | [diff] [blame] | 183 | |
mpw | 94250b8 | 2016-11-19 18:13:30 | [diff] [blame] | 184 | const string corrupt_signature = "1" + proof.signature; |
elawrence | 954bb547 | 2016-04-04 22:03:11 | [diff] [blame] | 185 | RunVerification(verifier.get(), hostname, port, server_config, quic_version, |
rch | 28f6469d | 2016-03-13 21:13:08 | [diff] [blame] | 186 | first_chlo_hash, chain->certs, corrupt_signature, false); |
[email protected] | 6a731c9 | 2014-03-22 00:43:24 | [diff] [blame] | 187 | |
rch | 872e00e | 2016-12-02 02:48:18 | [diff] [blame] | 188 | std::vector<string> wrong_certs; |
fayang | a64c1a9 | 2016-02-13 01:55:58 | [diff] [blame] | 189 | for (size_t i = 1; i < chain->certs.size(); i++) { |
| 190 | wrong_certs.push_back(chain->certs[i]); |
[email protected] | 6a731c9 | 2014-03-22 00:43:24 | [diff] [blame] | 191 | } |
elawrence | 954bb547 | 2016-04-04 22:03:11 | [diff] [blame] | 192 | |
| 193 | RunVerification(verifier.get(), "foo.com", port, server_config, quic_version, |
rch | 28f6469d | 2016-03-13 21:13:08 | [diff] [blame] | 194 | first_chlo_hash, wrong_certs, corrupt_signature, false); |
[email protected] | 6a731c9 | 2014-03-22 00:43:24 | [diff] [blame] | 195 | } |
| 196 | |
Nick Harper | b42e4e7d | 2017-08-31 00:18:11 | [diff] [blame] | 197 | namespace { |
Nick Harper | b00c9089 | 2017-08-31 04:08:09 | [diff] [blame] | 198 | |
Ryan Hamilton | 8d9ee76e | 2018-05-29 23:52:52 | [diff] [blame] | 199 | class TestingSignatureCallback : public quic::ProofSource::SignatureCallback { |
Nick Harper | b42e4e7d | 2017-08-31 00:18:11 | [diff] [blame] | 200 | public: |
| 201 | TestingSignatureCallback(bool* ok_out, std::string* signature_out) |
| 202 | : ok_out_(ok_out), signature_out_(signature_out) {} |
| 203 | |
Fan Yang | 7abc6bd | 2020-03-27 17:58:18 | [diff] [blame] | 204 | void Run(bool ok, |
| 205 | std::string signature, |
| 206 | std::unique_ptr<quic::ProofSource::Details> /*details*/) override { |
Nick Harper | b42e4e7d | 2017-08-31 00:18:11 | [diff] [blame] | 207 | *ok_out_ = ok; |
| 208 | *signature_out_ = std::move(signature); |
| 209 | } |
| 210 | |
| 211 | private: |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 212 | raw_ptr<bool> ok_out_; |
| 213 | raw_ptr<std::string> signature_out_; |
Nick Harper | b42e4e7d | 2017-08-31 00:18:11 | [diff] [blame] | 214 | }; |
| 215 | |
| 216 | } // namespace |
| 217 | |
| 218 | TEST_P(ProofTest, TlsSignature) { |
Ryan Hamilton | 8d9ee76e | 2018-05-29 23:52:52 | [diff] [blame] | 219 | std::unique_ptr<quic::ProofSource> source( |
| 220 | quic::test::crypto_test_utils::ProofSourceForTesting()); |
Nick Harper | b42e4e7d | 2017-08-31 00:18:11 | [diff] [blame] | 221 | |
Ryan Hamilton | 8d9ee76e | 2018-05-29 23:52:52 | [diff] [blame] | 222 | quic::QuicSocketAddress server_address; |
Nick Harper | b42e4e7d | 2017-08-31 00:18:11 | [diff] [blame] | 223 | const string hostname = "test.example.com"; |
| 224 | |
Zhongyi Shi | 43a8f224 | 2020-05-04 23:34:31 | [diff] [blame] | 225 | quic::QuicSocketAddress client_address; |
| 226 | |
David Schinazi | f492e4318a | 2021-09-09 16:41:19 | [diff] [blame] | 227 | bool cert_matched_sni; |
Victor Vasiliev | 5b04a6b | 2022-03-15 14:24:25 | [diff] [blame] | 228 | quiche::QuicheReferenceCountedPointer<quic::ProofSource::Chain> chain = |
David Schinazi | f492e4318a | 2021-09-09 16:41:19 | [diff] [blame] | 229 | source->GetCertChain(server_address, client_address, hostname, |
| 230 | &cert_matched_sni); |
Nick Harper | b42e4e7d | 2017-08-31 00:18:11 | [diff] [blame] | 231 | ASSERT_GT(chain->certs.size(), 0ul); |
| 232 | |
| 233 | // Generate a value to be signed similar to the example in TLS 1.3 section |
| 234 | // 4.4.3. The value to be signed starts with octed 0x20 repeated 64 times, |
| 235 | // followed by the context string, followed by a single 0 byte, followed by |
| 236 | // the transcript hash. Since there's no TLS stack here, we're using 32 bytes |
| 237 | // of 01 as the transcript hash. |
| 238 | string to_be_signed(64, ' '); |
| 239 | to_be_signed.append("TLS 1.3, server CertificateVerify"); |
| 240 | to_be_signed.append(1, '\0'); |
| 241 | to_be_signed.append(32, 1); |
| 242 | |
| 243 | string sig; |
| 244 | bool success; |
| 245 | std::unique_ptr<TestingSignatureCallback> callback = |
Victor Vasiliev | 7da0817 | 2019-10-14 06:04:25 | [diff] [blame] | 246 | std::make_unique<TestingSignatureCallback>(&success, &sig); |
Zhongyi Shi | 43a8f224 | 2020-05-04 23:34:31 | [diff] [blame] | 247 | source->ComputeTlsSignature(server_address, client_address, hostname, |
| 248 | SSL_SIGN_RSA_PSS_SHA256, to_be_signed, |
| 249 | std::move(callback)); |
Nick Harper | b42e4e7d | 2017-08-31 00:18:11 | [diff] [blame] | 250 | EXPECT_TRUE(success); |
| 251 | |
| 252 | // Verify that the signature from ComputeTlsSignature can be verified with the |
| 253 | // leaf cert from GetCertChain. |
| 254 | const uint8_t* data; |
| 255 | const uint8_t* orig_data; |
| 256 | orig_data = data = reinterpret_cast<const uint8_t*>(chain->certs[0].data()); |
| 257 | bssl::UniquePtr<X509> leaf(d2i_X509(nullptr, &data, chain->certs[0].size())); |
| 258 | ASSERT_NE(leaf.get(), nullptr); |
| 259 | EXPECT_EQ(data - orig_data, static_cast<ptrdiff_t>(chain->certs[0].size())); |
| 260 | bssl::UniquePtr<EVP_PKEY> pkey(X509_get_pubkey(leaf.get())); |
| 261 | bssl::ScopedEVP_MD_CTX md_ctx; |
| 262 | EVP_PKEY_CTX* ctx; |
| 263 | ASSERT_EQ(EVP_DigestVerifyInit(md_ctx.get(), &ctx, EVP_sha256(), nullptr, |
| 264 | pkey.get()), |
| 265 | 1); |
| 266 | ASSERT_EQ(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING), 1); |
| 267 | ASSERT_EQ(EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, -1), 1); |
| 268 | ASSERT_EQ(EVP_DigestVerifyUpdate(md_ctx.get(), to_be_signed.data(), |
| 269 | to_be_signed.size()), |
| 270 | 1); |
| 271 | EXPECT_EQ(EVP_DigestVerifyFinal(md_ctx.get(), |
| 272 | reinterpret_cast<const uint8_t*>(sig.data()), |
| 273 | sig.size()), |
| 274 | 1); |
| 275 | } |
| 276 | |
rch | 28f6469d | 2016-03-13 21:13:08 | [diff] [blame] | 277 | TEST_P(ProofTest, UseAfterFree) { |
Ryan Hamilton | 8d9ee76e | 2018-05-29 23:52:52 | [diff] [blame] | 278 | std::unique_ptr<quic::ProofSource> source( |
| 279 | quic::test::crypto_test_utils::ProofSourceForTesting()); |
fayang | a64c1a9 | 2016-02-13 01:55:58 | [diff] [blame] | 280 | |
| 281 | const string server_config = "server config bytes"; |
| 282 | const string hostname = "test.example.com"; |
rch | 28f6469d | 2016-03-13 21:13:08 | [diff] [blame] | 283 | const string chlo_hash = "proof nonce bytes"; |
fayang | f5f4cd51 | 2017-02-07 16:57:11 | [diff] [blame] | 284 | bool called = false; |
| 285 | bool ok; |
Victor Vasiliev | 5b04a6b | 2022-03-15 14:24:25 | [diff] [blame] | 286 | quiche::QuicheReferenceCountedPointer<quic::ProofSource::Chain> chain; |
mpw | 94250b8 | 2016-11-19 18:13:30 | [diff] [blame] | 287 | string error_details; |
Ryan Hamilton | 8d9ee76e | 2018-05-29 23:52:52 | [diff] [blame] | 288 | quic::QuicCryptoProof proof; |
| 289 | quic::QuicSocketAddress server_addr; |
Zhongyi Shi | 43a8f224 | 2020-05-04 23:34:31 | [diff] [blame] | 290 | quic::QuicSocketAddress client_addr; |
Tsuyoshi Horo | f8861cb | 2022-07-05 23:50:20 | [diff] [blame] | 291 | auto cb = std::make_unique<TestCallback>(&called, &ok, &chain, &proof); |
fayang | a64c1a9 | 2016-02-13 01:55:58 | [diff] [blame] | 292 | |
fayang | f5f4cd51 | 2017-02-07 16:57:11 | [diff] [blame] | 293 | // GetProof here expects the async method to invoke the callback |
| 294 | // synchronously. |
Zhongyi Shi | 43a8f224 | 2020-05-04 23:34:31 | [diff] [blame] | 295 | source->GetProof(server_addr, client_addr, hostname, server_config, |
Renjie Tang | 1085bf5 | 2019-11-20 00:10:53 | [diff] [blame] | 296 | GetParam().transport_version, chlo_hash, std::move(cb)); |
fayang | f5f4cd51 | 2017-02-07 16:57:11 | [diff] [blame] | 297 | ASSERT_TRUE(called); |
| 298 | ASSERT_TRUE(ok); |
fayang | a64c1a9 | 2016-02-13 01:55:58 | [diff] [blame] | 299 | |
| 300 | // Make sure we can safely access results after deleting where they came from. |
| 301 | EXPECT_FALSE(chain->HasOneRef()); |
fayang | 199cfb0 | 2016-07-13 03:56:39 | [diff] [blame] | 302 | source = nullptr; |
fayang | a64c1a9 | 2016-02-13 01:55:58 | [diff] [blame] | 303 | EXPECT_TRUE(chain->HasOneRef()); |
| 304 | |
| 305 | EXPECT_FALSE(chain->certs.empty()); |
| 306 | for (const string& cert : chain->certs) { |
| 307 | EXPECT_FALSE(cert.empty()); |
| 308 | } |
| 309 | } |
| 310 | |
Tsuyoshi Horo | 4f516be | 2022-06-14 11:53:13 | [diff] [blame] | 311 | } // namespace net::test |