crypto_handshake.cc revision d3868032626d59662ff73b372b5d584c1d144c53
1// Copyright (c) 2013 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/crypto/crypto_handshake.h"
6
7#include <ctype.h>
8
9#include "base/memory/scoped_ptr.h"
10#include "base/stl_util.h"
11#include "base/strings/stringprintf.h"
12#include "base/strings/string_number_conversions.h"
13#include "base/strings/string_split.h"
14#include "crypto/secure_hash.h"
15#include "net/base/net_util.h"
16#include "net/quic/crypto/cert_compressor.h"
17#include "net/quic/crypto/channel_id.h"
18#include "net/quic/crypto/common_cert_set.h"
19#include "net/quic/crypto/crypto_framer.h"
20#include "net/quic/crypto/crypto_utils.h"
21#include "net/quic/crypto/curve25519_key_exchange.h"
22#include "net/quic/crypto/key_exchange.h"
23#include "net/quic/crypto/p256_key_exchange.h"
24#include "net/quic/crypto/proof_verifier.h"
25#include "net/quic/crypto/quic_decrypter.h"
26#include "net/quic/crypto/quic_encrypter.h"
27#include "net/quic/crypto/quic_random.h"
28#include "net/quic/quic_protocol.h"
29#include "net/quic/quic_utils.h"
30
31using base::StringPiece;
32using base::StringPrintf;
33using std::map;
34using std::string;
35using std::vector;
36
37namespace net {
38
39CryptoHandshakeMessage::CryptoHandshakeMessage()
40    : tag_(0),
41      minimum_size_(0) {}
42
43CryptoHandshakeMessage::CryptoHandshakeMessage(
44    const CryptoHandshakeMessage& other)
45    : tag_(other.tag_),
46      tag_value_map_(other.tag_value_map_),
47      minimum_size_(other.minimum_size_) {
48  // Don't copy serialized_. scoped_ptr doesn't have a copy constructor.
49  // The new object can lazily reconstruct serialized_.
50}
51
52CryptoHandshakeMessage::~CryptoHandshakeMessage() {}
53
54CryptoHandshakeMessage& CryptoHandshakeMessage::operator=(
55    const CryptoHandshakeMessage& other) {
56  tag_ = other.tag_;
57  tag_value_map_ = other.tag_value_map_;
58  // Don't copy serialized_. scoped_ptr doesn't have an assignment operator.
59  // However, invalidate serialized_.
60  serialized_.reset();
61  minimum_size_ = other.minimum_size_;
62  return *this;
63}
64
65void CryptoHandshakeMessage::Clear() {
66  tag_ = 0;
67  tag_value_map_.clear();
68  minimum_size_ = 0;
69  serialized_.reset();
70}
71
72const QuicData& CryptoHandshakeMessage::GetSerialized() const {
73  if (!serialized_.get()) {
74    serialized_.reset(CryptoFramer::ConstructHandshakeMessage(*this));
75  }
76  return *serialized_.get();
77}
78
79void CryptoHandshakeMessage::MarkDirty() {
80  serialized_.reset();
81}
82
83void CryptoHandshakeMessage::Insert(QuicTagValueMap::const_iterator begin,
84                                    QuicTagValueMap::const_iterator end) {
85  tag_value_map_.insert(begin, end);
86}
87
88void CryptoHandshakeMessage::SetTaglist(QuicTag tag, ...) {
89  // Warning, if sizeof(QuicTag) > sizeof(int) then this function will break
90  // because the terminating 0 will only be promoted to int.
91  COMPILE_ASSERT(sizeof(QuicTag) <= sizeof(int),
92                 crypto_tag_may_not_be_larger_than_int_or_varargs_will_break);
93
94  vector<QuicTag> tags;
95  va_list ap;
96
97  va_start(ap, tag);
98  for (;;) {
99    QuicTag list_item = va_arg(ap, QuicTag);
100    if (list_item == 0) {
101      break;
102    }
103    tags.push_back(list_item);
104  }
105
106  // Because of the way that we keep tags in memory, we can copy the contents
107  // of the vector and get the correct bytes in wire format. See
108  // crypto_protocol.h. This assumes that the system is little-endian.
109  SetVector(tag, tags);
110
111  va_end(ap);
112}
113
114void CryptoHandshakeMessage::SetStringPiece(QuicTag tag, StringPiece value) {
115  tag_value_map_[tag] = value.as_string();
116}
117
118void CryptoHandshakeMessage::Erase(QuicTag tag) {
119  tag_value_map_.erase(tag);
120}
121
122QuicErrorCode CryptoHandshakeMessage::GetTaglist(QuicTag tag,
123                                                 const QuicTag** out_tags,
124                                                 size_t* out_len) const {
125  QuicTagValueMap::const_iterator it = tag_value_map_.find(tag);
126  QuicErrorCode ret = QUIC_NO_ERROR;
127
128  if (it == tag_value_map_.end()) {
129    ret = QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
130  } else if (it->second.size() % sizeof(QuicTag) != 0) {
131    ret = QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
132  }
133
134  if (ret != QUIC_NO_ERROR) {
135    *out_tags = NULL;
136    *out_len = 0;
137    return ret;
138  }
139
140  *out_tags = reinterpret_cast<const QuicTag*>(it->second.data());
141  *out_len = it->second.size() / sizeof(QuicTag);
142  return ret;
143}
144
145bool CryptoHandshakeMessage::GetStringPiece(QuicTag tag,
146                                            StringPiece* out) const {
147  QuicTagValueMap::const_iterator it = tag_value_map_.find(tag);
148  if (it == tag_value_map_.end()) {
149    return false;
150  }
151  *out = it->second;
152  return true;
153}
154
155QuicErrorCode CryptoHandshakeMessage::GetNthValue24(QuicTag tag,
156                                                    unsigned index,
157                                                    StringPiece* out) const {
158  StringPiece value;
159  if (!GetStringPiece(tag, &value)) {
160    return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
161  }
162
163  for (unsigned i = 0;; i++) {
164    if (value.empty()) {
165      return QUIC_CRYPTO_MESSAGE_INDEX_NOT_FOUND;
166    }
167    if (value.size() < 3) {
168      return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
169    }
170
171    const unsigned char* data =
172        reinterpret_cast<const unsigned char*>(value.data());
173    size_t size = static_cast<size_t>(data[0]) |
174                  (static_cast<size_t>(data[1]) << 8) |
175                  (static_cast<size_t>(data[2]) << 16);
176    value.remove_prefix(3);
177
178    if (value.size() < size) {
179      return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
180    }
181
182    if (i == index) {
183      *out = StringPiece(value.data(), size);
184      return QUIC_NO_ERROR;
185    }
186
187    value.remove_prefix(size);
188  }
189}
190
191QuicErrorCode CryptoHandshakeMessage::GetUint16(QuicTag tag,
192                                                uint16* out) const {
193  return GetPOD(tag, out, sizeof(uint16));
194}
195
196QuicErrorCode CryptoHandshakeMessage::GetUint32(QuicTag tag,
197                                                uint32* out) const {
198  return GetPOD(tag, out, sizeof(uint32));
199}
200
201QuicErrorCode CryptoHandshakeMessage::GetUint64(QuicTag tag,
202                                                uint64* out) const {
203  return GetPOD(tag, out, sizeof(uint64));
204}
205
206size_t CryptoHandshakeMessage::size() const {
207  size_t ret = sizeof(QuicTag) +
208               sizeof(uint16) /* number of entries */ +
209               sizeof(uint16) /* padding */;
210  ret += (sizeof(QuicTag) + sizeof(uint32) /* end offset */) *
211         tag_value_map_.size();
212  for (QuicTagValueMap::const_iterator i = tag_value_map_.begin();
213       i != tag_value_map_.end(); ++i) {
214    ret += i->second.size();
215  }
216
217  return ret;
218}
219
220void CryptoHandshakeMessage::set_minimum_size(size_t min_bytes) {
221  if (min_bytes == minimum_size_) {
222    return;
223  }
224  serialized_.reset();
225  minimum_size_ = min_bytes;
226}
227
228size_t CryptoHandshakeMessage::minimum_size() const {
229  return minimum_size_;
230}
231
232string CryptoHandshakeMessage::DebugString() const {
233  return DebugStringInternal(0);
234}
235
236QuicErrorCode CryptoHandshakeMessage::GetPOD(
237    QuicTag tag, void* out, size_t len) const {
238  QuicTagValueMap::const_iterator it = tag_value_map_.find(tag);
239  QuicErrorCode ret = QUIC_NO_ERROR;
240
241  if (it == tag_value_map_.end()) {
242    ret = QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
243  } else if (it->second.size() != len) {
244    ret = QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
245  }
246
247  if (ret != QUIC_NO_ERROR) {
248    memset(out, 0, len);
249    return ret;
250  }
251
252  memcpy(out, it->second.data(), len);
253  return ret;
254}
255
256string CryptoHandshakeMessage::DebugStringInternal(size_t indent) const {
257  string ret = string(2 * indent, ' ') + QuicUtils::TagToString(tag_) + "<\n";
258  ++indent;
259  for (QuicTagValueMap::const_iterator it = tag_value_map_.begin();
260       it != tag_value_map_.end(); ++it) {
261    ret += string(2 * indent, ' ') + QuicUtils::TagToString(it->first) + ": ";
262
263    bool done = false;
264    switch (it->first) {
265      case kKATO:
266      case kVERS:
267        // uint32 value
268        if (it->second.size() == 4) {
269          uint32 value;
270          memcpy(&value, it->second.data(), sizeof(value));
271          ret += base::UintToString(value);
272          done = true;
273        }
274        break;
275      case kKEXS:
276      case kAEAD:
277      case kCGST:
278      case kPDMD:
279        // tag lists
280        if (it->second.size() % sizeof(QuicTag) == 0) {
281          for (size_t j = 0; j < it->second.size(); j += sizeof(QuicTag)) {
282            QuicTag tag;
283            memcpy(&tag, it->second.data() + j, sizeof(tag));
284            if (j > 0) {
285              ret += ",";
286            }
287            ret += QuicUtils::TagToString(tag);
288          }
289          done = true;
290        }
291        break;
292      case kSCFG:
293        // nested messages.
294        if (!it->second.empty()) {
295          scoped_ptr<CryptoHandshakeMessage> msg(
296              CryptoFramer::ParseMessage(it->second));
297          if (msg.get()) {
298            ret += "\n";
299            ret += msg->DebugStringInternal(indent + 1);
300
301            done = true;
302          }
303        }
304        break;
305      case kPAD:
306        ret += StringPrintf("(%d bytes of padding)",
307                            static_cast<int>(it->second.size()));
308        done = true;
309        break;
310    }
311
312    if (!done) {
313      // If there's no specific format for this tag, or the value is invalid,
314      // then just use hex.
315      ret += base::HexEncode(it->second.data(), it->second.size());
316    }
317    ret += "\n";
318  }
319  --indent;
320  ret += string(2 * indent, ' ') + ">";
321  return ret;
322}
323
324QuicCryptoNegotiatedParameters::QuicCryptoNegotiatedParameters()
325    : version(0),
326      key_exchange(0),
327      aead(0) {
328}
329
330QuicCryptoNegotiatedParameters::~QuicCryptoNegotiatedParameters() {}
331
332CrypterPair::CrypterPair() {}
333
334CrypterPair::~CrypterPair() {}
335
336// static
337const char QuicCryptoConfig::kInitialLabel[] = "QUIC key expansion";
338
339// static
340const char QuicCryptoConfig::kCETVLabel[] = "QUIC CETV block";
341
342// static
343const char QuicCryptoConfig::kForwardSecureLabel[] =
344    "QUIC forward secure key expansion";
345
346QuicCryptoConfig::QuicCryptoConfig()
347    : version(0),
348      common_cert_sets(CommonCertSets::GetInstanceQUIC()) {
349}
350
351QuicCryptoConfig::~QuicCryptoConfig() {}
352
353QuicCryptoClientConfig::QuicCryptoClientConfig() {}
354
355QuicCryptoClientConfig::~QuicCryptoClientConfig() {
356  STLDeleteValues(&cached_states_);
357}
358
359QuicCryptoClientConfig::CachedState::CachedState()
360    : server_config_valid_(false),
361      generation_counter_(0) {}
362
363QuicCryptoClientConfig::CachedState::~CachedState() {}
364
365bool QuicCryptoClientConfig::CachedState::IsComplete(QuicWallTime now) const {
366  if (server_config_.empty() || !server_config_valid_) {
367    return false;
368  }
369
370  const CryptoHandshakeMessage* scfg = GetServerConfig();
371  if (!scfg) {
372    // Should be impossible short of cache corruption.
373    DCHECK(false);
374    return false;
375  }
376
377  uint64 expiry_seconds;
378  if (scfg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR ||
379      now.ToUNIXSeconds() >= expiry_seconds) {
380    return false;
381  }
382
383  return true;
384}
385
386const CryptoHandshakeMessage*
387QuicCryptoClientConfig::CachedState::GetServerConfig() const {
388  if (server_config_.empty()) {
389    return NULL;
390  }
391
392  if (!scfg_.get()) {
393    scfg_.reset(CryptoFramer::ParseMessage(server_config_));
394    DCHECK(scfg_.get());
395  }
396  return scfg_.get();
397}
398
399QuicErrorCode QuicCryptoClientConfig::CachedState::SetServerConfig(
400    StringPiece server_config, QuicWallTime now, string* error_details) {
401  const bool matches_existing = server_config == server_config_;
402
403  // Even if the new server config matches the existing one, we still wish to
404  // reject it if it has expired.
405  scoped_ptr<CryptoHandshakeMessage> new_scfg_storage;
406  const CryptoHandshakeMessage* new_scfg;
407
408  if (!matches_existing) {
409    new_scfg_storage.reset(CryptoFramer::ParseMessage(server_config));
410    new_scfg = new_scfg_storage.get();
411  } else {
412    new_scfg = GetServerConfig();
413  }
414
415  if (!new_scfg) {
416    *error_details = "SCFG invalid";
417    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
418  }
419
420  uint64 expiry_seconds;
421  if (new_scfg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR) {
422    *error_details = "SCFG missing EXPY";
423    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
424  }
425
426  if (now.ToUNIXSeconds() >= expiry_seconds) {
427    *error_details = "SCFG has expired";
428    return QUIC_CRYPTO_SERVER_CONFIG_EXPIRED;
429  }
430
431  if (!matches_existing) {
432    server_config_ = server_config.as_string();
433    SetProofInvalid();
434    scfg_.reset(new_scfg_storage.release());
435  }
436  return QUIC_NO_ERROR;
437}
438
439void QuicCryptoClientConfig::CachedState::InvalidateServerConfig() {
440  server_config_.clear();
441  scfg_.reset();
442  SetProofInvalid();
443}
444
445void QuicCryptoClientConfig::CachedState::SetProof(const vector<string>& certs,
446                                                   StringPiece signature) {
447  bool has_changed =
448      signature != server_config_sig_ || certs_.size() != certs.size();
449
450  if (!has_changed) {
451    for (size_t i = 0; i < certs_.size(); i++) {
452      if (certs_[i] != certs[i]) {
453        has_changed = true;
454        break;
455      }
456    }
457  }
458
459  if (!has_changed) {
460    return;
461  }
462
463  // If the proof has changed then it needs to be revalidated.
464  SetProofInvalid();
465  certs_ = certs;
466  server_config_sig_ = signature.as_string();
467}
468
469void QuicCryptoClientConfig::CachedState::SetProofValid() {
470  server_config_valid_ = true;
471}
472
473void QuicCryptoClientConfig::CachedState::SetProofInvalid() {
474  server_config_valid_ = false;
475  ++generation_counter_;
476}
477
478const string& QuicCryptoClientConfig::CachedState::server_config() const {
479  return server_config_;
480}
481
482const string&
483QuicCryptoClientConfig::CachedState::source_address_token() const {
484  return source_address_token_;
485}
486
487const vector<string>& QuicCryptoClientConfig::CachedState::certs() const {
488  return certs_;
489}
490
491const string& QuicCryptoClientConfig::CachedState::signature() const {
492  return server_config_sig_;
493}
494
495bool QuicCryptoClientConfig::CachedState::proof_valid() const {
496  return server_config_valid_;
497}
498
499uint64 QuicCryptoClientConfig::CachedState::generation_counter() const {
500  return generation_counter_;
501}
502
503const ProofVerifyDetails*
504QuicCryptoClientConfig::CachedState::proof_verify_details() const {
505  return proof_verify_details_.get();
506}
507
508void QuicCryptoClientConfig::CachedState::set_source_address_token(
509    StringPiece token) {
510  source_address_token_ = token.as_string();
511}
512
513void QuicCryptoClientConfig::CachedState::SetProofVerifyDetails(
514    ProofVerifyDetails* details) {
515  proof_verify_details_.reset(details);
516}
517
518void QuicCryptoClientConfig::SetDefaults() {
519  // Version must be 0.
520  // TODO(agl): this version stuff is obsolete now.
521  version = QuicCryptoConfig::CONFIG_VERSION;
522
523  // Key exchange methods.
524  kexs.resize(2);
525  kexs[0] = kC255;
526  kexs[1] = kP256;
527
528  // Authenticated encryption algorithms.
529  aead.resize(1);
530  aead[0] = kAESG;
531}
532
533QuicCryptoClientConfig::CachedState* QuicCryptoClientConfig::LookupOrCreate(
534    const string& server_hostname) {
535  map<string, CachedState*>::const_iterator it =
536      cached_states_.find(server_hostname);
537  if (it != cached_states_.end()) {
538    return it->second;
539  }
540
541  CachedState* cached = new CachedState;
542  cached_states_.insert(make_pair(server_hostname, cached));
543  return cached;
544}
545
546void QuicCryptoClientConfig::FillInchoateClientHello(
547    const string& server_hostname,
548    const CachedState* cached,
549    QuicCryptoNegotiatedParameters* out_params,
550    CryptoHandshakeMessage* out) const {
551  out->set_tag(kCHLO);
552  out->set_minimum_size(kClientHelloMinimumSize);
553
554  // Server name indication. We only send SNI if it's a valid domain name, as
555  // per the spec.
556  if (CryptoUtils::IsValidSNI(server_hostname)) {
557    out->SetStringPiece(kSNI, server_hostname);
558  }
559  out->SetValue(kVERS, version);
560
561  if (!cached->source_address_token().empty()) {
562    out->SetStringPiece(kSourceAddressTokenTag, cached->source_address_token());
563  }
564
565  if (proof_verifier_.get()) {
566    // TODO(rtenneti): Enable ECDSA proof verification on Windows. Disabled it
567    // because X509Certificate::GetPublicKeyInfo is not returning the correct
568    // type for ECDSA certificates.
569#if defined(OS_WIN)
570    out->SetTaglist(kPDMD, kX59R, 0);
571#else
572    out->SetTaglist(kPDMD, kX509, 0);
573#endif
574  }
575
576  if (proof_verifier_.get() && !cached->proof_valid()) {
577    // If we are expecting a certificate chain, double the size of the client
578    // hello so that the response from the server can be larger - hopefully
579    // including the whole certificate chain.
580    out->set_minimum_size(kClientHelloMinimumSize * 2);
581  }
582
583  if (common_cert_sets) {
584    out->SetStringPiece(kCCS, common_cert_sets->GetCommonHashes());
585  }
586
587  const vector<string>& certs = cached->certs();
588  // We save |certs| in the QuicCryptoNegotiatedParameters so that, if the
589  // client config is being used for multiple connections, another connection
590  // doesn't update the cached certificates and cause us to be unable to
591  // process the server's compressed certificate chain.
592  out_params->cached_certs = certs;
593  if (!certs.empty()) {
594    vector<uint64> hashes;
595    hashes.reserve(certs.size());
596    for (vector<string>::const_iterator i = certs.begin();
597         i != certs.end(); ++i) {
598      hashes.push_back(QuicUtils::FNV1a_64_Hash(i->data(), i->size()));
599    }
600    out->SetVector(kCCRT, hashes);
601  }
602}
603
604QuicErrorCode QuicCryptoClientConfig::FillClientHello(
605    const string& server_hostname,
606    QuicGuid guid,
607    const CachedState* cached,
608    QuicWallTime now,
609    QuicRandom* rand,
610    QuicCryptoNegotiatedParameters* out_params,
611    CryptoHandshakeMessage* out,
612    string* error_details) const {
613  DCHECK(error_details != NULL);
614
615  FillInchoateClientHello(server_hostname, cached, out_params, out);
616
617  const CryptoHandshakeMessage* scfg = cached->GetServerConfig();
618  if (!scfg) {
619    // This should never happen as our caller should have checked
620    // cached->IsComplete() before calling this function.
621    *error_details = "Handshake not ready";
622    return QUIC_CRYPTO_INTERNAL_ERROR;
623  }
624
625  StringPiece scid;
626  if (!scfg->GetStringPiece(kSCID, &scid)) {
627    *error_details = "SCFG missing SCID";
628    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
629  }
630  out->SetStringPiece(kSCID, scid);
631
632  const QuicTag* their_aeads;
633  const QuicTag* their_key_exchanges;
634  size_t num_their_aeads, num_their_key_exchanges;
635  if (scfg->GetTaglist(kAEAD, &their_aeads,
636                       &num_their_aeads) != QUIC_NO_ERROR ||
637      scfg->GetTaglist(kKEXS, &their_key_exchanges,
638                       &num_their_key_exchanges) != QUIC_NO_ERROR) {
639    *error_details = "Missing AEAD or KEXS";
640    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
641  }
642
643  size_t key_exchange_index;
644  if (!QuicUtils::FindMutualTag(
645          aead, their_aeads, num_their_aeads, QuicUtils::PEER_PRIORITY,
646          &out_params->aead, NULL) ||
647      !QuicUtils::FindMutualTag(
648          kexs, their_key_exchanges, num_their_key_exchanges,
649          QuicUtils::PEER_PRIORITY, &out_params->key_exchange,
650          &key_exchange_index)) {
651    *error_details = "Unsupported AEAD or KEXS";
652    return QUIC_CRYPTO_NO_SUPPORT;
653  }
654  out->SetTaglist(kAEAD, out_params->aead, 0);
655  out->SetTaglist(kKEXS, out_params->key_exchange, 0);
656
657  StringPiece public_value;
658  if (scfg->GetNthValue24(kPUBS, key_exchange_index, &public_value) !=
659          QUIC_NO_ERROR) {
660    *error_details = "Missing public value";
661    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
662  }
663
664  StringPiece orbit;
665  if (!scfg->GetStringPiece(kORBT, &orbit) || orbit.size() != kOrbitSize) {
666    *error_details = "SCFG missing OBIT";
667    return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
668  }
669
670  CryptoUtils::GenerateNonce(now, rand, orbit, &out_params->client_nonce);
671  out->SetStringPiece(kNONC, out_params->client_nonce);
672  if (!out_params->server_nonce.empty()) {
673    out->SetStringPiece(kServerNonceTag, out_params->server_nonce);
674  }
675
676  switch (out_params->key_exchange) {
677    case kC255:
678      out_params->client_key_exchange.reset(Curve25519KeyExchange::New(
679          Curve25519KeyExchange::NewPrivateKey(rand)));
680      break;
681    case kP256:
682      out_params->client_key_exchange.reset(P256KeyExchange::New(
683          P256KeyExchange::NewPrivateKey()));
684      break;
685    default:
686      DCHECK(false);
687      *error_details = "Configured to support an unknown key exchange";
688      return QUIC_CRYPTO_INTERNAL_ERROR;
689  }
690
691  if (!out_params->client_key_exchange->CalculateSharedKey(
692          public_value, &out_params->initial_premaster_secret)) {
693    *error_details = "Key exchange failure";
694    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
695  }
696  out->SetStringPiece(kPUBS, out_params->client_key_exchange->public_value());
697
698  bool do_channel_id = false;
699  if (channel_id_signer_.get()) {
700    const QuicTag* their_proof_demands;
701    size_t num_their_proof_demands;
702    if (scfg->GetTaglist(kPDMD, &their_proof_demands,
703                         &num_their_proof_demands) == QUIC_NO_ERROR) {
704      for (size_t i = 0; i < num_their_proof_demands; i++) {
705        if (their_proof_demands[i] == kCHID) {
706          do_channel_id = true;
707          break;
708        }
709      }
710    }
711  }
712
713  if (do_channel_id) {
714    // In order to calculate the encryption key for the CETV block we need to
715    // serialise the client hello as it currently is (i.e. without the CETV
716    // block). For this, the client hello is serialized without padding.
717    const size_t orig_min_size = out->minimum_size();
718    out->set_minimum_size(0);
719
720    CryptoHandshakeMessage cetv;
721    cetv.set_tag(kCETV);
722
723    string hkdf_input;
724    const QuicData& client_hello_serialized = out->GetSerialized();
725    hkdf_input.append(QuicCryptoConfig::kCETVLabel,
726                      strlen(QuicCryptoConfig::kCETVLabel) + 1);
727    hkdf_input.append(reinterpret_cast<char*>(&guid), sizeof(guid));
728    hkdf_input.append(client_hello_serialized.data(),
729                      client_hello_serialized.length());
730    hkdf_input.append(cached->server_config());
731
732    string key, signature;
733    if (!channel_id_signer_->Sign(server_hostname, hkdf_input,
734                                  &key, &signature)) {
735      *error_details = "Channel ID signature failed";
736      return QUIC_INTERNAL_ERROR;
737    }
738
739    cetv.SetStringPiece(kCIDK, key);
740    cetv.SetStringPiece(kCIDS, signature);
741
742    CrypterPair crypters;
743    CryptoUtils::DeriveKeys(out_params->initial_premaster_secret,
744                            out_params->aead, out_params->client_nonce,
745                            out_params->server_nonce, hkdf_input,
746                            CryptoUtils::CLIENT, &crypters);
747
748    const QuicData& cetv_plaintext = cetv.GetSerialized();
749    scoped_ptr<QuicData> cetv_ciphertext(crypters.encrypter->EncryptPacket(
750        0 /* sequence number */,
751        StringPiece() /* associated data */,
752        cetv_plaintext.AsStringPiece()));
753
754    out->SetStringPiece(kCETV, cetv_ciphertext->AsStringPiece());
755    out->MarkDirty();
756
757    out->set_minimum_size(orig_min_size);
758  }
759
760  out_params->hkdf_input_suffix.clear();
761  out_params->hkdf_input_suffix.append(reinterpret_cast<char*>(&guid),
762                                       sizeof(guid));
763  const QuicData& client_hello_serialized = out->GetSerialized();
764  out_params->hkdf_input_suffix.append(client_hello_serialized.data(),
765                                       client_hello_serialized.length());
766  out_params->hkdf_input_suffix.append(cached->server_config());
767
768  string hkdf_input;
769  const size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1;
770  hkdf_input.reserve(label_len + out_params->hkdf_input_suffix.size());
771  hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len);
772  hkdf_input.append(out_params->hkdf_input_suffix);
773
774  CryptoUtils::DeriveKeys(out_params->initial_premaster_secret,
775                          out_params->aead, out_params->client_nonce,
776                          out_params->server_nonce, hkdf_input,
777                          CryptoUtils::CLIENT, &out_params->initial_crypters);
778
779  return QUIC_NO_ERROR;
780}
781
782QuicErrorCode QuicCryptoClientConfig::ProcessRejection(
783    CachedState* cached,
784    const CryptoHandshakeMessage& rej,
785    QuicWallTime now,
786    QuicCryptoNegotiatedParameters* out_params,
787    string* error_details) {
788  DCHECK(error_details != NULL);
789
790  if (rej.tag() != kREJ) {
791    *error_details = "Message is not REJ";
792    return QUIC_CRYPTO_INTERNAL_ERROR;
793  }
794
795  StringPiece scfg;
796  if (!rej.GetStringPiece(kSCFG, &scfg)) {
797    *error_details = "Missing SCFG";
798    return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
799  }
800
801  QuicErrorCode error = cached->SetServerConfig(scfg, now, error_details);
802  if (error != QUIC_NO_ERROR) {
803    return error;
804  }
805
806  StringPiece token;
807  if (rej.GetStringPiece(kSourceAddressTokenTag, &token)) {
808    cached->set_source_address_token(token);
809  }
810
811  StringPiece nonce;
812  if (rej.GetStringPiece(kServerNonceTag, &nonce)) {
813    out_params->server_nonce = nonce.as_string();
814  }
815
816  StringPiece proof, cert_bytes;
817  if (rej.GetStringPiece(kPROF, &proof) &&
818      rej.GetStringPiece(kCertificateTag, &cert_bytes)) {
819    vector<string> certs;
820    if (!CertCompressor::DecompressChain(cert_bytes, out_params->cached_certs,
821                                         common_cert_sets, &certs)) {
822      *error_details = "Certificate data invalid";
823      return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
824    }
825
826    cached->SetProof(certs, proof);
827  }
828
829  return QUIC_NO_ERROR;
830}
831
832QuicErrorCode QuicCryptoClientConfig::ProcessServerHello(
833    const CryptoHandshakeMessage& server_hello,
834    QuicGuid guid,
835    QuicCryptoNegotiatedParameters* out_params,
836    string* error_details) {
837  DCHECK(error_details != NULL);
838
839  if (server_hello.tag() != kSHLO) {
840    *error_details = "Bad tag";
841    return QUIC_INVALID_CRYPTO_MESSAGE_TYPE;
842  }
843
844  // TODO(agl):
845  //   learn about updated SCFGs.
846
847  StringPiece public_value;
848  if (!server_hello.GetStringPiece(kPUBS, &public_value)) {
849    *error_details = "server hello missing forward secure public value";
850    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
851  }
852
853  if (!out_params->client_key_exchange->CalculateSharedKey(
854          public_value, &out_params->forward_secure_premaster_secret)) {
855    *error_details = "Key exchange failure";
856    return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
857  }
858
859  string hkdf_input;
860  const size_t label_len = strlen(QuicCryptoConfig::kForwardSecureLabel) + 1;
861  hkdf_input.reserve(label_len + out_params->hkdf_input_suffix.size());
862  hkdf_input.append(QuicCryptoConfig::kForwardSecureLabel, label_len);
863  hkdf_input.append(out_params->hkdf_input_suffix);
864
865  CryptoUtils::DeriveKeys(
866      out_params->forward_secure_premaster_secret, out_params->aead,
867      out_params->client_nonce, out_params->server_nonce, hkdf_input,
868      CryptoUtils::CLIENT, &out_params->forward_secure_crypters);
869
870  return QUIC_NO_ERROR;
871}
872
873ProofVerifier* QuicCryptoClientConfig::proof_verifier() const {
874  return proof_verifier_.get();
875}
876
877void QuicCryptoClientConfig::SetProofVerifier(ProofVerifier* verifier) {
878  proof_verifier_.reset(verifier);
879}
880
881ChannelIDSigner* QuicCryptoClientConfig::channel_id_signer() const {
882  return channel_id_signer_.get();
883}
884
885void QuicCryptoClientConfig::SetChannelIDSigner(ChannelIDSigner* signer) {
886  channel_id_signer_.reset(signer);
887}
888
889}  // namespace net
890