]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
wolfssl: coexist with openssl, further work
authorStefan Eissing <stefan@eissing.org>
Mon, 4 Nov 2024 11:26:47 +0000 (12:26 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 4 Nov 2024 13:48:30 +0000 (14:48 +0100)
Build wolfSSL master with

./configure --prefix=/path --enable-ip-alt-name --enable-quic
--enable-earlydata --enable-psk --enable-opensslcoexist

and configure curl with openssl + wolfssl. Normal tests run.

pytest session resumption fails, as wolfssl does not handle the
new_session callback without opensslextra right now.

Closes #15481

CMakeLists.txt
configure.ac
lib/curl_config.h.cmake
lib/vtls/rustls.c
lib/vtls/vtls.c
lib/vtls/vtls_int.h
lib/vtls/wolfssl.c
lib/vtls/wolfssl.h
m4/curl-wolfssl.m4
tests/http/test_05_errors.py

index 796ce8ad624127320b0df79cd6c0908a1d5bf6ef..c4ba74d9fb5a0555992028d6e0e75a5ab939ec80 100644 (file)
@@ -832,6 +832,7 @@ endmacro()
 
 if(USE_WOLFSSL)
   openssl_check_symbol_exists("wolfSSL_DES_ecb_encrypt" "wolfssl/openssl/des.h" HAVE_WOLFSSL_DES_ECB_ENCRYPT "")
+  openssl_check_symbol_exists("wolfSSL_BIO_new" "wolfssl/ssl.h" HAVE_WOLFSSL_BIO "")
   openssl_check_symbol_exists("wolfSSL_BIO_set_shutdown" "wolfssl/ssl.h" HAVE_WOLFSSL_FULL_BIO "")
 endif()
 
@@ -1985,7 +1986,7 @@ _add_if("MultiSSL"      CURL_WITH_MULTI_SSL)
 _add_if("HTTPS-proxy"   _ssl_enabled AND (USE_OPENSSL OR USE_GNUTLS
                         OR USE_SCHANNEL OR USE_RUSTLS OR USE_BEARSSL OR
                         USE_MBEDTLS OR USE_SECTRANSP OR
-                        (USE_WOLFSSL AND HAVE_WOLFSSL_FULL_BIO)))
+                        (USE_WOLFSSL AND HAVE_WOLFSSL_BIO)))
 _add_if("Unicode"       ENABLE_UNICODE)
 _add_if("threadsafe"    HAVE_ATOMIC OR
                         (USE_THREADS_POSIX AND HAVE_PTHREAD_H) OR
index 47c8353494c8a0951b8efb960a6fa4c6ffa55024..a8bd87e736fae7d95faa48d90910c940df8057c1 100644 (file)
@@ -5171,7 +5171,7 @@ if test "x$CURL_DISABLE_HTTP" != "x1"; then
         -o "x$MBEDTLS_ENABLED" = "x1"; then
       SUPPORT_FEATURES="$SUPPORT_FEATURES HTTPS-proxy"
       AC_MSG_RESULT([yes])
-    elif test "x$WOLFSSL_ENABLED" = "x1" -a "x$WOLFSSL_FULL_BIO" = "x1"; then
+    elif test "x$WOLFSSL_ENABLED" = "x1" -a "x$WOLFSSL_BIO" = "x1"; then
       SUPPORT_FEATURES="$SUPPORT_FEATURES HTTPS-proxy"
       AC_MSG_RESULT([yes])
     else
index 32a8208b68122918ea03120ad2e87d7f4cbf3360..7ee0a400f7fc144a61a33c8ae5be9035ccd1bd4f 100644 (file)
@@ -721,6 +721,9 @@ ${SIZEOF_TIME_T_CODE}
 /* if wolfSSL has the wolfSSL_DES_ecb_encrypt function. */
 #cmakedefine HAVE_WOLFSSL_DES_ECB_ENCRYPT 1
 
+/* if wolfSSL has the wolfSSL_BIO_new function. */
+#cmakedefine HAVE_WOLFSSL_BIO 1
+
 /* if wolfSSL has the wolfSSL_BIO_set_shutdown function. */
 #cmakedefine HAVE_WOLFSSL_FULL_BIO 1
 
index f0ef267039de0f3807d3952a8dc69c108c684e00..5d143486d6547a1f4714de75622bbca8c40d21e3 100644 (file)
@@ -37,6 +37,7 @@
 #include "sendf.h"
 #include "vtls.h"
 #include "vtls_int.h"
+#include "rustls.h"
 #include "select.h"
 #include "strerror.h"
 #include "multiif.h"
index 6d12dfd73e956d8638264048cbb2a6febed26b13..61b407ab22eaf198d51f3daecb3e532636383e86 100644 (file)
 
 #include "vtls.h" /* generic SSL protos etc */
 #include "vtls_int.h"
+
+#include "openssl.h"        /* OpenSSL versions */
+#include "gtls.h"           /* GnuTLS versions */
+#include "wolfssl.h"        /* wolfSSL versions */
+#include "schannel.h"       /* Schannel SSPI version */
+#include "sectransp.h"      /* Secure Transport (Darwin) version */
+#include "mbedtls.h"        /* mbedTLS versions */
+#include "bearssl.h"        /* BearSSL versions */
+#include "rustls.h"         /* Rustls versions */
+
 #include "slist.h"
 #include "sendf.h"
 #include "strcase.h"
index 660c3379b1bdde016d409bf1f88fd7b1ac904c8a..13bd3fbb5e71cedb7e010bc26a5ae53f270198f7 100644 (file)
@@ -250,15 +250,6 @@ CURLcode Curl_ssl_set_sessionid(struct Curl_cfilter *cf,
                                 size_t sessionid_size,
                                 Curl_ssl_sessionid_dtor *sessionid_free_cb);
 
-#include "openssl.h"        /* OpenSSL versions */
-#include "gtls.h"           /* GnuTLS versions */
-#include "wolfssl.h"        /* wolfSSL versions */
-#include "schannel.h"       /* Schannel SSPI version */
-#include "sectransp.h"      /* Secure Transport (Darwin) version */
-#include "mbedtls.h"        /* mbedTLS versions */
-#include "bearssl.h"        /* BearSSL versions */
-#include "rustls.h"         /* Rustls versions */
-
 #endif /* USE_SSL */
 
 #endif /* HEADER_CURL_VTLS_INT_H */
index 1769a1367a4661c2e282f84c20f052943ce40ad9..0d74b3e763dd972152a0a1f8db97f19146733c53 100644 (file)
 #endif
 #endif
 
-#if defined(HAVE_WOLFSSL_FULL_BIO) && HAVE_WOLFSSL_FULL_BIO
+#ifdef HAVE_WOLFSSL_BIO
 #define USE_BIO_CHAIN
-#else
+#ifdef HAVE_WOLFSSL_FULL_BIO
+#define USE_FULL_BIO
+#else /* HAVE_WOLFSSL_FULL_BIO */
+#undef USE_FULL_BIO
+#endif
+/* wolfSSL 5.7.4 and older do not have these symbols, but only the
+ * OpenSSL ones. */
+#ifndef WOLFSSL_BIO_CTRL_GET_CLOSE
+#define WOLFSSL_BIO_CTRL_GET_CLOSE    BIO_CTRL_GET_CLOSE
+#define WOLFSSL_BIO_CTRL_SET_CLOSE    BIO_CTRL_SET_CLOSE
+#define WOLFSSL_BIO_CTRL_FLUSH        BIO_CTRL_FLUSH
+#define WOLFSSL_BIO_CTRL_DUP          BIO_CTRL_DUP
+#define wolfSSL_BIO_set_retry_write   BIO_set_retry_write
+#define wolfSSL_BIO_set_retry_read    BIO_set_retry_read
+#endif /* !WOLFSSL_BIO_CTRL_GET_CLOSE */
+
+#else /* HAVE_WOLFSSL_BIO */
 #undef USE_BIO_CHAIN
 #endif
 
@@ -237,7 +253,9 @@ static const struct group_name_map gnm[] = {
 
 static int wolfssl_bio_cf_create(WOLFSSL_BIO *bio)
 {
+#ifdef USE_FULL_BIO
   wolfSSL_BIO_set_shutdown(bio, 1);
+#endif
   wolfSSL_BIO_set_data(bio, NULL);
   return 1;
 }
@@ -251,28 +269,35 @@ static int wolfssl_bio_cf_destroy(WOLFSSL_BIO *bio)
 
 static long wolfssl_bio_cf_ctrl(WOLFSSL_BIO *bio, int cmd, long num, void *ptr)
 {
-  struct Curl_cfilter *cf = BIO_get_data(bio);
+  struct Curl_cfilter *cf = wolfSSL_BIO_get_data(bio);
   long ret = 1;
 
   (void)cf;
   (void)ptr;
+  (void)num;
   switch(cmd) {
-  case BIO_CTRL_GET_CLOSE:
+  case WOLFSSL_BIO_CTRL_GET_CLOSE:
+#ifdef USE_FULL_BIO
     ret = (long)wolfSSL_BIO_get_shutdown(bio);
+#else
+    ret = 0;
+#endif
     break;
-  case BIO_CTRL_SET_CLOSE:
+  case WOLFSSL_BIO_CTRL_SET_CLOSE:
+#ifdef USE_FULL_BIO
     wolfSSL_BIO_set_shutdown(bio, (int)num);
+#endif
     break;
-  case BIO_CTRL_FLUSH:
+  case WOLFSSL_BIO_CTRL_FLUSH:
     /* we do no delayed writes, but if we ever would, this
      * needs to trigger it. */
     ret = 1;
     break;
-  case BIO_CTRL_DUP:
+  case WOLFSSL_BIO_CTRL_DUP:
     ret = 1;
     break;
-#ifdef BIO_CTRL_EOF
-  case BIO_CTRL_EOF:
+#ifdef WOLFSSL_BIO_CTRL_EOF
+  case WOLFSSL_BIO_CTRL_EOF:
     /* EOF has been reached on input? */
     return (!cf->next || !cf->next->connected);
 #endif
@@ -309,9 +334,11 @@ static int wolfssl_bio_cf_out_write(WOLFSSL_BIO *bio,
   backend->io_result = result;
   CURL_TRC_CF(data, cf, "bio_write(len=%d) -> %zd, %d",
               blen, nwritten, result);
+#ifdef USE_FULL_BIO
   wolfSSL_BIO_clear_retry_flags(bio);
+#endif
   if(nwritten < 0 && CURLE_AGAIN == result) {
-    BIO_set_retry_write(bio);
+    wolfSSL_BIO_set_retry_write(bio);
     if(backend->shutting_down && !backend->io_send_blocked_len)
       backend->io_send_blocked_len = blen;
   }
@@ -338,9 +365,11 @@ static int wolfssl_bio_cf_in_read(WOLFSSL_BIO *bio, char *buf, int blen)
   nread = Curl_conn_cf_recv(cf->next, data, buf, blen, &result);
   backend->io_result = result;
   CURL_TRC_CF(data, cf, "bio_read(len=%d) -> %zd, %d", blen, nread, result);
+#ifdef USE_FULL_BIO
   wolfSSL_BIO_clear_retry_flags(bio);
+#endif
   if(nread < 0 && CURLE_AGAIN == result)
-    BIO_set_retry_read(bio);
+    wolfSSL_BIO_set_retry_read(bio);
   else if(nread == 0)
     connssl->peer_closed = TRUE;
   return (int)nread;
@@ -350,7 +379,8 @@ static WOLFSSL_BIO_METHOD *wolfssl_bio_cf_method = NULL;
 
 static void wolfssl_bio_cf_init_methods(void)
 {
-  wolfssl_bio_cf_method = wolfSSL_BIO_meth_new(BIO_TYPE_MEM, "wolfSSL CF BIO");
+  wolfssl_bio_cf_method = wolfSSL_BIO_meth_new(WOLFSSL_BIO_MEMORY,
+                                               "wolfSSL CF BIO");
   wolfSSL_BIO_meth_set_write(wolfssl_bio_cf_method, &wolfssl_bio_cf_out_write);
   wolfSSL_BIO_meth_set_read(wolfssl_bio_cf_method, &wolfssl_bio_cf_in_read);
   wolfSSL_BIO_meth_set_ctrl(wolfssl_bio_cf_method, &wolfssl_bio_cf_ctrl);
@@ -1248,7 +1278,7 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
   {
     WOLFSSL_BIO *bio;
 
-    bio = BIO_new(wolfssl_bio_cf_method);
+    bio = wolfSSL_BIO_new(wolfssl_bio_cf_method);
     if(!bio)
       return CURLE_OUT_OF_MEMORY;
 
@@ -1730,6 +1760,11 @@ static ssize_t wolfssl_recv(struct Curl_cfilter *cf,
     case WOLFSSL_ERROR_NONE:
     case WOLFSSL_ERROR_WANT_READ:
     case WOLFSSL_ERROR_WANT_WRITE:
+      if(!backend->io_result && connssl->peer_closed) {
+        CURL_TRC_CF(data, cf, "wolfssl_recv(len=%zu) -> CLOSED", blen);
+        *curlcode = CURLE_OK;
+        return 0;
+      }
       /* there is data pending, re-invoke wolfSSL_read() */
       CURL_TRC_CF(data, cf, "wolfssl_recv(len=%zu) -> AGAIN", blen);
       *curlcode = CURLE_AGAIN;
@@ -1740,7 +1775,12 @@ static ssize_t wolfssl_recv(struct Curl_cfilter *cf,
         *curlcode = CURLE_AGAIN;
         return -1;
       }
-      {
+      else if(!backend->io_result && connssl->peer_closed) {
+        CURL_TRC_CF(data, cf, "wolfssl_recv(len=%zu) -> CLOSED", blen);
+        *curlcode = CURLE_OK;
+        return 0;
+      }
+      else {
         char error_buffer[256];
         failf(data, "SSL read: %s, errno %d",
               wolfssl_strerror((unsigned long)err, error_buffer,
index e39fa88adcd2b57a473397b9432b2ae7d403a2e7..dc2967d69c7480bc95e5135db25ed15338f3ba2d 100644 (file)
 #include "curl_setup.h"
 
 #ifdef USE_WOLFSSL
-#include <wolfssl/version.h>
-#include <wolfssl/options.h>
-#include <wolfssl/ssl.h>
-#include <wolfssl/error-ssl.h>
 
 #include "urldata.h"
 
+struct WOLFSSL;
+typedef struct WOLFSSL WOLFSSL;
+struct WOLFSSL_CTX;
+typedef struct WOLFSSL_CTX WOLFSSL_CTX;
+struct WOLFSSL_SESSION;
+typedef struct WOLFSSL_SESSION WOLFSSL_SESSION;
+
 extern const struct Curl_ssl Curl_ssl_wolfssl;
 
 struct wolfssl_ctx {
index ca60d3b48815a23f4bacb9292dd362b380d51682..cd5a2b14b5753284795a8e0b61bfd5fa16291d49 100644 (file)
@@ -145,6 +145,14 @@ if test "x$OPT_WOLFSSL" != xno; then
         )
 
       dnl if this symbol is present, we can make use of BIO filter chains
+      AC_CHECK_FUNC(wolfSSL_BIO_new,
+        [
+          AC_DEFINE(HAVE_WOLFSSL_BIO, 1,
+                    [if you have wolfSSL_BIO_new])
+          WOLFSSL_BIO=1
+        ]
+        )
+      dnl if this symbol is present, we have the full BIO feature set
       AC_CHECK_FUNC(wolfSSL_BIO_set_shutdown,
         [
           AC_DEFINE(HAVE_WOLFSSL_FULL_BIO, 1,
index e00edcfab6aa8760ec827e5441077950e0b5a32e..a496d6d8b5c1345c4eb740e71a303cc4cbc6f746 100644 (file)
@@ -127,7 +127,7 @@ class TestErrors:
         r = curl.http_download(urls=[url], alpn_proto=proto, extra_args=[
             '--parallel',
         ])
-        if proto == 'http/1.0' and \
+        if proto == 'http/1.0' and not env.curl_uses_lib('wolfssl') and \
                 (env.curl_is_debug() or not env.curl_uses_lib('openssl')):
             # we are inconsistent if we fail or not in missing TLS shutdown
             # openssl code ignore such errors intentionally in non-debug builds