OLD | NEW |
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" |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 } | 100 } |
101 | 101 |
102 void CryptoHandshakeMessage::SetStringPiece(QuicTag tag, StringPiece value) { | 102 void CryptoHandshakeMessage::SetStringPiece(QuicTag tag, StringPiece value) { |
103 tag_value_map_[tag] = value.as_string(); | 103 tag_value_map_[tag] = value.as_string(); |
104 } | 104 } |
105 | 105 |
106 QuicErrorCode CryptoHandshakeMessage::GetTaglist(QuicTag tag, | 106 QuicErrorCode CryptoHandshakeMessage::GetTaglist(QuicTag tag, |
107 const QuicTag** out_tags, | 107 const QuicTag** out_tags, |
108 size_t* out_len) const { | 108 size_t* out_len) const { |
109 QuicTagValueMap::const_iterator it = tag_value_map_.find(tag); | 109 QuicTagValueMap::const_iterator it = tag_value_map_.find(tag); |
110 *out_len = 0; | |
111 QuicErrorCode ret = QUIC_NO_ERROR; | 110 QuicErrorCode ret = QUIC_NO_ERROR; |
112 | 111 |
113 if (it == tag_value_map_.end()) { | 112 if (it == tag_value_map_.end()) { |
114 ret = QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND; | 113 ret = QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND; |
115 } else if (it->second.size() % sizeof(QuicTag) != 0) { | 114 } else if (it->second.size() % sizeof(QuicTag) != 0) { |
116 ret = QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 115 ret = QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
117 } | 116 } |
118 | 117 |
119 if (ret != QUIC_NO_ERROR) { | 118 if (ret != QUIC_NO_ERROR) { |
120 *out_tags = NULL; | 119 *out_tags = NULL; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 | 213 |
215 if (ret != QUIC_NO_ERROR) { | 214 if (ret != QUIC_NO_ERROR) { |
216 memset(out, 0, len); | 215 memset(out, 0, len); |
217 return ret; | 216 return ret; |
218 } | 217 } |
219 | 218 |
220 memcpy(out, it->second.data(), len); | 219 memcpy(out, it->second.data(), len); |
221 return ret; | 220 return ret; |
222 } | 221 } |
223 | 222 |
224 // TagToString is a utility function for pretty-printing handshake messages | |
225 // that converts a tag to a string. It will try to maintain the human friendly | |
226 // name if possible (i.e. kABCD -> "ABCD"), or will just treat it as a number | |
227 // if not. | |
228 static string TagToString(QuicTag tag) { | |
229 char chars[4]; | |
230 bool ascii = true; | |
231 const QuicTag orig_tag = tag; | |
232 | |
233 for (size_t i = 0; i < sizeof(chars); i++) { | |
234 chars[i] = tag; | |
235 if (chars[i] == 0 && i == 3) { | |
236 chars[i] = ' '; | |
237 } | |
238 if (!isprint(static_cast<unsigned char>(chars[i]))) { | |
239 ascii = false; | |
240 break; | |
241 } | |
242 tag >>= 8; | |
243 } | |
244 | |
245 if (ascii) { | |
246 return string(chars, sizeof(chars)); | |
247 } | |
248 | |
249 return base::UintToString(orig_tag); | |
250 } | |
251 | |
252 string CryptoHandshakeMessage::DebugStringInternal(size_t indent) const { | 223 string CryptoHandshakeMessage::DebugStringInternal(size_t indent) const { |
253 string ret = string(2 * indent, ' ') + TagToString(tag_) + "<\n"; | 224 string ret = string(2 * indent, ' ') + QuicUtils::TagToString(tag_) + "<\n"; |
254 ++indent; | 225 ++indent; |
255 for (QuicTagValueMap::const_iterator it = tag_value_map_.begin(); | 226 for (QuicTagValueMap::const_iterator it = tag_value_map_.begin(); |
256 it != tag_value_map_.end(); ++it) { | 227 it != tag_value_map_.end(); ++it) { |
257 ret += string(2 * indent, ' ') + TagToString(it->first) + ": "; | 228 ret += string(2 * indent, ' ') + QuicUtils::TagToString(it->first) + ": "; |
258 | 229 |
259 bool done = false; | 230 bool done = false; |
260 switch (it->first) { | 231 switch (it->first) { |
261 case kKATO: | 232 case kKATO: |
262 case kVERS: | 233 case kVERS: |
263 // uint32 value | 234 // uint32 value |
264 if (it->second.size() == 4) { | 235 if (it->second.size() == 4) { |
265 uint32 value; | 236 uint32 value; |
266 memcpy(&value, it->second.data(), sizeof(value)); | 237 memcpy(&value, it->second.data(), sizeof(value)); |
267 ret += base::UintToString(value); | 238 ret += base::UintToString(value); |
268 done = true; | 239 done = true; |
269 } | 240 } |
270 break; | 241 break; |
271 case kKEXS: | 242 case kKEXS: |
272 case kAEAD: | 243 case kAEAD: |
273 case kCGST: | 244 case kCGST: |
274 case kPDMD: | 245 case kPDMD: |
275 // tag lists | 246 // tag lists |
276 if (it->second.size() % sizeof(QuicTag) == 0) { | 247 if (it->second.size() % sizeof(QuicTag) == 0) { |
277 for (size_t j = 0; j < it->second.size(); j += sizeof(QuicTag)) { | 248 for (size_t j = 0; j < it->second.size(); j += sizeof(QuicTag)) { |
278 QuicTag tag; | 249 QuicTag tag; |
279 memcpy(&tag, it->second.data() + j, sizeof(tag)); | 250 memcpy(&tag, it->second.data() + j, sizeof(tag)); |
280 if (j > 0) { | 251 if (j > 0) { |
281 ret += ","; | 252 ret += ","; |
282 } | 253 } |
283 ret += TagToString(tag); | 254 ret += QuicUtils::TagToString(tag); |
284 } | 255 } |
285 done = true; | 256 done = true; |
286 } | 257 } |
287 break; | 258 break; |
288 case kSCFG: | 259 case kSCFG: |
289 // nested messages. | 260 // nested messages. |
290 if (!it->second.empty()) { | 261 if (!it->second.empty()) { |
291 scoped_ptr<CryptoHandshakeMessage> msg( | 262 scoped_ptr<CryptoHandshakeMessage> msg( |
292 CryptoFramer::ParseMessage(it->second)); | 263 CryptoFramer::ParseMessage(it->second)); |
293 if (msg.get()) { | 264 if (msg.get()) { |
(...skipping 30 matching lines...) Expand all Loading... |
324 CrypterPair::~CrypterPair() {} | 295 CrypterPair::~CrypterPair() {} |
325 | 296 |
326 // static | 297 // static |
327 const char QuicCryptoConfig::kInitialLabel[] = "QUIC key expansion"; | 298 const char QuicCryptoConfig::kInitialLabel[] = "QUIC key expansion"; |
328 | 299 |
329 const char QuicCryptoConfig::kForwardSecureLabel[] = | 300 const char QuicCryptoConfig::kForwardSecureLabel[] = |
330 "QUIC forward secure key expansion"; | 301 "QUIC forward secure key expansion"; |
331 | 302 |
332 QuicCryptoConfig::QuicCryptoConfig() | 303 QuicCryptoConfig::QuicCryptoConfig() |
333 : version(0), | 304 : version(0), |
334 common_cert_set_(new CommonCertSetsQUIC) { | 305 common_cert_sets(new CommonCertSetsQUIC) { |
335 } | 306 } |
336 | 307 |
337 QuicCryptoConfig::~QuicCryptoConfig() {} | 308 QuicCryptoConfig::~QuicCryptoConfig() {} |
338 | 309 |
339 QuicCryptoClientConfig::QuicCryptoClientConfig() {} | 310 QuicCryptoClientConfig::QuicCryptoClientConfig() {} |
340 | 311 |
341 QuicCryptoClientConfig::~QuicCryptoClientConfig() { | 312 QuicCryptoClientConfig::~QuicCryptoClientConfig() { |
342 STLDeleteValues(&cached_states_); | 313 STLDeleteValues(&cached_states_); |
343 } | 314 } |
344 | 315 |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 if (!server_hostname.empty() && | 440 if (!server_hostname.empty() && |
470 !ParseIPLiteralToNumber(server_hostname, &ip)) { | 441 !ParseIPLiteralToNumber(server_hostname, &ip)) { |
471 out->SetStringPiece(kSNI, server_hostname); | 442 out->SetStringPiece(kSNI, server_hostname); |
472 } | 443 } |
473 out->SetValue(kVERS, version); | 444 out->SetValue(kVERS, version); |
474 | 445 |
475 if (!cached->source_address_token().empty()) { | 446 if (!cached->source_address_token().empty()) { |
476 out->SetStringPiece(kSourceAddressTokenTag, cached->source_address_token()); | 447 out->SetStringPiece(kSourceAddressTokenTag, cached->source_address_token()); |
477 } | 448 } |
478 | 449 |
479 out->SetTaglist(kPDMD, kX509, 0); | 450 if (proof_verifier_.get()) { |
| 451 out->SetTaglist(kPDMD, kX509, 0); |
| 452 } |
480 | 453 |
481 if (common_cert_set_.get()) { | 454 if (common_cert_sets.get()) { |
482 out->SetStringPiece(kCCS, common_cert_set_->GetCommonHashes()); | 455 out->SetStringPiece(kCCS, common_cert_sets->GetCommonHashes()); |
483 } | 456 } |
484 | 457 |
485 const vector<string>& certs = cached->certs(); | 458 const vector<string>& certs = cached->certs(); |
| 459 // We save |certs| in the QuicCryptoNegotiatedParameters so that, if the |
| 460 // client config is being used for multiple connections, another connection |
| 461 // doesn't update the cached certificates and cause us to be unable to |
| 462 // process the server's compressed certificate chain. |
486 out_params->cached_certs = certs; | 463 out_params->cached_certs = certs; |
487 if (!certs.empty()) { | 464 if (!certs.empty()) { |
488 vector<uint64> hashes; | 465 vector<uint64> hashes; |
489 hashes.reserve(certs.size()); | 466 hashes.reserve(certs.size()); |
490 for (vector<string>::const_iterator i = certs.begin(); | 467 for (vector<string>::const_iterator i = certs.begin(); |
491 i != certs.end(); ++i) { | 468 i != certs.end(); ++i) { |
492 hashes.push_back(QuicUtils::FNV1a_64_Hash(i->data(), i->size())); | 469 hashes.push_back(QuicUtils::FNV1a_64_Hash(i->data(), i->size())); |
493 } | 470 } |
494 out->SetVector(kCCRT, hashes); | 471 out->SetVector(kCCRT, hashes); |
495 // We save |certs| in the QuicCryptoNegotiatedParameters so that, if the | |
496 // client config is being used for multiple connections, another connection | |
497 // doesn't update the cached certificates and cause us to be unable to | |
498 // process the server's compressed certificate chain. | |
499 } | 472 } |
500 } | 473 } |
501 | 474 |
502 QuicErrorCode QuicCryptoClientConfig::FillClientHello( | 475 QuicErrorCode QuicCryptoClientConfig::FillClientHello( |
503 const string& server_hostname, | 476 const string& server_hostname, |
504 QuicGuid guid, | 477 QuicGuid guid, |
505 const CachedState* cached, | 478 const CachedState* cached, |
506 QuicWallTime now, | 479 QuicWallTime now, |
507 QuicRandom* rand, | 480 QuicRandom* rand, |
508 QuicCryptoNegotiatedParameters* out_params, | 481 QuicCryptoNegotiatedParameters* out_params, |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
550 size_t num_their_aeads, num_their_key_exchanges; | 523 size_t num_their_aeads, num_their_key_exchanges; |
551 if (scfg->GetTaglist(kAEAD, &their_aeads, | 524 if (scfg->GetTaglist(kAEAD, &their_aeads, |
552 &num_their_aeads) != QUIC_NO_ERROR || | 525 &num_their_aeads) != QUIC_NO_ERROR || |
553 scfg->GetTaglist(kKEXS, &their_key_exchanges, | 526 scfg->GetTaglist(kKEXS, &their_key_exchanges, |
554 &num_their_key_exchanges) != QUIC_NO_ERROR) { | 527 &num_their_key_exchanges) != QUIC_NO_ERROR) { |
555 *error_details = "Missing AEAD or KEXS"; | 528 *error_details = "Missing AEAD or KEXS"; |
556 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 529 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
557 } | 530 } |
558 | 531 |
559 size_t key_exchange_index; | 532 size_t key_exchange_index; |
560 if (!CryptoUtils::FindMutualTag(aead, their_aeads, num_their_aeads, | 533 if (!QuicUtils::FindMutualTag(aead, their_aeads, num_their_aeads, |
561 CryptoUtils::PEER_PRIORITY, &out_params->aead, | 534 QuicUtils::PEER_PRIORITY, &out_params->aead, |
562 NULL) || | 535 NULL) || |
563 !CryptoUtils::FindMutualTag( | 536 !QuicUtils::FindMutualTag( |
564 kexs, their_key_exchanges, num_their_key_exchanges, | 537 kexs, their_key_exchanges, num_their_key_exchanges, |
565 CryptoUtils::PEER_PRIORITY, &out_params->key_exchange, | 538 QuicUtils::PEER_PRIORITY, &out_params->key_exchange, |
566 &key_exchange_index)) { | 539 &key_exchange_index)) { |
567 *error_details = "Unsupported AEAD or KEXS"; | 540 *error_details = "Unsupported AEAD or KEXS"; |
568 return QUIC_CRYPTO_NO_SUPPORT; | 541 return QUIC_CRYPTO_NO_SUPPORT; |
569 } | 542 } |
570 out->SetTaglist(kAEAD, out_params->aead, 0); | 543 out->SetTaglist(kAEAD, out_params->aead, 0); |
571 out->SetTaglist(kKEXS, out_params->key_exchange, 0); | 544 out->SetTaglist(kKEXS, out_params->key_exchange, 0); |
572 | 545 |
573 StringPiece public_value; | 546 StringPiece public_value; |
574 if (scfg->GetNthValue24(kPUBS, key_exchange_index, &public_value) != | 547 if (scfg->GetNthValue24(kPUBS, key_exchange_index, &public_value) != |
575 QUIC_NO_ERROR) { | 548 QUIC_NO_ERROR) { |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
660 if (rej.GetStringPiece(kServerNonceTag, &nonce) && nonce.size() == | 633 if (rej.GetStringPiece(kServerNonceTag, &nonce) && nonce.size() == |
661 kNonceSize) { | 634 kNonceSize) { |
662 out_params->server_nonce = nonce.as_string(); | 635 out_params->server_nonce = nonce.as_string(); |
663 } | 636 } |
664 | 637 |
665 StringPiece proof, cert_bytes; | 638 StringPiece proof, cert_bytes; |
666 if (rej.GetStringPiece(kPROF, &proof) && | 639 if (rej.GetStringPiece(kPROF, &proof) && |
667 rej.GetStringPiece(kCertificateTag, &cert_bytes)) { | 640 rej.GetStringPiece(kCertificateTag, &cert_bytes)) { |
668 vector<string> certs; | 641 vector<string> certs; |
669 if (!CertCompressor::DecompressChain(cert_bytes, out_params->cached_certs, | 642 if (!CertCompressor::DecompressChain(cert_bytes, out_params->cached_certs, |
670 common_cert_set_.get(), &certs)) { | 643 common_cert_sets.get(), &certs)) { |
671 *error_details = "Certificate data invalid"; | 644 *error_details = "Certificate data invalid"; |
672 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; | 645 return QUIC_INVALID_CRYPTO_MESSAGE_PARAMETER; |
673 } | 646 } |
674 | 647 |
675 cached->SetProof(certs, proof); | 648 cached->SetProof(certs, proof); |
676 } | 649 } |
677 | 650 |
678 return QUIC_NO_ERROR; | 651 return QUIC_NO_ERROR; |
679 } | 652 } |
680 | 653 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
721 | 694 |
722 const ProofVerifier* QuicCryptoClientConfig::proof_verifier() const { | 695 const ProofVerifier* QuicCryptoClientConfig::proof_verifier() const { |
723 return proof_verifier_.get(); | 696 return proof_verifier_.get(); |
724 } | 697 } |
725 | 698 |
726 void QuicCryptoClientConfig::SetProofVerifier(ProofVerifier* verifier) { | 699 void QuicCryptoClientConfig::SetProofVerifier(ProofVerifier* verifier) { |
727 proof_verifier_.reset(verifier); | 700 proof_verifier_.reset(verifier); |
728 } | 701 } |
729 | 702 |
730 } // namespace net | 703 } // namespace net |
OLD | NEW |