Reland: 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.

No-Try: True
Bug: webrtc:11410
Change-Id: I86ddb361b94ad85b15ebb8743490de83632ca53f
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/196941
Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#32818}
This commit is contained in:
Taylor Brandstetter
2020-12-10 16:23:03 -08:00
committed by Commit Bot
parent c1ad1ff178
commit 165c618bb9
24 changed files with 1620 additions and 279 deletions

View File

@ -508,8 +508,9 @@ class SSLStreamAdapterTestBase : public ::testing::Test,
}
}
// This tests that the handshake can complete before the identity is
// verified, and the identity will be verified after the fact.
// 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.
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);
@ -524,14 +525,9 @@ class SSLStreamAdapterTestBase : public ::testing::Test,
}
// Start the handshake
int rv;
server_ssl_->SetServerRole();
rv = server_ssl_->StartSSL();
ASSERT_EQ(0, rv);
rv = client_ssl_->StartSSL();
ASSERT_EQ(0, rv);
ASSERT_EQ(0, server_ssl_->StartSSL());
ASSERT_EQ(0, client_ssl_->StartSSL());
// Now run the handshake.
EXPECT_TRUE_WAIT(
@ -547,16 +543,57 @@ class SSLStreamAdapterTestBase : public ::testing::Test,
EXPECT_EQ(rtc::SR_BLOCK, client_ssl_->Write(&packet, 1, &sent, 0));
EXPECT_EQ(rtc::SR_BLOCK, server_ssl_->Write(&packet, 1, &sent, 0));
// If we set an invalid identity at this point, SetPeerCertificateDigest
// should return false.
SetPeerIdentitiesByDigest(valid_identity, valid_identity);
// 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);
// 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());
EXPECT_EQ(rtc::SS_OPEN, server_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, server_ssl_->GetState());
}
}