| OLD | NEW |
| 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/crypto/quic_crypto_server_config.h" | 5 #include "net/quic/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> |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 << "Deleting ValidateClientHelloHelper with a pending callback."; | 90 << "Deleting ValidateClientHelloHelper with a pending callback."; |
| 91 } | 91 } |
| 92 | 92 |
| 93 void ValidationComplete(QuicErrorCode error_code, const char* error_details) { | 93 void ValidationComplete(QuicErrorCode error_code, const char* error_details) { |
| 94 result_->error_code = error_code; | 94 result_->error_code = error_code; |
| 95 result_->error_details = error_details; | 95 result_->error_details = error_details; |
| 96 done_cb_->Run(result_); | 96 done_cb_->Run(result_); |
| 97 DetachCallback(); | 97 DetachCallback(); |
| 98 } | 98 } |
| 99 | 99 |
| 100 void StartedAsyncCallback() { DetachCallback(); } | |
| 101 | |
| 102 private: | |
| 103 void DetachCallback() { | 100 void DetachCallback() { |
| 104 QUIC_BUG_IF(done_cb_ == nullptr) << "Callback already detached."; | 101 QUIC_BUG_IF(done_cb_ == nullptr) << "Callback already detached."; |
| 105 done_cb_ = nullptr; | 102 done_cb_ = nullptr; |
| 106 } | 103 } |
| 107 | 104 |
| 105 private: |
| 108 ValidateClientHelloResultCallback::Result* result_; | 106 ValidateClientHelloResultCallback::Result* result_; |
| 109 ValidateClientHelloResultCallback* done_cb_; | 107 ValidateClientHelloResultCallback* done_cb_; |
| 110 | 108 |
| 111 DISALLOW_COPY_AND_ASSIGN(ValidateClientHelloHelper); | 109 DISALLOW_COPY_AND_ASSIGN(ValidateClientHelloHelper); |
| 112 }; | 110 }; |
| 113 | 111 |
| 114 class VerifyNonceIsValidAndUniqueCallback | 112 class VerifyNonceIsValidAndUniqueCallback |
| 115 : public StrikeRegisterClient::ResultCallback { | 113 : public StrikeRegisterClient::ResultCallback { |
| 116 public: | 114 public: |
| 117 VerifyNonceIsValidAndUniqueCallback( | 115 VerifyNonceIsValidAndUniqueCallback( |
| (...skipping 865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 983 << QuicUtils::HexEncode( | 981 << QuicUtils::HexEncode( |
| 984 reinterpret_cast<const char*>(primary_config_->orbit), | 982 reinterpret_cast<const char*>(primary_config_->orbit), |
| 985 kOrbitSize) | 983 kOrbitSize) |
| 986 << " scid: " << QuicUtils::HexEncode(primary_config_->id); | 984 << " scid: " << QuicUtils::HexEncode(primary_config_->id); |
| 987 next_config_promotion_time_ = QuicWallTime::Zero(); | 985 next_config_promotion_time_ = QuicWallTime::Zero(); |
| 988 if (primary_config_changed_cb_.get() != nullptr) { | 986 if (primary_config_changed_cb_.get() != nullptr) { |
| 989 primary_config_changed_cb_->Run(primary_config_->id); | 987 primary_config_changed_cb_->Run(primary_config_->id); |
| 990 } | 988 } |
| 991 } | 989 } |
| 992 | 990 |
| 991 class EvaluateClientHelloCallback : public ProofSource::Callback { |
| 992 public: |
| 993 EvaluateClientHelloCallback( |
| 994 const QuicCryptoServerConfig& config, |
| 995 bool found_error, |
| 996 const IPAddress& server_ip, |
| 997 QuicVersion version, |
| 998 const uint8_t* primary_orbit, |
| 999 scoped_refptr<QuicCryptoServerConfig::Config> requested_config, |
| 1000 scoped_refptr<QuicCryptoServerConfig::Config> primary_config, |
| 1001 QuicCryptoProof* crypto_proof, |
| 1002 ValidateClientHelloResultCallback::Result* client_hello_state, |
| 1003 ValidateClientHelloResultCallback* done_cb) |
| 1004 : config_(config), |
| 1005 found_error_(found_error), |
| 1006 server_ip_(server_ip), |
| 1007 version_(version), |
| 1008 primary_orbit_(primary_orbit), |
| 1009 requested_config_(std::move(requested_config)), |
| 1010 primary_config_(std::move(primary_config)), |
| 1011 crypto_proof_(crypto_proof), |
| 1012 client_hello_state_(client_hello_state), |
| 1013 done_cb_(done_cb) {} |
| 1014 |
| 1015 void Run(bool ok, |
| 1016 const scoped_refptr<ProofSource::Chain>& chain, |
| 1017 const string& signature, |
| 1018 const string& leaf_cert_sct) override { |
| 1019 if (ok) { |
| 1020 crypto_proof_->chain = chain; |
| 1021 crypto_proof_->signature = signature; |
| 1022 crypto_proof_->cert_sct = leaf_cert_sct; |
| 1023 } |
| 1024 config_.EvaluateClientHelloAfterGetProof( |
| 1025 found_error_, server_ip_, version_, primary_orbit_, requested_config_, |
| 1026 primary_config_, crypto_proof_, !ok, client_hello_state_, done_cb_); |
| 1027 } |
| 1028 |
| 1029 private: |
| 1030 const QuicCryptoServerConfig& config_; |
| 1031 const bool found_error_; |
| 1032 const IPAddress& server_ip_; |
| 1033 const QuicVersion version_; |
| 1034 const uint8_t* primary_orbit_; |
| 1035 const scoped_refptr<QuicCryptoServerConfig::Config> requested_config_; |
| 1036 const scoped_refptr<QuicCryptoServerConfig::Config> primary_config_; |
| 1037 QuicCryptoProof* crypto_proof_; |
| 1038 ValidateClientHelloResultCallback::Result* client_hello_state_; |
| 1039 ValidateClientHelloResultCallback* done_cb_; |
| 1040 }; |
| 1041 |
| 993 void QuicCryptoServerConfig::EvaluateClientHello( | 1042 void QuicCryptoServerConfig::EvaluateClientHello( |
| 994 const IPAddress& server_ip, | 1043 const IPAddress& server_ip, |
| 995 QuicVersion version, | 1044 QuicVersion version, |
| 996 const uint8_t* primary_orbit, | 1045 const uint8_t* primary_orbit, |
| 997 scoped_refptr<Config> requested_config, | 1046 scoped_refptr<Config> requested_config, |
| 998 scoped_refptr<Config> primary_config, | 1047 scoped_refptr<Config> primary_config, |
| 999 QuicCryptoProof* crypto_proof, | 1048 QuicCryptoProof* crypto_proof, |
| 1000 ValidateClientHelloResultCallback::Result* client_hello_state, | 1049 ValidateClientHelloResultCallback::Result* client_hello_state, |
| 1001 ValidateClientHelloResultCallback* done_cb) const { | 1050 ValidateClientHelloResultCallback* done_cb) const { |
| 1002 ValidateClientHelloHelper helper(client_hello_state, done_cb); | 1051 ValidateClientHelloHelper helper(client_hello_state, done_cb); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1056 return; | 1105 return; |
| 1057 } | 1106 } |
| 1058 | 1107 |
| 1059 bool found_error = false; | 1108 bool found_error = false; |
| 1060 if (source_address_token_error != HANDSHAKE_OK) { | 1109 if (source_address_token_error != HANDSHAKE_OK) { |
| 1061 info->reject_reasons.push_back(source_address_token_error); | 1110 info->reject_reasons.push_back(source_address_token_error); |
| 1062 // No valid source address token. | 1111 // No valid source address token. |
| 1063 found_error = true; | 1112 found_error = true; |
| 1064 } | 1113 } |
| 1065 | 1114 |
| 1115 bool get_proof_failed = false; |
| 1066 if (version > QUIC_VERSION_25) { | 1116 if (version > QUIC_VERSION_25) { |
| 1067 bool x509_supported = false; | 1117 bool x509_supported = false; |
| 1068 bool x509_ecdsa_supported = false; | 1118 bool x509_ecdsa_supported = false; |
| 1069 ParseProofDemand(client_hello, &x509_supported, &x509_ecdsa_supported); | 1119 ParseProofDemand(client_hello, &x509_supported, &x509_ecdsa_supported); |
| 1070 string serialized_config = primary_config->serialized; | 1120 string serialized_config = primary_config->serialized; |
| 1071 string chlo_hash; | 1121 string chlo_hash; |
| 1072 CryptoUtils::HashHandshakeMessage(client_hello, &chlo_hash); | 1122 CryptoUtils::HashHandshakeMessage(client_hello, &chlo_hash); |
| 1073 bool need_proof = true; | 1123 bool need_proof = true; |
| 1074 if (FLAGS_quic_refresh_proof) { | 1124 if (FLAGS_quic_refresh_proof) { |
| 1075 need_proof = !crypto_proof->chain; | 1125 need_proof = !crypto_proof->chain; |
| 1076 } | 1126 } |
| 1127 if (FLAGS_enable_async_get_proof) { |
| 1128 if (need_proof) { |
| 1129 // Make an async call to GetProof and setup the callback to trampoline |
| 1130 // back into EvaluateClientHelloAfterGetProof |
| 1131 std::unique_ptr<EvaluateClientHelloCallback> cb( |
| 1132 new EvaluateClientHelloCallback( |
| 1133 *this, found_error, server_ip, version, primary_orbit, |
| 1134 requested_config, primary_config, crypto_proof, |
| 1135 client_hello_state, done_cb)); |
| 1136 proof_source_->GetProof(server_ip, info->sni.as_string(), |
| 1137 serialized_config, version, chlo_hash, |
| 1138 x509_ecdsa_supported, std::move(cb)); |
| 1139 helper.DetachCallback(); |
| 1140 return; |
| 1141 } |
| 1142 } |
| 1143 |
| 1077 // No need to get a new proof if one was already generated. | 1144 // No need to get a new proof if one was already generated. |
| 1078 if (need_proof && | 1145 if (need_proof && |
| 1079 !proof_source_->GetProof( | 1146 !proof_source_->GetProof( |
| 1080 server_ip, info->sni.as_string(), serialized_config, version, | 1147 server_ip, info->sni.as_string(), serialized_config, version, |
| 1081 chlo_hash, x509_ecdsa_supported, &crypto_proof->chain, | 1148 chlo_hash, x509_ecdsa_supported, &crypto_proof->chain, |
| 1082 &crypto_proof->signature, &crypto_proof->cert_sct)) { | 1149 &crypto_proof->signature, &crypto_proof->cert_sct)) { |
| 1083 found_error = true; | 1150 get_proof_failed = true; |
| 1084 info->reject_reasons.push_back(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE); | |
| 1085 } | 1151 } |
| 1152 } |
| 1086 | 1153 |
| 1154 EvaluateClientHelloAfterGetProof( |
| 1155 found_error, server_ip, version, primary_orbit, requested_config, |
| 1156 primary_config, crypto_proof, get_proof_failed, client_hello_state, |
| 1157 done_cb); |
| 1158 helper.DetachCallback(); |
| 1159 } |
| 1160 |
| 1161 void QuicCryptoServerConfig::EvaluateClientHelloAfterGetProof( |
| 1162 bool found_error, |
| 1163 const IPAddress& server_ip, |
| 1164 QuicVersion version, |
| 1165 const uint8_t* primary_orbit, |
| 1166 scoped_refptr<Config> requested_config, |
| 1167 scoped_refptr<Config> primary_config, |
| 1168 QuicCryptoProof* crypto_proof, |
| 1169 bool get_proof_failed, |
| 1170 ValidateClientHelloResultCallback::Result* client_hello_state, |
| 1171 ValidateClientHelloResultCallback* done_cb) const { |
| 1172 ValidateClientHelloHelper helper(client_hello_state, done_cb); |
| 1173 const CryptoHandshakeMessage& client_hello = client_hello_state->client_hello; |
| 1174 ClientHelloInfo* info = &(client_hello_state->info); |
| 1175 |
| 1176 if (get_proof_failed) { |
| 1177 found_error = true; |
| 1178 info->reject_reasons.push_back(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE); |
| 1179 } |
| 1180 |
| 1181 if (version > QUIC_VERSION_25) { |
| 1087 if (!ValidateExpectedLeafCertificate(client_hello, *crypto_proof)) { | 1182 if (!ValidateExpectedLeafCertificate(client_hello, *crypto_proof)) { |
| 1088 found_error = true; | 1183 found_error = true; |
| 1089 info->reject_reasons.push_back(INVALID_EXPECTED_LEAF_CERTIFICATE); | 1184 info->reject_reasons.push_back(INVALID_EXPECTED_LEAF_CERTIFICATE); |
| 1090 } | 1185 } |
| 1091 } | 1186 } |
| 1092 | 1187 |
| 1093 if (info->client_nonce.size() != kNonceSize) { | 1188 if (info->client_nonce.size() != kNonceSize) { |
| 1094 info->reject_reasons.push_back(CLIENT_NONCE_INVALID_FAILURE); | 1189 info->reject_reasons.push_back(CLIENT_NONCE_INVALID_FAILURE); |
| 1095 // Invalid client nonce. | 1190 // Invalid client nonce. |
| 1096 LOG(ERROR) << "Invalid client nonce: " << client_hello.DebugString(); | 1191 LOG(ERROR) << "Invalid client nonce: " << client_hello.DebugString(); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1159 // Since neither are present, reject the handshake which will send a | 1254 // Since neither are present, reject the handshake which will send a |
| 1160 // server nonce to the client. | 1255 // server nonce to the client. |
| 1161 info->reject_reasons.push_back(SERVER_NONCE_REQUIRED_FAILURE); | 1256 info->reject_reasons.push_back(SERVER_NONCE_REQUIRED_FAILURE); |
| 1162 helper.ValidationComplete(QUIC_NO_ERROR, ""); | 1257 helper.ValidationComplete(QUIC_NO_ERROR, ""); |
| 1163 return; | 1258 return; |
| 1164 } | 1259 } |
| 1165 | 1260 |
| 1166 strike_register_client->VerifyNonceIsValidAndUnique( | 1261 strike_register_client->VerifyNonceIsValidAndUnique( |
| 1167 info->client_nonce, info->now, | 1262 info->client_nonce, info->now, |
| 1168 new VerifyNonceIsValidAndUniqueCallback(client_hello_state, done_cb)); | 1263 new VerifyNonceIsValidAndUniqueCallback(client_hello_state, done_cb)); |
| 1169 helper.StartedAsyncCallback(); | 1264 helper.DetachCallback(); |
| 1170 } | 1265 } |
| 1171 | 1266 |
| 1172 bool QuicCryptoServerConfig::BuildServerConfigUpdateMessage( | 1267 bool QuicCryptoServerConfig::BuildServerConfigUpdateMessage( |
| 1173 QuicVersion version, | 1268 QuicVersion version, |
| 1174 StringPiece chlo_hash, | 1269 StringPiece chlo_hash, |
| 1175 const SourceAddressTokens& previous_source_address_tokens, | 1270 const SourceAddressTokens& previous_source_address_tokens, |
| 1176 const IPAddress& server_ip, | 1271 const IPAddress& server_ip, |
| 1177 const IPAddress& client_ip, | 1272 const IPAddress& client_ip, |
| 1178 const QuicClock* clock, | 1273 const QuicClock* clock, |
| 1179 QuicRandom* rand, | 1274 QuicRandom* rand, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1193 clock->WallNow(), cached_network_params); | 1288 clock->WallNow(), cached_network_params); |
| 1194 } | 1289 } |
| 1195 | 1290 |
| 1196 out->set_tag(kSCUP); | 1291 out->set_tag(kSCUP); |
| 1197 out->SetStringPiece(kSCFG, serialized); | 1292 out->SetStringPiece(kSCFG, serialized); |
| 1198 out->SetStringPiece(kSourceAddressTokenTag, source_address_token); | 1293 out->SetStringPiece(kSourceAddressTokenTag, source_address_token); |
| 1199 | 1294 |
| 1200 scoped_refptr<ProofSource::Chain> chain; | 1295 scoped_refptr<ProofSource::Chain> chain; |
| 1201 string signature; | 1296 string signature; |
| 1202 string cert_sct; | 1297 string cert_sct; |
| 1203 if (FLAGS_quic_use_hash_in_scup) { | 1298 if (!proof_source_->GetProof(server_ip, params.sni, serialized, version, |
| 1204 if (!proof_source_->GetProof(server_ip, params.sni, serialized, version, | 1299 chlo_hash, params.x509_ecdsa_supported, &chain, |
| 1205 chlo_hash, params.x509_ecdsa_supported, &chain, | 1300 &signature, &cert_sct)) { |
| 1206 &signature, &cert_sct)) { | 1301 DVLOG(1) << "Server: failed to get proof."; |
| 1207 DVLOG(1) << "Server: failed to get proof."; | 1302 return false; |
| 1208 return false; | |
| 1209 } | |
| 1210 } else { | |
| 1211 if (!proof_source_->GetProof( | |
| 1212 server_ip, params.sni, serialized, version, params.client_nonce, | |
| 1213 params.x509_ecdsa_supported, &chain, &signature, &cert_sct)) { | |
| 1214 DVLOG(1) << "Server: failed to get proof."; | |
| 1215 return false; | |
| 1216 } | |
| 1217 } | 1303 } |
| 1218 | 1304 |
| 1219 const string compressed = CompressChain( | 1305 const string compressed = CompressChain( |
| 1220 compressed_certs_cache, chain, params.client_common_set_hashes, | 1306 compressed_certs_cache, chain, params.client_common_set_hashes, |
| 1221 params.client_cached_cert_hashes, common_cert_sets); | 1307 params.client_cached_cert_hashes, common_cert_sets); |
| 1222 | 1308 |
| 1223 out->SetStringPiece(kCertificateTag, compressed); | 1309 out->SetStringPiece(kCertificateTag, compressed); |
| 1224 out->SetStringPiece(kPROF, signature); | 1310 out->SetStringPiece(kPROF, signature); |
| 1225 if (params.sct_supported_by_client && version > QUIC_VERSION_29 && | 1311 if (params.sct_supported_by_client && version > QUIC_VERSION_29 && |
| 1226 enable_serving_sct_) { | 1312 enable_serving_sct_) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1260 CryptoHandshakeMessage message; | 1346 CryptoHandshakeMessage message; |
| 1261 message.set_tag(kSCUP); | 1347 message.set_tag(kSCUP); |
| 1262 message.SetStringPiece(kSCFG, serialized); | 1348 message.SetStringPiece(kSCFG, serialized); |
| 1263 message.SetStringPiece(kSourceAddressTokenTag, source_address_token); | 1349 message.SetStringPiece(kSourceAddressTokenTag, source_address_token); |
| 1264 | 1350 |
| 1265 std::unique_ptr<BuildServerConfigUpdateMessageProofSourceCallback> | 1351 std::unique_ptr<BuildServerConfigUpdateMessageProofSourceCallback> |
| 1266 proof_source_cb(new BuildServerConfigUpdateMessageProofSourceCallback( | 1352 proof_source_cb(new BuildServerConfigUpdateMessageProofSourceCallback( |
| 1267 this, version, compressed_certs_cache, common_cert_sets, params, | 1353 this, version, compressed_certs_cache, common_cert_sets, params, |
| 1268 std::move(message), std::move(cb))); | 1354 std::move(message), std::move(cb))); |
| 1269 | 1355 |
| 1270 if (FLAGS_quic_use_hash_in_scup) { | 1356 proof_source_->GetProof(server_ip, params.sni, serialized, version, chlo_hash, |
| 1271 proof_source_->GetProof(server_ip, params.sni, serialized, version, | 1357 params.x509_ecdsa_supported, |
| 1272 chlo_hash, params.x509_ecdsa_supported, | 1358 std::move(proof_source_cb)); |
| 1273 std::move(proof_source_cb)); | |
| 1274 } else { | |
| 1275 proof_source_->GetProof(server_ip, params.sni, serialized, version, | |
| 1276 params.client_nonce, params.x509_ecdsa_supported, | |
| 1277 std::move(proof_source_cb)); | |
| 1278 } | |
| 1279 } | 1359 } |
| 1280 | 1360 |
| 1281 QuicCryptoServerConfig::BuildServerConfigUpdateMessageProofSourceCallback:: | 1361 QuicCryptoServerConfig::BuildServerConfigUpdateMessageProofSourceCallback:: |
| 1282 ~BuildServerConfigUpdateMessageProofSourceCallback() {} | 1362 ~BuildServerConfigUpdateMessageProofSourceCallback() {} |
| 1283 | 1363 |
| 1284 QuicCryptoServerConfig::BuildServerConfigUpdateMessageProofSourceCallback:: | 1364 QuicCryptoServerConfig::BuildServerConfigUpdateMessageProofSourceCallback:: |
| 1285 BuildServerConfigUpdateMessageProofSourceCallback( | 1365 BuildServerConfigUpdateMessageProofSourceCallback( |
| 1286 const QuicCryptoServerConfig* config, | 1366 const QuicCryptoServerConfig* config, |
| 1287 QuicVersion version, | 1367 QuicVersion version, |
| 1288 QuicCompressedCertsCache* compressed_certs_cache, | 1368 QuicCompressedCertsCache* compressed_certs_cache, |
| (...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1965 priority(0), | 2045 priority(0), |
| 1966 source_address_token_boxer(nullptr) {} | 2046 source_address_token_boxer(nullptr) {} |
| 1967 | 2047 |
| 1968 QuicCryptoServerConfig::Config::~Config() { | 2048 QuicCryptoServerConfig::Config::~Config() { |
| 1969 STLDeleteElements(&key_exchanges); | 2049 STLDeleteElements(&key_exchanges); |
| 1970 } | 2050 } |
| 1971 | 2051 |
| 1972 QuicCryptoProof::QuicCryptoProof() {} | 2052 QuicCryptoProof::QuicCryptoProof() {} |
| 1973 QuicCryptoProof::~QuicCryptoProof() {} | 2053 QuicCryptoProof::~QuicCryptoProof() {} |
| 1974 } // namespace net | 2054 } // namespace net |
| OLD | NEW |