Chromium Code Reviews| 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 #include <algorithm> | 8 #include <algorithm> |
| 9 | 9 |
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 #include "net/quic/crypto/local_strike_register_client.h" | 26 #include "net/quic/crypto/local_strike_register_client.h" |
| 27 #include "net/quic/crypto/p256_key_exchange.h" | 27 #include "net/quic/crypto/p256_key_exchange.h" |
| 28 #include "net/quic/crypto/proof_source.h" | 28 #include "net/quic/crypto/proof_source.h" |
| 29 #include "net/quic/crypto/quic_decrypter.h" | 29 #include "net/quic/crypto/quic_decrypter.h" |
| 30 #include "net/quic/crypto/quic_encrypter.h" | 30 #include "net/quic/crypto/quic_encrypter.h" |
| 31 #include "net/quic/crypto/quic_random.h" | 31 #include "net/quic/crypto/quic_random.h" |
| 32 #include "net/quic/crypto/source_address_token.h" | 32 #include "net/quic/crypto/source_address_token.h" |
| 33 #include "net/quic/crypto/strike_register.h" | 33 #include "net/quic/crypto/strike_register.h" |
| 34 #include "net/quic/crypto/strike_register_client.h" | 34 #include "net/quic/crypto/strike_register_client.h" |
| 35 #include "net/quic/quic_clock.h" | 35 #include "net/quic/quic_clock.h" |
| 36 #include "net/quic/quic_flags.h" | |
| 36 #include "net/quic/quic_protocol.h" | 37 #include "net/quic/quic_protocol.h" |
| 37 #include "net/quic/quic_socket_address_coder.h" | 38 #include "net/quic/quic_socket_address_coder.h" |
| 38 #include "net/quic/quic_utils.h" | 39 #include "net/quic/quic_utils.h" |
| 39 | 40 |
| 40 using base::StringPiece; | 41 using base::StringPiece; |
| 41 using crypto::SecureHash; | 42 using crypto::SecureHash; |
| 42 using std::map; | 43 using std::map; |
| 43 using std::sort; | 44 using std::sort; |
| 44 using std::string; | 45 using std::string; |
| 45 using std::vector; | 46 using std::vector; |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 74 const QuicWallTime now; | 75 const QuicWallTime now; |
| 75 | 76 |
| 76 // Outputs from EvaluateClientHello. | 77 // Outputs from EvaluateClientHello. |
| 77 bool valid_source_address_token; | 78 bool valid_source_address_token; |
| 78 bool client_nonce_well_formed; | 79 bool client_nonce_well_formed; |
| 79 bool unique; | 80 bool unique; |
| 80 StringPiece sni; | 81 StringPiece sni; |
| 81 StringPiece client_nonce; | 82 StringPiece client_nonce; |
| 82 StringPiece server_nonce; | 83 StringPiece server_nonce; |
| 83 StringPiece user_agent_id; | 84 StringPiece user_agent_id; |
| 85 | |
| 86 // Errors from EvaluateClientHello. | |
| 87 vector<uint32> reject_reasons; | |
|
wtc
2014/06/19 19:58:42
Nit: you may want to add a COMPILE_ASSERT that siz
ramant (doing other things)
2014/06/20 23:20:47
Fixed in CL: https://codereview.chromium.org/33627
| |
| 84 }; | 88 }; |
| 85 | 89 |
| 86 struct ValidateClientHelloResultCallback::Result { | 90 struct ValidateClientHelloResultCallback::Result { |
| 87 Result(const CryptoHandshakeMessage& in_client_hello, | 91 Result(const CryptoHandshakeMessage& in_client_hello, |
| 88 IPEndPoint in_client_ip, | 92 IPEndPoint in_client_ip, |
| 89 QuicWallTime in_now) | 93 QuicWallTime in_now) |
| 90 : client_hello(in_client_hello), | 94 : client_hello(in_client_hello), |
| 91 info(in_client_ip, in_now), | 95 info(in_client_ip, in_now), |
| 92 error_code(QUIC_NO_ERROR) { | 96 error_code(QUIC_NO_ERROR) { |
| 93 } | 97 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 139 VerifyNonceIsValidAndUniqueCallback( | 143 VerifyNonceIsValidAndUniqueCallback( |
| 140 ValidateClientHelloResultCallback::Result* result, | 144 ValidateClientHelloResultCallback::Result* result, |
| 141 ValidateClientHelloResultCallback* done_cb) | 145 ValidateClientHelloResultCallback* done_cb) |
| 142 : result_(result), done_cb_(done_cb) { | 146 : result_(result), done_cb_(done_cb) { |
| 143 } | 147 } |
| 144 | 148 |
| 145 protected: | 149 protected: |
| 146 virtual void RunImpl(bool nonce_is_valid_and_unique) OVERRIDE { | 150 virtual void RunImpl(bool nonce_is_valid_and_unique) OVERRIDE { |
| 147 DVLOG(1) << "Using client nonce, unique: " << nonce_is_valid_and_unique; | 151 DVLOG(1) << "Using client nonce, unique: " << nonce_is_valid_and_unique; |
| 148 result_->info.unique = nonce_is_valid_and_unique; | 152 result_->info.unique = nonce_is_valid_and_unique; |
| 153 // TODO(rtenneti): Implement capturing of error from strike register. | |
| 154 // Temporarily treat them as CLIENT_NONCE_UNKNOWN_FAILURE. | |
| 155 if (!nonce_is_valid_and_unique) { | |
| 156 result_->info.reject_reasons.push_back( | |
| 157 static_cast<uint32>(CLIENT_NONCE_UNKNOWN_FAILURE)); | |
|
wtc
2014/06/19 20:04:09
It would be nice to omit the static_cast if the co
ramant (doing other things)
2014/06/20 23:20:47
Fixed in CL: https://codereview.chromium.org/33627
| |
| 158 } | |
| 149 done_cb_->Run(result_); | 159 done_cb_->Run(result_); |
| 150 } | 160 } |
| 151 | 161 |
| 152 private: | 162 private: |
| 153 ValidateClientHelloResultCallback::Result* result_; | 163 ValidateClientHelloResultCallback::Result* result_; |
| 154 ValidateClientHelloResultCallback* done_cb_; | 164 ValidateClientHelloResultCallback* done_cb_; |
| 155 | 165 |
| 156 DISALLOW_COPY_AND_ASSIGN(VerifyNonceIsValidAndUniqueCallback); | 166 DISALLOW_COPY_AND_ASSIGN(VerifyNonceIsValidAndUniqueCallback); |
| 157 }; | 167 }; |
| 158 | 168 |
| (...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 881 | 891 |
| 882 if (client_hello.GetStringPiece(kSNI, &info->sni) && | 892 if (client_hello.GetStringPiece(kSNI, &info->sni) && |
| 883 !CryptoUtils::IsValidSNI(info->sni)) { | 893 !CryptoUtils::IsValidSNI(info->sni)) { |
| 884 helper.ValidationComplete(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, | 894 helper.ValidationComplete(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, |
| 885 "Invalid SNI name"); | 895 "Invalid SNI name"); |
| 886 return; | 896 return; |
| 887 } | 897 } |
| 888 | 898 |
| 889 client_hello.GetStringPiece(kUAID, &info->user_agent_id); | 899 client_hello.GetStringPiece(kUAID, &info->user_agent_id); |
| 890 | 900 |
| 891 StringPiece srct; | 901 if (!requested_config.get()) { |
| 892 if (requested_config.get() != NULL && | 902 StringPiece requested_scid; |
| 893 client_hello.GetStringPiece(kSourceAddressTokenTag, &srct) && | 903 if (client_hello.GetStringPiece(kSCID, &requested_scid)) { |
| 894 ValidateSourceAddressToken(*requested_config, | 904 info->reject_reasons.push_back( |
| 895 srct, | 905 static_cast<uint32>(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE)); |
| 896 info->client_ip, | 906 } else { |
| 897 info->now)) { | 907 info->reject_reasons.push_back( |
| 898 info->valid_source_address_token = true; | 908 static_cast<uint32>(SERVER_CONFIG_INCHOATE_HELLO_FAILURE)); |
| 899 } else { | 909 } |
| 900 // No server config with the requested ID, or no valid source address token. | 910 // No server config with the requested ID. |
| 901 helper.ValidationComplete(QUIC_NO_ERROR, ""); | 911 helper.ValidationComplete(QUIC_NO_ERROR, ""); |
| 902 return; | 912 return; |
| 903 } | 913 } |
| 904 | 914 |
| 915 HandshakeFailureReason source_address_token_error; | |
| 916 StringPiece srct; | |
| 917 if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct)) { | |
| 918 source_address_token_error = | |
| 919 ValidateSourceAddressToken(*requested_config, | |
| 920 srct, | |
| 921 info->client_ip, | |
| 922 info->now); | |
| 923 info->valid_source_address_token = | |
| 924 (source_address_token_error == HANDSHAKE_OK); | |
| 925 } else { | |
| 926 source_address_token_error = SOURCE_ADDRESS_TOKEN_INVALID_FAILURE; | |
| 927 } | |
| 928 | |
| 929 bool found_error = false; | |
| 930 if (source_address_token_error != HANDSHAKE_OK) { | |
| 931 info->reject_reasons.push_back( | |
| 932 static_cast<uint32>(source_address_token_error)); | |
| 933 // No valid source address token. | |
| 934 if (FLAGS_use_early_return_when_verifying_chlo) { | |
| 935 helper.ValidationComplete(QUIC_NO_ERROR, ""); | |
| 936 return; | |
| 937 } | |
| 938 found_error = true; | |
| 939 } | |
| 940 | |
| 905 if (client_hello.GetStringPiece(kNONC, &info->client_nonce) && | 941 if (client_hello.GetStringPiece(kNONC, &info->client_nonce) && |
| 906 info->client_nonce.size() == kNonceSize) { | 942 info->client_nonce.size() == kNonceSize) { |
| 907 info->client_nonce_well_formed = true; | 943 info->client_nonce_well_formed = true; |
| 908 } else { | 944 } else { |
| 945 info->reject_reasons.push_back( | |
| 946 static_cast<uint32>(CLIENT_NONCE_INVALID_FAILURE)); | |
| 909 // Invalid client nonce. | 947 // Invalid client nonce. |
| 910 DVLOG(1) << "Invalid client nonce."; | 948 DVLOG(1) << "Invalid client nonce."; |
| 911 helper.ValidationComplete(QUIC_NO_ERROR, ""); | 949 if (FLAGS_use_early_return_when_verifying_chlo) { |
| 912 return; | 950 helper.ValidationComplete(QUIC_NO_ERROR, ""); |
| 951 return; | |
| 952 } | |
| 953 found_error = true; | |
| 913 } | 954 } |
| 914 | 955 |
| 915 if (!replay_protection_) { | 956 if (!replay_protection_) { |
| 916 info->unique = true; | 957 if (!found_error) { |
| 958 info->unique = true; | |
| 959 } | |
| 917 DVLOG(1) << "No replay protection."; | 960 DVLOG(1) << "No replay protection."; |
| 918 helper.ValidationComplete(QUIC_NO_ERROR, ""); | 961 helper.ValidationComplete(QUIC_NO_ERROR, ""); |
| 919 return; | 962 return; |
| 920 } | 963 } |
| 921 | 964 |
| 922 client_hello.GetStringPiece(kServerNonceTag, &info->server_nonce); | 965 client_hello.GetStringPiece(kServerNonceTag, &info->server_nonce); |
| 923 if (!info->server_nonce.empty()) { | 966 if (!info->server_nonce.empty()) { |
| 924 // If the server nonce is present, use it to establish uniqueness. | 967 // If the server nonce is present, use it to establish uniqueness. |
| 925 info->unique = ValidateServerNonce(info->server_nonce, info->now); | 968 HandshakeFailureReason server_nonce_error = |
| 969 ValidateServerNonce(info->server_nonce, info->now); | |
| 970 if (server_nonce_error == HANDSHAKE_OK) { | |
| 971 info->unique = true; | |
| 972 } else { | |
| 973 info->reject_reasons.push_back(static_cast<uint32>(server_nonce_error)); | |
| 974 info->unique = false; | |
| 975 } | |
| 926 DVLOG(1) << "Using server nonce, unique: " << info->unique; | 976 DVLOG(1) << "Using server nonce, unique: " << info->unique; |
| 927 helper.ValidationComplete(QUIC_NO_ERROR, ""); | 977 helper.ValidationComplete(QUIC_NO_ERROR, ""); |
| 928 return; | 978 return; |
| 929 } | 979 } |
| 930 | 980 |
| 981 // We want to contact strike register if there are no errors because it is | |
|
wtc
2014/06/19 19:58:42
Nit: add "only" before "if".
ramant (doing other things)
2014/06/20 23:20:47
Done.
| |
| 982 // a RPC call and is expensive. | |
| 983 if (found_error) { | |
| 984 helper.ValidationComplete(QUIC_NO_ERROR, ""); | |
| 985 return; | |
| 986 } | |
| 987 | |
| 931 // Use the client nonce to establish uniqueness. | 988 // Use the client nonce to establish uniqueness. |
| 932 StrikeRegisterClient* strike_register_client; | 989 StrikeRegisterClient* strike_register_client; |
| 933 { | 990 { |
| 934 base::AutoLock locked(strike_register_client_lock_); | 991 base::AutoLock locked(strike_register_client_lock_); |
| 935 | 992 |
| 936 if (strike_register_client_.get() == NULL) { | 993 if (strike_register_client_.get() == NULL) { |
| 937 strike_register_client_.reset(new LocalStrikeRegisterClient( | 994 strike_register_client_.reset(new LocalStrikeRegisterClient( |
| 938 strike_register_max_entries_, | 995 strike_register_max_entries_, |
| 939 static_cast<uint32>(info->now.ToUNIXSeconds()), | 996 static_cast<uint32>(info->now.ToUNIXSeconds()), |
| 940 strike_register_window_secs_, | 997 strike_register_window_secs_, |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 964 out->SetStringPiece(kSourceAddressTokenTag, | 1021 out->SetStringPiece(kSourceAddressTokenTag, |
| 965 NewSourceAddressToken( | 1022 NewSourceAddressToken( |
| 966 config, | 1023 config, |
| 967 info.client_ip, | 1024 info.client_ip, |
| 968 rand, | 1025 rand, |
| 969 info.now)); | 1026 info.now)); |
| 970 if (replay_protection_) { | 1027 if (replay_protection_) { |
| 971 out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now)); | 1028 out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now)); |
| 972 } | 1029 } |
| 973 | 1030 |
| 1031 if (FLAGS_send_quic_crypto_reject_reason) { | |
| 1032 // Send client the reject reason for debugging purposes. | |
| 1033 DCHECK_LT(0u, info.reject_reasons.size()); | |
| 1034 out->SetVector(kRREJ, info.reject_reasons); | |
| 1035 } | |
| 1036 | |
| 974 // The client may have requested a certificate chain. | 1037 // The client may have requested a certificate chain. |
| 975 const QuicTag* their_proof_demands; | 1038 const QuicTag* their_proof_demands; |
| 976 size_t num_their_proof_demands; | 1039 size_t num_their_proof_demands; |
| 977 | 1040 |
| 978 if (proof_source_.get() == NULL || | 1041 if (proof_source_.get() == NULL || |
| 979 client_hello.GetTaglist(kPDMD, &their_proof_demands, | 1042 client_hello.GetTaglist(kPDMD, &their_proof_demands, |
| 980 &num_their_proof_demands) != | 1043 &num_their_proof_demands) != |
| 981 QUIC_NO_ERROR) { | 1044 QUIC_NO_ERROR) { |
| 982 return; | 1045 return; |
| 983 } | 1046 } |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1281 if (ip.GetSockAddrFamily() == AF_INET) { | 1344 if (ip.GetSockAddrFamily() == AF_INET) { |
| 1282 ip_address = ConvertIPv4NumberToIPv6Number(ip_address); | 1345 ip_address = ConvertIPv4NumberToIPv6Number(ip_address); |
| 1283 } | 1346 } |
| 1284 source_address_token.set_ip(IPAddressToPackedString(ip_address)); | 1347 source_address_token.set_ip(IPAddressToPackedString(ip_address)); |
| 1285 source_address_token.set_timestamp(now.ToUNIXSeconds()); | 1348 source_address_token.set_timestamp(now.ToUNIXSeconds()); |
| 1286 | 1349 |
| 1287 return config.source_address_token_boxer->Box( | 1350 return config.source_address_token_boxer->Box( |
| 1288 rand, source_address_token.SerializeAsString()); | 1351 rand, source_address_token.SerializeAsString()); |
| 1289 } | 1352 } |
| 1290 | 1353 |
| 1291 bool QuicCryptoServerConfig::ValidateSourceAddressToken( | 1354 HandshakeFailureReason QuicCryptoServerConfig::ValidateSourceAddressToken( |
| 1292 const Config& config, | 1355 const Config& config, |
| 1293 StringPiece token, | 1356 StringPiece token, |
| 1294 const IPEndPoint& ip, | 1357 const IPEndPoint& ip, |
| 1295 QuicWallTime now) const { | 1358 QuicWallTime now) const { |
| 1296 string storage; | 1359 string storage; |
| 1297 StringPiece plaintext; | 1360 StringPiece plaintext; |
| 1298 if (!config.source_address_token_boxer->Unbox(token, &storage, &plaintext)) { | 1361 if (!config.source_address_token_boxer->Unbox(token, &storage, &plaintext)) { |
| 1299 return false; | 1362 return SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE; |
| 1300 } | 1363 } |
| 1301 | 1364 |
| 1302 SourceAddressToken source_address_token; | 1365 SourceAddressToken source_address_token; |
| 1303 if (!source_address_token.ParseFromArray(plaintext.data(), | 1366 if (!source_address_token.ParseFromArray(plaintext.data(), |
| 1304 plaintext.size())) { | 1367 plaintext.size())) { |
| 1305 return false; | 1368 return SOURCE_ADDRESS_TOKEN_PARSE_FAILURE; |
| 1306 } | 1369 } |
| 1307 | 1370 |
| 1308 IPAddressNumber ip_address = ip.address(); | 1371 IPAddressNumber ip_address = ip.address(); |
| 1309 if (ip.GetSockAddrFamily() == AF_INET) { | 1372 if (ip.GetSockAddrFamily() == AF_INET) { |
| 1310 ip_address = ConvertIPv4NumberToIPv6Number(ip_address); | 1373 ip_address = ConvertIPv4NumberToIPv6Number(ip_address); |
| 1311 } | 1374 } |
| 1312 if (source_address_token.ip() != IPAddressToPackedString(ip_address)) { | 1375 if (source_address_token.ip() != IPAddressToPackedString(ip_address)) { |
| 1313 // It's for a different IP address. | 1376 // It's for a different IP address. |
| 1314 return false; | 1377 return SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE; |
| 1315 } | 1378 } |
| 1316 | 1379 |
| 1317 const QuicWallTime timestamp( | 1380 const QuicWallTime timestamp( |
| 1318 QuicWallTime::FromUNIXSeconds(source_address_token.timestamp())); | 1381 QuicWallTime::FromUNIXSeconds(source_address_token.timestamp())); |
| 1319 const QuicTime::Delta delta(now.AbsoluteDifference(timestamp)); | 1382 const QuicTime::Delta delta(now.AbsoluteDifference(timestamp)); |
| 1320 | 1383 |
| 1321 if (now.IsBefore(timestamp) && | 1384 if (now.IsBefore(timestamp) && |
| 1322 delta.ToSeconds() > source_address_token_future_secs_) { | 1385 delta.ToSeconds() > source_address_token_future_secs_) { |
| 1323 return false; | 1386 return SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE; |
| 1324 } | 1387 } |
| 1325 | 1388 |
| 1326 if (now.IsAfter(timestamp) && | 1389 if (now.IsAfter(timestamp) && |
| 1327 delta.ToSeconds() > source_address_token_lifetime_secs_) { | 1390 delta.ToSeconds() > source_address_token_lifetime_secs_) { |
| 1328 return false; | 1391 return SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE; |
| 1329 } | 1392 } |
| 1330 | 1393 |
| 1331 return true; | 1394 return HANDSHAKE_OK; |
| 1332 } | 1395 } |
| 1333 | 1396 |
| 1334 // kServerNoncePlaintextSize is the number of bytes in an unencrypted server | 1397 // kServerNoncePlaintextSize is the number of bytes in an unencrypted server |
| 1335 // nonce. | 1398 // nonce. |
| 1336 static const size_t kServerNoncePlaintextSize = | 1399 static const size_t kServerNoncePlaintextSize = |
| 1337 4 /* timestamp */ + 20 /* random bytes */; | 1400 4 /* timestamp */ + 20 /* random bytes */; |
| 1338 | 1401 |
| 1339 string QuicCryptoServerConfig::NewServerNonce(QuicRandom* rand, | 1402 string QuicCryptoServerConfig::NewServerNonce(QuicRandom* rand, |
| 1340 QuicWallTime now) const { | 1403 QuicWallTime now) const { |
| 1341 const uint32 timestamp = static_cast<uint32>(now.ToUNIXSeconds()); | 1404 const uint32 timestamp = static_cast<uint32>(now.ToUNIXSeconds()); |
| 1342 | 1405 |
| 1343 uint8 server_nonce[kServerNoncePlaintextSize]; | 1406 uint8 server_nonce[kServerNoncePlaintextSize]; |
| 1344 COMPILE_ASSERT(sizeof(server_nonce) > sizeof(timestamp), nonce_too_small); | 1407 COMPILE_ASSERT(sizeof(server_nonce) > sizeof(timestamp), nonce_too_small); |
| 1345 server_nonce[0] = static_cast<uint8>(timestamp >> 24); | 1408 server_nonce[0] = static_cast<uint8>(timestamp >> 24); |
| 1346 server_nonce[1] = static_cast<uint8>(timestamp >> 16); | 1409 server_nonce[1] = static_cast<uint8>(timestamp >> 16); |
| 1347 server_nonce[2] = static_cast<uint8>(timestamp >> 8); | 1410 server_nonce[2] = static_cast<uint8>(timestamp >> 8); |
| 1348 server_nonce[3] = static_cast<uint8>(timestamp); | 1411 server_nonce[3] = static_cast<uint8>(timestamp); |
| 1349 rand->RandBytes(&server_nonce[sizeof(timestamp)], | 1412 rand->RandBytes(&server_nonce[sizeof(timestamp)], |
| 1350 sizeof(server_nonce) - sizeof(timestamp)); | 1413 sizeof(server_nonce) - sizeof(timestamp)); |
| 1351 | 1414 |
| 1352 return server_nonce_boxer_.Box( | 1415 return server_nonce_boxer_.Box( |
| 1353 rand, | 1416 rand, |
| 1354 StringPiece(reinterpret_cast<char*>(server_nonce), sizeof(server_nonce))); | 1417 StringPiece(reinterpret_cast<char*>(server_nonce), sizeof(server_nonce))); |
| 1355 } | 1418 } |
| 1356 | 1419 |
| 1357 bool QuicCryptoServerConfig::ValidateServerNonce(StringPiece token, | 1420 HandshakeFailureReason QuicCryptoServerConfig::ValidateServerNonce( |
| 1358 QuicWallTime now) const { | 1421 StringPiece token, |
| 1422 QuicWallTime now) const { | |
| 1359 string storage; | 1423 string storage; |
| 1360 StringPiece plaintext; | 1424 StringPiece plaintext; |
| 1361 if (!server_nonce_boxer_.Unbox(token, &storage, &plaintext)) { | 1425 if (!server_nonce_boxer_.Unbox(token, &storage, &plaintext)) { |
| 1362 return false; | 1426 return SERVER_NONCE_DECRYPTION_FAILURE; |
| 1363 } | 1427 } |
| 1364 | 1428 |
| 1365 // plaintext contains: | 1429 // plaintext contains: |
| 1366 // uint32 timestamp | 1430 // uint32 timestamp |
| 1367 // uint8[20] random bytes | 1431 // uint8[20] random bytes |
| 1368 | 1432 |
| 1369 if (plaintext.size() != kServerNoncePlaintextSize) { | 1433 if (plaintext.size() != kServerNoncePlaintextSize) { |
| 1370 // This should never happen because the value decrypted correctly. | 1434 // This should never happen because the value decrypted correctly. |
| 1371 LOG(DFATAL) << "Seemingly valid server nonce had incorrect length."; | 1435 LOG(DFATAL) << "Seemingly valid server nonce had incorrect length."; |
| 1372 return false; | 1436 return SERVER_NONCE_INVALID_FAILURE; |
| 1373 } | 1437 } |
| 1374 | 1438 |
| 1375 uint8 server_nonce[32]; | 1439 uint8 server_nonce[32]; |
| 1376 memcpy(server_nonce, plaintext.data(), 4); | 1440 memcpy(server_nonce, plaintext.data(), 4); |
| 1377 memcpy(server_nonce + 4, server_nonce_orbit_, sizeof(server_nonce_orbit_)); | 1441 memcpy(server_nonce + 4, server_nonce_orbit_, sizeof(server_nonce_orbit_)); |
| 1378 memcpy(server_nonce + 4 + sizeof(server_nonce_orbit_), plaintext.data() + 4, | 1442 memcpy(server_nonce + 4 + sizeof(server_nonce_orbit_), plaintext.data() + 4, |
| 1379 20); | 1443 20); |
| 1380 COMPILE_ASSERT(4 + sizeof(server_nonce_orbit_) + 20 == sizeof(server_nonce), | 1444 COMPILE_ASSERT(4 + sizeof(server_nonce_orbit_) + 20 == sizeof(server_nonce), |
| 1381 bad_nonce_buffer_length); | 1445 bad_nonce_buffer_length); |
| 1382 | 1446 |
| 1383 bool is_unique; | 1447 bool is_unique; |
| 1384 { | 1448 { |
| 1385 base::AutoLock auto_lock(server_nonce_strike_register_lock_); | 1449 base::AutoLock auto_lock(server_nonce_strike_register_lock_); |
| 1386 if (server_nonce_strike_register_.get() == NULL) { | 1450 if (server_nonce_strike_register_.get() == NULL) { |
| 1387 server_nonce_strike_register_.reset(new StrikeRegister( | 1451 server_nonce_strike_register_.reset(new StrikeRegister( |
| 1388 server_nonce_strike_register_max_entries_, | 1452 server_nonce_strike_register_max_entries_, |
| 1389 static_cast<uint32>(now.ToUNIXSeconds()), | 1453 static_cast<uint32>(now.ToUNIXSeconds()), |
| 1390 server_nonce_strike_register_window_secs_, server_nonce_orbit_, | 1454 server_nonce_strike_register_window_secs_, server_nonce_orbit_, |
| 1391 StrikeRegister::NO_STARTUP_PERIOD_NEEDED)); | 1455 StrikeRegister::NO_STARTUP_PERIOD_NEEDED)); |
| 1392 } | 1456 } |
| 1393 is_unique = server_nonce_strike_register_->Insert( | 1457 is_unique = server_nonce_strike_register_->Insert( |
| 1394 server_nonce, static_cast<uint32>(now.ToUNIXSeconds())); | 1458 server_nonce, static_cast<uint32>(now.ToUNIXSeconds())); |
| 1395 } | 1459 } |
| 1396 | 1460 |
| 1397 return is_unique; | 1461 return is_unique ? HANDSHAKE_OK : SERVER_NONCE_NOT_UNIQUE_FAILURE; |
| 1398 } | 1462 } |
| 1399 | 1463 |
| 1400 QuicCryptoServerConfig::Config::Config() | 1464 QuicCryptoServerConfig::Config::Config() |
| 1401 : channel_id_enabled(false), | 1465 : channel_id_enabled(false), |
| 1402 is_primary(false), | 1466 is_primary(false), |
| 1403 primary_time(QuicWallTime::Zero()), | 1467 primary_time(QuicWallTime::Zero()), |
| 1404 priority(0), | 1468 priority(0), |
| 1405 source_address_token_boxer(NULL) {} | 1469 source_address_token_boxer(NULL) {} |
| 1406 | 1470 |
| 1407 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); } | 1471 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); } |
| 1408 | 1472 |
| 1409 } // namespace net | 1473 } // namespace net |
| OLD | NEW |