Browse Source

Fix LibreSSL 3.5.0+ build

Bryan Drewery 2 years ago
parent
commit
e54a3acb98
7 changed files with 82 additions and 31 deletions
  1. 1 0
      doc/UPDATES.md
  2. 38 16
      src/compat/openssl.cc
  3. 8 4
      src/crypto/dh_util.cc
  4. 8 4
      src/dhparam.cc
  5. 2 1
      src/libcrypto.cc
  6. 18 2
      src/libssl.cc
  7. 7 4
      src/openssl.cc

+ 1 - 0
doc/UPDATES.md

@@ -1,5 +1,6 @@
 # maint
   * Fix OpenSSL 3 build.
+  * Fix LibreSSL 3.5+ build.
 
 # 1.4.10
   * Clear FiSH keys when a client quits.

+ 38 - 16
src/compat/openssl.cc

@@ -1,11 +1,23 @@
+/*
+ * Provide forward compat functions when built from < 1.1 in case the
+ * binary is run against a 1.1+ library. It will first try to find
+ * the symbol it wants, like SSLv23_client_method(), and fallback to
+ * _SSLv23_client_method() for TLS_client_method() if not found.
+ *
+ * Each condition here should match the condition in libssl.cc/libcrypto.cc
+ * for where DLSYM_GLOBAL_FWDCOMPAT() is used.
+ */
 #include <openssl/opensslv.h>
