1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "net/quic/quic_crypto_client_stream.h" 6 7 #include "net/base/completion_callback.h" 8 #include "net/base/net_errors.h" 9 #include "net/quic/crypto/crypto_protocol.h" 10 #include "net/quic/crypto/crypto_utils.h" 11 #include "net/quic/crypto/null_encrypter.h" 12 #include "net/quic/crypto/proof_verifier.h" 13 #include "net/quic/crypto/proof_verifier_chromium.h" 14 #include "net/quic/quic_protocol.h" 15 #include "net/quic/quic_session.h" 16 #include "net/ssl/ssl_connection_status_flags.h" 17 #include "net/ssl/ssl_info.h" 18 19 namespace net { 20 21 namespace { 22 23 // Copies CertVerifyResult from |verify_details| to |cert_verify_result|. 24 void CopyCertVerifyResult( 25 const ProofVerifyDetails* verify_details, 26 scoped_ptr<CertVerifyResult>* cert_verify_result) { 27 const CertVerifyResult* cert_verify_result_other = 28 &(reinterpret_cast<const ProofVerifyDetailsChromium*>( 29 verify_details))->cert_verify_result; 30 CertVerifyResult* result_copy = new CertVerifyResult; 31 result_copy->CopyFrom(*cert_verify_result_other); 32 cert_verify_result->reset(result_copy); 33 } 34 35 } // namespace 36 37 QuicCryptoClientStream::ProofVerifierCallbackImpl::ProofVerifierCallbackImpl( 38 QuicCryptoClientStream* stream) 39 : stream_(stream) {} 40 41 QuicCryptoClientStream::ProofVerifierCallbackImpl:: 42 ~ProofVerifierCallbackImpl() {} 43 44 void QuicCryptoClientStream::ProofVerifierCallbackImpl::Run( 45 bool ok, 46 const string& error_details, 47 scoped_ptr<ProofVerifyDetails>* details) { 48 if (stream_ == NULL) { 49 return; 50 } 51 52 stream_->verify_ok_ = ok; 53 stream_->verify_error_details_ = error_details; 54 stream_->verify_details_.reset(details->release()); 55 stream_->proof_verify_callback_ = NULL; 56 stream_->DoHandshakeLoop(NULL); 57 58 // The ProofVerifier owns this object and will delete it when this method 59 // returns. 60 } 61 62 void QuicCryptoClientStream::ProofVerifierCallbackImpl::Cancel() { 63 stream_ = NULL; 64 } 65 66 67 QuicCryptoClientStream::QuicCryptoClientStream( 68 const string& server_hostname, 69 QuicSession* session, 70 QuicCryptoClientConfig* crypto_config) 71 : QuicCryptoStream(session), 72 next_state_(STATE_IDLE), 73 num_client_hellos_(0), 74 crypto_config_(crypto_config), 75 server_hostname_(server_hostname), 76 generation_counter_(0), 77 proof_verify_callback_(NULL) { 78 } 79 80 QuicCryptoClientStream::~QuicCryptoClientStream() { 81 if (proof_verify_callback_) { 82 proof_verify_callback_->Cancel(); 83 } 84 } 85 86 void QuicCryptoClientStream::OnHandshakeMessage( 87 const CryptoHandshakeMessage& message) { 88 DoHandshakeLoop(&message); 89 } 90 91 bool QuicCryptoClientStream::CryptoConnect() { 92 next_state_ = STATE_SEND_CHLO; 93 DoHandshakeLoop(NULL); 94 return true; 95 } 96 97 int QuicCryptoClientStream::num_sent_client_hellos() const { 98 return num_client_hellos_; 99 } 100 101 // TODO(rtenneti): Add unittests for GetSSLInfo which exercise the various ways 102 // we learn about SSL info (sync vs async vs cached). 103 bool QuicCryptoClientStream::GetSSLInfo(SSLInfo* ssl_info) { 104 ssl_info->Reset(); 105 if (!cert_verify_result_) { 106 return false; 107 } 108 109 ssl_info->cert_status = cert_verify_result_->cert_status; 110 ssl_info->cert = cert_verify_result_->verified_cert; 111 112 // TODO(rtenneti): Figure out what to set for the following. 113 // Temporarily hard coded cipher_suite as 0xc031 to represent 114 // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (from 115 // net/ssl/ssl_cipher_suite_names.cc) and encryption as 256. 116 int cipher_suite = 0xc02f; 117 int ssl_connection_status = 0; 118 ssl_connection_status |= 119 (cipher_suite & SSL_CONNECTION_CIPHERSUITE_MASK) << 120 SSL_CONNECTION_CIPHERSUITE_SHIFT; 121 ssl_connection_status |= 122 (SSL_CONNECTION_VERSION_TLS1_2 & SSL_CONNECTION_VERSION_MASK) << 123 SSL_CONNECTION_VERSION_SHIFT; 124 125 ssl_info->public_key_hashes = cert_verify_result_->public_key_hashes; 126 ssl_info->is_issued_by_known_root = 127 cert_verify_result_->is_issued_by_known_root; 128 129 ssl_info->connection_status = ssl_connection_status; 130 ssl_info->client_cert_sent = false; 131 ssl_info->channel_id_sent = false; 132 ssl_info->security_bits = 256; 133 ssl_info->handshake_type = SSLInfo::HANDSHAKE_FULL; 134 return true; 135 } 136 137 // kMaxClientHellos is the maximum number of times that we'll send a client 138 // hello. The value 3 accounts for: 139 // * One failure due to an incorrect or missing source-address token. 140 // * One failure due the server's certificate chain being unavailible and the 141 // server being unwilling to send it without a valid source-address token. 142 static const int kMaxClientHellos = 3; 143 144 void QuicCryptoClientStream::DoHandshakeLoop( 145 const CryptoHandshakeMessage* in) { 146 CryptoHandshakeMessage out; 147 QuicErrorCode error; 148 string error_details; 149 QuicCryptoClientConfig::CachedState* cached = 150 crypto_config_->LookupOrCreate(server_hostname_); 151 152 if (in != NULL) { 153 DVLOG(1) << "Client received: " << in->DebugString(); 154 } 155 156 for (;;) { 157 const State state = next_state_; 158 next_state_ = STATE_IDLE; 159 switch (state) { 160 case STATE_SEND_CHLO: { 161 // Send the client hello in plaintext. 162 session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_NONE); 163 if (num_client_hellos_ > kMaxClientHellos) { 164 CloseConnection(QUIC_CRYPTO_TOO_MANY_REJECTS); 165 return; 166 } 167 num_client_hellos_++; 168 169 if (!cached->IsComplete(session()->connection()->clock()->WallNow())) { 170 crypto_config_->FillInchoateClientHello( 171 server_hostname_, cached, &crypto_negotiated_params_, &out); 172 next_state_ = STATE_RECV_REJ; 173 DVLOG(1) << "Client Sending: " << out.DebugString(); 174 SendHandshakeMessage(out); 175 return; 176 } 177 session()->config()->ToHandshakeMessage(&out); 178 error = crypto_config_->FillClientHello( 179 server_hostname_, 180 session()->connection()->guid(), 181 cached, 182 session()->connection()->clock()->WallNow(), 183 session()->connection()->random_generator(), 184 &crypto_negotiated_params_, 185 &out, 186 &error_details); 187 if (error != QUIC_NO_ERROR) { 188 // Flush the cached config so that, if it's bad, the server has a 189 // chance to send us another in the future. 190 cached->InvalidateServerConfig(); 191 CloseConnectionWithDetails(error, error_details); 192 return; 193 } 194 if (cached->proof_verify_details()) { 195 CopyCertVerifyResult(cached->proof_verify_details(), 196 &cert_verify_result_); 197 } else { 198 cert_verify_result_.reset(); 199 } 200 next_state_ = STATE_RECV_SHLO; 201 DVLOG(1) << "Client Sending: " << out.DebugString(); 202 SendHandshakeMessage(out); 203 // Be prepared to decrypt with the new server write key. 204 session()->connection()->SetAlternativeDecrypter( 205 crypto_negotiated_params_.initial_crypters.decrypter.release(), 206 true /* latch once used */); 207 // Send subsequent packets under encryption on the assumption that the 208 // server will accept the handshake. 209 session()->connection()->SetEncrypter( 210 ENCRYPTION_INITIAL, 211 crypto_negotiated_params_.initial_crypters.encrypter.release()); 212 session()->connection()->SetDefaultEncryptionLevel( 213 ENCRYPTION_INITIAL); 214 if (!encryption_established_) { 215 encryption_established_ = true; 216 session()->OnCryptoHandshakeEvent( 217 QuicSession::ENCRYPTION_FIRST_ESTABLISHED); 218 } else { 219 session()->OnCryptoHandshakeEvent( 220 QuicSession::ENCRYPTION_REESTABLISHED); 221 } 222 return; 223 } 224 case STATE_RECV_REJ: 225 // We sent a dummy CHLO because we didn't have enough information to 226 // perform a handshake, or we sent a full hello that the server 227 // rejected. Here we hope to have a REJ that contains the information 228 // that we need. 229 if (in->tag() != kREJ) { 230 CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE, 231 "Expected REJ"); 232 return; 233 } 234 error = crypto_config_->ProcessRejection( 235 cached, *in, session()->connection()->clock()->WallNow(), 236 &crypto_negotiated_params_, &error_details); 237 if (error != QUIC_NO_ERROR) { 238 CloseConnectionWithDetails(error, error_details); 239 return; 240 } 241 if (!cached->proof_valid()) { 242 ProofVerifier* verifier = crypto_config_->proof_verifier(); 243 if (!verifier) { 244 // If no verifier is set then we don't check the certificates. 245 cached->SetProofValid(); 246 } else if (!cached->signature().empty()) { 247 next_state_ = STATE_VERIFY_PROOF; 248 break; 249 } 250 } 251 next_state_ = STATE_SEND_CHLO; 252 break; 253 case STATE_VERIFY_PROOF: { 254 ProofVerifier* verifier = crypto_config_->proof_verifier(); 255 DCHECK(verifier); 256 next_state_ = STATE_VERIFY_PROOF_COMPLETE; 257 generation_counter_ = cached->generation_counter(); 258 259 ProofVerifierCallbackImpl* proof_verify_callback = 260 new ProofVerifierCallbackImpl(this); 261 262 verify_ok_ = false; 263 264 ProofVerifier::Status status = verifier->VerifyProof( 265 session()->connection()->version(), 266 server_hostname_, 267 cached->server_config(), 268 cached->certs(), 269 cached->signature(), 270 &verify_error_details_, 271 &verify_details_, 272 proof_verify_callback); 273 274 switch (status) { 275 case ProofVerifier::PENDING: 276 proof_verify_callback_ = proof_verify_callback; 277 DVLOG(1) << "Doing VerifyProof"; 278 return; 279 case ProofVerifier::FAILURE: 280 break; 281 case ProofVerifier::SUCCESS: 282 verify_ok_ = true; 283 break; 284 } 285 break; 286 } 287 case STATE_VERIFY_PROOF_COMPLETE: 288 if (!verify_ok_) { 289 CopyCertVerifyResult(verify_details_.get(), &cert_verify_result_); 290 CloseConnectionWithDetails( 291 QUIC_PROOF_INVALID, "Proof invalid: " + verify_error_details_); 292 return; 293 } 294 // Check if generation_counter has changed between STATE_VERIFY_PROOF 295 // and STATE_VERIFY_PROOF_COMPLETE state changes. 296 if (generation_counter_ != cached->generation_counter()) { 297 next_state_ = STATE_VERIFY_PROOF; 298 } else { 299 cached->SetProofValid(); 300 cached->SetProofVerifyDetails(verify_details_.release()); 301 next_state_ = STATE_SEND_CHLO; 302 } 303 break; 304 case STATE_RECV_SHLO: { 305 // We sent a CHLO that we expected to be accepted and now we're hoping 306 // for a SHLO from the server to confirm that. 307 if (in->tag() == kREJ) { 308 // alternative_decrypter will be NULL if the original alternative 309 // decrypter latched and became the primary decrypter. That happens 310 // if we received a message encrypted with the INITIAL key. 311 if (session()->connection()->alternative_decrypter() == NULL) { 312 // The rejection was sent encrypted! 313 CloseConnectionWithDetails(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT, 314 "encrypted REJ message"); 315 return; 316 } 317 next_state_ = STATE_RECV_REJ; 318 break; 319 } 320 if (in->tag() != kSHLO) { 321 CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE, 322 "Expected SHLO or REJ"); 323 return; 324 } 325 // alternative_decrypter will be NULL if the original alternative 326 // decrypter latched and became the primary decrypter. That happens 327 // if we received a message encrypted with the INITIAL key. 328 if (session()->connection()->alternative_decrypter() != NULL) { 329 // The server hello was sent without encryption. 330 CloseConnectionWithDetails(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT, 331 "unencrypted SHLO message"); 332 return; 333 } 334 error = crypto_config_->ProcessServerHello( 335 *in, session()->connection()->guid(), &crypto_negotiated_params_, 336 &error_details); 337 if (error != QUIC_NO_ERROR) { 338 CloseConnectionWithDetails( 339 error, "Server hello invalid: " + error_details); 340 return; 341 } 342 error = session()->config()->ProcessServerHello(*in, &error_details); 343 if (error != QUIC_NO_ERROR) { 344 CloseConnectionWithDetails( 345 error, "Server hello invalid: " + error_details); 346 return; 347 } 348 CrypterPair* crypters = 349 &crypto_negotiated_params_.forward_secure_crypters; 350 // TODO(agl): we don't currently latch this decrypter because the idea 351 // has been floated that the server shouldn't send packets encrypted 352 // with the FORWARD_SECURE key until it receives a FORWARD_SECURE 353 // packet from the client. 354 session()->connection()->SetAlternativeDecrypter( 355 crypters->decrypter.release(), false /* don't latch */); 356 session()->connection()->SetEncrypter( 357 ENCRYPTION_FORWARD_SECURE, crypters->encrypter.release()); 358 session()->connection()->SetDefaultEncryptionLevel( 359 ENCRYPTION_FORWARD_SECURE); 360 361 handshake_confirmed_ = true; 362 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED); 363 return; 364 } 365 case STATE_IDLE: 366 // This means that the peer sent us a message that we weren't expecting. 367 CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE); 368 return; 369 } 370 } 371 } 372 373 } // namespace net 374