diff options
author | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-01 20:28:03 +0000 |
---|---|---|
committer | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-01 20:28:03 +0000 |
commit | 3dd6f5e0807447194b12c7adc9a730d81738a0a6 (patch) | |
tree | 6176f288326fdb65d167ce419929260209fff32b | |
parent | 3f94a9eedbb0bd352beeea9ae65591c69c9012f1 (diff) | |
download | chromium_src-3dd6f5e0807447194b12c7adc9a730d81738a0a6.zip chromium_src-3dd6f5e0807447194b12c7adc9a730d81738a0a6.tar.gz chromium_src-3dd6f5e0807447194b12c7adc9a730d81738a0a6.tar.bz2 |
Use SSLClientSocketNSS on Mac OS X. By default, chrome still uses
SSLClientSocketMac. Specify the --use-nss-for-ssl command-line
option to use SSLClientSocketNSS.
The nss.gyp in src/net/third_party/nss is renamed ssl.gyp to avoid
a naming conflict with the nss.gyp in src/third_party/nss. The
GYP generator for Xcode project files disallows same-named .gyp files.
SSL client authentication doesn't work yet.
R=mark
BUG=30689
TEST=No build and test failures on Mac and Windows.
Review URL: http://codereview.chromium.org/2322008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@48650 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/base.gypi | 14 | ||||
-rw-r--r-- | base/nss_util.cc | 2 | ||||
-rw-r--r-- | build/all.gyp | 7 | ||||
-rw-r--r-- | build/linux/system.gyp | 2 | ||||
-rw-r--r-- | chrome/browser/browser_main.cc | 14 | ||||
-rw-r--r-- | chrome/common/chrome_switches.cc | 4 | ||||
-rw-r--r-- | chrome/common/chrome_switches.h | 1 | ||||
-rw-r--r-- | net/base/x509_certificate.h | 21 | ||||
-rw-r--r-- | net/net.gyp | 82 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_nss.cc | 52 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_nss.h | 6 | ||||
-rw-r--r-- | net/third_party/nss/ssl.gyp (renamed from net/third_party/nss/nss.gyp) | 31 |
12 files changed, 121 insertions, 115 deletions
diff --git a/base/base.gypi b/base/base.gypi index ad41e45..fd9ea54 100644 --- a/base/base.gypi +++ b/base/base.gypi @@ -332,14 +332,7 @@ 'sources/': [ ['exclude', '_openbsd\\.cc$'] ], }, ], - [ 'OS == "mac"', { - 'sources!': [ - # TODO(wtc): Remove nss_util.{cc,h} when http://crbug.com/30689 - # is fixed. - 'nss_util.cc', - 'nss_util.h', - ], - }, { # OS != "mac" + [ 'OS != "mac"', { 'sources!': [ 'crypto/cssm_init.cc', 'crypto/cssm_init.h', @@ -453,11 +446,12 @@ ], }, },], - [ 'OS == "win"', { + [ 'OS == "mac" or OS == "win"', { 'dependencies': [ '../third_party/nss/nss.gyp:nss', ], - }, { # OS != "win" + },], + [ 'OS != "win"', { 'dependencies': ['../third_party/libevent/libevent.gyp:libevent'], 'sources!': [ 'third_party/purify/pure_api.c', diff --git a/base/nss_util.cc b/base/nss_util.cc index 4e67faf..7043b8d 100644 --- a/base/nss_util.cc +++ b/base/nss_util.cc @@ -21,7 +21,7 @@ // On some platforms, we use NSS for SSL only -- we don't use NSS for crypto // or certificate verification, and we don't use the NSS certificate and key // databases. -#if defined(OS_WIN) +#if defined(OS_MACOSX) || defined(OS_WIN) #define USE_NSS_FOR_SSL_ONLY 1 #endif diff --git a/build/all.gyp b/build/all.gyp index 39513ed..175332b 100644 --- a/build/all.gyp +++ b/build/all.gyp @@ -19,6 +19,7 @@ '../ipc/ipc.gyp:*', '../media/media.gyp:*', '../net/net.gyp:*', + '../net/third_party/nss/ssl.gyp:*', '../printing/printing.gyp:*', '../sdch/sdch.gyp:*', '../skia/skia.gyp:*', @@ -58,6 +59,11 @@ '../third_party/yasm/yasm.gyp:*#host', ], }], + ['OS=="mac" or OS=="win"', { + 'dependencies': [ + '../third_party/nss/nss.gyp:*', + ], + }], ['OS=="mac"', { 'dependencies': [ '../third_party/ocmock/ocmock.gyp:*', @@ -81,7 +87,6 @@ 'dependencies': [ '../tools/gtk_clipboard_dump/gtk_clipboard_dump.gyp:*', '../tools/xdisplaycheck/xdisplaycheck.gyp:*', - '../net/third_party/nss/nss.gyp:*', ], }], ['OS=="win"', { diff --git a/build/linux/system.gyp b/build/linux/system.gyp index 94650e9..dbd394b 100644 --- a/build/linux/system.gyp +++ b/build/linux/system.gyp @@ -76,7 +76,7 @@ 'conditions': [ ['use_system_ssl==0', { 'dependencies': [ - '../../net/third_party/nss/nss.gyp:ssl', + '../../net/third_party/nss/ssl.gyp:ssl', '../../third_party/zlib/zlib.gyp:zlib', ], 'direct_dependent_settings': { diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc index b777843..2d959c3 100644 --- a/chrome/browser/browser_main.cc +++ b/chrome/browser/browser_main.cc @@ -113,7 +113,6 @@ #include "app/l10n_util_win.h" #include "app/win_util.h" -#include "base/nss_util.h" #include "base/registry.h" #include "base/win_util.h" #include "chrome/browser/browser.h" @@ -133,7 +132,6 @@ #include "net/base/net_util.h" #include "net/base/sdch_manager.h" #include "net/base/winsock_init.h" -#include "net/socket/ssl_client_socket_nss_factory.h" #include "printing/printed_document.h" #include "sandbox/src/sandbox.h" #endif // defined(OS_WIN) @@ -143,6 +141,11 @@ #include "chrome/browser/cocoa/install_from_dmg.h" #endif +#if defined(OS_MACOSX) || defined(OS_WIN) +#include "base/nss_util.h" +#include "net/socket/ssl_client_socket_nss_factory.h" +#endif + #if defined(TOOLKIT_VIEWS) #include "chrome/browser/views/chrome_views_delegate.h" #include "views/focus/accelerator_handler.h" @@ -757,8 +760,13 @@ int BrowserMain(const MainFunctionParams& parameters) { } } +#if defined(OS_MACOSX) || defined(OS_WIN) #if defined(OS_WIN) - if (!parsed_command_line.HasSwitch(switches::kUseSChannel) || + bool use_nss_for_ssl = !parsed_command_line.HasSwitch(switches::kUseSChannel); +#else + bool use_nss_for_ssl = parsed_command_line.HasSwitch(switches::kUseNSSForSSL); +#endif + if (use_nss_for_ssl || parsed_command_line.HasSwitch(switches::kUseSpdy) || is_spdy_trial) { net::ClientSocketFactory::SetSSLClientSocketFactory( diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index f09e7c5..04de5ab 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -931,6 +931,10 @@ const char kEnableSandboxLogging[] = "enable-sandbox-logging"; // Temporary flag to prevent Flash from negotiating the Core Animation drawing // model. This will be removed once the last issues have been resolved. const char kDisableFlashCoreAnimation[] = "disable-flash-core-animation"; + +// Use NSS instead of the system SSL library for SSL. +// This is a temporary testing flag. +const char kUseNSSForSSL[] = "use-nss-for-ssl"; #else // Enable Kiosk mode. const char kKioskMode[] = "kiosk"; diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index beb64fb..d21d221 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -272,6 +272,7 @@ extern const char kNoProcessSingletonDialog[]; #if defined(OS_MACOSX) extern const char kDisableFlashCoreAnimation[]; extern const char kEnableSandboxLogging[]; +extern const char kUseNSSForSSL[]; #else extern const char kKioskMode[]; #endif diff --git a/net/base/x509_certificate.h b/net/base/x509_certificate.h index 6bccdf3..5c80b2d 100644 --- a/net/base/x509_certificate.h +++ b/net/base/x509_certificate.h @@ -210,6 +210,16 @@ class X509Certificate : public base::RefCountedThreadSafe<X509Certificate> { // Returns true if two OSCertHandles refer to identical certificates. static bool IsSameOSCert(OSCertHandle a, OSCertHandle b); + // Creates an OS certificate handle from the BER-encoded representation. + // Returns NULL on failure. + static OSCertHandle CreateOSCertHandleFromBytes(const char* data, + int length); + + // Duplicates (or adds a reference to) an OS certificate handle. + static OSCertHandle DupOSCertHandle(OSCertHandle cert_handle); + + // Frees (or releases a reference to) an OS certificate handle. + static void FreeOSCertHandle(OSCertHandle cert_handle); private: friend class base::RefCountedThreadSafe<X509Certificate>; @@ -254,17 +264,6 @@ class X509Certificate : public base::RefCountedThreadSafe<X509Certificate> { bool VerifyEV() const; - // Creates an OS certificate handle from the BER-encoded representation. - // Returns NULL on failure. - static OSCertHandle CreateOSCertHandleFromBytes(const char* data, - int length); - - // Duplicates (or adds a reference to) an OS certificate handle. - static OSCertHandle DupOSCertHandle(OSCertHandle cert_handle); - - // Frees (or releases a reference to) an OS certificate handle. - static void FreeOSCertHandle(OSCertHandle cert_handle); - // Calculates the SHA-1 fingerprint of the certificate. Returns an empty // (all zero) fingerprint on failure. static Fingerprint CalculateFingerprint(OSCertHandle cert_handle); diff --git a/net/net.gyp b/net/net.gyp index 5be0bee..14f2db8 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -175,12 +175,20 @@ ], 'conditions': [ [ 'OS == "linux" or OS == "freebsd" or OS == "openbsd"', { - 'dependencies': [ - '../build/linux/system.gyp:gconf', - '../build/linux/system.gyp:gdk', - '../build/linux/system.gyp:nss', - ], - }], + 'dependencies': [ + '../build/linux/system.gyp:gconf', + '../build/linux/system.gyp:gdk', + '../build/linux/system.gyp:nss', + ], + }, + { # else: OS is not in the above list + 'sources!': [ + 'base/cert_database_nss.cc', + 'base/keygen_handler_nss.cc', + 'base/x509_certificate_nss.cc', + ], + }, + ], [ 'OS == "win"', { 'dependencies': [ # For nss_memio.{c,h}, which require only NSPR. @@ -194,22 +202,10 @@ ], }, ], - [ 'OS == "linux" or OS == "freebsd" or OS == "openbsd"', { - }, - { # else: OS is not in the above list - 'sources!': [ - 'base/cert_database_nss.cc', - 'base/keygen_handler_nss.cc', - 'base/x509_certificate_nss.cc', - ], - }, - ], [ 'OS == "mac"', { - 'sources!': [ - # TODO(wtc): Remove nss_memio.{c,h} when http://crbug.com/30689 - # is fixed. - 'base/nss_memio.c', - 'base/nss_memio.h', + 'dependencies': [ + # For nss_memio.{c,h}, which require only NSPR. + '../third_party/nss/nss.gyp:nspr', ], 'link_settings': { 'libraries': [ @@ -552,12 +548,23 @@ ], }], [ 'OS == "linux" or OS == "freebsd" or OS == "openbsd"', { - 'dependencies': [ - '../build/linux/system.gyp:gconf', - '../build/linux/system.gyp:gdk', - '../build/linux/system.gyp:nss', - ], - }], + 'sources!': [ + 'socket/ssl_client_socket_nss_factory.cc', + 'socket/ssl_client_socket_nss_factory.h', + ], + 'dependencies': [ + '../build/linux/system.gyp:gconf', + '../build/linux/system.gyp:gdk', + '../build/linux/system.gyp:nss', + ], + }, + { # else: OS is not in the above list + 'sources!': [ + 'ocsp/nss_ocsp.cc', + 'ocsp/nss_ocsp.h', + ], + }, + ], [ 'OS == "win"', { 'sources!': [ 'http/http_auth_handler_ntlm_portable.cc', @@ -565,7 +572,7 @@ ], 'dependencies': [ '../third_party/nss/nss.gyp:nss', - 'third_party/nss/nss.gyp:ssl', + 'third_party/nss/ssl.gyp:ssl', 'tld_cleanup', ], 'link_settings': { @@ -577,26 +584,13 @@ { # else: OS != "win" 'sources!': [ 'proxy/proxy_resolver_winhttp.cc', - 'socket/ssl_client_socket_nss_factory.cc', - 'socket/ssl_client_socket_nss_factory.h', - ], - }, - ], - [ 'OS == "linux" or OS == "freebsd" or OS == "openbsd"', { - }, - { # else: OS != "linux" - 'sources!': [ - 'ocsp/nss_ocsp.cc', - 'ocsp/nss_ocsp.h', ], }, ], [ 'OS == "mac"', { - 'sources!': [ - # TODO(wtc): Remove ssl_client_socket_nss.{cc,h} when - # http://crbug.com/30689 is fixed. - 'socket/ssl_client_socket_nss.cc', - 'socket/ssl_client_socket_nss.h', + 'dependencies': [ + '../third_party/nss/nss.gyp:nss', + 'third_party/nss/ssl.gyp:ssl', ], 'link_settings': { 'libraries': [ diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc index f5484ec..f015b57 100644 --- a/net/socket/ssl_client_socket_nss.cc +++ b/net/socket/ssl_client_socket_nss.cc @@ -318,7 +318,7 @@ int SSLClientSocketNSS::Init() { EnsureNSSSSLInit(); if (!NSS_IsInitialized()) return ERR_UNEXPECTED; -#if !defined(OS_WIN) +#if !defined(OS_MACOSX) && !defined(OS_WIN) // We must call EnsureOCSPInit() here, on the IO thread, to get the IO loop // by MessageLoopForIO::current(). // X509Certificate::Verify() runs on a worker thread of CertVerifier. @@ -663,16 +663,12 @@ X509Certificate *SSLClientSocketNSS::UpdateServerCert() { if (server_cert_ == NULL) { server_cert_nss_ = SSL_PeerCertificate(nss_fd_); if (server_cert_nss_) { -#if defined(OS_WIN) - // TODO(wtc): close cert_store_ at shutdown. - if (!cert_store_) - cert_store_ = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL); - +#if defined(OS_MACOSX) || defined(OS_WIN) // Get each of the intermediate certificates in the server's chain. // These will be added to the server's X509Certificate object, making // them available to X509Certificate::Verify() for chain building. X509Certificate::OSCertHandles intermediate_ca_certs; - PCCERT_CONTEXT cert_context = NULL; + X509Certificate::OSCertHandle cert_handle = NULL; CERTCertList* cert_list = CERT_GetCertChainFromCert( server_cert_nss_, PR_Now(), certUsageSSLCA); if (cert_list) { @@ -681,6 +677,7 @@ X509Certificate *SSLClientSocketNSS::UpdateServerCert() { node = CERT_LIST_NEXT(node)) { if (node->cert == server_cert_nss_) continue; +#if defined(OS_WIN) // Work around http://crbug.com/43538 by not importing the // problematic COMODO EV SGC CA certificate. CryptoAPI will // download a good certificate for that CA, issued by COMODO @@ -688,35 +685,27 @@ X509Certificate *SSLClientSocketNSS::UpdateServerCert() { // certificate. if (IsProblematicComodoEVCACert(*node->cert)) continue; - cert_context = NULL; - BOOL ok = CertAddEncodedCertificateToStore( - cert_store_, - X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - node->cert->derCert.data, - node->cert->derCert.len, - CERT_STORE_ADD_USE_EXISTING, - &cert_context); - DCHECK(ok); - intermediate_ca_certs.push_back(cert_context); +#endif + cert_handle = X509Certificate::CreateOSCertHandleFromBytes( + reinterpret_cast<char*>(node->cert->derCert.data), + node->cert->derCert.len); + DCHECK(cert_handle); + intermediate_ca_certs.push_back(cert_handle); } CERT_DestroyCertList(cert_list); } // Finally create the X509Certificate object. - BOOL ok = CertAddEncodedCertificateToStore( - cert_store_, - X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - server_cert_nss_->derCert.data, - server_cert_nss_->derCert.len, - CERT_STORE_ADD_USE_EXISTING, - &cert_context); - DCHECK(ok); + cert_handle = X509Certificate::CreateOSCertHandleFromBytes( + reinterpret_cast<char*>(server_cert_nss_->derCert.data), + server_cert_nss_->derCert.len); + DCHECK(cert_handle); server_cert_ = X509Certificate::CreateFromHandle( - cert_context, + cert_handle, X509Certificate::SOURCE_FROM_NETWORK, intermediate_ca_certs); for (size_t i = 0; i < intermediate_ca_certs.size(); ++i) - CertFreeCertificateContext(intermediate_ca_certs[i]); + X509Certificate::FreeOSCertHandle(intermediate_ca_certs[i]); #else server_cert_ = X509Certificate::CreateFromHandle( CERT_DupCertificate(server_cert_nss_), @@ -1215,6 +1204,10 @@ SECStatus SSLClientSocketNSS::ClientAuthHandler( PCCERT_CHAIN_CONTEXT chain_context = NULL; + // TODO(wtc): close cert_store_ at shutdown. + if (!cert_store_) + cert_store_ = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL); + for (;;) { // Find a certificate chain. chain_context = CertFindChainInStore(my_cert_store, @@ -1255,6 +1248,11 @@ SECStatus SSLClientSocketNSS::ClientAuthHandler( // Tell NSS to suspend the client authentication. We will then abort the // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED. return SECWouldBlock; +#elif defined(OS_MACOSX) + // TODO(wtc): see http://crbug.com/45369. + // Not implemented. Send no client certificate. + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); + return SECFailure; #else CERTCertificate* cert = NULL; SECKEYPrivateKey* privkey = NULL; diff --git a/net/socket/ssl_client_socket_nss.h b/net/socket/ssl_client_socket_nss.h index 74f2003..7d51d6d 100644 --- a/net/socket/ssl_client_socket_nss.h +++ b/net/socket/ssl_client_socket_nss.h @@ -165,10 +165,8 @@ class SSLClientSocketNSS : public SSLClientSocket { BoundNetLog net_log_; #if defined(OS_WIN) - // A CryptoAPI in-memory certificate store. We use it for two purposes: - // 1. Import server certificates into this store so that we can verify and - // display the certificates using CryptoAPI. - // 2. Copy client certificates from the "MY" system certificate store into + // A CryptoAPI in-memory certificate store. We use it for one purpose: + // 1. Copy client certificates from the "MY" system certificate store into // this store so that we can close the system store when we finish // searching for client certificates. static HCERTSTORE cert_store_; diff --git a/net/third_party/nss/nss.gyp b/net/third_party/nss/ssl.gyp index a3610f5..3166be8 100644 --- a/net/third_party/nss/nss.gyp +++ b/net/third_party/nss/ssl.gyp @@ -67,6 +67,10 @@ 'ssl/bodge/loader.h', 'ssl/bodge/secure_memcmp.c', ], + 'sources!': [ + 'ssl/os2_err.c', + 'ssl/os2_err.h', + ], 'defines': [ 'NSS_ENABLE_ECC', 'NSS_ENABLE_ZLIB', @@ -77,13 +81,20 @@ 'NO_NSPR_10_SUPPORT', ], 'conditions': [ + [ 'OS == "win"', { + 'sources!': [ + 'ssl/unix_err.c', + 'ssl/unix_err.h', + ], + }, + { # else: OS != "win" + 'sources!': [ + 'ssl/win32err.c', + 'ssl/win32err.h', + ], + }, + ], [ 'OS == "linux" or OS == "freebsd" or OS == "openbsd"', { - 'sources!': [ - 'ssl/os2_err.c', - 'ssl/os2_err.h', - 'ssl/win32err.c', - 'ssl/win32err.h', - ], 'defines': [ # These macros are needed only for compiling the files in # ssl/bodge. @@ -105,16 +116,10 @@ '<!@(<(pkg-config) --libs-only-l nss | sed -e "s/-lssl3//")', ], }], - [ 'OS == "win"', { + [ 'OS == "mac" or OS == "win"', { 'sources/': [ ['exclude', 'ssl/bodge/'], ], - 'sources!': [ - 'ssl/os2_err.c', - 'ssl/os2_err.h', - 'ssl/unix_err.c', - 'ssl/unix_err.h', - ], 'dependencies': [ '../../../third_party/zlib/zlib.gyp:zlib', '../../../third_party/nss/nss.gyp:nss', |