diff options
Diffstat (limited to 'chromium/net/quic/crypto')
20 files changed, 151 insertions, 223 deletions
diff --git a/chromium/net/quic/crypto/aes_128_gcm_12_encrypter.h b/chromium/net/quic/crypto/aes_128_gcm_12_encrypter.h index 451f84df6f8..ca9a2b1fca6 100644 --- a/chromium/net/quic/crypto/aes_128_gcm_12_encrypter.h +++ b/chromium/net/quic/crypto/aes_128_gcm_12_encrypter.h @@ -61,8 +61,6 @@ class NET_EXPORT_PRIVATE Aes128Gcm12Encrypter : public QuicEncrypter { unsigned char key_[16]; // The nonce prefix. unsigned char nonce_prefix_[4]; - // last_seq_num_ is the last sequence number observed. - QuicPacketSequenceNumber last_seq_num_; #if defined(USE_OPENSSL) ScopedEVPCipherCtx ctx_; diff --git a/chromium/net/quic/crypto/aes_128_gcm_12_encrypter_nss.cc b/chromium/net/quic/crypto/aes_128_gcm_12_encrypter_nss.cc index 1cd3540c884..ae6adab462b 100644 --- a/chromium/net/quic/crypto/aes_128_gcm_12_encrypter_nss.cc +++ b/chromium/net/quic/crypto/aes_128_gcm_12_encrypter_nss.cc @@ -250,7 +250,7 @@ SECStatus My_Encrypt(PK11SymKey* key, } // namespace -Aes128Gcm12Encrypter::Aes128Gcm12Encrypter() : last_seq_num_(0) { +Aes128Gcm12Encrypter::Aes128Gcm12Encrypter() { ignore_result(g_gcm_support_checker.Get()); } @@ -350,12 +350,8 @@ QuicData* Aes128Gcm12Encrypter::EncryptPacket( size_t ciphertext_size = GetCiphertextSize(plaintext.length()); scoped_ptr<char[]> ciphertext(new char[ciphertext_size]); - if (last_seq_num_ != 0 && sequence_number <= last_seq_num_) { - DLOG(FATAL) << "Sequence numbers regressed"; - return NULL; - } - last_seq_num_ = sequence_number; - + // TODO(ianswett): Introduce a check to ensure that we don't encrypt with the + // same sequence number twice. uint8 nonce[kNoncePrefixSize + sizeof(sequence_number)]; COMPILE_ASSERT(sizeof(nonce) == kAESNonceSize, bad_sequence_number_size); memcpy(nonce, nonce_prefix_, kNoncePrefixSize); diff --git a/chromium/net/quic/crypto/aes_128_gcm_12_encrypter_openssl.cc b/chromium/net/quic/crypto/aes_128_gcm_12_encrypter_openssl.cc index 79d0ec1a8a0..166fd55cb7c 100644 --- a/chromium/net/quic/crypto/aes_128_gcm_12_encrypter_openssl.cc +++ b/chromium/net/quic/crypto/aes_128_gcm_12_encrypter_openssl.cc @@ -21,7 +21,7 @@ const size_t kAESNonceSize = 12; } // namespace -Aes128Gcm12Encrypter::Aes128Gcm12Encrypter() : last_seq_num_(0) {} +Aes128Gcm12Encrypter::Aes128Gcm12Encrypter() {} Aes128Gcm12Encrypter::~Aes128Gcm12Encrypter() {} @@ -118,12 +118,8 @@ QuicData* Aes128Gcm12Encrypter::EncryptPacket( size_t ciphertext_size = GetCiphertextSize(plaintext.length()); scoped_ptr<char[]> ciphertext(new char[ciphertext_size]); - if (last_seq_num_ != 0 && sequence_number <= last_seq_num_) { - DLOG(FATAL) << "Sequence numbers regressed"; - return NULL; - } - last_seq_num_ = sequence_number; - + // TODO(ianswett): Introduce a check to ensure that we don't encrypt with the + // same sequence number twice. uint8 nonce[kNoncePrefixSize + sizeof(sequence_number)]; COMPILE_ASSERT(sizeof(nonce) == kAESNonceSize, bad_sequence_number_size); memcpy(nonce, nonce_prefix_, kNoncePrefixSize); diff --git a/chromium/net/quic/crypto/crypto_framer.h b/chromium/net/quic/crypto/crypto_framer.h index b070c66e277..ea69f3a5724 100644 --- a/chromium/net/quic/crypto/crypto_framer.h +++ b/chromium/net/quic/crypto/crypto_framer.h @@ -84,8 +84,6 @@ class NET_EXPORT_PRIVATE CryptoFramer { size_t pad_length, uint32* end_offset); - void set_error(QuicErrorCode error) { error_ = error; } - // Represents the current state of the parsing state machine. enum CryptoFramerState { STATE_READING_TAG, diff --git a/chromium/net/quic/crypto/crypto_handshake.cc b/chromium/net/quic/crypto/crypto_handshake.cc index d6a76f9f511..51465b75c4b 100644 --- a/chromium/net/quic/crypto/crypto_handshake.cc +++ b/chromium/net/quic/crypto/crypto_handshake.cc @@ -84,11 +84,6 @@ void CryptoHandshakeMessage::MarkDirty() { serialized_.reset(); } -void CryptoHandshakeMessage::Insert(QuicTagValueMap::const_iterator begin, - QuicTagValueMap::const_iterator end) { - tag_value_map_.insert(begin, end); -} - void CryptoHandshakeMessage::SetTaglist(QuicTag tag, ...) { // Warning, if sizeof(QuicTag) > sizeof(int) then this function will break // because the terminating 0 will only be promoted to int. @@ -326,8 +321,7 @@ string CryptoHandshakeMessage::DebugStringInternal(size_t indent) const { } QuicCryptoNegotiatedParameters::QuicCryptoNegotiatedParameters() - : version(0), - key_exchange(0), + : key_exchange(0), aead(0) { } @@ -470,6 +464,12 @@ void QuicCryptoClientConfig::CachedState::SetProof(const vector<string>& certs, server_config_sig_ = signature.as_string(); } +void QuicCryptoClientConfig::CachedState::ClearProof() { + SetProofInvalid(); + certs_.clear(); + server_config_sig_.clear(); +} + void QuicCryptoClientConfig::CachedState::SetProofValid() { server_config_valid_ = true; } @@ -758,6 +758,10 @@ QuicErrorCode QuicCryptoClientConfig::FillClientHello( 0 /* sequence number */, StringPiece() /* associated data */, cetv_plaintext.AsStringPiece())); + if (!cetv_ciphertext.get()) { + *error_details = "Packet encryption failed"; + return QUIC_ENCRYPTION_FAILURE; + } out->SetStringPiece(kCETV, cetv_ciphertext->AsStringPiece()); out->MarkDirty(); @@ -788,9 +792,9 @@ QuicErrorCode QuicCryptoClientConfig::FillClientHello( } QuicErrorCode QuicCryptoClientConfig::ProcessRejection( - CachedState* cached, const CryptoHandshakeMessage& rej, QuicWallTime now, + CachedState* cached, QuicCryptoNegotiatedParameters* out_params, string* error_details) { DCHECK(error_details != NULL); @@ -822,8 +826,9 @@ QuicErrorCode QuicCryptoClientConfig::ProcessRejection( } StringPiece proof, cert_bytes; - if (rej.GetStringPiece(kPROF, &proof) && - rej.GetStringPiece(kCertificateTag, &cert_bytes)) { + bool has_proof = rej.GetStringPiece(kPROF, &proof); + bool has_cert = rej.GetStringPiece(kCertificateTag, &cert_bytes); + if (has_proof && has_cert) { vector<string> certs; if (!CertCompressor::DecompressChain(cert_bytes, out_params->cached_certs, common_cert_sets, &certs)) { @@ -832,6 +837,17 @@ QuicErrorCode QuicCryptoClientConfig::ProcessRejection( } cached->SetProof(certs, proof); + } else { + cached->ClearProof(); + if (has_proof && !has_cert) { + *error_details = "Certificate missing"; + return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; + } + + if (!has_proof && has_cert) { + *error_details = "Proof missing"; + return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; + } } return QUIC_NO_ERROR; @@ -840,6 +856,7 @@ QuicErrorCode QuicCryptoClientConfig::ProcessRejection( QuicErrorCode QuicCryptoClientConfig::ProcessServerHello( const CryptoHandshakeMessage& server_hello, QuicGuid guid, + CachedState* cached, QuicCryptoNegotiatedParameters* out_params, string* error_details) { DCHECK(error_details != NULL); @@ -849,6 +866,12 @@ QuicErrorCode QuicCryptoClientConfig::ProcessServerHello( return QUIC_INVALID_CRYPTO_MESSAGE_TYPE; } + // Learn about updated source address tokens. + StringPiece token; + if (server_hello.GetStringPiece(kSourceAddressTokenTag, &token)) { + cached->set_source_address_token(token); + } + // TODO(agl): // learn about updated SCFGs. diff --git a/chromium/net/quic/crypto/crypto_handshake.h b/chromium/net/quic/crypto/crypto_handshake.h index fdc92a0fc38..cec393f7c77 100644 --- a/chromium/net/quic/crypto/crypto_handshake.h +++ b/chromium/net/quic/crypto/crypto_handshake.h @@ -73,9 +73,6 @@ class NET_EXPORT_PRIVATE CryptoHandshakeMessage { const QuicTagValueMap& tag_value_map() const { return tag_value_map_; } - void Insert(QuicTagValueMap::const_iterator begin, - QuicTagValueMap::const_iterator end); - // SetTaglist sets an element with the given tag to contain a list of tags, // passed as varargs. The argument list must be terminated with a 0 element. void SetTaglist(QuicTag tag, ...); @@ -160,7 +157,6 @@ struct NET_EXPORT_PRIVATE QuicCryptoNegotiatedParameters { QuicCryptoNegotiatedParameters(); ~QuicCryptoNegotiatedParameters(); - uint16 version; QuicTag key_exchange; QuicTag aead; std::string initial_premaster_secret; @@ -266,6 +262,9 @@ class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { void SetProof(const std::vector<std::string>& certs, base::StringPiece signature); + // Clears the certificate chain and signature and invalidates the proof. + void ClearProof(); + // SetProofValid records that the certificate chain and signature have been // validated and that it's safe to assume that the server is legitimate. // (Note: this does not check the chain or signature.) @@ -353,18 +352,20 @@ class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig { // state about a future handshake (i.e. an nonce value from the server), then // it will be saved in |out_params|. |now| is used to judge whether the // server config in the rejection message has expired. - QuicErrorCode ProcessRejection(CachedState* cached, - const CryptoHandshakeMessage& rej, + QuicErrorCode ProcessRejection(const CryptoHandshakeMessage& rej, QuicWallTime now, + CachedState* cached, QuicCryptoNegotiatedParameters* out_params, std::string* error_details); - // ProcessServerHello processes the message in |server_hello|, writes the - // negotiated parameters to |out_params| and returns QUIC_NO_ERROR. If - // |server_hello| is unacceptable then it puts an error message in - // |error_details| and returns an error code. + // ProcessServerHello processes the message in |server_hello|, updates the + // cached information about that server, writes the negotiated parameters to + // |out_params| and returns QUIC_NO_ERROR. If |server_hello| is unacceptable + // then it puts an error message in |error_details| and returns an error + // code. QuicErrorCode ProcessServerHello(const CryptoHandshakeMessage& server_hello, QuicGuid guid, + CachedState* cached, QuicCryptoNegotiatedParameters* out_params, std::string* error_details); diff --git a/chromium/net/quic/crypto/crypto_protocol.h b/chromium/net/quic/crypto/crypto_protocol.h index 586569a6a0a..4580fce4bb4 100644 --- a/chromium/net/quic/crypto/crypto_protocol.h +++ b/chromium/net/quic/crypto/crypto_protocol.h @@ -59,7 +59,6 @@ const QuicTag kCHID = TAG('C', 'H', 'I', 'D'); // Channel ID. // Client hello tags const QuicTag kVERS = TAG('V', 'E', 'R', 'S'); // Version const QuicTag kNONC = TAG('N', 'O', 'N', 'C'); // The client's nonce -const QuicTag kSSID = TAG('S', 'S', 'I', 'D'); // Session ID const QuicTag kKEXS = TAG('K', 'E', 'X', 'S'); // Key exchange methods const QuicTag kAEAD = TAG('A', 'E', 'A', 'D'); // Authenticated // encryption algorithms diff --git a/chromium/net/quic/crypto/crypto_server_config.cc b/chromium/net/quic/crypto/crypto_server_config.cc index f270ddeb31a..89cea42862d 100644 --- a/chromium/net/quic/crypto/crypto_server_config.cc +++ b/chromium/net/quic/crypto/crypto_server_config.cc @@ -11,6 +11,7 @@ #include "base/strings/string_number_conversions.h" #include "crypto/hkdf.h" #include "crypto/secure_hash.h" +#include "net/base/net_util.h" #include "net/quic/crypto/aes_128_gcm_12_decrypter.h" #include "net/quic/crypto/aes_128_gcm_12_encrypter.h" #include "net/quic/crypto/cert_compressor.h" @@ -56,6 +57,7 @@ QuicCryptoServerConfig::QuicCryptoServerConfig( next_config_promotion_time_(QuicWallTime::Zero()), strike_register_lock_(), server_nonce_strike_register_lock_(), + strike_register_no_startup_period_(false), strike_register_max_entries_(1 << 10), strike_register_window_secs_(600), source_address_token_future_secs_(3600), @@ -304,7 +306,6 @@ struct ClientHelloInfo { QuicErrorCode QuicCryptoServerConfig::ProcessClientHello( const CryptoHandshakeMessage& client_hello, - QuicVersion version, QuicGuid guid, const IPEndPoint& client_ip, const QuicClock* clock, @@ -359,8 +360,7 @@ QuicErrorCode QuicCryptoServerConfig::ProcessClientHello( !info.client_nonce_well_formed || !info.unique || !requested_config.get()) { - BuildRejection(version, primary_config.get(), client_hello, info, rand, - out); + BuildRejection(primary_config.get(), client_hello, info, rand, out); return QUIC_NO_ERROR; } @@ -636,6 +636,8 @@ QuicErrorCode QuicCryptoServerConfig::EvaluateClientHello( static_cast<uint32>(info->now.ToUNIXSeconds()), strike_register_window_secs_, orbit, + strike_register_no_startup_period_ ? + StrikeRegister::NO_STARTUP_PERIOD_NEEDED : StrikeRegister::DENY_REQUESTS_AT_STARTUP)); } @@ -664,7 +666,6 @@ QuicErrorCode QuicCryptoServerConfig::EvaluateClientHello( } void QuicCryptoServerConfig::BuildRejection( - QuicVersion version, const scoped_refptr<Config>& config, const CryptoHandshakeMessage& client_hello, const ClientHelloInfo& info, @@ -708,9 +709,8 @@ void QuicCryptoServerConfig::BuildRejection( const vector<string>* certs; string signature; - if (!proof_source_->GetProof(version, info.sni.as_string(), - config->serialized, x509_ecdsa_supported, - &certs, &signature)) { + if (!proof_source_->GetProof(info.sni.as_string(), config->serialized, + x509_ecdsa_supported, &certs, &signature)) { return; } @@ -908,6 +908,12 @@ void QuicCryptoServerConfig::set_replay_protection(bool on) { replay_protection_ = on; } +void QuicCryptoServerConfig::set_strike_register_no_startup_period() { + base::AutoLock auto_lock(strike_register_lock_); + DCHECK(!strike_register_.get()); + strike_register_no_startup_period_ = true; +} + void QuicCryptoServerConfig::set_strike_register_max_entries( uint32 max_entries) { base::AutoLock locker(strike_register_lock_); @@ -949,7 +955,7 @@ string QuicCryptoServerConfig::NewSourceAddressToken( QuicRandom* rand, QuicWallTime now) const { SourceAddressToken source_address_token; - source_address_token.set_ip(ip.ToString()); + source_address_token.set_ip(IPAddressToPackedString(ip.address())); source_address_token.set_timestamp(now.ToUNIXSeconds()); return source_address_token_boxer_.Box( @@ -972,7 +978,7 @@ bool QuicCryptoServerConfig::ValidateSourceAddressToken( return false; } - if (source_address_token.ip() != ip.ToString()) { + if (source_address_token.ip() != IPAddressToPackedString(ip.address())) { // It's for a different IP address. return false; } diff --git a/chromium/net/quic/crypto/crypto_server_config.h b/chromium/net/quic/crypto/crypto_server_config.h index 364c200a149..4255d228618 100644 --- a/chromium/net/quic/crypto/crypto_server_config.h +++ b/chromium/net/quic/crypto/crypto_server_config.h @@ -116,8 +116,6 @@ class NET_EXPORT_PRIVATE QuicCryptoServerConfig { // an error code is returned. // // client_hello: the incoming client hello message. - // version: the QUIC version for the connection. TODO(wtc): Remove once - // QUIC_VERSION_7 and before are removed. // guid: the GUID for the connection, which is used in key derivation. // client_ip: the IP address of the client, which is used to generate and // validate source-address tokens. @@ -129,7 +127,6 @@ class NET_EXPORT_PRIVATE QuicCryptoServerConfig { // out: the resulting handshake message (either REJ or SHLO) // error_details: used to store a string describing any error. QuicErrorCode ProcessClientHello(const CryptoHandshakeMessage& client_hello, - QuicVersion version, QuicGuid guid, const IPEndPoint& client_ip, const QuicClock* clock, @@ -155,6 +152,10 @@ class NET_EXPORT_PRIVATE QuicCryptoServerConfig { // request to be processed twice. void set_replay_protection(bool on); + // set_strike_register_no_startup_period configures the strike register to + // not have a startup period. + void set_strike_register_no_startup_period(); + // set_strike_register_max_entries sets the maximum number of entries that // the internal strike register will hold. If the strike register fills up // then the oldest entries (by the client's clock) will be dropped. @@ -262,7 +263,6 @@ class NET_EXPORT_PRIVATE QuicCryptoServerConfig { // BuildRejection sets |out| to be a REJ message in reply to |client_hello|. void BuildRejection( - QuicVersion version, const scoped_refptr<Config>& config, const CryptoHandshakeMessage& client_hello, const ClientHelloInfo& info, @@ -351,6 +351,7 @@ class NET_EXPORT_PRIVATE QuicCryptoServerConfig { // These fields store configuration values. See the comments for their // respective setter functions. + bool strike_register_no_startup_period_; uint32 strike_register_max_entries_; uint32 strike_register_window_secs_; uint32 source_address_token_future_secs_; diff --git a/chromium/net/quic/crypto/crypto_server_test.cc b/chromium/net/quic/crypto/crypto_server_test.cc index 6744d12e5e0..b2cdf820c34 100644 --- a/chromium/net/quic/crypto/crypto_server_test.cc +++ b/chromium/net/quic/crypto/crypto_server_test.cc @@ -72,8 +72,8 @@ class CryptoServerTest : public ::testing::Test { void ShouldSucceed(const CryptoHandshakeMessage& message) { string error_details; QuicErrorCode error = config_.ProcessClientHello( - message, QuicVersionMax(), 1 /* GUID */, addr_, - &clock_, rand_, ¶ms_, &out_, &error_details); + message, 1 /* GUID */, addr_, &clock_, + rand_, ¶ms_, &out_, &error_details); ASSERT_EQ(error, QUIC_NO_ERROR) << "Message failed with error " << error_details << ": " @@ -84,8 +84,8 @@ class CryptoServerTest : public ::testing::Test { const CryptoHandshakeMessage& message) { string error_details; QuicErrorCode error = config_.ProcessClientHello( - message, QuicVersionMax(), 1 /* GUID */, addr_, - &clock_, rand_, ¶ms_, &out_, &error_details); + message, 1 /* GUID */, addr_, &clock_, + rand_, ¶ms_, &out_, &error_details); ASSERT_NE(error, QUIC_NO_ERROR) << "Message didn't fail: " << message.DebugString(); diff --git a/chromium/net/quic/crypto/proof_source.h b/chromium/net/quic/crypto/proof_source.h index ba5087b0f61..4482dd99561 100644 --- a/chromium/net/quic/crypto/proof_source.h +++ b/chromium/net/quic/crypto/proof_source.h @@ -9,7 +9,6 @@ #include <vector> #include "net/base/net_export.h" -#include "net/quic/quic_protocol.h" namespace net { @@ -28,9 +27,6 @@ class NET_EXPORT_PRIVATE ProofSource { // // The signature uses SHA-256 as the hash function when the key is ECDSA. // - // |version| is the QUIC version for the connection. TODO(wtc): Remove once - // QUIC_VERSION_7 and before are removed. - // // If |ecdsa_ok| is true, the signature may use an ECDSA key. Otherwise, the // signature must use an RSA key. // @@ -49,8 +45,7 @@ class NET_EXPORT_PRIVATE ProofSource { // used. // // This function may be called concurrently. - virtual bool GetProof(QuicVersion version, - const std::string& hostname, + virtual bool GetProof(const std::string& hostname, const std::string& server_config, bool ecdsa_ok, const std::vector<std::string>** out_certs, diff --git a/chromium/net/quic/crypto/proof_source_chromium.cc b/chromium/net/quic/crypto/proof_source_chromium.cc index 4c1fe263b62..75226313818 100644 --- a/chromium/net/quic/crypto/proof_source_chromium.cc +++ b/chromium/net/quic/crypto/proof_source_chromium.cc @@ -12,8 +12,7 @@ namespace net { ProofSourceChromium::ProofSourceChromium() { } -bool ProofSourceChromium::GetProof(QuicVersion version, - const string& hostname, +bool ProofSourceChromium::GetProof(const string& hostname, const string& server_config, bool ecdsa_ok, const vector<string>** out_certs, diff --git a/chromium/net/quic/crypto/proof_source_chromium.h b/chromium/net/quic/crypto/proof_source_chromium.h index 2b93e2d9a4c..70ab92d91cf 100644 --- a/chromium/net/quic/crypto/proof_source_chromium.h +++ b/chromium/net/quic/crypto/proof_source_chromium.h @@ -23,8 +23,7 @@ class NET_EXPORT_PRIVATE ProofSourceChromium : public ProofSource { virtual ~ProofSourceChromium() {} // ProofSource interface - virtual bool GetProof(QuicVersion version, - const std::string& hostname, + virtual bool GetProof(const std::string& hostname, const std::string& server_config, bool ecdsa_ok, const std::vector<std::string>** out_certs, diff --git a/chromium/net/quic/crypto/proof_test.cc b/chromium/net/quic/crypto/proof_test.cc index 97b0dcb4ea9..e4e661a298c 100644 --- a/chromium/net/quic/crypto/proof_test.cc +++ b/chromium/net/quic/crypto/proof_test.cc @@ -25,21 +25,7 @@ using std::vector; namespace net { namespace test { -class ProofTest : public ::testing::TestWithParam<QuicVersion> { - protected: - ProofTest() { - version_ = GetParam(); - } - - QuicVersion version_; -}; - -// Run all ProofTests with QUIC versions 7 and 8. -INSTANTIATE_TEST_CASE_P(ProofTests, - ProofTest, - ::testing::Values(QUIC_VERSION_7, QUIC_VERSION_8)); - -TEST_P(ProofTest, Verify) { +TEST(ProofTest, Verify) { // TODO(rtenneti): Enable testing of ProofVerifier. #if 0 scoped_ptr<ProofSource> source(CryptoTestUtils::ProofSourceForTesting()); @@ -53,11 +39,10 @@ TEST_P(ProofTest, Verify) { string error_details, signature, first_signature; CertVerifyResult cert_verify_result; - ASSERT_TRUE(source->GetProof(version_, hostname, server_config, - false /* no ECDSA */, &first_certs, - &first_signature)); - ASSERT_TRUE(source->GetProof(version_, hostname, server_config, - false /* no ECDSA */, &certs, &signature)); + ASSERT_TRUE(source->GetProof(hostname, server_config, false /* no ECDSA */, + &first_certs, &first_signature)); + ASSERT_TRUE(source->GetProof(hostname, server_config, false /* no ECDSA */, + &certs, &signature)); // Check that the proof source is caching correctly: ASSERT_EQ(first_certs, certs); @@ -65,23 +50,22 @@ TEST_P(ProofTest, Verify) { int rv; TestCompletionCallback callback; - rv = verifier->VerifyProof(version_, hostname, server_config, *certs, - signature, &error_details, &cert_verify_result, + rv = verifier->VerifyProof(hostname, server_config, *certs, signature, + &error_details, &cert_verify_result, callback.callback()); rv = callback.GetResult(rv); ASSERT_EQ(OK, rv); ASSERT_EQ("", error_details); ASSERT_FALSE(IsCertStatusError(cert_verify_result.cert_status)); - rv = verifier->VerifyProof(version_, "foo.com", server_config, *certs, - signature, &error_details, &cert_verify_result, + rv = verifier->VerifyProof("foo.com", server_config, *certs, signature, + &error_details, &cert_verify_result, callback.callback()); rv = callback.GetResult(rv); ASSERT_EQ(ERR_FAILED, rv); ASSERT_NE("", error_details); - rv = verifier->VerifyProof(version_, hostname, - server_config.substr(1, string::npos), + rv = verifier->VerifyProof(hostname, server_config.substr(1, string::npos), *certs, signature, &error_details, &cert_verify_result, callback.callback()); rv = callback.GetResult(rv); @@ -89,7 +73,7 @@ TEST_P(ProofTest, Verify) { ASSERT_NE("", error_details); const string corrupt_signature = "1" + signature; - rv = verifier->VerifyProof(version_, hostname, server_config, *certs, + rv = verifier->VerifyProof(hostname, server_config, *certs, corrupt_signature, &error_details, &cert_verify_result, callback.callback()); rv = callback.GetResult(rv); @@ -100,8 +84,8 @@ TEST_P(ProofTest, Verify) { for (size_t i = 1; i < certs->size(); i++) { wrong_certs.push_back((*certs)[i]); } - rv = verifier->VerifyProof(version_, "foo.com", server_config, wrong_certs, - signature, &error_details, &cert_verify_result, + rv = verifier->VerifyProof("foo.com", server_config, wrong_certs, signature, + &error_details, &cert_verify_result, callback.callback()); rv = callback.GetResult(rv); ASSERT_EQ(ERR_FAILED, rv); @@ -138,8 +122,7 @@ class TestProofVerifierCallback : public ProofVerifierCallback { // RunVerification runs |verifier->VerifyProof| and asserts that the result // matches |expected_ok|. -static void RunVerification(QuicVersion version, - ProofVerifier* verifier, +static void RunVerification(ProofVerifier* verifier, const std::string& hostname, const std::string& server_config, const vector<std::string>& certs, @@ -153,7 +136,7 @@ static void RunVerification(QuicVersion version, new TestProofVerifierCallback(&comp_callback, &ok, &error_details); ProofVerifier::Status status = verifier->VerifyProof( - version, hostname, server_config, certs, proof, &error_details, &details, + hostname, server_config, certs, proof, &error_details, &details, callback); switch (status) { @@ -185,56 +168,11 @@ static string PEMCertFileToDER(const string& file_name) { // A known answer test that allows us to test ProofVerifier without a working // ProofSource. -TEST_P(ProofTest, VerifyRSAKnownAnswerTest) { +TEST(ProofTest, VerifyRSAKnownAnswerTest) { // These sample signatures were generated by running the Proof.Verify test // and dumping the bytes of the |signature| output of ProofSource::GetProof(). // sLen = special value -2 used by OpenSSL. static const unsigned char signature_data_0[] = { - 0x4c, 0x68, 0x3c, 0xc2, 0x1f, 0x31, 0x73, 0xa5, 0x29, 0xd3, - 0x56, 0x75, 0xb1, 0xbf, 0xbd, 0x31, 0x17, 0xfb, 0x2e, 0x24, - 0xb3, 0xc4, 0x0d, 0xfa, 0x56, 0xb8, 0x65, 0x94, 0x12, 0x38, - 0x6e, 0xff, 0xb3, 0x10, 0x2e, 0xf8, 0x5c, 0xc1, 0x21, 0x9d, - 0x29, 0x0c, 0x3a, 0x0a, 0x1a, 0xbf, 0x6b, 0x1c, 0x63, 0x77, - 0xf7, 0x86, 0xd3, 0xa4, 0x36, 0xf2, 0xb1, 0x6f, 0xac, 0xc3, - 0x23, 0x8d, 0xda, 0xe6, 0xd5, 0x83, 0xba, 0xdf, 0x28, 0x3e, - 0x7f, 0x4e, 0x79, 0xfc, 0xba, 0xdb, 0xf7, 0xd0, 0x4b, 0xad, - 0x79, 0xd0, 0xeb, 0xcf, 0xfa, 0x6e, 0x84, 0x44, 0x7a, 0x26, - 0xb1, 0x29, 0xa3, 0x08, 0xa8, 0x63, 0xfd, 0xed, 0x85, 0xff, - 0x9a, 0xe6, 0x79, 0x8b, 0xb6, 0x81, 0x13, 0x2c, 0xde, 0xe2, - 0xd8, 0x31, 0x29, 0xa4, 0xe0, 0x1b, 0x75, 0x2d, 0x8a, 0xf8, - 0x27, 0x55, 0xbc, 0xc7, 0x3b, 0x1e, 0xc1, 0x42, - }; - static const unsigned char signature_data_1[] = { - 0xbb, 0xd1, 0x17, 0x43, 0xf3, 0x42, 0x16, 0xe9, 0xf9, 0x76, - 0xe6, 0xe3, 0xaa, 0x50, 0x47, 0x5f, 0x93, 0xb6, 0x7d, 0x35, - 0x03, 0x49, 0x0a, 0x07, 0x61, 0xd5, 0xf1, 0x9c, 0x6b, 0xaf, - 0xaa, 0xd7, 0x64, 0xe4, 0x0a, 0x0c, 0xab, 0x97, 0xfb, 0x4e, - 0x5c, 0x14, 0x08, 0xf6, 0xb9, 0xa9, 0x1d, 0xa9, 0xf8, 0x6d, - 0xb0, 0x2b, 0x2a, 0x0e, 0xc4, 0xd0, 0xd2, 0xe9, 0x96, 0x4f, - 0x44, 0x70, 0x90, 0x46, 0xb9, 0xd5, 0x89, 0x72, 0xb9, 0xa8, - 0xe4, 0xfb, 0x88, 0xbc, 0x69, 0x7f, 0xc9, 0xdc, 0x84, 0x87, - 0x18, 0x21, 0x9b, 0xde, 0x22, 0x33, 0xde, 0x16, 0x3f, 0xe6, - 0xfd, 0x27, 0x56, 0xd3, 0xa4, 0x97, 0x91, 0x65, 0x1a, 0xe7, - 0x5e, 0x80, 0x9a, 0xbf, 0xbf, 0x1a, 0x29, 0x8a, 0xbe, 0xa2, - 0x8c, 0x9c, 0x23, 0xf4, 0xcb, 0xba, 0x79, 0x31, 0x28, 0xab, - 0x77, 0x94, 0x92, 0xb2, 0xc2, 0x35, 0xb2, 0xfa, - }; - static const unsigned char signature_data_2[] = { - 0x7e, 0x17, 0x01, 0xcb, 0x76, 0x9e, 0x9f, 0xce, 0xeb, 0x66, - 0x3e, 0xaa, 0xc9, 0x36, 0x5b, 0x7e, 0x48, 0x25, 0x99, 0xf8, - 0x0d, 0xe1, 0xa8, 0x48, 0x93, 0x3c, 0xe8, 0x97, 0x2e, 0x98, - 0xd6, 0x73, 0x0f, 0xd0, 0x74, 0x9c, 0x17, 0xef, 0xee, 0xf8, - 0x0e, 0x2a, 0x27, 0x3f, 0xc6, 0x55, 0xc6, 0xb9, 0xfe, 0x17, - 0xcc, 0xeb, 0x5d, 0xa1, 0xdc, 0xbd, 0x64, 0xd9, 0x5e, 0xec, - 0x57, 0x9d, 0xc3, 0xdc, 0x11, 0xbf, 0x23, 0x02, 0x58, 0xc4, - 0xf1, 0x18, 0xc1, 0x6f, 0x3f, 0xef, 0x18, 0x4d, 0xa6, 0x1e, - 0xe8, 0x25, 0x32, 0x8f, 0x92, 0x1e, 0xad, 0xbc, 0xbe, 0xde, - 0x83, 0x2a, 0x92, 0xd5, 0x59, 0x6f, 0xe4, 0x95, 0x6f, 0xe6, - 0xb1, 0xf9, 0xaf, 0x3f, 0xdb, 0x69, 0x6f, 0xae, 0xa6, 0x36, - 0xd2, 0x50, 0x81, 0x78, 0x41, 0x13, 0x2c, 0x65, 0x9c, 0x9e, - 0xf4, 0xd2, 0xd5, 0x58, 0x5b, 0x8b, 0x87, 0xcf, - }; - static const unsigned char signature_data_4[] = { 0x9e, 0xe6, 0x74, 0x3b, 0x8f, 0xb8, 0x66, 0x77, 0x57, 0x09, 0x8a, 0x04, 0xe9, 0xf0, 0x7c, 0x91, 0xa9, 0x5c, 0xe9, 0xdf, 0x12, 0x4d, 0x23, 0x82, 0x8c, 0x29, 0x72, 0x7f, 0xc2, 0x20, @@ -249,7 +187,7 @@ TEST_P(ProofTest, VerifyRSAKnownAnswerTest) { 0x78, 0xc8, 0x8b, 0xf5, 0xb9, 0x36, 0x5d, 0x72, 0x1f, 0xfc, 0x14, 0xff, 0xa7, 0x81, 0x27, 0x49, 0xae, 0xe1, }; - static const unsigned char signature_data_5[] = { + static const unsigned char signature_data_1[] = { 0x5e, 0xc2, 0xab, 0x6b, 0x16, 0xe6, 0x55, 0xf3, 0x16, 0x46, 0x35, 0xdc, 0xcc, 0xde, 0xd0, 0xbd, 0x6c, 0x66, 0xb2, 0x3d, 0xd3, 0x14, 0x78, 0xed, 0x47, 0x55, 0xfb, 0xdb, 0xe1, 0x7d, @@ -264,7 +202,7 @@ TEST_P(ProofTest, VerifyRSAKnownAnswerTest) { 0xaf, 0x6b, 0x47, 0xbc, 0x16, 0x55, 0x37, 0x0a, 0xbe, 0x0e, 0xc5, 0x75, 0x3f, 0x3d, 0x8e, 0xe8, 0x44, 0xe3, }; - static const unsigned char signature_data_6[] = { + static const unsigned char signature_data_2[] = { 0x8e, 0x5c, 0x78, 0x63, 0x74, 0x99, 0x2e, 0x96, 0xc0, 0x14, 0x8d, 0xb5, 0x13, 0x74, 0xa3, 0xa4, 0xe0, 0x43, 0x3e, 0x85, 0xba, 0x8f, 0x3c, 0x5e, 0x14, 0x64, 0x0e, 0x5e, 0xff, 0x89, @@ -295,52 +233,41 @@ TEST_P(ProofTest, VerifyRSAKnownAnswerTest) { // Signatures are nondeterministic, so we test multiple signatures on the // same server_config. vector<string> signatures(3); - if (version_ < QUIC_VERSION_8) { - signatures[0].assign(reinterpret_cast<const char*>(signature_data_0), - sizeof(signature_data_0)); - signatures[1].assign(reinterpret_cast<const char*>(signature_data_1), - sizeof(signature_data_1)); - signatures[2].assign(reinterpret_cast<const char*>(signature_data_2), - sizeof(signature_data_2)); - } else { - signatures[0].assign(reinterpret_cast<const char*>(signature_data_4), - sizeof(signature_data_4)); - signatures[1].assign(reinterpret_cast<const char*>(signature_data_5), - sizeof(signature_data_5)); - signatures[2].assign(reinterpret_cast<const char*>(signature_data_6), - sizeof(signature_data_6)); - } + signatures[0].assign(reinterpret_cast<const char*>(signature_data_0), + sizeof(signature_data_0)); + signatures[1].assign(reinterpret_cast<const char*>(signature_data_1), + sizeof(signature_data_1)); + signatures[2].assign(reinterpret_cast<const char*>(signature_data_2), + sizeof(signature_data_2)); for (size_t i = 0; i < signatures.size(); i++) { const string& signature = signatures[i]; RunVerification( - version_, verifier.get(), hostname, server_config, certs, signature, - true); + verifier.get(), hostname, server_config, certs, signature, true); RunVerification( - version_, verifier.get(), "foo.com", server_config, certs, signature, - false); + verifier.get(), "foo.com", server_config, certs, signature, false); RunVerification( - version_, verifier.get(), hostname, - server_config.substr(1, string::npos), certs, signature, false); + verifier.get(), hostname, server_config.substr(1, string::npos), + certs, signature, false); const string corrupt_signature = "1" + signature; RunVerification( - version_, verifier.get(), hostname, server_config, certs, - corrupt_signature, false); + verifier.get(), hostname, server_config, certs, corrupt_signature, + false); vector<string> wrong_certs; for (size_t i = 1; i < certs.size(); i++) { wrong_certs.push_back(certs[i]); } - RunVerification(version_, verifier.get(), hostname, server_config, - wrong_certs, signature, false); + RunVerification(verifier.get(), hostname, server_config, wrong_certs, + signature, false); } } // A known answer test that allows us to test ProofVerifier without a working // ProofSource. -TEST_P(ProofTest, VerifyECDSAKnownAnswerTest) { +TEST(ProofTest, VerifyECDSAKnownAnswerTest) { // Disable this test on platforms that do not support ECDSA certificates. #if defined(OS_WIN) if (base::win::GetVersion() < base::win::VERSION_VISTA) @@ -406,36 +333,34 @@ TEST_P(ProofTest, VerifyECDSAKnownAnswerTest) { const string& signature = signatures[i]; RunVerification( - version_, verifier.get(), hostname, server_config, certs, signature, - true); + verifier.get(), hostname, server_config, certs, signature, true); RunVerification( - version_, verifier.get(), "foo.com", server_config, certs, signature, - false); + verifier.get(), "foo.com", server_config, certs, signature, false); RunVerification( - version_, verifier.get(), hostname, - server_config.substr(1, string::npos), certs, signature, false); + verifier.get(), hostname, server_config.substr(1, string::npos), + certs, signature, false); // An ECDSA signature is DER-encoded. Corrupt the last byte so that the // signature can still be DER-decoded correctly. string corrupt_signature = signature; corrupt_signature[corrupt_signature.size() - 1] += 1; RunVerification( - version_, verifier.get(), hostname, server_config, certs, - corrupt_signature, false); + verifier.get(), hostname, server_config, certs, corrupt_signature, + false); // Prepending a "1" makes the DER invalid. const string bad_der_signature1 = "1" + signature; RunVerification( - version_, verifier.get(), hostname, server_config, certs, - bad_der_signature1, false); + verifier.get(), hostname, server_config, certs, bad_der_signature1, + false); vector<string> wrong_certs; for (size_t i = 1; i < certs.size(); i++) { wrong_certs.push_back(certs[i]); } RunVerification( - version_, verifier.get(), hostname, server_config, wrong_certs, - signature, false); + verifier.get(), hostname, server_config, wrong_certs, signature, + false); } } diff --git a/chromium/net/quic/crypto/proof_verifier.h b/chromium/net/quic/crypto/proof_verifier.h index ecab113e694..f469c552959 100644 --- a/chromium/net/quic/crypto/proof_verifier.h +++ b/chromium/net/quic/crypto/proof_verifier.h @@ -10,7 +10,6 @@ #include "net/base/completion_callback.h" #include "net/base/net_export.h" -#include "net/quic/quic_protocol.h" namespace net { @@ -71,11 +70,7 @@ class NET_EXPORT_PRIVATE ProofVerifier { // // The signature uses SHA-256 as the hash function and PSS padding in the // case of RSA. - // - // |version| is the QUIC version for the connection. TODO(wtc): Remove once - // QUIC_VERSION_7 and before are removed. - virtual Status VerifyProof(QuicVersion version, - const std::string& hostname, + virtual Status VerifyProof(const std::string& hostname, const std::string& server_config, const std::vector<std::string>& certs, const std::string& signature, diff --git a/chromium/net/quic/crypto/proof_verifier_chromium.cc b/chromium/net/quic/crypto/proof_verifier_chromium.cc index 88653053f3e..8c4796204ec 100644 --- a/chromium/net/quic/crypto/proof_verifier_chromium.cc +++ b/chromium/net/quic/crypto/proof_verifier_chromium.cc @@ -42,7 +42,6 @@ ProofVerifierChromium::~ProofVerifierChromium() { } ProofVerifierChromium::Status ProofVerifierChromium::VerifyProof( - QuicVersion version, const string& hostname, const string& server_config, const vector<string>& certs, @@ -90,7 +89,7 @@ ProofVerifierChromium::Status ProofVerifierChromium::VerifyProof( // We call VerifySignature first to avoid copying of server_config and // signature. - if (!VerifySignature(version, server_config, signature, certs[0])) { + if (!VerifySignature(server_config, signature, certs[0])) { *error_details = "Failed to verify signature of server config"; DLOG(WARNING) << *error_details; verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID; @@ -177,8 +176,7 @@ int ProofVerifierChromium::DoVerifyCertComplete(int result) { return result; } -bool ProofVerifierChromium::VerifySignature(QuicVersion version, - const string& signed_data, +bool ProofVerifierChromium::VerifySignature(const string& signed_data, const string& signature, const string& cert) { StringPiece spki; @@ -198,11 +196,9 @@ bool ProofVerifierChromium::VerifySignature(QuicVersion version, crypto::SignatureVerifier::SHA256; crypto::SignatureVerifier::HashAlgorithm mask_hash_alg = hash_alg; unsigned int hash_len = 32; // 32 is the length of a SHA-256 hash. - unsigned int salt_len = - version >= QUIC_VERSION_8 ? hash_len : signature.size() - hash_len - 2; bool ok = verifier.VerifyInitRSAPSS( - hash_alg, mask_hash_alg, salt_len, + hash_alg, mask_hash_alg, hash_len, reinterpret_cast<const uint8*>(signature.data()), signature.size(), reinterpret_cast<const uint8*>(spki.data()), spki.size()); if (!ok) { diff --git a/chromium/net/quic/crypto/proof_verifier_chromium.h b/chromium/net/quic/crypto/proof_verifier_chromium.h index 8786e52e7dd..4969cc8aa55 100644 --- a/chromium/net/quic/crypto/proof_verifier_chromium.h +++ b/chromium/net/quic/crypto/proof_verifier_chromium.h @@ -39,8 +39,7 @@ class NET_EXPORT_PRIVATE ProofVerifierChromium : public ProofVerifier { virtual ~ProofVerifierChromium(); // ProofVerifier interface - virtual Status VerifyProof(QuicVersion version, - const std::string& hostname, + virtual Status VerifyProof(const std::string& hostname, const std::string& server_config, const std::vector<std::string>& certs, const std::string& signature, @@ -60,8 +59,7 @@ class NET_EXPORT_PRIVATE ProofVerifierChromium : public ProofVerifier { int DoVerifyCert(int result); int DoVerifyCertComplete(int result); - bool VerifySignature(QuicVersion version, - const std::string& signed_data, + bool VerifySignature(const std::string& signed_data, const std::string& signature, const std::string& cert); diff --git a/chromium/net/quic/crypto/source_address_token.cc b/chromium/net/quic/crypto/source_address_token.cc index d15afebf2a7..b095e762265 100644 --- a/chromium/net/quic/crypto/source_address_token.cc +++ b/chromium/net/quic/crypto/source_address_token.cc @@ -21,24 +21,36 @@ SourceAddressToken::~SourceAddressToken() { } string SourceAddressToken::SerializeAsString() const { - return ip_ + " " + base::Int64ToString(timestamp_); + string out; + out.push_back(ip_.size()); + out.append(ip_); + string time_str = base::Int64ToString(timestamp_); + out.push_back(time_str.size()); + out.append(time_str); + return out; } bool SourceAddressToken::ParseFromArray(const char* plaintext, size_t plaintext_length) { - string data(plaintext, plaintext_length); - vector<string> results; - base::SplitString(data, ' ', &results); - if (results.size() < 2) { + if (plaintext_length == 0) { + return false; + } + size_t ip_len = plaintext[0]; + if (plaintext_length <= 1 + ip_len) { + return false; + } + size_t time_len = plaintext[1 + ip_len]; + if (plaintext_length != 1 + ip_len + 1 + time_len) { return false; } + string time_str(&plaintext[1 + ip_len + 1], time_len); int64 timestamp; - if (!base::StringToInt64(results[1], ×tamp)) { + if (!base::StringToInt64(time_str, ×tamp)) { return false; } - ip_ = results[0]; + ip_.assign(&plaintext[1], ip_len); timestamp_ = timestamp; return true; } diff --git a/chromium/net/quic/crypto/strike_register.cc b/chromium/net/quic/crypto/strike_register.cc index 97aca184cd0..f45bfabd9f0 100644 --- a/chromium/net/quic/crypto/strike_register.cc +++ b/chromium/net/quic/crypto/strike_register.cc @@ -56,8 +56,8 @@ class StrikeRegister::InternalNode { }; // kCreationTimeFromInternalEpoch contains the number of seconds between the -// start of the internal epoch and |creation_time_external_|. This allows us -// to consider times that are before |creation_time_external_|. +// start of the internal epoch and the creation time. This allows us +// to consider times that are before the creation time. static const uint32 kCreationTimeFromInternalEpoch = 63115200.0; // 2 years. StrikeRegister::StrikeRegister(unsigned max_entries, @@ -67,22 +67,17 @@ StrikeRegister::StrikeRegister(unsigned max_entries, StartupType startup) : max_entries_(max_entries), window_secs_(window_secs), + internal_epoch_(current_time > kCreationTimeFromInternalEpoch + ? current_time - kCreationTimeFromInternalEpoch + : 0), // The horizon is initially set |window_secs| into the future because, if // we just crashed, then we may have accepted nonces in the span // [current_time...current_time+window_secs) and so we conservatively // reject the whole timespan unless |startup| tells us otherwise. - creation_time_external_(current_time), - internal_epoch_(current_time > kCreationTimeFromInternalEpoch - ? current_time - kCreationTimeFromInternalEpoch - : 0), horizon_(ExternalTimeToInternal(current_time) + window_secs), horizon_valid_(startup == DENY_REQUESTS_AT_STARTUP) { memcpy(orbit_, orbit, sizeof(orbit_)); - // TODO(rtenneti): Remove the following check, Added the following to silence - // "is not used" error. - CHECK_GE(creation_time_external_, 0u); - // We only have 23 bits of index available. CHECK_LT(max_entries, 1u << 23); CHECK_GT(max_entries, 1u); // There must be at least two entries. diff --git a/chromium/net/quic/crypto/strike_register.h b/chromium/net/quic/crypto/strike_register.h index 98bc04cb630..fda62a802b2 100644 --- a/chromium/net/quic/crypto/strike_register.h +++ b/chromium/net/quic/crypto/strike_register.h @@ -129,7 +129,7 @@ class NET_EXPORT_PRIVATE StrikeRegister { static uint32 TimeFromBytes(const uint8 d[4]); // ExternalTimeToInternal converts an external time value into an internal - // time value using |creation_time_external_|. + // time value using |internal_epoch_|. uint32 ExternalTimeToInternal(uint32 external_time); // BestMatch returns either kNil, or an external node index which could @@ -164,10 +164,6 @@ class NET_EXPORT_PRIVATE StrikeRegister { const uint32 max_entries_; const uint32 window_secs_; - // creation_time_external_ contains the uint32, external time when this - // object was created (i.e. the value passed to the constructor). This is - // used to translate external times to internal times. - const uint32 creation_time_external_; // internal_epoch_ contains the external time value of the start of internal // time. const uint32 internal_epoch_; |