Commit 9783dc4e authored by Christopher Dykes's avatar Christopher Dykes Committed by Facebook Github Bot

Re-work the OpenSSL portability header to be a portability header

Summary:
It was defining the same functions as OpenSSL, but it was putting them in the `folly::ssl` namespace and requiring a manual `use namespace` everywhere to actually be able to use it. Proper portability headers require no interaction to function correctly other than including them in the build.
This adjusts it so including it is all that is required to get an OpenSSL 1.1.0 compatible API.
This also re-organizes the code to significantly lower the amount of nesting in the `#if`'s, and puts it in order from oldest APIs to newest, rather than haphazard.

Reviewed By: yfeldblum

Differential Revision: D4856784

fbshipit-source-id: 7c00fdf4a3e51e37287d2b1ef294046f38a96a43
parent 46b709bc
...@@ -14,20 +14,57 @@ ...@@ -14,20 +14,57 @@
* limitations under the License. * limitations under the License.
*/ */
#include <folly/portability/OpenSSL.h> #include <folly/portability/OpenSSL.h>
#include <stdexcept> #include <stdexcept>
namespace folly { namespace folly {
namespace portability {
namespace ssl { namespace ssl {
#if FOLLY_OPENSSL_IS_110 #if OPENSSL_IS_BORINGSSL
//////////////////////////////////////////////////////////////////////////////// int SSL_CTX_set1_sigalgs_list(SSL_CTX*, const char*) {
// APIs needed in 1.1.0 only return 1; // 0 implies error
//////////////////////////////////////////////////////////////////////////////// }
int TLS1_get_client_version(SSL* s) {
// Note that this isn't the client version, and the API to
// get this has been hidden. It may be found by parsing the
// ClientHello (there is a callback via the SSL_HANDSHAKE struct)
return s->version;
}
#endif
#if FOLLY_OPENSSL_IS_100
uint32_t SSL_CIPHER_get_id(const SSL_CIPHER* c) {
return c->id;
}
int TLS1_get_client_version(const SSL* s) {
return (s->client_version >> 8) == TLS1_VERSION_MAJOR ? s->client_version : 0;
}
#endif
#if FOLLY_OPENSSL_IS_100 || FOLLY_OPENSSL_IS_101
int X509_get_signature_nid(X509* cert) {
return OBJ_obj2nid(cert->sig_alg->algorithm);
}
#endif
#if FOLLY_OPENSSL_IS_100 || FOLLY_OPENSSL_IS_101 || FOLLY_OPENSSL_IS_102
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);
}
#endif
#else #if !FOLLY_OPENSSL_IS_110
////////////////////////////////////////////////////////////////////////////////
// APIs needed in BoringSSL and OpenSSL < 1.1.0 (i.e., 1.0.2, 1.0.1, 1.0.0, etc)
////////////////////////////////////////////////////////////////////////////////
void BIO_meth_free(BIO_METHOD* biom) { void BIO_meth_free(BIO_METHOD* biom) {
OPENSSL_free((void*)biom); OPENSSL_free((void*)biom);
} }
...@@ -42,15 +79,11 @@ int BIO_meth_set_write(BIO_METHOD* biom, int (*write)(BIO*, const char*, int)) { ...@@ -42,15 +79,11 @@ int BIO_meth_set_write(BIO_METHOD* biom, int (*write)(BIO*, const char*, int)) {
return 1; return 1;
} }
void EVP_MD_CTX_free(EVP_MD_CTX* ctx) {
EVP_MD_CTX_destroy(ctx);
}
const char* SSL_SESSION_get0_hostname(const SSL_SESSION* s) { const char* SSL_SESSION_get0_hostname(const SSL_SESSION* s) {
return s->tlsext_hostname; return s->tlsext_hostname;
} }
EVP_MD_CTX* EVP_MD_CTX_new(void) { EVP_MD_CTX* EVP_MD_CTX_new() {
EVP_MD_CTX* ctx = (EVP_MD_CTX*)OPENSSL_malloc(sizeof(EVP_MD_CTX)); EVP_MD_CTX* ctx = (EVP_MD_CTX*)OPENSSL_malloc(sizeof(EVP_MD_CTX));
if (!ctx) { if (!ctx) {
throw std::runtime_error("Cannot allocate EVP_MD_CTX"); throw std::runtime_error("Cannot allocate EVP_MD_CTX");
...@@ -59,7 +92,11 @@ EVP_MD_CTX* EVP_MD_CTX_new(void) { ...@@ -59,7 +92,11 @@ EVP_MD_CTX* EVP_MD_CTX_new(void) {
return ctx; return ctx;
} }
HMAC_CTX* HMAC_CTX_new(void) { void EVP_MD_CTX_free(EVP_MD_CTX* ctx) {
EVP_MD_CTX_destroy(ctx);
}
HMAC_CTX* HMAC_CTX_new() {
HMAC_CTX* ctx = (HMAC_CTX*)OPENSSL_malloc(sizeof(HMAC_CTX)); HMAC_CTX* ctx = (HMAC_CTX*)OPENSSL_malloc(sizeof(HMAC_CTX));
if (!ctx) { if (!ctx) {
throw std::runtime_error("Cannot allocate HMAC_CTX"); throw std::runtime_error("Cannot allocate HMAC_CTX");
...@@ -116,67 +153,8 @@ int DH_set0_pqg(DH* dh, BIGNUM* p, BIGNUM* q, BIGNUM* g) { ...@@ -116,67 +153,8 @@ int DH_set0_pqg(DH* dh, BIGNUM* p, BIGNUM* q, BIGNUM* g) {
return 1; return 1;
} }
#ifdef OPENSSL_IS_BORINGSSL
////////////////////////////////////////////////////////////////////////////////
// APIs needed in BoringSSL only
////////////////////////////////////////////////////////////////////////////////
int SSL_CTX_set1_sigalgs_list(SSL_CTX*, const char*) {
return 1; // 0 implies error
}
int TLS1_get_client_version(SSL* s) {
// Note that this isn't the client version, and the API to
// get this has been hidden. It may be found by parsing the
// ClientHello (there is a callback via the SSL_HANDSHAKE struct)
return s->version;
}
#elif FOLLY_OPENSSL_IS_102 || FOLLY_OPENSSL_IS_101 || FOLLY_OPENSSL_IS_100
////////////////////////////////////////////////////////////////////////////////
// APIs needed in 1.0.2 and 1.0.1/1.0.0 (both deprecated)
////////////////////////////////////////////////////////////////////////////////
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);
}
#if FOLLY_OPENSSL_IS_101 || FOLLY_OPENSSL_IS_100
////////////////////////////////////////////////////////////////////////////////
// APIs needed in 1.0.1/1.0.0 (both deprecated)
////////////////////////////////////////////////////////////////////////////////
int X509_get_signature_nid(X509* cert) {
return OBJ_obj2nid(cert->sig_alg->algorithm);
}
#endif #endif
#if FOLLY_OPENSSL_IS_100
////////////////////////////////////////////////////////////////////////////////
// APIs needed only in 1.0.0 only (deprecated)
////////////////////////////////////////////////////////////////////////////////
uint32_t SSL_CIPHER_get_id(const SSL_CIPHER* c) {
return c->id;
}
int TLS1_get_client_version(const SSL* s) {
return (s->client_version >> 8) == TLS1_VERSION_MAJOR ? s->client_version : 0;
} }
#endif
#endif // !(OPENSSL_IS_BORINGSSL ||
// FOLLY_OPENSSL_IS_101 ||
// FOLLY_OPENSSL_IS_102 ||
// FOLLY_OPENSSL_IS_100)
#endif // !FOLLY_OPENSSL_IS_110
} }
} }
...@@ -14,129 +14,110 @@ ...@@ -14,129 +14,110 @@
* limitations under the License. * limitations under the License.
*/ */
//
// This class attempts to "unify" the OpenSSL libcrypto/libssl APIs between
// OpenSSL 1.0.2, 1.1.0 (and some earlier versions) and BoringSSL. The general
// idea is to provide namespaced wrapper methods for versions which do not
// 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
//
#pragma once #pragma once
// This must come before the OpenSSL includes. // This must come before the OpenSSL includes.
#include <folly/portability/Windows.h> #include <folly/portability/Windows.h>
#include <folly/Portability.h>
#include <openssl/dh.h> #include <openssl/dh.h>
#include <openssl/evp.h> #include <openssl/evp.h>
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <openssl/x509.h> #include <openssl/x509.h>
#include <cstdint>
namespace folly {
namespace ssl {
// BoringSSL doesn't have notion of versioning although it defines // BoringSSL doesn't have notion of versioning although it defines
// OPENSSL_VERSION_NUMBER to maintain compatibility. The following variables are // OPENSSL_VERSION_NUMBER to maintain compatibility. The following variables are
// intended to be specific to OpenSSL. // intended to be specific to OpenSSL.
#if !defined(OPENSSL_IS_BORINGSSL) #if !defined(OPENSSL_IS_BORINGSSL)
#define FOLLY_OPENSSL_IS_100 \ # define FOLLY_OPENSSL_IS_100 \
(OPENSSL_VERSION_NUMBER >= 0x10000003L && \ (OPENSSL_VERSION_NUMBER >= 0x10000003L && \
OPENSSL_VERSION_NUMBER < 0x1000105fL) OPENSSL_VERSION_NUMBER < 0x1000105fL)
#define FOLLY_OPENSSL_IS_101 \ # define FOLLY_OPENSSL_IS_101 \
(OPENSSL_VERSION_NUMBER >= 0x1000105fL && \ (OPENSSL_VERSION_NUMBER >= 0x1000105fL && \
OPENSSL_VERSION_NUMBER < 0x1000200fL) OPENSSL_VERSION_NUMBER < 0x1000200fL)
#define FOLLY_OPENSSL_IS_102 \ # define FOLLY_OPENSSL_IS_102 \
(OPENSSL_VERSION_NUMBER >= 0x1000200fL && \ (OPENSSL_VERSION_NUMBER >= 0x1000200fL && \
OPENSSL_VERSION_NUMBER < 0x10100000L) OPENSSL_VERSION_NUMBER < 0x10100000L)
#define FOLLY_OPENSSL_IS_110 (OPENSSL_VERSION_NUMBER >= 0x10100000L) # define FOLLY_OPENSSL_IS_110 (OPENSSL_VERSION_NUMBER >= 0x10100000L)
#endif // !defined(OPENSSL_IS_BORINGSSL) #endif
// BoringSSL and OpenSSL 1.0.2 later with TLS extension support ALPN. #if !OPENSSL_IS_BORINGSSL && !FOLLY_OPENSSL_IS_100 && !FOLLY_OPENSSL_IS_101 \
#if defined(OPENSSL_IS_BORINGSSL) || \ && !FOLLY_OPENSSL_IS_102 && !FOLLY_OPENSSL_IS_110
(OPENSSL_VERSION_NUMBER >= 0x1000200fL && \ # warning Compiling with unsupported OpenSSL version
!defined(OPENSSL_NO_TLSEXT))
#define FOLLY_OPENSSL_HAS_ALPN 1
#else
#define FOLLY_OPENSSL_HAS_ALPN 0
#endif #endif
// BoringSSL and OpenSSL 0.9.8f later with TLS extension support SNI. // BoringSSL and OpenSSL 0.9.8f later with TLS extension support SNI.
#if defined(OPENSSL_IS_BORINGSSL) || \ #if OPENSSL_IS_BORINGSSL || \
(OPENSSL_VERSION_NUMBER >= 0x00908070L && \ (OPENSSL_VERSION_NUMBER >= 0x00908070L && !defined(OPENSSL_NO_TLSEXT))
!defined(OPENSSL_NO_TLSEXT)) # define FOLLY_OPENSSL_HAS_SNI 1
#define FOLLY_OPENSSL_HAS_SNI 1
#else #else
#define FOLLY_OPENSSL_HAS_SNI 0 # define FOLLY_OPENSSL_HAS_SNI 0
#endif #endif
#if FOLLY_OPENSSL_IS_110 // BoringSSL and OpenSSL 1.0.2 later with TLS extension support ALPN.
//////////////////////////////////////////////////////////////////////////////// #if OPENSSL_IS_BORINGSSL || \
// APIs needed in 1.1.0 only (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(OPENSSL_NO_TLSEXT))
//////////////////////////////////////////////////////////////////////////////// # define FOLLY_OPENSSL_HAS_ALPN 1
#else #else
//////////////////////////////////////////////////////////////////////////////// # define FOLLY_OPENSSL_HAS_ALPN 0
// APIs needed in BoringSSL and OpenSSL != 1.1.0 (1.0.2, 1.0.1, 1.0.0...) #endif
////////////////////////////////////////////////////////////////////////////////
void BIO_meth_free(BIO_METHOD* biom);
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));
void EVP_MD_CTX_free(EVP_MD_CTX* ctx);
const char* SSL_SESSION_get0_hostname(const SSL_SESSION* s);
EVP_MD_CTX* EVP_MD_CTX_new(void);
void EVP_MD_CTX_free(EVP_MD_CTX* ctx);
HMAC_CTX* HMAC_CTX_new(void);
void HMAC_CTX_free(HMAC_CTX* ctx);
unsigned long SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION* s);
int SSL_SESSION_has_ticket(const SSL_SESSION*);
int DH_set0_pqg(DH* dh, BIGNUM* p, BIGNUM* q, BIGNUM* g);
#ifdef OPENSSL_IS_BORINGSSL // This attempts to "unify" the OpenSSL libcrypto/libssl APIs between
//////////////////////////////////////////////////////////////////////////////// // OpenSSL 1.0.2, 1.1.0 (and some earlier versions) and BoringSSL. The general
// APIs needed in BoringSSL only // idea is to provide namespaced wrapper methods for versions which do not
//////////////////////////////////////////////////////////////////////////////// // 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
namespace folly {
namespace portability {
namespace ssl {
#if OPENSSL_IS_BORINGSSL
int SSL_CTX_set1_sigalgs_list(SSL_CTX* ctx, const char* sigalgs_list); int SSL_CTX_set1_sigalgs_list(SSL_CTX* ctx, const char* sigalgs_list);
int TLS1_get_client_version(SSL* s); int TLS1_get_client_version(SSL* s);
#endif
#elif FOLLY_OPENSSL_IS_102 || FOLLY_OPENSSL_IS_101 || FOLLY_OPENSSL_IS_100 #if FOLLY_OPENSSL_IS_100
//////////////////////////////////////////////////////////////////////////////// uint32_t SSL_CIPHER_get_id(const SSL_CIPHER*);
// APIs needed in 1.0.2 and 1.0.1/1.0.0 (both deprecated) int TLS1_get_client_version(const SSL*);
//////////////////////////////////////////////////////////////////////////////// #endif
#if FOLLY_OPENSSL_IS_100 || FOLLY_OPENSSL_IS_101
int X509_get_signature_nid(X509* cert);
#endif
#if FOLLY_OPENSSL_IS_100 || FOLLY_OPENSSL_IS_101 || FOLLY_OPENSSL_IS_102
int SSL_CTX_up_ref(SSL_CTX* session); int SSL_CTX_up_ref(SSL_CTX* session);
int SSL_SESSION_up_ref(SSL_SESSION* session); int SSL_SESSION_up_ref(SSL_SESSION* session);
int X509_up_ref(X509* x); int X509_up_ref(X509* x);
#endif
#if FOLLY_OPENSSL_IS_101 || FOLLY_OPENSSL_IS_100 #if !FOLLY_OPENSSL_IS_110
//////////////////////////////////////////////////////////////////////////////// void BIO_meth_free(BIO_METHOD* biom);
// APIs needed in 1.0.1/1.0.0 (both deprecated) 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));
int X509_get_signature_nid(X509* cert);
#endif const char* SSL_SESSION_get0_hostname(const SSL_SESSION* s);
#if FOLLY_OPENSSL_IS_100 EVP_MD_CTX* EVP_MD_CTX_new();
//////////////////////////////////////////////////////////////////////////////// void EVP_MD_CTX_free(EVP_MD_CTX* ctx);
// APIs needed only in 1.0.0 only (deprecated)
////////////////////////////////////////////////////////////////////////////////
uint32_t SSL_CIPHER_get_id(const SSL_CIPHER*); HMAC_CTX* HMAC_CTX_new();
int TLS1_get_client_version(const SSL*); void HMAC_CTX_free(HMAC_CTX* ctx);
unsigned long SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION* s);
int SSL_SESSION_has_ticket(const SSL_SESSION* s);
int DH_set0_pqg(DH* dh, BIGNUM* p, BIGNUM* q, BIGNUM* g);
#endif #endif
#else
#warning Compiling with unsupported OpenSSL version
#endif // !(OPENSSL_IS_BORINGSSL || FOLLY_OPENSSL_IS_101 ||
// FOLLY_OPENSSL_IS_102 || FOLLY_OPENSSL_IS_100)
#endif // !FOLLY_OPENSSL_IS_110 }
}
}
} // ssl FOLLY_PUSH_WARNING
} // folly #if __CLANG_PREREQ(3, 0)
FOLLY_GCC_DISABLE_WARNING(header-hygiene)
#endif
/* using override */ using namespace folly::portability::ssl;
FOLLY_POP_WARNING
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