Re-work the OpenSSL portability header to be a portability header
authorChristopher Dykes <cdykes@fb.com>
Mon, 10 Apr 2017 18:10:21 +0000 (11:10 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Mon, 10 Apr 2017 18:20:12 +0000 (11:20 -0700)
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

folly/portability/OpenSSL.cpp
folly/portability/OpenSSL.h

index 43a4692b2d3617d9d0677f63904e698a954ac5b2..b1052dba00bef6273faad50b68fb8e540602e189 100644 (file)
  * 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
 }
 }
index d105dc47f4b57261d53a1a038e708688e8bbf292..b70f55a0ee12dd39666802bf6156d6a30706e4df 100644 (file)
  * 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