-/* Provide forward compat functions when built from < 1.1. */
-#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L
+
 #include <stdlib.h>
 #include <stdint.h>
 #include "dl.h"
 
 extern "C" {
+/*
+ * src/libssl.cc
+ */
+#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L
 typedef int (*OPENSSL_init_ssl_t)(uint64_t a1, const void *a2);
 static int _OPENSSL_init_ssl(uint64_t a1, const void *a2) {
   if (DLSYM_VAR(OPENSSL_init_ssl) == NULL)
@@ -13,19 +25,6 @@ static int _OPENSSL_init_ssl(uint64_t a1, const void *a2) {
       return 0;
   return DLSYM_VAR(OPENSSL_init_ssl)(a1, a2);
 }
-
-void _ERR_free_strings(void) __attribute__((const));
-void _ERR_free_strings(void) {
-}
-
-void _EVP_cleanup(void) __attribute__((const));
-void _EVP_cleanup(void) {
-}
-
-void _CRYPTO_cleanup_all_ex_data(void) __attribute__((const));
-void _CRYPTO_cleanup_all_ex_data(void) {
-}
-
 int _SSL_library_init(void) {
   return _OPENSSL_init_ssl(0, NULL);
 }
@@ -36,7 +35,10 @@ void _SSL_load_error_strings(void) {
     _OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS \
                      | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
 }
+#endif
 
+#if !((defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER > 0x20020002L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L))
 typedef void *(*TLS_client_method_t)(void);
 static const void *_TLS_client_method(void) {
   if (DLSYM_VAR(TLS_client_method) == NULL)
@@ -44,10 +46,30 @@ static const void *_TLS_client_method(void) {
       return NULL;
   return DLSYM_VAR(TLS_client_method)();
 }
+#endif
 
+#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L
 const void *_SSLv23_client_method(void) {
   return _TLS_client_method();
 }
+#endif
+
+/*
+ * src/libcrypto.cc
+ */
+#if !((defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x30500000L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L))
+void _ERR_free_strings(void) __attribute__((const));
+void _ERR_free_strings(void) {
+}
+
+void _EVP_cleanup(void) __attribute__((const));
+void _EVP_cleanup(void) {
+}
+
+void _CRYPTO_cleanup_all_ex_data(void) __attribute__((const));
+void _CRYPTO_cleanup_all_ex_data(void) {
+}
+#endif
 
 } /* extern "C" */
-#endif	/* OPENSSL_VERSION_NUMBER < 0x10100000L */

+ 8 - 4
src/crypto/dh_util.cc

@@ -84,7 +84,8 @@ void DH1080_gen(bd::String& privateKey, bd::String& publicKeyB64) {
   const BIGNUM *priv_key, *pub_key;
 
   dh = DH_new();
-#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x30500000L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L)
   if (b_prime == NULL || b_generator == NULL ||
       !DH_set0_pqg(dh, BN_dup(b_prime), NULL, BN_dup(b_generator)))
     return;
@@ -99,7 +100,8 @@ void DH1080_gen(bd::String& privateKey, bd::String& publicKeyB64) {
   }
 
   // Get private key
-#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x30500000L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L)
   DH_get0_key(dh, &pub_key, &priv_key);
 #else
   priv_key = dh->priv_key;
@@ -126,7 +128,8 @@ bool DH1080_comp(const bd::String privateKey, const bd::String theirPublicKeyB64
 
 
   dh = DH_new();
-#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x30500000L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L)
   if (b_prime == NULL || b_generator == NULL ||
       !DH_set0_pqg(dh, BN_dup(b_prime), NULL, BN_dup(b_generator)))
     return false;
@@ -137,7 +140,8 @@ bool DH1080_comp(const bd::String privateKey, const bd::String theirPublicKeyB64
 
   // Setup my private key
   b_myPrivkey = BN_bin2bn(reinterpret_cast<const unsigned char*>(privateKey.data()), privateKey.length(), NULL);
-#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x30500000L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L)
   DH_set0_key(dh, NULL, b_myPrivkey);
 #else
   dh->priv_key = b_myPrivkey;

+ 8 - 4
src/dhparam.cc

@@ -32,7 +32,8 @@ DH *get_dh2048() {
   if ((dh=DH_new()) == NULL) return(NULL);
   dhp_bn = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
   dhg_bn = BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
-#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x30500000L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L)
   if (dhp_bn == NULL || dhg_bn == NULL
       || !DH_set0_pqg(dh, dhp_bn, NULL, dhg_bn)) {
     DH_free(dh);
@@ -82,7 +83,8 @@ DH *get_dh1024() {
   if ((dh=DH_new()) == NULL) return(NULL);
   dhp_bn = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
   dhg_bn = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
-#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x30500000L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L)
   if (dhp_bn == NULL || dhg_bn == NULL
       || !DH_set0_pqg(dh, dhp_bn, NULL, dhg_bn)) {
     DH_free(dh);
@@ -123,7 +125,8 @@ DH *get_dh512() {
   if ((dh=DH_new()) == NULL) return(NULL);
   dhp_bn = BN_bin2bn(dh512_p, sizeof(dh512_p), NULL);
   dhg_bn = BN_bin2bn(dh512_g, sizeof(dh512_g), NULL);
-#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x30500000L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L)
   if (dhp_bn == NULL || dhg_bn == NULL
       || !DH_set0_pqg(dh, dhp_bn, NULL, dhg_bn)) {
     DH_free(dh);
@@ -212,7 +215,8 @@ DH *get_dh4096()
         return NULL;
     dhp_bn = BN_bin2bn(dhp_4096, sizeof(dhp_4096), NULL);
     dhg_bn = BN_bin2bn(dhg_4096, sizeof(dhg_4096), NULL);
-#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x30500000L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L)
   if (dhp_bn == NULL || dhg_bn == NULL
       || !DH_set0_pqg(dh, dhp_bn, NULL, dhg_bn)) {
     DH_free(dh);

+ 2 - 1
src/libcrypto.cc

@@ -84,7 +84,8 @@ static int load_symbols(void *handle) {
   DLSYM_GLOBAL(handle, DH_new);
   DLSYM_GLOBAL(handle, DH_size);
 
-#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x30500000L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L)
   /* For dh_util.cc */
   DLSYM_GLOBAL(handle, DH_get0_key);
   DLSYM_GLOBAL(handle, DH_set0_key);

+ 18 - 2
src/libssl.cc

@@ -58,8 +58,15 @@ static int load_symbols(void *handle) {
   DLSYM_GLOBAL(handle, SSL_CTX_ctrl);
   DLSYM_GLOBAL(handle, SSL_CTX_set_cipher_list);
   DLSYM_GLOBAL(handle, SSL_CTX_set_tmp_dh_callback);
-#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L
+#if defined(LIBRESSL_VERSION_NUMBER)
+  /* SSL_library_init: always symbol in LibreSSL. */
+  DLSYM_GLOBAL(handle, SSL_library_init);
+  /* SSL_load_error_strings: always symbol in LibreSSL. */
+  DLSYM_GLOBAL(handle, SSL_load_error_strings);
+#elif OPENSSL_VERSION_NUMBER < 0x10100000L
+  /* SSL_library_init: symbol in LibreSSL and 1.0. Macro in 1.1+. */
   DLSYM_GLOBAL_FWDCOMPAT(handle, SSL_library_init);
+  /* SSL_load_error_strings: Symbol in LibreSSL and 1.0. Macro in 1.1+. */
   DLSYM_GLOBAL_FWDCOMPAT(handle, SSL_load_error_strings);
   /* Some forward-compat is handled in src/compat/openssl.cc. */
 #else
@@ -67,9 +74,18 @@ static int load_symbols(void *handle) {
   DLSYM_GLOBAL(handle, OPENSSL_init_ssl);
 #endif
 #if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
-  DLSYM_GLOBAL(handle, TLS_client_method);
+  /* Macro in 1.0 and LibreSSL. Symbol in 1.1+. */
   DLSYM_GLOBAL(handle, SSL_CTX_set_options);
+#endif
+#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER > 0x20020002L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L)
+  /* Not in 1.0. Symbol in 1.1+ and LibreSSL 2.2+ 0x20020002L. */
+  DLSYM_GLOBAL(handle, TLS_client_method);
+#elif defined(LIBRESSL_VERSION_NUMBER)
+  /* LibreSSL always has a symbol and not a macro to TLS_client_method. */
+  DLSYM_GLOBAL(handle, SSLv23_client_method);
 #else
+  /* Symbol in 1.0 and LibreSSL. Macro in OpenSSL 1.1+. */
   DLSYM_GLOBAL_FWDCOMPAT(handle, SSLv23_client_method);
   /* Some forward-compat is handled in src/compat/openssl.cc. */
 #endif

+ 7 - 4
src/openssl.cc

@@ -78,10 +78,11 @@ int init_openssl() {
   /* good place to init ssl stuff */
   SSL_load_error_strings();
   OpenSSL_add_ssl_algorithms();
-#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L
-  ssl_ctx = SSL_CTX_new(SSLv23_client_method());
-#else
+#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER > 0x20020002L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L)
   ssl_ctx = SSL_CTX_new(TLS_client_method());
+#else
+  ssl_ctx = SSL_CTX_new(SSLv23_client_method());
 #endif
   if (!ssl_ctx) {
     sdprintf("SSL_CTX_new() failed");
@@ -125,7 +126,9 @@ int uninit_openssl () {
     RAND_write_file(tls_rand_file);
 #endif
 
-#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10100000L
+  /* Macro from src/libcrypto.cc */
+#if !((defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x30500000L) || \
+    (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L))
   ERR_free_strings();
   EVP_cleanup();
   CRYPTO_cleanup_all_ex_data();