| 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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 bool valid_source_address_token; | 78 bool valid_source_address_token; |
| 79 bool client_nonce_well_formed; | 79 bool client_nonce_well_formed; |
| 80 bool unique; | 80 bool unique; |
| 81 StringPiece sni; | 81 StringPiece sni; |
| 82 StringPiece client_nonce; | 82 StringPiece client_nonce; |
| 83 StringPiece server_nonce; | 83 StringPiece server_nonce; |
| 84 StringPiece user_agent_id; | 84 StringPiece user_agent_id; |
| 85 | 85 |
| 86 // Errors from EvaluateClientHello. | 86 // Errors from EvaluateClientHello. |
| 87 vector<uint32> reject_reasons; | 87 vector<uint32> reject_reasons; |
| 88 COMPILE_ASSERT(sizeof(QuicTag) == sizeof(uint32), header_out_of_sync); |
| 88 }; | 89 }; |
| 89 | 90 |
| 90 struct ValidateClientHelloResultCallback::Result { | 91 struct ValidateClientHelloResultCallback::Result { |
| 91 Result(const CryptoHandshakeMessage& in_client_hello, | 92 Result(const CryptoHandshakeMessage& in_client_hello, |
| 92 IPEndPoint in_client_ip, | 93 IPEndPoint in_client_ip, |
| 93 QuicWallTime in_now) | 94 QuicWallTime in_now) |
| 94 : client_hello(in_client_hello), | 95 : client_hello(in_client_hello), |
| 95 info(in_client_ip, in_now), | 96 info(in_client_ip, in_now), |
| 96 error_code(QUIC_NO_ERROR) { | 97 error_code(QUIC_NO_ERROR) { |
| 97 } | 98 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 : result_(result), done_cb_(done_cb) { | 147 : result_(result), done_cb_(done_cb) { |
| 147 } | 148 } |
| 148 | 149 |
| 149 protected: | 150 protected: |
| 150 virtual void RunImpl(bool nonce_is_valid_and_unique) OVERRIDE { | 151 virtual void RunImpl(bool nonce_is_valid_and_unique) OVERRIDE { |
| 151 DVLOG(1) << "Using client nonce, unique: " << nonce_is_valid_and_unique; | 152 DVLOG(1) << "Using client nonce, unique: " << nonce_is_valid_and_unique; |
| 152 result_->info.unique = nonce_is_valid_and_unique; | 153 result_->info.unique = nonce_is_valid_and_unique; |
| 153 // TODO(rtenneti): Implement capturing of error from strike register. | 154 // TODO(rtenneti): Implement capturing of error from strike register. |
| 154 // Temporarily treat them as CLIENT_NONCE_UNKNOWN_FAILURE. | 155 // Temporarily treat them as CLIENT_NONCE_UNKNOWN_FAILURE. |
| 155 if (!nonce_is_valid_and_unique) { | 156 if (!nonce_is_valid_and_unique) { |
| 156 result_->info.reject_reasons.push_back( | 157 result_->info.reject_reasons.push_back(CLIENT_NONCE_UNKNOWN_FAILURE); |
| 157 static_cast<uint32>(CLIENT_NONCE_UNKNOWN_FAILURE)); | |
| 158 } | 158 } |
| 159 done_cb_->Run(result_); | 159 done_cb_->Run(result_); |
| 160 } | 160 } |
| 161 | 161 |
| 162 private: | 162 private: |
| 163 ValidateClientHelloResultCallback::Result* result_; | 163 ValidateClientHelloResultCallback::Result* result_; |
| 164 ValidateClientHelloResultCallback* done_cb_; | 164 ValidateClientHelloResultCallback* done_cb_; |
| 165 | 165 |
| 166 DISALLOW_COPY_AND_ASSIGN(VerifyNonceIsValidAndUniqueCallback); | 166 DISALLOW_COPY_AND_ASSIGN(VerifyNonceIsValidAndUniqueCallback); |
| 167 }; | 167 }; |
| (...skipping 726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 894 helper.ValidationComplete(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, | 894 helper.ValidationComplete(QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER, |
| 895 "Invalid SNI name"); | 895 "Invalid SNI name"); |
| 896 return; | 896 return; |
| 897 } | 897 } |
| 898 | 898 |
| 899 client_hello.GetStringPiece(kUAID, &info->user_agent_id); | 899 client_hello.GetStringPiece(kUAID, &info->user_agent_id); |
| 900 | 900 |
| 901 if (!requested_config.get()) { | 901 if (!requested_config.get()) { |
| 902 StringPiece requested_scid; | 902 StringPiece requested_scid; |
| 903 if (client_hello.GetStringPiece(kSCID, &requested_scid)) { | 903 if (client_hello.GetStringPiece(kSCID, &requested_scid)) { |
| 904 info->reject_reasons.push_back( | 904 info->reject_reasons.push_back(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE); |
| 905 static_cast<uint32>(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE)); | |
| 906 } else { | 905 } else { |
| 907 info->reject_reasons.push_back( | 906 info->reject_reasons.push_back(SERVER_CONFIG_INCHOATE_HELLO_FAILURE); |
| 908 static_cast<uint32>(SERVER_CONFIG_INCHOATE_HELLO_FAILURE)); | |
| 909 } | 907 } |
| 910 // No server config with the requested ID. | 908 // No server config with the requested ID. |
| 911 helper.ValidationComplete(QUIC_NO_ERROR, ""); | 909 helper.ValidationComplete(QUIC_NO_ERROR, ""); |
| 912 return; | 910 return; |
| 913 } | 911 } |
| 914 | 912 |
| 915 HandshakeFailureReason source_address_token_error; | 913 HandshakeFailureReason source_address_token_error; |
| 916 StringPiece srct; | 914 StringPiece srct; |
| 917 if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct)) { | 915 if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct)) { |
| 918 source_address_token_error = | 916 source_address_token_error = |
| 919 ValidateSourceAddressToken(*requested_config, | 917 ValidateSourceAddressToken(*requested_config, |
| 920 srct, | 918 srct, |
| 921 info->client_ip, | 919 info->client_ip, |
| 922 info->now); | 920 info->now); |
| 923 info->valid_source_address_token = | 921 info->valid_source_address_token = |
| 924 (source_address_token_error == HANDSHAKE_OK); | 922 (source_address_token_error == HANDSHAKE_OK); |
| 925 } else { | 923 } else { |
| 926 source_address_token_error = SOURCE_ADDRESS_TOKEN_INVALID_FAILURE; | 924 source_address_token_error = SOURCE_ADDRESS_TOKEN_INVALID_FAILURE; |
| 927 } | 925 } |
| 928 | 926 |
| 929 bool found_error = false; | 927 bool found_error = false; |
| 930 if (source_address_token_error != HANDSHAKE_OK) { | 928 if (source_address_token_error != HANDSHAKE_OK) { |
| 931 info->reject_reasons.push_back( | 929 info->reject_reasons.push_back(source_address_token_error); |
| 932 static_cast<uint32>(source_address_token_error)); | |
| 933 // No valid source address token. | 930 // No valid source address token. |
| 934 if (FLAGS_use_early_return_when_verifying_chlo) { | 931 if (FLAGS_use_early_return_when_verifying_chlo) { |
| 935 helper.ValidationComplete(QUIC_NO_ERROR, ""); | 932 helper.ValidationComplete(QUIC_NO_ERROR, ""); |
| 936 return; | 933 return; |
| 937 } | 934 } |
| 938 found_error = true; | 935 found_error = true; |
| 939 } | 936 } |
| 940 | 937 |
| 941 if (client_hello.GetStringPiece(kNONC, &info->client_nonce) && | 938 if (client_hello.GetStringPiece(kNONC, &info->client_nonce) && |
| 942 info->client_nonce.size() == kNonceSize) { | 939 info->client_nonce.size() == kNonceSize) { |
| 943 info->client_nonce_well_formed = true; | 940 info->client_nonce_well_formed = true; |
| 944 } else { | 941 } else { |
| 945 info->reject_reasons.push_back( | 942 info->reject_reasons.push_back(CLIENT_NONCE_INVALID_FAILURE); |
| 946 static_cast<uint32>(CLIENT_NONCE_INVALID_FAILURE)); | |
| 947 // Invalid client nonce. | 943 // Invalid client nonce. |
| 948 DVLOG(1) << "Invalid client nonce."; | 944 DVLOG(1) << "Invalid client nonce."; |
| 949 if (FLAGS_use_early_return_when_verifying_chlo) { | 945 if (FLAGS_use_early_return_when_verifying_chlo) { |
| 950 helper.ValidationComplete(QUIC_NO_ERROR, ""); | 946 helper.ValidationComplete(QUIC_NO_ERROR, ""); |
| 951 return; | 947 return; |
| 952 } | 948 } |
| 953 found_error = true; | 949 found_error = true; |
| 954 } | 950 } |
| 955 | 951 |
| 956 if (!replay_protection_) { | 952 if (!replay_protection_) { |
| 957 if (!found_error) { | 953 if (!found_error) { |
| 958 info->unique = true; | 954 info->unique = true; |
| 959 } | 955 } |
| 960 DVLOG(1) << "No replay protection."; | 956 DVLOG(1) << "No replay protection."; |
| 961 helper.ValidationComplete(QUIC_NO_ERROR, ""); | 957 helper.ValidationComplete(QUIC_NO_ERROR, ""); |
| 962 return; | 958 return; |
| 963 } | 959 } |
| 964 | 960 |
| 965 client_hello.GetStringPiece(kServerNonceTag, &info->server_nonce); | 961 client_hello.GetStringPiece(kServerNonceTag, &info->server_nonce); |
| 966 if (!info->server_nonce.empty()) { | 962 if (!info->server_nonce.empty()) { |
| 967 // If the server nonce is present, use it to establish uniqueness. | 963 // If the server nonce is present, use it to establish uniqueness. |
| 968 HandshakeFailureReason server_nonce_error = | 964 HandshakeFailureReason server_nonce_error = |
| 969 ValidateServerNonce(info->server_nonce, info->now); | 965 ValidateServerNonce(info->server_nonce, info->now); |
| 970 if (server_nonce_error == HANDSHAKE_OK) { | 966 if (server_nonce_error == HANDSHAKE_OK) { |
| 971 info->unique = true; | 967 info->unique = true; |
| 972 } else { | 968 } else { |
| 973 info->reject_reasons.push_back(static_cast<uint32>(server_nonce_error)); | 969 info->reject_reasons.push_back(server_nonce_error); |
| 974 info->unique = false; | 970 info->unique = false; |
| 975 } | 971 } |
| 976 DVLOG(1) << "Using server nonce, unique: " << info->unique; | 972 DVLOG(1) << "Using server nonce, unique: " << info->unique; |
| 977 helper.ValidationComplete(QUIC_NO_ERROR, ""); | 973 helper.ValidationComplete(QUIC_NO_ERROR, ""); |
| 978 return; | 974 return; |
| 979 } | 975 } |
| 980 | 976 |
| 981 // We want to contact strike register if there are no errors because it is | 977 // We want to contact strike register only if there are no errors because it |
| 982 // a RPC call and is expensive. | 978 // is a RPC call and is expensive. |
| 983 if (found_error) { | 979 if (found_error) { |
| 984 helper.ValidationComplete(QUIC_NO_ERROR, ""); | 980 helper.ValidationComplete(QUIC_NO_ERROR, ""); |
| 985 return; | 981 return; |
| 986 } | 982 } |
| 987 | 983 |
| 988 // Use the client nonce to establish uniqueness. | 984 // Use the client nonce to establish uniqueness. |
| 989 StrikeRegisterClient* strike_register_client; | 985 StrikeRegisterClient* strike_register_client; |
| 990 { | 986 { |
| 991 base::AutoLock locked(strike_register_client_lock_); | 987 base::AutoLock locked(strike_register_client_lock_); |
| 992 | 988 |
| (...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1464 QuicCryptoServerConfig::Config::Config() | 1460 QuicCryptoServerConfig::Config::Config() |
| 1465 : channel_id_enabled(false), | 1461 : channel_id_enabled(false), |
| 1466 is_primary(false), | 1462 is_primary(false), |
| 1467 primary_time(QuicWallTime::Zero()), | 1463 primary_time(QuicWallTime::Zero()), |
| 1468 priority(0), | 1464 priority(0), |
| 1469 source_address_token_boxer(NULL) {} | 1465 source_address_token_boxer(NULL) {} |
| 1470 | 1466 |
| 1471 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); } | 1467 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); } |
| 1472 | 1468 |
| 1473 } // namespace net | 1469 } // namespace net |
| OLD | NEW |