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}
This commit is contained in:
Sam Zackrisson
2020-12-10 07:55:28 +00:00
committed by Commit Bot
parent 72f638a9a2
commit 7e6290d1d2
24 changed files with 278 additions and 1619 deletions

View File

@ -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::SetCertVerifier(
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 @@ void OpenSSLAdapter::SSLInfoCallback(const SSL* s, int where, int ret) {
#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 @@ int OpenSSLAdapter::SSLVerifyInternal(int ok, SSL* ssl, X509_STORE_CTX* store) {
<< 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 @@ int OpenSSLAdapter::NewSSLSessionCallback(SSL* ssl, SSL_SESSION* session) {
}
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* OpenSSLAdapter::CreateContext(SSLMode mode, bool enable_cache) {
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