Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(274)

Side by Side Diff: net/quic/core/crypto/quic_crypto_server_config.cc

Issue 2513113002: Remove strike-register code from QuicCryptoServerConfig (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 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 "net/quic/core/crypto/quic_crypto_server_config.h" 5 #include "net/quic/core/crypto/quic_crypto_server_config.h"
6 6
7 #include <stdlib.h> 7 #include <stdlib.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <memory> 10 #include <memory>
11 11
12 #include "base/macros.h" 12 #include "base/macros.h"
13 #include "base/memory/ref_counted.h" 13 #include "base/memory/ref_counted.h"
14 #include "crypto/hkdf.h" 14 #include "crypto/hkdf.h"
15 #include "crypto/secure_hash.h" 15 #include "crypto/secure_hash.h"
16 #include "net/base/ip_address.h" 16 #include "net/base/ip_address.h"
17 #include "net/quic/core/crypto/aes_128_gcm_12_decrypter.h" 17 #include "net/quic/core/crypto/aes_128_gcm_12_decrypter.h"
18 #include "net/quic/core/crypto/aes_128_gcm_12_encrypter.h" 18 #include "net/quic/core/crypto/aes_128_gcm_12_encrypter.h"
19 #include "net/quic/core/crypto/cert_compressor.h" 19 #include "net/quic/core/crypto/cert_compressor.h"
20 #include "net/quic/core/crypto/chacha20_poly1305_encrypter.h" 20 #include "net/quic/core/crypto/chacha20_poly1305_encrypter.h"
21 #include "net/quic/core/crypto/channel_id.h" 21 #include "net/quic/core/crypto/channel_id.h"
22 #include "net/quic/core/crypto/crypto_framer.h" 22 #include "net/quic/core/crypto/crypto_framer.h"
23 #include "net/quic/core/crypto/crypto_handshake_message.h" 23 #include "net/quic/core/crypto/crypto_handshake_message.h"
24 #include "net/quic/core/crypto/crypto_server_config_protobuf.h" 24 #include "net/quic/core/crypto/crypto_server_config_protobuf.h"
25 #include "net/quic/core/crypto/crypto_utils.h" 25 #include "net/quic/core/crypto/crypto_utils.h"
26 #include "net/quic/core/crypto/curve25519_key_exchange.h" 26 #include "net/quic/core/crypto/curve25519_key_exchange.h"
27 #include "net/quic/core/crypto/ephemeral_key_source.h" 27 #include "net/quic/core/crypto/ephemeral_key_source.h"
28 #include "net/quic/core/crypto/key_exchange.h" 28 #include "net/quic/core/crypto/key_exchange.h"
29 #include "net/quic/core/crypto/local_strike_register_client.h"
30 #include "net/quic/core/crypto/p256_key_exchange.h" 29 #include "net/quic/core/crypto/p256_key_exchange.h"
31 #include "net/quic/core/crypto/proof_source.h" 30 #include "net/quic/core/crypto/proof_source.h"
32 #include "net/quic/core/crypto/quic_decrypter.h" 31 #include "net/quic/core/crypto/quic_decrypter.h"
33 #include "net/quic/core/crypto/quic_encrypter.h" 32 #include "net/quic/core/crypto/quic_encrypter.h"
34 #include "net/quic/core/crypto/quic_random.h" 33 #include "net/quic/core/crypto/quic_random.h"
35 #include "net/quic/core/crypto/strike_register.h"
36 #include "net/quic/core/crypto/strike_register_client.h"
37 #include "net/quic/core/proto/source_address_token.pb.h" 34 #include "net/quic/core/proto/source_address_token.pb.h"
38 #include "net/quic/core/quic_bug_tracker.h" 35 #include "net/quic/core/quic_bug_tracker.h"
39 #include "net/quic/core/quic_clock.h" 36 #include "net/quic/core/quic_clock.h"
40 #include "net/quic/core/quic_flags.h" 37 #include "net/quic/core/quic_flags.h"
41 #include "net/quic/core/quic_protocol.h" 38 #include "net/quic/core/quic_protocol.h"
42 #include "net/quic/core/quic_socket_address_coder.h" 39 #include "net/quic/core/quic_socket_address_coder.h"
43 #include "net/quic/core/quic_utils.h" 40 #include "net/quic/core/quic_utils.h"
44 41
45 using base::StringPiece; 42 using base::StringPiece;
46 using crypto::SecureHash; 43 using crypto::SecureHash;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 done_cb_ = nullptr; 104 done_cb_ = nullptr;
108 } 105 }
109 106
110 private: 107 private:
111 scoped_refptr<ValidateClientHelloResultCallback::Result> result_; 108 scoped_refptr<ValidateClientHelloResultCallback::Result> result_;
112 std::unique_ptr<ValidateClientHelloResultCallback>* done_cb_; 109 std::unique_ptr<ValidateClientHelloResultCallback>* done_cb_;
113 110
114 DISALLOW_COPY_AND_ASSIGN(ValidateClientHelloHelper); 111 DISALLOW_COPY_AND_ASSIGN(ValidateClientHelloHelper);
115 }; 112 };
116 113
117 class VerifyNonceIsValidAndUniqueCallback
118 : public StrikeRegisterClient::ResultCallback {
119 public:
120 VerifyNonceIsValidAndUniqueCallback(
121 scoped_refptr<ValidateClientHelloResultCallback::Result> result,
122 std::unique_ptr<ProofSource::Details> proof_source_details,
123 std::unique_ptr<ValidateClientHelloResultCallback> done_cb)
124 : result_(std::move(result)),
125 proof_source_details_(std::move(proof_source_details)),
126 done_cb_(std::move(done_cb)) {}
127
128 protected:
129 void RunImpl(bool nonce_is_valid_and_unique,
130 InsertStatus nonce_error) override {
131 DVLOG(1) << "Using client nonce, unique: " << nonce_is_valid_and_unique
132 << " nonce_error: " << nonce_error;
133 if (!nonce_is_valid_and_unique) {
134 HandshakeFailureReason client_nonce_error;
135 switch (nonce_error) {
136 case NONCE_INVALID_FAILURE:
137 client_nonce_error = CLIENT_NONCE_INVALID_FAILURE;
138 break;
139 case NONCE_NOT_UNIQUE_FAILURE:
140 client_nonce_error = CLIENT_NONCE_NOT_UNIQUE_FAILURE;
141 break;
142 case NONCE_INVALID_ORBIT_FAILURE:
143 client_nonce_error = CLIENT_NONCE_INVALID_ORBIT_FAILURE;
144 break;
145 case NONCE_INVALID_TIME_FAILURE:
146 client_nonce_error = CLIENT_NONCE_INVALID_TIME_FAILURE;
147 break;
148 case STRIKE_REGISTER_TIMEOUT:
149 client_nonce_error = CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT;
150 break;
151 case STRIKE_REGISTER_FAILURE:
152 client_nonce_error = CLIENT_NONCE_STRIKE_REGISTER_FAILURE;
153 break;
154 case NONCE_UNKNOWN_FAILURE:
155 client_nonce_error = CLIENT_NONCE_UNKNOWN_FAILURE;
156 break;
157 case NONCE_OK:
158 default:
159 QUIC_BUG << "Unexpected client nonce error: " << nonce_error;
160 client_nonce_error = CLIENT_NONCE_UNKNOWN_FAILURE;
161 break;
162 }
163 result_->info.reject_reasons.push_back(client_nonce_error);
164 }
165 done_cb_->Run(result_, std::move(proof_source_details_));
166 }
167
168 private:
169 scoped_refptr<ValidateClientHelloResultCallback::Result> result_;
170 std::unique_ptr<ProofSource::Details> proof_source_details_;
171 std::unique_ptr<ValidateClientHelloResultCallback> done_cb_;
172
173 DISALLOW_COPY_AND_ASSIGN(VerifyNonceIsValidAndUniqueCallback);
174 };
175
176 // static 114 // static
177 const char QuicCryptoServerConfig::TESTING[] = "secret string for testing"; 115 const char QuicCryptoServerConfig::TESTING[] = "secret string for testing";
178 116
179 ClientHelloInfo::ClientHelloInfo(const IPAddress& in_client_ip, 117 ClientHelloInfo::ClientHelloInfo(const IPAddress& in_client_ip,
180 QuicWallTime in_now) 118 QuicWallTime in_now)
181 : client_ip(in_client_ip), now(in_now), valid_source_address_token(false) {} 119 : client_ip(in_client_ip), now(in_now), valid_source_address_token(false) {}
182 120
183 ClientHelloInfo::ClientHelloInfo(const ClientHelloInfo& other) = default; 121 ClientHelloInfo::ClientHelloInfo(const ClientHelloInfo& other) = default;
184 122
185 ClientHelloInfo::~ClientHelloInfo() {} 123 ClientHelloInfo::~ClientHelloInfo() {}
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 156
219 QuicCryptoServerConfig::QuicCryptoServerConfig( 157 QuicCryptoServerConfig::QuicCryptoServerConfig(
220 StringPiece source_address_token_secret, 158 StringPiece source_address_token_secret,
221 QuicRandom* server_nonce_entropy, 159 QuicRandom* server_nonce_entropy,
222 std::unique_ptr<ProofSource> proof_source) 160 std::unique_ptr<ProofSource> proof_source)
223 : replay_protection_(true), 161 : replay_protection_(true),
224 chlo_multiplier_(kMultiplier), 162 chlo_multiplier_(kMultiplier),
225 configs_lock_(), 163 configs_lock_(),
226 primary_config_(nullptr), 164 primary_config_(nullptr),
227 next_config_promotion_time_(QuicWallTime::Zero()), 165 next_config_promotion_time_(QuicWallTime::Zero()),
228 server_nonce_strike_register_lock_(),
229 proof_source_(std::move(proof_source)), 166 proof_source_(std::move(proof_source)),
230 strike_register_no_startup_period_(false),
231 strike_register_max_entries_(1 << 10),
232 strike_register_window_secs_(600),
233 source_address_token_future_secs_(3600), 167 source_address_token_future_secs_(3600),
234 source_address_token_lifetime_secs_(86400), 168 source_address_token_lifetime_secs_(86400),
235 server_nonce_strike_register_max_entries_(1 << 10),
236 server_nonce_strike_register_window_secs_(120),
237 enable_serving_sct_(false), 169 enable_serving_sct_(false),
238 rejection_observer_(nullptr) { 170 rejection_observer_(nullptr) {
239 DCHECK(proof_source_.get()); 171 DCHECK(proof_source_.get());
240 source_address_token_boxer_.SetKeys( 172 source_address_token_boxer_.SetKeys(
241 {DeriveSourceAddressTokenKey(source_address_token_secret)}); 173 {DeriveSourceAddressTokenKey(source_address_token_secret)});
242 174
243 // Generate a random key and orbit for server nonces. 175 // Generate a random key and orbit for server nonces.
244 server_nonce_entropy->RandBytes(server_nonce_orbit_, 176 server_nonce_entropy->RandBytes(server_nonce_orbit_,
245 sizeof(server_nonce_orbit_)); 177 sizeof(server_nonce_orbit_));
246 const size_t key_size = server_nonce_boxer_.GetKeySize(); 178 const size_t key_size = server_nonce_boxer_.GetKeySize();
(...skipping 1528 matching lines...) Expand 10 before | Expand all | Expand 10 after
1775 if (orbit.size() != kOrbitSize) { 1707 if (orbit.size() != kOrbitSize) {
1776 LOG(WARNING) << "Orbit value in server config is the wrong length." 1708 LOG(WARNING) << "Orbit value in server config is the wrong length."
1777 " Got " 1709 " Got "
1778 << orbit.size() << " want " << kOrbitSize; 1710 << orbit.size() << " want " << kOrbitSize;
1779 return nullptr; 1711 return nullptr;
1780 } 1712 }
1781 static_assert(sizeof(config->orbit) == kOrbitSize, 1713 static_assert(sizeof(config->orbit) == kOrbitSize,
1782 "orbit has incorrect size"); 1714 "orbit has incorrect size");
1783 memcpy(config->orbit, orbit.data(), sizeof(config->orbit)); 1715 memcpy(config->orbit, orbit.data(), sizeof(config->orbit));
1784 1716
1785 {
1786 StrikeRegisterClient* strike_register_client;
1787 {
1788 base::AutoLock locked(strike_register_client_lock_);
1789 strike_register_client = strike_register_client_.get();
1790 }
1791
1792 if (strike_register_client != nullptr &&
1793 !strike_register_client->IsKnownOrbit(orbit)) {
1794 LOG(WARNING)
1795 << "Rejecting server config with orbit that the strike register "
1796 "client doesn't know about.";
1797 return nullptr;
1798 }
1799 }
1800
1801 if (kexs_len != protobuf->key_size()) { 1717 if (kexs_len != protobuf->key_size()) {
1802 LOG(WARNING) << "Server config has " << kexs_len 1718 LOG(WARNING) << "Server config has " << kexs_len
1803 << " key exchange methods configured, but " 1719 << " key exchange methods configured, but "
1804 << protobuf->key_size() << " private keys"; 1720 << protobuf->key_size() << " private keys";
1805 return nullptr; 1721 return nullptr;
1806 } 1722 }
1807 1723
1808 const QuicTag* proof_demand_tags; 1724 const QuicTag* proof_demand_tags;
1809 size_t num_proof_demand_tags; 1725 size_t num_proof_demand_tags;
1810 if (msg->GetTaglist(kPDMD, &proof_demand_tags, &num_proof_demand_tags) == 1726 if (msg->GetTaglist(kPDMD, &proof_demand_tags, &num_proof_demand_tags) ==
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1881 config->expiry_time = QuicWallTime::FromUNIXSeconds(expiry_seconds); 1797 config->expiry_time = QuicWallTime::FromUNIXSeconds(expiry_seconds);
1882 1798
1883 return config; 1799 return config;
1884 } 1800 }
1885 1801
1886 void QuicCryptoServerConfig::SetEphemeralKeySource( 1802 void QuicCryptoServerConfig::SetEphemeralKeySource(
1887 EphemeralKeySource* ephemeral_key_source) { 1803 EphemeralKeySource* ephemeral_key_source) {
1888 ephemeral_key_source_.reset(ephemeral_key_source); 1804 ephemeral_key_source_.reset(ephemeral_key_source);
1889 } 1805 }
1890 1806
1891 void QuicCryptoServerConfig::SetStrikeRegisterClient(
1892 StrikeRegisterClient* strike_register_client) {
1893 base::AutoLock locker(strike_register_client_lock_);
1894 DCHECK(!strike_register_client_.get());
1895 strike_register_client_.reset(strike_register_client);
1896 }
1897
1898 void QuicCryptoServerConfig::set_replay_protection(bool on) { 1807 void QuicCryptoServerConfig::set_replay_protection(bool on) {
1899 replay_protection_ = on; 1808 replay_protection_ = on;
1900 } 1809 }
1901 1810
1902 void QuicCryptoServerConfig::set_chlo_multiplier(size_t multiplier) { 1811 void QuicCryptoServerConfig::set_chlo_multiplier(size_t multiplier) {
1903 chlo_multiplier_ = multiplier; 1812 chlo_multiplier_ = multiplier;
1904 } 1813 }
1905 1814
1906 void QuicCryptoServerConfig::set_strike_register_no_startup_period() {
1907 base::AutoLock locker(strike_register_client_lock_);
1908 DCHECK(!strike_register_client_.get());
1909 strike_register_no_startup_period_ = true;
1910 }
1911
1912 void QuicCryptoServerConfig::set_strike_register_max_entries(
1913 uint32_t max_entries) {
1914 base::AutoLock locker(strike_register_client_lock_);
1915 DCHECK(!strike_register_client_.get());
1916 strike_register_max_entries_ = max_entries;
1917 }
1918
1919 void QuicCryptoServerConfig::set_strike_register_window_secs(
1920 uint32_t window_secs) {
1921 base::AutoLock locker(strike_register_client_lock_);
1922 DCHECK(!strike_register_client_.get());
1923 strike_register_window_secs_ = window_secs;
1924 }
1925
1926 void QuicCryptoServerConfig::set_source_address_token_future_secs( 1815 void QuicCryptoServerConfig::set_source_address_token_future_secs(
1927 uint32_t future_secs) { 1816 uint32_t future_secs) {
1928 source_address_token_future_secs_ = future_secs; 1817 source_address_token_future_secs_ = future_secs;
1929 } 1818 }
1930 1819
1931 void QuicCryptoServerConfig::set_source_address_token_lifetime_secs( 1820 void QuicCryptoServerConfig::set_source_address_token_lifetime_secs(
1932 uint32_t lifetime_secs) { 1821 uint32_t lifetime_secs) {
1933 source_address_token_lifetime_secs_ = lifetime_secs; 1822 source_address_token_lifetime_secs_ = lifetime_secs;
1934 } 1823 }
1935 1824
1936 void QuicCryptoServerConfig::set_server_nonce_strike_register_max_entries(
1937 uint32_t max_entries) {
1938 DCHECK(!server_nonce_strike_register_.get());
1939 server_nonce_strike_register_max_entries_ = max_entries;
1940 }
1941
1942 void QuicCryptoServerConfig::set_server_nonce_strike_register_window_secs(
1943 uint32_t window_secs) {
1944 DCHECK(!server_nonce_strike_register_.get());
1945 server_nonce_strike_register_window_secs_ = window_secs;
1946 }
1947
1948 void QuicCryptoServerConfig::set_enable_serving_sct(bool enable_serving_sct) { 1825 void QuicCryptoServerConfig::set_enable_serving_sct(bool enable_serving_sct) {
1949 enable_serving_sct_ = enable_serving_sct; 1826 enable_serving_sct_ = enable_serving_sct;
1950 } 1827 }
1951 1828
1952 void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb( 1829 void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb(
1953 std::unique_ptr<PrimaryConfigChangedCallback> cb) { 1830 std::unique_ptr<PrimaryConfigChangedCallback> cb) {
1954 base::AutoLock locked(configs_lock_); 1831 base::AutoLock locked(configs_lock_);
1955 primary_config_changed_cb_ = std::move(cb); 1832 primary_config_changed_cb_ = std::move(cb);
1956 } 1833 }
1957 1834
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
2092 server_nonce[2] = static_cast<uint8_t>(timestamp >> 8); 1969 server_nonce[2] = static_cast<uint8_t>(timestamp >> 8);
2093 server_nonce[3] = static_cast<uint8_t>(timestamp); 1970 server_nonce[3] = static_cast<uint8_t>(timestamp);
2094 rand->RandBytes(&server_nonce[sizeof(timestamp)], 1971 rand->RandBytes(&server_nonce[sizeof(timestamp)],
2095 sizeof(server_nonce) - sizeof(timestamp)); 1972 sizeof(server_nonce) - sizeof(timestamp));
2096 1973
2097 return server_nonce_boxer_.Box( 1974 return server_nonce_boxer_.Box(
2098 rand, 1975 rand,
2099 StringPiece(reinterpret_cast<char*>(server_nonce), sizeof(server_nonce))); 1976 StringPiece(reinterpret_cast<char*>(server_nonce), sizeof(server_nonce)));
2100 } 1977 }
2101 1978
2102 HandshakeFailureReason QuicCryptoServerConfig::ValidateServerNonce(
2103 StringPiece token,
2104 QuicWallTime now) const {
2105 string storage;
2106 StringPiece plaintext;
2107 if (!server_nonce_boxer_.Unbox(token, &storage, &plaintext)) {
2108 return SERVER_NONCE_DECRYPTION_FAILURE;
2109 }
2110
2111 // plaintext contains:
2112 // uint32_t timestamp
2113 // uint8_t[20] random bytes
2114
2115 if (plaintext.size() != kServerNoncePlaintextSize) {
2116 // This should never happen because the value decrypted correctly.
2117 QUIC_BUG << "Seemingly valid server nonce had incorrect length.";
2118 return SERVER_NONCE_INVALID_FAILURE;
2119 }
2120
2121 uint8_t server_nonce[32];
2122 memcpy(server_nonce, plaintext.data(), 4);
2123 memcpy(server_nonce + 4, server_nonce_orbit_, sizeof(server_nonce_orbit_));
2124 memcpy(server_nonce + 4 + sizeof(server_nonce_orbit_), plaintext.data() + 4,
2125 20);
2126 static_assert(4 + sizeof(server_nonce_orbit_) + 20 == sizeof(server_nonce),
2127 "bad nonce buffer length");
2128
2129 InsertStatus nonce_error;
2130 {
2131 base::AutoLock auto_lock(server_nonce_strike_register_lock_);
2132 if (server_nonce_strike_register_.get() == nullptr) {
2133 server_nonce_strike_register_.reset(new StrikeRegister(
2134 server_nonce_strike_register_max_entries_,
2135 static_cast<uint32_t>(now.ToUNIXSeconds()),
2136 server_nonce_strike_register_window_secs_, server_nonce_orbit_,
2137 StrikeRegister::NO_STARTUP_PERIOD_NEEDED));
2138 }
2139 nonce_error = server_nonce_strike_register_->Insert(
2140 server_nonce, static_cast<uint32_t>(now.ToUNIXSeconds()));
2141 }
2142
2143 switch (nonce_error) {
2144 case NONCE_OK:
2145 return HANDSHAKE_OK;
2146 case NONCE_INVALID_FAILURE:
2147 case NONCE_INVALID_ORBIT_FAILURE:
2148 return SERVER_NONCE_INVALID_FAILURE;
2149 case NONCE_NOT_UNIQUE_FAILURE:
2150 return SERVER_NONCE_NOT_UNIQUE_FAILURE;
2151 case NONCE_INVALID_TIME_FAILURE:
2152 return SERVER_NONCE_INVALID_TIME_FAILURE;
2153 case NONCE_UNKNOWN_FAILURE:
2154 case STRIKE_REGISTER_TIMEOUT:
2155 case STRIKE_REGISTER_FAILURE:
2156 default:
2157 QUIC_BUG << "Unexpected server nonce error: " << nonce_error;
2158 return SERVER_NONCE_NOT_UNIQUE_FAILURE;
2159 }
2160 }
2161
2162 bool QuicCryptoServerConfig::ValidateExpectedLeafCertificate( 1979 bool QuicCryptoServerConfig::ValidateExpectedLeafCertificate(
2163 const CryptoHandshakeMessage& client_hello, 1980 const CryptoHandshakeMessage& client_hello,
2164 const QuicSignedServerConfig& signed_config) const { 1981 const QuicSignedServerConfig& signed_config) const {
2165 if (signed_config.chain->certs.empty()) { 1982 if (signed_config.chain->certs.empty()) {
2166 return false; 1983 return false;
2167 } 1984 }
2168 1985
2169 uint64_t hash_from_client; 1986 uint64_t hash_from_client;
2170 if (client_hello.GetUint64(kXLCT, &hash_from_client) != QUIC_NO_ERROR) { 1987 if (client_hello.GetUint64(kXLCT, &hash_from_client) != QUIC_NO_ERROR) {
2171 return false; 1988 return false;
(...skipping 30 matching lines...) Expand all
2202 source_address_token_boxer(nullptr) {} 2019 source_address_token_boxer(nullptr) {}
2203 2020
2204 QuicCryptoServerConfig::Config::~Config() { 2021 QuicCryptoServerConfig::Config::~Config() {
2205 } 2022 }
2206 2023
2207 QuicSignedServerConfig::QuicSignedServerConfig() 2024 QuicSignedServerConfig::QuicSignedServerConfig()
2208 : send_expect_ct_header(false) {} 2025 : send_expect_ct_header(false) {}
2209 QuicSignedServerConfig::~QuicSignedServerConfig() {} 2026 QuicSignedServerConfig::~QuicSignedServerConfig() {}
2210 2027
2211 } // namespace net 2028 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/core/crypto/quic_crypto_server_config.h ('k') | net/quic/core/crypto/quic_crypto_server_config_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698