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