Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 254 | 254 |
| 255 // PeerCertificateChain is a helper object which extracts the certificate | 255 // PeerCertificateChain is a helper object which extracts the certificate |
| 256 // chain, as given by the server, from an NSS socket and performs the needed | 256 // chain, as given by the server, from an NSS socket and performs the needed |
| 257 // resource management. The first element of the chain is the leaf certificate | 257 // resource management. The first element of the chain is the leaf certificate |
| 258 // and the other elements are in the order given by the server. | 258 // and the other elements are in the order given by the server. |
| 259 class PeerCertificateChain { | 259 class PeerCertificateChain { |
| 260 public: | 260 public: |
| 261 explicit PeerCertificateChain(PRFileDesc* nss_fd) | 261 explicit PeerCertificateChain(PRFileDesc* nss_fd) |
| 262 : num_certs_(0), | 262 : num_certs_(0), |
| 263 certs_(NULL) { | 263 certs_(NULL) { |
| 264 SECStatus rv = SSL_PeerCertificateChain(nss_fd, NULL, &num_certs_); | 264 SECStatus rv = SSL_PeerCertificateChain(nss_fd, NULL, &num_certs_, 0); |
| 265 DCHECK_EQ(rv, SECSuccess); | 265 DCHECK_EQ(rv, SECSuccess); |
| 266 | 266 |
| 267 certs_ = new CERTCertificate*[num_certs_]; | 267 certs_ = new CERTCertificate*[num_certs_]; |
| 268 const unsigned expected_num_certs = num_certs_; | 268 const unsigned expected_num_certs = num_certs_; |
| 269 rv = SSL_PeerCertificateChain(nss_fd, certs_, &num_certs_); | 269 rv = SSL_PeerCertificateChain(nss_fd, certs_, &num_certs_, |
| 270 expected_num_certs); | |
| 270 DCHECK_EQ(rv, SECSuccess); | 271 DCHECK_EQ(rv, SECSuccess); |
| 271 DCHECK_EQ(num_certs_, expected_num_certs); | 272 DCHECK_EQ(num_certs_, expected_num_certs); |
| 272 } | 273 } |
| 273 | 274 |
| 274 ~PeerCertificateChain() { | 275 ~PeerCertificateChain() { |
| 275 for (unsigned i = 0; i < num_certs_; i++) | 276 for (unsigned i = 0; i < num_certs_; i++) |
| 276 CERT_DestroyCertificate(certs_[i]); | 277 CERT_DestroyCertificate(certs_[i]); |
| 277 delete[] certs_; | 278 delete[] certs_; |
| 278 } | 279 } |
| 279 | 280 |
| (...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 906 #ifdef SSL_ENABLE_DEFLATE | 907 #ifdef SSL_ENABLE_DEFLATE |
| 907 // Some web servers have been found to break if TLS is used *or* if DEFLATE | 908 // Some web servers have been found to break if TLS is used *or* if DEFLATE |
| 908 // is advertised. Thus, if TLS is disabled (probably because we are doing | 909 // is advertised. Thus, if TLS is disabled (probably because we are doing |
| 909 // SSLv3 fallback), we disable DEFLATE also. | 910 // SSLv3 fallback), we disable DEFLATE also. |
| 910 // See http://crbug.com/31628 | 911 // See http://crbug.com/31628 |
| 911 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_DEFLATE, ssl_config_.tls1_enabled); | 912 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_DEFLATE, ssl_config_.tls1_enabled); |
| 912 if (rv != SECSuccess) | 913 if (rv != SECSuccess) |
| 913 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_DEFLATE"); | 914 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_DEFLATE"); |
| 914 #endif | 915 #endif |
| 915 | 916 |
| 916 #ifdef SSL_ENABLE_FALSE_START | 917 PRBool false_start_enabled = |
| 917 rv = SSL_OptionSet( | |
| 918 nss_fd_, SSL_ENABLE_FALSE_START, | |
| 919 ssl_config_.false_start_enabled && | 918 ssl_config_.false_start_enabled && |
| 920 !SSLConfigService::IsKnownFalseStartIncompatibleServer( | 919 !SSLConfigService::IsKnownFalseStartIncompatibleServer( |
| 921 host_and_port_.host())); | 920 host_and_port_.host()); |
| 921 #ifdef SSL_ENABLE_FALSE_START | |
| 922 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_FALSE_START, false_start_enabled); | |
| 922 if (rv != SECSuccess) | 923 if (rv != SECSuccess) |
| 923 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_FALSE_START"); | 924 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_FALSE_START"); |
| 924 #endif | 925 #endif |
| 925 | 926 |
| 926 #ifdef SSL_ENABLE_RENEGOTIATION | 927 #ifdef SSL_ENABLE_RENEGOTIATION |
| 927 // We allow servers to request renegotiation. Since we're a client, | 928 // We allow servers to request renegotiation. Since we're a client, |
| 928 // prohibiting this is rather a waste of time. Only servers are in a | 929 // prohibiting this is rather a waste of time. Only servers are in a |
| 929 // position to prevent renegotiation attacks. | 930 // position to prevent renegotiation attacks. |
| 930 // http://extendedsubset.com/?p=8 | 931 // http://extendedsubset.com/?p=8 |
| 931 | 932 |
| 932 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_RENEGOTIATION, | 933 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_RENEGOTIATION, |
| 933 SSL_RENEGOTIATE_TRANSITIONAL); | 934 SSL_RENEGOTIATE_TRANSITIONAL); |
| 934 if (rv != SECSuccess) { | 935 if (rv != SECSuccess) { |
| 935 LogFailedNSSFunction( | 936 LogFailedNSSFunction( |
| 936 net_log_, "SSL_OptionSet", "SSL_ENABLE_RENEGOTIATION"); | 937 net_log_, "SSL_OptionSet", "SSL_ENABLE_RENEGOTIATION"); |
| 937 } | 938 } |
| 938 #endif // SSL_ENABLE_RENEGOTIATION | 939 #endif // SSL_ENABLE_RENEGOTIATION |
| 939 | 940 |
| 940 #ifdef SSL_NEXT_PROTO_NEGOTIATED | |
|
wtc
2012/03/02 23:06:17
In the NSS upstream, SSL_NEXT_PROTO_NEGOTIATED is
| |
| 941 if (!ssl_config_.next_protos.empty()) { | 941 if (!ssl_config_.next_protos.empty()) { |
| 942 rv = SSL_SetNextProtoCallback( | 942 rv = SSL_SetNextProtoCallback( |
| 943 nss_fd_, SSLClientSocketNSS::NextProtoCallback, this); | 943 nss_fd_, SSLClientSocketNSS::NextProtoCallback, this); |
| 944 if (rv != SECSuccess) | 944 if (rv != SECSuccess) |
| 945 LogFailedNSSFunction(net_log_, "SSL_SetNextProtoCallback", ""); | 945 LogFailedNSSFunction(net_log_, "SSL_SetNextProtoCallback", ""); |
| 946 } | 946 } |
| 947 | |
| 948 #ifdef SSL_CBC_RANDOM_IV | |
| 949 rv = SSL_OptionSet(nss_fd_, SSL_CBC_RANDOM_IV, false_start_enabled); | |
|
wtc
2012/03/02 23:06:17
The SSL_CBC_RANDOM_IV option (SSL 1/n-1 record spl
| |
| 950 if (rv != SECSuccess) | |
| 951 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_CBC_RANDOM_IV"); | |
| 947 #endif | 952 #endif |
| 948 | 953 |
| 949 #ifdef SSL_ENABLE_OCSP_STAPLING | 954 #ifdef SSL_ENABLE_OCSP_STAPLING |
| 950 if (IsOCSPStaplingSupported()) { | 955 if (IsOCSPStaplingSupported()) { |
| 951 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_OCSP_STAPLING, PR_TRUE); | 956 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_OCSP_STAPLING, PR_TRUE); |
| 952 if (rv != SECSuccess) { | 957 if (rv != SECSuccess) { |
| 953 LogFailedNSSFunction(net_log_, "SSL_OptionSet", | 958 LogFailedNSSFunction(net_log_, "SSL_OptionSet", |
| 954 "SSL_ENABLE_OCSP_STAPLING"); | 959 "SSL_ENABLE_OCSP_STAPLING"); |
| 955 } | 960 } |
| 956 } | 961 } |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1363 LeaveFunction(""); | 1368 LeaveFunction(""); |
| 1364 return rv; | 1369 return rv; |
| 1365 } | 1370 } |
| 1366 | 1371 |
| 1367 bool SSLClientSocketNSS::LoadSSLHostInfo() { | 1372 bool SSLClientSocketNSS::LoadSSLHostInfo() { |
| 1368 const SSLHostInfo::State& state(ssl_host_info_->state()); | 1373 const SSLHostInfo::State& state(ssl_host_info_->state()); |
| 1369 | 1374 |
| 1370 if (state.certs.empty()) | 1375 if (state.certs.empty()) |
| 1371 return true; | 1376 return true; |
| 1372 | 1377 |
| 1373 SECStatus rv; | |
| 1374 const std::vector<std::string>& certs_in = state.certs; | 1378 const std::vector<std::string>& certs_in = state.certs; |
| 1375 scoped_array<CERTCertificate*> certs(new CERTCertificate*[certs_in.size()]); | 1379 scoped_array<CERTCertificate*> certs(new CERTCertificate*[certs_in.size()]); |
| 1376 | 1380 |
| 1377 for (size_t i = 0; i < certs_in.size(); i++) { | 1381 for (size_t i = 0; i < certs_in.size(); i++) { |
| 1378 SECItem derCert; | 1382 SECItem derCert; |
| 1379 derCert.data = | 1383 derCert.data = |
| 1380 const_cast<uint8*>(reinterpret_cast<const uint8*>(certs_in[i].data())); | 1384 const_cast<uint8*>(reinterpret_cast<const uint8*>(certs_in[i].data())); |
| 1381 derCert.len = certs_in[i].size(); | 1385 derCert.len = certs_in[i].size(); |
| 1382 certs[i] = CERT_NewTempCertificate( | 1386 certs[i] = CERT_NewTempCertificate( |
| 1383 CERT_GetDefaultCertDB(), &derCert, NULL /* no nickname given */, | 1387 CERT_GetDefaultCertDB(), &derCert, NULL /* no nickname given */, |
| 1384 PR_FALSE /* not permanent */, PR_TRUE /* copy DER data */); | 1388 PR_FALSE /* not permanent */, PR_TRUE /* copy DER data */); |
| 1385 if (!certs[i]) { | 1389 if (!certs[i]) { |
| 1386 DestroyCertificates(&certs[0], i); | 1390 DestroyCertificates(&certs[0], i); |
| 1387 NOTREACHED(); | 1391 NOTREACHED(); |
| 1388 return false; | 1392 return false; |
| 1389 } | 1393 } |
| 1390 } | 1394 } |
| 1391 | 1395 |
| 1396 SECStatus rv; | |
| 1397 #ifdef SSL_ENABLE_CACHED_INFO | |
|
wtc
2012/03/02 23:06:17
This ifdef is necessary because SSL_SetPredictedPe
| |
| 1392 rv = SSL_SetPredictedPeerCertificates(nss_fd_, certs.get(), certs_in.size()); | 1398 rv = SSL_SetPredictedPeerCertificates(nss_fd_, certs.get(), certs_in.size()); |
| 1399 DCHECK_EQ(SECSuccess, rv); | |
| 1400 #else | |
| 1401 rv = SECFailure; // Not implemented. | |
| 1402 #endif | |
| 1393 DestroyCertificates(&certs[0], certs_in.size()); | 1403 DestroyCertificates(&certs[0], certs_in.size()); |
| 1394 DCHECK_EQ(SECSuccess, rv); | |
| 1395 | 1404 |
| 1396 return true; | 1405 return rv == SECSuccess; |
| 1397 } | 1406 } |
| 1398 | 1407 |
| 1399 int SSLClientSocketNSS::DoLoadSSLHostInfo() { | 1408 int SSLClientSocketNSS::DoLoadSSLHostInfo() { |
| 1400 EnterFunction(""); | 1409 EnterFunction(""); |
| 1401 int rv = ssl_host_info_->WaitForDataReady( | 1410 int rv = ssl_host_info_->WaitForDataReady( |
| 1402 base::Bind(&SSLClientSocketNSS::OnHandshakeIOComplete, | 1411 base::Bind(&SSLClientSocketNSS::OnHandshakeIOComplete, |
| 1403 base::Unretained(this))); | 1412 base::Unretained(this))); |
| 1404 GotoState(STATE_HANDSHAKE); | 1413 GotoState(STATE_HANDSHAKE); |
| 1405 | 1414 |
| 1406 if (rv == OK) { | 1415 if (rv == OK) { |
| (...skipping 1242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2649 // supports NPN, to select a protocol from the list that the server offered. | 2658 // supports NPN, to select a protocol from the list that the server offered. |
| 2650 // See the comment in net/third_party/nss/ssl/ssl.h for the meanings of the | 2659 // See the comment in net/third_party/nss/ssl/ssl.h for the meanings of the |
| 2651 // arguments. | 2660 // arguments. |
| 2652 // static | 2661 // static |
| 2653 SECStatus | 2662 SECStatus |
| 2654 SSLClientSocketNSS::NextProtoCallback(void* arg, | 2663 SSLClientSocketNSS::NextProtoCallback(void* arg, |
| 2655 PRFileDesc* nss_fd, | 2664 PRFileDesc* nss_fd, |
| 2656 const unsigned char* protos, | 2665 const unsigned char* protos, |
| 2657 unsigned int protos_len, | 2666 unsigned int protos_len, |
| 2658 unsigned char* proto_out, | 2667 unsigned char* proto_out, |
| 2659 unsigned int* proto_out_len) { | 2668 unsigned int* proto_out_len, |
| 2669 unsigned int proto_max_len) { | |
| 2660 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); | 2670 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); |
| 2661 | 2671 |
| 2662 // For each protocol in server preference, see if we support it. | 2672 // For each protocol in server preference, see if we support it. |
| 2663 for (unsigned int i = 0; i < protos_len; ) { | 2673 for (unsigned int i = 0; i < protos_len; ) { |
| 2664 const size_t len = protos[i]; | 2674 const size_t len = protos[i]; |
| 2665 for (std::vector<std::string>::const_iterator | 2675 for (std::vector<std::string>::const_iterator |
| 2666 j = that->ssl_config_.next_protos.begin(); | 2676 j = that->ssl_config_.next_protos.begin(); |
| 2667 j != that->ssl_config_.next_protos.end(); j++) { | 2677 j != that->ssl_config_.next_protos.end(); j++) { |
| 2668 // Having very long elements in the |next_protos| vector isn't a disaster | 2678 // Having very long elements in the |next_protos| vector isn't a disaster |
| 2669 // because they'll never be selected, but it does indicate an error | 2679 // because they'll never be selected, but it does indicate an error |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 2688 | 2698 |
| 2689 that->server_protos_.assign( | 2699 that->server_protos_.assign( |
| 2690 reinterpret_cast<const char*>(protos), protos_len); | 2700 reinterpret_cast<const char*>(protos), protos_len); |
| 2691 | 2701 |
| 2692 // If we didn't find a protocol, we select the first one from our list. | 2702 // If we didn't find a protocol, we select the first one from our list. |
| 2693 if (that->next_proto_status_ != kNextProtoNegotiated) { | 2703 if (that->next_proto_status_ != kNextProtoNegotiated) { |
| 2694 that->next_proto_status_ = kNextProtoNoOverlap; | 2704 that->next_proto_status_ = kNextProtoNoOverlap; |
| 2695 that->next_proto_ = that->ssl_config_.next_protos[0]; | 2705 that->next_proto_ = that->ssl_config_.next_protos[0]; |
| 2696 } | 2706 } |
| 2697 | 2707 |
| 2708 if (that->next_proto_.size() > proto_max_len) { | |
| 2709 PORT_SetError(SEC_ERROR_OUTPUT_LEN); | |
| 2710 return SECFailure; | |
| 2711 } | |
| 2698 memcpy(proto_out, that->next_proto_.data(), that->next_proto_.size()); | 2712 memcpy(proto_out, that->next_proto_.data(), that->next_proto_.size()); |
| 2699 *proto_out_len = that->next_proto_.size(); | 2713 *proto_out_len = that->next_proto_.size(); |
| 2700 return SECSuccess; | 2714 return SECSuccess; |
| 2701 } | 2715 } |
| 2702 | 2716 |
| 2703 void SSLClientSocketNSS::EnsureThreadIdAssigned() const { | 2717 void SSLClientSocketNSS::EnsureThreadIdAssigned() const { |
| 2704 base::AutoLock auto_lock(lock_); | 2718 base::AutoLock auto_lock(lock_); |
| 2705 if (valid_thread_id_ != base::kInvalidThreadId) | 2719 if (valid_thread_id_ != base::kInvalidThreadId) |
| 2706 return; | 2720 return; |
| 2707 valid_thread_id_ = base::PlatformThread::CurrentId(); | 2721 valid_thread_id_ = base::PlatformThread::CurrentId(); |
| 2708 } | 2722 } |
| 2709 | 2723 |
| 2710 bool SSLClientSocketNSS::CalledOnValidThread() const { | 2724 bool SSLClientSocketNSS::CalledOnValidThread() const { |
| 2711 EnsureThreadIdAssigned(); | 2725 EnsureThreadIdAssigned(); |
| 2712 base::AutoLock auto_lock(lock_); | 2726 base::AutoLock auto_lock(lock_); |
| 2713 return valid_thread_id_ == base::PlatformThread::CurrentId(); | 2727 return valid_thread_id_ == base::PlatformThread::CurrentId(); |
| 2714 } | 2728 } |
| 2715 | 2729 |
| 2716 OriginBoundCertService* SSLClientSocketNSS::GetOriginBoundCertService() const { | 2730 OriginBoundCertService* SSLClientSocketNSS::GetOriginBoundCertService() const { |
| 2717 return origin_bound_cert_service_; | 2731 return origin_bound_cert_service_; |
| 2718 } | 2732 } |
| 2719 | 2733 |
| 2720 } // namespace net | 2734 } // namespace net |
| OLD | NEW |