Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / net / quic / quic_crypto_client_stream.cc
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 "base/metrics/histogram.h"
8 #include "net/quic/crypto/crypto_protocol.h"
9 #include "net/quic/crypto/crypto_utils.h"
10 #include "net/quic/crypto/null_encrypter.h"
11 #include "net/quic/quic_client_session_base.h"
12 #include "net/quic/quic_protocol.h"
13 #include "net/quic/quic_session.h"
14
15 namespace net {
16
17 QuicCryptoClientStream::ChannelIDSourceCallbackImpl::
18 ChannelIDSourceCallbackImpl(QuicCryptoClientStream* stream)
19     : stream_(stream) {}
20
21 QuicCryptoClientStream::ChannelIDSourceCallbackImpl::
22 ~ChannelIDSourceCallbackImpl() {}
23
24 void QuicCryptoClientStream::ChannelIDSourceCallbackImpl::Run(
25     scoped_ptr<ChannelIDKey>* channel_id_key) {
26   if (stream_ == nullptr) {
27     return;
28   }
29
30   stream_->channel_id_key_.reset(channel_id_key->release());
31   stream_->channel_id_source_callback_run_ = true;
32   stream_->channel_id_source_callback_ = nullptr;
33   stream_->DoHandshakeLoop(nullptr);
34
35   // The ChannelIDSource owns this object and will delete it when this method
36   // returns.
37 }
38
39 void QuicCryptoClientStream::ChannelIDSourceCallbackImpl::Cancel() {
40   stream_ = nullptr;
41 }
42
43 QuicCryptoClientStream::ProofVerifierCallbackImpl::ProofVerifierCallbackImpl(
44     QuicCryptoClientStream* stream)
45     : stream_(stream) {}
46
47 QuicCryptoClientStream::ProofVerifierCallbackImpl::
48 ~ProofVerifierCallbackImpl() {}
49
50 void QuicCryptoClientStream::ProofVerifierCallbackImpl::Run(
51     bool ok,
52     const string& error_details,
53     scoped_ptr<ProofVerifyDetails>* details) {
54   if (stream_ == nullptr) {
55     return;
56   }
57
58   stream_->verify_ok_ = ok;
59   stream_->verify_error_details_ = error_details;
60   stream_->verify_details_.reset(details->release());
61   stream_->proof_verify_callback_ = nullptr;
62   stream_->DoHandshakeLoop(nullptr);
63
64   // The ProofVerifier owns this object and will delete it when this method
65   // returns.
66 }
67
68 void QuicCryptoClientStream::ProofVerifierCallbackImpl::Cancel() {
69   stream_ = nullptr;
70 }
71
72 QuicCryptoClientStream::QuicCryptoClientStream(
73     const QuicServerId& server_id,
74     QuicClientSessionBase* session,
75     ProofVerifyContext* verify_context,
76     QuicCryptoClientConfig* crypto_config)
77     : QuicCryptoStream(session),
78       next_state_(STATE_IDLE),
79       num_client_hellos_(0),
80       crypto_config_(crypto_config),
81       server_id_(server_id),
82       generation_counter_(0),
83       channel_id_sent_(false),
84       channel_id_source_callback_run_(false),
85       channel_id_source_callback_(nullptr),
86       verify_context_(verify_context),
87       proof_verify_callback_(nullptr) {}
88
89 QuicCryptoClientStream::~QuicCryptoClientStream() {
90   if (channel_id_source_callback_) {
91     channel_id_source_callback_->Cancel();
92   }
93   if (proof_verify_callback_) {
94     proof_verify_callback_->Cancel();
95   }
96 }
97
98 void QuicCryptoClientStream::OnHandshakeMessage(
99     const CryptoHandshakeMessage& message) {
100   QuicCryptoStream::OnHandshakeMessage(message);
101
102   if (message.tag() == kSCUP) {
103     if (!handshake_confirmed()) {
104       CloseConnection(QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE);
105       return;
106     }
107
108     // |message| is an update from the server, so we treat it differently from a
109     // handshake message.
110     HandleServerConfigUpdateMessage(message);
111     return;
112   }
113
114   // Do not process handshake messages after the handshake is confirmed.
115   if (handshake_confirmed()) {
116     CloseConnection(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE);
117     return;
118   }
119
120   DoHandshakeLoop(&message);
121 }
122
123 bool QuicCryptoClientStream::CryptoConnect() {
124   next_state_ = STATE_INITIALIZE;
125   DoHandshakeLoop(nullptr);
126   return true;
127 }
128
129 int QuicCryptoClientStream::num_sent_client_hellos() const {
130   return num_client_hellos_;
131 }
132
133 bool QuicCryptoClientStream::WasChannelIDSent() const {
134   return channel_id_sent_;
135 }
136
137 bool QuicCryptoClientStream::WasChannelIDSourceCallbackRun() const {
138   return channel_id_source_callback_run_;
139 }
140
141 void QuicCryptoClientStream::HandleServerConfigUpdateMessage(
142     const CryptoHandshakeMessage& server_config_update) {
143   DCHECK(server_config_update.tag() == kSCUP);
144   string error_details;
145   QuicCryptoClientConfig::CachedState* cached =
146       crypto_config_->LookupOrCreate(server_id_);
147   QuicErrorCode error = crypto_config_->ProcessServerConfigUpdate(
148       server_config_update,
149       session()->connection()->clock()->WallNow(),
150       cached,
151       &crypto_negotiated_params_,
152       &error_details);
153
154   if (error != QUIC_NO_ERROR) {
155     CloseConnectionWithDetails(
156         error, "Server config update invalid: " + error_details);
157     return;
158   }
159
160   DCHECK(handshake_confirmed());
161   if (proof_verify_callback_) {
162     proof_verify_callback_->Cancel();
163   }
164   next_state_ = STATE_INITIALIZE_SCUP;
165   DoHandshakeLoop(nullptr);
166 }
167
168 // kMaxClientHellos is the maximum number of times that we'll send a client
169 // hello. The value 3 accounts for:
170 //   * One failure due to an incorrect or missing source-address token.
171 //   * One failure due the server's certificate chain being unavailible and the
172 //     server being unwilling to send it without a valid source-address token.
173 static const int kMaxClientHellos = 3;
174
175 void QuicCryptoClientStream::DoHandshakeLoop(
176     const CryptoHandshakeMessage* in) {
177   QuicCryptoClientConfig::CachedState* cached =
178       crypto_config_->LookupOrCreate(server_id_);
179
180   QuicAsyncStatus rv = QUIC_SUCCESS;
181   do {
182     CHECK_NE(STATE_NONE, next_state_);
183     const State state = next_state_;
184     next_state_ = STATE_IDLE;
185     rv = QUIC_SUCCESS;
186     switch (state) {
187       case STATE_INITIALIZE:
188         DoInitialize(cached);
189         break;
190       case STATE_SEND_CHLO:
191         DoSendCHLO(in, cached);
192         return;
193       case STATE_RECV_REJ:
194         DoReceiveREJ(in, cached);
195         break;
196       case STATE_VERIFY_PROOF:
197         rv = DoVerifyProof(cached);
198         break;
199       case STATE_VERIFY_PROOF_COMPLETE:
200         DoVerifyProofComplete(cached);
201         break;
202       case STATE_GET_CHANNEL_ID:
203         rv = DoGetChannelID(cached);
204         break;
205       case STATE_GET_CHANNEL_ID_COMPLETE:
206         DoGetChannelIDComplete();
207         break;
208       case STATE_RECV_SHLO:
209         DoReceiveSHLO(in, cached);
210         break;
211       case STATE_IDLE:
212         // This means that the peer sent us a message that we weren't expecting.
213         CloseConnection(QUIC_INVALID_CRYPTO_MESSAGE_TYPE);
214         return;
215       case STATE_INITIALIZE_SCUP:
216         DoInitializeServerConfigUpdate(cached);
217         break;
218       case STATE_NONE:
219         NOTREACHED();
220         return;  // We are done.
221     }
222   } while (rv != QUIC_PENDING && next_state_ != STATE_NONE);
223 }
224
225 void QuicCryptoClientStream::DoInitialize(
226     QuicCryptoClientConfig::CachedState* cached) {
227   if (!cached->IsEmpty() && !cached->signature().empty() &&
228       server_id_.is_https()) {
229     // Note that we verify the proof even if the cached proof is valid.
230     // This allows us to respond to CA trust changes or certificate
231     // expiration because it may have been a while since we last verified
232     // the proof.
233     DCHECK(crypto_config_->proof_verifier());
234     // If the cached state needs to be verified, do it now.
235     next_state_ = STATE_VERIFY_PROOF;
236   } else {
237     next_state_ = STATE_GET_CHANNEL_ID;
238   }
239 }
240
241 void QuicCryptoClientStream::DoSendCHLO(
242     const CryptoHandshakeMessage* in,
243     QuicCryptoClientConfig::CachedState* cached) {
244   // Send the client hello in plaintext.
245   session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_NONE);
246   if (num_client_hellos_ > kMaxClientHellos) {
247     CloseConnection(QUIC_CRYPTO_TOO_MANY_REJECTS);
248     return;
249   }
250   num_client_hellos_++;
251
252   CryptoHandshakeMessage out;
253   if (!cached->IsComplete(session()->connection()->clock()->WallNow())) {
254     crypto_config_->FillInchoateClientHello(
255         server_id_,
256         session()->connection()->supported_versions().front(),
257         cached, &crypto_negotiated_params_, &out);
258     // Pad the inchoate client hello to fill up a packet.
259     const size_t kFramingOverhead = 50;  // A rough estimate.
260     const size_t max_packet_size =
261         session()->connection()->max_packet_length();
262     if (max_packet_size <= kFramingOverhead) {
263       DLOG(DFATAL) << "max_packet_length (" << max_packet_size
264                    << ") has no room for framing overhead.";
265       CloseConnection(QUIC_INTERNAL_ERROR);
266       return;
267     }
268     if (kClientHelloMinimumSize > max_packet_size - kFramingOverhead) {
269       DLOG(DFATAL) << "Client hello won't fit in a single packet.";
270       CloseConnection(QUIC_INTERNAL_ERROR);
271       return;
272     }
273     out.set_minimum_size(max_packet_size - kFramingOverhead);
274     next_state_ = STATE_RECV_REJ;
275     SendHandshakeMessage(out);
276     return;
277   }
278
279   session()->config()->ToHandshakeMessage(&out);
280   string error_details;
281   QuicErrorCode error = crypto_config_->FillClientHello(
282       server_id_,
283       session()->connection()->connection_id(),
284       session()->connection()->supported_versions().front(),
285       cached,
286       session()->connection()->clock()->WallNow(),
287       session()->connection()->random_generator(),
288       channel_id_key_.get(),
289       &crypto_negotiated_params_,
290       &out,
291       &error_details);
292   if (error != QUIC_NO_ERROR) {
293     // Flush the cached config so that, if it's bad, the server has a
294     // chance to send us another in the future.
295     cached->InvalidateServerConfig();
296     CloseConnectionWithDetails(error, error_details);
297     return;
298   }
299   channel_id_sent_ = (channel_id_key_.get() != nullptr);
300   if (cached->proof_verify_details()) {
301     client_session()->OnProofVerifyDetailsAvailable(
302         *cached->proof_verify_details());
303   }
304   next_state_ = STATE_RECV_SHLO;
305   SendHandshakeMessage(out);
306   // Be prepared to decrypt with the new server write key.
307   session()->connection()->SetAlternativeDecrypter(
308       crypto_negotiated_params_.initial_crypters.decrypter.release(),
309       ENCRYPTION_INITIAL,
310       true /* latch once used */);
311   // Send subsequent packets under encryption on the assumption that the
312   // server will accept the handshake.
313   session()->connection()->SetEncrypter(
314       ENCRYPTION_INITIAL,
315       crypto_negotiated_params_.initial_crypters.encrypter.release());
316   session()->connection()->SetDefaultEncryptionLevel(
317       ENCRYPTION_INITIAL);
318   if (!encryption_established_) {
319     encryption_established_ = true;
320     session()->OnCryptoHandshakeEvent(
321         QuicSession::ENCRYPTION_FIRST_ESTABLISHED);
322   } else {
323     session()->OnCryptoHandshakeEvent(
324         QuicSession::ENCRYPTION_REESTABLISHED);
325   }
326 }
327
328 void QuicCryptoClientStream::DoReceiveREJ(
329     const CryptoHandshakeMessage* in,
330     QuicCryptoClientConfig::CachedState* cached) {
331   // We sent a dummy CHLO because we didn't have enough information to
332   // perform a handshake, or we sent a full hello that the server
333   // rejected. Here we hope to have a REJ that contains the information
334   // that we need.
335   if (in->tag() != kREJ) {
336     next_state_ = STATE_NONE;
337     CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
338                                "Expected REJ");
339     return;
340   }
341   string error_details;
342   QuicErrorCode error = crypto_config_->ProcessRejection(
343       *in, session()->connection()->clock()->WallNow(), cached,
344       server_id_.is_https(), &crypto_negotiated_params_, &error_details);
345   if (error != QUIC_NO_ERROR) {
346     next_state_ = STATE_NONE;
347     CloseConnectionWithDetails(error, error_details);
348     return;
349   }
350   if (!cached->proof_valid()) {
351     if (!server_id_.is_https()) {
352       // We don't check the certificates for insecure QUIC connections.
353       SetCachedProofValid(cached);
354     } else if (!cached->signature().empty()) {
355       // Note that we only verify the proof if the cached proof is not
356       // valid. If the cached proof is valid here, someone else must have
357       // just added the server config to the cache and verified the proof,
358       // so we can assume no CA trust changes or certificate expiration
359       // has happened since then.
360       next_state_ = STATE_VERIFY_PROOF;
361       return;
362     }
363   }
364   next_state_ = STATE_GET_CHANNEL_ID;
365 }
366
367 QuicAsyncStatus QuicCryptoClientStream::DoVerifyProof(
368     QuicCryptoClientConfig::CachedState* cached) {
369   ProofVerifier* verifier = crypto_config_->proof_verifier();
370   DCHECK(verifier);
371   next_state_ = STATE_VERIFY_PROOF_COMPLETE;
372   generation_counter_ = cached->generation_counter();
373
374   ProofVerifierCallbackImpl* proof_verify_callback =
375       new ProofVerifierCallbackImpl(this);
376
377   verify_ok_ = false;
378
379   QuicAsyncStatus status = verifier->VerifyProof(
380       server_id_.host(),
381       cached->server_config(),
382       cached->certs(),
383       cached->signature(),
384       verify_context_.get(),
385       &verify_error_details_,
386       &verify_details_,
387       proof_verify_callback);
388
389   switch (status) {
390     case QUIC_PENDING:
391       proof_verify_callback_ = proof_verify_callback;
392       DVLOG(1) << "Doing VerifyProof";
393       break;
394     case QUIC_FAILURE:
395       delete proof_verify_callback;
396       break;
397     case QUIC_SUCCESS:
398       delete proof_verify_callback;
399       verify_ok_ = true;
400       break;
401   }
402   return status;
403 }
404
405 void QuicCryptoClientStream::DoVerifyProofComplete(
406     QuicCryptoClientConfig::CachedState* cached) {
407   if (!verify_ok_) {
408     next_state_ = STATE_NONE;
409     client_session()->OnProofVerifyDetailsAvailable(*verify_details_);
410     UMA_HISTOGRAM_BOOLEAN("Net.QuicVerifyProofFailed.HandshakeConfirmed",
411                           handshake_confirmed());
412     CloseConnectionWithDetails(
413         QUIC_PROOF_INVALID, "Proof invalid: " + verify_error_details_);
414     return;
415   }
416
417   // Check if generation_counter has changed between STATE_VERIFY_PROOF and
418   // STATE_VERIFY_PROOF_COMPLETE state changes.
419   if (generation_counter_ != cached->generation_counter()) {
420     next_state_ = STATE_VERIFY_PROOF;
421   } else {
422     SetCachedProofValid(cached);
423     cached->SetProofVerifyDetails(verify_details_.release());
424     if (!handshake_confirmed()) {
425       next_state_ = STATE_GET_CHANNEL_ID;
426     } else {
427       next_state_ = STATE_NONE;
428     }
429   }
430 }
431
432 QuicAsyncStatus QuicCryptoClientStream::DoGetChannelID(
433     QuicCryptoClientConfig::CachedState* cached) {
434   next_state_ = STATE_GET_CHANNEL_ID_COMPLETE;
435   channel_id_key_.reset();
436   if (!RequiresChannelID(cached)) {
437     next_state_ = STATE_SEND_CHLO;
438     return QUIC_SUCCESS;
439   }
440
441   ChannelIDSourceCallbackImpl* channel_id_source_callback =
442       new ChannelIDSourceCallbackImpl(this);
443   QuicAsyncStatus status =
444       crypto_config_->channel_id_source()->GetChannelIDKey(
445           server_id_.host(), &channel_id_key_,
446           channel_id_source_callback);
447
448   switch (status) {
449     case QUIC_PENDING:
450       channel_id_source_callback_ = channel_id_source_callback;
451       DVLOG(1) << "Looking up channel ID";
452       break;
453     case QUIC_FAILURE:
454       next_state_ = STATE_NONE;
455       delete channel_id_source_callback;
456       CloseConnectionWithDetails(QUIC_INVALID_CHANNEL_ID_SIGNATURE,
457                                  "Channel ID lookup failed");
458       break;
459     case QUIC_SUCCESS:
460       delete channel_id_source_callback;
461       break;
462   }
463   return status;
464 }
465
466 void QuicCryptoClientStream::DoGetChannelIDComplete() {
467   if (!channel_id_key_.get()) {
468     next_state_ = STATE_NONE;
469     CloseConnectionWithDetails(QUIC_INVALID_CHANNEL_ID_SIGNATURE,
470                                "Channel ID lookup failed");
471     return;
472   }
473   next_state_ = STATE_SEND_CHLO;
474 }
475
476 void QuicCryptoClientStream::DoReceiveSHLO(
477     const CryptoHandshakeMessage* in,
478     QuicCryptoClientConfig::CachedState* cached) {
479   next_state_ = STATE_NONE;
480   // We sent a CHLO that we expected to be accepted and now we're hoping
481   // for a SHLO from the server to confirm that.
482   if (in->tag() == kREJ) {
483     // alternative_decrypter will be nullptr if the original alternative
484     // decrypter latched and became the primary decrypter. That happens
485     // if we received a message encrypted with the INITIAL key.
486     if (session()->connection()->alternative_decrypter() == nullptr) {
487       // The rejection was sent encrypted!
488       CloseConnectionWithDetails(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT,
489                                  "encrypted REJ message");
490       return;
491     }
492     next_state_ = STATE_RECV_REJ;
493     return;
494   }
495
496   if (in->tag() != kSHLO) {
497     CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
498                                "Expected SHLO or REJ");
499     return;
500   }
501
502   // alternative_decrypter will be nullptr if the original alternative
503   // decrypter latched and became the primary decrypter. That happens
504   // if we received a message encrypted with the INITIAL key.
505   if (session()->connection()->alternative_decrypter() != nullptr) {
506     // The server hello was sent without encryption.
507     CloseConnectionWithDetails(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT,
508                                "unencrypted SHLO message");
509     return;
510   }
511
512   string error_details;
513   QuicErrorCode error = crypto_config_->ProcessServerHello(
514       *in, session()->connection()->connection_id(),
515       session()->connection()->server_supported_versions(),
516       cached, &crypto_negotiated_params_, &error_details);
517
518   if (error != QUIC_NO_ERROR) {
519     CloseConnectionWithDetails(error, "Server hello invalid: " + error_details);
520     return;
521   }
522   error = session()->config()->ProcessPeerHello(*in, SERVER, &error_details);
523   if (error != QUIC_NO_ERROR) {
524     CloseConnectionWithDetails(error, "Server hello invalid: " + error_details);
525     return;
526   }
527   session()->OnConfigNegotiated();
528
529   CrypterPair* crypters = &crypto_negotiated_params_.forward_secure_crypters;
530   // TODO(agl): we don't currently latch this decrypter because the idea
531   // has been floated that the server shouldn't send packets encrypted
532   // with the FORWARD_SECURE key until it receives a FORWARD_SECURE
533   // packet from the client.
534   session()->connection()->SetAlternativeDecrypter(
535       crypters->decrypter.release(), ENCRYPTION_FORWARD_SECURE,
536       false /* don't latch */);
537   session()->connection()->SetEncrypter(
538       ENCRYPTION_FORWARD_SECURE, crypters->encrypter.release());
539   session()->connection()->SetDefaultEncryptionLevel(
540       ENCRYPTION_FORWARD_SECURE);
541
542   handshake_confirmed_ = true;
543   session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED);
544   session()->connection()->OnHandshakeComplete();
545 }
546
547 void QuicCryptoClientStream::DoInitializeServerConfigUpdate(
548     QuicCryptoClientConfig::CachedState* cached) {
549   bool update_ignored = false;
550   if (!server_id_.is_https()) {
551     // We don't check the certificates for insecure QUIC connections.
552     SetCachedProofValid(cached);
553     next_state_ = STATE_NONE;
554   } else if (!cached->IsEmpty() && !cached->signature().empty()) {
555     // Note that we verify the proof even if the cached proof is valid.
556     DCHECK(crypto_config_->proof_verifier());
557     next_state_ = STATE_VERIFY_PROOF;
558   } else {
559     update_ignored = true;
560     next_state_ = STATE_NONE;
561   }
562   UMA_HISTOGRAM_COUNTS("Net.QuicNumServerConfig.UpdateMessagesIgnored",
563                        update_ignored);
564 }
565
566 void QuicCryptoClientStream::SetCachedProofValid(
567     QuicCryptoClientConfig::CachedState* cached) {
568   cached->SetProofValid();
569   client_session()->OnProofValid(*cached);
570 }
571
572 bool QuicCryptoClientStream::RequiresChannelID(
573     QuicCryptoClientConfig::CachedState* cached) {
574   if (!server_id_.is_https() ||
575       server_id_.privacy_mode() == PRIVACY_MODE_ENABLED ||
576       !crypto_config_->channel_id_source()) {
577     return false;
578   }
579   const CryptoHandshakeMessage* scfg = cached->GetServerConfig();
580   if (!scfg) {  // scfg may be null when we send an inchoate CHLO.
581     return false;
582   }
583   const QuicTag* their_proof_demands;
584   size_t num_their_proof_demands;
585   if (scfg->GetTaglist(kPDMD, &their_proof_demands,
586                        &num_their_proof_demands) != QUIC_NO_ERROR) {
587     return false;
588   }
589   for (size_t i = 0; i < num_their_proof_demands; i++) {
590     if (their_proof_demands[i] == kCHID) {
591       return true;
592     }
593   }
594   return false;
595 }
596
597 QuicClientSessionBase* QuicCryptoClientStream::client_session() {
598   return reinterpret_cast<QuicClientSessionBase*>(session());
599 }
600
601 }  // namespace net