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

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

Issue 822713002: Update from https://crrev.com/309415 (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 12 months 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/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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 using crypto::SecureHash; 43 using crypto::SecureHash;
44 using std::map; 44 using std::map;
45 using std::sort; 45 using std::sort;
46 using std::string; 46 using std::string;
47 using std::vector; 47 using std::vector;
48 48
49 namespace net { 49 namespace net {
50 50
51 namespace { 51 namespace {
52 52
53 const size_t kMaxTokenAddresses = 4;
54
53 string DeriveSourceAddressTokenKey(StringPiece source_address_token_secret) { 55 string DeriveSourceAddressTokenKey(StringPiece source_address_token_secret) {
54 crypto::HKDF hkdf(source_address_token_secret, 56 crypto::HKDF hkdf(source_address_token_secret,
55 StringPiece() /* no salt */, 57 StringPiece() /* no salt */,
56 "QUIC source address token key", 58 "QUIC source address token key",
57 CryptoSecretBoxer::GetKeySize(), 59 CryptoSecretBoxer::GetKeySize(),
58 0 /* no fixed IV needed */, 60 0 /* no fixed IV needed */,
59 0 /* no subkey secret */); 61 0 /* no subkey secret */);
60 return hkdf.server_write_key().as_string(); 62 return hkdf.server_write_key().as_string();
61 } 63 }
62 64
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED; 760 return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED;
759 } 761 }
760 762
761 out->set_tag(kSHLO); 763 out->set_tag(kSHLO);
762 QuicTagVector supported_version_tags; 764 QuicTagVector supported_version_tags;
763 for (size_t i = 0; i < supported_versions.size(); ++i) { 765 for (size_t i = 0; i < supported_versions.size(); ++i) {
764 supported_version_tags.push_back 766 supported_version_tags.push_back
765 (QuicVersionToQuicTag(supported_versions[i])); 767 (QuicVersionToQuicTag(supported_versions[i]));
766 } 768 }
767 out->SetVector(kVER, supported_version_tags); 769 out->SetVector(kVER, supported_version_tags);
768 out->SetStringPiece(kSourceAddressTokenTag, 770 out->SetStringPiece(
769 NewSourceAddressToken(*requested_config.get(), 771 kSourceAddressTokenTag,
770 client_address, 772 NewSourceAddressToken(*requested_config.get(), info.source_address_tokens,
771 rand, 773 client_address, rand, info.now, nullptr));
772 info.now,
773 nullptr));
774 QuicSocketAddressCoder address_coder(client_address); 774 QuicSocketAddressCoder address_coder(client_address);
775 out->SetStringPiece(kCADR, address_coder.Encode()); 775 out->SetStringPiece(kCADR, address_coder.Encode());
776 out->SetStringPiece(kPUBS, forward_secure_public_value); 776 out->SetStringPiece(kPUBS, forward_secure_public_value);
777 777
778 return QUIC_NO_ERROR; 778 return QUIC_NO_ERROR;
779 } 779 }
780 780
781 scoped_refptr<QuicCryptoServerConfig::Config> 781 scoped_refptr<QuicCryptoServerConfig::Config>
782 QuicCryptoServerConfig::GetConfigWithScid(StringPiece requested_scid) const { 782 QuicCryptoServerConfig::GetConfigWithScid(StringPiece requested_scid) const {
783 // In Chromium, we will dead lock if the lock is held by the current thread. 783 // In Chromium, we will dead lock if the lock is held by the current thread.
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
933 info->reject_reasons.push_back(SERVER_CONFIG_INCHOATE_HELLO_FAILURE); 933 info->reject_reasons.push_back(SERVER_CONFIG_INCHOATE_HELLO_FAILURE);
934 } 934 }
935 // No server config with the requested ID. 935 // No server config with the requested ID.
936 helper.ValidationComplete(QUIC_NO_ERROR, ""); 936 helper.ValidationComplete(QUIC_NO_ERROR, "");
937 return; 937 return;
938 } 938 }
939 939
940 HandshakeFailureReason source_address_token_error; 940 HandshakeFailureReason source_address_token_error;
941 StringPiece srct; 941 StringPiece srct;
942 if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct)) { 942 if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct)) {
943 source_address_token_error = 943 if (!FLAGS_quic_use_multiple_address_in_source_tokens) {
944 ValidateSourceAddressToken(*requested_config.get(), 944 source_address_token_error = ValidateSourceAddressToken(
945 srct, 945 *requested_config.get(), srct, info->client_ip, info->now,
946 info->client_ip, 946 &client_hello_state->cached_network_params);
947 info->now, 947 } else {
948 &client_hello_state->cached_network_params); 948 source_address_token_error = ParseSourceAddressToken(
949 *requested_config.get(), srct, &info->source_address_tokens);
950
951 if (source_address_token_error == HANDSHAKE_OK) {
952 source_address_token_error = ValidateSourceAddressTokens(
953 info->source_address_tokens, info->client_ip, info->now,
954 &client_hello_state->cached_network_params);
955 }
956 }
949 info->valid_source_address_token = 957 info->valid_source_address_token =
950 (source_address_token_error == HANDSHAKE_OK); 958 (source_address_token_error == HANDSHAKE_OK);
951 } else { 959 } else {
952 source_address_token_error = SOURCE_ADDRESS_TOKEN_INVALID_FAILURE; 960 source_address_token_error = SOURCE_ADDRESS_TOKEN_INVALID_FAILURE;
953 } 961 }
954 962
955 bool found_error = false; 963 bool found_error = false;
956 if (source_address_token_error != HANDSHAKE_OK) { 964 if (source_address_token_error != HANDSHAKE_OK) {
957 info->reject_reasons.push_back(source_address_token_error); 965 info->reject_reasons.push_back(source_address_token_error);
958 // No valid source address token. 966 // No valid source address token.
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1028 } 1036 }
1029 1037
1030 strike_register_client->VerifyNonceIsValidAndUnique( 1038 strike_register_client->VerifyNonceIsValidAndUnique(
1031 info->client_nonce, 1039 info->client_nonce,
1032 info->now, 1040 info->now,
1033 new VerifyNonceIsValidAndUniqueCallback(client_hello_state, done_cb)); 1041 new VerifyNonceIsValidAndUniqueCallback(client_hello_state, done_cb));
1034 helper.StartedAsyncCallback(); 1042 helper.StartedAsyncCallback();
1035 } 1043 }
1036 1044
1037 bool QuicCryptoServerConfig::BuildServerConfigUpdateMessage( 1045 bool QuicCryptoServerConfig::BuildServerConfigUpdateMessage(
1046 const SourceAddressTokens& previous_source_address_tokens,
1038 const IPEndPoint& server_ip, 1047 const IPEndPoint& server_ip,
1039 const IPEndPoint& client_ip, 1048 const IPEndPoint& client_ip,
1040 const QuicClock* clock, 1049 const QuicClock* clock,
1041 QuicRandom* rand, 1050 QuicRandom* rand,
1042 const QuicCryptoNegotiatedParameters& params, 1051 const QuicCryptoNegotiatedParameters& params,
1043 const CachedNetworkParameters* cached_network_params, 1052 const CachedNetworkParameters* cached_network_params,
1044 CryptoHandshakeMessage* out) const { 1053 CryptoHandshakeMessage* out) const {
1045 base::AutoLock locked(configs_lock_); 1054 base::AutoLock locked(configs_lock_);
1046 out->set_tag(kSCUP); 1055 out->set_tag(kSCUP);
1047 out->SetStringPiece(kSCFG, primary_config_->serialized); 1056 out->SetStringPiece(kSCFG, primary_config_->serialized);
1048 out->SetStringPiece(kSourceAddressTokenTag, 1057 out->SetStringPiece(
1049 NewSourceAddressToken(*primary_config_.get(), 1058 kSourceAddressTokenTag,
1050 client_ip, 1059 NewSourceAddressToken(*primary_config_.get(),
1051 rand, 1060 previous_source_address_tokens, client_ip, rand,
1052 clock->WallNow(), 1061 clock->WallNow(), cached_network_params));
1053 cached_network_params));
1054 1062
1055 if (proof_source_ == nullptr) { 1063 if (proof_source_ == nullptr) {
1056 // Insecure QUIC, can send SCFG without proof. 1064 // Insecure QUIC, can send SCFG without proof.
1057 return true; 1065 return true;
1058 } 1066 }
1059 1067
1060 const vector<string>* certs; 1068 const vector<string>* certs;
1061 string signature; 1069 string signature;
1062 if (!proof_source_->GetProof( 1070 if (!proof_source_->GetProof(
1063 server_ip, params.sni, primary_config_->serialized, 1071 server_ip, params.sni, primary_config_->serialized,
(...skipping 15 matching lines...) Expand all
1079 const IPEndPoint& server_ip, 1087 const IPEndPoint& server_ip,
1080 const Config& config, 1088 const Config& config,
1081 const CryptoHandshakeMessage& client_hello, 1089 const CryptoHandshakeMessage& client_hello,
1082 const ClientHelloInfo& info, 1090 const ClientHelloInfo& info,
1083 const CachedNetworkParameters& cached_network_params, 1091 const CachedNetworkParameters& cached_network_params,
1084 QuicRandom* rand, 1092 QuicRandom* rand,
1085 QuicCryptoNegotiatedParameters* params, 1093 QuicCryptoNegotiatedParameters* params,
1086 CryptoHandshakeMessage* out) const { 1094 CryptoHandshakeMessage* out) const {
1087 out->set_tag(kREJ); 1095 out->set_tag(kREJ);
1088 out->SetStringPiece(kSCFG, config.serialized); 1096 out->SetStringPiece(kSCFG, config.serialized);
1089 out->SetStringPiece(kSourceAddressTokenTag, 1097 out->SetStringPiece(
1090 NewSourceAddressToken( 1098 kSourceAddressTokenTag,
1091 config, 1099 NewSourceAddressToken(config, info.source_address_tokens, info.client_ip,
1092 info.client_ip, 1100 rand, info.now, &cached_network_params));
1093 rand,
1094 info.now,
1095 &cached_network_params));
1096 if (replay_protection_) { 1101 if (replay_protection_) {
1097 out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now)); 1102 out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now));
1098 } 1103 }
1099 1104
1100 if (FLAGS_send_quic_crypto_reject_reason) { 1105 if (FLAGS_send_quic_crypto_reject_reason) {
1101 // Send client the reject reason for debugging purposes. 1106 // Send client the reject reason for debugging purposes.
1102 DCHECK_LT(0u, info.reject_reasons.size()); 1107 DCHECK_LT(0u, info.reject_reasons.size());
1103 out->SetVector(kRREJ, info.reject_reasons); 1108 out->SetVector(kRREJ, info.reject_reasons);
1104 } 1109 }
1105 1110
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
1405 } 1410 }
1406 1411
1407 void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb( 1412 void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb(
1408 PrimaryConfigChangedCallback* cb) { 1413 PrimaryConfigChangedCallback* cb) {
1409 base::AutoLock locked(configs_lock_); 1414 base::AutoLock locked(configs_lock_);
1410 primary_config_changed_cb_.reset(cb); 1415 primary_config_changed_cb_.reset(cb);
1411 } 1416 }
1412 1417
1413 string QuicCryptoServerConfig::NewSourceAddressToken( 1418 string QuicCryptoServerConfig::NewSourceAddressToken(
1414 const Config& config, 1419 const Config& config,
1420 const SourceAddressTokens& previous_tokens,
1415 const IPEndPoint& ip, 1421 const IPEndPoint& ip,
1416 QuicRandom* rand, 1422 QuicRandom* rand,
1417 QuicWallTime now, 1423 QuicWallTime now,
1418 const CachedNetworkParameters* cached_network_params) const { 1424 const CachedNetworkParameters* cached_network_params) const {
1419 IPAddressNumber ip_address = ip.address(); 1425 IPAddressNumber ip_address = ip.address();
1420 if (ip.GetSockAddrFamily() == AF_INET) { 1426 if (ip.GetSockAddrFamily() == AF_INET) {
1421 ip_address = ConvertIPv4NumberToIPv6Number(ip_address); 1427 ip_address = ConvertIPv4NumberToIPv6Number(ip_address);
1422 } 1428 }
1423 SourceAddressToken source_address_token; 1429 SourceAddressTokens source_address_tokens;
1424 source_address_token.set_ip(IPAddressToPackedString(ip_address)); 1430 SourceAddressToken* source_address_token = source_address_tokens.add_tokens();
1425 source_address_token.set_timestamp(now.ToUNIXSeconds()); 1431 source_address_token->set_ip(IPAddressToPackedString(ip_address));
1432 source_address_token->set_timestamp(now.ToUNIXSeconds());
1426 if (cached_network_params != nullptr) { 1433 if (cached_network_params != nullptr) {
1427 source_address_token.set_cached_network_parameters(*cached_network_params); 1434 *(source_address_token->mutable_cached_network_parameters()) =
1435 *cached_network_params;
1436 }
1437
1438 if (!FLAGS_quic_use_multiple_address_in_source_tokens) {
1439 return config.source_address_token_boxer->Box(
1440 rand, source_address_token->SerializeAsString());
1441 }
1442
1443 // Append previous tokens.
1444 for (size_t i = 0; i < previous_tokens.tokens_size(); i++) {
1445 const SourceAddressToken& token = previous_tokens.tokens(i);
1446 if (source_address_tokens.tokens_size() > kMaxTokenAddresses) {
1447 break;
1448 }
1449
1450 if (token.ip() == source_address_token->ip()) {
1451 // It's for the same IP address.
1452 continue;
1453 }
1454
1455 if (ValidateSourceAddressTokenTimestamp(token, now) != HANDSHAKE_OK) {
1456 continue;
1457 }
1458
1459 *(source_address_tokens.add_tokens()) = token;
1428 } 1460 }
1429 1461
1430 return config.source_address_token_boxer->Box( 1462 return config.source_address_token_boxer->Box(
1431 rand, source_address_token.SerializeAsString()); 1463 rand, source_address_tokens.SerializeAsString());
1432 } 1464 }
1433 1465
1434 bool QuicCryptoServerConfig::HasProofSource() const { 1466 bool QuicCryptoServerConfig::HasProofSource() const {
1435 return proof_source_ != nullptr; 1467 return proof_source_ != nullptr;
1436 } 1468 }
1437 1469
1470 HandshakeFailureReason QuicCryptoServerConfig::ParseSourceAddressToken(
1471 const Config& config,
1472 StringPiece token,
1473 SourceAddressTokens* tokens) const {
1474 string storage;
1475 StringPiece plaintext;
1476 if (!config.source_address_token_boxer->Unbox(token, &storage, &plaintext)) {
1477 return SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE;
1478 }
1479
1480 if (!FLAGS_quic_use_multiple_address_in_source_tokens) {
1481 SourceAddressToken token;
1482 if (!token.ParseFromArray(plaintext.data(), plaintext.size())) {
1483 return SOURCE_ADDRESS_TOKEN_PARSE_FAILURE;
1484 }
1485 *(tokens->add_tokens()) = token;
1486 return HANDSHAKE_OK;
1487 }
1488
1489 if (!tokens->ParseFromArray(plaintext.data(), plaintext.size())) {
1490 // Some clients might still be using the old source token format so
1491 // attempt to parse that format.
1492 // TODO(rch): remove this code once the new format is ubiquitous.
1493 SourceAddressToken token;
1494 if (!token.ParseFromArray(plaintext.data(), plaintext.size())) {
1495 return SOURCE_ADDRESS_TOKEN_PARSE_FAILURE;
1496 }
1497 *tokens->add_tokens() = token;
1498 }
1499
1500 return HANDSHAKE_OK;
1501 }
1502
1438 HandshakeFailureReason QuicCryptoServerConfig::ValidateSourceAddressToken( 1503 HandshakeFailureReason QuicCryptoServerConfig::ValidateSourceAddressToken(
1439 const Config& config, 1504 const Config& config,
1440 StringPiece token, 1505 StringPiece token,
1441 const IPEndPoint& ip, 1506 const IPEndPoint& ip,
1442 QuicWallTime now, 1507 QuicWallTime now,
1443 CachedNetworkParameters* cached_network_params) const { 1508 CachedNetworkParameters* cached_network_params) const {
1444 string storage; 1509 string storage;
1445 StringPiece plaintext; 1510 StringPiece plaintext;
1446 if (!config.source_address_token_boxer->Unbox(token, &storage, &plaintext)) { 1511 if (!config.source_address_token_boxer->Unbox(token, &storage, &plaintext)) {
1447 return SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE; 1512 return SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE;
(...skipping 28 matching lines...) Expand all
1476 return SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE; 1541 return SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE;
1477 } 1542 }
1478 1543
1479 if (source_address_token.has_cached_network_parameters()) { 1544 if (source_address_token.has_cached_network_parameters()) {
1480 *cached_network_params = source_address_token.cached_network_parameters(); 1545 *cached_network_params = source_address_token.cached_network_parameters();
1481 } 1546 }
1482 1547
1483 return HANDSHAKE_OK; 1548 return HANDSHAKE_OK;
1484 } 1549 }
1485 1550
1551 HandshakeFailureReason QuicCryptoServerConfig::ValidateSourceAddressTokens(
1552 const SourceAddressTokens& source_address_tokens,
1553 const IPEndPoint& ip,
1554 QuicWallTime now,
1555 CachedNetworkParameters* cached_network_params) const {
1556 HandshakeFailureReason reason =
1557 SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE;
1558 for (size_t i = 0; i < source_address_tokens.tokens_size(); i++) {
1559 const SourceAddressToken& token = source_address_tokens.tokens(i);
1560 reason = ValidateSingleSourceAddressToken(token, ip, now);
1561 if (reason == HANDSHAKE_OK) {
1562 if (token.has_cached_network_parameters()) {
1563 *cached_network_params = token.cached_network_parameters();
1564 }
1565 break;
1566 }
1567 }
1568 return reason;
1569 }
1570
1571 HandshakeFailureReason QuicCryptoServerConfig::ValidateSingleSourceAddressToken(
1572 const SourceAddressToken& source_address_token,
1573 const IPEndPoint& ip,
1574 QuicWallTime now) const {
1575 IPAddressNumber ip_address = ip.address();
1576 if (ip.GetSockAddrFamily() == AF_INET) {
1577 ip_address = ConvertIPv4NumberToIPv6Number(ip_address);
1578 }
1579 if (source_address_token.ip() != IPAddressToPackedString(ip_address)) {
1580 // It's for a different IP address.
1581 return SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE;
1582 }
1583
1584 return ValidateSourceAddressTokenTimestamp(source_address_token, now);
1585 }
1586
1587 HandshakeFailureReason
1588 QuicCryptoServerConfig::ValidateSourceAddressTokenTimestamp(
1589 const SourceAddressToken& source_address_token,
1590 QuicWallTime now) const {
1591 const QuicWallTime timestamp(
1592 QuicWallTime::FromUNIXSeconds(source_address_token.timestamp()));
1593 const QuicTime::Delta delta(now.AbsoluteDifference(timestamp));
1594
1595 if (now.IsBefore(timestamp) &&
1596 delta.ToSeconds() > source_address_token_future_secs_) {
1597 return SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE;
1598 }
1599
1600 if (now.IsAfter(timestamp) &&
1601 delta.ToSeconds() > source_address_token_lifetime_secs_) {
1602 return SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE;
1603 }
1604
1605 return HANDSHAKE_OK;
1606 }
1607
1486 // kServerNoncePlaintextSize is the number of bytes in an unencrypted server 1608 // kServerNoncePlaintextSize is the number of bytes in an unencrypted server
1487 // nonce. 1609 // nonce.
1488 static const size_t kServerNoncePlaintextSize = 1610 static const size_t kServerNoncePlaintextSize =
1489 4 /* timestamp */ + 20 /* random bytes */; 1611 4 /* timestamp */ + 20 /* random bytes */;
1490 1612
1491 string QuicCryptoServerConfig::NewServerNonce(QuicRandom* rand, 1613 string QuicCryptoServerConfig::NewServerNonce(QuicRandom* rand,
1492 QuicWallTime now) const { 1614 QuicWallTime now) const {
1493 const uint32 timestamp = static_cast<uint32>(now.ToUNIXSeconds()); 1615 const uint32 timestamp = static_cast<uint32>(now.ToUNIXSeconds());
1494 1616
1495 uint8 server_nonce[kServerNoncePlaintextSize]; 1617 uint8 server_nonce[kServerNoncePlaintextSize];
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1569 QuicCryptoServerConfig::Config::Config() 1691 QuicCryptoServerConfig::Config::Config()
1570 : channel_id_enabled(false), 1692 : channel_id_enabled(false),
1571 is_primary(false), 1693 is_primary(false),
1572 primary_time(QuicWallTime::Zero()), 1694 primary_time(QuicWallTime::Zero()),
1573 priority(0), 1695 priority(0),
1574 source_address_token_boxer(nullptr) {} 1696 source_address_token_boxer(nullptr) {}
1575 1697
1576 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); } 1698 QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); }
1577 1699
1578 } // namespace net 1700 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698