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 @@
* limitations under the License.
*/
#include <folly/portability/OpenSSL.h>
#include <stdexcept>
namespace folly {
namespace portability {
namespace ssl {
#if FOLLY_OPENSSL_IS_110
////////////////////////////////////////////////////////////////////////////////
// APIs needed in 1.1.0 only
////////////////////////////////////////////////////////////////////////////////
#if 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) {
// 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
////////////////////////////////////////////////////////////////////////////////
// APIs needed in BoringSSL and OpenSSL < 1.1.0 (i.e., 1.0.2, 1.0.1, 1.0.0, etc)
////////////////////////////////////////////////////////////////////////////////
#if !FOLLY_OPENSSL_IS_110
void BIO_meth_free(BIO_METHOD* biom) {
OPENSSL_free((void*)biom);
}
......@@ -42,15 +79,11 @@ int BIO_meth_set_write(BIO_METHOD* biom, int (*write)(BIO*, const char*, int)) {
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) {
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));
if (!ctx) {
throw std::runtime_error("Cannot allocate EVP_MD_CTX");
......@@ -59,7 +92,11 @@ EVP_MD_CTX* EVP_MD_CTX_new(void) {
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));
if (!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) {
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
#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 @@
* 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
// This must come before the OpenSSL includes.
#include <folly/portability/Windows.h>
#include <folly/Portability.h>
#include <openssl/dh.h>
#include <openssl/evp.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include <cstdint>
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_100 \
# define FOLLY_OPENSSL_IS_100 \
(OPENSSL_VERSION_NUMBER >= 0x10000003L && \
OPENSSL_VERSION_NUMBER < 0x1000105fL)
#define FOLLY_OPENSSL_IS_101 \
# define FOLLY_OPENSSL_IS_101 \
(OPENSSL_VERSION_NUMBER >= 0x1000105fL && \
OPENSSL_VERSION_NUMBER < 0x1000200fL)
#define FOLLY_OPENSSL_IS_102 \
# 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)
# define FOLLY_OPENSSL_IS_110 (OPENSSL_VERSION_NUMBER >= 0x10100000L)
#endif
// BoringSSL and OpenSSL 1.0.2 later with TLS extension support ALPN.
#if defined(OPENSSL_IS_BORINGSSL) || \
(OPENSSL_VERSION_NUMBER >= 0x1000200fL && \
!defined(OPENSSL_NO_TLSEXT))
#define FOLLY_OPENSSL_HAS_ALPN 1
#else
#define FOLLY_OPENSSL_HAS_ALPN 0
#if !OPENSSL_IS_BORINGSSL && !FOLLY_OPENSSL_IS_100 && !FOLLY_OPENSSL_IS_101 \
&& !FOLLY_OPENSSL_IS_102 && !FOLLY_OPENSSL_IS_110
# warning Compiling with unsupported OpenSSL version
#endif
// BoringSSL and OpenSSL 0.9.8f later with TLS extension support SNI.
#if defined(OPENSSL_IS_BORINGSSL) || \
(OPENSSL_VERSION_NUMBER >= 0x00908070L && \
!defined(OPENSSL_NO_TLSEXT))
#define FOLLY_OPENSSL_HAS_SNI 1
#if OPENSSL_IS_BORINGSSL || \
(OPENSSL_VERSION_NUMBER >= 0x00908070L && !defined(OPENSSL_NO_TLSEXT))
# define FOLLY_OPENSSL_HAS_SNI 1
#else
#define FOLLY_OPENSSL_HAS_SNI 0
# define FOLLY_OPENSSL_HAS_SNI 0
#endif
#if FOLLY_OPENSSL_IS_110
////////////////////////////////////////////////////////////////////////////////
// APIs needed in 1.1.0 only
////////////////////////////////////////////////////////////////////////////////
// BoringSSL and OpenSSL 1.0.2 later with TLS extension support ALPN.
#if OPENSSL_IS_BORINGSSL || \
(OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(OPENSSL_NO_TLSEXT))
# define FOLLY_OPENSSL_HAS_ALPN 1
#else
////////////////////////////////////////////////////////////////////////////////
// APIs needed in BoringSSL and OpenSSL != 1.1.0 (1.0.2, 1.0.1, 1.0.0...)
////////////////////////////////////////////////////////////////////////////////
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);
# define FOLLY_OPENSSL_HAS_ALPN 0
#endif
#ifdef OPENSSL_IS_BORINGSSL
////////////////////////////////////////////////////////////////////////////////
// APIs needed in BoringSSL only
////////////////////////////////////////////////////////////////////////////////
// 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
// 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 TLS1_get_client_version(SSL* s);
#endif
#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)
////////////////////////////////////////////////////////////////////////////////
#if FOLLY_OPENSSL_IS_100
uint32_t SSL_CIPHER_get_id(const SSL_CIPHER*);
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_SESSION_up_ref(SSL_SESSION* session);
int X509_up_ref(X509* x);
#endif
#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);
#if !FOLLY_OPENSSL_IS_110
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));
#endif
const char* SSL_SESSION_get0_hostname(const SSL_SESSION* s);
#if FOLLY_OPENSSL_IS_100
////////////////////////////////////////////////////////////////////////////////
// APIs needed only in 1.0.0 only (deprecated)
////////////////////////////////////////////////////////////////////////////////
EVP_MD_CTX* EVP_MD_CTX_new();
void EVP_MD_CTX_free(EVP_MD_CTX* ctx);
uint32_t SSL_CIPHER_get_id(const SSL_CIPHER*);
int TLS1_get_client_version(const SSL*);
HMAC_CTX* HMAC_CTX_new();
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
#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
FOLLY_PUSH_WARNING
#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