Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(273)

Side by Side Diff: net/quic/crypto/crypto_handshake.cc

Issue 15937012: Land Recent QUIC changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Small bug fixes Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/quic/crypto/crypto_handshake.h" 5 #include "net/quic/crypto/crypto_handshake.h"
6 6
7 #include <ctype.h> 7 #include <ctype.h>
8 8
9 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
11 #include "base/stringprintf.h" 11 #include "base/stringprintf.h"
12 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/string_split.h" 13 #include "base/strings/string_split.h"
14 #include "crypto/secure_hash.h" 14 #include "crypto/secure_hash.h"
15 #include "net/base/net_util.h" 15 #include "net/base/net_util.h"
16 #include "net/quic/crypto/cert_compressor.h" 16 #include "net/quic/crypto/cert_compressor.h"
17 #include "net/quic/crypto/channel_id.h"
17 #include "net/quic/crypto/common_cert_set.h" 18 #include "net/quic/crypto/common_cert_set.h"
18 #include "net/quic/crypto/crypto_framer.h" 19 #include "net/quic/crypto/crypto_framer.h"
19 #include "net/quic/crypto/crypto_utils.h" 20 #include "net/quic/crypto/crypto_utils.h"
20 #include "net/quic/crypto/curve25519_key_exchange.h" 21 #include "net/quic/crypto/curve25519_key_exchange.h"
21 #include "net/quic/crypto/key_exchange.h" 22 #include "net/quic/crypto/key_exchange.h"
22 #include "net/quic/crypto/p256_key_exchange.h" 23 #include "net/quic/crypto/p256_key_exchange.h"
23 #include "net/quic/crypto/proof_verifier.h" 24 #include "net/quic/crypto/proof_verifier.h"
24 #include "net/quic/crypto/quic_decrypter.h" 25 #include "net/quic/crypto/quic_decrypter.h"
25 #include "net/quic/crypto/quic_encrypter.h" 26 #include "net/quic/crypto/quic_encrypter.h"
26 #include "net/quic/crypto/quic_random.h" 27 #include "net/quic/crypto/quic_random.h"
(...skipping 11 matching lines...) Expand all
38 CryptoHandshakeMessage::CryptoHandshakeMessage() 39 CryptoHandshakeMessage::CryptoHandshakeMessage()
39 : tag_(0), 40 : tag_(0),
40 minimum_size_(0) {} 41 minimum_size_(0) {}
41 42
42 CryptoHandshakeMessage::CryptoHandshakeMessage( 43 CryptoHandshakeMessage::CryptoHandshakeMessage(
43 const CryptoHandshakeMessage& other) 44 const CryptoHandshakeMessage& other)
44 : tag_(other.tag_), 45 : tag_(other.tag_),
45 tag_value_map_(other.tag_value_map_), 46 tag_value_map_(other.tag_value_map_),
46 minimum_size_(other.minimum_size_) { 47 minimum_size_(other.minimum_size_) {
47 // Don't copy serialized_. scoped_ptr doesn't have a copy constructor. 48 // Don't copy serialized_. scoped_ptr doesn't have a copy constructor.
48 // The new object can reconstruct serialized_ lazily. 49 // The new object can lazily reconstruct serialized_.
49 } 50 }
50 51
51 CryptoHandshakeMessage::~CryptoHandshakeMessage() {} 52 CryptoHandshakeMessage::~CryptoHandshakeMessage() {}
52 53
53 CryptoHandshakeMessage& CryptoHandshakeMessage::operator=( 54 CryptoHandshakeMessage& CryptoHandshakeMessage::operator=(
54 const CryptoHandshakeMessage& other) { 55 const CryptoHandshakeMessage& other) {
55 tag_ = other.tag_; 56 tag_ = other.tag_;
56 tag_value_map_ = other.tag_value_map_; 57 tag_value_map_ = other.tag_value_map_;
57 // Don't copy serialized_. scoped_ptr doesn't have an assignment operator. 58 // Don't copy serialized_. scoped_ptr doesn't have an assignment operator.
58 // However, invalidate serialized_. 59 // However, invalidate serialized_.
59 serialized_.reset(); 60 serialized_.reset();
60 minimum_size_ = other.minimum_size_; 61 minimum_size_ = other.minimum_size_;
61 return *this; 62 return *this;
62 } 63 }
63 64
64 void CryptoHandshakeMessage::Clear() { 65 void CryptoHandshakeMessage::Clear() {
65 tag_ = 0; 66 tag_ = 0;
66 tag_value_map_.clear(); 67 tag_value_map_.clear();
67 minimum_size_ = 0; 68 minimum_size_ = 0;
68 serialized_.reset(); 69 serialized_.reset();
69 } 70 }
70 71
71 const QuicData& CryptoHandshakeMessage::GetSerialized() const { 72 const QuicData& CryptoHandshakeMessage::GetSerialized() const {
72 if (!serialized_.get()) { 73 if (!serialized_.get()) {
73 serialized_.reset(CryptoFramer::ConstructHandshakeMessage(*this)); 74 serialized_.reset(CryptoFramer::ConstructHandshakeMessage(*this));
74 } 75 }
75 return *serialized_.get(); 76 return *serialized_.get();
76 } 77 }
77 78
79 void CryptoHandshakeMessage::MarkDirty() {
80 serialized_.reset();
81 }
82
78 void CryptoHandshakeMessage::Insert(QuicTagValueMap::const_iterator begin, 83 void CryptoHandshakeMessage::Insert(QuicTagValueMap::const_iterator begin,
79 QuicTagValueMap::const_iterator end) { 84 QuicTagValueMap::const_iterator end) {
80 tag_value_map_.insert(begin, end); 85 tag_value_map_.insert(begin, end);
81 } 86 }
82 87
83 void CryptoHandshakeMessage::SetTaglist(QuicTag tag, ...) { 88 void CryptoHandshakeMessage::SetTaglist(QuicTag tag, ...) {
84 // Warning, if sizeof(QuicTag) > sizeof(int) then this function will break 89 // Warning, if sizeof(QuicTag) > sizeof(int) then this function will break
85 // because the terminating 0 will only be promoted to int. 90 // because the terminating 0 will only be promoted to int.
86 COMPILE_ASSERT(sizeof(QuicTag) <= sizeof(int), 91 COMPILE_ASSERT(sizeof(QuicTag) <= sizeof(int),
87 crypto_tag_not_be_larger_than_int_or_varargs_will_break); 92 crypto_tag_may_not_be_larger_than_int_or_varargs_will_break);
88 93
89 vector<QuicTag> tags; 94 vector<QuicTag> tags;
90 va_list ap; 95 va_list ap;
91 96
92 va_start(ap, tag); 97 va_start(ap, tag);
93 for (;;) { 98 for (;;) {
94 QuicTag list_item = va_arg(ap, QuicTag); 99 QuicTag list_item = va_arg(ap, QuicTag);
95 if (list_item == 0) { 100 if (list_item == 0) {
96 break; 101 break;
97 } 102 }
98 tags.push_back(list_item); 103 tags.push_back(list_item);
99 } 104 }
100 105
101 // Because of the way that we keep tags in memory, we can copy the contents 106 // Because of the way that we keep tags in memory, we can copy the contents
102 // of the vector and get the correct bytes in wire format. See 107 // of the vector and get the correct bytes in wire format. See
103 // crypto_protocol.h. This assumes that the system is little-endian. 108 // crypto_protocol.h. This assumes that the system is little-endian.
104 SetVector(tag, tags); 109 SetVector(tag, tags);
105 110
106 va_end(ap); 111 va_end(ap);
107 } 112 }
108 113
109 void CryptoHandshakeMessage::SetStringPiece(QuicTag tag, StringPiece value) { 114 void CryptoHandshakeMessage::SetStringPiece(QuicTag tag, StringPiece value) {
110 tag_value_map_[tag] = value.as_string(); 115 tag_value_map_[tag] = value.as_string();
111 } 116 }
112 117
118 void CryptoHandshakeMessage::Erase(QuicTag tag) {
119 tag_value_map_.erase(tag);
120 }
121
113 QuicErrorCode CryptoHandshakeMessage::GetTaglist(QuicTag tag, 122 QuicErrorCode CryptoHandshakeMessage::GetTaglist(QuicTag tag,
114 const QuicTag** out_tags, 123 const QuicTag** out_tags,
115 size_t* out_len) const { 124 size_t* out_len) const {
116 QuicTagValueMap::const_iterator it = tag_value_map_.find(tag); 125 QuicTagValueMap::const_iterator it = tag_value_map_.find(tag);
117 QuicErrorCode ret = QUIC_NO_ERROR; 126 QuicErrorCode ret = QUIC_NO_ERROR;
118 127
119 if (it == tag_value_map_.end()) { 128 if (it == tag_value_map_.end()) {
120 ret = QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND; 129 ret = QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
121 } else if (it->second.size() % sizeof(QuicTag) != 0) { 130 } else if (it->second.size() % sizeof(QuicTag) != 0) {
122 ret = QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 131 ret = QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 181
173 if (i == index) { 182 if (i == index) {
174 *out = StringPiece(value.data(), size); 183 *out = StringPiece(value.data(), size);
175 return QUIC_NO_ERROR; 184 return QUIC_NO_ERROR;
176 } 185 }
177 186
178 value.remove_prefix(size); 187 value.remove_prefix(size);
179 } 188 }
180 } 189 }
181 190
182 bool CryptoHandshakeMessage::GetString(QuicTag tag, string* out) const {
183 QuicTagValueMap::const_iterator it = tag_value_map_.find(tag);
184 if (it == tag_value_map_.end()) {
185 return false;
186 }
187 *out = it->second;
188 return true;
189 }
190
191 QuicErrorCode CryptoHandshakeMessage::GetUint16(QuicTag tag, 191 QuicErrorCode CryptoHandshakeMessage::GetUint16(QuicTag tag,
192 uint16* out) const { 192 uint16* out) const {
193 return GetPOD(tag, out, sizeof(uint16)); 193 return GetPOD(tag, out, sizeof(uint16));
194 } 194 }
195 195
196 QuicErrorCode CryptoHandshakeMessage::GetUint32(QuicTag tag, 196 QuicErrorCode CryptoHandshakeMessage::GetUint32(QuicTag tag,
197 uint32* out) const { 197 uint32* out) const {
198 return GetPOD(tag, out, sizeof(uint32)); 198 return GetPOD(tag, out, sizeof(uint32));
199 } 199 }
200 200
(...skipping 10 matching lines...) Expand all
211 tag_value_map_.size(); 211 tag_value_map_.size();
212 for (QuicTagValueMap::const_iterator i = tag_value_map_.begin(); 212 for (QuicTagValueMap::const_iterator i = tag_value_map_.begin();
213 i != tag_value_map_.end(); ++i) { 213 i != tag_value_map_.end(); ++i) {
214 ret += i->second.size(); 214 ret += i->second.size();
215 } 215 }
216 216
217 return ret; 217 return ret;
218 } 218 }
219 219
220 void CryptoHandshakeMessage::set_minimum_size(size_t min_bytes) { 220 void CryptoHandshakeMessage::set_minimum_size(size_t min_bytes) {
221 if (min_bytes == minimum_size_) {
222 return;
223 }
221 serialized_.reset(); 224 serialized_.reset();
222 minimum_size_ = min_bytes; 225 minimum_size_ = min_bytes;
223 } 226 }
224 227
225 size_t CryptoHandshakeMessage::minimum_size() const { 228 size_t CryptoHandshakeMessage::minimum_size() const {
226 return minimum_size_; 229 return minimum_size_;
227 } 230 }
228 231
229 string CryptoHandshakeMessage::DebugString() const { 232 string CryptoHandshakeMessage::DebugString() const {
230 return DebugStringInternal(0); 233 return DebugStringInternal(0);
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 323
321 QuicCryptoNegotiatedParameters::QuicCryptoNegotiatedParameters() 324 QuicCryptoNegotiatedParameters::QuicCryptoNegotiatedParameters()
322 : version(0), 325 : version(0),
323 key_exchange(0), 326 key_exchange(0),
324 aead(0) { 327 aead(0) {
325 } 328 }
326 329
327 QuicCryptoNegotiatedParameters::~QuicCryptoNegotiatedParameters() {} 330 QuicCryptoNegotiatedParameters::~QuicCryptoNegotiatedParameters() {}
328 331
329 CrypterPair::CrypterPair() {} 332 CrypterPair::CrypterPair() {}
333
330 CrypterPair::~CrypterPair() {} 334 CrypterPair::~CrypterPair() {}
331 335
332 // static 336 // static
333 const char QuicCryptoConfig::kInitialLabel[] = "QUIC key expansion"; 337 const char QuicCryptoConfig::kInitialLabel[] = "QUIC key expansion";
334 338
339 // static
340 const char QuicCryptoConfig::kCETVLabel[] = "QUIC CETV block";
341
342 // static
335 const char QuicCryptoConfig::kForwardSecureLabel[] = 343 const char QuicCryptoConfig::kForwardSecureLabel[] =
336 "QUIC forward secure key expansion"; 344 "QUIC forward secure key expansion";
337 345
338 QuicCryptoConfig::QuicCryptoConfig() 346 QuicCryptoConfig::QuicCryptoConfig()
339 : version(0), 347 : version(0),
340 common_cert_sets(new CommonCertSetsQUIC) { 348 common_cert_sets(CommonCertSets::GetInstanceQUIC()) {
341 } 349 }
342 350
343 QuicCryptoConfig::~QuicCryptoConfig() {} 351 QuicCryptoConfig::~QuicCryptoConfig() {}
344 352
345 QuicCryptoClientConfig::QuicCryptoClientConfig() {} 353 QuicCryptoClientConfig::QuicCryptoClientConfig() {}
346 354
347 QuicCryptoClientConfig::~QuicCryptoClientConfig() { 355 QuicCryptoClientConfig::~QuicCryptoClientConfig() {
348 STLDeleteValues(&cached_states_); 356 STLDeleteValues(&cached_states_);
349 } 357 }
350 358
351 QuicCryptoClientConfig::CachedState::CachedState() 359 QuicCryptoClientConfig::CachedState::CachedState()
352 : server_config_valid_(false) {} 360 : server_config_valid_(false) {}
353 361
354 QuicCryptoClientConfig::CachedState::~CachedState() {} 362 QuicCryptoClientConfig::CachedState::~CachedState() {}
355 363
356 bool QuicCryptoClientConfig::CachedState::is_complete() const { 364 bool QuicCryptoClientConfig::CachedState::IsComplete(QuicWallTime now) const {
357 return !server_config_.empty() && server_config_valid_; 365 if (server_config_.empty() || !server_config_valid_) {
366 return false;
367 }
368
369 const CryptoHandshakeMessage* scfg = GetServerConfig();
370 if (!scfg) {
371 // Should be impossible short of cache corruption.
372 DCHECK(false);
373 return false;
374 }
375
376 uint64 expiry_seconds;
377 if (scfg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR ||
378 now.ToUNIXSeconds() >= expiry_seconds) {
379 return false;
380 }
381
382 return true;
358 } 383 }
359 384
360 const CryptoHandshakeMessage* 385 const CryptoHandshakeMessage*
361 QuicCryptoClientConfig::CachedState::GetServerConfig() const { 386 QuicCryptoClientConfig::CachedState::GetServerConfig() const {
362 if (server_config_.empty()) { 387 if (server_config_.empty()) {
363 return NULL; 388 return NULL;
364 } 389 }
365 390
366 if (!scfg_.get()) { 391 if (!scfg_.get()) {
367 scfg_.reset(CryptoFramer::ParseMessage(server_config_)); 392 scfg_.reset(CryptoFramer::ParseMessage(server_config_));
368 DCHECK(scfg_.get()); 393 DCHECK(scfg_.get());
369 } 394 }
370 return scfg_.get(); 395 return scfg_.get();
371 } 396 }
372 397
373 bool QuicCryptoClientConfig::CachedState::SetServerConfig(StringPiece scfg) { 398 QuicErrorCode QuicCryptoClientConfig::CachedState::SetServerConfig(
374 if (scfg == server_config_) { 399 StringPiece server_config, QuicWallTime now, string* error_details) {
375 return true; 400 const bool matches_existing = server_config == server_config_;
401
402 // Even if the new server config matches the existing one, we still wish to
403 // reject it if it has expired.
404 scoped_ptr<CryptoHandshakeMessage> new_scfg_storage;
405 const CryptoHandshakeMessage* new_scfg;
406
407 if (!matches_existing) {
408 new_scfg_storage.reset(CryptoFramer::ParseMessage(server_config));
409 new_scfg = new_scfg_storage.get();
410 } else {
411 new_scfg = GetServerConfig();
376 } 412 }
377 413
378 scfg_.reset(CryptoFramer::ParseMessage(scfg)); 414 if (!new_scfg) {
379 if (!scfg_.get()) { 415 *error_details = "SCFG invalid";
380 return false; 416 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
381 } 417 }
382 server_config_ = scfg.as_string(); 418
419 uint64 expiry_seconds;
420 if (new_scfg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR) {
421 *error_details = "SCFG missing EXPY";
422 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
423 }
424
425 if (now.ToUNIXSeconds() >= expiry_seconds) {
426 *error_details = "SCFG has expired";
427 return QUIC_CRYPTO_SERVER_CONFIG_EXPIRED;
428 }
429
430 if (!matches_existing) {
431 server_config_ = server_config.as_string();
432 server_config_valid_ = false;
433 scfg_.reset(new_scfg_storage.release());
434 }
435 return QUIC_NO_ERROR;
436 }
437
438 void QuicCryptoClientConfig::CachedState::InvalidateServerConfig() {
439 server_config_.clear();
440 scfg_.reset();
383 server_config_valid_ = false; 441 server_config_valid_ = false;
384 return true;
385 } 442 }
386 443
387 void QuicCryptoClientConfig::CachedState::SetProof(const vector<string>& certs, 444 void QuicCryptoClientConfig::CachedState::SetProof(const vector<string>& certs,
388 StringPiece signature) { 445 StringPiece signature) {
389 bool has_changed = signature != server_config_sig_; 446 bool has_changed =
447 signature != server_config_sig_ || certs_.size() != certs.size();
390 448
391 if (certs_.size() != certs.size()) {
392 has_changed = true;
393 }
394 if (!has_changed) { 449 if (!has_changed) {
395 for (size_t i = 0; i < certs_.size(); i++) { 450 for (size_t i = 0; i < certs_.size(); i++) {
396 if (certs_[i] != certs[i]) { 451 if (certs_[i] != certs[i]) {
397 has_changed = true; 452 has_changed = true;
398 break; 453 break;
399 } 454 }
400 } 455 }
401 } 456 }
402 457
403 if (!has_changed) { 458 if (!has_changed) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 return server_config_valid_; 490 return server_config_valid_;
436 } 491 }
437 492
438 void QuicCryptoClientConfig::CachedState::set_source_address_token( 493 void QuicCryptoClientConfig::CachedState::set_source_address_token(
439 StringPiece token) { 494 StringPiece token) {
440 source_address_token_ = token.as_string(); 495 source_address_token_ = token.as_string();
441 } 496 }
442 497
443 void QuicCryptoClientConfig::SetDefaults() { 498 void QuicCryptoClientConfig::SetDefaults() {
444 // Version must be 0. 499 // Version must be 0.
500 // TODO(agl): this version stuff is obsolete now.
445 version = QuicCryptoConfig::CONFIG_VERSION; 501 version = QuicCryptoConfig::CONFIG_VERSION;
446 502
447 // Key exchange methods. 503 // Key exchange methods.
448 kexs.resize(2); 504 kexs.resize(2);
449 kexs[0] = kC255; 505 kexs[0] = kC255;
450 kexs[1] = kP256; 506 kexs[1] = kP256;
451 507
452 // Authenticated encryption algorithms. 508 // Authenticated encryption algorithms.
453 aead.resize(1); 509 aead.resize(1);
454 aead[0] = kAESG; 510 aead[0] = kAESG;
(...skipping 28 matching lines...) Expand all
483 out->SetValue(kVERS, version); 539 out->SetValue(kVERS, version);
484 540
485 if (!cached->source_address_token().empty()) { 541 if (!cached->source_address_token().empty()) {
486 out->SetStringPiece(kSourceAddressTokenTag, cached->source_address_token()); 542 out->SetStringPiece(kSourceAddressTokenTag, cached->source_address_token());
487 } 543 }
488 544
489 if (proof_verifier_.get()) { 545 if (proof_verifier_.get()) {
490 out->SetTaglist(kPDMD, kX509, 0); 546 out->SetTaglist(kPDMD, kX509, 0);
491 } 547 }
492 548
493 if (common_cert_sets.get()) { 549 if (common_cert_sets) {
494 out->SetStringPiece(kCCS, common_cert_sets->GetCommonHashes()); 550 out->SetStringPiece(kCCS, common_cert_sets->GetCommonHashes());
495 } 551 }
496 552
497 const vector<string>& certs = cached->certs(); 553 const vector<string>& certs = cached->certs();
498 // We save |certs| in the QuicCryptoNegotiatedParameters so that, if the 554 // We save |certs| in the QuicCryptoNegotiatedParameters so that, if the
499 // client config is being used for multiple connections, another connection 555 // client config is being used for multiple connections, another connection
500 // doesn't update the cached certificates and cause us to be unable to 556 // doesn't update the cached certificates and cause us to be unable to
501 // process the server's compressed certificate chain. 557 // process the server's compressed certificate chain.
502 out_params->cached_certs = certs; 558 out_params->cached_certs = certs;
503 if (!certs.empty()) { 559 if (!certs.empty()) {
(...skipping 16 matching lines...) Expand all
520 QuicCryptoNegotiatedParameters* out_params, 576 QuicCryptoNegotiatedParameters* out_params,
521 CryptoHandshakeMessage* out, 577 CryptoHandshakeMessage* out,
522 string* error_details) const { 578 string* error_details) const {
523 DCHECK(error_details != NULL); 579 DCHECK(error_details != NULL);
524 580
525 FillInchoateClientHello(server_hostname, cached, out_params, out); 581 FillInchoateClientHello(server_hostname, cached, out_params, out);
526 582
527 const CryptoHandshakeMessage* scfg = cached->GetServerConfig(); 583 const CryptoHandshakeMessage* scfg = cached->GetServerConfig();
528 if (!scfg) { 584 if (!scfg) {
529 // This should never happen as our caller should have checked 585 // This should never happen as our caller should have checked
530 // cached->is_complete() before calling this function. 586 // cached->IsComplete() before calling this function.
531 *error_details = "Handshake not ready"; 587 *error_details = "Handshake not ready";
532 return QUIC_CRYPTO_INTERNAL_ERROR; 588 return QUIC_CRYPTO_INTERNAL_ERROR;
533 } 589 }
534 590
535 uint64 expiry_seconds;
536 if (scfg->GetUint64(kEXPY, &expiry_seconds) != QUIC_NO_ERROR) {
537 *error_details = "SCFG missing EXPY";
538 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
539 }
540
541 if (static_cast<uint64>(now.ToUNIXSeconds()) >= expiry_seconds) {
542 *error_details = "SCFG expired";
543 return QUIC_CRYPTO_SERVER_CONFIG_EXPIRED;
544 }
545
546 StringPiece scid; 591 StringPiece scid;
547 if (!scfg->GetStringPiece(kSCID, &scid)) { 592 if (!scfg->GetStringPiece(kSCID, &scid)) {
548 *error_details = "SCFG missing SCID"; 593 *error_details = "SCFG missing SCID";
549 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 594 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
550 } 595 }
551 out->SetStringPiece(kSCID, scid); 596 out->SetStringPiece(kSCID, scid);
552 597
553 // Calculate the mutual algorithms that the connection is going to use.
554 if (scfg->GetUint16(kVERS, &out_params->version) != QUIC_NO_ERROR ||
555 out_params->version != QuicCryptoConfig::CONFIG_VERSION) {
556 *error_details = "Bad version";
557 return QUIC_CRYPTO_VERSION_NOT_SUPPORTED;
558 }
559
560 const QuicTag* their_aeads; 598 const QuicTag* their_aeads;
561 const QuicTag* their_key_exchanges; 599 const QuicTag* their_key_exchanges;
562 size_t num_their_aeads, num_their_key_exchanges; 600 size_t num_their_aeads, num_their_key_exchanges;
563 if (scfg->GetTaglist(kAEAD, &their_aeads, 601 if (scfg->GetTaglist(kAEAD, &their_aeads,
564 &num_their_aeads) != QUIC_NO_ERROR || 602 &num_their_aeads) != QUIC_NO_ERROR ||
565 scfg->GetTaglist(kKEXS, &their_key_exchanges, 603 scfg->GetTaglist(kKEXS, &their_key_exchanges,
566 &num_their_key_exchanges) != QUIC_NO_ERROR) { 604 &num_their_key_exchanges) != QUIC_NO_ERROR) {
567 *error_details = "Missing AEAD or KEXS"; 605 *error_details = "Missing AEAD or KEXS";
568 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 606 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
569 } 607 }
570 608
571 size_t key_exchange_index; 609 size_t key_exchange_index;
572 if (!QuicUtils::FindMutualTag(aead, their_aeads, num_their_aeads, 610 if (!QuicUtils::FindMutualTag(
573 QuicUtils::PEER_PRIORITY, &out_params->aead, 611 aead, their_aeads, num_their_aeads, QuicUtils::PEER_PRIORITY,
574 NULL) || 612 &out_params->aead, NULL) ||
575 !QuicUtils::FindMutualTag( 613 !QuicUtils::FindMutualTag(
576 kexs, their_key_exchanges, num_their_key_exchanges, 614 kexs, their_key_exchanges, num_their_key_exchanges,
577 QuicUtils::PEER_PRIORITY, &out_params->key_exchange, 615 QuicUtils::PEER_PRIORITY, &out_params->key_exchange,
578 &key_exchange_index)) { 616 &key_exchange_index)) {
579 *error_details = "Unsupported AEAD or KEXS"; 617 *error_details = "Unsupported AEAD or KEXS";
580 return QUIC_CRYPTO_NO_SUPPORT; 618 return QUIC_CRYPTO_NO_SUPPORT;
581 } 619 }
582 out->SetTaglist(kAEAD, out_params->aead, 0); 620 out->SetTaglist(kAEAD, out_params->aead, 0);
583 out->SetTaglist(kKEXS, out_params->key_exchange, 0); 621 out->SetTaglist(kKEXS, out_params->key_exchange, 0);
584 622
(...skipping 15 matching lines...) Expand all
600 if (!out_params->server_nonce.empty()) { 638 if (!out_params->server_nonce.empty()) {
601 out->SetStringPiece(kServerNonceTag, out_params->server_nonce); 639 out->SetStringPiece(kServerNonceTag, out_params->server_nonce);
602 } 640 }
603 641
604 switch (out_params->key_exchange) { 642 switch (out_params->key_exchange) {
605 case kC255: 643 case kC255:
606 out_params->client_key_exchange.reset(Curve25519KeyExchange::New( 644 out_params->client_key_exchange.reset(Curve25519KeyExchange::New(
607 Curve25519KeyExchange::NewPrivateKey(rand))); 645 Curve25519KeyExchange::NewPrivateKey(rand)));
608 break; 646 break;
609 case kP256: 647 case kP256:
610 out_params->client_key_exchange 648 out_params->client_key_exchange.reset(P256KeyExchange::New(
611 .reset(P256KeyExchange::New(P256KeyExchange::NewPrivateKey())); 649 P256KeyExchange::NewPrivateKey()));
612 break; 650 break;
613 default: 651 default:
614 DCHECK(false); 652 DCHECK(false);
615 *error_details = "Configured to support an unknown key exchange"; 653 *error_details = "Configured to support an unknown key exchange";
616 return QUIC_CRYPTO_INTERNAL_ERROR; 654 return QUIC_CRYPTO_INTERNAL_ERROR;
617 } 655 }
618 656
619 if (!out_params->client_key_exchange->CalculateSharedKey( 657 if (!out_params->client_key_exchange->CalculateSharedKey(
620 public_value, &out_params->initial_premaster_secret)) { 658 public_value, &out_params->initial_premaster_secret)) {
621 *error_details = "Key exchange failure"; 659 *error_details = "Key exchange failure";
622 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 660 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
623 } 661 }
624 out->SetStringPiece(kPUBS, out_params->client_key_exchange->public_value()); 662 out->SetStringPiece(kPUBS, out_params->client_key_exchange->public_value());
625 663
664 bool do_channel_id = false;
665 if (channel_id_signer_.get()) {
666 const QuicTag* their_proof_demands;
667 size_t num_their_proof_demands;
668 if (scfg->GetTaglist(kPDMD, &their_proof_demands,
669 &num_their_proof_demands) == QUIC_NO_ERROR) {
670 for (size_t i = 0; i < num_their_proof_demands; i++) {
671 if (their_proof_demands[i] == kCHID) {
672 do_channel_id = true;
673 break;
674 }
675 }
676 }
677 }
678
679 if (do_channel_id) {
680 // In order to calculate the encryption key for the CETV block we need to
681 // serialise the client hello as it currently is (i.e. without the CETV
682 // block). For this, the client hello is serialized without padding.
683 const size_t orig_min_size = out->minimum_size();
684 out->set_minimum_size(0);
685
686 CryptoHandshakeMessage cetv;
687 cetv.set_tag(kCETV);
688
689 string hkdf_input;
690 const QuicData& client_hello_serialized = out->GetSerialized();
691 hkdf_input.append(QuicCryptoConfig::kCETVLabel,
692 strlen(QuicCryptoConfig::kCETVLabel) + 1);
693 hkdf_input.append(reinterpret_cast<char*>(&guid), sizeof(guid));
694 hkdf_input.append(client_hello_serialized.data(),
695 client_hello_serialized.length());
696 hkdf_input.append(cached->server_config());
697
698 string key, signature;
699 if (!channel_id_signer_->Sign(server_hostname, hkdf_input,
700 &key, &signature)) {
701 *error_details = "Channel ID signature failed";
702 return QUIC_INTERNAL_ERROR;
703 }
704
705 cetv.SetStringPiece(kCIDK, key);
706 cetv.SetStringPiece(kCIDS, signature);
707
708 CrypterPair crypters;
709 CryptoUtils::DeriveKeys(out_params->initial_premaster_secret,
710 out_params->aead, out_params->client_nonce,
711 out_params->server_nonce, hkdf_input,
712 CryptoUtils::CLIENT, &crypters);
713
714 const QuicData& cetv_plaintext = cetv.GetSerialized();
715 scoped_ptr<QuicData> cetv_ciphertext(crypters.encrypter->EncryptPacket(
716 0 /* sequence number */,
717 StringPiece() /* associated data */,
718 cetv_plaintext.AsStringPiece()));
719
720 out->SetStringPiece(kCETV, cetv_ciphertext->AsStringPiece());
721 out->MarkDirty();
722
723 out->set_minimum_size(orig_min_size);
724 }
725
626 out_params->hkdf_input_suffix.clear(); 726 out_params->hkdf_input_suffix.clear();
627 out_params->hkdf_input_suffix.append(reinterpret_cast<char*>(&guid), 727 out_params->hkdf_input_suffix.append(reinterpret_cast<char*>(&guid),
628 sizeof(guid)); 728 sizeof(guid));
629 const QuicData& client_hello_serialized = out->GetSerialized(); 729 const QuicData& client_hello_serialized = out->GetSerialized();
630 out_params->hkdf_input_suffix.append(client_hello_serialized.data(), 730 out_params->hkdf_input_suffix.append(client_hello_serialized.data(),
631 client_hello_serialized.length()); 731 client_hello_serialized.length());
632 out_params->hkdf_input_suffix.append(cached->server_config()); 732 out_params->hkdf_input_suffix.append(cached->server_config());
633 733
634 string hkdf_input; 734 string hkdf_input;
635 const size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1; 735 const size_t label_len = strlen(QuicCryptoConfig::kInitialLabel) + 1;
636 hkdf_input.reserve(label_len + out_params->hkdf_input_suffix.size()); 736 hkdf_input.reserve(label_len + out_params->hkdf_input_suffix.size());
637 hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len); 737 hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len);
638 hkdf_input.append(out_params->hkdf_input_suffix); 738 hkdf_input.append(out_params->hkdf_input_suffix);
639 739
640 CryptoUtils::DeriveKeys(out_params->initial_premaster_secret, 740 CryptoUtils::DeriveKeys(out_params->initial_premaster_secret,
641 out_params->aead, out_params->client_nonce, 741 out_params->aead, out_params->client_nonce,
642 out_params->server_nonce, hkdf_input, 742 out_params->server_nonce, hkdf_input,
643 CryptoUtils::CLIENT, &out_params->initial_crypters); 743 CryptoUtils::CLIENT, &out_params->initial_crypters);
644 744
645 return QUIC_NO_ERROR; 745 return QUIC_NO_ERROR;
646 } 746 }
647 747
648 QuicErrorCode QuicCryptoClientConfig::ProcessRejection( 748 QuicErrorCode QuicCryptoClientConfig::ProcessRejection(
649 CachedState* cached, 749 CachedState* cached,
650 const CryptoHandshakeMessage& rej, 750 const CryptoHandshakeMessage& rej,
751 QuicWallTime now,
651 QuicCryptoNegotiatedParameters* out_params, 752 QuicCryptoNegotiatedParameters* out_params,
652 string* error_details) { 753 string* error_details) {
653 DCHECK(error_details != NULL); 754 DCHECK(error_details != NULL);
654 755
756 if (rej.tag() != kREJ) {
757 *error_details = "Message is not REJ";
758 return QUIC_CRYPTO_INTERNAL_ERROR;
759 }
760
655 StringPiece scfg; 761 StringPiece scfg;
656 if (!rej.GetStringPiece(kSCFG, &scfg)) { 762 if (!rej.GetStringPiece(kSCFG, &scfg)) {
657 *error_details = "Missing SCFG"; 763 *error_details = "Missing SCFG";
658 return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND; 764 return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
659 } 765 }
660 766
661 if (!cached->SetServerConfig(scfg)) { 767 QuicErrorCode error = cached->SetServerConfig(scfg, now, error_details);
662 *error_details = "Invalid SCFG"; 768 if (error != QUIC_NO_ERROR) {
663 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 769 return error;
664 } 770 }
665 771
666 StringPiece token; 772 StringPiece token;
667 if (rej.GetStringPiece(kSourceAddressTokenTag, &token)) { 773 if (rej.GetStringPiece(kSourceAddressTokenTag, &token)) {
668 cached->set_source_address_token(token); 774 cached->set_source_address_token(token);
669 } 775 }
670 776
671 StringPiece nonce; 777 StringPiece nonce;
672 if (rej.GetStringPiece(kServerNonceTag, &nonce) && nonce.size() == 778 if (rej.GetStringPiece(kServerNonceTag, &nonce)) {
673 kNonceSize) {
674 out_params->server_nonce = nonce.as_string(); 779 out_params->server_nonce = nonce.as_string();
675 } 780 }
676 781
677 StringPiece proof, cert_bytes; 782 StringPiece proof, cert_bytes;
678 if (rej.GetStringPiece(kPROF, &proof) && 783 if (rej.GetStringPiece(kPROF, &proof) &&
679 rej.GetStringPiece(kCertificateTag, &cert_bytes)) { 784 rej.GetStringPiece(kCertificateTag, &cert_bytes)) {
680 vector<string> certs; 785 vector<string> certs;
681 if (!CertCompressor::DecompressChain(cert_bytes, out_params->cached_certs, 786 if (!CertCompressor::DecompressChain(cert_bytes, out_params->cached_certs,
682 common_cert_sets.get(), &certs)) { 787 common_cert_sets, &certs)) {
683 *error_details = "Certificate data invalid"; 788 *error_details = "Certificate data invalid";
684 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; 789 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER;
685 } 790 }
686 791
687 cached->SetProof(certs, proof); 792 cached->SetProof(certs, proof);
688 } 793 }
689 794
690 return QUIC_NO_ERROR; 795 return QUIC_NO_ERROR;
691 } 796 }
692 797
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
732 } 837 }
733 838
734 const ProofVerifier* QuicCryptoClientConfig::proof_verifier() const { 839 const ProofVerifier* QuicCryptoClientConfig::proof_verifier() const {
735 return proof_verifier_.get(); 840 return proof_verifier_.get();
736 } 841 }
737 842
738 void QuicCryptoClientConfig::SetProofVerifier(ProofVerifier* verifier) { 843 void QuicCryptoClientConfig::SetProofVerifier(ProofVerifier* verifier) {
739 proof_verifier_.reset(verifier); 844 proof_verifier_.reset(verifier);
740 } 845 }
741 846
847 void QuicCryptoClientConfig::SetChannelIDSigner(ChannelIDSigner* signer) {
848 channel_id_signer_.reset(signer);
849 }
850
742 } // namespace net 851 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698