Revert "Use CRYPTO_BUFFER APIs instead of X509 when building with BoringSSL."
This reverts commit 72f638a9a279e7abb5534fa66a0ade2cf18ec1a7.
Reason for revert: downstream build failures
Original change's description:
> Use CRYPTO_BUFFER APIs instead of X509 when building with BoringSSL.
>
> Using CRYPTO_BUFFERs instead of legacy X509 objects offers memory and
> security gains, and will provide binary size improvements as well once
> the default list of built-in certificates can be removed; the code
> dealing with them still depends on the X509 API.
>
> Implemented by splitting openssl_identity and openssl_certificate
> into BoringSSL and vanilla OpenSSL implementations.
>
> Bug: webrtc:11410
> Change-Id: Idc043462faac5e4ab1b75bedab2057197f80aba6
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174120
> Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
> Reviewed-by: David Benjamin <davidben@webrtc.org>
> Reviewed-by: Harald Alvestrand <hta@webrtc.org>
> Commit-Queue: Taylor <deadbeef@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#32811}
TBR=deadbeef@webrtc.org,mbonadei@webrtc.org,davidben@webrtc.org,hta@webrtc.org
Change-Id: Ib5e55cb5798a2f3d25a4460f5311d2e650d3fa82
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:11410
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/196742
Reviewed-by: Sam Zackrisson <saza@webrtc.org>
Commit-Queue: Sam Zackrisson <saza@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#32812}
diff --git a/pc/test/fake_rtc_certificate_generator.h b/pc/test/fake_rtc_certificate_generator.h
index b591c4c..b726a4c 100644
--- a/pc/test/fake_rtc_certificate_generator.h
+++ b/pc/test/fake_rtc_certificate_generator.h
@@ -83,7 +83,7 @@
// ECDSA with EC_NIST_P256.
// These PEM strings were created by generating an identity with
-// |SSLIdentity::Create| and invoking |identity->PrivateKeyToPEMString()|,
+// |SSLIdentity::Generate| and invoking |identity->PrivateKeyToPEMString()|,
// |identity->PublicKeyToPEMString()| and
// |identity->certificate().ToPEMString()|.
static const rtc::RTCCertificatePEM kEcdsaPems[] = {
diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn
index 8762bfb..8b92090 100644
--- a/rtc_base/BUILD.gn
+++ b/rtc_base/BUILD.gn
@@ -911,10 +911,12 @@
"openssl.h",
"openssl_adapter.cc",
"openssl_adapter.h",
+ "openssl_certificate.cc",
+ "openssl_certificate.h",
"openssl_digest.cc",
"openssl_digest.h",
- "openssl_key_pair.cc",
- "openssl_key_pair.h",
+ "openssl_identity.cc",
+ "openssl_identity.h",
"openssl_session_cache.cc",
"openssl_session_cache.h",
"openssl_stream_adapter.cc",
@@ -960,22 +962,6 @@
"unique_id_generator.h",
]
- if (rtc_openssl_is_boringssl) {
- sources += [
- "boringssl_certificate.cc",
- "boringssl_certificate.h",
- "boringssl_identity.cc",
- "boringssl_identity.h",
- ]
- } else {
- sources += [
- "openssl_certificate.cc",
- "openssl_certificate.h",
- "openssl_identity.cc",
- "openssl_identity.h",
- ]
- }
-
if (build_with_chromium) {
include_dirs = [ "../../boringssl/src/include" ]
public_configs += [ ":rtc_base_chromium_config" ]
diff --git a/rtc_base/boringssl_certificate.cc b/rtc_base/boringssl_certificate.cc
deleted file mode 100644
index c9713c2..0000000
--- a/rtc_base/boringssl_certificate.cc
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * Copyright 2020 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 "rtc_base/boringssl_certificate.h"
-
-#if defined(WEBRTC_WIN)
-// Must be included first before openssl headers.
-#include "rtc_base/win32.h" // NOLINT
-#endif // WEBRTC_WIN
-
-#include <openssl/asn1.h>
-#include <openssl/bytestring.h>
-#include <openssl/digest.h>
-#include <openssl/evp.h>
-#include <openssl/mem.h>
-#include <openssl/pool.h>
-#include <openssl/rand.h>
-#include <time.h>
-
-#include <cstring>
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "rtc_base/checks.h"
-#include "rtc_base/helpers.h"
-#include "rtc_base/logging.h"
-#include "rtc_base/message_digest.h"
-#include "rtc_base/openssl_digest.h"
-#include "rtc_base/openssl_identity.h"
-#include "rtc_base/openssl_utility.h"
-
-namespace rtc {
-namespace {
-
-// List of OIDs of signature algorithms accepted by WebRTC.
-// Taken from openssl/nid.h.
-static const uint8_t kMD5WithRSA[] = {0x2b, 0x0e, 0x03, 0x02, 0x03};
-static const uint8_t kMD5WithRSAEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x04};
-static const uint8_t kECDSAWithSHA1[] = {0x2a, 0x86, 0x48, 0xce,
- 0x3d, 0x04, 0x01};
-static const uint8_t kDSAWithSHA1[] = {0x2a, 0x86, 0x48, 0xce,
- 0x38, 0x04, 0x03};
-static const uint8_t kDSAWithSHA1_2[] = {0x2b, 0x0e, 0x03, 0x02, 0x1b};
-static const uint8_t kSHA1WithRSA[] = {0x2b, 0x0e, 0x03, 0x02, 0x1d};
-static const uint8_t kSHA1WithRSAEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x05};
-static const uint8_t kECDSAWithSHA224[] = {0x2a, 0x86, 0x48, 0xce,
- 0x3d, 0x04, 0x03, 0x01};
-static const uint8_t kSHA224WithRSAEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x0e};
-static const uint8_t kDSAWithSHA224[] = {0x60, 0x86, 0x48, 0x01, 0x65,
- 0x03, 0x04, 0x03, 0x01};
-static const uint8_t kECDSAWithSHA256[] = {0x2a, 0x86, 0x48, 0xce,
- 0x3d, 0x04, 0x03, 0x02};
-static const uint8_t kSHA256WithRSAEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x0b};
-static const uint8_t kDSAWithSHA256[] = {0x60, 0x86, 0x48, 0x01, 0x65,
- 0x03, 0x04, 0x03, 0x028};
-static const uint8_t kECDSAWithSHA384[] = {0x2a, 0x86, 0x48, 0xce,
- 0x3d, 0x04, 0x03, 0x03};
-static const uint8_t kSHA384WithRSAEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x0c};
-static const uint8_t kECDSAWithSHA512[] = {0x2a, 0x86, 0x48, 0xce,
- 0x3d, 0x04, 0x03, 0x04};
-static const uint8_t kSHA512WithRSAEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
- 0x0d, 0x01, 0x01, 0x0d};
-
-#if !defined(NDEBUG)
-// Print a certificate to the log, for debugging.
-static void PrintCert(BoringSSLCertificate* cert) {
- // Since we're using CRYPTO_BUFFER, we can't use X509_print_ex, so we'll just
- // print the PEM string.
- RTC_DLOG(LS_VERBOSE) << "PEM representation of certificate:\n"
- << cert->ToPEMString();
-}
-#endif
-
-bool AddSHA256SignatureAlgorithm(CBB* cbb, KeyType key_type) {
- // An AlgorithmIdentifier is described in RFC 5280, 4.1.1.2.
- CBB sequence, oid, params;
- if (!CBB_add_asn1(cbb, &sequence, CBS_ASN1_SEQUENCE) ||
- !CBB_add_asn1(&sequence, &oid, CBS_ASN1_OBJECT)) {
- return false;
- }
-
- switch (key_type) {
- case KT_RSA:
- if (!CBB_add_bytes(&oid, kSHA256WithRSAEncryption,
- sizeof(kSHA256WithRSAEncryption)) ||
- !CBB_add_asn1(&sequence, ¶ms, CBS_ASN1_NULL)) {
- return false;
- }
- break;
- case KT_ECDSA:
- if (!CBB_add_bytes(&oid, kECDSAWithSHA256, sizeof(kECDSAWithSHA256))) {
- return false;
- }
- break;
- default:
- RTC_NOTREACHED();
- return false;
- }
- if (!CBB_flush(cbb)) {
- return false;
- }
- return true;
-}
-
-// Adds an X.509 Common Name to |cbb|.
-bool AddCommonName(CBB* cbb, const std::string& common_name) {
- // See RFC 4519.
- static const uint8_t kCommonName[] = {0x55, 0x04, 0x03};
-
- if (common_name.empty()) {
- RTC_LOG(LS_ERROR) << "Common name cannot be empty.";
- return false;
- }
-
- // See RFC 5280, section 4.1.2.4.
- CBB rdns;
- if (!CBB_add_asn1(cbb, &rdns, CBS_ASN1_SEQUENCE)) {
- return false;
- }
-
- CBB rdn, attr, type, value;
- if (!CBB_add_asn1(&rdns, &rdn, CBS_ASN1_SET) ||
- !CBB_add_asn1(&rdn, &attr, CBS_ASN1_SEQUENCE) ||
- !CBB_add_asn1(&attr, &type, CBS_ASN1_OBJECT) ||
- !CBB_add_bytes(&type, kCommonName, sizeof(kCommonName)) ||
- !CBB_add_asn1(&attr, &value, CBS_ASN1_UTF8STRING) ||
- !CBB_add_bytes(&value,
- reinterpret_cast<const uint8_t*>(common_name.c_str()),
- common_name.size()) ||
- !CBB_flush(cbb)) {
- return false;
- }
-
- return true;
-}
-
-bool AddTime(CBB* cbb, time_t time) {
- bssl::UniquePtr<ASN1_TIME> asn1_time(ASN1_TIME_new());
- if (!asn1_time) {
- return false;
- }
-
- if (!ASN1_TIME_set(asn1_time.get(), time)) {
- return false;
- }
-
- unsigned tag;
- switch (asn1_time->type) {
- case V_ASN1_UTCTIME:
- tag = CBS_ASN1_UTCTIME;
- break;
- case V_ASN1_GENERALIZEDTIME:
- tag = CBS_ASN1_GENERALIZEDTIME;
- break;
- default:
- return false;
- }
-
- CBB child;
- if (!CBB_add_asn1(cbb, &child, tag) ||
- !CBB_add_bytes(&child, asn1_time->data, asn1_time->length) ||
- !CBB_flush(cbb)) {
- return false;
- }
-
- return true;
-}
-
-// Generate a self-signed certificate, with the public key from the
-// given key pair. Caller is responsible for freeing the returned object.
-static bssl::UniquePtr<CRYPTO_BUFFER> MakeCertificate(
- EVP_PKEY* pkey,
- const SSLIdentityParams& params) {
- RTC_LOG(LS_INFO) << "Making certificate for " << params.common_name;
-
- // See RFC 5280, section 4.1. First, construct the TBSCertificate.
- bssl::ScopedCBB cbb;
- CBB tbs_cert, version, validity;
- uint8_t* tbs_cert_bytes;
- size_t tbs_cert_len;
- uint64_t serial_number;
- if (!CBB_init(cbb.get(), 64) ||
- !CBB_add_asn1(cbb.get(), &tbs_cert, CBS_ASN1_SEQUENCE) ||
- !CBB_add_asn1(&tbs_cert, &version,
- CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
- !CBB_add_asn1_uint64(&version, 2) ||
- !RAND_bytes(reinterpret_cast<uint8_t*>(&serial_number),
- sizeof(serial_number)) ||
- !CBB_add_asn1_uint64(&tbs_cert, serial_number) ||
- !AddSHA256SignatureAlgorithm(&tbs_cert, params.key_params.type()) ||
- !AddCommonName(&tbs_cert, params.common_name) || // issuer
- !CBB_add_asn1(&tbs_cert, &validity, CBS_ASN1_SEQUENCE) ||
- !AddTime(&validity, params.not_before) ||
- !AddTime(&validity, params.not_after) ||
- !AddCommonName(&tbs_cert, params.common_name) || // subject
- !EVP_marshal_public_key(&tbs_cert, pkey) || // subjectPublicKeyInfo
- !CBB_finish(cbb.get(), &tbs_cert_bytes, &tbs_cert_len)) {
- return nullptr;
- }
-
- bssl::UniquePtr<uint8_t> delete_tbs_cert_bytes(tbs_cert_bytes);
-
- // Sign the TBSCertificate and write the entire certificate.
- CBB cert, signature;
- bssl::ScopedEVP_MD_CTX ctx;
- uint8_t* sig_out;
- size_t sig_len;
- uint8_t* cert_bytes;
- size_t cert_len;
- if (!CBB_init(cbb.get(), tbs_cert_len) ||
- !CBB_add_asn1(cbb.get(), &cert, CBS_ASN1_SEQUENCE) ||
- !CBB_add_bytes(&cert, tbs_cert_bytes, tbs_cert_len) ||
- !AddSHA256SignatureAlgorithm(&cert, params.key_params.type()) ||
- !CBB_add_asn1(&cert, &signature, CBS_ASN1_BITSTRING) ||
- !CBB_add_u8(&signature, 0 /* no unused bits */) ||
- !EVP_DigestSignInit(ctx.get(), nullptr, EVP_sha256(), nullptr, pkey) ||
- // Compute the maximum signature length.
- !EVP_DigestSign(ctx.get(), nullptr, &sig_len, tbs_cert_bytes,
- tbs_cert_len) ||
- !CBB_reserve(&signature, &sig_out, sig_len) ||
- // Actually sign the TBSCertificate.
- !EVP_DigestSign(ctx.get(), sig_out, &sig_len, tbs_cert_bytes,
- tbs_cert_len) ||
- !CBB_did_write(&signature, sig_len) ||
- !CBB_finish(cbb.get(), &cert_bytes, &cert_len)) {
- return nullptr;
- }
- bssl::UniquePtr<uint8_t> delete_cert_bytes(cert_bytes);
-
- RTC_LOG(LS_INFO) << "Returning certificate";
- return bssl::UniquePtr<CRYPTO_BUFFER>(
- CRYPTO_BUFFER_new(cert_bytes, cert_len, openssl::GetBufferPool()));
-}
-
-} // namespace
-
-BoringSSLCertificate::BoringSSLCertificate(
- bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer)
- : cert_buffer_(std::move(cert_buffer)) {
- RTC_DCHECK(cert_buffer_ != nullptr);
-}
-
-std::unique_ptr<BoringSSLCertificate> BoringSSLCertificate::Generate(
- OpenSSLKeyPair* key_pair,
- const SSLIdentityParams& params) {
- SSLIdentityParams actual_params(params);
- if (actual_params.common_name.empty()) {
- // Use a random string, arbitrarily 8 chars long.
- actual_params.common_name = CreateRandomString(8);
- }
- bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer =
- MakeCertificate(key_pair->pkey(), actual_params);
- if (!cert_buffer) {
- openssl::LogSSLErrors("Generating certificate");
- return nullptr;
- }
- auto ret = std::make_unique<BoringSSLCertificate>(std::move(cert_buffer));
-#if !defined(NDEBUG)
- PrintCert(ret.get());
-#endif
- return ret;
-}
-
-std::unique_ptr<BoringSSLCertificate> BoringSSLCertificate::FromPEMString(
- const std::string& pem_string) {
- std::string der;
- if (!SSLIdentity::PemToDer(kPemTypeCertificate, pem_string, &der)) {
- return nullptr;
- }
- bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer(
- CRYPTO_BUFFER_new(reinterpret_cast<const uint8_t*>(der.c_str()),
- der.length(), openssl::GetBufferPool()));
- if (!cert_buffer) {
- return nullptr;
- }
- return std::make_unique<BoringSSLCertificate>(std::move(cert_buffer));
-}
-
-#define OID_MATCHES(oid, oid_other) \
- (CBS_len(&oid) == sizeof(oid_other) && \
- 0 == memcmp(CBS_data(&oid), oid_other, sizeof(oid_other)))
-
-bool BoringSSLCertificate::GetSignatureDigestAlgorithm(
- std::string* algorithm) const {
- CBS oid;
- if (!openssl::ParseCertificate(cert_buffer_.get(), &oid, nullptr)) {
- RTC_LOG(LS_ERROR) << "Failed to parse certificate.";
- return false;
- }
- if (OID_MATCHES(oid, kMD5WithRSA) ||
- OID_MATCHES(oid, kMD5WithRSAEncryption)) {
- *algorithm = DIGEST_MD5;
- return true;
- }
- if (OID_MATCHES(oid, kECDSAWithSHA1) || OID_MATCHES(oid, kDSAWithSHA1) ||
- OID_MATCHES(oid, kDSAWithSHA1_2) || OID_MATCHES(oid, kSHA1WithRSA) ||
- OID_MATCHES(oid, kSHA1WithRSAEncryption)) {
- *algorithm = DIGEST_SHA_1;
- return true;
- }
- if (OID_MATCHES(oid, kECDSAWithSHA224) ||
- OID_MATCHES(oid, kSHA224WithRSAEncryption) ||
- OID_MATCHES(oid, kDSAWithSHA224)) {
- *algorithm = DIGEST_SHA_224;
- return true;
- }
- if (OID_MATCHES(oid, kECDSAWithSHA256) ||
- OID_MATCHES(oid, kSHA256WithRSAEncryption) ||
- OID_MATCHES(oid, kDSAWithSHA256)) {
- *algorithm = DIGEST_SHA_256;
- return true;
- }
- if (OID_MATCHES(oid, kECDSAWithSHA384) ||
- OID_MATCHES(oid, kSHA384WithRSAEncryption)) {
- *algorithm = DIGEST_SHA_384;
- return true;
- }
- if (OID_MATCHES(oid, kECDSAWithSHA512) ||
- OID_MATCHES(oid, kSHA512WithRSAEncryption)) {
- *algorithm = DIGEST_SHA_512;
- return true;
- }
- // Unknown algorithm. There are several unhandled options that are less
- // common and more complex.
- RTC_LOG(LS_ERROR) << "Unknown signature algorithm.";
- algorithm->clear();
- return false;
-}
-
-bool BoringSSLCertificate::ComputeDigest(const std::string& algorithm,
- unsigned char* digest,
- size_t size,
- size_t* length) const {
- return ComputeDigest(cert_buffer_.get(), algorithm, digest, size, length);
-}
-
-bool BoringSSLCertificate::ComputeDigest(const CRYPTO_BUFFER* cert_buffer,
- const std::string& algorithm,
- unsigned char* digest,
- size_t size,
- size_t* length) {
- const EVP_MD* md = nullptr;
- unsigned int n = 0;
- if (!OpenSSLDigest::GetDigestEVP(algorithm, &md)) {
- return false;
- }
- if (size < static_cast<size_t>(EVP_MD_size(md))) {
- return false;
- }
- if (!EVP_Digest(CRYPTO_BUFFER_data(cert_buffer),
- CRYPTO_BUFFER_len(cert_buffer), digest, &n, md, nullptr)) {
- return false;
- }
- *length = n;
- return true;
-}
-
-BoringSSLCertificate::~BoringSSLCertificate() {}
-
-std::unique_ptr<SSLCertificate> BoringSSLCertificate::Clone() const {
- return std::make_unique<BoringSSLCertificate>(
- bssl::UpRef(cert_buffer_.get()));
-}
-
-std::string BoringSSLCertificate::ToPEMString() const {
- return OpenSSLIdentity::DerToPem(kPemTypeCertificate,
- CRYPTO_BUFFER_data(cert_buffer_.get()),
- CRYPTO_BUFFER_len(cert_buffer_.get()));
-}
-
-void BoringSSLCertificate::ToDER(Buffer* der_buffer) const {
- der_buffer->SetData(CRYPTO_BUFFER_data(cert_buffer_.get()),
- CRYPTO_BUFFER_len(cert_buffer_.get()));
-}
-
-bool BoringSSLCertificate::operator==(const BoringSSLCertificate& other) const {
- return CRYPTO_BUFFER_len(cert_buffer_.get()) ==
- CRYPTO_BUFFER_len(other.cert_buffer_.get()) &&
- 0 == memcmp(CRYPTO_BUFFER_data(cert_buffer_.get()),
- CRYPTO_BUFFER_data(other.cert_buffer_.get()),
- CRYPTO_BUFFER_len(cert_buffer_.get()));
-}
-
-bool BoringSSLCertificate::operator!=(const BoringSSLCertificate& other) const {
- return !(*this == other);
-}
-
-int64_t BoringSSLCertificate::CertificateExpirationTime() const {
- int64_t ret;
- if (!openssl::ParseCertificate(cert_buffer_.get(), nullptr, &ret)) {
- RTC_LOG(LS_ERROR) << "Failed to parse certificate.";
- return -1;
- }
- return ret;
-}
-
-} // namespace rtc
diff --git a/rtc_base/boringssl_certificate.h b/rtc_base/boringssl_certificate.h
deleted file mode 100644
index 740763d..0000000
--- a/rtc_base/boringssl_certificate.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2020 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 RTC_BASE_BORINGSSL_CERTIFICATE_H_
-#define RTC_BASE_BORINGSSL_CERTIFICATE_H_
-
-#include <openssl/ossl_typ.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#include <memory>
-#include <string>
-
-#include "rtc_base/buffer.h"
-#include "rtc_base/constructor_magic.h"
-#include "rtc_base/ssl_certificate.h"
-#include "rtc_base/ssl_identity.h"
-
-namespace rtc {
-
-class OpenSSLKeyPair;
-
-// BoringSSLCertificate encapsulates a BoringSSL CRYPTO_BUFFER object holding a
-// certificate, which is also reference counted inside the BoringSSL library.
-// This offers binary size and memory improvements over the OpenSSL X509
-// object.
-class BoringSSLCertificate final : public SSLCertificate {
- public:
- explicit BoringSSLCertificate(bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer);
-
- static std::unique_ptr<BoringSSLCertificate> Generate(
- OpenSSLKeyPair* key_pair,
- const SSLIdentityParams& params);
- static std::unique_ptr<BoringSSLCertificate> FromPEMString(
- const std::string& pem_string);
-
- ~BoringSSLCertificate() override;
-
- std::unique_ptr<SSLCertificate> Clone() const override;
-
- CRYPTO_BUFFER* cert_buffer() const { return cert_buffer_.get(); }
-
- std::string ToPEMString() const override;
- void ToDER(Buffer* der_buffer) const override;
- bool operator==(const BoringSSLCertificate& other) const;
- bool operator!=(const BoringSSLCertificate& other) const;
-
- // Compute the digest of the certificate given |algorithm|.
- bool ComputeDigest(const std::string& algorithm,
- unsigned char* digest,
- size_t size,
- size_t* length) const override;
-
- // Compute the digest of a certificate as a CRYPTO_BUFFER.
- static bool ComputeDigest(const CRYPTO_BUFFER* cert_buffer,
- const std::string& algorithm,
- unsigned char* digest,
- size_t size,
- size_t* length);
-
- bool GetSignatureDigestAlgorithm(std::string* algorithm) const override;
-
- int64_t CertificateExpirationTime() const override;
-
- private:
- // A handle to the DER encoded certificate data.
- bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer_;
- RTC_DISALLOW_COPY_AND_ASSIGN(BoringSSLCertificate);
-};
-
-} // namespace rtc
-
-#endif // RTC_BASE_BORINGSSL_CERTIFICATE_H_
diff --git a/rtc_base/boringssl_identity.cc b/rtc_base/boringssl_identity.cc
deleted file mode 100644
index d22c8ce..0000000
--- a/rtc_base/boringssl_identity.cc
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright 2020 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 "rtc_base/boringssl_identity.h"
-
-#include <openssl/bio.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
-#include <openssl/pool.h>
-#include <stdint.h>
-#include <string.h>
-
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "absl/memory/memory.h"
-#include "rtc_base/checks.h"
-#include "rtc_base/logging.h"
-#include "rtc_base/numerics/safe_conversions.h"
-#include "rtc_base/openssl.h"
-#include "rtc_base/openssl_utility.h"
-
-namespace rtc {
-
-BoringSSLIdentity::BoringSSLIdentity(
- std::unique_ptr<OpenSSLKeyPair> key_pair,
- std::unique_ptr<BoringSSLCertificate> certificate)
- : key_pair_(std::move(key_pair)) {
- RTC_DCHECK(key_pair_ != nullptr);
- RTC_DCHECK(certificate != nullptr);
- std::vector<std::unique_ptr<SSLCertificate>> certs;
- certs.push_back(std::move(certificate));
- cert_chain_.reset(new SSLCertChain(std::move(certs)));
-}
-
-BoringSSLIdentity::BoringSSLIdentity(std::unique_ptr<OpenSSLKeyPair> key_pair,
- std::unique_ptr<SSLCertChain> cert_chain)
- : key_pair_(std::move(key_pair)), cert_chain_(std::move(cert_chain)) {
- RTC_DCHECK(key_pair_ != nullptr);
- RTC_DCHECK(cert_chain_ != nullptr);
-}
-
-BoringSSLIdentity::~BoringSSLIdentity() = default;
-
-std::unique_ptr<BoringSSLIdentity> BoringSSLIdentity::CreateInternal(
- const SSLIdentityParams& params) {
- auto key_pair = OpenSSLKeyPair::Generate(params.key_params);
- if (key_pair) {
- std::unique_ptr<BoringSSLCertificate> certificate(
- BoringSSLCertificate::Generate(key_pair.get(), params));
- if (certificate != nullptr) {
- return absl::WrapUnique(
- new BoringSSLIdentity(std::move(key_pair), std::move(certificate)));
- }
- }
- RTC_LOG(LS_ERROR) << "Identity generation failed.";
- return nullptr;
-}
-
-// static
-std::unique_ptr<BoringSSLIdentity> BoringSSLIdentity::CreateWithExpiration(
- const std::string& common_name,
- const KeyParams& key_params,
- time_t certificate_lifetime) {
- SSLIdentityParams params;
- params.key_params = key_params;
- params.common_name = common_name;
- time_t now = time(nullptr);
- params.not_before = now + kCertificateWindowInSeconds;
- params.not_after = now + certificate_lifetime;
- if (params.not_before > params.not_after)
- return nullptr;
- return CreateInternal(params);
-}
-
-std::unique_ptr<BoringSSLIdentity> BoringSSLIdentity::CreateForTest(
- const SSLIdentityParams& params) {
- return CreateInternal(params);
-}
-
-std::unique_ptr<SSLIdentity> BoringSSLIdentity::CreateFromPEMStrings(
- const std::string& private_key,
- const std::string& certificate) {
- std::unique_ptr<BoringSSLCertificate> cert(
- BoringSSLCertificate::FromPEMString(certificate));
- if (!cert) {
- RTC_LOG(LS_ERROR)
- << "Failed to create BoringSSLCertificate from PEM string.";
- return nullptr;
- }
-
- auto key_pair = OpenSSLKeyPair::FromPrivateKeyPEMString(private_key);
- if (!key_pair) {
- RTC_LOG(LS_ERROR) << "Failed to create key pair from PEM string.";
- return nullptr;
- }
-
- return absl::WrapUnique(
- new BoringSSLIdentity(std::move(key_pair), std::move(cert)));
-}
-
-std::unique_ptr<SSLIdentity> BoringSSLIdentity::CreateFromPEMChainStrings(
- const std::string& private_key,
- const std::string& certificate_chain) {
- bssl::UniquePtr<BIO> bio(
- BIO_new_mem_buf(certificate_chain.data(),
- rtc::dchecked_cast<int>(certificate_chain.size())));
- if (!bio) {
- return nullptr;
- }
- BIO_set_mem_eof_return(bio.get(), 0);
- std::vector<std::unique_ptr<SSLCertificate>> certs;
- while (true) {
- char* name;
- char* header;
- unsigned char* data;
- long len; // NOLINT
- int ret = PEM_read_bio(bio.get(), &name, &header, &data, &len);
- if (ret == 0) {
- uint32_t err = ERR_peek_error();
- if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
- ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
- break;
- }
- RTC_LOG(LS_ERROR) << "Failed to parse certificate from PEM string.";
- return nullptr;
- }
- bssl::UniquePtr<char> owned_name(name);
- bssl::UniquePtr<char> owned_header(header);
- bssl::UniquePtr<unsigned char> owned_data(data);
- if (strcmp(owned_name.get(), PEM_STRING_X509) != 0) {
- RTC_LOG(LS_ERROR)
- << "Non-certificate found while parsing certificate chain: "
- << owned_name.get();
- return nullptr;
- }
- bssl::UniquePtr<CRYPTO_BUFFER> crypto_buffer(
- CRYPTO_BUFFER_new(data, len, openssl::GetBufferPool()));
- if (!crypto_buffer) {
- return nullptr;
- }
- certs.emplace_back(new BoringSSLCertificate(std::move(crypto_buffer)));
- }
- if (certs.empty()) {
- RTC_LOG(LS_ERROR) << "Found no certificates in PEM string.";
- return nullptr;
- }
-
- auto key_pair = OpenSSLKeyPair::FromPrivateKeyPEMString(private_key);
- if (!key_pair) {
- RTC_LOG(LS_ERROR) << "Failed to create key pair from PEM string.";
- return nullptr;
- }
-
- return absl::WrapUnique(new BoringSSLIdentity(
- std::move(key_pair), std::make_unique<SSLCertChain>(std::move(certs))));
-}
-
-const BoringSSLCertificate& BoringSSLIdentity::certificate() const {
- return *static_cast<const BoringSSLCertificate*>(&cert_chain_->Get(0));
-}
-
-const SSLCertChain& BoringSSLIdentity::cert_chain() const {
- return *cert_chain_.get();
-}
-
-std::unique_ptr<SSLIdentity> BoringSSLIdentity::CloneInternal() const {
- // We cannot use std::make_unique here because the referenced
- // BoringSSLIdentity constructor is private.
- return absl::WrapUnique(
- new BoringSSLIdentity(key_pair_->Clone(), cert_chain_->Clone()));
-}
-
-bool BoringSSLIdentity::ConfigureIdentity(SSL_CTX* ctx) {
- std::vector<CRYPTO_BUFFER*> cert_buffers;
- for (size_t i = 0; i < cert_chain_->GetSize(); ++i) {
- cert_buffers.push_back(
- static_cast<const BoringSSLCertificate*>(&cert_chain_->Get(i))
- ->cert_buffer());
- }
- // 1 is the documented success return code.
- if (1 != SSL_CTX_set_chain_and_key(ctx, &cert_buffers[0], cert_buffers.size(),
- key_pair_->pkey(), nullptr)) {
- openssl::LogSSLErrors("Configuring key and certificate");
- return false;
- }
- return true;
-}
-
-std::string BoringSSLIdentity::PrivateKeyToPEMString() const {
- return key_pair_->PrivateKeyToPEMString();
-}
-
-std::string BoringSSLIdentity::PublicKeyToPEMString() const {
- return key_pair_->PublicKeyToPEMString();
-}
-
-bool BoringSSLIdentity::operator==(const BoringSSLIdentity& other) const {
- return *this->key_pair_ == *other.key_pair_ &&
- this->certificate() == other.certificate();
-}
-
-bool BoringSSLIdentity::operator!=(const BoringSSLIdentity& other) const {
- return !(*this == other);
-}
-
-} // namespace rtc
diff --git a/rtc_base/boringssl_identity.h b/rtc_base/boringssl_identity.h
deleted file mode 100644
index 71b29b4..0000000
--- a/rtc_base/boringssl_identity.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2020 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 RTC_BASE_BORINGSSL_IDENTITY_H_
-#define RTC_BASE_BORINGSSL_IDENTITY_H_
-
-#include <openssl/ossl_typ.h>
-
-#include <ctime>
-#include <memory>
-#include <string>
-
-#include "rtc_base/boringssl_certificate.h"
-#include "rtc_base/constructor_magic.h"
-#include "rtc_base/openssl_key_pair.h"
-#include "rtc_base/ssl_certificate.h"
-#include "rtc_base/ssl_identity.h"
-
-namespace rtc {
-
-// Holds a keypair and certificate together, and a method to generate them
-// consistently. Uses CRYPTO_BUFFER instead of X509, which offers binary size
-// and memory improvements.
-class BoringSSLIdentity final : public SSLIdentity {
- public:
- static std::unique_ptr<BoringSSLIdentity> CreateWithExpiration(
- const std::string& common_name,
- const KeyParams& key_params,
- time_t certificate_lifetime);
- static std::unique_ptr<BoringSSLIdentity> CreateForTest(
- const SSLIdentityParams& params);
- static std::unique_ptr<SSLIdentity> CreateFromPEMStrings(
- const std::string& private_key,
- const std::string& certificate);
- static std::unique_ptr<SSLIdentity> CreateFromPEMChainStrings(
- const std::string& private_key,
- const std::string& certificate_chain);
- ~BoringSSLIdentity() override;
-
- const BoringSSLCertificate& certificate() const override;
- const SSLCertChain& cert_chain() const override;
-
- // Configure an SSL context object to use our key and certificate.
- bool ConfigureIdentity(SSL_CTX* ctx);
-
- std::string PrivateKeyToPEMString() const override;
- std::string PublicKeyToPEMString() const override;
- bool operator==(const BoringSSLIdentity& other) const;
- bool operator!=(const BoringSSLIdentity& other) const;
-
- private:
- BoringSSLIdentity(std::unique_ptr<OpenSSLKeyPair> key_pair,
- std::unique_ptr<BoringSSLCertificate> certificate);
- BoringSSLIdentity(std::unique_ptr<OpenSSLKeyPair> key_pair,
- std::unique_ptr<SSLCertChain> cert_chain);
- std::unique_ptr<SSLIdentity> CloneInternal() const override;
-
- static std::unique_ptr<BoringSSLIdentity> CreateInternal(
- const SSLIdentityParams& params);
-
- std::unique_ptr<OpenSSLKeyPair> key_pair_;
- std::unique_ptr<SSLCertChain> cert_chain_;
-
- RTC_DISALLOW_COPY_AND_ASSIGN(BoringSSLIdentity);
-};
-
-} // namespace rtc
-
-#endif // RTC_BASE_BORINGSSL_IDENTITY_H_
diff --git a/rtc_base/openssl_adapter.cc b/rtc_base/openssl_adapter.cc
index e5c2c42..8fd882c 100644
--- a/rtc_base/openssl_adapter.cc
+++ b/rtc_base/openssl_adapter.cc
@@ -13,9 +13,6 @@
#include <errno.h>
#include <openssl/bio.h>
#include <openssl/err.h>
-#ifdef OPENSSL_IS_BORINGSSL
-#include <openssl/pool.h>
-#endif
#include <openssl/rand.h>
#include <openssl/x509.h>
#include <string.h>
@@ -23,24 +20,13 @@
#include <memory>
-// Use CRYPTO_BUFFER APIs if available and we have no dependency on X509
-// objects.
-#if defined(OPENSSL_IS_BORINGSSL) && \
- defined(WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS)
-#define WEBRTC_USE_CRYPTO_BUFFER_CALLBACK
-#endif
-
#include "absl/memory/memory.h"
#include "rtc_base/checks.h"
#include "rtc_base/location.h"
#include "rtc_base/logging.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/openssl.h"
-#ifdef OPENSSL_IS_BORINGSSL
-#include "rtc_base/boringssl_identity.h"
-#else
-#include "rtc_base/openssl_identity.h"
-#endif
+#include "rtc_base/openssl_certificate.h"
#include "rtc_base/openssl_utility.h"
#include "rtc_base/string_encode.h"
#include "rtc_base/thread.h"
@@ -237,13 +223,8 @@
void OpenSSLAdapter::SetIdentity(std::unique_ptr<SSLIdentity> identity) {
RTC_DCHECK(!identity_);
-#ifdef OPENSSL_IS_BORINGSSL
- identity_ =
- absl::WrapUnique(static_cast<BoringSSLIdentity*>(identity.release()));
-#else
identity_ =
absl::WrapUnique(static_cast<OpenSSLIdentity*>(identity.release()));
-#endif
}
void OpenSSLAdapter::SetRole(SSLRole role) {
@@ -816,70 +797,7 @@
#endif
-#ifdef WEBRTC_USE_CRYPTO_BUFFER_CALLBACK
-// static
-enum ssl_verify_result_t OpenSSLAdapter::SSLVerifyCallback(SSL* ssl,
- uint8_t* out_alert) {
- // Get our stream pointer from the SSL context.
- OpenSSLAdapter* stream =
- reinterpret_cast<OpenSSLAdapter*>(SSL_get_app_data(ssl));
-
- ssl_verify_result_t ret = stream->SSLVerifyInternal(ssl, out_alert);
-
- // Should only be used for debugging and development.
- if (ret != ssl_verify_ok && stream->ignore_bad_cert_) {
- RTC_DLOG(LS_WARNING) << "Ignoring cert error while verifying cert chain";
- return ssl_verify_ok;
- }
-
- return ret;
-}
-
-enum ssl_verify_result_t OpenSSLAdapter::SSLVerifyInternal(SSL* ssl,
- uint8_t* out_alert) {
- if (ssl_cert_verifier_ == nullptr) {
- RTC_LOG(LS_WARNING) << "Built-in trusted root certificates disabled but no "
- "SSL verify callback provided.";
- return ssl_verify_invalid;
- }
-
- RTC_LOG(LS_INFO) << "Invoking SSL Verify Callback.";
- const STACK_OF(CRYPTO_BUFFER)* chain = SSL_get0_peer_certificates(ssl);
- if (sk_CRYPTO_BUFFER_num(chain) == 0) {
- RTC_LOG(LS_ERROR) << "Peer certificate chain empty?";
- return ssl_verify_invalid;
- }
-
- BoringSSLCertificate cert(bssl::UpRef(sk_CRYPTO_BUFFER_value(chain, 0)));
- if (!ssl_cert_verifier_->Verify(cert)) {
- RTC_LOG(LS_WARNING) << "Failed to verify certificate using custom callback";
- return ssl_verify_invalid;
- }
-
- custom_cert_verifier_status_ = true;
- RTC_LOG(LS_INFO) << "Validated certificate using custom callback";
- return ssl_verify_ok;
-}
-#else // WEBRTC_USE_CRYPTO_BUFFER_CALLBACK
int OpenSSLAdapter::SSLVerifyCallback(int ok, X509_STORE_CTX* store) {
- // Get our stream pointer from the store
- SSL* ssl = reinterpret_cast<SSL*>(
- X509_STORE_CTX_get_ex_data(store, SSL_get_ex_data_X509_STORE_CTX_idx()));
-
- OpenSSLAdapter* stream =
- reinterpret_cast<OpenSSLAdapter*>(SSL_get_app_data(ssl));
- ok = stream->SSLVerifyInternal(ok, ssl, store);
-
- // Should only be used for debugging and development.
- if (!ok && stream->ignore_bad_cert_) {
- RTC_DLOG(LS_WARNING) << "Ignoring cert error while verifying cert chain";
- return 1;
- }
-
- return ok;
-}
-
-int OpenSSLAdapter::SSLVerifyInternal(int ok, SSL* ssl, X509_STORE_CTX* store) {
#if !defined(NDEBUG)
if (!ok) {
char data[256];
@@ -896,40 +814,33 @@
<< X509_verify_cert_error_string(err);
}
#endif
- if (ssl_cert_verifier_ == nullptr) {
- return ok;
+ // Get our stream pointer from the store
+ SSL* ssl = reinterpret_cast<SSL*>(
+ X509_STORE_CTX_get_ex_data(store, SSL_get_ex_data_X509_STORE_CTX_idx()));
+
+ OpenSSLAdapter* stream =
+ reinterpret_cast<OpenSSLAdapter*>(SSL_get_app_data(ssl));
+
+ if (!ok && stream->ssl_cert_verifier_ != nullptr) {
+ RTC_LOG(LS_INFO) << "Invoking SSL Verify Callback.";
+ const OpenSSLCertificate cert(X509_STORE_CTX_get_current_cert(store));
+ if (stream->ssl_cert_verifier_->Verify(cert)) {
+ stream->custom_cert_verifier_status_ = true;
+ RTC_LOG(LS_INFO) << "Validated certificate using custom callback";
+ ok = true;
+ } else {
+ RTC_LOG(LS_INFO) << "Failed to verify certificate using custom callback";
+ }
}
- RTC_LOG(LS_INFO) << "Invoking SSL Verify Callback.";
-#ifdef OPENSSL_IS_BORINGSSL
- // Convert X509 to CRYPTO_BUFFER.
- uint8_t* data = nullptr;
- int length = i2d_X509(X509_STORE_CTX_get_current_cert(store), &data);
- if (length < 0) {
- RTC_LOG(LS_ERROR) << "Failed to encode X509.";
- return ok;
- }
- bssl::UniquePtr<uint8_t> owned_data(data);
- bssl::UniquePtr<CRYPTO_BUFFER> crypto_buffer(
- CRYPTO_BUFFER_new(data, length, openssl::GetBufferPool()));
- if (!crypto_buffer) {
- RTC_LOG(LS_ERROR) << "Failed to allocate CRYPTO_BUFFER.";
- return ok;
- }
- const BoringSSLCertificate cert(std::move(crypto_buffer));
-#else
- const OpenSSLCertificate cert(X509_STORE_CTX_get_current_cert(store));
-#endif
- if (!ssl_cert_verifier_->Verify(cert)) {
- RTC_LOG(LS_INFO) << "Failed to verify certificate using custom callback";
- return ok;
+ // Should only be used for debugging and development.
+ if (!ok && stream->ignore_bad_cert_) {
+ RTC_DLOG(LS_WARNING) << "Ignoring cert error while verifying cert chain";
+ ok = 1;
}
- custom_cert_verifier_status_ = true;
- RTC_LOG(LS_INFO) << "Validated certificate using custom callback";
- return 1;
+ return ok;
}
-#endif // !defined(WEBRTC_USE_CRYPTO_BUFFER_CALLBACK)
int OpenSSLAdapter::NewSSLSessionCallback(SSL* ssl, SSL_SESSION* session) {
OpenSSLAdapter* stream =
@@ -941,15 +852,8 @@
}
SSL_CTX* OpenSSLAdapter::CreateContext(SSLMode mode, bool enable_cache) {
-#ifdef WEBRTC_USE_CRYPTO_BUFFER_CALLBACK
- // If X509 objects aren't used, we can use these methods to avoid
- // linking the sizable crypto/x509 code.
- SSL_CTX* ctx = SSL_CTX_new(mode == SSL_MODE_DTLS ? DTLS_with_buffers_method()
- : TLS_with_buffers_method());
-#else
SSL_CTX* ctx =
SSL_CTX_new(mode == SSL_MODE_DTLS ? DTLS_method() : TLS_method());
-#endif
if (ctx == nullptr) {
unsigned long error = ERR_get_error(); // NOLINT: type used by OpenSSL.
RTC_LOG(LS_WARNING) << "SSL_CTX creation failed: " << '"'
@@ -973,16 +877,8 @@
SSL_CTX_set_info_callback(ctx, SSLInfoCallback);
#endif
-#ifdef OPENSSL_IS_BORINGSSL
- SSL_CTX_set0_buffer_pool(ctx, openssl::GetBufferPool());
-#endif
-
-#ifdef WEBRTC_USE_CRYPTO_BUFFER_CALLBACK
- SSL_CTX_set_custom_verify(ctx, SSL_VERIFY_PEER, SSLVerifyCallback);
-#else
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, SSLVerifyCallback);
SSL_CTX_set_verify_depth(ctx, 4);
-#endif
// Use defaults, but disable HMAC-SHA256 and HMAC-SHA384 ciphers
// (note that SHA256 and SHA384 only select legacy CBC ciphers).
// Additionally disable HMAC-SHA1 ciphers in ECDSA. These are the remaining
diff --git a/rtc_base/openssl_adapter.h b/rtc_base/openssl_adapter.h
index 76b003a..6f1f7dc 100644
--- a/rtc_base/openssl_adapter.h
+++ b/rtc_base/openssl_adapter.h
@@ -11,7 +11,6 @@
#ifndef RTC_BASE_OPENSSL_ADAPTER_H_
#define RTC_BASE_OPENSSL_ADAPTER_H_
-#include <openssl/ossl_typ.h>
#include <stddef.h>
#include <stdint.h>
@@ -22,11 +21,7 @@
#include "rtc_base/async_socket.h"
#include "rtc_base/buffer.h"
#include "rtc_base/message_handler.h"
-#ifdef OPENSSL_IS_BORINGSSL
-#include "rtc_base/boringssl_identity.h"
-#else
#include "rtc_base/openssl_identity.h"
-#endif
#include "rtc_base/openssl_session_cache.h"
#include "rtc_base/socket.h"
#include "rtc_base/socket_address.h"
@@ -114,16 +109,7 @@
// In debug builds, logs info about the state of the SSL connection.
static void SSLInfoCallback(const SSL* ssl, int where, int ret);
#endif
-
-#if defined(OPENSSL_IS_BORINGSSL) && \
- defined(WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS)
- static enum ssl_verify_result_t SSLVerifyCallback(SSL* ssl,
- uint8_t* out_alert);
- enum ssl_verify_result_t SSLVerifyInternal(SSL* ssl, uint8_t* out_alert);
-#else
static int SSLVerifyCallback(int ok, X509_STORE_CTX* store);
- int SSLVerifyInternal(int ok, SSL* ssl, X509_STORE_CTX* store);
-#endif
friend class OpenSSLStreamAdapter; // for custom_verify_callback_;
// If the SSL_CTX was created with |enable_cache| set to true, this callback
@@ -137,12 +123,7 @@
SSLCertificateVerifier* ssl_cert_verifier_ = nullptr;
// The current connection state of the (d)TLS connection.
SSLState state_;
-
-#ifdef OPENSSL_IS_BORINGSSL
- std::unique_ptr<BoringSSLIdentity> identity_;
-#else
std::unique_ptr<OpenSSLIdentity> identity_;
-#endif
// Indicates whethere this is a client or a server.
SSLRole role_;
bool ssl_read_needs_write_;
diff --git a/rtc_base/openssl_identity.cc b/rtc_base/openssl_identity.cc
index 3794d98..c94df40 100644
--- a/rtc_base/openssl_identity.cc
+++ b/rtc_base/openssl_identity.cc
@@ -20,8 +20,10 @@
#endif // WEBRTC_WIN
#include <openssl/bio.h>
+#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/pem.h>
+#include <openssl/rsa.h>
#include <stdint.h>
#include "absl/memory/memory.h"
@@ -33,6 +35,160 @@
namespace rtc {
+// We could have exposed a myriad of parameters for the crypto stuff,
+// but keeping it simple seems best.
+
+// Generate a key pair. Caller is responsible for freeing the returned object.
+static EVP_PKEY* MakeKey(const KeyParams& key_params) {
+ RTC_LOG(LS_INFO) << "Making key pair";
+ EVP_PKEY* pkey = EVP_PKEY_new();
+ if (key_params.type() == KT_RSA) {
+ int key_length = key_params.rsa_params().mod_size;
+ BIGNUM* exponent = BN_new();
+ RSA* rsa = RSA_new();
+ if (!pkey || !exponent || !rsa ||
+ !BN_set_word(exponent, key_params.rsa_params().pub_exp) ||
+ !RSA_generate_key_ex(rsa, key_length, exponent, nullptr) ||
+ !EVP_PKEY_assign_RSA(pkey, rsa)) {
+ EVP_PKEY_free(pkey);
+ BN_free(exponent);
+ RSA_free(rsa);
+ RTC_LOG(LS_ERROR) << "Failed to make RSA key pair";
+ return nullptr;
+ }
+ // ownership of rsa struct was assigned, don't free it.
+ BN_free(exponent);
+ } else if (key_params.type() == KT_ECDSA) {
+ if (key_params.ec_curve() == EC_NIST_P256) {
+ EC_KEY* ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+
+ // Ensure curve name is included when EC key is serialized.
+ // Without this call, OpenSSL versions before 1.1.0 will create
+ // certificates that don't work for TLS.
+ // This is a no-op for BoringSSL and OpenSSL 1.1.0+
+ EC_KEY_set_asn1_flag(ec_key, OPENSSL_EC_NAMED_CURVE);
+
+ if (!pkey || !ec_key || !EC_KEY_generate_key(ec_key) ||
+ !EVP_PKEY_assign_EC_KEY(pkey, ec_key)) {
+ EVP_PKEY_free(pkey);
+ EC_KEY_free(ec_key);
+ RTC_LOG(LS_ERROR) << "Failed to make EC key pair";
+ return nullptr;
+ }
+ // ownership of ec_key struct was assigned, don't free it.
+ } else {
+ // Add generation of any other curves here.
+ EVP_PKEY_free(pkey);
+ RTC_LOG(LS_ERROR) << "ECDSA key requested for unknown curve";
+ return nullptr;
+ }
+ } else {
+ EVP_PKEY_free(pkey);
+ RTC_LOG(LS_ERROR) << "Key type requested not understood";
+ return nullptr;
+ }
+
+ RTC_LOG(LS_INFO) << "Returning key pair";
+ return pkey;
+}
+
+OpenSSLKeyPair* OpenSSLKeyPair::Generate(const KeyParams& key_params) {
+ EVP_PKEY* pkey = MakeKey(key_params);
+ if (!pkey) {
+ openssl::LogSSLErrors("Generating key pair");
+ return nullptr;
+ }
+ return new OpenSSLKeyPair(pkey);
+}
+
+OpenSSLKeyPair* OpenSSLKeyPair::FromPrivateKeyPEMString(
+ const std::string& pem_string) {
+ BIO* bio = BIO_new_mem_buf(const_cast<char*>(pem_string.c_str()), -1);
+ if (!bio) {
+ RTC_LOG(LS_ERROR) << "Failed to create a new BIO buffer.";
+ return nullptr;
+ }
+ BIO_set_mem_eof_return(bio, 0);
+ EVP_PKEY* pkey =
+ PEM_read_bio_PrivateKey(bio, nullptr, nullptr, const_cast<char*>("\0"));
+ BIO_free(bio); // Frees the BIO, but not the pointed-to string.
+ if (!pkey) {
+ RTC_LOG(LS_ERROR) << "Failed to create the private key from PEM string.";
+ return nullptr;
+ }
+ if (EVP_PKEY_missing_parameters(pkey) != 0) {
+ RTC_LOG(LS_ERROR)
+ << "The resulting key pair is missing public key parameters.";
+ EVP_PKEY_free(pkey);
+ return nullptr;
+ }
+ return new OpenSSLKeyPair(pkey);
+}
+
+OpenSSLKeyPair::~OpenSSLKeyPair() {
+ EVP_PKEY_free(pkey_);
+}
+
+OpenSSLKeyPair* OpenSSLKeyPair::GetReference() {
+ AddReference();
+ return new OpenSSLKeyPair(pkey_);
+}
+
+void OpenSSLKeyPair::AddReference() {
+ EVP_PKEY_up_ref(pkey_);
+}
+
+std::string OpenSSLKeyPair::PrivateKeyToPEMString() const {
+ BIO* temp_memory_bio = BIO_new(BIO_s_mem());
+ if (!temp_memory_bio) {
+ RTC_LOG_F(LS_ERROR) << "Failed to allocate temporary memory bio";
+ RTC_NOTREACHED();
+ return "";
+ }
+ if (!PEM_write_bio_PrivateKey(temp_memory_bio, pkey_, nullptr, nullptr, 0,
+ nullptr, nullptr)) {
+ RTC_LOG_F(LS_ERROR) << "Failed to write private key";
+ BIO_free(temp_memory_bio);
+ RTC_NOTREACHED();
+ return "";
+ }
+ BIO_write(temp_memory_bio, "\0", 1);
+ char* buffer;
+ BIO_get_mem_data(temp_memory_bio, &buffer);
+ std::string priv_key_str = buffer;
+ BIO_free(temp_memory_bio);
+ return priv_key_str;
+}
+
+std::string OpenSSLKeyPair::PublicKeyToPEMString() const {
+ BIO* temp_memory_bio = BIO_new(BIO_s_mem());
+ if (!temp_memory_bio) {
+ RTC_LOG_F(LS_ERROR) << "Failed to allocate temporary memory bio";
+ RTC_NOTREACHED();
+ return "";
+ }
+ if (!PEM_write_bio_PUBKEY(temp_memory_bio, pkey_)) {
+ RTC_LOG_F(LS_ERROR) << "Failed to write public key";
+ BIO_free(temp_memory_bio);
+ RTC_NOTREACHED();
+ return "";
+ }
+ BIO_write(temp_memory_bio, "\0", 1);
+ char* buffer;
+ BIO_get_mem_data(temp_memory_bio, &buffer);
+ std::string pub_key_str = buffer;
+ BIO_free(temp_memory_bio);
+ return pub_key_str;
+}
+
+bool OpenSSLKeyPair::operator==(const OpenSSLKeyPair& other) const {
+ return EVP_PKEY_cmp(this->pkey_, other.pkey_) == 1;
+}
+
+bool OpenSSLKeyPair::operator!=(const OpenSSLKeyPair& other) const {
+ return !(*this == other);
+}
+
OpenSSLIdentity::OpenSSLIdentity(
std::unique_ptr<OpenSSLKeyPair> key_pair,
std::unique_ptr<OpenSSLCertificate> certificate)
@@ -55,7 +211,8 @@
std::unique_ptr<OpenSSLIdentity> OpenSSLIdentity::CreateInternal(
const SSLIdentityParams& params) {
- auto key_pair = OpenSSLKeyPair::Generate(params.key_params);
+ std::unique_ptr<OpenSSLKeyPair> key_pair(
+ OpenSSLKeyPair::Generate(params.key_params));
if (key_pair) {
std::unique_ptr<OpenSSLCertificate> certificate(
OpenSSLCertificate::Generate(key_pair.get(), params));
@@ -64,7 +221,7 @@
new OpenSSLIdentity(std::move(key_pair), std::move(certificate)));
}
}
- RTC_LOG(LS_ERROR) << "Identity generation failed";
+ RTC_LOG(LS_INFO) << "Identity generation failed";
return nullptr;
}
@@ -99,7 +256,8 @@
return nullptr;
}
- auto key_pair = OpenSSLKeyPair::FromPrivateKeyPEMString(private_key);
+ std::unique_ptr<OpenSSLKeyPair> key_pair(
+ OpenSSLKeyPair::FromPrivateKeyPEMString(private_key));
if (!key_pair) {
RTC_LOG(LS_ERROR) << "Failed to create key pair from PEM string.";
return nullptr;
@@ -140,7 +298,8 @@
return nullptr;
}
- auto key_pair = OpenSSLKeyPair::FromPrivateKeyPEMString(private_key);
+ std::unique_ptr<OpenSSLKeyPair> key_pair(
+ OpenSSLKeyPair::FromPrivateKeyPEMString(private_key));
if (!key_pair) {
RTC_LOG(LS_ERROR) << "Failed to create key pair from PEM string.";
return nullptr;
@@ -161,8 +320,8 @@
std::unique_ptr<SSLIdentity> OpenSSLIdentity::CloneInternal() const {
// We cannot use std::make_unique here because the referenced OpenSSLIdentity
// constructor is private.
- return absl::WrapUnique(
- new OpenSSLIdentity(key_pair_->Clone(), cert_chain_->Clone()));
+ return absl::WrapUnique(new OpenSSLIdentity(
+ absl::WrapUnique(key_pair_->GetReference()), cert_chain_->Clone()));
}
bool OpenSSLIdentity::ConfigureIdentity(SSL_CTX* ctx) {
diff --git a/rtc_base/openssl_identity.h b/rtc_base/openssl_identity.h
index 00d6c74..a2ac87c 100644
--- a/rtc_base/openssl_identity.h
+++ b/rtc_base/openssl_identity.h
@@ -17,14 +17,45 @@
#include <memory>
#include <string>
+#include "rtc_base/checks.h"
#include "rtc_base/constructor_magic.h"
#include "rtc_base/openssl_certificate.h"
-#include "rtc_base/openssl_key_pair.h"
#include "rtc_base/ssl_certificate.h"
#include "rtc_base/ssl_identity.h"
namespace rtc {
+// OpenSSLKeyPair encapsulates an OpenSSL EVP_PKEY* keypair object,
+// which is reference counted inside the OpenSSL library.
+class OpenSSLKeyPair final {
+ public:
+ explicit OpenSSLKeyPair(EVP_PKEY* pkey) : pkey_(pkey) {
+ RTC_DCHECK(pkey_ != nullptr);
+ }
+
+ static OpenSSLKeyPair* Generate(const KeyParams& key_params);
+ // Constructs a key pair from the private key PEM string. This must not result
+ // in missing public key parameters. Returns null on error.
+ static OpenSSLKeyPair* FromPrivateKeyPEMString(const std::string& pem_string);
+
+ virtual ~OpenSSLKeyPair();
+
+ virtual OpenSSLKeyPair* GetReference();
+
+ EVP_PKEY* pkey() const { return pkey_; }
+ std::string PrivateKeyToPEMString() const;
+ std::string PublicKeyToPEMString() const;
+ bool operator==(const OpenSSLKeyPair& other) const;
+ bool operator!=(const OpenSSLKeyPair& other) const;
+
+ private:
+ void AddReference();
+
+ EVP_PKEY* pkey_;
+
+ RTC_DISALLOW_COPY_AND_ASSIGN(OpenSSLKeyPair);
+};
+
// Holds a keypair and certificate together, and a method to generate
// them consistently.
class OpenSSLIdentity final : public SSLIdentity {
diff --git a/rtc_base/openssl_key_pair.cc b/rtc_base/openssl_key_pair.cc
deleted file mode 100644
index 911a751..0000000
--- a/rtc_base/openssl_key_pair.cc
+++ /dev/null
@@ -1,192 +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 "rtc_base/openssl_key_pair.h"
-
-#include <memory>
-#include <utility>
-
-#if defined(WEBRTC_WIN)
-// Must be included first before openssl headers.
-#include "rtc_base/win32.h" // NOLINT
-#endif // WEBRTC_WIN
-
-#include <openssl/bio.h>
-#include <openssl/bn.h>
-#include <openssl/pem.h>
-#include <openssl/rsa.h>
-
-#include "rtc_base/checks.h"
-#include "rtc_base/logging.h"
-#include "rtc_base/openssl.h"
-#include "rtc_base/openssl_utility.h"
-
-namespace rtc {
-
-// We could have exposed a myriad of parameters for the crypto stuff,
-// but keeping it simple seems best.
-
-// Generate a key pair. Caller is responsible for freeing the returned object.
-static EVP_PKEY* MakeKey(const KeyParams& key_params) {
- RTC_LOG(LS_INFO) << "Making key pair";
- EVP_PKEY* pkey = EVP_PKEY_new();
- if (key_params.type() == KT_RSA) {
- int key_length = key_params.rsa_params().mod_size;
- BIGNUM* exponent = BN_new();
- RSA* rsa = RSA_new();
- if (!pkey || !exponent || !rsa ||
- !BN_set_word(exponent, key_params.rsa_params().pub_exp) ||
- !RSA_generate_key_ex(rsa, key_length, exponent, nullptr) ||
- !EVP_PKEY_assign_RSA(pkey, rsa)) {
- EVP_PKEY_free(pkey);
- BN_free(exponent);
- RSA_free(rsa);
- RTC_LOG(LS_ERROR) << "Failed to make RSA key pair";
- return nullptr;
- }
- // ownership of rsa struct was assigned, don't free it.
- BN_free(exponent);
- } else if (key_params.type() == KT_ECDSA) {
- if (key_params.ec_curve() == EC_NIST_P256) {
- EC_KEY* ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
- if (!ec_key) {
- EVP_PKEY_free(pkey);
- RTC_LOG(LS_ERROR) << "Failed to allocate EC key";
- return nullptr;
- }
-
- // Ensure curve name is included when EC key is serialized.
- // Without this call, OpenSSL versions before 1.1.0 will create
- // certificates that don't work for TLS.
- // This is a no-op for BoringSSL and OpenSSL 1.1.0+
- EC_KEY_set_asn1_flag(ec_key, OPENSSL_EC_NAMED_CURVE);
-
- if (!pkey || !ec_key || !EC_KEY_generate_key(ec_key) ||
- !EVP_PKEY_assign_EC_KEY(pkey, ec_key)) {
- EVP_PKEY_free(pkey);
- EC_KEY_free(ec_key);
- RTC_LOG(LS_ERROR) << "Failed to make EC key pair";
- return nullptr;
- }
- // ownership of ec_key struct was assigned, don't free it.
- } else {
- // Add generation of any other curves here.
- EVP_PKEY_free(pkey);
- RTC_LOG(LS_ERROR) << "ECDSA key requested for unknown curve";
- return nullptr;
- }
- } else {
- EVP_PKEY_free(pkey);
- RTC_LOG(LS_ERROR) << "Key type requested not understood";
- return nullptr;
- }
-
- RTC_LOG(LS_INFO) << "Returning key pair";
- return pkey;
-}
-
-std::unique_ptr<OpenSSLKeyPair> OpenSSLKeyPair::Generate(
- const KeyParams& key_params) {
- EVP_PKEY* pkey = MakeKey(key_params);
- if (!pkey) {
- openssl::LogSSLErrors("Generating key pair");
- return nullptr;
- }
- return std::make_unique<OpenSSLKeyPair>(pkey);
-}
-
-std::unique_ptr<OpenSSLKeyPair> OpenSSLKeyPair::FromPrivateKeyPEMString(
- const std::string& pem_string) {
- BIO* bio =
- BIO_new_mem_buf(const_cast<char*>(pem_string.data()), pem_string.size());
- if (!bio) {
- RTC_LOG(LS_ERROR) << "Failed to create a new BIO buffer.";
- return nullptr;
- }
- BIO_set_mem_eof_return(bio, 0);
- EVP_PKEY* pkey = PEM_read_bio_PrivateKey(bio, nullptr, nullptr, nullptr);
- BIO_free(bio); // Frees the BIO, but not the pointed-to string.
- if (!pkey) {
- RTC_LOG(LS_ERROR) << "Failed to create the private key from PEM string.";
- return nullptr;
- }
- if (EVP_PKEY_missing_parameters(pkey) != 0) {
- RTC_LOG(LS_ERROR)
- << "The resulting key pair is missing public key parameters.";
- EVP_PKEY_free(pkey);
- return nullptr;
- }
- return std::make_unique<OpenSSLKeyPair>(pkey);
-}
-
-OpenSSLKeyPair::~OpenSSLKeyPair() {
- EVP_PKEY_free(pkey_);
-}
-
-std::unique_ptr<OpenSSLKeyPair> OpenSSLKeyPair::Clone() {
- AddReference();
- return std::make_unique<OpenSSLKeyPair>(pkey_);
-}
-
-void OpenSSLKeyPair::AddReference() {
- EVP_PKEY_up_ref(pkey_);
-}
-
-std::string OpenSSLKeyPair::PrivateKeyToPEMString() const {
- BIO* temp_memory_bio = BIO_new(BIO_s_mem());
- if (!temp_memory_bio) {
- RTC_LOG_F(LS_ERROR) << "Failed to allocate temporary memory bio";
- RTC_NOTREACHED();
- return "";
- }
- if (!PEM_write_bio_PrivateKey(temp_memory_bio, pkey_, nullptr, nullptr, 0,
- nullptr, nullptr)) {
- RTC_LOG_F(LS_ERROR) << "Failed to write private key";
- BIO_free(temp_memory_bio);
- RTC_NOTREACHED();
- return "";
- }
- char* buffer;
- size_t len = BIO_get_mem_data(temp_memory_bio, &buffer);
- std::string priv_key_str(buffer, len);
- BIO_free(temp_memory_bio);
- return priv_key_str;
-}
-
-std::string OpenSSLKeyPair::PublicKeyToPEMString() const {
- BIO* temp_memory_bio = BIO_new(BIO_s_mem());
- if (!temp_memory_bio) {
- RTC_LOG_F(LS_ERROR) << "Failed to allocate temporary memory bio";
- RTC_NOTREACHED();
- return "";
- }
- if (!PEM_write_bio_PUBKEY(temp_memory_bio, pkey_)) {
- RTC_LOG_F(LS_ERROR) << "Failed to write public key";
- BIO_free(temp_memory_bio);
- RTC_NOTREACHED();
- return "";
- }
- BIO_write(temp_memory_bio, "\0", 1);
- char* buffer;
- BIO_get_mem_data(temp_memory_bio, &buffer);
- std::string pub_key_str = buffer;
- BIO_free(temp_memory_bio);
- return pub_key_str;
-}
-
-bool OpenSSLKeyPair::operator==(const OpenSSLKeyPair& other) const {
- return EVP_PKEY_cmp(this->pkey_, other.pkey_) == 1;
-}
-
-bool OpenSSLKeyPair::operator!=(const OpenSSLKeyPair& other) const {
- return !(*this == other);
-}
-
-} // namespace rtc
diff --git a/rtc_base/openssl_key_pair.h b/rtc_base/openssl_key_pair.h
deleted file mode 100644
index a84c43b..0000000
--- a/rtc_base/openssl_key_pair.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2020 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 RTC_BASE_OPENSSL_KEY_PAIR_H_
-#define RTC_BASE_OPENSSL_KEY_PAIR_H_
-
-#include <openssl/ossl_typ.h>
-
-#include <memory>
-#include <string>
-
-#include "rtc_base/checks.h"
-#include "rtc_base/constructor_magic.h"
-#include "rtc_base/ssl_identity.h"
-
-namespace rtc {
-
-// OpenSSLKeyPair encapsulates an OpenSSL EVP_PKEY* keypair object,
-// which is reference counted inside the OpenSSL library.
-class OpenSSLKeyPair final {
- public:
- // Takes ownership of the key.
- explicit OpenSSLKeyPair(EVP_PKEY* pkey) : pkey_(pkey) {
- RTC_DCHECK(pkey_ != nullptr);
- }
-
- static std::unique_ptr<OpenSSLKeyPair> Generate(const KeyParams& key_params);
- // Constructs a key pair from the private key PEM string. This must not result
- // in missing public key parameters. Returns null on error.
- static std::unique_ptr<OpenSSLKeyPair> FromPrivateKeyPEMString(
- const std::string& pem_string);
-
- ~OpenSSLKeyPair();
-
- std::unique_ptr<OpenSSLKeyPair> Clone();
-
- EVP_PKEY* pkey() const { return pkey_; }
- std::string PrivateKeyToPEMString() const;
- std::string PublicKeyToPEMString() const;
- bool operator==(const OpenSSLKeyPair& other) const;
- bool operator!=(const OpenSSLKeyPair& other) const;
-
- private:
- void AddReference();
-
- EVP_PKEY* pkey_;
-
- RTC_DISALLOW_COPY_AND_ASSIGN(OpenSSLKeyPair);
-};
-
-} // namespace rtc
-
-#endif // RTC_BASE_OPENSSL_KEY_PAIR_H_
diff --git a/rtc_base/openssl_session_cache_unittest.cc b/rtc_base/openssl_session_cache_unittest.cc
index 0441d5c..1d3084b 100644
--- a/rtc_base/openssl_session_cache_unittest.cc
+++ b/rtc_base/openssl_session_cache_unittest.cc
@@ -19,28 +19,10 @@
#include "rtc_base/gunit.h"
#include "rtc_base/openssl.h"
-namespace {
-// Use methods that avoid X509 objects if possible.
-SSL_CTX* NewDtlsContext() {
-#ifdef OPENSSL_IS_BORINGSSL
- return SSL_CTX_new(DTLS_with_buffers_method());
-#else
- return SSL_CTX_new(DTLS_method());
-#endif
-}
-SSL_CTX* NewTlsContext() {
-#ifdef OPENSSL_IS_BORINGSSL
- return SSL_CTX_new(TLS_with_buffers_method());
-#else
- return SSL_CTX_new(TLS_method());
-#endif
-}
-} // namespace
-
namespace rtc {
TEST(OpenSSLSessionCache, DTLSModeSetCorrectly) {
- SSL_CTX* ssl_ctx = NewDtlsContext();
+ SSL_CTX* ssl_ctx = SSL_CTX_new(DTLSv1_2_client_method());
OpenSSLSessionCache session_cache(SSL_MODE_DTLS, ssl_ctx);
EXPECT_EQ(session_cache.GetSSLMode(), SSL_MODE_DTLS);
@@ -49,7 +31,7 @@
}
TEST(OpenSSLSessionCache, TLSModeSetCorrectly) {
- SSL_CTX* ssl_ctx = NewTlsContext();
+ SSL_CTX* ssl_ctx = SSL_CTX_new(TLSv1_2_client_method());
OpenSSLSessionCache session_cache(SSL_MODE_TLS, ssl_ctx);
EXPECT_EQ(session_cache.GetSSLMode(), SSL_MODE_TLS);
@@ -58,7 +40,7 @@
}
TEST(OpenSSLSessionCache, SSLContextSetCorrectly) {
- SSL_CTX* ssl_ctx = NewDtlsContext();
+ SSL_CTX* ssl_ctx = SSL_CTX_new(DTLSv1_2_client_method());
OpenSSLSessionCache session_cache(SSL_MODE_DTLS, ssl_ctx);
EXPECT_EQ(session_cache.GetSSLContext(), ssl_ctx);
@@ -67,7 +49,7 @@
}
TEST(OpenSSLSessionCache, InvalidLookupReturnsNullptr) {
- SSL_CTX* ssl_ctx = NewDtlsContext();
+ SSL_CTX* ssl_ctx = SSL_CTX_new(DTLSv1_2_client_method());
OpenSSLSessionCache session_cache(SSL_MODE_DTLS, ssl_ctx);
EXPECT_EQ(session_cache.LookupSession("Invalid"), nullptr);
@@ -78,7 +60,7 @@
}
TEST(OpenSSLSessionCache, SimpleValidSessionLookup) {
- SSL_CTX* ssl_ctx = NewDtlsContext();
+ SSL_CTX* ssl_ctx = SSL_CTX_new(DTLSv1_2_client_method());
SSL_SESSION* ssl_session = SSL_SESSION_new(ssl_ctx);
OpenSSLSessionCache session_cache(SSL_MODE_DTLS, ssl_ctx);
@@ -89,7 +71,7 @@
}
TEST(OpenSSLSessionCache, AddToExistingReplacesPrevious) {
- SSL_CTX* ssl_ctx = NewDtlsContext();
+ SSL_CTX* ssl_ctx = SSL_CTX_new(DTLSv1_2_client_method());
SSL_SESSION* ssl_session_1 = SSL_SESSION_new(ssl_ctx);
SSL_SESSION* ssl_session_2 = SSL_SESSION_new(ssl_ctx);
diff --git a/rtc_base/openssl_stream_adapter.cc b/rtc_base/openssl_stream_adapter.cc
index 63b8069..f59b4ed 100644
--- a/rtc_base/openssl_stream_adapter.cc
+++ b/rtc_base/openssl_stream_adapter.cc
@@ -32,12 +32,7 @@
#include "rtc_base/openssl.h"
#include "rtc_base/openssl_adapter.h"
#include "rtc_base/openssl_digest.h"
-#ifdef OPENSSL_IS_BORINGSSL
-#include "rtc_base/boringssl_identity.h"
-#else
#include "rtc_base/openssl_identity.h"
-#endif
-#include "rtc_base/openssl_utility.h"
#include "rtc_base/ssl_certificate.h"
#include "rtc_base/stream.h"
#include "rtc_base/task_utils/to_queued_task.h"
@@ -309,14 +304,10 @@
void OpenSSLStreamAdapter::SetIdentity(std::unique_ptr<SSLIdentity> identity) {
RTC_DCHECK(!identity_);
-#ifdef OPENSSL_IS_BORINGSSL
- identity_.reset(static_cast<BoringSSLIdentity*>(identity.release()));
-#else
identity_.reset(static_cast<OpenSSLIdentity*>(identity.release()));
-#endif
}
-SSLIdentity* OpenSSLStreamAdapter::GetIdentityForTesting() const {
+OpenSSLIdentity* OpenSSLStreamAdapter::GetIdentityForTesting() const {
return identity_.get();
}
@@ -1003,16 +994,8 @@
}
SSL_CTX* OpenSSLStreamAdapter::SetupSSLContext() {
-#ifdef OPENSSL_IS_BORINGSSL
- // If X509 objects aren't used, we can use these methods to avoid
- // linking the sizable crypto/x509 code, using CRYPTO_BUFFER instead.
- SSL_CTX* ctx =
- SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ? DTLS_with_buffers_method()
- : TLS_with_buffers_method());
-#else
SSL_CTX* ctx =
SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ? DTLS_method() : TLS_method());
-#endif
if (ctx == nullptr) {
return nullptr;
}
@@ -1050,7 +1033,6 @@
if (g_use_time_callback_for_testing) {
SSL_CTX_set_current_time_cb(ctx, &TimeCallbackForTesting);
}
- SSL_CTX_set0_buffer_pool(ctx, openssl::GetBufferPool());
#endif
if (identity_ && !identity_->ConfigureIdentity(ctx)) {
@@ -1071,16 +1053,11 @@
}
// Configure a custom certificate verification callback to check the peer
- // certificate digest.
-#ifdef OPENSSL_IS_BORINGSSL
- // Use CRYPTO_BUFFER version of the callback if building with BoringSSL.
- SSL_CTX_set_custom_verify(ctx, mode, SSLVerifyCallback);
-#else
- // Note the second argument to SSL_CTX_set_verify is to override individual
- // errors in the default verification logic, which is not what we want here.
+ // certificate digest. Note the second argument to SSL_CTX_set_verify is to
+ // override individual errors in the default verification logic, which is not
+ // what we want here.
SSL_CTX_set_verify(ctx, mode, nullptr);
SSL_CTX_set_cert_verify_callback(ctx, SSLVerifyCallback, nullptr);
-#endif
// Select list of available ciphers. Note that !SHA256 and !SHA384 only
// remove HMAC-SHA256 and HMAC-SHA384 cipher suites, not GCM cipher suites
@@ -1105,12 +1082,14 @@
RTC_LOG(LS_WARNING) << "Missing digest or peer certificate.";
return false;
}
+ const OpenSSLCertificate* leaf_cert =
+ static_cast<const OpenSSLCertificate*>(&peer_cert_chain_->Get(0));
unsigned char digest[EVP_MAX_MD_SIZE];
size_t digest_length;
- if (!peer_cert_chain_->Get(0).ComputeDigest(
- peer_certificate_digest_algorithm_, digest, sizeof(digest),
- &digest_length)) {
+ if (!OpenSSLCertificate::ComputeDigest(
+ leaf_cert->x509(), peer_certificate_digest_algorithm_, digest,
+ sizeof(digest), &digest_length)) {
RTC_LOG(LS_WARNING) << "Failed to compute peer cert digest.";
return false;
}
@@ -1134,36 +1113,6 @@
return peer_cert_chain_ ? peer_cert_chain_->Clone() : nullptr;
}
-#ifdef OPENSSL_IS_BORINGSSL
-enum ssl_verify_result_t OpenSSLStreamAdapter::SSLVerifyCallback(
- SSL* ssl,
- uint8_t* out_alert) {
- // Get our OpenSSLStreamAdapter from the context.
- OpenSSLStreamAdapter* stream =
- reinterpret_cast<OpenSSLStreamAdapter*>(SSL_get_app_data(ssl));
- const STACK_OF(CRYPTO_BUFFER)* chain = SSL_get0_peer_certificates(ssl);
- // Creates certificate chain.
- std::vector<std::unique_ptr<SSLCertificate>> cert_chain;
- for (CRYPTO_BUFFER* cert : chain) {
- cert_chain.emplace_back(new BoringSSLCertificate(bssl::UpRef(cert)));
- }
- stream->peer_cert_chain_.reset(new SSLCertChain(std::move(cert_chain)));
-
- // If the peer certificate digest isn't known yet, we'll wait to verify
- // until it's known, and for now just return a success status.
- if (stream->peer_certificate_digest_algorithm_.empty()) {
- RTC_LOG(LS_INFO) << "Waiting to verify certificate until digest is known.";
- // TODO(deadbeef): Use ssl_verify_retry?
- return ssl_verify_ok;
- }
-
- if (!stream->VerifyPeerCertificate()) {
- return ssl_verify_invalid;
- }
-
- return ssl_verify_ok;
-}
-#else // OPENSSL_IS_BORINGSSL
int OpenSSLStreamAdapter::SSLVerifyCallback(X509_STORE_CTX* store, void* arg) {
// Get our SSL structure and OpenSSLStreamAdapter from the store.
SSL* ssl = reinterpret_cast<SSL*>(
@@ -1171,10 +1120,20 @@
OpenSSLStreamAdapter* stream =
reinterpret_cast<OpenSSLStreamAdapter*>(SSL_get_app_data(ssl));
+#if defined(OPENSSL_IS_BORINGSSL)
+ STACK_OF(X509)* chain = SSL_get_peer_full_cert_chain(ssl);
+ // Creates certificate chain.
+ std::vector<std::unique_ptr<SSLCertificate>> cert_chain;
+ for (X509* cert : chain) {
+ cert_chain.emplace_back(new OpenSSLCertificate(cert));
+ }
+ stream->peer_cert_chain_.reset(new SSLCertChain(std::move(cert_chain)));
+#else
// Record the peer's certificate.
X509* cert = X509_STORE_CTX_get0_cert(store);
stream->peer_cert_chain_.reset(
new SSLCertChain(std::make_unique<OpenSSLCertificate>(cert)));
+#endif
// If the peer certificate digest isn't known yet, we'll wait to verify
// until it's known, and for now just return a success status.
@@ -1190,7 +1149,6 @@
return 1;
}
-#endif // !OPENSSL_IS_BORINGSSL
bool OpenSSLStreamAdapter::IsBoringSsl() {
#ifdef OPENSSL_IS_BORINGSSL
diff --git a/rtc_base/openssl_stream_adapter.h b/rtc_base/openssl_stream_adapter.h
index a09737c..fbfccd684 100644
--- a/rtc_base/openssl_stream_adapter.h
+++ b/rtc_base/openssl_stream_adapter.h
@@ -21,11 +21,7 @@
#include "absl/types/optional.h"
#include "rtc_base/buffer.h"
-#ifdef OPENSSL_IS_BORINGSSL
-#include "rtc_base/boringssl_identity.h"
-#else
#include "rtc_base/openssl_identity.h"
-#endif
#include "rtc_base/ssl_identity.h"
#include "rtc_base/ssl_stream_adapter.h"
#include "rtc_base/stream.h"
@@ -75,7 +71,7 @@
~OpenSSLStreamAdapter() override;
void SetIdentity(std::unique_ptr<SSLIdentity> identity) override;
- SSLIdentity* GetIdentityForTesting() const override;
+ OpenSSLIdentity* GetIdentityForTesting() const override;
// Default argument is for compatibility
void SetServerRole(SSLRole role = SSL_SERVER) override;
@@ -183,16 +179,9 @@
SSL_CTX* SetupSSLContext();
// Verify the peer certificate matches the signaled digest.
bool VerifyPeerCertificate();
-
-#ifdef OPENSSL_IS_BORINGSSL
- // SSL certificate verification callback. See SSL_CTX_set_custom_verify.
- static enum ssl_verify_result_t SSLVerifyCallback(SSL* ssl,
- uint8_t* out_alert);
-#else
// SSL certificate verification callback. See
// SSL_CTX_set_cert_verify_callback.
static int SSLVerifyCallback(X509_STORE_CTX* store, void* arg);
-#endif
bool WaitingToVerifyPeerCertificate() const {
return GetClientAuthEnabled() && !peer_certificate_verified_;
@@ -219,11 +208,7 @@
SSL_CTX* ssl_ctx_;
// Our key and certificate.
-#ifdef OPENSSL_IS_BORINGSSL
- std::unique_ptr<BoringSSLIdentity> identity_;
-#else
std::unique_ptr<OpenSSLIdentity> identity_;
-#endif
// The certificate chain that the peer presented. Initially null, until the
// connection is established.
std::unique_ptr<SSLCertChain> peer_cert_chain_;
diff --git a/rtc_base/openssl_utility.cc b/rtc_base/openssl_utility.cc
index f91e8d9..1984eb0 100644
--- a/rtc_base/openssl_utility.cc
+++ b/rtc_base/openssl_utility.cc
@@ -14,9 +14,6 @@
#include "rtc_base/win32.h" // NOLINT
#endif // WEBRTC_WIN
-#ifdef OPENSSL_IS_BORINGSSL
-#include <openssl/pool.h>
-#endif
#include <openssl/err.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
@@ -36,10 +33,6 @@
// Holds various helper methods.
namespace {
-
-// TODO(crbug.com/webrtc/11710): When OS certificate verification is available,
-// and we don't need VerifyPeerCertMatchesHost, don't compile this in order to
-// avoid a dependency on OpenSSL X509 objects (see crbug.com/webrtc/11410).
void LogCertificates(SSL* ssl, X509* certificate) {
// Logging certificates is extremely verbose. So it is disabled by default.
#ifdef LOG_CERTIFICATES
@@ -72,118 +65,6 @@
}
} // namespace
-#ifdef OPENSSL_IS_BORINGSSL
-bool ParseCertificate(CRYPTO_BUFFER* cert_buffer,
- CBS* signature_algorithm_oid,
- int64_t* expiration_time) {
- CBS cbs;
- CRYPTO_BUFFER_init_CBS(cert_buffer, &cbs);
-
- // Certificate ::= SEQUENCE {
- CBS certificate;
- if (!CBS_get_asn1(&cbs, &certificate, CBS_ASN1_SEQUENCE)) {
- return false;
- }
- // tbsCertificate TBSCertificate,
- CBS tbs_certificate;
- if (!CBS_get_asn1(&certificate, &tbs_certificate, CBS_ASN1_SEQUENCE)) {
- return false;
- }
- // signatureAlgorithm AlgorithmIdentifier,
- CBS signature_algorithm;
- if (!CBS_get_asn1(&certificate, &signature_algorithm, CBS_ASN1_SEQUENCE)) {
- return false;
- }
- if (!CBS_get_asn1(&signature_algorithm, signature_algorithm_oid,
- CBS_ASN1_OBJECT)) {
- return false;
- }
- // signatureValue BIT STRING }
- if (!CBS_get_asn1(&certificate, nullptr, CBS_ASN1_BITSTRING)) {
- return false;
- }
- if (CBS_len(&certificate)) {
- return false;
- }
-
- // Now parse the inner TBSCertificate.
- // version [0] EXPLICIT Version DEFAULT v1,
- if (!CBS_get_optional_asn1(
- &tbs_certificate, nullptr, nullptr,
- CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC)) {
- return false;
- }
- // serialNumber CertificateSerialNumber,
- if (!CBS_get_asn1(&tbs_certificate, nullptr, CBS_ASN1_INTEGER)) {
- return false;
- }
- // signature AlgorithmIdentifier
- if (!CBS_get_asn1(&tbs_certificate, nullptr, CBS_ASN1_SEQUENCE)) {
- return false;
- }
- // issuer Name,
- if (!CBS_get_asn1(&tbs_certificate, nullptr, CBS_ASN1_SEQUENCE)) {
- return false;
- }
- // validity Validity,
- CBS validity;
- if (!CBS_get_asn1(&tbs_certificate, &validity, CBS_ASN1_SEQUENCE)) {
- return false;
- }
- // Skip over notBefore.
- if (!CBS_get_any_asn1_element(&validity, nullptr, nullptr, nullptr)) {
- return false;
- }
- // Parse notAfter.
- CBS not_after;
- unsigned not_after_tag;
- if (!CBS_get_any_asn1(&validity, ¬_after, ¬_after_tag)) {
- return false;
- }
- bool long_format;
- if (not_after_tag == CBS_ASN1_UTCTIME) {
- long_format = false;
- } else if (not_after_tag == CBS_ASN1_GENERALIZEDTIME) {
- long_format = true;
- } else {
- return false;
- }
- if (expiration_time) {
- *expiration_time =
- ASN1TimeToSec(CBS_data(¬_after), CBS_len(¬_after), long_format);
- }
- // subject Name,
- if (!CBS_get_asn1_element(&tbs_certificate, nullptr, CBS_ASN1_SEQUENCE)) {
- return false;
- }
- // subjectPublicKeyInfo SubjectPublicKeyInfo,
- if (!CBS_get_asn1(&tbs_certificate, nullptr, CBS_ASN1_SEQUENCE)) {
- return false;
- }
- // issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL
- if (!CBS_get_optional_asn1(&tbs_certificate, nullptr, nullptr,
- 0x01 | CBS_ASN1_CONTEXT_SPECIFIC)) {
- return false;
- }
- // subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL
- if (!CBS_get_optional_asn1(&tbs_certificate, nullptr, nullptr,
- 0x02 | CBS_ASN1_CONTEXT_SPECIFIC)) {
- return false;
- }
- // extensions [3] EXPLICIT Extensions OPTIONAL
- if (!CBS_get_optional_asn1(
- &tbs_certificate, nullptr, nullptr,
- 0x03 | CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC)) {
- return false;
- }
- if (CBS_len(&tbs_certificate)) {
- return false;
- }
-
- return true;
-}
-#endif // OPENSSL_IS_BORINGSSL
-
bool VerifyPeerCertMatchesHost(SSL* ssl, const std::string& host) {
if (host.empty()) {
RTC_DLOG(LS_ERROR) << "Hostname is empty. Cannot verify peer certificate.";
@@ -195,28 +76,9 @@
return false;
}
-#ifdef OPENSSL_IS_BORINGSSL
- // We can't grab a X509 object directly, as the SSL context may have been
- // initialized with TLS_with_buffers_method.
- const STACK_OF(CRYPTO_BUFFER)* chain = SSL_get0_peer_certificates(ssl);
- if (chain == nullptr || sk_CRYPTO_BUFFER_num(chain) == 0) {
- RTC_LOG(LS_ERROR)
- << "SSL_get0_peer_certificates failed. This should never happen.";
- return false;
- }
- CRYPTO_BUFFER* leaf = sk_CRYPTO_BUFFER_value(chain, 0);
- bssl::UniquePtr<X509> x509(X509_parse_from_buffer(leaf));
- if (!x509) {
- RTC_LOG(LS_ERROR) << "Failed to parse certificate to X509 object.";
- return false;
- }
- LogCertificates(ssl, x509.get());
- return X509_check_host(x509.get(), host.c_str(), host.size(), 0, nullptr) ==
- 1;
-#else // OPENSSL_IS_BORINGSSL
X509* certificate = SSL_get_peer_certificate(ssl);
if (certificate == nullptr) {
- RTC_LOG(LS_ERROR)
+ RTC_DLOG(LS_ERROR)
<< "SSL_get_peer_certificate failed. This should never happen.";
return false;
}
@@ -227,7 +89,6 @@
X509_check_host(certificate, host.c_str(), host.size(), 0, nullptr) == 1;
X509_free(certificate);
return is_valid_cert_name;
-#endif // !defined(OPENSSL_IS_BORINGSSL)
}
void LogSSLErrors(const std::string& prefix) {
@@ -262,12 +123,5 @@
}
#endif // WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS
-#ifdef OPENSSL_IS_BORINGSSL
-CRYPTO_BUFFER_POOL* GetBufferPool() {
- static CRYPTO_BUFFER_POOL* instance = CRYPTO_BUFFER_POOL_new();
- return instance;
-}
-#endif
-
} // namespace openssl
} // namespace rtc
diff --git a/rtc_base/openssl_utility.h b/rtc_base/openssl_utility.h
index ee29ccd..022294d 100644
--- a/rtc_base/openssl_utility.h
+++ b/rtc_base/openssl_utility.h
@@ -20,21 +20,8 @@
// to OpenSSL that are commonly used and don't require global state should be
// placed here.
namespace openssl {
-
-#ifdef OPENSSL_IS_BORINGSSL
-// Does minimal parsing of a certificate (only verifying the presence of major
-// fields), primarily for the purpose of extracting the relevant out
-// parameters. Any that the caller is uninterested in can be null.
-bool ParseCertificate(CRYPTO_BUFFER* cert_buffer,
- CBS* signature_algorithm_oid,
- int64_t* expiration_time);
-#endif
-
// Verifies that the hostname provided matches that in the peer certificate
// attached to this SSL state.
-// TODO(crbug.com/webrtc/11710): When OS certificate verification is available,
-// skip compiling this as it adds a dependency on OpenSSL X509 objects, which we
-// are trying to avoid in favor of CRYPTO_BUFFERs (see crbug.com/webrtc/11410).
bool VerifyPeerCertMatchesHost(SSL* ssl, const std::string& host);
// Logs all the errors in the OpenSSL errror queue from the current thread. A
@@ -48,10 +35,6 @@
bool LoadBuiltinSSLRootCertificates(SSL_CTX* ssl_ctx);
#endif // WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS
-#ifdef OPENSSL_IS_BORINGSSL
-CRYPTO_BUFFER_POOL* GetBufferPool();
-#endif
-
} // namespace openssl
} // namespace rtc
diff --git a/rtc_base/openssl_utility_unittest.cc b/rtc_base/openssl_utility_unittest.cc
index d090524..9c9b971 100644
--- a/rtc_base/openssl_utility_unittest.cc
+++ b/rtc_base/openssl_utility_unittest.cc
@@ -24,12 +24,8 @@
#include <openssl/crypto.h>
#include <openssl/evp.h>
#include <openssl/ssl.h>
-#ifdef OPENSSL_IS_BORINGSSL
-#include <openssl/pool.h>
-#else
#include <openssl/x509.h>
#include <openssl/x509v3.h>
-#endif
#include "rtc_base/arraysize.h"
#include "rtc_base/checks.h"
@@ -173,17 +169,14 @@
0x84, 0x0b, 0xc7, 0x15, 0x86, 0xc3, 0xfc, 0x48, 0x55, 0xb5, 0x81, 0x94,
0x73, 0xbd, 0x18, 0xcd, 0x9d, 0x92, 0x47, 0xaa, 0xfd, 0x18};
-#ifdef OPENSSL_IS_BORINGSSL
-enum ssl_verify_result_t DummyVerifyCallback(SSL* ssl, uint8_t* out_alert) {
- return ssl_verify_ok;
-}
-#endif
-
// Creates a client SSL that has completed handshaking with a server that uses
// the specified certificate (which must have private key kFakeSSLPrivateKey).
// The server is deallocated. This client will have a peer certificate available
// and is thus suitable for testing VerifyPeerCertMatchesHost.
SSL* CreateSSLWithPeerCertificate(const unsigned char* cert, size_t cert_len) {
+ X509* x509 =
+ d2i_X509(nullptr, &cert, checked_cast<long>(cert_len)); // NOLINT
+ RTC_CHECK(x509);
const unsigned char* key_ptr = kFakeSSLPrivateKey;
EVP_PKEY* key = d2i_PrivateKey(
@@ -191,33 +184,14 @@
checked_cast<long>(arraysize(kFakeSSLPrivateKey))); // NOLINT
RTC_CHECK(key);
-#ifdef OPENSSL_IS_BORINGSSL
- SSL_CTX* ctx = SSL_CTX_new(TLS_with_buffers_method());
-#else
- SSL_CTX* ctx = SSL_CTX_new(TLS_method());
-#endif
+ SSL_CTX* ctx = SSL_CTX_new(SSLv23_method());
SSL* client = SSL_new(ctx);
SSL* server = SSL_new(ctx);
SSL_set_connect_state(client);
SSL_set_accept_state(server);
-#ifdef OPENSSL_IS_BORINGSSL
- bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer(CRYPTO_BUFFER_new(
- static_cast<const uint8_t*>(cert), cert_len, openssl::GetBufferPool()));
- RTC_CHECK(cert_buffer);
- std::vector<CRYPTO_BUFFER*> cert_buffers;
- cert_buffers.push_back(cert_buffer.get());
- RTC_CHECK(1 == SSL_set_chain_and_key(server, cert_buffers.data(),
- cert_buffers.size(), key, nullptr));
- // When using crypto buffers we don't get any built-in verification.
- SSL_set_custom_verify(client, SSL_VERIFY_PEER, DummyVerifyCallback);
-#else
- X509* x509 =
- d2i_X509(nullptr, &cert, checked_cast<long>(cert_len)); // NOLINT
- RTC_CHECK(x509);
RTC_CHECK(SSL_use_certificate(server, x509));
RTC_CHECK(SSL_use_PrivateKey(server, key));
-#endif
BIO* bio1;
BIO* bio2;
@@ -247,19 +221,13 @@
SSL_free(server);
SSL_CTX_free(ctx);
EVP_PKEY_free(key);
-#ifndef OPENSSL_IS_BORINGSSL
X509_free(x509);
-#endif
return client;
}
} // namespace
TEST(OpenSSLUtilityTest, VerifyPeerCertMatchesHostFailsOnNoPeerCertificate) {
-#ifdef OPENSSL_IS_BORINGSSL
- SSL_CTX* ssl_ctx = SSL_CTX_new(DTLS_with_buffers_method());
-#else
- SSL_CTX* ssl_ctx = SSL_CTX_new(DTLS_method());
-#endif
+ SSL_CTX* ssl_ctx = SSL_CTX_new(DTLSv1_2_client_method());
SSL* ssl = SSL_new(ssl_ctx);
EXPECT_FALSE(openssl::VerifyPeerCertMatchesHost(ssl, "webrtc.org"));
diff --git a/rtc_base/rtc_certificate_generator.cc b/rtc_base/rtc_certificate_generator.cc
index 5e1fdca..d95b645 100644
--- a/rtc_base/rtc_certificate_generator.cc
+++ b/rtc_base/rtc_certificate_generator.cc
@@ -51,7 +51,7 @@
expires_s = std::min(expires_s, kYearInSeconds);
// TODO(torbjorng): Stop using |time_t|, its type is unspecified. It it safe
// to assume it can hold up to a year's worth of seconds (and more), but
- // |SSLIdentity::Create| should stop relying on |time_t|.
+ // |SSLIdentity::Generate| should stop relying on |time_t|.
// See bugs.webrtc.org/5720.
time_t cert_lifetime_s = static_cast<time_t>(expires_s);
identity = SSLIdentity::Create(kIdentityName, key_params, cert_lifetime_s);
diff --git a/rtc_base/ssl_certificate.cc b/rtc_base/ssl_certificate.cc
index 3f7013e..db9097b 100644
--- a/rtc_base/ssl_certificate.cc
+++ b/rtc_base/ssl_certificate.cc
@@ -16,12 +16,7 @@
#include "absl/algorithm/container.h"
#include "rtc_base/checks.h"
-#include "rtc_base/openssl.h"
-#ifdef OPENSSL_IS_BORINGSSL
-#include "rtc_base/boringssl_identity.h"
-#else
-#include "rtc_base/openssl_identity.h"
-#endif
+#include "rtc_base/openssl_certificate.h"
#include "rtc_base/ssl_fingerprint.h"
#include "rtc_base/third_party/base64/base64.h"
@@ -122,11 +117,7 @@
// static
std::unique_ptr<SSLCertificate> SSLCertificate::FromPEMString(
const std::string& pem_string) {
-#ifdef OPENSSL_IS_BORINGSSL
- return BoringSSLCertificate::FromPEMString(pem_string);
-#else
return OpenSSLCertificate::FromPEMString(pem_string);
-#endif
}
} // namespace rtc
diff --git a/rtc_base/ssl_identity.cc b/rtc_base/ssl_identity.cc
index 8d93ecf..09d25d2 100644
--- a/rtc_base/ssl_identity.cc
+++ b/rtc_base/ssl_identity.cc
@@ -11,16 +11,12 @@
// Handling of certificates and keypairs for SSLStreamAdapter's peer mode.
#include "rtc_base/ssl_identity.h"
-#include <openssl/ossl_typ.h>
#include <string.h>
#include <time.h>
+#include <string>
#include "rtc_base/checks.h"
-#ifdef OPENSSL_IS_BORINGSSL
-#include "rtc_base/boringssl_identity.h"
-#else
#include "rtc_base/openssl_identity.h"
-#endif
#include "rtc_base/ssl_certificate.h"
#include "rtc_base/strings/string_builder.h"
#include "rtc_base/third_party/base64/base64.h"
@@ -217,36 +213,28 @@
std::unique_ptr<SSLIdentity> SSLIdentity::Create(const std::string& common_name,
const KeyParams& key_param,
time_t certificate_lifetime) {
-#ifdef OPENSSL_IS_BORINGSSL
- return BoringSSLIdentity::CreateWithExpiration(common_name, key_param,
- certificate_lifetime);
-#else
return OpenSSLIdentity::CreateWithExpiration(common_name, key_param,
certificate_lifetime);
-#endif
}
// static
std::unique_ptr<SSLIdentity> SSLIdentity::Create(const std::string& common_name,
const KeyParams& key_param) {
- return Create(common_name, key_param, kDefaultCertificateLifetimeInSeconds);
+ return OpenSSLIdentity::CreateWithExpiration(
+ common_name, key_param, kDefaultCertificateLifetimeInSeconds);
}
// static
std::unique_ptr<SSLIdentity> SSLIdentity::Create(const std::string& common_name,
KeyType key_type) {
- return Create(common_name, KeyParams(key_type),
- kDefaultCertificateLifetimeInSeconds);
+ return OpenSSLIdentity::CreateWithExpiration(
+ common_name, KeyParams(key_type), kDefaultCertificateLifetimeInSeconds);
}
// static
std::unique_ptr<SSLIdentity> SSLIdentity::CreateForTest(
const SSLIdentityParams& params) {
-#ifdef OPENSSL_IS_BORINGSSL
- return BoringSSLIdentity::CreateForTest(params);
-#else
return OpenSSLIdentity::CreateForTest(params);
-#endif
}
// Construct an identity from a private key and a certificate.
@@ -254,11 +242,7 @@
std::unique_ptr<SSLIdentity> SSLIdentity::CreateFromPEMStrings(
const std::string& private_key,
const std::string& certificate) {
-#ifdef OPENSSL_IS_BORINGSSL
- return BoringSSLIdentity::CreateFromPEMStrings(private_key, certificate);
-#else
return OpenSSLIdentity::CreateFromPEMStrings(private_key, certificate);
-#endif
}
// Construct an identity from a private key and a certificate chain.
@@ -266,23 +250,13 @@
std::unique_ptr<SSLIdentity> SSLIdentity::CreateFromPEMChainStrings(
const std::string& private_key,
const std::string& certificate_chain) {
-#ifdef OPENSSL_IS_BORINGSSL
- return BoringSSLIdentity::CreateFromPEMChainStrings(private_key,
- certificate_chain);
-#else
return OpenSSLIdentity::CreateFromPEMChainStrings(private_key,
certificate_chain);
-#endif
}
bool operator==(const SSLIdentity& a, const SSLIdentity& b) {
-#ifdef OPENSSL_IS_BORINGSSL
- return static_cast<const BoringSSLIdentity&>(a) ==
- static_cast<const BoringSSLIdentity&>(b);
-#else
return static_cast<const OpenSSLIdentity&>(a) ==
static_cast<const OpenSSLIdentity&>(b);
-#endif
}
bool operator!=(const SSLIdentity& a, const SSLIdentity& b) {
return !(a == b);
diff --git a/rtc_base/ssl_identity_unittest.cc b/rtc_base/ssl_identity_unittest.cc
index a907bfc..0d9d0fd 100644
--- a/rtc_base/ssl_identity_unittest.cc
+++ b/rtc_base/ssl_identity_unittest.cc
@@ -65,7 +65,7 @@
0x35, 0xce, 0x26, 0x58, 0x4a, 0x33, 0x6d, 0xbc, 0xb6};
// These PEM strings were created by generating an identity with
-// |SSLIdentity::Create| and invoking |identity->PrivateKeyToPEMString()|,
+// |SSLIdentity::Generate| and invoking |identity->PrivateKeyToPEMString()|,
// |identity->PublicKeyToPEMString()| and
// |identity->certificate().ToPEMString()|. If the crypto library is updated,
// and the update changes the string form of the keys, these will have to be
@@ -406,21 +406,6 @@
EXPECT_EQ(kECDSA_CERT_PEM, identity->certificate().ToPEMString());
}
-TEST_F(SSLIdentityTest, FromPEMChainStrings) {
- // This doesn't form a valid certificate chain, but that doesn't matter for
- // the purposes of the test
- std::string chain(kRSA_CERT_PEM);
- chain.append(kTestCertificate);
- std::unique_ptr<SSLIdentity> identity(
- SSLIdentity::CreateFromPEMChainStrings(kRSA_PRIVATE_KEY_PEM, chain));
- EXPECT_TRUE(identity);
- EXPECT_EQ(kRSA_PRIVATE_KEY_PEM, identity->PrivateKeyToPEMString());
- EXPECT_EQ(kRSA_PUBLIC_KEY_PEM, identity->PublicKeyToPEMString());
- ASSERT_EQ(2u, identity->cert_chain().GetSize());
- EXPECT_EQ(kRSA_CERT_PEM, identity->cert_chain().Get(0).ToPEMString());
- EXPECT_EQ(kTestCertificate, identity->cert_chain().Get(1).ToPEMString());
-}
-
TEST_F(SSLIdentityTest, CloneIdentityRSA) {
TestCloningIdentity(*identity_rsa1_);
TestCloningIdentity(*identity_rsa2_);
diff --git a/rtc_base/ssl_stream_adapter_unittest.cc b/rtc_base/ssl_stream_adapter_unittest.cc
index c580d83..379acac 100644
--- a/rtc_base/ssl_stream_adapter_unittest.cc
+++ b/rtc_base/ssl_stream_adapter_unittest.cc
@@ -508,9 +508,8 @@
}
}
- // This tests that the handshake can complete before the identity is verified,
- // and the identity will be verified after the fact. It also verifies that
- // packets can't be read or written before the identity has been verified.
+ // This tests that the handshake can complete before the identity is
+ // verified, and the identity will be verified after the fact.
void TestHandshakeWithDelayedIdentity(bool valid_identity) {
server_ssl_->SetMode(dtls_ ? rtc::SSL_MODE_DTLS : rtc::SSL_MODE_TLS);
client_ssl_->SetMode(dtls_ ? rtc::SSL_MODE_DTLS : rtc::SSL_MODE_TLS);
@@ -525,9 +524,14 @@
}
// Start the handshake
+ int rv;
+
server_ssl_->SetServerRole();
- ASSERT_EQ(0, server_ssl_->StartSSL());
- ASSERT_EQ(0, client_ssl_->StartSSL());
+ rv = server_ssl_->StartSSL();
+ ASSERT_EQ(0, rv);
+
+ rv = client_ssl_->StartSSL();
+ ASSERT_EQ(0, rv);
// Now run the handshake.
EXPECT_TRUE_WAIT(
@@ -543,57 +547,16 @@
EXPECT_EQ(rtc::SR_BLOCK, client_ssl_->Write(&packet, 1, &sent, 0));
EXPECT_EQ(rtc::SR_BLOCK, server_ssl_->Write(&packet, 1, &sent, 0));
- // Collect both of the certificate digests; needs to be done before calling
- // SetPeerCertificateDigest as that may reset the identity.
- unsigned char server_digest[20];
- size_t server_digest_len;
- unsigned char client_digest[20];
- size_t client_digest_len;
- bool rv;
-
- rv = server_identity()->certificate().ComputeDigest(
- rtc::DIGEST_SHA_1, server_digest, 20, &server_digest_len);
- ASSERT_TRUE(rv);
- rv = client_identity()->certificate().ComputeDigest(
- rtc::DIGEST_SHA_1, client_digest, 20, &client_digest_len);
- ASSERT_TRUE(rv);
-
- if (!valid_identity) {
- RTC_LOG(LS_INFO) << "Setting bogus digest for client/server certs";
- client_digest[0]++;
- server_digest[0]++;
- }
-
- // Set the peer certificate digest for the client.
- rtc::SSLPeerCertificateDigestError err;
- rtc::SSLPeerCertificateDigestError expected_err =
- valid_identity
- ? rtc::SSLPeerCertificateDigestError::NONE
- : rtc::SSLPeerCertificateDigestError::VERIFICATION_FAILED;
- rv = client_ssl_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, server_digest,
- server_digest_len, &err);
- EXPECT_EQ(expected_err, err);
- EXPECT_EQ(valid_identity, rv);
+ // If we set an invalid identity at this point, SetPeerCertificateDigest
+ // should return false.
+ SetPeerIdentitiesByDigest(valid_identity, valid_identity);
// State should then transition to SS_OPEN or SS_CLOSED based on validation
// of the identity.
if (valid_identity) {
EXPECT_EQ(rtc::SS_OPEN, client_ssl_->GetState());
- // If the client sends a packet while the server still hasn't verified the
- // client identity, the server should continue to return SR_BLOCK.
- EXPECT_EQ(rtc::SR_SUCCESS, client_ssl_->Write(&packet, 1, &sent, 0));
- EXPECT_EQ(rtc::SR_BLOCK, server_ssl_->Read(&packet, 1, 0, 0));
- } else {
- EXPECT_EQ(rtc::SS_CLOSED, client_ssl_->GetState());
- }
-
- // Set the peer certificate digest for the server.
- rv = server_ssl_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, client_digest,
- client_digest_len, &err);
- EXPECT_EQ(expected_err, err);
- EXPECT_EQ(valid_identity, rv);
- if (valid_identity) {
EXPECT_EQ(rtc::SS_OPEN, server_ssl_->GetState());
} else {
+ EXPECT_EQ(rtc::SS_CLOSED, client_ssl_->GetState());
EXPECT_EQ(rtc::SS_CLOSED, server_ssl_->GetState());
}
}
diff --git a/webrtc.gni b/webrtc.gni
index 2f6e77d..05a230c 100644
--- a/webrtc.gni
+++ b/webrtc.gni
@@ -227,10 +227,6 @@
rtc_libvpx_build_vp9 = !build_with_mozilla
rtc_build_opus = !build_with_mozilla
rtc_build_ssl = !build_with_mozilla
-
- # Can be set to true if rtc_build_ssl is false, but externally provided
- # openssl library is boringssl, to enable the use of boringssl-specific code.
- rtc_openssl_is_boringssl = !build_with_mozilla
rtc_build_usrsctp = !build_with_mozilla
# Enable libevent task queues on platforms that support it.