diff --git a/talk/media/sctp/sctpdataengine_unittest.cc b/talk/media/sctp/sctpdataengine_unittest.cc index d406fa18cd..c540e7c810 100644 --- a/talk/media/sctp/sctpdataengine_unittest.cc +++ b/talk/media/sctp/sctpdataengine_unittest.cc @@ -45,11 +45,6 @@ #include "webrtc/base/ssladapter.h" #include "webrtc/base/thread.h" -#ifdef HAVE_NSS_SSL_H -// TODO(thorcarpenter): Remove after webrtc switches over to BoringSSL. -#include "webrtc/base/nssstreamadapter.h" -#endif // HAVE_NSS_SSL_H - enum { MSG_PACKET = 1, }; @@ -223,12 +218,6 @@ class SctpDataMediaChannelTest : public testing::Test, // usrsctp uses the NSS random number generator on non-Android platforms, // so we need to initialize SSL. static void SetUpTestCase() { -#ifdef HAVE_NSS_SSL_H - // TODO(thorcarpenter): Remove after webrtc switches over to BoringSSL. - if (!rtc::NSSContext::InitializeSSL(NULL)) { - LOG(LS_WARNING) << "Unabled to initialize NSS."; - } -#endif // HAVE_NSS_SSL_H } virtual void SetUp() { diff --git a/webrtc/base/BUILD.gn b/webrtc/base/BUILD.gn index ed0690c4c1..dec6277a82 100644 --- a/webrtc/base/BUILD.gn +++ b/webrtc/base/BUILD.gn @@ -39,14 +39,6 @@ config("openssl_config") { ] } -config("nss_config") { - defines = [ - "SSL_USE_NSS", - "HAVE_NSS_SSL_H", - "SSL_USE_NSS_RNG", - ] -} - config("ios_config") { libs = [ "CFNetwork.framework", @@ -84,15 +76,6 @@ if (is_linux && !build_with_chromium) { deps = [ "//third_party/boringssl", ] - } else { - deps = [ - "//net/third_party/nss/ssl:libssl", - ] - - public_configs = [ - "//net/third_party/nss/ssl:ssl_config", - "//third_party/nss:system_nss_no_ssl_config", - ] } } } @@ -490,31 +473,6 @@ static_library("rtc_base") { "opensslstreamadapter.cc", "opensslstreamadapter.h", ] - } else { - public_configs += [ ":nss_config" ] - if (rtc_build_ssl) { - if (build_with_chromium) { - deps += [ "//crypto:platform" ] - } else { - deps += [ "//net/third_party/nss/ssl:libssl" ] - if (is_linux) { - deps += [ ":linux_system_ssl" ] - } else { - deps += [ - "//third_party/nss:nspr", - "//third_party/nss:nss", - ] - } - } - } else { - configs += [ "external_ssl_library" ] - } - sources += [ - "nssidentity.cc", - "nssidentity.h", - "nssstreamadapter.cc", - "nssstreamadapter.h", - ] } if (is_android) { diff --git a/webrtc/base/base.gyp b/webrtc/base/base.gyp index 1536b4f8b9..b111dacfd9 100644 --- a/webrtc/base/base.gyp +++ b/webrtc/base/base.gyp @@ -104,6 +104,8 @@ ], 'defines': [ 'FEATURE_ENABLE_SSL', + 'SSL_USE_OPENSSL', + 'HAVE_OPENSSL_SSL_H', 'LOGGING=1', ], 'sources': [ @@ -220,6 +222,15 @@ 'network.cc', 'network.h', 'nullsocketserver.h', + 'openssl.h', + 'openssladapter.cc', + 'openssladapter.h', + 'openssldigest.cc', + 'openssldigest.h', + 'opensslidentity.cc', + 'opensslidentity.h', + 'opensslstreamadapter.cc', + 'opensslstreamadapter.h', 'optionsfile.cc', 'optionsfile.h', 'pathutils.cc', @@ -357,6 +368,8 @@ ], 'defines': [ 'FEATURE_ENABLE_SSL', + 'SSL_USE_OPENSSL', + 'HAVE_OPENSSL_SSL_H', ], }, 'include_dirs': [ @@ -486,85 +499,6 @@ '../overrides/webrtc/base/logging.h', ], }], - ['use_openssl==1', { - 'defines': [ - 'SSL_USE_OPENSSL', - 'HAVE_OPENSSL_SSL_H', - ], - 'direct_dependent_settings': { - 'defines': [ - 'SSL_USE_OPENSSL', - 'HAVE_OPENSSL_SSL_H', - ], - }, - 'sources': [ - 'openssl.h', - 'openssladapter.cc', - 'openssladapter.h', - 'openssldigest.cc', - 'openssldigest.h', - 'opensslidentity.cc', - 'opensslidentity.h', - 'opensslstreamadapter.cc', - 'opensslstreamadapter.h', - ], - 'conditions': [ - ['build_ssl==1', { - 'dependencies': [ - '<(DEPTH)/third_party/boringssl/boringssl.gyp:boringssl', - ], - }, { - 'include_dirs': [ - '<(ssl_root)', - ], - }], - ], - }, { - 'sources': [ - 'nssidentity.cc', - 'nssidentity.h', - 'nssstreamadapter.cc', - 'nssstreamadapter.h', - ], - 'conditions': [ - ['use_legacy_ssl_defaults!=1', { - 'defines': [ - 'SSL_USE_NSS', - 'HAVE_NSS_SSL_H', - 'SSL_USE_NSS_RNG', - ], - 'direct_dependent_settings': { - 'defines': [ - 'SSL_USE_NSS', - 'HAVE_NSS_SSL_H', - 'SSL_USE_NSS_RNG', - ], - }, - }], - ['build_ssl==1', { - 'conditions': [ - # On some platforms, the rest of NSS is bundled. On others, - # it's pulled from the system. - ['OS == "mac" or OS == "ios"', { - 'dependencies': [ - '<(DEPTH)/net/third_party/nss/ssl.gyp:libssl', - '<(DEPTH)/third_party/nss/nss.gyp:nspr', - '<(DEPTH)/third_party/nss/nss.gyp:nss', - ], - }], - ['os_posix == 1 and OS != "mac" and OS != "ios" and OS != "android"', { - 'dependencies': [ - '<(DEPTH)/build/linux/system.gyp:ssl', - ], - }], - ], - }, { - 'include_dirs': [ - '<(ssl_root)', - ], - }], - ], - }], ['OS == "android"', { 'link_settings': { 'libraries': [ @@ -733,6 +667,15 @@ 'linux.h', ], }], + ['build_ssl==1', { + 'dependencies': [ + '<(DEPTH)/third_party/boringssl/boringssl.gyp:boringssl', + ], + }, { + 'include_dirs': [ + '<(ssl_root)', + ], + }], ], }, ], diff --git a/webrtc/base/helpers.cc b/webrtc/base/helpers.cc index e12ba107ea..0102c10e7b 100644 --- a/webrtc/base/helpers.cc +++ b/webrtc/base/helpers.cc @@ -16,14 +16,6 @@ #include "webrtc/base/sslconfig.h" #if defined(SSL_USE_OPENSSL) #include -#elif defined(SSL_USE_NSS_RNG) -// Hack: Define+undefine int64 and uint64 to avoid typedef conflict with NSS. -// TODO(kjellander): Remove when webrtc:4497 is completed. -#define uint64 foo_uint64 -#define int64 foo_int64 -#include "pk11func.h" -#undef uint64 -#undef int64 #else #if defined(WEBRTC_WIN) #define WIN32_LEAN_AND_MEAN diff --git a/webrtc/base/nssidentity.cc b/webrtc/base/nssidentity.cc deleted file mode 100644 index 6511942a34..0000000000 --- a/webrtc/base/nssidentity.cc +++ /dev/null @@ -1,581 +0,0 @@ -/* - * Copyright 2012 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include -#include - -#if HAVE_CONFIG_H -#include "config.h" -#endif // HAVE_CONFIG_H - -#if HAVE_NSS_SSL_H - -#include "webrtc/base/nssidentity.h" - -#include "cert.h" -#include "cryptohi.h" -#include "keyhi.h" -#include "nss.h" -#include "pk11pub.h" -#include "sechash.h" - -#include "webrtc/base/logging.h" -#include "webrtc/base/helpers.h" -#include "webrtc/base/nssstreamadapter.h" -#include "webrtc/base/safe_conversions.h" -#include "webrtc/base/stringutils.h" - -namespace rtc { - -// Certificate validity lifetime in seconds. -static const int CERTIFICATE_LIFETIME = 60*60*24*30; // 30 days, arbitrarily -// Certificate validity window in seconds. -// This is to compensate for slightly incorrect system clocks. -static const int CERTIFICATE_WINDOW = -60*60*24; - -NSSKeyPair::~NSSKeyPair() { - if (privkey_) - SECKEY_DestroyPrivateKey(privkey_); - if (pubkey_) - SECKEY_DestroyPublicKey(pubkey_); -} - -NSSKeyPair* NSSKeyPair::Generate(KeyType key_type) { - SECKEYPrivateKey* privkey = nullptr; - SECKEYPublicKey* pubkey = nullptr; - SSLKEAType ssl_kea_type; - if (key_type == KT_RSA) { - PK11RSAGenParams rsa_params; - rsa_params.keySizeInBits = 1024; - rsa_params.pe = 0x010001; // 65537 -- a common RSA public exponent. - - privkey = PK11_GenerateKeyPair( - NSSContext::GetSlot(), CKM_RSA_PKCS_KEY_PAIR_GEN, &rsa_params, &pubkey, - PR_FALSE /*permanent*/, PR_FALSE /*sensitive*/, nullptr); - - ssl_kea_type = ssl_kea_rsa; - } else if (key_type == KT_ECDSA) { - unsigned char param_buf[12]; // OIDs are small - SECItem ecdsa_params = {siBuffer, param_buf, sizeof(param_buf)}; - SECOidData* oid_data = SECOID_FindOIDByTag(SEC_OID_SECG_EC_SECP256R1); - if (!oid_data || oid_data->oid.len > sizeof(param_buf) - 2) { - LOG(LS_ERROR) << "oid_data incorrect: " << oid_data->oid.len; - return nullptr; - } - ecdsa_params.data[0] = SEC_ASN1_OBJECT_ID; - ecdsa_params.data[1] = oid_data->oid.len; - memcpy(ecdsa_params.data + 2, oid_data->oid.data, oid_data->oid.len); - ecdsa_params.len = oid_data->oid.len + 2; - - privkey = PK11_GenerateKeyPair( - NSSContext::GetSlot(), CKM_EC_KEY_PAIR_GEN, &ecdsa_params, &pubkey, - PR_FALSE /*permanent*/, PR_FALSE /*sensitive*/, nullptr); - - ssl_kea_type = ssl_kea_ecdh; - } else { - LOG(LS_ERROR) << "Key type requested not understood"; - return nullptr; - } - - if (!privkey) { - LOG(LS_ERROR) << "Couldn't generate key pair: " << PORT_GetError(); - return nullptr; - } - - return new NSSKeyPair(privkey, pubkey, ssl_kea_type); -} - -// Just make a copy. -NSSKeyPair* NSSKeyPair::GetReference() { - SECKEYPrivateKey* privkey = SECKEY_CopyPrivateKey(privkey_); - if (!privkey) - return nullptr; - - SECKEYPublicKey* pubkey = SECKEY_CopyPublicKey(pubkey_); - if (!pubkey) { - SECKEY_DestroyPrivateKey(privkey); - return nullptr; - } - - return new NSSKeyPair(privkey, pubkey, ssl_kea_type_); -} - -NSSCertificate::NSSCertificate(CERTCertificate* cert) - : certificate_(CERT_DupCertificate(cert)) { - ASSERT(certificate_ != nullptr); -} - -static void DeleteCert(SSLCertificate* cert) { - delete cert; -} - -NSSCertificate::NSSCertificate(CERTCertList* cert_list) { - // Copy the first cert into certificate_. - CERTCertListNode* node = CERT_LIST_HEAD(cert_list); - certificate_ = CERT_DupCertificate(node->cert); - - // Put any remaining certificates into the chain. - node = CERT_LIST_NEXT(node); - std::vector certs; - for (; !CERT_LIST_END(node, cert_list); node = CERT_LIST_NEXT(node)) { - certs.push_back(new NSSCertificate(node->cert)); - } - - if (!certs.empty()) - chain_.reset(new SSLCertChain(certs)); - - // The SSLCertChain constructor copies its input, so now we have to delete - // the originals. - std::for_each(certs.begin(), certs.end(), DeleteCert); -} - -NSSCertificate::NSSCertificate(CERTCertificate* cert, SSLCertChain* chain) - : certificate_(CERT_DupCertificate(cert)) { - ASSERT(certificate_ != nullptr); - if (chain) - chain_.reset(chain->Copy()); -} - -NSSCertificate::~NSSCertificate() { - if (certificate_) - CERT_DestroyCertificate(certificate_); -} - -NSSCertificate* NSSCertificate::FromPEMString(const std::string& pem_string) { - std::string der; - if (!SSLIdentity::PemToDer(kPemTypeCertificate, pem_string, &der)) - return nullptr; - - SECItem der_cert; - der_cert.data = reinterpret_cast(const_cast( - der.data())); - der_cert.len = checked_cast(der.size()); - CERTCertificate* cert = CERT_NewTempCertificate( - CERT_GetDefaultCertDB(), &der_cert, nullptr, PR_FALSE, PR_TRUE); - - if (!cert) - return nullptr; - - NSSCertificate* ret = new NSSCertificate(cert); - CERT_DestroyCertificate(cert); - return ret; -} - -NSSCertificate* NSSCertificate::GetReference() const { - return new NSSCertificate(certificate_, chain_.get()); -} - -std::string NSSCertificate::ToPEMString() const { - return SSLIdentity::DerToPem(kPemTypeCertificate, - certificate_->derCert.data, - certificate_->derCert.len); -} - -void NSSCertificate::ToDER(Buffer* der_buffer) const { - der_buffer->SetData(certificate_->derCert.data, certificate_->derCert.len); -} - -static bool Certifies(CERTCertificate* parent, CERTCertificate* child) { - // TODO(bemasc): Identify stricter validation checks to use here. In the - // context of some future identity standard, it might make sense to check - // the certificates' roles, expiration dates, self-signatures (if - // self-signed), certificate transparency logging, or many other attributes. - // NOTE: Future changes to this validation may reject some previously allowed - // certificate chains. Users should be advised not to deploy chained - // certificates except in controlled environments until the validity - // requirements are finalized. - - // Check that the parent's name is the same as the child's claimed issuer. - SECComparison name_status = - CERT_CompareName(&child->issuer, &parent->subject); - if (name_status != SECEqual) - return false; - - // Extract the parent's public key, or fail if the key could not be read - // (e.g. certificate is corrupted). - SECKEYPublicKey* parent_key = CERT_ExtractPublicKey(parent); - if (!parent_key) - return false; - - // Check that the parent's privkey was actually used to generate the child's - // signature. - SECStatus verified = CERT_VerifySignedDataWithPublicKey(&child->signatureWrap, - parent_key, nullptr); - SECKEY_DestroyPublicKey(parent_key); - return verified == SECSuccess; -} - -bool NSSCertificate::IsValidChain(const CERTCertList* cert_list) { - CERTCertListNode* child = CERT_LIST_HEAD(cert_list); - for (CERTCertListNode* parent = CERT_LIST_NEXT(child); - !CERT_LIST_END(parent, cert_list); - child = parent, parent = CERT_LIST_NEXT(parent)) { - if (!Certifies(parent->cert, child->cert)) - return false; - } - return true; -} - -bool NSSCertificate::GetDigestLength(const std::string& algorithm, - size_t* length) { - const SECHashObject* ho = nullptr; - - if (!GetDigestObject(algorithm, &ho)) - return false; - - *length = ho->length; - - return true; -} - -bool NSSCertificate::GetSignatureDigestAlgorithm(std::string* algorithm) const { - // The function sec_DecodeSigAlg in NSS provides this mapping functionality. - // Unfortunately it is private, so the functionality must be duplicated here. - // See https://bugzilla.mozilla.org/show_bug.cgi?id=925165 . - SECOidTag sig_alg = SECOID_GetAlgorithmTag(&certificate_->signature); - switch (sig_alg) { - case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: - *algorithm = DIGEST_MD5; - break; - case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION: - case SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE: - case SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE: - case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST: - case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST: - case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE: - case SEC_OID_MISSI_DSS: - case SEC_OID_MISSI_KEA_DSS: - case SEC_OID_MISSI_KEA_DSS_OLD: - case SEC_OID_MISSI_DSS_OLD: - *algorithm = DIGEST_SHA_1; - break; - case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE: - case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION: - case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST: - *algorithm = DIGEST_SHA_224; - break; - case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE: - case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION: - case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST: - *algorithm = DIGEST_SHA_256; - break; - case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE: - case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION: - *algorithm = DIGEST_SHA_384; - break; - case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE: - case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION: - *algorithm = DIGEST_SHA_512; - break; - default: - // Unknown algorithm. There are several unhandled options that are less - // common and more complex. - algorithm->clear(); - return false; - } - return true; -} - -bool NSSCertificate::ComputeDigest(const std::string& algorithm, - unsigned char* digest, - size_t size, - size_t* length) const { - const SECHashObject* ho = nullptr; - - if (!GetDigestObject(algorithm, &ho)) - return false; - - if (size < ho->length) // Sanity check for fit - return false; - - SECStatus rv = HASH_HashBuf(ho->type, digest, - certificate_->derCert.data, - certificate_->derCert.len); - if (rv != SECSuccess) - return false; - - *length = ho->length; - - return true; -} - -bool NSSCertificate::GetChain(SSLCertChain** chain) const { - if (!chain_) - return false; - - *chain = chain_->Copy(); - return true; -} - -bool NSSCertificate::Equals(const NSSCertificate* tocompare) const { - if (!certificate_->derCert.len) - return false; - if (!tocompare->certificate_->derCert.len) - return false; - - if (certificate_->derCert.len != tocompare->certificate_->derCert.len) - return false; - - return memcmp(certificate_->derCert.data, - tocompare->certificate_->derCert.data, - certificate_->derCert.len) == 0; -} - -bool NSSCertificate::GetDigestObject(const std::string& algorithm, - const SECHashObject** hop) { - const SECHashObject* ho; - HASH_HashType hash_type; - - if (algorithm == DIGEST_SHA_1) { - hash_type = HASH_AlgSHA1; - // HASH_AlgSHA224 is not supported in the chromium linux build system. -#if 0 - } else if (algorithm == DIGEST_SHA_224) { - hash_type = HASH_AlgSHA224; -#endif - } else if (algorithm == DIGEST_SHA_256) { - hash_type = HASH_AlgSHA256; - } else if (algorithm == DIGEST_SHA_384) { - hash_type = HASH_AlgSHA384; - } else if (algorithm == DIGEST_SHA_512) { - hash_type = HASH_AlgSHA512; - } else { - return false; - } - - ho = HASH_GetHashObject(hash_type); - - ASSERT(ho->length >= 20); // Can't happen - *hop = ho; - - return true; -} - -NSSIdentity::NSSIdentity(NSSKeyPair* keypair, NSSCertificate* cert) - : keypair_(keypair), certificate_(cert) { -} - -NSSIdentity* NSSIdentity::GenerateInternal(const SSLIdentityParams& params) { - std::string subject_name_string = "CN=" + params.common_name; - CERTName* subject_name = - CERT_AsciiToName(const_cast(subject_name_string.c_str())); - NSSIdentity* identity = nullptr; - CERTSubjectPublicKeyInfo* spki = nullptr; - CERTCertificateRequest* certreq = nullptr; - CERTValidity* validity = nullptr; - CERTCertificate* certificate = nullptr; - NSSKeyPair* keypair = NSSKeyPair::Generate(params.key_type); - SECItem inner_der; - SECStatus rv; - PLArenaPool* arena; - SECItem signed_cert; - PRTime now = PR_Now(); - PRTime not_before = - now + static_cast(params.not_before) * PR_USEC_PER_SEC; - PRTime not_after = - now + static_cast(params.not_after) * PR_USEC_PER_SEC; - - inner_der.len = 0; - inner_der.data = nullptr; - - if (!keypair) { - LOG(LS_ERROR) << "Couldn't generate key pair"; - goto fail; - } - - if (!subject_name) { - LOG(LS_ERROR) << "Couldn't convert subject name " << subject_name; - goto fail; - } - - spki = SECKEY_CreateSubjectPublicKeyInfo(keypair->pubkey()); - if (!spki) { - LOG(LS_ERROR) << "Couldn't create SPKI"; - goto fail; - } - - certreq = CERT_CreateCertificateRequest(subject_name, spki, nullptr); - if (!certreq) { - LOG(LS_ERROR) << "Couldn't create certificate signing request"; - goto fail; - } - - validity = CERT_CreateValidity(not_before, not_after); - if (!validity) { - LOG(LS_ERROR) << "Couldn't create validity"; - goto fail; - } - - unsigned long serial; - // Note: This serial in principle could collide, but it's unlikely - rv = PK11_GenerateRandom(reinterpret_cast(&serial), - sizeof(serial)); - if (rv != SECSuccess) { - LOG(LS_ERROR) << "Couldn't generate random serial"; - goto fail; - } - - certificate = CERT_CreateCertificate(serial, subject_name, validity, certreq); - if (!certificate) { - LOG(LS_ERROR) << "Couldn't create certificate"; - goto fail; - } - - arena = certificate->arena; - - SECOidTag sec_oid; - if (params.key_type == KT_RSA) { - sec_oid = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; - } else if (params.key_type == KT_ECDSA) { - sec_oid = SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE; - } else { - // We should not arrive here since NSSKeyPair::Generate would have failed. - // Play it safe in order to accomodate code changes. - LOG(LS_ERROR) << "Key type requested not understood"; - goto fail; - } - - rv = SECOID_SetAlgorithmID(arena, &certificate->signature, sec_oid, nullptr); - if (rv != SECSuccess) { - LOG(LS_ERROR) << "Couldn't set hashing algorithm"; - goto fail; - } - - // Set version to X509v3. - *(certificate->version.data) = 2; - certificate->version.len = 1; - - if (!SEC_ASN1EncodeItem(arena, &inner_der, certificate, - SEC_ASN1_GET(CERT_CertificateTemplate))) { - LOG(LS_ERROR) << "Couldn't encode certificate"; - goto fail; - } - - rv = SEC_DerSignData(arena, &signed_cert, inner_der.data, inner_der.len, - keypair->privkey(), sec_oid); - if (rv != SECSuccess) { - LOG(LS_ERROR) << "Couldn't sign certificate"; - goto fail; - } - certificate->derCert = signed_cert; - - identity = new NSSIdentity(keypair, new NSSCertificate(certificate)); - - goto done; - - fail: - delete keypair; - - done: - if (certificate) CERT_DestroyCertificate(certificate); - if (subject_name) CERT_DestroyName(subject_name); - if (spki) SECKEY_DestroySubjectPublicKeyInfo(spki); - if (certreq) CERT_DestroyCertificateRequest(certreq); - if (validity) CERT_DestroyValidity(validity); - return identity; -} - -NSSIdentity* NSSIdentity::Generate(const std::string& common_name, - KeyType key_type) { - SSLIdentityParams params; - params.common_name = common_name; - params.not_before = CERTIFICATE_WINDOW; - params.not_after = CERTIFICATE_LIFETIME; - params.key_type = key_type; - return GenerateInternal(params); -} - -NSSIdentity* NSSIdentity::GenerateForTest(const SSLIdentityParams& params) { - return GenerateInternal(params); -} - -SSLIdentity* NSSIdentity::FromPEMStrings(const std::string& private_key, - const std::string& certificate) { - std::string private_key_der; - if (!SSLIdentity::PemToDer( - kPemTypeRsaPrivateKey, private_key, &private_key_der)) - return nullptr; - - SECItem private_key_item; - private_key_item.data = reinterpret_cast( - const_cast(private_key_der.c_str())); - private_key_item.len = checked_cast(private_key_der.size()); - - const unsigned int key_usage = KU_KEY_ENCIPHERMENT | KU_DATA_ENCIPHERMENT | - KU_DIGITAL_SIGNATURE; - - SECKEYPrivateKey* privkey = nullptr; - SECStatus rv = PK11_ImportDERPrivateKeyInfoAndReturnKey( - NSSContext::GetSlot(), &private_key_item, nullptr, nullptr, PR_FALSE, - PR_FALSE, key_usage, &privkey, nullptr); - if (rv != SECSuccess) { - LOG(LS_ERROR) << "Couldn't import private key"; - return nullptr; - } - - SECKEYPublicKey* pubkey = SECKEY_ConvertToPublicKey(privkey); - if (rv != SECSuccess) { - SECKEY_DestroyPrivateKey(privkey); - LOG(LS_ERROR) << "Couldn't convert private key to public key"; - return nullptr; - } - - SSLKEAType ssl_kea_type; - if (rtc::starts_with(private_key.c_str(), - "-----BEGIN RSA PRIVATE KEY-----")) { - ssl_kea_type = ssl_kea_rsa; - } else { - // We might want to check more key types here. But since we're moving to - // Open/BoringSSL, don't bother. Besides, this will likely be correct for - // any future key type, causing a test to do more harm than good. - ssl_kea_type = ssl_kea_ecdh; - } - - // Assign to a scoped_ptr so we don't leak on error. - scoped_ptr keypair(new NSSKeyPair(privkey, pubkey, ssl_kea_type)); - - scoped_ptr cert(NSSCertificate::FromPEMString(certificate)); - if (!cert) { - LOG(LS_ERROR) << "Couldn't parse certificate"; - return nullptr; - } - - // TODO(ekr@rtfm.com): Check the public key against the certificate. - return new NSSIdentity(keypair.release(), cert.release()); -} - -NSSIdentity::~NSSIdentity() { - LOG(LS_INFO) << "Destroying NSS identity"; -} - -NSSIdentity* NSSIdentity::GetReference() const { - NSSKeyPair* keypair = keypair_->GetReference(); - if (!keypair) - return nullptr; - - NSSCertificate* certificate = certificate_->GetReference(); - if (!certificate) { - delete keypair; - return nullptr; - } - - return new NSSIdentity(keypair, certificate); -} - - -NSSCertificate &NSSIdentity::certificate() const { - return *certificate_; -} - - -} // rtc namespace - -#endif // HAVE_NSS_SSL_H diff --git a/webrtc/base/nssidentity.h b/webrtc/base/nssidentity.h deleted file mode 100644 index a28ce62ba1..0000000000 --- a/webrtc/base/nssidentity.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_NSSIDENTITY_H_ -#define WEBRTC_BASE_NSSIDENTITY_H_ - -#include - -// Hack: Define+undefine int64 and uint64 to avoid typedef conflict with NSS. -// TODO(kjellander): Remove when webrtc:4497 is completed. -#define uint64 foo_uint64 -#define int64 foo_int64 -#include "cert.h" -#undef uint64 -#undef int64 -#include "nspr.h" -#include "hasht.h" -#include "keythi.h" - -#ifdef NSS_SSL_RELATIVE_PATH -#include "ssl.h" -#else -#include "net/third_party/nss/ssl/ssl.h" -#endif - -#include "webrtc/base/common.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/sslidentity.h" - -namespace rtc { - -class NSSKeyPair { - public: - NSSKeyPair(SECKEYPrivateKey* privkey, SECKEYPublicKey* pubkey) - : privkey_(privkey), pubkey_(pubkey), ssl_kea_type_(ssl_kea_null) {} - NSSKeyPair(SECKEYPrivateKey* privkey, - SECKEYPublicKey* pubkey, - SSLKEAType ssl_kea_type) - : privkey_(privkey), pubkey_(pubkey), ssl_kea_type_(ssl_kea_type) {} - ~NSSKeyPair(); - - // Generate a 1024-bit RSA key pair. - static NSSKeyPair* Generate(KeyType key_type); - NSSKeyPair* GetReference(); - - SECKEYPrivateKey* privkey() const { return privkey_; } - SECKEYPublicKey * pubkey() const { return pubkey_; } - SSLKEAType ssl_kea_type() const { return ssl_kea_type_; } - - private: - SECKEYPrivateKey* privkey_; - SECKEYPublicKey* pubkey_; - SSLKEAType ssl_kea_type_; - - RTC_DISALLOW_COPY_AND_ASSIGN(NSSKeyPair); -}; - - -class NSSCertificate : public SSLCertificate { - public: - static NSSCertificate* FromPEMString(const std::string& pem_string); - // The caller retains ownership of the argument to all the constructors, - // and the constructor makes a copy. - explicit NSSCertificate(CERTCertificate* cert); - explicit NSSCertificate(CERTCertList* cert_list); - ~NSSCertificate() override; - - NSSCertificate* GetReference() const override; - - std::string ToPEMString() const override; - - void ToDER(Buffer* der_buffer) const override; - - bool GetSignatureDigestAlgorithm(std::string* algorithm) const override; - - bool ComputeDigest(const std::string& algorithm, - unsigned char* digest, - size_t size, - size_t* length) const override; - - bool GetChain(SSLCertChain** chain) const override; - - CERTCertificate* certificate() { return certificate_; } - - // Performs minimal checks to determine if the list is a valid chain. This - // only checks that each certificate certifies the preceding certificate, - // and ignores many other certificate features such as expiration dates. - static bool IsValidChain(const CERTCertList* cert_list); - - // Helper function to get the length of a digest - static bool GetDigestLength(const std::string& algorithm, size_t* length); - - // Comparison. Only the certificate itself is considered, not the chain. - bool Equals(const NSSCertificate* tocompare) const; - - private: - NSSCertificate(CERTCertificate* cert, SSLCertChain* chain); - static bool GetDigestObject(const std::string& algorithm, - const SECHashObject** hash_object); - - CERTCertificate* certificate_; - scoped_ptr chain_; - - RTC_DISALLOW_COPY_AND_ASSIGN(NSSCertificate); -}; - -// Represents a SSL key pair and certificate for NSS. -class NSSIdentity : public SSLIdentity { - public: - static NSSIdentity* Generate(const std::string& common_name, - KeyType key_type); - static NSSIdentity* GenerateForTest(const SSLIdentityParams& params); - static SSLIdentity* FromPEMStrings(const std::string& private_key, - const std::string& certificate); - ~NSSIdentity() override; - - NSSIdentity* GetReference() const override; - NSSCertificate& certificate() const override; - - NSSKeyPair* keypair() const { return keypair_.get(); } - - private: - NSSIdentity(NSSKeyPair* keypair, NSSCertificate* cert); - - static NSSIdentity* GenerateInternal(const SSLIdentityParams& params); - - rtc::scoped_ptr keypair_; - rtc::scoped_ptr certificate_; - - RTC_DISALLOW_COPY_AND_ASSIGN(NSSIdentity); -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_NSSIDENTITY_H_ diff --git a/webrtc/base/nssstreamadapter.cc b/webrtc/base/nssstreamadapter.cc deleted file mode 100644 index 2e78adfc0e..0000000000 --- a/webrtc/base/nssstreamadapter.cc +++ /dev/null @@ -1,1127 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#if HAVE_CONFIG_H -#include "config.h" -#endif // HAVE_CONFIG_H - -#if HAVE_NSS_SSL_H - -#include "webrtc/base/nssstreamadapter.h" - -#include "keyhi.h" -#include "nspr.h" -#include "nss.h" -#include "pk11pub.h" -#include "secerr.h" - -#ifdef NSS_SSL_RELATIVE_PATH -#include "ssl.h" -#include "sslerr.h" -#include "sslproto.h" -#else -#include "net/third_party/nss/ssl/ssl.h" -#include "net/third_party/nss/ssl/sslerr.h" -#include "net/third_party/nss/ssl/sslproto.h" -#endif - -#include "webrtc/base/nssidentity.h" -#include "webrtc/base/safe_conversions.h" -#include "webrtc/base/thread.h" - -namespace rtc { - -PRDescIdentity NSSStreamAdapter::nspr_layer_identity = PR_INVALID_IO_LAYER; - -#define UNIMPLEMENTED \ - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); \ - LOG(LS_ERROR) \ - << "Call to unimplemented function "<< __FUNCTION__; ASSERT(false) - -#ifdef SRTP_AES128_CM_HMAC_SHA1_80 -#define HAVE_DTLS_SRTP -#endif - -#ifdef HAVE_DTLS_SRTP -// SRTP cipher suite table -struct SrtpCipherMapEntry { - const char* external_name; - PRUint16 cipher_id; -}; - -// This isn't elegant, but it's better than an external reference -static const SrtpCipherMapEntry kSrtpCipherMap[] = { - {"AES_CM_128_HMAC_SHA1_80", SRTP_AES128_CM_HMAC_SHA1_80 }, - {"AES_CM_128_HMAC_SHA1_32", SRTP_AES128_CM_HMAC_SHA1_32 }, - {NULL, 0} -}; -#endif - -// Ciphers to enable to get ECDHE encryption with endpoints that support it. -static const uint32_t kEnabledCiphers[] = { - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}; - -// Default cipher used between NSS stream adapters. -// This needs to be updated when the default of the SSL library changes. -static const char kDefaultSslCipher10[] = - "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"; -static const char kDefaultSslCipher12[] = - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"; -static const char kDefaultSslEcCipher10[] = - "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"; -static const char kDefaultSslEcCipher12[] = - "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"; - -// Implementation of NSPR methods -static PRStatus StreamClose(PRFileDesc *socket) { - ASSERT(!socket->lower); - socket->dtor(socket); - return PR_SUCCESS; -} - -static PRInt32 StreamRead(PRFileDesc *socket, void *buf, PRInt32 length) { - StreamInterface *stream = reinterpret_cast(socket->secret); - size_t read; - int error; - StreamResult result = stream->Read(buf, length, &read, &error); - if (result == SR_SUCCESS) { - return checked_cast(read); - } - - if (result == SR_EOS) { - return 0; - } - - if (result == SR_BLOCK) { - PR_SetError(PR_WOULD_BLOCK_ERROR, 0); - return -1; - } - - PR_SetError(PR_UNKNOWN_ERROR, error); - return -1; -} - -static PRInt32 StreamWrite(PRFileDesc *socket, const void *buf, - PRInt32 length) { - StreamInterface *stream = reinterpret_cast(socket->secret); - size_t written; - int error; - StreamResult result = stream->Write(buf, length, &written, &error); - if (result == SR_SUCCESS) { - return checked_cast(written); - } - - if (result == SR_BLOCK) { - LOG(LS_INFO) << - "NSSStreamAdapter: write to underlying transport would block"; - PR_SetError(PR_WOULD_BLOCK_ERROR, 0); - return -1; - } - - LOG(LS_ERROR) << "Write error"; - PR_SetError(PR_UNKNOWN_ERROR, error); - return -1; -} - -static PRInt32 StreamAvailable(PRFileDesc *socket) { - UNIMPLEMENTED; - return -1; -} - -PRInt64 StreamAvailable64(PRFileDesc *socket) { - UNIMPLEMENTED; - return -1; -} - -static PRStatus StreamSync(PRFileDesc *socket) { - UNIMPLEMENTED; - return PR_FAILURE; -} - -static PROffset32 StreamSeek(PRFileDesc *socket, PROffset32 offset, - PRSeekWhence how) { - UNIMPLEMENTED; - return -1; -} - -static PROffset64 StreamSeek64(PRFileDesc *socket, PROffset64 offset, - PRSeekWhence how) { - UNIMPLEMENTED; - return -1; -} - -static PRStatus StreamFileInfo(PRFileDesc *socket, PRFileInfo *info) { - UNIMPLEMENTED; - return PR_FAILURE; -} - -static PRStatus StreamFileInfo64(PRFileDesc *socket, PRFileInfo64 *info) { - UNIMPLEMENTED; - return PR_FAILURE; -} - -static PRInt32 StreamWritev(PRFileDesc *socket, const PRIOVec *iov, - PRInt32 iov_size, PRIntervalTime timeout) { - UNIMPLEMENTED; - return -1; -} - -static PRStatus StreamConnect(PRFileDesc *socket, const PRNetAddr *addr, - PRIntervalTime timeout) { - UNIMPLEMENTED; - return PR_FAILURE; -} - -static PRFileDesc *StreamAccept(PRFileDesc *sd, PRNetAddr *addr, - PRIntervalTime timeout) { - UNIMPLEMENTED; - return NULL; -} - -static PRStatus StreamBind(PRFileDesc *socket, const PRNetAddr *addr) { - UNIMPLEMENTED; - return PR_FAILURE; -} - -static PRStatus StreamListen(PRFileDesc *socket, PRIntn depth) { - UNIMPLEMENTED; - return PR_FAILURE; -} - -static PRStatus StreamShutdown(PRFileDesc *socket, PRIntn how) { - UNIMPLEMENTED; - return PR_FAILURE; -} - -// Note: this is always nonblocking and ignores the timeout. -// TODO(ekr@rtfm.com): In future verify that the socket is -// actually in non-blocking mode. -// This function does not support peek. -static PRInt32 StreamRecv(PRFileDesc *socket, void *buf, PRInt32 amount, - PRIntn flags, PRIntervalTime to) { - ASSERT(flags == 0); - - if (flags != 0) { - PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); - return -1; - } - - return StreamRead(socket, buf, amount); -} - -// Note: this is always nonblocking and assumes a zero timeout. -// This function does not support peek. -static PRInt32 StreamSend(PRFileDesc *socket, const void *buf, - PRInt32 amount, PRIntn flags, - PRIntervalTime to) { - ASSERT(flags == 0); - - return StreamWrite(socket, buf, amount); -} - -static PRInt32 StreamRecvfrom(PRFileDesc *socket, void *buf, - PRInt32 amount, PRIntn flags, - PRNetAddr *addr, PRIntervalTime to) { - UNIMPLEMENTED; - return -1; -} - -static PRInt32 StreamSendto(PRFileDesc *socket, const void *buf, - PRInt32 amount, PRIntn flags, - const PRNetAddr *addr, PRIntervalTime to) { - UNIMPLEMENTED; - return -1; -} - -static PRInt16 StreamPoll(PRFileDesc *socket, PRInt16 in_flags, - PRInt16 *out_flags) { - UNIMPLEMENTED; - return -1; -} - -static PRInt32 StreamAcceptRead(PRFileDesc *sd, PRFileDesc **nd, - PRNetAddr **raddr, - void *buf, PRInt32 amount, PRIntervalTime t) { - UNIMPLEMENTED; - return -1; -} - -static PRInt32 StreamTransmitFile(PRFileDesc *sd, PRFileDesc *socket, - const void *headers, PRInt32 hlen, - PRTransmitFileFlags flags, PRIntervalTime t) { - UNIMPLEMENTED; - return -1; -} - -static PRStatus StreamGetPeerName(PRFileDesc *socket, PRNetAddr *addr) { - // TODO(ekr@rtfm.com): Modify to return unique names for each channel - // somehow, as opposed to always the same static address. The current - // implementation messes up the session cache, which is why it's off - // elsewhere - addr->inet.family = PR_AF_INET; - addr->inet.port = 0; - addr->inet.ip = 0; - - return PR_SUCCESS; -} - -static PRStatus StreamGetSockName(PRFileDesc *socket, PRNetAddr *addr) { - UNIMPLEMENTED; - return PR_FAILURE; -} - -static PRStatus StreamGetSockOption(PRFileDesc *socket, PRSocketOptionData *opt) { - switch (opt->option) { - case PR_SockOpt_Nonblocking: - opt->value.non_blocking = PR_TRUE; - return PR_SUCCESS; - default: - UNIMPLEMENTED; - break; - } - - return PR_FAILURE; -} - -// Imitate setting socket options. These are mostly noops. -static PRStatus StreamSetSockOption(PRFileDesc *socket, - const PRSocketOptionData *opt) { - switch (opt->option) { - case PR_SockOpt_Nonblocking: - return PR_SUCCESS; - case PR_SockOpt_NoDelay: - return PR_SUCCESS; - default: - UNIMPLEMENTED; - break; - } - - return PR_FAILURE; -} - -static PRInt32 StreamSendfile(PRFileDesc *out, PRSendFileData *in, - PRTransmitFileFlags flags, PRIntervalTime to) { - UNIMPLEMENTED; - return -1; -} - -static PRStatus StreamConnectContinue(PRFileDesc *socket, PRInt16 flags) { - UNIMPLEMENTED; - return PR_FAILURE; -} - -static PRIntn StreamReserved(PRFileDesc *socket) { - UNIMPLEMENTED; - return -1; -} - -static const struct PRIOMethods nss_methods = { - PR_DESC_LAYERED, - StreamClose, - StreamRead, - StreamWrite, - StreamAvailable, - StreamAvailable64, - StreamSync, - StreamSeek, - StreamSeek64, - StreamFileInfo, - StreamFileInfo64, - StreamWritev, - StreamConnect, - StreamAccept, - StreamBind, - StreamListen, - StreamShutdown, - StreamRecv, - StreamSend, - StreamRecvfrom, - StreamSendto, - StreamPoll, - StreamAcceptRead, - StreamTransmitFile, - StreamGetSockName, - StreamGetPeerName, - StreamReserved, - StreamReserved, - StreamGetSockOption, - StreamSetSockOption, - StreamSendfile, - StreamConnectContinue, - StreamReserved, - StreamReserved, - StreamReserved, - StreamReserved -}; - -NSSStreamAdapter::NSSStreamAdapter(StreamInterface *stream) - : SSLStreamAdapterHelper(stream), - ssl_fd_(NULL), - cert_ok_(false) { -} - -bool NSSStreamAdapter::Init() { - if (nspr_layer_identity == PR_INVALID_IO_LAYER) { - nspr_layer_identity = PR_GetUniqueIdentity("nssstreamadapter"); - } - PRFileDesc *pr_fd = PR_CreateIOLayerStub(nspr_layer_identity, &nss_methods); - if (!pr_fd) - return false; - pr_fd->secret = reinterpret_cast(stream()); - - PRFileDesc *ssl_fd; - if (ssl_mode_ == SSL_MODE_DTLS) { - ssl_fd = DTLS_ImportFD(NULL, pr_fd); - } else { - ssl_fd = SSL_ImportFD(NULL, pr_fd); - } - ASSERT(ssl_fd != NULL); // This should never happen - if (!ssl_fd) { - PR_Close(pr_fd); - return false; - } - - SECStatus rv; - // Turn on security. - rv = SSL_OptionSet(ssl_fd, SSL_SECURITY, PR_TRUE); - if (rv != SECSuccess) { - LOG(LS_ERROR) << "Error enabling security on SSL Socket"; - return false; - } - - // Disable SSLv2. - rv = SSL_OptionSet(ssl_fd, SSL_ENABLE_SSL2, PR_FALSE); - if (rv != SECSuccess) { - LOG(LS_ERROR) << "Error disabling SSL2"; - return false; - } - - // Disable caching. - // TODO(ekr@rtfm.com): restore this when I have the caching - // identity set. - rv = SSL_OptionSet(ssl_fd, SSL_NO_CACHE, PR_TRUE); - if (rv != SECSuccess) { - LOG(LS_ERROR) << "Error disabling cache"; - return false; - } - - // Disable session tickets. - rv = SSL_OptionSet(ssl_fd, SSL_ENABLE_SESSION_TICKETS, PR_FALSE); - if (rv != SECSuccess) { - LOG(LS_ERROR) << "Error enabling tickets"; - return false; - } - - // Disable renegotiation. - rv = SSL_OptionSet(ssl_fd, SSL_ENABLE_RENEGOTIATION, - SSL_RENEGOTIATE_NEVER); - if (rv != SECSuccess) { - LOG(LS_ERROR) << "Error disabling renegotiation"; - return false; - } - - // Disable false start. - rv = SSL_OptionSet(ssl_fd, SSL_ENABLE_FALSE_START, PR_FALSE); - if (rv != SECSuccess) { - LOG(LS_ERROR) << "Error disabling false start"; - return false; - } - - // Disable reusing of ECDHE keys. By default NSS, when in server mode, uses - // the same key for multiple connections, so disable this behaviour to get - // ephemeral keys. - rv = SSL_OptionSet(ssl_fd, SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE); - if (rv != SECSuccess) { - LOG(LS_ERROR) << "Error disabling ECDHE key reuse"; - return false; - } - - ssl_fd_ = ssl_fd; - - return true; -} - -NSSStreamAdapter::~NSSStreamAdapter() { - if (ssl_fd_) - PR_Close(ssl_fd_); -}; - - -int NSSStreamAdapter::BeginSSL() { - SECStatus rv; - - if (!Init()) { - Error("Init", -1, false); - return -1; - } - - ASSERT(state_ == SSL_CONNECTING); - // The underlying stream has been opened. If we are in peer-to-peer mode - // then a peer certificate must have been specified by now. - ASSERT(!ssl_server_name_.empty() || - peer_certificate_.get() != NULL || - !peer_certificate_digest_algorithm_.empty()); - LOG(LS_INFO) << "BeginSSL: " - << (!ssl_server_name_.empty() ? ssl_server_name_ : - "with peer"); - - if (role_ == SSL_CLIENT) { - LOG(LS_INFO) << "BeginSSL: as client"; - - rv = SSL_GetClientAuthDataHook(ssl_fd_, GetClientAuthDataHook, - this); - if (rv != SECSuccess) { - Error("BeginSSL", -1, false); - return -1; - } - } else { - LOG(LS_INFO) << "BeginSSL: as server"; - NSSIdentity *identity; - - if (identity_.get()) { - identity = static_cast(identity_.get()); - } else { - LOG(LS_ERROR) << "Can't be an SSL server without an identity"; - Error("BeginSSL", -1, false); - return -1; - } - rv = SSL_ConfigSecureServer(ssl_fd_, identity->certificate().certificate(), - identity->keypair()->privkey(), - identity->keypair()->ssl_kea_type()); - if (rv != SECSuccess) { - Error("BeginSSL", -1, false); - return -1; - } - - // Insist on a certificate from the client - rv = SSL_OptionSet(ssl_fd_, SSL_REQUEST_CERTIFICATE, PR_TRUE); - if (rv != SECSuccess) { - Error("BeginSSL", -1, false); - return -1; - } - - // TODO(juberti): Check for client_auth_enabled() - - rv = SSL_OptionSet(ssl_fd_, SSL_REQUIRE_CERTIFICATE, PR_TRUE); - if (rv != SECSuccess) { - Error("BeginSSL", -1, false); - return -1; - } - } - - // Set the version range. - SSLVersionRange vrange; - if (ssl_mode_ == SSL_MODE_DTLS) { - vrange.min = SSL_LIBRARY_VERSION_TLS_1_1; - switch (ssl_max_version_) { - case SSL_PROTOCOL_DTLS_10: - vrange.max = SSL_LIBRARY_VERSION_TLS_1_1; - break; - case SSL_PROTOCOL_DTLS_12: - default: - vrange.max = SSL_LIBRARY_VERSION_TLS_1_2; - break; - } - } else { - // SSL_MODE_TLS - vrange.min = SSL_LIBRARY_VERSION_TLS_1_0; - switch (ssl_max_version_) { - case SSL_PROTOCOL_TLS_10: - vrange.max = SSL_LIBRARY_VERSION_TLS_1_0; - break; - case SSL_PROTOCOL_TLS_11: - vrange.max = SSL_LIBRARY_VERSION_TLS_1_1; - break; - case SSL_PROTOCOL_TLS_12: - default: - vrange.max = SSL_LIBRARY_VERSION_TLS_1_2; - break; - } - } - - rv = SSL_VersionRangeSet(ssl_fd_, &vrange); - if (rv != SECSuccess) { - Error("BeginSSL", -1, false); - return -1; - } - - // SRTP -#ifdef HAVE_DTLS_SRTP - if (!srtp_ciphers_.empty()) { - rv = SSL_SetSRTPCiphers( - ssl_fd_, &srtp_ciphers_[0], - checked_cast(srtp_ciphers_.size())); - if (rv != SECSuccess) { - Error("BeginSSL", -1, false); - return -1; - } - } -#endif - - // Enable additional ciphers. - for (size_t i = 0; i < ARRAY_SIZE(kEnabledCiphers); i++) { - rv = SSL_CipherPrefSet(ssl_fd_, kEnabledCiphers[i], PR_TRUE); - if (rv != SECSuccess) { - Error("BeginSSL", -1, false); - return -1; - } - } - - // Certificate validation - rv = SSL_AuthCertificateHook(ssl_fd_, AuthCertificateHook, this); - if (rv != SECSuccess) { - Error("BeginSSL", -1, false); - return -1; - } - - // Now start the handshake - rv = SSL_ResetHandshake(ssl_fd_, role_ == SSL_SERVER ? PR_TRUE : PR_FALSE); - if (rv != SECSuccess) { - Error("BeginSSL", -1, false); - return -1; - } - - return ContinueSSL(); -} - -int NSSStreamAdapter::ContinueSSL() { - LOG(LS_INFO) << "ContinueSSL"; - ASSERT(state_ == SSL_CONNECTING); - - // Clear the DTLS timer - Thread::Current()->Clear(this, MSG_DTLS_TIMEOUT); - - SECStatus rv = SSL_ForceHandshake(ssl_fd_); - - if (rv == SECSuccess) { - LOG(LS_INFO) << "Handshake complete"; - - ASSERT(cert_ok_); - if (!cert_ok_) { - Error("ContinueSSL", -1, true); - return -1; - } - - state_ = SSL_CONNECTED; - StreamAdapterInterface::OnEvent(stream(), SE_OPEN|SE_READ|SE_WRITE, 0); - return 0; - } - - PRInt32 err = PR_GetError(); - switch (err) { - case SSL_ERROR_RX_MALFORMED_HANDSHAKE: - if (ssl_mode_ != SSL_MODE_DTLS) { - Error("ContinueSSL", -1, true); - return -1; - } else { - LOG(LS_INFO) << "Malformed DTLS message. Ignoring."; - FALLTHROUGH(); // Fall through - } - case PR_WOULD_BLOCK_ERROR: - LOG(LS_INFO) << "Would have blocked"; - if (ssl_mode_ == SSL_MODE_DTLS) { - PRIntervalTime timeout; - - SECStatus rv = DTLS_GetHandshakeTimeout(ssl_fd_, &timeout); - if (rv == SECSuccess) { - LOG(LS_INFO) << "Timeout is " << timeout << " ms"; - Thread::Current()->PostDelayed(PR_IntervalToMilliseconds(timeout), - this, MSG_DTLS_TIMEOUT, 0); - } - } - - return 0; - default: - LOG(LS_INFO) << "Error " << err; - break; - } - - Error("ContinueSSL", -1, true); - return -1; -} - -void NSSStreamAdapter::Cleanup() { - if (state_ != SSL_ERROR) { - state_ = SSL_CLOSED; - } - - if (ssl_fd_) { - PR_Close(ssl_fd_); - ssl_fd_ = NULL; - } - - identity_.reset(); - peer_certificate_.reset(); - - Thread::Current()->Clear(this, MSG_DTLS_TIMEOUT); -} - -bool NSSStreamAdapter::GetDigestLength(const std::string& algorithm, - size_t* length) { - return NSSCertificate::GetDigestLength(algorithm, length); -} - -StreamResult NSSStreamAdapter::Read(void* data, size_t data_len, - size_t* read, int* error) { - // SSL_CONNECTED sanity check. - switch (state_) { - case SSL_NONE: - case SSL_WAIT: - case SSL_CONNECTING: - return SR_BLOCK; - - case SSL_CONNECTED: - break; - - case SSL_CLOSED: - return SR_EOS; - - case SSL_ERROR: - default: - if (error) - *error = ssl_error_code_; - return SR_ERROR; - } - - PRInt32 rv = PR_Read(ssl_fd_, data, checked_cast(data_len)); - - if (rv == 0) { - return SR_EOS; - } - - // Error - if (rv < 0) { - PRInt32 err = PR_GetError(); - - switch (err) { - case PR_WOULD_BLOCK_ERROR: - return SR_BLOCK; - default: - Error("Read", -1, false); - *error = err; // libjingle semantics are that this is impl-specific - return SR_ERROR; - } - } - - // Success - *read = rv; - - return SR_SUCCESS; -} - -StreamResult NSSStreamAdapter::Write(const void* data, size_t data_len, - size_t* written, int* error) { - // SSL_CONNECTED sanity check. - switch (state_) { - case SSL_NONE: - case SSL_WAIT: - case SSL_CONNECTING: - return SR_BLOCK; - - case SSL_CONNECTED: - break; - - case SSL_ERROR: - case SSL_CLOSED: - default: - if (error) - *error = ssl_error_code_; - return SR_ERROR; - } - - PRInt32 rv = PR_Write(ssl_fd_, data, checked_cast(data_len)); - - // Error - if (rv < 0) { - PRInt32 err = PR_GetError(); - - switch (err) { - case PR_WOULD_BLOCK_ERROR: - return SR_BLOCK; - default: - Error("Write", -1, false); - *error = err; // libjingle semantics are that this is impl-specific - return SR_ERROR; - } - } - - // Success - *written = rv; - - return SR_SUCCESS; -} - -void NSSStreamAdapter::OnEvent(StreamInterface* stream, int events, - int err) { - int events_to_signal = 0; - int signal_error = 0; - ASSERT(stream == this->stream()); - if ((events & SE_OPEN)) { - LOG(LS_INFO) << "NSSStreamAdapter::OnEvent SE_OPEN"; - if (state_ != SSL_WAIT) { - ASSERT(state_ == SSL_NONE); - events_to_signal |= SE_OPEN; - } else { - state_ = SSL_CONNECTING; - if (int err = BeginSSL()) { - Error("BeginSSL", err, true); - return; - } - } - } - if ((events & (SE_READ|SE_WRITE))) { - LOG(LS_INFO) << "NSSStreamAdapter::OnEvent" - << ((events & SE_READ) ? " SE_READ" : "") - << ((events & SE_WRITE) ? " SE_WRITE" : ""); - if (state_ == SSL_NONE) { - events_to_signal |= events & (SE_READ|SE_WRITE); - } else if (state_ == SSL_CONNECTING) { - if (int err = ContinueSSL()) { - Error("ContinueSSL", err, true); - return; - } - } else if (state_ == SSL_CONNECTED) { - if (events & SE_WRITE) { - LOG(LS_INFO) << " -- onStreamWriteable"; - events_to_signal |= SE_WRITE; - } - if (events & SE_READ) { - LOG(LS_INFO) << " -- onStreamReadable"; - events_to_signal |= SE_READ; - } - } - } - if ((events & SE_CLOSE)) { - LOG(LS_INFO) << "NSSStreamAdapter::OnEvent(SE_CLOSE, " << err << ")"; - Cleanup(); - events_to_signal |= SE_CLOSE; - // SE_CLOSE is the only event that uses the final parameter to OnEvent(). - ASSERT(signal_error == 0); - signal_error = err; - } - if (events_to_signal) - StreamAdapterInterface::OnEvent(stream, events_to_signal, signal_error); -} - -void NSSStreamAdapter::OnMessage(Message* msg) { - // Process our own messages and then pass others to the superclass - if (MSG_DTLS_TIMEOUT == msg->message_id) { - LOG(LS_INFO) << "DTLS timeout expired"; - ContinueSSL(); - } else { - StreamInterface::OnMessage(msg); - } -} - -// Certificate verification callback. Called to check any certificate -SECStatus NSSStreamAdapter::AuthCertificateHook(void *arg, - PRFileDesc *fd, - PRBool checksig, - PRBool isServer) { - LOG(LS_INFO) << "NSSStreamAdapter::AuthCertificateHook"; - // SSL_PeerCertificate returns a pointer that is owned by the caller, and - // the NSSCertificate constructor copies its argument, so |raw_peer_cert| - // must be destroyed in this function. - CERTCertificate* raw_peer_cert = SSL_PeerCertificate(fd); - NSSCertificate peer_cert(raw_peer_cert); - CERT_DestroyCertificate(raw_peer_cert); - - NSSStreamAdapter *stream = reinterpret_cast(arg); - stream->cert_ok_ = false; - - // Read the peer's certificate chain. - CERTCertList* cert_list = SSL_PeerCertificateChain(fd); - ASSERT(cert_list != NULL); - - // If the peer provided multiple certificates, check that they form a valid - // chain as defined by RFC 5246 Section 7.4.2: "Each following certificate - // MUST directly certify the one preceding it.". This check does NOT - // verify other requirements, such as whether the chain reaches a trusted - // root, self-signed certificates have valid signatures, certificates are not - // expired, etc. - // Even if the chain is valid, the leaf certificate must still match a - // provided certificate or digest. - if (!NSSCertificate::IsValidChain(cert_list)) { - CERT_DestroyCertList(cert_list); - PORT_SetError(SEC_ERROR_BAD_SIGNATURE); - return SECFailure; - } - - if (stream->peer_certificate_.get()) { - LOG(LS_INFO) << "Checking against specified certificate"; - - // The peer certificate was specified - if (reinterpret_cast(stream->peer_certificate_.get())-> - Equals(&peer_cert)) { - LOG(LS_INFO) << "Accepted peer certificate"; - stream->cert_ok_ = true; - } - } else if (!stream->peer_certificate_digest_algorithm_.empty()) { - LOG(LS_INFO) << "Checking against specified digest"; - // The peer certificate digest was specified - unsigned char digest[64]; // Maximum size - size_t digest_length; - - if (!peer_cert.ComputeDigest( - stream->peer_certificate_digest_algorithm_, - digest, sizeof(digest), &digest_length)) { - LOG(LS_ERROR) << "Digest computation failed"; - } else { - Buffer computed_digest(digest, digest_length); - if (computed_digest == stream->peer_certificate_digest_value_) { - LOG(LS_INFO) << "Accepted peer certificate"; - stream->cert_ok_ = true; - } - } - } else { - // Other modes, but we haven't implemented yet - // TODO(ekr@rtfm.com): Implement real certificate validation - UNIMPLEMENTED; - } - - if (!stream->cert_ok_ && stream->ignore_bad_cert()) { - LOG(LS_WARNING) << "Ignoring cert error while verifying cert chain"; - stream->cert_ok_ = true; - } - - if (stream->cert_ok_) - stream->peer_certificate_.reset(new NSSCertificate(cert_list)); - - CERT_DestroyCertList(cert_list); - - if (stream->cert_ok_) - return SECSuccess; - - PORT_SetError(SEC_ERROR_UNTRUSTED_CERT); - return SECFailure; -} - - -SECStatus NSSStreamAdapter::GetClientAuthDataHook(void *arg, PRFileDesc *fd, - CERTDistNames *caNames, - CERTCertificate **pRetCert, - SECKEYPrivateKey **pRetKey) { - LOG(LS_INFO) << "Client cert requested"; - NSSStreamAdapter *stream = reinterpret_cast(arg); - - if (!stream->identity_.get()) { - LOG(LS_ERROR) << "No identity available"; - return SECFailure; - } - - NSSIdentity *identity = static_cast(stream->identity_.get()); - // Destroyed internally by NSS - *pRetCert = CERT_DupCertificate(identity->certificate().certificate()); - *pRetKey = SECKEY_CopyPrivateKey(identity->keypair()->privkey()); - - return SECSuccess; -} - -bool NSSStreamAdapter::GetSslCipher(std::string* cipher) { - ASSERT(state_ == SSL_CONNECTED); - if (state_ != SSL_CONNECTED) - return false; - - SSLChannelInfo channel_info; - SECStatus rv = SSL_GetChannelInfo(ssl_fd_, &channel_info, - sizeof(channel_info)); - if (rv == SECFailure) - return false; - - SSLCipherSuiteInfo ciphersuite_info; - rv = SSL_GetCipherSuiteInfo(channel_info.cipherSuite, &ciphersuite_info, - sizeof(ciphersuite_info)); - if (rv == SECFailure) - return false; - - *cipher = ciphersuite_info.cipherSuiteName; - return true; -} - -// RFC 5705 Key Exporter -bool NSSStreamAdapter::ExportKeyingMaterial(const std::string& label, - const uint8* context, - size_t context_len, - bool use_context, - uint8* result, - size_t result_len) { - SECStatus rv = SSL_ExportKeyingMaterial( - ssl_fd_, - label.c_str(), - checked_cast(label.size()), - use_context, - context, - checked_cast(context_len), - result, - checked_cast(result_len)); - - return rv == SECSuccess; -} - -bool NSSStreamAdapter::SetDtlsSrtpCiphers( - const std::vector& ciphers) { -#ifdef HAVE_DTLS_SRTP - std::vector internal_ciphers; - if (state_ != SSL_NONE) - return false; - - for (std::vector::const_iterator cipher = ciphers.begin(); - cipher != ciphers.end(); ++cipher) { - bool found = false; - for (const SrtpCipherMapEntry *entry = kSrtpCipherMap; entry->cipher_id; - ++entry) { - if (*cipher == entry->external_name) { - found = true; - internal_ciphers.push_back(entry->cipher_id); - break; - } - } - - if (!found) { - LOG(LS_ERROR) << "Could not find cipher: " << *cipher; - return false; - } - } - - if (internal_ciphers.empty()) - return false; - - srtp_ciphers_ = internal_ciphers; - - return true; -#else - return false; -#endif -} - -bool NSSStreamAdapter::GetDtlsSrtpCipher(std::string* cipher) { -#ifdef HAVE_DTLS_SRTP - ASSERT(state_ == SSL_CONNECTED); - if (state_ != SSL_CONNECTED) - return false; - - PRUint16 selected_cipher; - - SECStatus rv = SSL_GetSRTPCipher(ssl_fd_, &selected_cipher); - if (rv == SECFailure) - return false; - - for (const SrtpCipherMapEntry *entry = kSrtpCipherMap; - entry->cipher_id; ++entry) { - if (selected_cipher == entry->cipher_id) { - *cipher = entry->external_name; - return true; - } - } - - ASSERT(false); // This should never happen -#endif - return false; -} - - -GlobalLockPod NSSContext::lock; -NSSContext *NSSContext::global_nss_context; - -// Static initialization and shutdown -NSSContext *NSSContext::Instance() { - lock.Lock(); - if (!global_nss_context) { - scoped_ptr new_ctx(new NSSContext(PK11_GetInternalSlot())); - if (new_ctx->slot_) - global_nss_context = new_ctx.release(); - } - lock.Unlock(); - - return global_nss_context; -} - -bool NSSContext::InitializeSSL(VerificationCallback callback) { - ASSERT(!callback); - - static bool initialized = false; - - if (!initialized) { - SECStatus rv; - - rv = NSS_NoDB_Init(NULL); - if (rv != SECSuccess) { - LOG(LS_ERROR) << "Couldn't initialize NSS error=" << - PORT_GetError(); - return false; - } - - NSS_SetDomesticPolicy(); - - initialized = true; - } - - return true; -} - -bool NSSContext::InitializeSSLThread() { - // Not needed - return true; -} - -bool NSSContext::CleanupSSL() { - // Not needed - return true; -} - -bool NSSStreamAdapter::HaveDtls() { - return true; -} - -bool NSSStreamAdapter::HaveDtlsSrtp() { -#ifdef HAVE_DTLS_SRTP - return true; -#else - return false; -#endif -} - -bool NSSStreamAdapter::HaveExporter() { - return true; -} - -std::string NSSStreamAdapter::GetDefaultSslCipher(SSLProtocolVersion version, - KeyType key_type) { - if (key_type == KT_RSA) { - switch (version) { - case SSL_PROTOCOL_TLS_10: - case SSL_PROTOCOL_TLS_11: - return kDefaultSslCipher10; - case SSL_PROTOCOL_TLS_12: - default: - return kDefaultSslCipher12; - } - } else if (key_type == KT_ECDSA) { - switch (version) { - case SSL_PROTOCOL_TLS_10: - case SSL_PROTOCOL_TLS_11: - return kDefaultSslEcCipher10; - case SSL_PROTOCOL_TLS_12: - default: - return kDefaultSslEcCipher12; - } - } else { - return std::string(); - } -} - -} // namespace rtc - -#endif // HAVE_NSS_SSL_H diff --git a/webrtc/base/nssstreamadapter.h b/webrtc/base/nssstreamadapter.h deleted file mode 100644 index 04c310ecb8..0000000000 --- a/webrtc/base/nssstreamadapter.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2004 The WebRTC Project Authors. All rights reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_BASE_NSSSTREAMADAPTER_H_ -#define WEBRTC_BASE_NSSSTREAMADAPTER_H_ - -#include -#include - -// Hack: Define+undefine int64 and uint64 to avoid typedef conflict with NSS. -// TODO(kjellander): Remove when webrtc:4497 is completed. -#define uint64 foo_uint64 -#define int64 foo_int64 -#include "nspr.h" -#undef uint64 -#undef int64 - -#include "nss.h" -#include "secmodt.h" - -#include "webrtc/base/buffer.h" -#include "webrtc/base/criticalsection.h" -#include "webrtc/base/nssidentity.h" -#include "webrtc/base/ssladapter.h" -#include "webrtc/base/sslstreamadapter.h" -#include "webrtc/base/sslstreamadapterhelper.h" - -namespace rtc { - -// Singleton -class NSSContext { - public: - explicit NSSContext(PK11SlotInfo* slot) : slot_(slot) {} - ~NSSContext() { - } - - static PK11SlotInfo *GetSlot() { - return Instance() ? Instance()->slot_: NULL; - } - - static NSSContext *Instance(); - static bool InitializeSSL(VerificationCallback callback); - static bool InitializeSSLThread(); - static bool CleanupSSL(); - - private: - PK11SlotInfo *slot_; // The PKCS-11 slot - static GlobalLockPod lock; // To protect the global context - static NSSContext *global_nss_context; // The global context -}; - - -class NSSStreamAdapter : public SSLStreamAdapterHelper { - public: - explicit NSSStreamAdapter(StreamInterface* stream); - ~NSSStreamAdapter() override; - bool Init(); - - StreamResult Read(void* data, - size_t data_len, - size_t* read, - int* error) override; - StreamResult Write(const void* data, - size_t data_len, - size_t* written, - int* error) override; - void OnMessage(Message* msg) override; - - bool GetSslCipher(std::string* cipher) override; - - // Key Extractor interface - bool ExportKeyingMaterial(const std::string& label, - const uint8* context, - size_t context_len, - bool use_context, - uint8* result, - size_t result_len) override; - - // DTLS-SRTP interface - bool SetDtlsSrtpCiphers(const std::vector& ciphers) override; - bool GetDtlsSrtpCipher(std::string* cipher) override; - - // Capabilities interfaces - static bool HaveDtls(); - static bool HaveDtlsSrtp(); - static bool HaveExporter(); - static std::string GetDefaultSslCipher(SSLProtocolVersion version, - KeyType key_type); - - protected: - // Override SSLStreamAdapter - void OnEvent(StreamInterface* stream, int events, int err) override; - - // Override SSLStreamAdapterHelper - int BeginSSL() override; - void Cleanup() override; - bool GetDigestLength(const std::string& algorithm, size_t* length) override; - - private: - int ContinueSSL(); - static SECStatus AuthCertificateHook(void *arg, PRFileDesc *fd, - PRBool checksig, PRBool isServer); - static SECStatus GetClientAuthDataHook(void *arg, PRFileDesc *fd, - CERTDistNames *caNames, - CERTCertificate **pRetCert, - SECKEYPrivateKey **pRetKey); - - PRFileDesc *ssl_fd_; // NSS's SSL file descriptor - static bool initialized; // Was InitializeSSL() called? - bool cert_ok_; // Did we get and check a cert - std::vector srtp_ciphers_; // SRTP cipher list - - static PRDescIdentity nspr_layer_identity; // The NSPR layer identity -}; - -} // namespace rtc - -#endif // WEBRTC_BASE_NSSSTREAMADAPTER_H_ diff --git a/webrtc/base/opensslstreamadapter.cc b/webrtc/base/opensslstreamadapter.cc index 3d1760721f..ed2505e8b7 100644 --- a/webrtc/base/opensslstreamadapter.cc +++ b/webrtc/base/opensslstreamadapter.cc @@ -1041,7 +1041,7 @@ int OpenSSLStreamAdapter::SSLVerifyCallback(int ok, X509_STORE_CTX* store) { // the digest. // // TODO(jiayl): Verify the chain is a proper chain and report the chain to - // |stream->peer_certificate_|, like what NSS does. + // |stream->peer_certificate_|. if (depth > 0) { LOG(LS_INFO) << "Ignored chained certificate at depth " << depth; return 1; diff --git a/webrtc/base/ssladapter.cc b/webrtc/base/ssladapter.cc index d83a2779e8..77ad90b504 100644 --- a/webrtc/base/ssladapter.cc +++ b/webrtc/base/ssladapter.cc @@ -24,11 +24,7 @@ #include "openssladapter.h" -#elif SSL_USE_NSS // && !SSL_USE_CHANNEL && !SSL_USE_OPENSSL - -#include "nssstreamadapter.h" - -#endif // SSL_USE_OPENSSL && !SSL_USE_SCHANNEL && !SSL_USE_NSS +#endif // SSL_USE_OPENSSL && !SSL_USE_SCHANNEL /////////////////////////////////////////////////////////////////////////////// @@ -62,21 +58,7 @@ bool CleanupSSL() { return OpenSSLAdapter::CleanupSSL(); } -#elif SSL_USE_NSS // !SSL_USE_OPENSSL - -bool InitializeSSL(VerificationCallback callback) { - return NSSContext::InitializeSSL(callback); -} - -bool InitializeSSLThread() { - return NSSContext::InitializeSSLThread(); -} - -bool CleanupSSL() { - return NSSContext::CleanupSSL(); -} - -#else // !SSL_USE_OPENSSL && !SSL_USE_NSS +#else // !SSL_USE_OPENSSL bool InitializeSSL(VerificationCallback callback) { return true; @@ -90,7 +72,7 @@ bool CleanupSSL() { return true; } -#endif // !SSL_USE_OPENSSL && !SSL_USE_NSS +#endif // !SSL_USE_OPENSSL /////////////////////////////////////////////////////////////////////////////// diff --git a/webrtc/base/sslconfig.h b/webrtc/base/sslconfig.h index d824ab0627..6aabad07a8 100644 --- a/webrtc/base/sslconfig.h +++ b/webrtc/base/sslconfig.h @@ -13,8 +13,7 @@ // If no preference has been indicated, default to SChannel on Windows and // OpenSSL everywhere else, if it is available. -#if !defined(SSL_USE_SCHANNEL) && !defined(SSL_USE_OPENSSL) && \ - !defined(SSL_USE_NSS) +#if !defined(SSL_USE_SCHANNEL) && !defined(SSL_USE_OPENSSL) #if defined(WEBRTC_WIN) #define SSL_USE_SCHANNEL 1 @@ -23,8 +22,6 @@ #if defined(HAVE_OPENSSL_SSL_H) #define SSL_USE_OPENSSL 1 -#elif defined(HAVE_NSS_SSL_H) -#define SSL_USE_NSS 1 #endif #endif // !defined(WEBRTC_WIN) diff --git a/webrtc/base/sslidentity.cc b/webrtc/base/sslidentity.cc index 5e565beb8a..ed9e5aca93 100644 --- a/webrtc/base/sslidentity.cc +++ b/webrtc/base/sslidentity.cc @@ -27,10 +27,6 @@ #include "webrtc/base/opensslidentity.h" -#elif SSL_USE_NSS // !SSL_USE_SCHANNEL && !SSL_USE_OPENSSL - -#include "webrtc/base/nssidentity.h" - #endif // SSL_USE_SCHANNEL namespace rtc { @@ -147,27 +143,7 @@ SSLIdentity* SSLIdentity::FromPEMStrings(const std::string& private_key, return OpenSSLIdentity::FromPEMStrings(private_key, certificate); } -#elif SSL_USE_NSS // !SSL_USE_OPENSSL && !SSL_USE_SCHANNEL - -SSLCertificate* SSLCertificate::FromPEMString(const std::string& pem_string) { - return NSSCertificate::FromPEMString(pem_string); -} - -SSLIdentity* SSLIdentity::Generate(const std::string& common_name, - KeyType key_type) { - return NSSIdentity::Generate(common_name, key_type); -} - -SSLIdentity* SSLIdentity::GenerateForTest(const SSLIdentityParams& params) { - return NSSIdentity::GenerateForTest(params); -} - -SSLIdentity* SSLIdentity::FromPEMStrings(const std::string& private_key, - const std::string& certificate) { - return NSSIdentity::FromPEMStrings(private_key, certificate); -} - -#else // !SSL_USE_OPENSSL && !SSL_USE_SCHANNEL && !SSL_USE_NSS +#else // !SSL_USE_OPENSSL && !SSL_USE_SCHANNEL #error "No SSL implementation" diff --git a/webrtc/base/sslidentity_unittest.cc b/webrtc/base/sslidentity_unittest.cc index b49d0d23a7..e8df41506b 100644 --- a/webrtc/base/sslidentity_unittest.cc +++ b/webrtc/base/sslidentity_unittest.cc @@ -185,11 +185,7 @@ TEST_F(SSLIdentityTest, FixedDigestSHA1) { } // HASH_AlgSHA224 is not supported in the chromium linux build. -#if SSL_USE_NSS -TEST_F(SSLIdentityTest, DISABLED_FixedDigestSHA224) { -#else TEST_F(SSLIdentityTest, FixedDigestSHA224) { -#endif TestDigestForFixedCert(rtc::DIGEST_SHA_224, 28, kTestCertSha224); } @@ -206,11 +202,7 @@ TEST_F(SSLIdentityTest, FixedDigestSHA512) { } // HASH_AlgSHA224 is not supported in the chromium linux build. -#if SSL_USE_NSS -TEST_F(SSLIdentityTest, DISABLED_DigestSHA224) { -#else TEST_F(SSLIdentityTest, DigestSHA224) { -#endif TestDigestForGeneratedCert(rtc::DIGEST_SHA_224, 28); } @@ -264,11 +256,6 @@ TEST_F(SSLIdentityTest, FromPEMStringsRSA) { EXPECT_EQ(kCERT_PEM, identity->certificate().ToPEMString()); } -#if SSL_USE_OPENSSL -// This will not work on NSS as PK11_ImportDERPrivateKeyInfoAndReturnKey is not -// ready for EC keys. Furthermore, NSSIdentity::FromPEMStrings is currently -// hardwired for RSA (the header matching via kPemTypeRsaPrivateKey needs -// trivial generalization). TEST_F(SSLIdentityTest, FromPEMStringsEC) { static const char kRSA_PRIVATE_KEY_PEM[] = "-----BEGIN EC PRIVATE KEY-----\n" @@ -295,7 +282,6 @@ TEST_F(SSLIdentityTest, FromPEMStringsEC) { EXPECT_TRUE(identity); EXPECT_EQ(kCERT_PEM, identity->certificate().ToPEMString()); } -#endif TEST_F(SSLIdentityTest, PemDerConversion) { std::string der; diff --git a/webrtc/base/sslstreamadapter.cc b/webrtc/base/sslstreamadapter.cc index 39426cdb74..42dea9c036 100644 --- a/webrtc/base/sslstreamadapter.cc +++ b/webrtc/base/sslstreamadapter.cc @@ -23,11 +23,7 @@ #include "webrtc/base/opensslstreamadapter.h" -#elif SSL_USE_NSS // && !SSL_USE_SCHANNEL && !SSL_USE_OPENSSL - -#include "webrtc/base/nssstreamadapter.h" - -#endif // !SSL_USE_OPENSSL && !SSL_USE_SCHANNEL && !SSL_USE_NSS +#endif // !SSL_USE_OPENSSL && !SSL_USE_SCHANNEL /////////////////////////////////////////////////////////////////////////////// @@ -38,9 +34,7 @@ SSLStreamAdapter* SSLStreamAdapter::Create(StreamInterface* stream) { return NULL; #elif SSL_USE_OPENSSL // !SSL_USE_SCHANNEL return new OpenSSLStreamAdapter(stream); -#elif SSL_USE_NSS // !SSL_USE_SCHANNEL && !SSL_USE_OPENSSL - return new NSSStreamAdapter(stream); -#else // !SSL_USE_SCHANNEL && !SSL_USE_OPENSSL && !SSL_USE_NSS +#else // !SSL_USE_SCHANNEL && !SSL_USE_OPENSSL return NULL; #endif } @@ -90,21 +84,7 @@ std::string SSLStreamAdapter::GetDefaultSslCipher(SSLProtocolVersion version, KeyType key_type) { return OpenSSLStreamAdapter::GetDefaultSslCipher(version, key_type); } -#elif SSL_USE_NSS -bool SSLStreamAdapter::HaveDtls() { - return NSSStreamAdapter::HaveDtls(); -} -bool SSLStreamAdapter::HaveDtlsSrtp() { - return NSSStreamAdapter::HaveDtlsSrtp(); -} -bool SSLStreamAdapter::HaveExporter() { - return NSSStreamAdapter::HaveExporter(); -} -std::string SSLStreamAdapter::GetDefaultSslCipher(SSLProtocolVersion version, - KeyType key_type) { - return NSSStreamAdapter::GetDefaultSslCipher(version, key_type); -} -#endif // !SSL_USE_SCHANNEL && !SSL_USE_OPENSSL && !SSL_USE_NSS +#endif // !SSL_USE_SCHANNEL && !SSL_USE_OPENSSL /////////////////////////////////////////////////////////////////////////////// diff --git a/webrtc/base/sslstreamadapter_unittest.cc b/webrtc/base/sslstreamadapter_unittest.cc index 18cc9bde11..68e1b64dbe 100644 --- a/webrtc/base/sslstreamadapter_unittest.cc +++ b/webrtc/base/sslstreamadapter_unittest.cc @@ -701,24 +701,6 @@ class SSLStreamAdapterTestDTLSFromPEMStrings : public SSLStreamAdapterTestDTLS { // Basic tests: TLS -// Test that we cannot read/write if we have not yet handshaked. -// This test only applies to NSS because OpenSSL has passthrough -// semantics for I/O before the handshake is started. -#if SSL_USE_NSS -TEST_P(SSLStreamAdapterTestTLS, TestNoReadWriteBeforeConnect) { - rtc::StreamResult rv; - char block[kBlockSize]; - size_t dummy; - - rv = client_ssl_->Write(block, sizeof(block), &dummy, NULL); - ASSERT_EQ(rtc::SR_BLOCK, rv); - - rv = client_ssl_->Read(block, sizeof(block), &dummy, NULL); - ASSERT_EQ(rtc::SR_BLOCK, rv); -} -#endif - - // Test that we can make a handshake work TEST_P(SSLStreamAdapterTestTLS, TestTLSConnect) { TestHandshake(); diff --git a/webrtc/base/sslstreamadapterhelper.h b/webrtc/base/sslstreamadapterhelper.h index a28dba4dea..c6979ba036 100644 --- a/webrtc/base/sslstreamadapterhelper.h +++ b/webrtc/base/sslstreamadapterhelper.h @@ -23,7 +23,7 @@ namespace rtc { // SSLStreamAdapterHelper : A stream adapter which implements much // of the logic that is common between the known implementations -// (NSS and OpenSSL) +// (OpenSSL and previously NSS) class SSLStreamAdapterHelper : public SSLStreamAdapter { public: explicit SSLStreamAdapterHelper(StreamInterface* stream); diff --git a/webrtc/build/sanitizers/lsan_suppressions_webrtc.cc b/webrtc/build/sanitizers/lsan_suppressions_webrtc.cc index 6d19a34881..61fdbbc20b 100644 --- a/webrtc/build/sanitizers/lsan_suppressions_webrtc.cc +++ b/webrtc/build/sanitizers/lsan_suppressions_webrtc.cc @@ -31,23 +31,6 @@ char kLSanDefaultSuppressions[] = // Leaks in Nvidia's libGL. "leak:libGL.so\n" -// TODO(earthdok): revisit NSS suppressions after the switch to BoringSSL -// NSS leaks in CertDatabaseNSSTest tests. http://crbug.com/51988 -"leak:net::NSSCertDatabase::ImportFromPKCS12\n" -"leak:net::NSSCertDatabase::ListCerts\n" -"leak:net::NSSCertDatabase::DeleteCertAndKey\n" -"leak:crypto::ScopedTestNSSDB::ScopedTestNSSDB\n" -// Another leak due to not shutting down NSS properly. http://crbug.com/124445 -"leak:error_get_my_stack\n" -// The NSS suppressions above will not fire when the fast stack unwinder is -// used, because it can't unwind through NSS libraries. Apply blanket -// suppressions for now. -"leak:libnssutil3\n" -"leak:libnspr4\n" -"leak:libnss3\n" -"leak:libplds4\n" -"leak:libnssckbi\n" - // XRandR has several one time leaks. "leak:libxrandr\n"