Chromium Code Reviews| Index: net/socket/ssl_client_socket_nss.cc |
| diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc |
| index cefe6306f5ffbe596b2789618ae108bea6a21b16..a77f19b0ce2ec23d66f2433c0bfe54a537bc3b52 100644 |
| --- a/net/socket/ssl_client_socket_nss.cc |
| +++ b/net/socket/ssl_client_socket_nss.cc |
| @@ -52,6 +52,7 @@ |
| #include <keyhi.h> |
| #include <nspr.h> |
| #include <nss.h> |
| +#include <ocsp.h> |
| #include <pk11pub.h> |
| #include <secerr.h> |
| #include <sechash.h> |
| @@ -111,6 +112,28 @@ static const int kRecvBufferSize = 4096; |
| // and some will time out such sockets quite aggressively. |
| static const int kCorkTimeoutMs = 200; |
| +#if defined(OS_LINUX) |
|
wtc
2010/11/23 00:44:45
We should ideally test USE_NSS instead of OS_LINUX
agl
2010/11/30 15:59:46
I think this is specifically a Linux (and maybe Fr
|
| +// On Linux, we dynamically link against the system version of libnss3.so. In |
| +// order to continue working on systems without up-to-date versions of NSS we |
| +// declare CERT_CacheOCSPResponseFromSideChannel to be a weak symbol. If, at |
| +// run time, we find that the symbol didn't resolve then we can avoid calling |
| +// the function. |
| +extern SECStatus |
| +CERT_CacheOCSPResponseFromSideChannel( |
| + CERTCertDBHandle *handle, CERTCertificate *cert, PRTime time, |
| + SECItem *encodedResponse, void *pwArg) __attribute__((weak)); |
|
wtc
2010/11/23 00:44:45
Does "weak" need to be double-parenthesized?
agl
2010/11/30 15:59:46
It's the GCC syntax.
|
| + |
| +static bool HaveCacheOCSPResponseFromSideChannelFunction() { |
| + return CERT_CacheOCSPResponseFromSideChannel != NULL; |
| +} |
| +#else |
| +// On other platforms we ship this function ourselves so we know that we have |
|
wtc
2010/11/23 00:44:45
This comment is misleading because on other platfo
agl
2010/11/30 15:59:46
Have changed the comment to include that point, ha
|
| +// it. |
| +static bool HaveCacheOCSPResponseFromSideChannelFunction() { |
| + return true; |
| +} |
| +#endif |
| + |
| namespace net { |
| // State machines are easier to debug if you log state transitions. |
| @@ -801,6 +824,14 @@ int SSLClientSocketNSS::InitializeSSLOptions() { |
| } |
| #endif |
| +#ifdef SSL_ENABLE_OCSP_STAPLING |
| + if (!ssl_config_.snap_start_enabled) { |
| + rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_OCSP_STAPLING, PR_TRUE); |
| + if (rv != SECSuccess) |
| + LogFailedNSSFunction(net_log_, "SSL_OptionSet (OCSP stapling)", ""); |
| + } |
| +#endif |
| + |
| rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); |
| if (rv != SECSuccess) { |
| LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT"); |
| @@ -2157,6 +2188,29 @@ int SSLClientSocketNSS::DoHandshake() { |
| } |
| } |
| +#if defined(SSL_ENABLE_OCSP_STAPLING) |
| + if (!predicted_cert_chain_correct_ && |
| + HaveCacheOCSPResponseFromSideChannelFunction()) { |
|
wtc
2010/11/23 00:44:45
Could you add a TODO comment to note that we need
agl
2010/11/30 15:59:46
Done.
|
| + unsigned int len = 0; |
| + SSL_GetOCSPStapledData(nss_fd_, NULL, &len); |
| + if (len) { |
| + const unsigned int orig_len = len; |
| + scoped_array<uint8> ocsp_response(new uint8[orig_len]); |
| + SSL_GetOCSPStapledData(nss_fd_, ocsp_response.get(), &len); |
| + DCHECK_EQ(orig_len, len); |
| + |
| + SECItem ocsp_response_item; |
| + memset(&ocsp_response_item, 0, sizeof(ocsp_response_item)); |
|
wtc
2010/11/23 00:44:45
Nit: you can replace this memset call with
ocs
agl
2010/11/30 15:59:46
Done.
|
| + ocsp_response_item.data = ocsp_response.get(); |
| + ocsp_response_item.len = len; |
| + |
| + CERT_CacheOCSPResponseFromSideChannel( |
| + CERT_GetDefaultCertDB(), server_cert_nss_, PR_Now(), |
| + &ocsp_response_item, NULL); |
| + } |
| + } |
| +#endif |
| + |
| SaveSnapStartInfo(); |
| // SSL handshake is completed. It's possible that we mispredicted the |
| // NPN agreed protocol. In this case, we've just sent a request in the |