summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--build/build_config.h7
-rw-r--r--build/common.gypi15
-rw-r--r--build/config/BUILD.gn9
-rw-r--r--build/config/crypto.gni15
-rw-r--r--build/linux/system.gyp30
-rw-r--r--chrome/chrome_common.gypi32
-rw-r--r--chrome/chrome_utility.gypi19
-rw-r--r--chrome/common/net/BUILD.gn28
-rw-r--r--chrome/utility/BUILD.gn24
-rw-r--r--chrome/utility/importer/nss_decryptor.h9
-rw-r--r--chrome/utility/importer/nss_decryptor_null.h44
-rw-r--r--components/webcrypto/test/test_helpers.cc2
-rw-r--r--crypto/BUILD.gn52
-rw-r--r--crypto/crypto.gyp24
-rw-r--r--crypto/rsa_private_key.h29
-rw-r--r--crypto/rsa_private_key_nss.cc32
-rw-r--r--crypto/rsa_private_key_nss_unittest.cc6
-rw-r--r--crypto/rsa_private_key_unittest.cc4
-rw-r--r--net/BUILD.gn107
-rw-r--r--net/cert/ev_root_ca_metadata_unittest.cc2
-rw-r--r--net/cert/x509_util_nss.cc317
-rw-r--r--net/cert/x509_util_nss_certs.cc346
-rw-r--r--net/net.gyp12
-rw-r--r--net/net.gypi2
-rw-r--r--net/net_common.gypi64
-rw-r--r--net/socket/ssl_client_socket_openssl.cc2
-rw-r--r--net/ssl/channel_id_service.cc4
-rw-r--r--net/ssl/openssl_platform_key_nss.cc17
-rw-r--r--net/test/cert_test_util_nss.cc9
29 files changed, 620 insertions, 643 deletions
diff --git a/build/build_config.h b/build/build_config.h
index 7137b4b..d8c3db6 100644
--- a/build/build_config.h
+++ b/build/build_config.h
@@ -61,11 +61,8 @@
#error Please add support for your platform in build/build_config.h
#endif
-#if defined(USE_OPENSSL) && defined(USE_NSS_CERTS)
-// TODO(davidben): This constraint compares somewhat orthogonal things and will
-// be fixed when BoringSSL with NSS for certificates is added as a build
-// configuration. See https://crbug.com/462040.
-#error Cannot use both OpenSSL and NSS
+#if defined(USE_OPENSSL_CERTS) && defined(USE_NSS_CERTS)
+#error Cannot use both OpenSSL and NSS for certificates
#endif
// For access to standard BSD features, use OS_BSD instead of a
diff --git a/build/common.gypi b/build/common.gypi
index c5a8e73..7c3074b 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -70,7 +70,10 @@
# certificates, use_openssl_certs must be set.
'use_openssl%': 0,
- # Typedef X509Certificate::OSCertHandle to OpenSSL's struct X509*.
+ # Use OpenSSL for representing certificates. When targeting Android,
+ # the platform certificate library is used for certificate
+ # verification. On other targets, this flag also enables OpenSSL for
+ # certificate verification, but this configuration is unsupported.
'use_openssl_certs%': 0,
# Disable viewport meta tag by default.
@@ -681,20 +684,12 @@
}],
# NSS usage.
- ['(OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris") and use_openssl==0', {
+ ['(OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris")', {
'use_nss_certs%': 1,
}, {
'use_nss_certs%': 0,
}],
- # When OpenSSL is used for SSL and crypto on Unix-like systems, use
- # OpenSSL's certificate definition.
- ['(OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris") and use_openssl==1', {
- 'use_openssl_certs%': 1,
- }, {
- 'use_openssl_certs%': 0,
- }],
-
# libudev usage. This currently only affects the content layer.
['OS=="linux" and embedded==0', {
'use_udev%': 1,
diff --git a/build/config/BUILD.gn b/build/config/BUILD.gn
index 471994d..22cb45a 100644
--- a/build/config/BUILD.gn
+++ b/build/config/BUILD.gn
@@ -122,10 +122,11 @@ config("feature_flags") {
}
if (use_openssl) {
defines += [ "USE_OPENSSL=1" ]
- if (use_openssl_certs) {
- defines += [ "USE_OPENSSL_CERTS=1" ]
- }
- } else if (use_nss_certs) {
+ }
+ if (use_openssl_certs) {
+ defines += [ "USE_OPENSSL_CERTS=1" ]
+ }
+ if (use_nss_certs) {
defines += [ "USE_NSS_CERTS=1" ]
}
if (use_ozone) {
diff --git a/build/config/crypto.gni b/build/config/crypto.gni
index ee23569..7f090b7 100644
--- a/build/config/crypto.gni
+++ b/build/config/crypto.gni
@@ -14,10 +14,13 @@ declare_args() {
use_openssl = is_android || is_mac || is_nacl || is_win
}
-# True when we're using OpenSSL for certificate verification and storage. We
-# only do this when we're using OpenSSL on desktop Linux systems. For other
-# systems (Mac/Win/Android) we use the system certificate features.
-use_openssl_certs = use_openssl && (is_linux || is_android)
+# True when we're using OpenSSL for representing certificates. When targeting
+# Android, the platform certificate library is used for certificate
+# verification. On other targets, this flag also enables OpenSSL for certificate
+# verification, but this configuration is unsupported.
+use_openssl_certs = is_android
-# Same meaning as use_openssl_certs but for NSS.
-use_nss_certs = !use_openssl && is_linux
+# True if NSS is used for certificate verification. Note that this is
+# independent from use_openssl. It is possible to use OpenSSL for the crypto
+# library, but NSS for the platform certificate library.
+use_nss_certs = is_linux
diff --git a/build/linux/system.gyp b/build/linux/system.gyp
index 5333798..cc6e81b 100644
--- a/build/linux/system.gyp
+++ b/build/linux/system.gyp
@@ -1180,8 +1180,7 @@
'dependencies': [
'../../third_party/boringssl/boringssl.gyp:boringssl',
],
- }],
- ['use_openssl==0', {
+ }, {
'dependencies': [
'../../net/third_party/nss/ssl.gyp:libssl',
],
@@ -1191,6 +1190,13 @@
# before other includes, as we are shadowing system headers.
'<(DEPTH)/net/third_party/nss/ssl',
],
+ },
+ }],
+ # Link in the system NSS if it is used for either the internal
+ # crypto library (use_openssl==0) or platform certificate
+ # library (use_nss_certs==1).
+ ['use_openssl==0 or use_nss_certs==1', {
+ 'direct_dependent_settings': {
'cflags': [
'<!@(<(pkg-config) --cflags nss)',
],
@@ -1203,15 +1209,17 @@
'<!@(<(pkg-config) --libs-only-l nss | sed -e "s/-lssl3//")',
],
},
- }],
- ['use_openssl==0 and clang==1', {
- 'direct_dependent_settings': {
- 'cflags': [
- # There is a broken header guard in /usr/include/nss/secmod.h:
- # https://bugzilla.mozilla.org/show_bug.cgi?id=884072
- '-Wno-header-guard',
- ],
- },
+ 'conditions': [
+ ['clang==1', {
+ 'direct_dependent_settings': {
+ 'cflags': [
+ # There is a broken header guard in /usr/include/nss/secmod.h:
+ # https://bugzilla.mozilla.org/show_bug.cgi?id=884072
+ '-Wno-header-guard',
+ ],
+ },
+ }],
+ ],
}],
]
}],
diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi
index 2f7ccad..7faa5e6 100644
--- a/chrome/chrome_common.gypi
+++ b/chrome/chrome_common.gypi
@@ -634,43 +634,31 @@
}, { # OS == ios
'sources!': [
'common/net/net_resource_provider.cc',
+ ],
+ }],
+ ['OS == "android" or OS == "ios"', {
+ 'sources!': [
'common/net/x509_certificate_model.cc',
],
}],
- ['os_posix == 1 and OS != "mac" and OS != "ios" and OS != "android"', {
+ ['use_openssl_certs == 1 and OS != "android"', {
'dependencies': [
- '../build/linux/system.gyp:ssl',
+ '<(DEPTH)/third_party/boringssl/boringssl.gyp:boringssl',
],
- },
- ],
- ['os_posix != 1 or OS == "mac" or OS == "ios"', {
+ }, {
'sources!': [
- 'common/net/x509_certificate_model_nss.cc',
'common/net/x509_certificate_model_openssl.cc',
],
},
],
- ['OS == "android"', {
+ ['use_nss_certs == 1', {
'dependencies': [
- '../third_party/boringssl/boringssl.gyp:boringssl',
- ],
- 'sources!': [
- 'common/net/x509_certificate_model.cc',
- 'common/net/x509_certificate_model_openssl.cc',
+ '../build/linux/system.gyp:ssl',
],
- }],
- ['use_openssl==1', {
+ }, {
'sources!': [
'common/net/x509_certificate_model_nss.cc',
],
- 'dependencies': [
- '<(DEPTH)/third_party/boringssl/boringssl.gyp:boringssl',
- ],
- },
- { # else !use_openssl: remove the unneeded files
- 'sources!': [
- 'common/net/x509_certificate_model_openssl.cc',
- ],
},
],
['OS=="win"', {
diff --git a/chrome/chrome_utility.gypi b/chrome/chrome_utility.gypi
index d076a1b..08d58b2 100644
--- a/chrome/chrome_utility.gypi
+++ b/chrome/chrome_utility.gypi
@@ -133,26 +133,21 @@
},
},
}],
- ['OS!="win" and OS!="mac" and use_openssl==1', {
- 'sources!': [
- 'utility/importer/nss_decryptor.cc',
- ]
- }],
- ['OS!="win" and OS!="mac" and use_openssl==0', {
+ ['OS!="android"', {
'dependencies': [
- '../crypto/crypto.gyp:crypto',
+ '../net/net.gyp:net_utility_services',
],
'sources': [
- 'utility/importer/nss_decryptor_system_nss.cc',
- 'utility/importer/nss_decryptor_system_nss.h',
+ '<@(chrome_utility_importer_sources)',
],
}],
- ['OS!="android"', {
+ ['use_nss_certs==1', {
'dependencies': [
- '../net/net.gyp:net_utility_services',
+ '../crypto/crypto.gyp:crypto',
],
'sources': [
- '<@(chrome_utility_importer_sources)',
+ 'utility/importer/nss_decryptor_system_nss.cc',
+ 'utility/importer/nss_decryptor_system_nss.h',
],
}],
['OS=="android" and use_seccomp_bpf==1', {
diff --git a/chrome/common/net/BUILD.gn b/chrome/common/net/BUILD.gn
index b69512c..b73de58 100644
--- a/chrome/common/net/BUILD.gn
+++ b/chrome/common/net/BUILD.gn
@@ -30,31 +30,25 @@ static_library("net") {
]
if (is_ios) {
- sources -= [
- "net_resource_provider.cc",
- "x509_certificate_model.cc",
- ]
+ sources -= [ "net_resource_provider.cc" ]
} else {
deps += [ "//gpu/ipc" ]
}
- if (is_win || is_mac || is_ios) {
- sources -= [
- "x509_certificate_model_nss.cc",
- "x509_certificate_model_openssl.cc",
- ]
- } else if (use_openssl) {
- sources -= [ "x509_certificate_model_nss.cc" ]
+ if (is_android || is_ios) {
+ sources -= [ "x509_certificate_model.cc" ]
+ }
+
+ if (use_openssl_certs && !is_android) {
+ deps += [ "//third_party/boringssl" ]
} else {
sources -= [ "x509_certificate_model_openssl.cc" ]
}
- if (is_android) {
- sources -= [
- "x509_certificate_model.cc",
- "x509_certificate_model_openssl.cc",
- ]
- deps += [ "//third_party/boringssl" ]
+ if (use_nss_certs) {
+ deps += [ "//crypto:platform" ]
+ } else {
+ sources -= [ "x509_certificate_model_nss.cc" ]
}
configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
diff --git a/chrome/utility/BUILD.gn b/chrome/utility/BUILD.gn
index c469307..dbf408f 100644
--- a/chrome/utility/BUILD.gn
+++ b/chrome/utility/BUILD.gn
@@ -83,21 +83,15 @@ static_library("utility") {
}
}
- if (use_openssl) {
- if (!is_win && !is_mac && !is_android) {
- sources -= [ "importer/nss_decryptor.cc" ]
- }
- } else { # !use_openssl
- if (!is_win && !is_mac) {
- sources += [
- "importer/nss_decryptor_system_nss.cc",
- "importer/nss_decryptor_system_nss.h",
- ]
- deps += [
- "//crypto",
- "//crypto:platform",
- ]
- }
+ if (use_nss_certs) {
+ sources += [
+ "importer/nss_decryptor_system_nss.cc",
+ "importer/nss_decryptor_system_nss.h",
+ ]
+ deps += [
+ "//crypto",
+ "//crypto:platform",
+ ]
}
if (!enable_print_preview) {
diff --git a/chrome/utility/importer/nss_decryptor.h b/chrome/utility/importer/nss_decryptor.h
index 5c36112..d53e640 100644
--- a/chrome/utility/importer/nss_decryptor.h
+++ b/chrome/utility/importer/nss_decryptor.h
@@ -11,15 +11,10 @@
#include "chrome/utility/importer/nss_decryptor_mac.h"
#elif defined(OS_WIN)
#include "chrome/utility/importer/nss_decryptor_win.h"
-#elif defined(USE_OPENSSL)
-// TODO(joth): It should be an error to include this file with USE_OPENSSL
-// defined. (Unless there is a way to do nss decrypt with OpenSSL). Ideally
-// we remove the importers that depend on NSS when doing USE_OPENSSL builds, but
-// that is going to take some non-trivial refactoring so in the meantime we're
-// just falling back to a no-op implementation.
-#include "chrome/utility/importer/nss_decryptor_null.h"
#elif defined(USE_NSS_CERTS)
#include "chrome/utility/importer/nss_decryptor_system_nss.h"
+#else
+#error NSSDecryptor not implemented.
#endif
#endif // CHROME_UTILITY_IMPORTER_NSS_DECRYPTOR_H_
diff --git a/chrome/utility/importer/nss_decryptor_null.h b/chrome/utility/importer/nss_decryptor_null.h
deleted file mode 100644
index e99334b..0000000
--- a/chrome/utility/importer/nss_decryptor_null.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_UTILITY_IMPORTER_NSS_DECRYPTOR_NULL_H_
-#define CHROME_UTILITY_IMPORTER_NSS_DECRYPTOR_NULL_H_
-
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/strings/string16.h"
-
-namespace autofill {
-struct PasswordForm;
-}
-
-namespace base {
-class FilePath;
-}
-
-// A NULL wrapper for Firefox NSS decrypt component, for use in builds where
-// we do not have the NSS library.
-class NSSDecryptor {
- public:
- NSSDecryptor() {}
- bool Init(const base::FilePath& dll_path, const base::FilePath& db_path) {
- return false;
- }
- base::string16 Decrypt(const std::string& crypt) const {
- return base::string16();
- }
- void ParseSignons(const std::string& content,
- std::vector<autofill::PasswordForm>* forms) {}
- bool ReadAndParseSignons(const base::FilePath& sqlite_file,
- std::vector<autofill::PasswordForm>* forms) {
- return false;
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(NSSDecryptor);
-};
-
-#endif // CHROME_UTILITY_IMPORTER_NSS_DECRYPTOR_NULL_H_
diff --git a/components/webcrypto/test/test_helpers.cc b/components/webcrypto/test/test_helpers.cc
index 39b8196..76da7fa 100644
--- a/components/webcrypto/test/test_helpers.cc
+++ b/components/webcrypto/test/test_helpers.cc
@@ -124,7 +124,7 @@ bool SupportsRsaOaep() {
bool SupportsRsaPrivateKeyImport() {
// TODO(eroman): Exclude version test for OS_CHROMEOS
-#if defined(USE_NSS_CERTS)
+#if !defined(USE_OPENSSL) && defined(USE_NSS_CERTS)
crypto::EnsureNSSInit();
if (!NSS_VersionCheck("3.16.2")) {
LOG(WARNING) << "RSA key import is not supported by this version of NSS. "
diff --git a/crypto/BUILD.gn b/crypto/BUILD.gn
index d3456d3..27e786c 100644
--- a/crypto/BUILD.gn
+++ b/crypto/BUILD.gn
@@ -136,9 +136,6 @@ component("crypto") {
"ec_signature_creator_nss.cc",
"encryptor_nss.cc",
"hmac_nss.cc",
- "nss_util.cc",
- "nss_util.h",
- "nss_util_internal.h",
"rsa_private_key_nss.cc",
"secure_hash_default.cc",
"signature_creator_nss.cc",
@@ -170,6 +167,16 @@ component("crypto") {
]
}
+ # Remove nss_util when NSS is used for neither the internal crypto library
+ # nor the platform certificate library.
+ if (use_openssl && !use_nss_certs) {
+ sources -= [
+ "nss_util.cc",
+ "nss_util.h",
+ "nss_util_internal.h",
+ ]
+ }
+
defines = [ "CRYPTO_IMPLEMENTATION" ]
}
@@ -229,12 +236,14 @@ test("crypto_unittests") {
"symmetric_key_unittest.cc",
]
- if (use_openssl || !is_linux) {
- sources -= [ "rsa_private_key_nss_unittest.cc" ]
+ # Remove nss_util when NSS is used for neither the internal crypto library
+ # nor the platform certificate library.
+ if (use_openssl && !use_nss_certs) {
+ sources -= [ "nss_util_unittest.cc" ]
}
if (use_openssl) {
- sources -= [ "nss_util_unittest.cc" ]
+ sources -= [ "rsa_private_key_nss_unittest.cc" ]
} else {
sources -= [ "openssl_bio_string_unittest.cc" ]
}
@@ -286,7 +295,7 @@ source_set("test_support") {
}
config("platform_config") {
- if (!use_openssl && is_clang) {
+ if ((!use_openssl || use_nss_certs) && is_clang) {
# There is a broken header guard in /usr/include/nss/secmod.h:
# https://bugzilla.mozilla.org/show_bug.cgi?id=884072
cflags = [ "-Wno-header-guard" ]
@@ -305,21 +314,26 @@ group("platform") {
deps = [
"//net/third_party/nss/ssl:libssl",
]
+ }
+
+ # Link in NSS if it is used for either the internal crypto library
+ # (!use_openssl) or platform certificate library (use_nss_certs).
+ if (!use_openssl || use_nss_certs) {
if (is_linux) {
# On Linux, we use the system NSS (excepting SSL where we always use our
# own).
- #
- # We always need our SSL header search path to come before the system one
- # so our versions are used. The libssl target will add the search path we
- # want, but according to GN's ordering rules, public_configs' search path
- # will get applied before ones inherited from our dependencies.
- # Therefore, we need to explicitly list our custom libssl's config here
- # before the system one.
- public_configs = [
- ":platform_config",
- "//net/third_party/nss/ssl:ssl_config",
- "//third_party/nss:system_nss_no_ssl_config",
- ]
+ public_configs = [ ":platform_config" ]
+ if (!use_openssl) {
+ # If using a bundled copy of NSS's SSL library, ensure the bundled SSL
+ # header search path comes before the system one so our versions are
+ # used. The libssl target will add the search path we want, but
+ # according to GN's ordering rules, public_configs' search path will get
+ # applied before ones inherited from our dependencies. Therefore, we
+ # need to explicitly list our custom libssl's config here before the
+ # system one.
+ public_configs += [ "//net/third_party/nss/ssl:ssl_config" ]
+ }
+ public_configs += [ "//third_party/nss:system_nss_no_ssl_config" ]
} else {
# Non-Linux platforms use the hermetic NSS from the tree.
deps += [
diff --git a/crypto/crypto.gyp b/crypto/crypto.gyp
index c8551e7..a9cff55 100644
--- a/crypto/crypto.gyp
+++ b/crypto/crypto.gyp
@@ -108,9 +108,6 @@
'ec_signature_creator_nss.cc',
'encryptor_nss.cc',
'hmac_nss.cc',
- 'nss_util.cc',
- 'nss_util.h',
- 'nss_util_internal.h',
'rsa_private_key_nss.cc',
'secure_hash_default.cc',
'signature_creator_nss.cc',
@@ -143,6 +140,15 @@
'symmetric_key_openssl.cc',
],
},],
+ [ 'use_openssl==1 and use_nss_certs==0', {
+ # NSS is used for neither the internal crypto library nor the
+ # platform certificate library.
+ 'sources!': [
+ 'nss_util.cc',
+ 'nss_util.h',
+ 'nss_util_internal.h',
+ ],
+ },],
],
'sources': [
'<@(crypto_sources)',
@@ -182,7 +188,7 @@
'../testing/gtest.gyp:gtest',
],
'conditions': [
- [ 'os_posix == 1 and OS != "mac" and OS != "android" and OS != "ios"', {
+ [ 'use_nss_certs == 1', {
'conditions': [
[ 'use_allocator!="none"', {
'dependencies': [
@@ -194,10 +200,13 @@
'dependencies': [
'../build/linux/system.gyp:ssl',
],
- }, { # os_posix != 1 or OS == "mac" or OS == "android" or OS == "ios"
+ }],
+ [ 'use_openssl == 1 and use_nss_certs == 0', {
+ # nss_util is built if NSS is used for either the internal crypto
+ # library or the platform certificate library.
'sources!': [
- 'rsa_private_key_nss_unittest.cc',
- ]
+ 'nss_util_unittest.cc',
+ ],
}],
[ 'use_openssl == 0 and (OS == "mac" or OS == "ios" or OS == "win")', {
'dependencies': [
@@ -213,7 +222,6 @@
'../third_party/boringssl/boringssl.gyp:boringssl',
],
'sources!': [
- 'nss_util_unittest.cc',
'rsa_private_key_nss_unittest.cc',
],
}, {
diff --git a/crypto/rsa_private_key.h b/crypto/rsa_private_key.h
index 78a660e..9ab9c57 100644
--- a/crypto/rsa_private_key.h
+++ b/crypto/rsa_private_key.h
@@ -180,7 +180,22 @@ class CRYPTO_EXPORT RSAPrivateKey {
static RSAPrivateKey* CreateFromPrivateKeyInfo(
const std::vector<uint8>& input);
-#if defined(USE_NSS_CERTS)
+#if defined(USE_OPENSSL)
+ // Create a new instance from an existing EVP_PKEY, taking a
+ // reference to it. |key| must be an RSA key. Returns NULL on
+ // failure.
+ static RSAPrivateKey* CreateFromKey(EVP_PKEY* key);
+#else
+ // Create a new instance by referencing an existing private key
+ // structure. Does not import the key.
+ static RSAPrivateKey* CreateFromKey(SECKEYPrivateKey* key);
+#endif
+
+ // TODO(davidben): These functions are used when NSS is the platform key
+ // store, but they also assume that the internal crypto library is NSS. Split
+ // out the convenience NSS platform key methods from the logic which expects
+ // an RSAPrivateKey. See https://crbug.com/478777.
+#if defined(USE_NSS_CERTS) && !defined(USE_OPENSSL)
// Create a new random instance in |slot|. Can return NULL if initialization
// fails. The created key is permanent and is not exportable in plaintext
// form.
@@ -194,10 +209,6 @@ class CRYPTO_EXPORT RSAPrivateKey {
PK11SlotInfo* slot,
const std::vector<uint8>& input);
- // Create a new instance by referencing an existing private key
- // structure. Does not import the key.
- static RSAPrivateKey* CreateFromKey(SECKEYPrivateKey* key);
-
// Import an existing public key, and then search for the private
// half in the key database. The format of the public key blob is is
// an X509 SubjectPublicKeyInfo block. This can return NULL if
@@ -216,13 +227,7 @@ class CRYPTO_EXPORT RSAPrivateKey {
static RSAPrivateKey* FindFromPublicKeyInfoInSlot(
const std::vector<uint8>& input,
PK11SlotInfo* slot);
-#elif defined(USE_OPENSSL)
- // Create a new instance from an existing EVP_PKEY, taking a
- // reference to it. |key| must be an RSA key. Returns NULL on
- // failure.
- static RSAPrivateKey* CreateFromKey(EVP_PKEY* key);
-
-#endif
+#endif // USE_NSS_CERTS && !USE_OPENSSL
#if defined(USE_OPENSSL)
EVP_PKEY* key() { return key_; }
diff --git a/crypto/rsa_private_key_nss.cc b/crypto/rsa_private_key_nss.cc
index 45b2be7..c9e6a87 100644
--- a/crypto/rsa_private_key_nss.cc
+++ b/crypto/rsa_private_key_nss.cc
@@ -104,6 +104,22 @@ RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo(
false /* not sensitive */);
}
+// static
+RSAPrivateKey* RSAPrivateKey::CreateFromKey(SECKEYPrivateKey* key) {
+ DCHECK(key);
+ if (SECKEY_GetPrivateKeyType(key) != rsaKey)
+ return NULL;
+ RSAPrivateKey* copy = new RSAPrivateKey();
+ copy->key_ = SECKEY_CopyPrivateKey(key);
+ copy->public_key_ = SECKEY_ConvertToPublicKey(key);
+ if (!copy->key_ || !copy->public_key_) {
+ NOTREACHED();
+ delete copy;
+ return NULL;
+ }
+ return copy;
+}
+
#if defined(USE_NSS_CERTS)
// static
RSAPrivateKey* RSAPrivateKey::CreateSensitive(PK11SlotInfo* slot,
@@ -125,22 +141,6 @@ RSAPrivateKey* RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo(
}
// static
-RSAPrivateKey* RSAPrivateKey::CreateFromKey(SECKEYPrivateKey* key) {
- DCHECK(key);
- if (SECKEY_GetPrivateKeyType(key) != rsaKey)
- return NULL;
- RSAPrivateKey* copy = new RSAPrivateKey();
- copy->key_ = SECKEY_CopyPrivateKey(key);
- copy->public_key_ = SECKEY_ConvertToPublicKey(key);
- if (!copy->key_ || !copy->public_key_) {
- NOTREACHED();
- delete copy;
- return NULL;
- }
- return copy;
-}
-
-// static
RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo(
const std::vector<uint8>& input) {
scoped_ptr<RSAPrivateKey> result(InitPublicPart(input));
diff --git a/crypto/rsa_private_key_nss_unittest.cc b/crypto/rsa_private_key_nss_unittest.cc
index 98360e8..dad6688 100644
--- a/crypto/rsa_private_key_nss_unittest.cc
+++ b/crypto/rsa_private_key_nss_unittest.cc
@@ -13,6 +13,10 @@
namespace crypto {
+// TODO(davidben): These tests assume NSS is used for both the internal crypto
+// library and the platform key store. See https://crbug.com/478777.
+#if defined(USE_NSS_CERTS)
+
class RSAPrivateKeyNSSTest : public testing::Test {
public:
RSAPrivateKeyNSSTest() {}
@@ -57,4 +61,6 @@ TEST_F(RSAPrivateKeyNSSTest, FailedFindFromPublicKey) {
EXPECT_EQ(NULL, crypto::RSAPrivateKey::FindFromPublicKeyInfo(public_key));
}
+#endif // USE_NSS_CERTS
+
} // namespace crypto
diff --git a/crypto/rsa_private_key_unittest.cc b/crypto/rsa_private_key_unittest.cc
index ee5b121..b231cac 100644
--- a/crypto/rsa_private_key_unittest.cc
+++ b/crypto/rsa_private_key_unittest.cc
@@ -445,9 +445,6 @@ TEST(RSAPrivateKeyUnitTest, ShortIntegers) {
input2.size()));
}
-// The following test can run if either USE_NSS_CERTS or USE_OPENSSL is defined,
-// but not otherwise (since it uses crypto::RSAPrivateKey::CreateFromKey).
-#if defined(USE_NSS_CERTS) || defined(USE_OPENSSL)
TEST(RSAPrivateKeyUnitTest, CreateFromKeyTest) {
scoped_ptr<crypto::RSAPrivateKey> key_pair(
crypto::RSAPrivateKey::Create(256));
@@ -469,5 +466,4 @@ TEST(RSAPrivateKeyUnitTest, CreateFromKeyTest) {
ASSERT_EQ(privkey, privkey_copy);
ASSERT_EQ(pubkey, pubkey_copy);
}
-#endif
diff --git a/net/BUILD.gn b/net/BUILD.gn
index 0f6cbbb..130a597 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -194,11 +194,7 @@ component("net") {
"cert/ct_objects_extractor_nss.cc",
"cert/jwk_serializer_nss.cc",
"cert/scoped_nss_types.h",
- "cert/test_root_certs_nss.cc",
"cert/x509_util_nss.cc",
- "cert/x509_util_nss.h",
- "cert_net/nss_ocsp.cc",
- "cert_net/nss_ocsp.h",
"quic/crypto/aead_base_decrypter_nss.cc",
"quic/crypto/aead_base_encrypter_nss.cc",
"quic/crypto/aes_128_gcm_12_decrypter_nss.cc",
@@ -214,31 +210,6 @@ component("net") {
"socket/ssl_server_socket_nss.cc",
"socket/ssl_server_socket_nss.h",
]
- if (is_chromeos) {
- sources -= [
- "cert/nss_cert_database_chromeos.cc",
- "cert/nss_cert_database_chromeos.h",
- "cert/nss_profile_filter_chromeos.cc",
- "cert/nss_profile_filter_chromeos.h",
- ]
- }
- if (is_linux) {
- # These are always removed for non-Linux cases below.
- sources -= [
- "base/crypto_module_nss.cc",
- "base/keygen_handler_nss.cc",
- "cert/cert_database_nss.cc",
- "cert/nss_cert_database.cc",
- "cert/nss_cert_database.h",
- "cert/x509_certificate_nss.cc",
- "third_party/mozilla_security_manager/nsKeygenHandler.cpp",
- "third_party/mozilla_security_manager/nsKeygenHandler.h",
- "third_party/mozilla_security_manager/nsNSSCertificateDB.cpp",
- "third_party/mozilla_security_manager/nsNSSCertificateDB.h",
- "third_party/mozilla_security_manager/nsPKCS12Blob.cpp",
- "third_party/mozilla_security_manager/nsPKCS12Blob.h",
- ]
- }
if (is_ios) {
# Always removed for !ios below.
sources -= [
@@ -249,9 +220,11 @@ component("net") {
if (is_win) {
sources -= [ "cert/sha256_legacy_support_nss_win.cc" ]
}
+ if (!use_nss_certs && !is_ios) {
+ sources -= [ "cert/x509_util_nss.h" ]
+ }
} else {
sources -= [
- "base/crypto_module_openssl.cc",
"cert/ct_log_verifier_openssl.cc",
"cert/ct_objects_extractor_openssl.cc",
"cert/jwk_serializer_openssl.cc",
@@ -272,6 +245,7 @@ component("net") {
"socket/ssl_server_socket_openssl.cc",
"socket/ssl_server_socket_openssl.h",
"ssl/openssl_platform_key.h",
+ "ssl/openssl_platform_key_nss.cc",
"ssl/openssl_ssl_util.cc",
"ssl/openssl_ssl_util.h",
"ssl/ssl_client_session_cache_openssl.cc",
@@ -290,6 +264,7 @@ component("net") {
if (!use_openssl_certs) {
sources -= [
+ "base/crypto_module_openssl.cc",
"base/keygen_handler_openssl.cc",
"base/openssl_private_key_store.h",
"base/openssl_private_key_store_memory.cc",
@@ -321,7 +296,9 @@ component("net") {
if (is_linux) {
configs += [ "//build/config/linux:libresolv" ]
- } else {
+ }
+
+ if (!use_nss_certs) {
sources -= [
"base/crypto_module_nss.cc",
"base/keygen_handler_nss.cc",
@@ -329,6 +306,8 @@ component("net") {
"cert/nss_cert_database.cc",
"cert/nss_cert_database.h",
"cert/x509_certificate_nss.cc",
+ "ssl/client_cert_store_nss.cc",
+ "ssl/client_cert_store_nss.h",
"third_party/mozilla_security_manager/nsKeygenHandler.cpp",
"third_party/mozilla_security_manager/nsKeygenHandler.h",
"third_party/mozilla_security_manager/nsNSSCertificateDB.cpp",
@@ -336,38 +315,37 @@ component("net") {
"third_party/mozilla_security_manager/nsPKCS12Blob.cpp",
"third_party/mozilla_security_manager/nsPKCS12Blob.h",
]
-
- if (!is_ios && !use_openssl) {
- # These files are part of the partial implementation of NSS on iOS so
- # keep them in that case.
- sources -= [
- "cert/test_root_certs_nss.cc",
- "cert_net/nss_ocsp.cc",
- "cert_net/nss_ocsp.h",
- ]
- }
- }
-
- if (!use_nss_certs) {
- sources -= [
- "ssl/client_cert_store_nss.cc",
- "ssl/client_cert_store_nss.h",
- ]
if (!is_ios) {
# These files are part of the partial implementation of NSS on iOS so
# keep them in that case (even though use_nss_certs is not set).
sources -= [
"cert/cert_verify_proc_nss.cc",
"cert/cert_verify_proc_nss.h",
+ "cert/test_root_certs_nss.cc",
+ "cert/x509_util_nss_certs.cc",
+ "cert_net/nss_ocsp.cc",
+ "cert_net/nss_ocsp.h",
]
}
if (is_chromeos) {
# These were already removed on non-ChromeOS.
sources -= [
+ "cert/nss_cert_database_chromeos.cc",
+ "cert/nss_cert_database_chromeos.h",
+ "cert/nss_profile_filter_chromeos.cc",
+ "cert/nss_profile_filter_chromeos.h",
"ssl/client_cert_store_chromeos.cc",
"ssl/client_cert_store_chromeos.h",
]
}
+ if (use_openssl) {
+ sources -= [ "ssl/openssl_platform_key_nss.cc" ]
+ }
+ } else if (use_openssl) {
+ # client_cert_store_nss.c requires NSS_CmpCertChainWCANames from NSS's
+ # libssl, but our bundled copy is not built in OpenSSL ports. Pull that file
+ # in directly.
+ sources += [ "third_party/nss/ssl/cmpcert.c" ]
}
if (!enable_websockets) {
@@ -460,8 +438,8 @@ component("net") {
}
if (is_ios) {
- # Add back some sources that were otherwise filtered out. iOS additionally
- # doesn't set USE_NSS_CERTS but needs some of the files.
+ # Add back some sources that were otherwise filtered out. iOS needs some Mac
+ # files.
set_sources_assignment_filter([])
sources += [
"base/net_util_mac.cc",
@@ -469,13 +447,6 @@ component("net") {
"base/network_change_notifier_mac.cc",
"base/network_config_watcher_mac.cc",
"base/platform_mime_util_mac.mm",
- "cert/cert_verify_proc_nss.cc",
- "cert/cert_verify_proc_nss.h",
- "cert/test_root_certs_nss.cc",
- "cert/x509_util_nss.cc",
- "cert/x509_util_nss.h",
- "cert_net/nss_ocsp.cc",
- "cert_net/nss_ocsp.h",
"proxy/proxy_resolver_mac.cc",
"proxy/proxy_server_mac.cc",
]
@@ -1392,9 +1363,16 @@ if (!is_android && !is_mac) {
}
if (!use_nss_certs) {
- sources -= [ "ssl/client_cert_store_nss_unittest.cc" ]
+ sources -= [
+ "cert/nss_cert_database_unittest.cc",
+ "ssl/client_cert_store_nss_unittest.cc",
+ ]
if (is_chromeos) { # Already removed for all non-ChromeOS builds.
- sources -= [ "ssl/client_cert_store_chromeos_unittest.cc" ]
+ sources -= [
+ "cert/nss_cert_database_chromeos_unittest.cc",
+ "cert/nss_profile_filter_chromeos_unittest.cc",
+ "ssl/client_cert_store_chromeos_unittest.cc",
+ ]
}
}
@@ -1404,17 +1382,9 @@ if (!is_android && !is_mac) {
# TODO(bulach): Add equivalent tests when the underlying
# functionality is ported to OpenSSL.
sources -= [
- "cert/nss_cert_database_unittest.cc",
"cert/x509_util_nss_unittest.cc",
"quic/test_tools/crypto_test_utils_nss.cc",
]
- if (is_chromeos) {
- # These were already removed in the non-ChromeOS case.
- sources -= [
- "cert/nss_cert_database_chromeos_unittest.cc",
- "cert/nss_profile_filter_chromeos_unittest.cc",
- ]
- }
} else {
sources -= [
"cert/x509_util_openssl_unittest.cc",
@@ -1422,9 +1392,6 @@ if (!is_android && !is_mac) {
"socket/ssl_client_socket_openssl_unittest.cc",
"ssl/ssl_client_session_cache_openssl_unittest.cc",
]
- if (!is_desktop_linux && !is_chromeos) {
- sources -= [ "cert/nss_cert_database_unittest.cc" ]
- }
}
if (use_kerberos) {
diff --git a/net/cert/ev_root_ca_metadata_unittest.cc b/net/cert/ev_root_ca_metadata_unittest.cc
index 39699e26..9da0064 100644
--- a/net/cert/ev_root_ca_metadata_unittest.cc
+++ b/net/cert/ev_root_ca_metadata_unittest.cc
@@ -9,6 +9,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#if defined(USE_NSS_CERTS)
+#include "crypto/nss_util.h"
#include "crypto/scoped_nss_types.h"
#endif
@@ -63,6 +64,7 @@ EVOidData::EVOidData()
}
bool EVOidData::Init() {
+ crypto::EnsureNSSInit();
crypto::ScopedPLArenaPool pool(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
if (!pool.get())
return false;
diff --git a/net/cert/x509_util_nss.cc b/net/cert/x509_util_nss.cc
index 9711ef6..ecdf08b 100644
--- a/net/cert/x509_util_nss.cc
+++ b/net/cert/x509_util_nss.cc
@@ -194,58 +194,6 @@ bool SignCertificate(
return true;
}
-#if defined(USE_NSS_CERTS) || defined(OS_IOS)
-// Callback for CERT_DecodeCertPackage(), used in
-// CreateOSCertHandlesFromBytes().
-SECStatus PR_CALLBACK CollectCertsCallback(void* arg,
- SECItem** certs,
- int num_certs) {
- X509Certificate::OSCertHandles* results =
- reinterpret_cast<X509Certificate::OSCertHandles*>(arg);
-
- for (int i = 0; i < num_certs; ++i) {
- X509Certificate::OSCertHandle handle =
- X509Certificate::CreateOSCertHandleFromBytes(
- reinterpret_cast<char*>(certs[i]->data), certs[i]->len);
- if (handle)
- results->push_back(handle);
- }
-
- return SECSuccess;
-}
-
-typedef scoped_ptr<
- CERTName,
- crypto::NSSDestroyer<CERTName, CERT_DestroyName> > ScopedCERTName;
-
-// Create a new CERTName object from its encoded representation.
-// |arena| is the allocation pool to use.
-// |data| points to a DER-encoded X.509 DistinguishedName.
-// Return a new CERTName pointer on success, or NULL.
-CERTName* CreateCertNameFromEncoded(PLArenaPool* arena,
- const base::StringPiece& data) {
- if (!arena)
- return NULL;
-
- ScopedCERTName name(PORT_ArenaZNew(arena, CERTName));
- if (!name.get())
- return NULL;
-
- SECItem item;
- item.len = static_cast<unsigned int>(data.length());
- item.data = reinterpret_cast<unsigned char*>(
- const_cast<char*>(data.data()));
-
- SECStatus rv = SEC_ASN1DecodeItem(
- arena, name.get(), SEC_ASN1_GET(CERT_NameTemplate), &item);
- if (rv != SECSuccess)
- return NULL;
-
- return name.release();
-}
-
-#endif // defined(USE_NSS_CERTS) || defined(OS_IOS)
-
} // namespace
namespace x509_util {
@@ -368,271 +316,6 @@ bool CreateChannelIDEC(crypto::ECPrivateKey* key,
return true;
}
-#if defined(USE_NSS_CERTS) || defined(OS_IOS)
-void ParsePrincipal(CERTName* name, CertPrincipal* principal) {
-// Starting in NSS 3.15, CERTGetNameFunc takes a const CERTName* argument.
-#if NSS_VMINOR >= 15
- typedef char* (*CERTGetNameFunc)(const CERTName* name);
-#else
- typedef char* (*CERTGetNameFunc)(CERTName* name);
-#endif
-
- // TODO(jcampan): add business_category and serial_number.
- // TODO(wtc): NSS has the CERT_GetOrgName, CERT_GetOrgUnitName, and
- // CERT_GetDomainComponentName functions, but they return only the most
- // general (the first) RDN. NSS doesn't have a function for the street
- // address.
- static const SECOidTag kOIDs[] = {
- SEC_OID_AVA_STREET_ADDRESS,
- SEC_OID_AVA_ORGANIZATION_NAME,
- SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME,
- SEC_OID_AVA_DC };
-
- std::vector<std::string>* values[] = {
- &principal->street_addresses,
- &principal->organization_names,
- &principal->organization_unit_names,
- &principal->domain_components };
- DCHECK_EQ(arraysize(kOIDs), arraysize(values));
-
- CERTRDN** rdns = name->rdns;
- for (size_t rdn = 0; rdns[rdn]; ++rdn) {
- CERTAVA** avas = rdns[rdn]->avas;
- for (size_t pair = 0; avas[pair] != 0; ++pair) {
- SECOidTag tag = CERT_GetAVATag(avas[pair]);
- for (size_t oid = 0; oid < arraysize(kOIDs); ++oid) {
- if (kOIDs[oid] == tag) {
- SECItem* decode_item = CERT_DecodeAVAValue(&avas[pair]->value);
- if (!decode_item)
- break;
- // TODO(wtc): Pass decode_item to CERT_RFC1485_EscapeAndQuote.
- std::string value(reinterpret_cast<char*>(decode_item->data),
- decode_item->len);
- values[oid]->push_back(value);
- SECITEM_FreeItem(decode_item, PR_TRUE);
- break;
- }
- }
- }
- }
-
- // Get CN, L, S, and C.
- CERTGetNameFunc get_name_funcs[4] = {
- CERT_GetCommonName, CERT_GetLocalityName,
- CERT_GetStateName, CERT_GetCountryName };
- std::string* single_values[4] = {
- &principal->common_name, &principal->locality_name,
- &principal->state_or_province_name, &principal->country_name };
- for (size_t i = 0; i < arraysize(get_name_funcs); ++i) {
- char* value = get_name_funcs[i](name);
- if (value) {
- single_values[i]->assign(value);
- PORT_Free(value);
- }
- }
-}
-
-void ParseDate(const SECItem* der_date, base::Time* result) {
- PRTime prtime;
- SECStatus rv = DER_DecodeTimeChoice(&prtime, der_date);
- DCHECK_EQ(SECSuccess, rv);
- *result = crypto::PRTimeToBaseTime(prtime);
-}
-
-std::string ParseSerialNumber(const CERTCertificate* certificate) {
- return std::string(reinterpret_cast<char*>(certificate->serialNumber.data),
- certificate->serialNumber.len);
-}
-
-void GetSubjectAltName(CERTCertificate* cert_handle,
- std::vector<std::string>* dns_names,
- std::vector<std::string>* ip_addrs) {
- if (dns_names)
- dns_names->clear();
- if (ip_addrs)
- ip_addrs->clear();
-
- SECItem alt_name;
- SECStatus rv = CERT_FindCertExtension(cert_handle,
- SEC_OID_X509_SUBJECT_ALT_NAME,
- &alt_name);
- if (rv != SECSuccess)
- return;
-
- PLArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- DCHECK(arena != NULL);
-
- CERTGeneralName* alt_name_list;
- alt_name_list = CERT_DecodeAltNameExtension(arena, &alt_name);
- SECITEM_FreeItem(&alt_name, PR_FALSE);
-
- CERTGeneralName* name = alt_name_list;
- while (name) {
- // DNSName and IPAddress are encoded as IA5String and OCTET STRINGs
- // respectively, both of which can be byte copied from
- // SECItemType::data into the appropriate output vector.
- if (dns_names && name->type == certDNSName) {
- dns_names->push_back(std::string(
- reinterpret_cast<char*>(name->name.other.data),
- name->name.other.len));
- } else if (ip_addrs && name->type == certIPAddress) {
- ip_addrs->push_back(std::string(
- reinterpret_cast<char*>(name->name.other.data),
- name->name.other.len));
- }
- name = CERT_GetNextGeneralName(name);
- if (name == alt_name_list)
- break;
- }
- PORT_FreeArena(arena, PR_FALSE);
-}
-
-X509Certificate::OSCertHandles CreateOSCertHandlesFromBytes(
- const char* data,
- int length,
- X509Certificate::Format format) {
- X509Certificate::OSCertHandles results;
- if (length < 0)
- return results;
-
- crypto::EnsureNSSInit();
-
- if (!NSS_IsInitialized())
- return results;
-
- switch (format) {
- case X509Certificate::FORMAT_SINGLE_CERTIFICATE: {
- X509Certificate::OSCertHandle handle =
- X509Certificate::CreateOSCertHandleFromBytes(data, length);
- if (handle)
- results.push_back(handle);
- break;
- }
- case X509Certificate::FORMAT_PKCS7: {
- // Make a copy since CERT_DecodeCertPackage may modify it
- std::vector<char> data_copy(data, data + length);
-
- SECStatus result = CERT_DecodeCertPackage(&data_copy[0],
- length, CollectCertsCallback, &results);
- if (result != SECSuccess)
- results.clear();
- break;
- }
- default:
- NOTREACHED() << "Certificate format " << format << " unimplemented";
- break;
- }
-
- return results;
-}
-
-X509Certificate::OSCertHandle ReadOSCertHandleFromPickle(
- PickleIterator* pickle_iter) {
- const char* data;
- int length;
- if (!pickle_iter->ReadData(&data, &length))
- return NULL;
-
- return X509Certificate::CreateOSCertHandleFromBytes(data, length);
-}
-
-void GetPublicKeyInfo(CERTCertificate* handle,
- size_t* size_bits,
- X509Certificate::PublicKeyType* type) {
- // Since we might fail, set the output parameters to default values first.
- *type = X509Certificate::kPublicKeyTypeUnknown;
- *size_bits = 0;
-
- crypto::ScopedSECKEYPublicKey key(CERT_ExtractPublicKey(handle));
- if (!key.get())
- return;
-
- *size_bits = SECKEY_PublicKeyStrengthInBits(key.get());
-
- switch (key->keyType) {
- case rsaKey:
- *type = X509Certificate::kPublicKeyTypeRSA;
- break;
- case dsaKey:
- *type = X509Certificate::kPublicKeyTypeDSA;
- break;
- case dhKey:
- *type = X509Certificate::kPublicKeyTypeDH;
- break;
- case ecKey:
- *type = X509Certificate::kPublicKeyTypeECDSA;
- break;
- default:
- *type = X509Certificate::kPublicKeyTypeUnknown;
- *size_bits = 0;
- break;
- }
-}
-
-bool GetIssuersFromEncodedList(
- const std::vector<std::string>& encoded_issuers,
- PLArenaPool* arena,
- std::vector<CERTName*>* out) {
- std::vector<CERTName*> result;
- for (size_t n = 0; n < encoded_issuers.size(); ++n) {
- CERTName* name = CreateCertNameFromEncoded(arena, encoded_issuers[n]);
- if (name != NULL)
- result.push_back(name);
- }
-
- if (result.size() == encoded_issuers.size()) {
- out->swap(result);
- return true;
- }
-
- for (size_t n = 0; n < result.size(); ++n)
- CERT_DestroyName(result[n]);
- return false;
-}
-
-
-bool IsCertificateIssuedBy(const std::vector<CERTCertificate*>& cert_chain,
- const std::vector<CERTName*>& valid_issuers) {
- for (size_t n = 0; n < cert_chain.size(); ++n) {
- CERTName* cert_issuer = &cert_chain[n]->issuer;
- for (size_t i = 0; i < valid_issuers.size(); ++i) {
- if (CERT_CompareName(valid_issuers[i], cert_issuer) == SECEqual)
- return true;
- }
- }
- return false;
-}
-
-std::string GetUniqueNicknameForSlot(const std::string& nickname,
- const SECItem* subject,
- PK11SlotInfo* slot) {
- int index = 2;
- std::string new_name = nickname;
- std::string temp_nickname = new_name;
- std::string token_name;
-
- if (!slot)
- return new_name;
-
- if (!PK11_IsInternalKeySlot(slot)) {
- token_name.assign(PK11_GetTokenName(slot));
- token_name.append(":");
-
- temp_nickname = token_name + new_name;
- }
-
- while (SEC_CertNicknameConflict(temp_nickname.c_str(),
- const_cast<SECItem*>(subject),
- CERT_GetDefaultCertDB())) {
- base::SStringPrintf(&new_name, "%s #%d", nickname.c_str(), index++);
- temp_nickname = token_name + new_name;
- }
-
- return new_name;
-}
-
-#endif // defined(USE_NSS_CERTS) || defined(OS_IOS)
-
} // namespace x509_util
} // namespace net
diff --git a/net/cert/x509_util_nss_certs.cc b/net/cert/x509_util_nss_certs.cc
new file mode 100644
index 0000000..b308355
--- /dev/null
+++ b/net/cert/x509_util_nss_certs.cc
@@ -0,0 +1,346 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <cert.h> // Must be included before certdb.h
+#include <certdb.h>
+#include <cryptohi.h>
+#include <nss.h>
+#include <pk11pub.h>
+#include <prerror.h>
+#include <secder.h>
+#include <secmod.h>
+#include <secport.h>
+
+#include "base/debug/leak_annotations.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/singleton.h"
+#include "base/pickle.h"
+#include "base/strings/stringprintf.h"
+#include "crypto/ec_private_key.h"
+#include "crypto/nss_util.h"
+#include "crypto/nss_util_internal.h"
+#include "crypto/rsa_private_key.h"
+#include "crypto/scoped_nss_types.h"
+#include "crypto/third_party/nss/chromium-nss.h"
+#include "net/cert/x509_certificate.h"
+#include "net/cert/x509_util.h"
+#include "net/cert/x509_util_nss.h"
+
+namespace net {
+
+namespace {
+
+// Callback for CERT_DecodeCertPackage(), used in
+// CreateOSCertHandlesFromBytes().
+SECStatus PR_CALLBACK
+CollectCertsCallback(void* arg, SECItem** certs, int num_certs) {
+ X509Certificate::OSCertHandles* results =
+ reinterpret_cast<X509Certificate::OSCertHandles*>(arg);
+
+ for (int i = 0; i < num_certs; ++i) {
+ X509Certificate::OSCertHandle handle =
+ X509Certificate::CreateOSCertHandleFromBytes(
+ reinterpret_cast<char*>(certs[i]->data), certs[i]->len);
+ if (handle)
+ results->push_back(handle);
+ }
+
+ return SECSuccess;
+}
+
+typedef scoped_ptr<CERTName, crypto::NSSDestroyer<CERTName, CERT_DestroyName>>
+ ScopedCERTName;
+
+// Create a new CERTName object from its encoded representation.
+// |arena| is the allocation pool to use.
+// |data| points to a DER-encoded X.509 DistinguishedName.
+// Return a new CERTName pointer on success, or NULL.
+CERTName* CreateCertNameFromEncoded(PLArenaPool* arena,
+ const base::StringPiece& data) {
+ if (!arena)
+ return NULL;
+
+ ScopedCERTName name(PORT_ArenaZNew(arena, CERTName));
+ if (!name.get())
+ return NULL;
+
+ SECItem item;
+ item.len = static_cast<unsigned int>(data.length());
+ item.data = reinterpret_cast<unsigned char*>(const_cast<char*>(data.data()));
+
+ SECStatus rv = SEC_ASN1DecodeItem(arena, name.get(),
+ SEC_ASN1_GET(CERT_NameTemplate), &item);
+ if (rv != SECSuccess)
+ return NULL;
+
+ return name.release();
+}
+
+} // namespace
+
+namespace x509_util {
+
+void ParsePrincipal(CERTName* name, CertPrincipal* principal) {
+// Starting in NSS 3.15, CERTGetNameFunc takes a const CERTName* argument.
+#if NSS_VMINOR >= 15
+ typedef char* (*CERTGetNameFunc)(const CERTName* name);
+#else
+ typedef char* (*CERTGetNameFunc)(CERTName* name);
+#endif
+
+ // TODO(jcampan): add business_category and serial_number.
+ // TODO(wtc): NSS has the CERT_GetOrgName, CERT_GetOrgUnitName, and
+ // CERT_GetDomainComponentName functions, but they return only the most
+ // general (the first) RDN. NSS doesn't have a function for the street
+ // address.
+ static const SECOidTag kOIDs[] = {SEC_OID_AVA_STREET_ADDRESS,
+ SEC_OID_AVA_ORGANIZATION_NAME,
+ SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME,
+ SEC_OID_AVA_DC};
+
+ std::vector<std::string>* values[] = {&principal->street_addresses,
+ &principal->organization_names,
+ &principal->organization_unit_names,
+ &principal->domain_components};
+ DCHECK_EQ(arraysize(kOIDs), arraysize(values));
+
+ CERTRDN** rdns = name->rdns;
+ for (size_t rdn = 0; rdns[rdn]; ++rdn) {
+ CERTAVA** avas = rdns[rdn]->avas;
+ for (size_t pair = 0; avas[pair] != 0; ++pair) {
+ SECOidTag tag = CERT_GetAVATag(avas[pair]);
+ for (size_t oid = 0; oid < arraysize(kOIDs); ++oid) {
+ if (kOIDs[oid] == tag) {
+ SECItem* decode_item = CERT_DecodeAVAValue(&avas[pair]->value);
+ if (!decode_item)
+ break;
+ // TODO(wtc): Pass decode_item to CERT_RFC1485_EscapeAndQuote.
+ std::string value(reinterpret_cast<char*>(decode_item->data),
+ decode_item->len);
+ values[oid]->push_back(value);
+ SECITEM_FreeItem(decode_item, PR_TRUE);
+ break;
+ }
+ }
+ }
+ }
+
+ // Get CN, L, S, and C.
+ CERTGetNameFunc get_name_funcs[4] = {CERT_GetCommonName,
+ CERT_GetLocalityName,
+ CERT_GetStateName,
+ CERT_GetCountryName};
+ std::string* single_values[4] = {&principal->common_name,
+ &principal->locality_name,
+ &principal->state_or_province_name,
+ &principal->country_name};
+ for (size_t i = 0; i < arraysize(get_name_funcs); ++i) {
+ char* value = get_name_funcs[i](name);
+ if (value) {
+ single_values[i]->assign(value);
+ PORT_Free(value);
+ }
+ }
+}
+
+void ParseDate(const SECItem* der_date, base::Time* result) {
+ PRTime prtime;
+ SECStatus rv = DER_DecodeTimeChoice(&prtime, der_date);
+ DCHECK_EQ(SECSuccess, rv);
+ *result = crypto::PRTimeToBaseTime(prtime);
+}
+
+std::string ParseSerialNumber(const CERTCertificate* certificate) {
+ return std::string(reinterpret_cast<char*>(certificate->serialNumber.data),
+ certificate->serialNumber.len);
+}
+
+void GetSubjectAltName(CERTCertificate* cert_handle,
+ std::vector<std::string>* dns_names,
+ std::vector<std::string>* ip_addrs) {
+ if (dns_names)
+ dns_names->clear();
+ if (ip_addrs)
+ ip_addrs->clear();
+
+ SECItem alt_name;
+ SECStatus rv = CERT_FindCertExtension(
+ cert_handle, SEC_OID_X509_SUBJECT_ALT_NAME, &alt_name);
+ if (rv != SECSuccess)
+ return;
+
+ PLArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ DCHECK(arena != NULL);
+
+ CERTGeneralName* alt_name_list;
+ alt_name_list = CERT_DecodeAltNameExtension(arena, &alt_name);
+ SECITEM_FreeItem(&alt_name, PR_FALSE);
+
+ CERTGeneralName* name = alt_name_list;
+ while (name) {
+ // DNSName and IPAddress are encoded as IA5String and OCTET STRINGs
+ // respectively, both of which can be byte copied from
+ // SECItemType::data into the appropriate output vector.
+ if (dns_names && name->type == certDNSName) {
+ dns_names->push_back(
+ std::string(reinterpret_cast<char*>(name->name.other.data),
+ name->name.other.len));
+ } else if (ip_addrs && name->type == certIPAddress) {
+ ip_addrs->push_back(
+ std::string(reinterpret_cast<char*>(name->name.other.data),
+ name->name.other.len));
+ }
+ name = CERT_GetNextGeneralName(name);
+ if (name == alt_name_list)
+ break;
+ }
+ PORT_FreeArena(arena, PR_FALSE);
+}
+
+X509Certificate::OSCertHandles CreateOSCertHandlesFromBytes(
+ const char* data,
+ int length,
+ X509Certificate::Format format) {
+ X509Certificate::OSCertHandles results;
+ if (length < 0)
+ return results;
+
+ crypto::EnsureNSSInit();
+
+ if (!NSS_IsInitialized())
+ return results;
+
+ switch (format) {
+ case X509Certificate::FORMAT_SINGLE_CERTIFICATE: {
+ X509Certificate::OSCertHandle handle =
+ X509Certificate::CreateOSCertHandleFromBytes(data, length);
+ if (handle)
+ results.push_back(handle);
+ break;
+ }
+ case X509Certificate::FORMAT_PKCS7: {
+ // Make a copy since CERT_DecodeCertPackage may modify it
+ std::vector<char> data_copy(data, data + length);
+
+ SECStatus result = CERT_DecodeCertPackage(&data_copy[0], length,
+ CollectCertsCallback, &results);
+ if (result != SECSuccess)
+ results.clear();
+ break;
+ }
+ default:
+ NOTREACHED() << "Certificate format " << format << " unimplemented";
+ break;
+ }
+
+ return results;
+}
+
+X509Certificate::OSCertHandle ReadOSCertHandleFromPickle(
+ PickleIterator* pickle_iter) {
+ const char* data;
+ int length;
+ if (!pickle_iter->ReadData(&data, &length))
+ return NULL;
+
+ return X509Certificate::CreateOSCertHandleFromBytes(data, length);
+}
+
+void GetPublicKeyInfo(CERTCertificate* handle,
+ size_t* size_bits,
+ X509Certificate::PublicKeyType* type) {
+ // Since we might fail, set the output parameters to default values first.
+ *type = X509Certificate::kPublicKeyTypeUnknown;
+ *size_bits = 0;
+
+ crypto::ScopedSECKEYPublicKey key(CERT_ExtractPublicKey(handle));
+ if (!key.get())
+ return;
+
+ *size_bits = SECKEY_PublicKeyStrengthInBits(key.get());
+
+ switch (key->keyType) {
+ case rsaKey:
+ *type = X509Certificate::kPublicKeyTypeRSA;
+ break;
+ case dsaKey:
+ *type = X509Certificate::kPublicKeyTypeDSA;
+ break;
+ case dhKey:
+ *type = X509Certificate::kPublicKeyTypeDH;
+ break;
+ case ecKey:
+ *type = X509Certificate::kPublicKeyTypeECDSA;
+ break;
+ default:
+ *type = X509Certificate::kPublicKeyTypeUnknown;
+ *size_bits = 0;
+ break;
+ }
+}
+
+bool GetIssuersFromEncodedList(const std::vector<std::string>& encoded_issuers,
+ PLArenaPool* arena,
+ std::vector<CERTName*>* out) {
+ std::vector<CERTName*> result;
+ for (size_t n = 0; n < encoded_issuers.size(); ++n) {
+ CERTName* name = CreateCertNameFromEncoded(arena, encoded_issuers[n]);
+ if (name != NULL)
+ result.push_back(name);
+ }
+
+ if (result.size() == encoded_issuers.size()) {
+ out->swap(result);
+ return true;
+ }
+
+ for (size_t n = 0; n < result.size(); ++n)
+ CERT_DestroyName(result[n]);
+ return false;
+}
+
+bool IsCertificateIssuedBy(const std::vector<CERTCertificate*>& cert_chain,
+ const std::vector<CERTName*>& valid_issuers) {
+ for (size_t n = 0; n < cert_chain.size(); ++n) {
+ CERTName* cert_issuer = &cert_chain[n]->issuer;
+ for (size_t i = 0; i < valid_issuers.size(); ++i) {
+ if (CERT_CompareName(valid_issuers[i], cert_issuer) == SECEqual)
+ return true;
+ }
+ }
+ return false;
+}
+
+std::string GetUniqueNicknameForSlot(const std::string& nickname,
+ const SECItem* subject,
+ PK11SlotInfo* slot) {
+ int index = 2;
+ std::string new_name = nickname;
+ std::string temp_nickname = new_name;
+ std::string token_name;
+
+ if (!slot)
+ return new_name;
+
+ if (!PK11_IsInternalKeySlot(slot)) {
+ token_name.assign(PK11_GetTokenName(slot));
+ token_name.append(":");
+
+ temp_nickname = token_name + new_name;
+ }
+
+ while (SEC_CertNicknameConflict(temp_nickname.c_str(),
+ const_cast<SECItem*>(subject),
+ CERT_GetDefaultCertDB())) {
+ base::SStringPrintf(&new_name, "%s #%d", nickname.c_str(), index++);
+ temp_nickname = token_name + new_name;
+ }
+
+ return new_name;
+}
+
+} // namespace x509_util
+
+} // namespace net
diff --git a/net/net.gyp b/net/net.gyp
index 9dacd43..2caae5a 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -180,6 +180,9 @@
}],
[ 'use_nss_certs != 1', {
'sources!': [
+ 'cert/nss_cert_database_unittest.cc',
+ 'cert/nss_cert_database_chromeos_unittest.cc',
+ 'cert/nss_profile_filter_chromeos_unittest.cc',
'ssl/client_cert_store_chromeos_unittest.cc',
'ssl/client_cert_store_nss_unittest.cc',
],
@@ -189,7 +192,8 @@
'dependencies': [
'../third_party/boringssl/boringssl.gyp:boringssl',
],
- }, { # use_openssl == 0
+ }],
+ [ 'use_nss_certs == 1 or OS == "ios" or use_openssl == 0', {
'conditions': [
[ 'desktop_linux == 1 or chromeos == 1', {
'dependencies': [
@@ -201,9 +205,6 @@
'../third_party/nss/nss.gyp:nss',
'third_party/nss/ssl.gyp:libssl',
],
- 'sources!': [
- 'cert/nss_cert_database_unittest.cc',
- ],
}],
],
}],
@@ -241,9 +242,6 @@
# TODO(bulach): Add equivalent tests when the underlying
# functionality is ported to OpenSSL.
'sources!': [
- 'cert/nss_cert_database_chromeos_unittest.cc',
- 'cert/nss_cert_database_unittest.cc',
- 'cert/nss_profile_filter_chromeos_unittest.cc',
'cert/x509_util_nss_unittest.cc',
'quic/test_tools/crypto_test_utils_nss.cc',
],
diff --git a/net/net.gypi b/net/net.gypi
index 9c4a22c..37a5d88 100644
--- a/net/net.gypi
+++ b/net/net.gypi
@@ -140,6 +140,7 @@
'ssl/openssl_client_key_store.h',
'ssl/openssl_platform_key.h',
'ssl/openssl_platform_key_mac.cc',
+ 'ssl/openssl_platform_key_nss.cc',
'ssl/openssl_platform_key_win.cc',
'ssl/openssl_ssl_util.cc',
'ssl/openssl_ssl_util.h',
@@ -378,6 +379,7 @@
'cert/x509_util_mac.h',
'cert/x509_util_nss.cc',
'cert/x509_util_nss.h',
+ 'cert/x509_util_nss_certs.cc',
'cert_net/cert_net_fetcher_impl.cc',
'cert_net/cert_net_fetcher_impl.h',
'cookies/canonical_cookie.cc',
diff --git a/net/net_common.gypi b/net/net_common.gypi
index 4bb8235..77134f5 100644
--- a/net/net_common.gypi
+++ b/net/net_common.gypi
@@ -125,30 +125,14 @@
}],
['use_openssl==1', {
'sources!': [
- 'base/crypto_module_nss.cc',
- 'base/keygen_handler_nss.cc',
'base/nss_memio.c',
'base/nss_memio.h',
- 'cert/cert_database_nss.cc',
- 'cert/cert_verify_proc_nss.cc',
- 'cert/cert_verify_proc_nss.h',
'cert/ct_log_verifier_nss.cc',
'cert/ct_objects_extractor_nss.cc',
'cert/jwk_serializer_nss.cc',
- 'cert/nss_cert_database.cc',
- 'cert/nss_cert_database.h',
- 'cert/nss_cert_database_chromeos.cc',
- 'cert/nss_cert_database_chromeos.h',
- 'cert/nss_profile_filter_chromeos.cc',
- 'cert/nss_profile_filter_chromeos.h',
'cert/scoped_nss_types.h',
'cert/sha256_legacy_support_nss_win.cc',
- 'cert/test_root_certs_nss.cc',
- 'cert/x509_certificate_nss.cc',
'cert/x509_util_nss.cc',
- 'cert/x509_util_nss.h',
- 'cert_net/nss_ocsp.cc',
- 'cert_net/nss_ocsp.h',
'quic/crypto/aead_base_decrypter_nss.cc',
'quic/crypto/aead_base_encrypter_nss.cc',
'quic/crypto/aes_128_gcm_12_decrypter_nss.cc',
@@ -163,12 +147,6 @@
'socket/ssl_client_socket_nss.h',
'socket/ssl_server_socket_nss.cc',
'socket/ssl_server_socket_nss.h',
- 'third_party/mozilla_security_manager/nsKeygenHandler.cpp',
- 'third_party/mozilla_security_manager/nsKeygenHandler.h',
- 'third_party/mozilla_security_manager/nsNSSCertificateDB.cpp',
- 'third_party/mozilla_security_manager/nsNSSCertificateDB.h',
- 'third_party/mozilla_security_manager/nsPKCS12Blob.cpp',
- 'third_party/mozilla_security_manager/nsPKCS12Blob.h',
],
'dependencies': [
'../third_party/boringssl/boringssl.gyp:boringssl',
@@ -176,7 +154,6 @@
},
{ # else !use_openssl: remove the unneeded files and depend on NSS.
'sources!': [
- 'base/crypto_module_openssl.cc',
'cert/ct_log_verifier_openssl.cc',
'cert/ct_objects_extractor_openssl.cc',
'cert/jwk_serializer_openssl.cc',
@@ -199,12 +176,16 @@
'socket/ssl_server_socket_openssl.h',
'ssl/openssl_platform_key.h',
'ssl/openssl_platform_key_mac.cc',
+ 'ssl/openssl_platform_key_nss.cc',
'ssl/openssl_platform_key_win.cc',
'ssl/openssl_ssl_util.cc',
'ssl/openssl_ssl_util.h',
'ssl/ssl_client_session_cache_openssl.cc',
'ssl/ssl_client_session_cache_openssl.h',
],
+ },
+ ],
+ [ 'use_nss_certs == 1 or OS == "ios" or use_openssl == 0', {
'conditions': [
# Pull in the bundled or system NSS as appropriate.
[ 'desktop_linux == 1 or chromeos == 1', {
@@ -219,10 +200,15 @@
],
}]
],
+ }, {
+ 'sources!': [
+ 'cert/x509_util_nss.h',
+ ],
},
],
[ 'use_openssl_certs == 0', {
'sources!': [
+ 'base/crypto_module_openssl.cc',
'base/keygen_handler_openssl.cc',
'base/openssl_private_key_store.h',
'base/openssl_private_key_store_android.cc',
@@ -264,17 +250,30 @@
}],
],
},
- { # else: OS is not in the above list
+ ],
+ [ 'use_nss_certs != 1', {
'sources!': [
'base/crypto_module_nss.cc',
'base/keygen_handler_nss.cc',
'cert/cert_database_nss.cc',
+ 'cert/cert_verify_proc_nss.cc',
+ 'cert/cert_verify_proc_nss.h',
'cert/nss_cert_database.cc',
'cert/nss_cert_database.h',
+ 'cert/nss_cert_database_chromeos.cc',
+ 'cert/nss_cert_database_chromeos.h',
+ 'cert/nss_profile_filter_chromeos.cc',
+ 'cert/nss_profile_filter_chromeos.h',
'cert/test_root_certs_nss.cc',
'cert/x509_certificate_nss.cc',
+ 'cert/x509_util_nss_certs.cc',
'cert_net/nss_ocsp.cc',
'cert_net/nss_ocsp.h',
+ 'ssl/client_cert_store_chromeos.cc',
+ 'ssl/client_cert_store_chromeos.h',
+ 'ssl/client_cert_store_nss.cc',
+ 'ssl/client_cert_store_nss.h',
+ 'ssl/openssl_platform_key_nss.cc',
'third_party/mozilla_security_manager/nsKeygenHandler.cpp',
'third_party/mozilla_security_manager/nsKeygenHandler.h',
'third_party/mozilla_security_manager/nsNSSCertificateDB.cpp',
@@ -284,14 +283,12 @@
],
},
],
- [ 'use_nss_certs != 1', {
- 'sources!': [
- 'cert/cert_verify_proc_nss.cc',
- 'cert/cert_verify_proc_nss.h',
- 'ssl/client_cert_store_chromeos.cc',
- 'ssl/client_cert_store_chromeos.h',
- 'ssl/client_cert_store_nss.cc',
- 'ssl/client_cert_store_nss.h',
+ # client_cert_store_nss.c requires NSS_CmpCertChainWCANames from NSS's
+ # libssl, but our bundled copy is not built in OpenSSL ports. Pull that
+ # file in directly.
+ [ 'use_nss_certs == 1 and use_openssl == 1', {
+ 'sources': [
+ 'third_party/nss/ssl/cmpcert.c',
],
}],
[ 'enable_websockets != 1', {
@@ -416,8 +413,7 @@
['include', '^cert/cert_verify_proc_nss\\.cc$'],
['include', '^cert/cert_verify_proc_nss\\.h$'],
['include', '^cert/test_root_certs_nss\\.cc$'],
- ['include', '^cert/x509_util_nss\\.cc$'],
- ['include', '^cert/x509_util_nss\\.h$'],
+ ['include', '^cert/x509_util_nss_certs\\.cc$'],
['include', '^cert_net/nss_ocsp\\.cc$'],
['include', '^cert_net/nss_ocsp\\.h$'],
['include', '^proxy/proxy_resolver_mac\\.cc$'],
diff --git a/net/socket/ssl_client_socket_openssl.cc b/net/socket/ssl_client_socket_openssl.cc
index e36534c..7b11ddc 100644
--- a/net/socket/ssl_client_socket_openssl.cc
+++ b/net/socket/ssl_client_socket_openssl.cc
@@ -1196,6 +1196,8 @@ void SSLClientSocketOpenSSL::UpdateServerCert() {
<< GetLastError();
}
#else
+ // TODO(davidben): Support OCSP stapling when NSS is the system
+ // certificate verifier. https://crbug.com/479034.
NOTREACHED();
#endif
}
diff --git a/net/ssl/channel_id_service.cc b/net/ssl/channel_id_service.cc
index e52d470..7fcbc53 100644
--- a/net/ssl/channel_id_service.cc
+++ b/net/ssl/channel_id_service.cc
@@ -27,7 +27,7 @@
#include "net/cert/x509_util.h"
#include "url/gurl.h"
-#if defined(USE_NSS_CERTS)
+#if !defined(USE_OPENSSL)
#include <private/pprthred.h> // PR_DetachThread
#endif
@@ -246,7 +246,7 @@ class ChannelIDServiceWorker {
scoped_ptr<ChannelIDStore::ChannelID> cert =
GenerateChannelID(server_identifier_, serial_number_, &error);
DVLOG(1) << "GenerateCert " << server_identifier_ << " returned " << error;
-#if defined(USE_NSS_CERTS)
+#if !defined(USE_OPENSSL)
// Detach the thread from NSPR.
// Calling NSS functions attaches the thread to NSPR, which stores
// the NSPR thread ID in thread-specific data.
diff --git a/net/ssl/openssl_platform_key_nss.cc b/net/ssl/openssl_platform_key_nss.cc
new file mode 100644
index 0000000..a9471e4
--- /dev/null
+++ b/net/ssl/openssl_platform_key_nss.cc
@@ -0,0 +1,17 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/logging.h"
+#include "net/ssl/openssl_platform_key.h"
+
+namespace net {
+
+crypto::ScopedEVP_PKEY FetchClientCertPrivateKey(
+ const X509Certificate* certificate) {
+ // TODO(davidben): Implement client auth for NSS. https://crbug.com/479036
+ NOTIMPLEMENTED();
+ return nullptr;
+}
+
+} // namespace net
diff --git a/net/test/cert_test_util_nss.cc b/net/test/cert_test_util_nss.cc
index ee929e5..74884c7 100644
--- a/net/test/cert_test_util_nss.cc
+++ b/net/test/cert_test_util_nss.cc
@@ -19,6 +19,14 @@ scoped_ptr<crypto::RSAPrivateKey> ImportSensitiveKeyFromFile(
const base::FilePath& dir,
const std::string& key_filename,
PK11SlotInfo* slot) {
+#if defined(USE_OPENSSL)
+ // TODO(davidben): Port RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo away
+ // from RSAPrivateKey so it doesn't make assumptions about the internal crypto
+ // library. Instead, return a ScopedSECKEYPrivateKey or have this function
+ // just return bool. https://crbug.com/478777
+ NOTIMPLEMENTED();
+ return nullptr;
+#else
base::FilePath key_path = dir.AppendASCII(key_filename);
std::string key_pkcs8;
bool success = base::ReadFileToString(key_path, &key_pkcs8);
@@ -38,6 +46,7 @@ scoped_ptr<crypto::RSAPrivateKey> ImportSensitiveKeyFromFile(
LOG_IF(ERROR, !private_key) << "Could not create key from file "
<< key_path.value();
return private_key.Pass();
+#endif
}
bool ImportClientCertToSlot(const scoped_refptr<X509Certificate>& cert,