Chromium Code Reviews| Index: net/socket/ssl_client_socket_nss.cc |
| =================================================================== |
| --- net/socket/ssl_client_socket_nss.cc (revision 86360) |
| +++ net/socket/ssl_client_socket_nss.cc (working copy) |
| @@ -620,7 +620,11 @@ |
| } |
| } |
| - GotoState(STATE_HANDSHAKE); |
| + if (ssl_host_info_.get()) { |
|
wtc
2011/06/03 22:56:55
This should also check that the cached info extens
rkn
2011/06/04 20:50:19
Done.
|
| + GotoState(STATE_LOAD_SSL_HOST_INFO); |
| + } else { |
| + GotoState(STATE_HANDSHAKE); |
| + } |
| rv = DoHandshakeLoop(OK); |
| if (rv == ERR_IO_PENDING) { |
| @@ -956,6 +960,13 @@ |
| } |
| #endif |
| +#ifdef SSL_ENABLE_CACHED_INFO |
| + rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_CACHED_INFO, |
| + ssl_config_.cached_info_enabled); |
| + if (rv != SECSuccess) |
| + LogFailedNSSFunction(net_log_, "SSL_OptionSet (CachedInfo)", ""); |
|
wtc
2011/06/03 22:56:55
I think we should imitate lines 940 and 972 instea
rkn
2011/06/04 20:50:19
Done.
|
| +#endif |
| + |
| rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); |
| if (rv != SECSuccess) { |
| LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT"); |
| @@ -1237,6 +1248,9 @@ |
| case STATE_NONE: |
| // we're just pumping data between the buffer and the network |
| break; |
| + case STATE_LOAD_SSL_HOST_INFO: |
| + rv = DoLoadSSLHostInfo(); |
| + break; |
| case STATE_HANDSHAKE: |
| rv = DoHandshake(); |
| break; |
| @@ -1321,6 +1335,56 @@ |
| return rv; |
| } |
| +bool SSLClientSocketNSS::LoadSSLHostInfo() { |
| + const SSLHostInfo::State& state(ssl_host_info_->state()); |
| + |
| + if (state.certs.empty()) { |
| + return false; |
| + } |
| + |
| + SECStatus rv; |
| + |
| + const std::vector<std::string>& certs_in = state.certs; |
| + scoped_array<CERTCertificate*> certs(new CERTCertificate*[certs_in.size()]); |
| + for (size_t i = 0; i < certs_in.size(); i++) { |
| + SECItem derCert; |
| + derCert.data = |
| + const_cast<uint8*>(reinterpret_cast<const uint8*>(certs_in[i].data())); |
| + derCert.len = certs_in[i].size(); |
| + certs[i] = CERT_NewTempCertificate( |
| + CERT_GetDefaultCertDB(), &derCert, NULL /* no nickname given */, |
| + PR_FALSE /* not permanent */, PR_TRUE /* copy DER data */); |
| + if (!certs[i]) { |
| + DestroyCertificates(&certs[0], i); |
| + NOTREACHED(); // I don't understand this line. |
| + return false; |
| + } |
| + } |
| + |
| + rv = SSL_SetPredictedPeerCertificates(nss_fd_, certs.get(), certs_in.size()); |
| + DestroyCertificates(&certs[0], certs_in.size()); |
| + DCHECK_EQ(SECSuccess, rv); |
| + |
| + return true; |
| +} |
| + |
| +int SSLClientSocketNSS::DoLoadSSLHostInfo() { |
| + EnterFunction(""); |
| + int rv = ssl_host_info_->WaitForDataReady(&handshake_io_callback_); |
| + GotoState(STATE_HANDSHAKE); |
| + |
| + if (rv == OK) { |
| + if (!LoadSSLHostInfo()) |
| + LOG(WARNING) << "LoadSSLHostInfo failed: " << host_and_port_.ToString(); |
| + } else { |
| + DCHECK_EQ(ERR_IO_PENDING, rv); |
| + GotoState(STATE_LOAD_SSL_HOST_INFO); |
| + } |
| + |
| + LeaveFunction(""); |
| + return rv; |
| +} |
| + |
| int SSLClientSocketNSS::DoHandshake() { |
| EnterFunction(""); |
| int net_error = net::OK; |
| @@ -1345,7 +1409,8 @@ |
| } else { |
| // We need to see if the predicted certificate chain (in |
| // |ssl_host_info_->state().certs) matches the actual certificate chain |
| - // before we try to save it before we update |ssl_host_info_|. |
| + // before we call SaveSSLHostInfo, as that will update |
| + // |ssl_host_info_|. |
| if (ssl_host_info_.get() && !ssl_host_info_->state().certs.empty()) { |
| PeerCertificateChain certs(nss_fd_); |
| const SSLHostInfo::State& state = ssl_host_info_->state(); |