Commit 87659d07 authored by Anirudh Ramachandran's avatar Anirudh Ramachandran Committed by Facebook Github Bot

Add OpenSSL portability layer

Summary:
Enable folly to build with OpenSSL alternatives (e.g., BoringSSL).

Some SSL-related tests are disabled:

 - Async session cache ones (BoringSSL has an async cache impl but with a different API)
 - TFO tests
 - Some changes to error tests which expect specific error strings. This is
   flaky as a test because it will break everytime even within a version, so we
   should fix that first.

This should be a noop for OpenSSL 1.0.2.

BoringSSL commit used is 35c8afd3143289c99aa3820e01950c564d7aced8 (10/26/2016)

Closes: https://github.com/facebook/folly/issues/198

Reviewed By: siyengar

Differential Revision: D3280382

fbshipit-source-id: 4141d992e0d8dd797ac4af479cfe90844a23278f
parent ec5f59cf
...@@ -295,6 +295,7 @@ nobase_follyinclude_HEADERS = \ ...@@ -295,6 +295,7 @@ nobase_follyinclude_HEADERS = \
portability/Malloc.h \ portability/Malloc.h \
portability/Math.h \ portability/Math.h \
portability/Memory.h \ portability/Memory.h \
portability/OpenSSL.h \
portability/PThread.h \ portability/PThread.h \
portability/Sockets.h \ portability/Sockets.h \
portability/Stdio.h \ portability/Stdio.h \
...@@ -336,8 +337,8 @@ nobase_follyinclude_HEADERS = \ ...@@ -336,8 +337,8 @@ nobase_follyinclude_HEADERS = \
SpookyHashV1.h \ SpookyHashV1.h \
SpookyHashV2.h \ SpookyHashV2.h \
ssl/OpenSSLHash.h \ ssl/OpenSSLHash.h \
ssl/OpenSSLVersionFinder.h \
ssl/SSLSession.h \ ssl/SSLSession.h \
ssl/detail/OpenSSLVersionFinder.h \
ssl/detail/SSLSessionImpl.h \ ssl/detail/SSLSessionImpl.h \
stats/BucketedTimeSeries-defs.h \ stats/BucketedTimeSeries-defs.h \
stats/BucketedTimeSeries.h \ stats/BucketedTimeSeries.h \
...@@ -477,6 +478,7 @@ libfolly_la_SOURCES = \ ...@@ -477,6 +478,7 @@ libfolly_la_SOURCES = \
portability/Libgen.cpp \ portability/Libgen.cpp \
portability/Malloc.cpp \ portability/Malloc.cpp \
portability/Memory.cpp \ portability/Memory.cpp \
portability/OpenSSL.cpp \
portability/Sockets.cpp \ portability/Sockets.cpp \
portability/Stdio.cpp \ portability/Stdio.cpp \
portability/Stdlib.cpp \ portability/Stdlib.cpp \
......
...@@ -31,8 +31,9 @@ ...@@ -31,8 +31,9 @@
#include <folly/Bits.h> #include <folly/Bits.h>
#include <folly/SocketAddress.h> #include <folly/SocketAddress.h>
#include <folly/SpinLock.h> #include <folly/SpinLock.h>
#include <folly/io/IOBuf.h>
#include <folly/io/Cursor.h> #include <folly/io/Cursor.h>
#include <folly/io/IOBuf.h>
#include <folly/portability/OpenSSL.h>
#include <folly/portability/Unistd.h> #include <folly/portability/Unistd.h>
using folly::SocketAddress; using folly::SocketAddress;
...@@ -54,6 +55,8 @@ using folly::AsyncSocketException; ...@@ -54,6 +55,8 @@ using folly::AsyncSocketException;
using folly::AsyncSSLSocket; using folly::AsyncSSLSocket;
using folly::Optional; using folly::Optional;
using folly::SSLContext; using folly::SSLContext;
// For OpenSSL portability API
using namespace folly::ssl;
using folly::ssl::OpenSSLUtils; using folly::ssl::OpenSSLUtils;
// We have one single dummy SSL context so that we can implement attach // We have one single dummy SSL context so that we can implement attach
...@@ -475,8 +478,8 @@ void AsyncSSLSocket::attachSSLContext( ...@@ -475,8 +478,8 @@ void AsyncSSLSocket::attachSSLContext(
// previously called. // previously called.
// We need to update the initial_ctx if necessary // We need to update the initial_ctx if necessary
auto sslCtx = ctx->getSSLCtx(); auto sslCtx = ctx->getSSLCtx();
SSL_CTX_up_ref(sslCtx);
#ifndef OPENSSL_NO_TLSEXT #ifndef OPENSSL_NO_TLSEXT
CRYPTO_add(&sslCtx->references, 1, CRYPTO_LOCK_SSL_CTX);
// note that detachSSLContext has already freed ssl_->initial_ctx // note that detachSSLContext has already freed ssl_->initial_ctx
ssl_->initial_ctx = sslCtx; ssl_->initial_ctx = sslCtx;
#endif #endif
...@@ -773,7 +776,8 @@ void AsyncSSLSocket::setSSLSession(SSL_SESSION *session, bool takeOwnership) { ...@@ -773,7 +776,8 @@ void AsyncSSLSocket::setSSLSession(SSL_SESSION *session, bool takeOwnership) {
sslSession_ = session; sslSession_ = session;
if (!takeOwnership && session != nullptr) { if (!takeOwnership && session != nullptr) {
// Increment the reference count // Increment the reference count
CRYPTO_add(&session->references, 1, CRYPTO_LOCK_SSL_SESSION); // This API exists in BoringSSL and OpenSSL 1.1.0
SSL_SESSION_up_ref(session);
} }
} }
......
...@@ -35,6 +35,9 @@ struct CRYPTO_dynlock_value { ...@@ -35,6 +35,9 @@ struct CRYPTO_dynlock_value {
}; };
namespace folly { namespace folly {
//
// For OpenSSL portability API
using namespace folly::ssl;
bool SSLContext::initialized_ = false; bool SSLContext::initialized_ = false;
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <random> #include <random>
// This has to come before SSL. // This has to come before SSL.
#include <folly/portability/OpenSSL.h>
#include <folly/portability/Sockets.h> #include <folly/portability/Sockets.h>
#include <openssl/ssl.h> #include <openssl/ssl.h>
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
*/ */
#include <folly/io/async/ssl/OpenSSLUtils.h> #include <folly/io/async/ssl/OpenSSLUtils.h>
#include <folly/ScopeGuard.h> #include <folly/ScopeGuard.h>
#include <folly/portability/OpenSSL.h>
#include <folly/portability/Sockets.h> #include <folly/portability/Sockets.h>
#include <glog/logging.h> #include <glog/logging.h>
#include <openssl/bio.h> #include <openssl/bio.h>
...@@ -24,12 +25,6 @@ ...@@ -24,12 +25,6 @@
#include <openssl/x509v3.h> #include <openssl/x509v3.h>
#include <unordered_map> #include <unordered_map>
#define OPENSSL_IS_101 (OPENSSL_VERSION_NUMBER >= 0x1000105fL && \
OPENSSL_VERSION_NUMBER < 0x1000200fL)
#define OPENSSL_IS_102 (OPENSSL_VERSION_NUMBER >= 0x1000200fL && \
OPENSSL_VERSION_NUMBER < 0x10100000L)
#define OPENSSL_IS_110 (OPENSSL_VERSION_NUMBER >= 0x10100000L)
namespace { namespace {
#if defined(OPENSSL_IS_BORINGSSL) #if defined(OPENSSL_IS_BORINGSSL)
// BoringSSL doesn't (as of May 2016) export the equivalent // BoringSSL doesn't (as of May 2016) export the equivalent
...@@ -45,7 +40,7 @@ namespace ssl { ...@@ -45,7 +40,7 @@ namespace ssl {
bool OpenSSLUtils::getTLSMasterKey( bool OpenSSLUtils::getTLSMasterKey(
const SSL_SESSION* session, const SSL_SESSION* session,
MutableByteRange keyOut) { MutableByteRange keyOut) {
#if OPENSSL_IS_101 || OPENSSL_IS_102 #if FOLLY_OPENSSL_IS_101 || FOLLY_OPENSSL_IS_102
if (session && if (session &&
session->master_key_length == static_cast<int>(keyOut.size())) { session->master_key_length == static_cast<int>(keyOut.size())) {
auto masterKey = session->master_key; auto masterKey = session->master_key;
...@@ -53,6 +48,9 @@ bool OpenSSLUtils::getTLSMasterKey( ...@@ -53,6 +48,9 @@ bool OpenSSLUtils::getTLSMasterKey(
masterKey, masterKey + session->master_key_length, keyOut.begin()); masterKey, masterKey + session->master_key_length, keyOut.begin());
return true; return true;
} }
#else
(SSL_SESSION*)session;
(MutableByteRange) keyOut;
#endif #endif
return false; return false;
} }
...@@ -60,13 +58,16 @@ bool OpenSSLUtils::getTLSMasterKey( ...@@ -60,13 +58,16 @@ bool OpenSSLUtils::getTLSMasterKey(
bool OpenSSLUtils::getTLSClientRandom( bool OpenSSLUtils::getTLSClientRandom(
const SSL* ssl, const SSL* ssl,
MutableByteRange randomOut) { MutableByteRange randomOut) {
#if OPENSSL_IS_101 || OPENSSL_IS_102 #if FOLLY_OPENSSL_IS_101 || FOLLY_OPENSSL_IS_102
if ((SSL_version(ssl) >> 8) == TLS1_VERSION_MAJOR && ssl->s3 && if ((SSL_version(ssl) >> 8) == TLS1_VERSION_MAJOR && ssl->s3 &&
randomOut.size() == SSL3_RANDOM_SIZE) { randomOut.size() == SSL3_RANDOM_SIZE) {
auto clientRandom = ssl->s3->client_random; auto clientRandom = ssl->s3->client_random;
std::copy(clientRandom, clientRandom + SSL3_RANDOM_SIZE, randomOut.begin()); std::copy(clientRandom, clientRandom + SSL3_RANDOM_SIZE, randomOut.begin());
return true; return true;
} }
#else
(SSL*)ssl;
(MutableByteRange) randomOut;
#endif #endif
return false; return false;
} }
...@@ -121,7 +122,7 @@ bool OpenSSLUtils::validatePeerCertNames(X509* cert, ...@@ -121,7 +122,7 @@ bool OpenSSLUtils::validatePeerCertNames(X509* cert,
} }
} }
for (int i = 0; i < sk_GENERAL_NAME_num(altNames); i++) { for (size_t i = 0; i < (size_t)sk_GENERAL_NAME_num(altNames); i++) {
auto name = sk_GENERAL_NAME_value(altNames, i); auto name = sk_GENERAL_NAME_value(altNames, i);
if ((addr4 != nullptr || addr6 != nullptr) && name->type == GEN_IPADD) { if ((addr4 != nullptr || addr6 != nullptr) && name->type == GEN_IPADD) {
// Extra const-ness for paranoia // Extra const-ness for paranoia
...@@ -199,13 +200,7 @@ bool OpenSSLUtils::setCustomBioReadMethod( ...@@ -199,13 +200,7 @@ bool OpenSSLUtils::setCustomBioReadMethod(
BIO_METHOD* bioMeth, BIO_METHOD* bioMeth,
int (*meth)(BIO*, char*, int)) { int (*meth)(BIO*, char*, int)) {
bool ret = false; bool ret = false;
#if OPENSSL_IS_110
ret = (BIO_meth_set_read(bioMeth, meth) == 1); ret = (BIO_meth_set_read(bioMeth, meth) == 1);
#elif (defined(OPENSSL_IS_BORINGSSL) || OPENSSL_IS_101 || OPENSSL_IS_102)
bioMeth->bread = meth;
ret = true;
#endif
return ret; return ret;
} }
...@@ -213,13 +208,7 @@ bool OpenSSLUtils::setCustomBioWriteMethod( ...@@ -213,13 +208,7 @@ bool OpenSSLUtils::setCustomBioWriteMethod(
BIO_METHOD* bioMeth, BIO_METHOD* bioMeth,
int (*meth)(BIO*, const char*, int)) { int (*meth)(BIO*, const char*, int)) {
bool ret = false; bool ret = false;
#if OPENSSL_IS_110
ret = (BIO_meth_set_write(bioMeth, meth) == 1); ret = (BIO_meth_set_write(bioMeth, meth) == 1);
#elif (defined(OPENSSL_IS_BORINGSSL) || OPENSSL_IS_101 || OPENSSL_IS_102)
bioMeth->bwrite = meth;
ret = true;
#endif
return ret; return ret;
} }
......
...@@ -26,15 +26,29 @@ using namespace folly; ...@@ -26,15 +26,29 @@ using namespace folly;
TEST(SSLErrorsTest, TestMessage) { TEST(SSLErrorsTest, TestMessage) {
ERR_load_crypto_strings(); ERR_load_crypto_strings();
auto err = ERR_PACK( unsigned long err;
#ifdef OPENSSL_IS_BORINGSSL
err = ERR_PACK(ERR_LIB_X509, X509_R_CERT_ALREADY_IN_HASH_TABLE);
#else
err = ERR_PACK(
ERR_LIB_X509, ERR_LIB_X509,
X509_F_X509_STORE_ADD_CERT, X509_F_X509_STORE_ADD_CERT,
X509_R_CERT_ALREADY_IN_HASH_TABLE); X509_R_CERT_ALREADY_IN_HASH_TABLE);
#endif
SSLException ex(0, err, 0, 0); SSLException ex(0, err, 0, 0);
// This is flaky - we should not be testing error strings
// which may change version to version
#if defined(OPENSSL_IS_BORINGSSL)
std::string expectedMsg =
"AsyncSocketException: error:0b000069:X.509 certificate routines:"
"OPENSSL_internal:CERT_ALREADY_IN_HASH_TABLE, type = SSL error";
#else
std::string expectedMsg = std::string expectedMsg =
"AsyncSocketException: error:0B07C065:" "AsyncSocketException: error:0B07C065:"
"x509 certificate routines:X509_STORE_add_cert:" "x509 certificate routines:X509_STORE_add_cert:"
"cert already in hash table, type = SSL error"; "cert already in hash table, type = SSL error";
#endif
std::string actual = ex.what(); std::string actual = ex.what();
EXPECT_EQ(expectedMsg, actual); EXPECT_EQ(expectedMsg, actual);
} }
...@@ -239,6 +239,7 @@ TEST(AsyncSSLSocketTest, ReadAfterClose) { ...@@ -239,6 +239,7 @@ TEST(AsyncSSLSocketTest, ReadAfterClose) {
/** /**
* Test bad renegotiation * Test bad renegotiation
*/ */
#if !defined(OPENSSL_IS_BORINGSSL)
TEST(AsyncSSLSocketTest, Renegotiate) { TEST(AsyncSSLSocketTest, Renegotiate) {
EventBase eventBase; EventBase eventBase;
auto clientCtx = std::make_shared<SSLContext>(); auto clientCtx = std::make_shared<SSLContext>();
...@@ -284,6 +285,7 @@ TEST(AsyncSSLSocketTest, Renegotiate) { ...@@ -284,6 +285,7 @@ TEST(AsyncSSLSocketTest, Renegotiate) {
eventBase.loop(); eventBase.loop();
ASSERT_TRUE(server.renegotiationError_); ASSERT_TRUE(server.renegotiationError_);
} }
#endif
/** /**
* Negative test for handshakeError(). * Negative test for handshakeError().
...@@ -549,7 +551,18 @@ TEST_P(NextProtocolTest, NpnTestNoOverlap) { ...@@ -549,7 +551,18 @@ TEST_P(NextProtocolTest, NpnTestNoOverlap) {
// mismatch should result in a fatal alert, but this is OpenSSL's current // mismatch should result in a fatal alert, but this is OpenSSL's current
// behavior and we want to know if it changes. // behavior and we want to know if it changes.
expectNoProtocol(); expectNoProtocol();
} else { }
#if defined(OPENSSL_IS_BORINGSSL)
// BoringSSL also doesn't fatal on mismatch but behaves slightly differently
// from OpenSSL 1.0.2h+ - it doesn't select a protocol if both ends support
// NPN *and* ALPN
else if (
GetParam().first == SSLContext::NextProtocolType::ANY &&
GetParam().second == SSLContext::NextProtocolType::ANY) {
expectNoProtocol();
}
#endif
else {
expectProtocol("blub"); expectProtocol("blub");
expectProtocolType( expectProtocolType(
{SSLContext::NextProtocolType::NPN, SSLContext::NextProtocolType::NPN}); {SSLContext::NextProtocolType::NPN, SSLContext::NextProtocolType::NPN});
...@@ -877,7 +890,7 @@ TEST(AsyncSSLSocketTest, SSLClientTimeoutTest) { ...@@ -877,7 +890,7 @@ TEST(AsyncSSLSocketTest, SSLClientTimeoutTest) {
cerr << "SSLClientTimeoutTest test completed" << endl; cerr << "SSLClientTimeoutTest test completed" << endl;
} }
// This is a FB-only extension, and the tests will fail without it // The next 3 tests need an FB-only extension, and will fail without it
#ifdef SSL_ERROR_WANT_SESS_CACHE_LOOKUP #ifdef SSL_ERROR_WANT_SESS_CACHE_LOOKUP
/** /**
* Test SSL server async cache * Test SSL server async cache
...@@ -907,7 +920,6 @@ TEST(AsyncSSLSocketTest, SSLServerAsyncCacheTest) { ...@@ -907,7 +920,6 @@ TEST(AsyncSSLSocketTest, SSLServerAsyncCacheTest) {
cerr << "SSLServerAsyncCacheTest test completed" << endl; cerr << "SSLServerAsyncCacheTest test completed" << endl;
} }
/** /**
* Test SSL server accept timeout with cache path * Test SSL server accept timeout with cache path
*/ */
...@@ -999,7 +1011,7 @@ TEST(AsyncSSLSocketTest, SSLServerCacheCloseTest) { ...@@ -999,7 +1011,7 @@ TEST(AsyncSSLSocketTest, SSLServerCacheCloseTest) {
cerr << "SSLServerCacheCloseTest test completed" << endl; cerr << "SSLServerCacheCloseTest test completed" << endl;
} }
#endif #endif // !SSL_ERROR_WANT_SESS_CACHE_LOOKUP
/** /**
* Verify Client Ciphers obtained using SSL MSG Callback. * Verify Client Ciphers obtained using SSL MSG Callback.
...@@ -1016,7 +1028,7 @@ TEST(AsyncSSLSocketTest, SSLParseClientHelloSuccess) { ...@@ -1016,7 +1028,7 @@ TEST(AsyncSSLSocketTest, SSLParseClientHelloSuccess) {
serverCtx->loadClientCAList(testCA); serverCtx->loadClientCAList(testCA);
clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY); clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
clientCtx->ciphers("AES256-SHA:RC4-MD5"); clientCtx->ciphers("AES256-SHA:AES128-SHA");
clientCtx->loadPrivateKey(testKey); clientCtx->loadPrivateKey(testKey);
clientCtx->loadCertificate(testCert); clientCtx->loadCertificate(testCert);
clientCtx->loadTrustedCertificates(testCA); clientCtx->loadTrustedCertificates(testCA);
...@@ -1034,7 +1046,11 @@ TEST(AsyncSSLSocketTest, SSLParseClientHelloSuccess) { ...@@ -1034,7 +1046,11 @@ TEST(AsyncSSLSocketTest, SSLParseClientHelloSuccess) {
eventBase.loop(); eventBase.loop();
EXPECT_EQ(server.clientCiphers_, "AES256-SHA:RC4-MD5:00ff"); #if defined(OPENSSL_IS_BORINGSSL)
EXPECT_EQ(server.clientCiphers_, "AES256-SHA:AES128-SHA");
#else
EXPECT_EQ(server.clientCiphers_, "AES256-SHA:AES128-SHA:00ff");
#endif
EXPECT_EQ(server.chosenCipher_, "AES256-SHA"); EXPECT_EQ(server.chosenCipher_, "AES256-SHA");
EXPECT_TRUE(client.handshakeVerify_); EXPECT_TRUE(client.handshakeVerify_);
EXPECT_TRUE(client.handshakeSuccess_); EXPECT_TRUE(client.handshakeSuccess_);
...@@ -1692,8 +1708,14 @@ TEST(AsyncSSLSocketTest, ConnOpenSSLErrorString) { ...@@ -1692,8 +1708,14 @@ TEST(AsyncSSLSocketTest, ConnOpenSSLErrorString) {
handshakeCallback.waitForHandshake(); handshakeCallback.waitForHandshake();
EXPECT_NE(handshakeCallback.errorString_.find("SSL routines"), EXPECT_NE(handshakeCallback.errorString_.find("SSL routines"),
std::string::npos); std::string::npos);
#if defined(OPENSSL_IS_BORINGSSL)
EXPECT_NE(
handshakeCallback.errorString_.find("ENCRYPTED_LENGTH_TOO_LONG"),
std::string::npos);
#else
EXPECT_NE(handshakeCallback.errorString_.find("unknown protocol"), EXPECT_NE(handshakeCallback.errorString_.find("unknown protocol"),
std::string::npos); std::string::npos);
#endif
} }
TEST(AsyncSSLSocketTest, TestSSLCipherCodeToNameMap) { TEST(AsyncSSLSocketTest, TestSSLCipherCodeToNameMap) {
...@@ -1868,6 +1890,7 @@ TEST(AsyncSSLSocketTest, ConnectWriteReadCloseTFOFallback) { ...@@ -1868,6 +1890,7 @@ TEST(AsyncSSLSocketTest, ConnectWriteReadCloseTFOFallback) {
sock.close(); sock.close();
} }
#if !defined(OPENSSL_IS_BORINGSSL)
TEST(AsyncSSLSocketTest, ConnectTFOTimeout) { TEST(AsyncSSLSocketTest, ConnectTFOTimeout) {
// Start listening on a local port // Start listening on a local port
ConnectTimeoutCallback acceptCallback; ConnectTimeoutCallback acceptCallback;
...@@ -1883,7 +1906,9 @@ TEST(AsyncSSLSocketTest, ConnectTFOTimeout) { ...@@ -1883,7 +1906,9 @@ TEST(AsyncSSLSocketTest, ConnectTFOTimeout) {
EXPECT_THROW( EXPECT_THROW(
socket->open(std::chrono::milliseconds(20)), AsyncSocketException); socket->open(std::chrono::milliseconds(20)), AsyncSocketException);
} }
#endif
#if !defined(OPENSSL_IS_BORINGSSL)
TEST(AsyncSSLSocketTest, ConnectTFOFallbackTimeout) { TEST(AsyncSSLSocketTest, ConnectTFOFallbackTimeout) {
// Start listening on a local port // Start listening on a local port
ConnectTimeoutCallback acceptCallback; ConnectTimeoutCallback acceptCallback;
...@@ -1899,6 +1924,7 @@ TEST(AsyncSSLSocketTest, ConnectTFOFallbackTimeout) { ...@@ -1899,6 +1924,7 @@ TEST(AsyncSSLSocketTest, ConnectTFOFallbackTimeout) {
evb.loop(); evb.loop();
EXPECT_EQ(ConnCallback::State::ERROR, ccb.state); EXPECT_EQ(ConnCallback::State::ERROR, ccb.state);
} }
#endif
TEST(AsyncSSLSocketTest, HandshakeTFOFallbackTimeout) { TEST(AsyncSSLSocketTest, HandshakeTFOFallbackTimeout) {
// Start listening on a local port // Start listening on a local port
......
...@@ -683,6 +683,7 @@ class TestSSLAsyncCacheServer : public TestSSLServer { ...@@ -683,6 +683,7 @@ class TestSSLAsyncCacheServer : public TestSSLServer {
int* copyflag) { int* copyflag) {
*copyflag = 0; *copyflag = 0;
asyncCallbacks_++; asyncCallbacks_++;
(void)ssl;
#ifdef SSL_ERROR_WANT_SESS_CACHE_LOOKUP #ifdef SSL_ERROR_WANT_SESS_CACHE_LOOKUP
if (!SSL_want_sess_cache_lookup(ssl)) { if (!SSL_want_sess_cache_lookup(ssl)) {
// libssl.so mismatch // libssl.so mismatch
......
...@@ -197,9 +197,16 @@ int main(int argc, char *argv[]) { ...@@ -197,9 +197,16 @@ int main(int argc, char *argv[]) {
signal(SIGPIPE, SIG_IGN); signal(SIGPIPE, SIG_IGN);
#endif #endif
folly::SSLContext::setSSLLockTypes({ folly::SSLContext::setSSLLockTypes({
#ifdef CRYPTO_LOCK_EVP_PKEY
{CRYPTO_LOCK_EVP_PKEY, folly::SSLContext::LOCK_NONE}, {CRYPTO_LOCK_EVP_PKEY, folly::SSLContext::LOCK_NONE},
#endif
#ifdef CRYPTO_LOCK_SSL_SESSION
{CRYPTO_LOCK_SSL_SESSION, folly::SSLContext::LOCK_SPINLOCK}, {CRYPTO_LOCK_SSL_SESSION, folly::SSLContext::LOCK_SPINLOCK},
{CRYPTO_LOCK_SSL_CTX, folly::SSLContext::LOCK_NONE}}); #endif
#ifdef CRYPTO_LOCK_SSL_CTX
{CRYPTO_LOCK_SSL_CTX, folly::SSLContext::LOCK_NONE}
#endif
});
testing::InitGoogleTest(&argc, argv); testing::InitGoogleTest(&argc, argv);
gflags::ParseCommandLineFlags(&argc, &argv, true); gflags::ParseCommandLineFlags(&argc, &argv, true);
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
......
/*
* Copyright 2016 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <folly/portability/OpenSSL.h>
namespace folly {
namespace ssl {
#ifdef OPENSSL_IS_BORINGSSL
int SSL_CTX_set1_sigalgs_list(SSL_CTX*, const char*) {
return 1; // 0 implies error
}
int TLS1_get_client_version(SSL* s) {
return s->client_version;
}
int BIO_meth_set_read(BIO_METHOD* biom, int (*read)(BIO*, char*, int)) {
biom->bread = read;
return 1;
}
int BIO_meth_set_write(BIO_METHOD* biom, int (*write)(BIO*, const char*, int)) {
biom->bwrite = write;
return 1;
}
#elif FOLLY_OPENSSL_IS_102 || FOLLY_OPENSSL_IS_101
int SSL_CTX_up_ref(SSL_CTX* ctx) {
return CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
}
int SSL_SESSION_up_ref(SSL_SESSION* session) {
return CRYPTO_add(&session->references, 1, CRYPTO_LOCK_SSL_SESSION);
}
int X509_up_ref(X509* x) {
return CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
}
int BIO_meth_set_read(BIO_METHOD* biom, int (*read)(BIO*, char*, int)) {
biom->bread = read;
return 1;
}
int BIO_meth_set_write(BIO_METHOD* biom, int (*write)(BIO*, const char*, int)) {
biom->bwrite = write;
return 1;
}
#elif FOLLY_OPENSSL_IS_110
#endif
}
}
/*
* Copyright 2016 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <openssl/ssl.h>
#include <openssl/x509.h>
namespace folly {
namespace ssl {
// BoringSSL doesn't have notion of versioning although it defines
// OPENSSL_VERSION_NUMBER to maintain compatibility. The following variables are
// intended to be specific to OpenSSL.
#if !defined(OPENSSL_IS_BORINGSSL)
#define FOLLY_OPENSSL_IS_101 \
(OPENSSL_VERSION_NUMBER >= 0x1000105fL && \
OPENSSL_VERSION_NUMBER < 0x1000200fL)
#define FOLLY_OPENSSL_IS_102 \
(OPENSSL_VERSION_NUMBER >= 0x1000200fL && \
OPENSSL_VERSION_NUMBER < 0x10100000L)
#define FOLLY_OPENSSL_IS_110 (OPENSSL_VERSION_NUMBER >= 0x10100000L)
#endif // !defined(OPENSSL_IS_BORINGSSL)
// This class attempts to "unify" the OpenSSL libssl APIs between OpenSSL 1.0.2,
// 1.1.0 and BoringSSL. The general idea is to provide wrapper methods for 1.0.2
// which already exist in BoringSSL and 1.1.0, but there are few APIs such as
// SSL_CTX_set1_sigalgs_list and so on which exist in 1.0.2 but were removed
// in BoringSSL
#ifdef OPENSSL_IS_BORINGSSL
int SSL_CTX_set1_sigalgs_list(SSL_CTX* ctx, const char* sigalgs_list);
int TLS1_get_client_version(SSL* s);
int BIO_meth_set_read(BIO_METHOD* biom, int (*read)(BIO*, char*, int));
int BIO_meth_set_write(BIO_METHOD* biom, int (*write)(BIO*, const char*, int));
#elif FOLLY_OPENSSL_IS_102 || FOLLY_OPENSSL_IS_101
int SSL_CTX_up_ref(SSL_CTX* session);
int SSL_SESSION_up_ref(SSL_SESSION* session);
int X509_up_ref(X509* x);
int BIO_meth_set_read(BIO_METHOD* biom, int (*read)(BIO*, char*, int));
int BIO_meth_set_write(BIO_METHOD* biom, int (*write)(BIO*, const char*, int));
#elif FOLLY_OPENSSL_IS_110
#else
#warning Compiling with unsupported OpenSSL version
#endif
} // ssl
} // folly
...@@ -16,23 +16,11 @@ ...@@ -16,23 +16,11 @@
#pragma once #pragma once
#include <folly/Conv.h> #include <folly/Conv.h>
#include <folly/portability/OpenSSL.h>
#include <openssl/crypto.h> #include <openssl/crypto.h>
#include <openssl/opensslv.h> #include <openssl/opensslv.h>
// BoringSSL doesn't have notion of versioning although it defines
// OPENSSL_VERSION_NUMBER to maintain compatibility. The following variables are
// intended to be specific to OpenSSL.
#if !defined(OPENSSL_IS_BORINGSSL)
# define OPENSSL_IS_101 \
(OPENSSL_VERSION_NUMBER >= 0x1000105fL && \
OPENSSL_VERSION_NUMBER < 0x1000200fL)
# define OPENSSL_IS_102 \
(OPENSSL_VERSION_NUMBER >= 0x1000200fL && \
OPENSSL_VERSION_NUMBER < 0x10100000L)
# define OPENSSL_IS_110 (OPENSSL_VERSION_NUMBER >= 0x10100000L)
#endif // !defined(OPENSSL_IS_BORINGSSL)
// This is used to find the OpenSSL version at runtime. Just returning // This is used to find the OpenSSL version at runtime. Just returning
// OPENSSL_VERSION_NUMBER is insufficient as runtime version may be different // OPENSSL_VERSION_NUMBER is insufficient as runtime version may be different
// from the compile-time version // from the compile-time version
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#pragma once #pragma once
#include <folly/Memory.h> #include <folly/Memory.h>
#include <folly/ssl/detail/OpenSSLVersionFinder.h> #include <folly/portability/OpenSSL.h>
#include <folly/ssl/detail/SSLSessionImpl.h> #include <folly/ssl/detail/SSLSessionImpl.h>
namespace folly { namespace folly {
......
...@@ -15,7 +15,8 @@ ...@@ -15,7 +15,8 @@
*/ */
#include <folly/ssl/detail/SSLSessionImpl.h> #include <folly/ssl/detail/SSLSessionImpl.h>
#include <folly/ssl/detail/OpenSSLVersionFinder.h> #include <folly/portability/OpenSSL.h>
#include <folly/ssl/OpenSSLVersionFinder.h>
namespace folly { namespace folly {
namespace ssl { namespace ssl {
...@@ -74,12 +75,7 @@ std::string SSLSessionImpl::getSessionID() const { ...@@ -74,12 +75,7 @@ std::string SSLSessionImpl::getSessionID() const {
if (session_) { if (session_) {
const unsigned char* ptr = nullptr; const unsigned char* ptr = nullptr;
unsigned int len = 0; unsigned int len = 0;
#if defined(OPENSSL_IS_102) || defined(OPENSSL_IS_101)
len = session_->session_id_length;
ptr = session_->session_id;
#elif defined(OPENSSL_IS_110) || defined(OPENSSL_IS_BORINGSSL)
ptr = SSL_SESSION_get_id(session_, &len); ptr = SSL_SESSION_get_id(session_, &len);
#endif
ret.assign(ptr, ptr + len); ret.assign(ptr, ptr + len);
} }
return ret; return ret;
...@@ -96,11 +92,7 @@ SSL_SESSION* SSLSessionImpl::getRawSSLSessionDangerous() { ...@@ -96,11 +92,7 @@ SSL_SESSION* SSLSessionImpl::getRawSSLSessionDangerous() {
void SSLSessionImpl::upRef() { void SSLSessionImpl::upRef() {
if (session_) { if (session_) {
#if defined(OPENSSL_IS_102) || defined(OPENSSL_IS_101)
CRYPTO_add(&session_->references, 1, CRYPTO_LOCK_SSL_SESSION);
#elif defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_110)
SSL_SESSION_up_ref(session_); SSL_SESSION_up_ref(session_);
#endif
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment