OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived | 5 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived |
6 // from AuthCertificateCallback() in | 6 // from AuthCertificateCallback() in |
7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. | 7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. |
8 | 8 |
9 /* ***** BEGIN LICENSE BLOCK ***** | 9 /* ***** BEGIN LICENSE BLOCK ***** |
10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
458 completed_handshake_(false), | 458 completed_handshake_(false), |
459 eset_mitm_detected_(false), | 459 eset_mitm_detected_(false), |
460 kaspersky_mitm_detected_(false), | 460 kaspersky_mitm_detected_(false), |
461 predicted_cert_chain_correct_(false), | 461 predicted_cert_chain_correct_(false), |
462 next_handshake_state_(STATE_NONE), | 462 next_handshake_state_(STATE_NONE), |
463 nss_fd_(NULL), | 463 nss_fd_(NULL), |
464 nss_bufs_(NULL), | 464 nss_bufs_(NULL), |
465 net_log_(transport_socket->socket()->NetLog()), | 465 net_log_(transport_socket->socket()->NetLog()), |
466 ssl_host_info_(ssl_host_info), | 466 ssl_host_info_(ssl_host_info), |
467 dns_cert_checker_(context.dns_cert_checker), | 467 dns_cert_checker_(context.dns_cert_checker), |
468 next_proto_status_(kNextProtoUnsupported), | |
468 valid_thread_id_(base::kInvalidThreadId) { | 469 valid_thread_id_(base::kInvalidThreadId) { |
469 EnterFunction(""); | 470 EnterFunction(""); |
470 } | 471 } |
471 | 472 |
472 SSLClientSocketNSS::~SSLClientSocketNSS() { | 473 SSLClientSocketNSS::~SSLClientSocketNSS() { |
473 EnterFunction(""); | 474 EnterFunction(""); |
474 Disconnect(); | 475 Disconnect(); |
475 LeaveFunction(""); | 476 LeaveFunction(""); |
476 } | 477 } |
477 | 478 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
545 context.length(), out, outlen); | 546 context.length(), out, outlen); |
546 if (result != SECSuccess) { | 547 if (result != SECSuccess) { |
547 LogFailedNSSFunction(net_log_, "SSL_ExportKeyingMaterial", ""); | 548 LogFailedNSSFunction(net_log_, "SSL_ExportKeyingMaterial", ""); |
548 return MapNSSError(PORT_GetError()); | 549 return MapNSSError(PORT_GetError()); |
549 } | 550 } |
550 return OK; | 551 return OK; |
551 } | 552 } |
552 | 553 |
553 SSLClientSocket::NextProtoStatus | 554 SSLClientSocket::NextProtoStatus |
554 SSLClientSocketNSS::GetNextProto(std::string* proto) { | 555 SSLClientSocketNSS::GetNextProto(std::string* proto) { |
555 #if defined(SSL_NEXT_PROTO_NEGOTIATED) | 556 *proto = next_proto_; |
556 unsigned char buf[255]; | 557 return next_proto_status_; |
557 int state; | |
558 unsigned len; | |
559 SECStatus rv = SSL_GetNextProto(nss_fd_, &state, buf, &len, sizeof(buf)); | |
560 if (rv != SECSuccess) { | |
561 NOTREACHED() << "Error return from SSL_GetNextProto: " << rv; | |
562 proto->clear(); | |
563 return kNextProtoUnsupported; | |
564 } | |
565 // We don't check for truncation because sizeof(buf) is large enough to hold | |
566 // the maximum protocol size. | |
567 switch (state) { | |
568 case SSL_NEXT_PROTO_NO_SUPPORT: | |
569 proto->clear(); | |
570 return kNextProtoUnsupported; | |
571 case SSL_NEXT_PROTO_NEGOTIATED: | |
572 *proto = std::string(reinterpret_cast<char*>(buf), len); | |
573 return kNextProtoNegotiated; | |
574 case SSL_NEXT_PROTO_NO_OVERLAP: | |
575 *proto = std::string(reinterpret_cast<char*>(buf), len); | |
576 return kNextProtoNoOverlap; | |
577 default: | |
578 NOTREACHED() << "Unknown status from SSL_GetNextProto: " << state; | |
579 proto->clear(); | |
580 return kNextProtoUnsupported; | |
581 } | |
582 #else | |
583 // No NPN support in the libssl that we are building with. | |
584 proto->clear(); | |
585 return kNextProtoUnsupported; | |
586 #endif | |
587 } | 558 } |
588 | 559 |
589 int SSLClientSocketNSS::Connect(OldCompletionCallback* callback) { | 560 int SSLClientSocketNSS::Connect(OldCompletionCallback* callback) { |
590 EnterFunction(""); | 561 EnterFunction(""); |
591 DCHECK(transport_.get()); | 562 DCHECK(transport_.get()); |
592 DCHECK(next_handshake_state_ == STATE_NONE); | 563 DCHECK(next_handshake_state_ == STATE_NONE); |
593 DCHECK(!user_read_callback_); | 564 DCHECK(!user_read_callback_); |
594 DCHECK(!user_write_callback_); | 565 DCHECK(!user_write_callback_); |
595 DCHECK(!user_connect_callback_); | 566 DCHECK(!user_connect_callback_); |
596 DCHECK(!user_read_buf_); | 567 DCHECK(!user_read_buf_); |
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
956 // http://extendedsubset.com/?p=8 | 927 // http://extendedsubset.com/?p=8 |
957 | 928 |
958 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_RENEGOTIATION, | 929 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_RENEGOTIATION, |
959 SSL_RENEGOTIATE_TRANSITIONAL); | 930 SSL_RENEGOTIATE_TRANSITIONAL); |
960 if (rv != SECSuccess) { | 931 if (rv != SECSuccess) { |
961 LogFailedNSSFunction( | 932 LogFailedNSSFunction( |
962 net_log_, "SSL_OptionSet", "SSL_ENABLE_RENEGOTIATION"); | 933 net_log_, "SSL_OptionSet", "SSL_ENABLE_RENEGOTIATION"); |
963 } | 934 } |
964 #endif // SSL_ENABLE_RENEGOTIATION | 935 #endif // SSL_ENABLE_RENEGOTIATION |
965 | 936 |
966 #ifdef SSL_NEXT_PROTO_NEGOTIATED | 937 #ifdef SSL_NEXT_PROTO_NEGOTIATION_SUPPORTED |
967 if (!ssl_config_.next_protos.empty()) { | 938 if (!ssl_config_.next_protos.empty()) { |
968 rv = SSL_SetNextProtoNego( | 939 rv = SSL_SetNextProtoCallback( |
969 nss_fd_, | 940 nss_fd_, SSLClientSocketNSS::NextProtoCallback, this); |
970 reinterpret_cast<const unsigned char *>(ssl_config_.next_protos.data()), | |
971 ssl_config_.next_protos.size()); | |
972 if (rv != SECSuccess) | 941 if (rv != SECSuccess) |
973 LogFailedNSSFunction(net_log_, "SSL_SetNextProtoNego", ""); | 942 LogFailedNSSFunction(net_log_, "SSL_SetNextProtoCallback", ""); |
974 } | 943 } |
975 #endif | 944 #endif |
976 | 945 |
977 #ifdef SSL_ENABLE_OCSP_STAPLING | 946 #ifdef SSL_ENABLE_OCSP_STAPLING |
978 if (IsOCSPStaplingSupported()) { | 947 if (IsOCSPStaplingSupported()) { |
979 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_OCSP_STAPLING, PR_TRUE); | 948 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_OCSP_STAPLING, PR_TRUE); |
980 if (rv != SECSuccess) { | 949 if (rv != SECSuccess) { |
981 LogFailedNSSFunction(net_log_, "SSL_OptionSet", | 950 LogFailedNSSFunction(net_log_, "SSL_OptionSet", |
982 "SSL_ENABLE_OCSP_STAPLING"); | 951 "SSL_ENABLE_OCSP_STAPLING"); |
983 } | 952 } |
(...skipping 1526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2510 void SSLClientSocketNSS::HandshakeCallback(PRFileDesc* socket, | 2479 void SSLClientSocketNSS::HandshakeCallback(PRFileDesc* socket, |
2511 void* arg) { | 2480 void* arg) { |
2512 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); | 2481 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); |
2513 | 2482 |
2514 that->handshake_callback_called_ = true; | 2483 that->handshake_callback_called_ = true; |
2515 | 2484 |
2516 that->UpdateServerCert(); | 2485 that->UpdateServerCert(); |
2517 that->UpdateConnectionStatus(); | 2486 that->UpdateConnectionStatus(); |
2518 } | 2487 } |
2519 | 2488 |
2489 // NextProtoCallback is called by NSS during the handshake, if the server | |
2490 // supports NPN, to select a protocol from the list that the server offered. | |
2491 // See the comment in net/third_party/nss/ssl/ssl.h for the meanings of the | |
2492 // arguments. | |
2493 // static | |
2494 SECStatus | |
2495 SSLClientSocketNSS::NextProtoCallback(void* arg, | |
2496 PRFileDesc* nss_fd, | |
2497 const unsigned char* protos, | |
2498 unsigned short protos_len, | |
2499 unsigned char* proto_out, | |
2500 unsigned char* proto_out_len) { | |
2501 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); | |
2502 | |
2503 // For each protocol in server preference, see if we support it. | |
2504 for (unsigned int i = 0; i < protos_len; ) { | |
2505 const size_t len = protos[i]; | |
2506 for (std::vector<std::string>::const_iterator | |
2507 j = that->ssl_config_.next_protos.begin(); | |
2508 j != that->ssl_config_.next_protos.end(); j++) { | |
2509 // Having very long elements in the |next_protos| vector isn't a disaster | |
2510 // because they'll never be selected, but it does indicate an error | |
2511 // somewhere. | |
2512 DCHECK_LT(j->size(), 256u); | |
wtc
2011/10/11 23:43:04
If a DCHECK failure here indicates an NSS bug, the
agl
2011/10/17 17:37:24
It represents a major programming error. I think t
| |
2513 | |
2514 if (j->size() == len && | |
2515 memcmp(&protos[i+1], j->data(), len) == 0) { | |
wtc
2011/10/11 23:43:04
Nit: our Style Guide recommend spaces around '+'.
agl
2011/10/17 17:37:24
Done.
| |
2516 that->next_proto_status_ = kNextProtoNegotiated; | |
2517 that->next_proto_ = *j; | |
2518 break; | |
2519 } | |
2520 } | |
2521 | |
2522 if (that->next_proto_status_ == kNextProtoNegotiated) | |
2523 break; | |
2524 | |
2525 // NSS checks that the data in |protos| is well formed, so we know that | |
2526 // this doesn't cause us to jump off the end of the buffer. | |
2527 i += len + 1; | |
2528 } | |
2529 | |
2530 // If we didn't find a protocol, we select the first one from our list. | |
2531 if (that->next_proto_status_ != kNextProtoNegotiated) { | |
2532 that->next_proto_status_ = kNextProtoNoOverlap; | |
2533 that->next_proto_ = that->ssl_config_.next_protos[0]; | |
2534 } | |
2535 | |
2536 memcpy(proto_out, that->next_proto_.data(), that->next_proto_.size()); | |
2537 *proto_out_len = that->next_proto_.size(); | |
2538 return SECSuccess; | |
2539 } | |
2540 | |
2520 void SSLClientSocketNSS::EnsureThreadIdAssigned() const { | 2541 void SSLClientSocketNSS::EnsureThreadIdAssigned() const { |
2521 base::AutoLock auto_lock(lock_); | 2542 base::AutoLock auto_lock(lock_); |
2522 if (valid_thread_id_ != base::kInvalidThreadId) | 2543 if (valid_thread_id_ != base::kInvalidThreadId) |
2523 return; | 2544 return; |
2524 valid_thread_id_ = base::PlatformThread::CurrentId(); | 2545 valid_thread_id_ = base::PlatformThread::CurrentId(); |
2525 } | 2546 } |
2526 | 2547 |
2527 bool SSLClientSocketNSS::CalledOnValidThread() const { | 2548 bool SSLClientSocketNSS::CalledOnValidThread() const { |
2528 EnsureThreadIdAssigned(); | 2549 EnsureThreadIdAssigned(); |
2529 base::AutoLock auto_lock(lock_); | 2550 base::AutoLock auto_lock(lock_); |
2530 return valid_thread_id_ == base::PlatformThread::CurrentId(); | 2551 return valid_thread_id_ == base::PlatformThread::CurrentId(); |
2531 } | 2552 } |
2532 | 2553 |
2533 } // namespace net | 2554 } // namespace net |
OLD | NEW |