diff --git a/.github/workflows/hitch.yml b/.github/workflows/hitch.yml new file mode 100644 index 0000000000..c790ba3c09 --- /dev/null +++ b/.github/workflows/hitch.yml @@ -0,0 +1,90 @@ +name: hitch Tests + +on: + workflow_call: + +jobs: + build_wolfssl: + name: Build wolfSSL + # Just to keep it the same as the testing target + runs-on: ubuntu-latest + steps: + - name: Build wolfSSL + uses: wolfSSL/actions-build-autotools-project@v1 + with: + path: wolfssl + configure: --enable-hitch + install: true + + - name: Upload built lib + uses: actions/upload-artifact@v3 + with: + name: wolf-install-hitch + path: build-dir + retention-days: 1 + + hitch_check: + strategy: + fail-fast: false + matrix: + # List of releases to test + include: + - ref: 1.7.3 + ignore-tests: >- + test13-r82.sh test15-proxy-v2-npn.sh test39-client-cert-proxy.sh + name: ${{ matrix.ref }} + runs-on: ubuntu-latest + needs: build_wolfssl + steps: + - name: Download lib + uses: actions/download-artifact@v3 + with: + name: wolf-install-hitch + path: build-dir + + - name: Checkout OSP + uses: actions/checkout@v3 + with: + repository: wolfssl/osp + path: osp + + - name: Install dependencies + run: | + export DEBIAN_FRONTEND=noninteractive + sudo apt-get update + sudo apt-get install -y libev-dev libssl-dev automake python3-docutils flex bison pkg-config make + + - name: Checkout hitch + uses: actions/checkout@v3 + with: + repository: varnish/hitch + ref: 1.7.3 + path: hitch + + # Do this before configuring so that it only detects the updated list of + # tests + - if: ${{ matrix.ignore-tests }} + name: Remove tests that we want to ignore + working-directory: ./hitch/src/tests + run: | + rm ${{ matrix.ignore-tests }} + + - name: Configure and build hitch + run: | + cd $GITHUB_WORKSPACE/hitch/ + patch -p1 < $GITHUB_WORKSPACE/osp/hitch/hitch_1.7.3.patch + autoreconf -ivf + SSL_CFLAGS="-I$GITHUB_WORKSPACE/build-dir/include/ -I$GITHUB_WORKSPACE/build-dir/include/wolfssl" SSL_LIBS="-L$GITHUB_WORKSPACE/build-dir/lib -lwolfssl" ./configure --with-wolfssl=$GITHUB_WORKSPACE/build-dir/ --enable-silent-rules --enable-documentation --enable-warnings --with-lex --with-yacc --prefix=$GITHUB_WORKSPACE/build-dir + make -j$(nproc) + + - name: Confirm hitch built with wolfSSL + working-directory: ./hitch + run: | + export LD_LIBRARY_PATH=$GITHUB_WORKSPACE/build-dir/lib:$LD_LIBRARY_PATH + ldd src/hitch | grep wolfssl + + - name: Run hitch tests, skipping ignored tests + working-directory: ./hitch + run: | + export LD_LIBRARY_PATH=$GITHUB_WORKSPACE/build-dir/lib:$LD_LIBRARY_PATH + make check \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a72148c470..890acce150 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -30,6 +30,8 @@ jobs: uses: ./.github/workflows/nginx.yml zephyr: uses: ./.github/workflows/zephyr.yml + hitch: + uses: ./.github/workflows/hitch.yml # TODO: Currently this test fails. Enable it once it becomes passing. # haproxy: # uses: ./.github/workflows/haproxy.yml diff --git a/configure.ac b/configure.ac index 210f25f3ee..c8da54698b 100644 --- a/configure.ac +++ b/configure.ac @@ -1377,6 +1377,7 @@ AC_ARG_ENABLE([mcast], # FFmpeg (--enable-ffmpeg) WOLFSSL_FFMPEG # strongSwan (--enable-strongswan) # OpenLDAP (--enable-openldap) +# hitch (--enable-hitch) # Bind DNS compatibility Build AC_ARG_ENABLE([bind], @@ -1580,6 +1581,13 @@ AC_ARG_ENABLE([strongswan], [ ENABLED_STRONGSWAN=no ] ) +# hitch support +AC_ARG_ENABLE([hitch], + [AS_HELP_STRING([--enable-hitch],[Enable hitch support (default: disabled)])], + [ ENABLED_HITCH=$enableval ], + [ ENABLED_HITCH=no ] + ) + # OpenSSL Coexist AC_ARG_ENABLE([opensslcoexist], [AS_HELP_STRING([--enable-opensslcoexist],[Enable coexistence of wolfssl/openssl (default: disabled)])], @@ -1691,7 +1699,7 @@ if test "$ENABLED_LIBWEBSOCKETS" = "yes" || test "$ENABLED_OPENVPN" = "yes" || \ test "$ENABLED_OPENRESTY" = "yes" || test "$ENABLED_RSYSLOG" = "yes" || \ test "$ENABLED_KRB" = "yes" || test "$ENABLED_CHRONY" = "yes" || \ test "$ENABLED_FFMPEG" = "yes" || test "$ENABLED_STRONGSWAN" = "yes" || \ - test "$ENABLED_OPENLDAP" = "yes" + test "$ENABLED_OPENLDAP" = "yes" || test "$ENABLED_HITCH" = "yes" then ENABLED_OPENSSLALL="yes" fi @@ -3109,7 +3117,7 @@ AC_ARG_ENABLE([sessioncerts], if test "x$ENABLED_NGINX" = "xyes" || test "x$ENABLED_OPENVPN" = "xyes" || \ test "x$ENABLED_LIGHTY" = "xyes" || test "x$ENABLED_NETSNMP" = "xyes" || \ - test "x$ENABLED_STRONGSWAN" = "xyes" + test "x$ENABLED_STRONGSWAN" = "xyes" || test "x$ENABLED_HITCH" = "xyes" then ENABLED_SESSIONCERTS=yes fi @@ -3149,7 +3157,7 @@ AC_ARG_ENABLE([certgen], if test "$ENABLED_OPENVPN" = "yes" || test "$ENABLED_OPENSSH" = "yes" || \ test "$ENABLED_BIND" = "yes" || test "$ENABLED_NTP" = "yes" || \ test "$ENABLED_CHRONY" = "yes" || test "$ENABLED_STRONGSWAN" = "yes" || \ - test "$ENABLED_OPENLDAP" = "yes" + test "$ENABLED_OPENLDAP" = "yes" || test "$ENABLED_HITCH" = "yes" then ENABLED_CERTGEN=yes fi @@ -5961,6 +5969,45 @@ then AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DES_ECB -DHAVE_EX_DATA -DWOLFSSL_KEY_GEN" fi +if test "$ENABLED_HITCH" = "yes" +then + # Requires opensslextra make sure on + if test "x$ENABLED_OPENSSLEXTRA" = "xno" && test "x$ENABLED_OPENSSLCOEXIST" = "xno" + then + ENABLED_OPENSSLEXTRA="yes" + AM_CFLAGS="$AM_CFLAGS -DOPENSSL_EXTRA" + fi + + # Requires OCSP make sure on + if test "x$ENABLED_OCSP" = "xno" + then + ENABLED_OCSP="yes" + fi + + # Requires ALPN + if test "x$ENABLED_ALPN" = "xno" + then + ENABLED_ALPN="yes" + AM_CFLAGS="$AM_CFLAGS -DHAVE_TLS_EXTENSIONS -DHAVE_ALPN" + fi + + if test "x$ENABLED_KEYGEN" = "xno" + then + ENABLED_KEYGEN="yes" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_KEY_GEN" + fi + + # Requires sessioncerts make sure on + if test "x$ENABLED_SESSIONCERTS" = "xno" + then + ENABLED_SESSIONCERTS="yes" + AM_CFLAGS="$AM_CFLAGS -DSESSION_CERTS" + fi + + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_HITCH -DHAVE_EX_DATA -DWOLFSSL_SIGNER_DER_CERT" + AM_CFLAGS="$AM_CFLAGS -DOPENSSL_COMPATIBLE_DEFAULTS -DWOLFSSL_CIPHER_INTERNALNAME" +fi + if test "$ENABLED_NGINX" = "yes"|| test "x$ENABLED_HAPROXY" = "xyes" || test "x$ENABLED_LIGHTY" = "xyes" then @@ -8003,7 +8050,7 @@ if test "$ENABLED_OPENSSH" = "yes" || test "$ENABLED_NGINX" = "yes" || \ test "$ENABLED_LIBWEBSOCKETS" = "yes" || \ test "x$ENABLED_LIGHTY" = "xyes" || test "$ENABLED_LIBSSH2" = "yes" || \ test "x$ENABLED_NTP" = "xyes" || test "$ENABLED_RSYSLOG" = "yes" || \ - test "$ENABLED_OPENLDAP" = "yes" + test "$ENABLED_OPENLDAP" = "yes" || test "$ENABLED_HITCH" = "yes" then ENABLED_OPENSSLEXTRA="yes" fi @@ -9189,6 +9236,7 @@ echo " * SIGNAL: $ENABLED_SIGNAL" echo " * chrony: $ENABLED_CHRONY" echo " * strongSwan: $ENABLED_STRONGSWAN" echo " * OpenLDAP: $ENABLED_OPENLDAP" +echo " * hitch: $ENABLED_HITCH" echo " * ERROR_STRINGS: $ENABLED_ERROR_STRINGS" echo " * DTLS: $ENABLED_DTLS" echo " * DTLS v1.3: $ENABLED_DTLS13" diff --git a/src/bio.c b/src/bio.c index eb635bc280..2e6de0a9c6 100644 --- a/src/bio.c +++ b/src/bio.c @@ -1155,6 +1155,32 @@ long wolfSSL_BIO_get_mem_ptr(WOLFSSL_BIO *bio, WOLFSSL_BUF_MEM **ptr) return ret; } +#ifdef OPENSSL_ALL + int wolfSSL_BIO_set_mem_buf(WOLFSSL_BIO* bio, WOLFSSL_BUF_MEM* bufMem, + int closeFlag) + { + if (!bio || !bufMem || + (closeFlag != BIO_NOCLOSE && closeFlag != BIO_CLOSE)) + return BAD_FUNC_ARG; + + if (bio->mem_buf) + if (closeFlag == BIO_CLOSE) + wolfSSL_BUF_MEM_free(bio->mem_buf); + + bio->mem_buf = bufMem; + bio->shutdown = closeFlag; + + bio->wrSz = (int)bio->mem_buf->length; + bio->wrSzReset = bio->wrSz; + bio->num = (int)bio->mem_buf->max; + bio->ptr = bio->mem_buf->data; + bio->wrIdx = 0; + bio->rdIdx = 0; + + return WOLFSSL_SUCCESS; + } +#endif + WOLFSSL_API long wolfSSL_BIO_int_ctrl(WOLFSSL_BIO *bp, int cmd, long larg, int iarg) { (void) bp; @@ -2334,14 +2360,13 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) return WOLFSSL_SUCCESS; } - WOLFSSL_BIO* wolfSSL_BIO_new_ssl_connect(WOLFSSL_CTX* ctx) + WOLFSSL_BIO* wolfSSL_BIO_new_ssl(WOLFSSL_CTX* ctx, int client) { WOLFSSL* ssl = NULL; WOLFSSL_BIO* sslBio = NULL; - WOLFSSL_BIO* connBio = NULL; int err = 0; - WOLFSSL_ENTER("wolfSSL_BIO_new_ssl_connect"); + WOLFSSL_ENTER("wolfSSL_BIO_new_ssl"); if (ctx == NULL) { WOLFSSL_MSG("ctx is NULL."); @@ -2362,11 +2387,46 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) err = 1; } } + if (err == 0) { + if (!client) + wolfSSL_set_accept_state(ssl); + else + wolfSSL_set_connect_state(ssl); + } if (err == 0 && wolfSSL_BIO_set_ssl(sslBio, ssl, BIO_CLOSE) != WOLFSSL_SUCCESS) { WOLFSSL_MSG("Failed to set SSL pointer in BIO."); err = 1; } + + if (err) { + wolfSSL_free(ssl); + wolfSSL_BIO_free(sslBio); + } + + return sslBio; + } + + WOLFSSL_BIO* wolfSSL_BIO_new_ssl_connect(WOLFSSL_CTX* ctx) + { + WOLFSSL_BIO* sslBio = NULL; + WOLFSSL_BIO* connBio = NULL; + int err = 0; + + WOLFSSL_ENTER("wolfSSL_BIO_new_ssl_connect"); + + if (ctx == NULL) { + WOLFSSL_MSG("ctx is NULL."); + err = 1; + } + + if (err == 0) { + sslBio = wolfSSL_BIO_new_ssl(ctx, 1); + if (sslBio == NULL) { + WOLFSSL_MSG("Failed to create SSL BIO."); + err = 1; + } + } if (err == 0) { connBio = wolfSSL_BIO_new(wolfSSL_BIO_s_socket()); if (connBio == NULL) { @@ -2379,7 +2439,6 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) } if (err == 1) { - wolfSSL_free(ssl); wolfSSL_BIO_free(sslBio); sslBio = NULL; wolfSSL_BIO_free(connBio); @@ -3219,6 +3278,26 @@ int wolfSSL_BIO_should_retry(WOLFSSL_BIO *bio) return ret; } +int wolfSSL_BIO_should_read(WOLFSSL_BIO *bio) +{ + int ret = 0; + if (bio != NULL) { + ret = (int)(bio->flags & WOLFSSL_BIO_FLAG_READ); + } + + return ret; +} + +int wolfSSL_BIO_should_write(WOLFSSL_BIO *bio) +{ + int ret = 0; + if (bio != NULL) { + ret = (int)(bio->flags & WOLFSSL_BIO_FLAG_WRITE); + } + + return ret; +} + #endif /* OPENSSL_ALL */ #endif /* WOLFSSL_BIO_INCLUDED */ diff --git a/src/internal.c b/src/internal.c index f6eebc938c..be0059c2d9 100644 --- a/src/internal.c +++ b/src/internal.c @@ -3286,14 +3286,23 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + /* OpenSSL enables ECDHE when using ECDHE aliases without RSA */ + #ifdef OPENSSL_EXTRA + if ((tls1_2 && haveRSA) || (tls1_2 && haveECDSAsig)) { + #else if (tls1_2 && haveRSA) { + #endif suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384; } #endif #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + #ifdef OPENSSL_EXTRA + if ((tls1_2 && haveRSA) || (tls1_2 && haveECDSAsig)) { + #else if (tls1_2 && haveRSA) { + #endif suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256; } @@ -3405,7 +3414,11 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + #ifdef OPENSSL_EXTRA + if ((tls1_2 && haveRSA) || (tls1_2 && haveECDSAsig)) { + #else if (tls1_2 && haveRSA) { + #endif suites->suites[idx++] = CHACHA_BYTE; suites->suites[idx++] = TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256; } @@ -3429,7 +3442,11 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 + #ifdef OPENSSL_EXTRA + if ((tls1_2 && haveRSA) || (tls1_2 && haveECDSAsig)) { + #else if (tls1_2 && haveRSA) { + #endif suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256; } @@ -3457,7 +3474,11 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 + #ifdef OPENSSL_EXTRA + if ((tls1_2 && haveRSA) || (tls1_2 && haveECDSAsig)) { + #else if (tls1_2 && haveRSA) { + #endif suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384; } @@ -3541,7 +3562,11 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + #ifdef OPENSSL_EXTRA + if ((tls && haveRSA) || (tls && haveECDSAsig)) { + #else if (tls && haveRSA) { + #endif suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA; } @@ -3555,7 +3580,11 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + #ifdef OPENSSL_EXTRA + if ((tls && haveRSA) || (tls && haveECDSAsig)) { + #else if (tls && haveRSA) { + #endif suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA; } @@ -3583,7 +3612,11 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA + #ifdef OPENSSL_EXTRA + if ((tls && haveRSA) || (tls && haveECDSAsig)) { + #else if (tls && haveRSA) { + #endif suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA; } @@ -3726,14 +3759,22 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, #endif #ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 + #ifdef OPENSSL_EXTRA + if ((tls1_2 && haveRSA) || (tls1_2 && haveECDSAsig)) { + #else if (tls1_2 && haveRSA) { + #endif suites->suites[idx++] = CHACHA_BYTE; suites->suites[idx++] = TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256; } #endif #ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 + #ifdef OPENSSL_EXTRA + if ((tls1_2 && haveRSA) || (tls1_2 && haveECDSAsig)) { + #else if (tls1_2 && haveRSA) { + #endif suites->suites[idx++] = CHACHA_BYTE; suites->suites[idx++] = TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256; } @@ -25410,17 +25451,24 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) } if (XSTRCMP(name, "kDH") == 0) { - haveStaticECC = allowing; if (allowing) { - haveECC = 1; - haveSig |= SIG_ECDSA; + haveDH = 1; callInitSuites = 1; ret = 1; } continue; } - if (XSTRCMP(name, "ECDHE") == 0) { + if (XSTRCMP(name, "DHE") == 0 || XSTRCMP(name, "EDH") == 0) { + if (allowing) { + haveDH = 1; + callInitSuites = 1; + ret = 1; + } + continue; + } + + if (XSTRCMP(name, "ECDHE") == 0 || XSTRCMP(name, "EECDH") == 0) { if (allowing) { haveECC = 1; haveSig |= SIG_ECDSA; @@ -34470,6 +34518,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, WOLFSSL_OP_NO_SSLv3) { WOLFSSL_MSG("\tError, option set to not allow SSLv3"); ret = VERSION_ERROR; +#ifdef WOLFSSL_EXTRA_ALERTS + SendAlert(ssl, alert_fatal, wolfssl_alert_protocol_version); +#endif goto out; } @@ -38304,6 +38355,13 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ], int ad = 0; int sniRet = 0; int ret = 0; + + /* OpenSSL defaults alert to SSL_AD_UNRECOGNIZED_NAME, use this if + WOLFSSL_EXTRA_ALERTS is defined, indicating user is OK with + potential information disclosure from alerts. */ +#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_EXTRA_ALERTS) + ad = SSL_AD_UNRECOGNIZED_NAME; +#endif /* Stunnel supports a custom sni callback to switch an SSL's ctx * when SNI is received. Call it now if exists */ if(ssl && ssl->ctx && ssl->ctx->sniRecvCb) { diff --git a/src/ssl.c b/src/ssl.c index 66ab6a89e4..3b64142ef6 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -16149,17 +16149,50 @@ int wolfSSL_set_compression(WOLFSSL* ssl) /* * This is an OpenSSL compatibility layer function, but it doesn't mirror * the exact functionality of its OpenSSL counterpart. We don't support the - * notion of an "OpenSSL directory," nor do we support the environment - * variables SSL_CERT_DIR or SSL_CERT_FILE. This function is simply a - * wrapper around our native wolfSSL_CTX_load_system_CA_certs function. This - * function does conform to OpenSSL's return value conventions, though. + * notion of an "OpenSSL directory". This function will attempt to load the + * environment variables SSL_CERT_DIR and SSL_CERT_FILE, if either are found, + * they will be loaded. Otherwise, it will act as a wrapper around our + * native wolfSSL_CTX_load_system_CA_certs function. This function does + * conform to OpenSSL's return value conventions. */ int wolfSSL_CTX_set_default_verify_paths(WOLFSSL_CTX* ctx) { int ret; +#ifdef XGETENV + char* certDir; + char* certFile; + word32 flags; +#endif WOLFSSL_ENTER("wolfSSL_CTX_set_default_verify_paths"); +#ifdef XGETENV + certDir = XGETENV("SSL_CERT_DIR"); + certFile = XGETENV("SSL_CERT_FILE"); + flags = WOLFSSL_LOAD_FLAG_PEM_CA_ONLY; + + if (certDir || certFile) { + if (certDir) { + /* + * We want to keep trying to load more CAs even if one cert in + * the directory is bad and can't be used (e.g. if one is expired), + * so we use WOLFSSL_LOAD_FLAG_IGNORE_ERR. + */ + flags |= WOLFSSL_LOAD_FLAG_IGNORE_ERR; + } + + ret = wolfSSL_CTX_load_verify_locations_ex(ctx, certFile, certDir, + flags); + if (ret != WOLFSSL_SUCCESS) { + WOLFSSL_MSG_EX("Failed to load CA certs from SSL_CERT_FILE: %s" + " SSL_CERT_DIR: %s. Error: %d", certFile, + certDir, ret); + return WOLFSSL_FAILURE; + } + return ret; + } +#endif + ret = wolfSSL_CTX_load_system_CA_certs(ctx); if (ret == WOLFSSL_BAD_PATH) { /* @@ -16649,6 +16682,32 @@ int wolfSSL_set_compression(WOLFSSL* ssl) and free it with CTX free*/ } +#ifdef OPENSSL_ALL + int wolfSSL_CTX_set1_verify_cert_store(WOLFSSL_CTX* ctx, WOLFSSL_X509_STORE* str) + { + WOLFSSL_ENTER("wolfSSL_CTX_set1_verify_cert_store"); + + if (ctx == NULL || str == NULL) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + /* NO-OP when setting existing store */ + if (str == CTX_STORE(ctx)) + return WOLFSSL_SUCCESS; + + if (wolfSSL_X509_STORE_up_ref(str) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_X509_STORE_up_ref error"); + return WOLFSSL_FAILURE; + } + + /* free existing store if it exists */ + wolfSSL_X509_STORE_free(ctx->x509_store_pt); + ctx->x509_store_pt = str; /* take ownership of store and free it + with CTX free */ + return WOLFSSL_SUCCESS; + } +#endif int wolfSSL_set0_verify_cert_store(WOLFSSL *ssl, WOLFSSL_X509_STORE* str) { @@ -16752,7 +16811,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) return 0; } - void wolfSSL_set_locking_callback(void (*f)(int, int, const char*, int)) + void wolfSSL_set_locking_callback(mutex_cb* f) { WOLFSSL_ENTER("wolfSSL_set_locking_callback"); @@ -16761,6 +16820,13 @@ int wolfSSL_set_compression(WOLFSSL* ssl) } } + mutex_cb* wolfSSL_get_locking_callback(void) + { + WOLFSSL_ENTER("wolfSSL_get_locking_callback"); + + return wc_GetMutexCb(); + } + typedef unsigned long (idCb)(void); static idCb* inner_idCb = NULL; @@ -31977,8 +32043,7 @@ int wolfSSL_CTX_get_extra_chain_certs(WOLFSSL_CTX* ctx, WOLF_STACK_OF(X509)** ch /* Create a new stack of WOLFSSL_X509 object from chain buffer. */ for (idx = 0; idx < ctx->certChain->length; ) { - node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL, - DYNAMIC_TYPE_OPENSSL); + node = wolfSSL_sk_X509_new_null(); if (node == NULL) return WOLFSSL_FAILURE; node->next = NULL; @@ -32065,8 +32130,11 @@ int wolfSSL_CTX_get0_chain_certs(WOLFSSL_CTX *ctx, WOLFSSL_MSG("Bad parameter"); return WOLFSSL_FAILURE; } - *sk = ctx->x509Chain; - return WOLFSSL_SUCCESS; + + /* This function should return ctx->x509Chain if it is populated, otherwise + it should be populated from ctx->certChain. This matches the behavior of + wolfSSL_CTX_get_extra_chain_certs, so it is used directly. */ + return wolfSSL_CTX_get_extra_chain_certs(ctx, sk); } #ifdef KEEP_OUR_CERT diff --git a/tests/api.c b/tests/api.c index 4c6eac23cb..90f04764ad 100644 --- a/tests/api.c +++ b/tests/api.c @@ -35198,8 +35198,10 @@ static int test_wolfSSL_X509_STORE(void) SSL_SUCCESS); } else { - ExpectIntEQ(SSL_set1_verify_cert_store(ssl, store), - SSL_SUCCESS); + ExpectIntEQ(SSL_set1_verify_cert_store(ssl, store), SSL_SUCCESS); + #ifdef OPENSSL_ALL + ExpectIntEQ(SSL_CTX_set1_verify_cert_store(ctx, store), SSL_SUCCESS); + #endif } if (EXPECT_FAIL() || (i == 1)) { X509_STORE_free(store); @@ -40189,9 +40191,16 @@ static int test_wolfSSL_BIO_gets(void) char emp[] = ""; char bio_buffer[20]; int bufferSz = 20; +#ifdef OPENSSL_ALL + BUF_MEM* emp_bm = NULL; + BUF_MEM* msg_bm = NULL; +#endif /* try with bad args */ ExpectNull(bio = BIO_new_mem_buf(NULL, sizeof(msg))); +#ifdef OPENSSL_ALL + ExpectIntEQ(BIO_set_mem_buf(bio, NULL, BIO_NOCLOSE), BAD_FUNC_ARG); +#endif /* try with real msg */ ExpectNotNull(bio = BIO_new_mem_buf((void*)msg, -1)); @@ -40213,6 +40222,42 @@ static int test_wolfSSL_BIO_gets(void) ExpectIntEQ(BIO_gets(bio, bio_buffer, bufferSz), 8); ExpectIntEQ(BIO_gets(bio, bio_buffer, -1), 0); +#ifdef OPENSSL_ALL + /* test setting the mem_buf manually */ + BIO_free(bio); + ExpectNotNull(bio = BIO_new_mem_buf((void*)msg, -1)); + ExpectNotNull(emp_bm = BUF_MEM_new()); + ExpectNotNull(msg_bm = BUF_MEM_new()); + ExpectIntEQ(BUF_MEM_grow(msg_bm, sizeof(msg)), sizeof(msg)); + XFREE(msg_bm->data, NULL, DYNAMIC_TYPE_OPENSSL); + /* emp size is 1 for terminator */ + ExpectIntEQ(BUF_MEM_grow(emp_bm, sizeof(emp)), sizeof(emp)); + XFREE(emp_bm->data, NULL, DYNAMIC_TYPE_OPENSSL); + emp_bm->data = emp; + msg_bm->data = msg; + ExpectIntEQ(BIO_set_mem_buf(bio, emp_bm, BIO_CLOSE), WOLFSSL_SUCCESS); + + /* check reading an empty string */ + ExpectIntEQ(BIO_gets(bio, bio_buffer, bufferSz), 1); /* just terminator */ + ExpectStrEQ(emp, bio_buffer); + ExpectIntEQ(BIO_gets(bio, bio_buffer, bufferSz), 0); /* Nothing to read */ + + /* BIO_gets reads a line of data */ + ExpectIntEQ(BIO_set_mem_buf(bio, msg_bm, BIO_NOCLOSE), WOLFSSL_SUCCESS); + ExpectIntEQ(BIO_gets(bio, bio_buffer, -3), 0); + ExpectIntEQ(BIO_gets(bio, bio_buffer, bufferSz), 1); + ExpectIntEQ(BIO_gets(bio, bio_buffer, bufferSz), 14); + ExpectStrEQ(bio_buffer, "hello wolfSSL\n"); + ExpectIntEQ(BIO_gets(bio, bio_buffer, bufferSz), 19); + ExpectIntEQ(BIO_gets(bio, bio_buffer, bufferSz), 8); + ExpectIntEQ(BIO_gets(bio, bio_buffer, -1), 0); + + emp_bm->data = NULL; + BUF_MEM_free(emp_bm); + msg_bm->data = NULL; + BUF_MEM_free(msg_bm); +#endif + /* check not null terminated string */ BIO_free(bio); bio = NULL; @@ -40468,12 +40513,11 @@ static int test_wolfSSL_BIO_should_retry(void) tcp_connect(&sockfd, wolfSSLIP, server_args.signal->port, 0, 0, NULL); /* force retry */ - ExpectNotNull(ssl = wolfSSL_new(ctx)); + ExpectNotNull(bio = wolfSSL_BIO_new_ssl(ctx, 1)); + ExpectIntEQ(BIO_get_ssl(bio, &ssl), 1); + ExpectNotNull(ssl); ExpectIntEQ(wolfSSL_set_fd(ssl, sockfd), WOLFSSL_SUCCESS); wolfSSL_SSLSetIORecv(ssl, forceWantRead); - - ExpectNotNull(bio = BIO_new(BIO_f_ssl())); - ExpectIntEQ(BIO_set_ssl(bio, ssl, BIO_CLOSE), 1); if (EXPECT_FAIL()) { wolfSSL_free(ssl); ssl = NULL; @@ -40481,6 +40525,8 @@ static int test_wolfSSL_BIO_should_retry(void) ExpectIntLE(BIO_write(bio, msg, msgSz), 0); ExpectIntNE(BIO_should_retry(bio), 0); + ExpectIntEQ(BIO_should_read(bio), 0); + ExpectIntEQ(BIO_should_write(bio), 0); /* now perform successful connection */ @@ -40490,9 +40536,21 @@ static int test_wolfSSL_BIO_should_retry(void) ret = wolfSSL_get_error(ssl, -1); if (ret == WOLFSSL_ERROR_WANT_READ || ret == WOLFSSL_ERROR_WANT_WRITE) { ExpectIntNE(BIO_should_retry(bio), 0); + + if (ret == WOLFSSL_ERROR_WANT_READ) + ExpectIntEQ(BIO_should_read(bio), 1); + else + ExpectIntEQ(BIO_should_read(bio), 0); + + if (ret == WOLFSSL_ERROR_WANT_WRITE) + ExpectIntEQ(BIO_should_write(bio), 1); + else + ExpectIntEQ(BIO_should_write(bio), 0); } else { ExpectIntEQ(BIO_should_retry(bio), 0); + ExpectIntEQ(BIO_should_read(bio), 0); + ExpectIntEQ(BIO_should_write(bio), 0); } ExpectIntEQ(XMEMCMP(reply, "I hear you fa shizzle!", XSTRLEN("I hear you fa shizzle!")), 0); diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index a8c14b1661..1e893f5b95 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -1342,6 +1342,14 @@ int wolfSSL_CryptHwMutexUnLock(void) compat_mutex_cb = cb; return 0; } + + /* Gets the current callback function in use for locking/unlocking mutex + * + */ + mutex_cb* wc_GetMutexCb(void) + { + return compat_mutex_cb; + } #endif /* defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) */ #ifdef SINGLE_THREADED diff --git a/wolfssl/internal.h b/wolfssl/internal.h index cb2b476441..436344ca1a 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -5804,10 +5804,14 @@ struct WOLFSSL { * Always use SSL specific objects when available and revert to CTX otherwise. */ #ifdef WOLFSSL_LOCAL_X509_STORE -#define SSL_CM(ssl) ((ssl)->x509_store_pt ? (ssl)->x509_store_pt->cm : (ssl)->ctx->cm) +#define SSL_CM(ssl) ((ssl)->x509_store_pt ? (ssl)->x509_store_pt->cm : \ + ((ssl)->ctx->x509_store_pt ? (ssl)->ctx->x509_store_pt->cm : \ + (ssl)->ctx->cm)) #define SSL_STORE(ssl) ((ssl)->x509_store_pt ? (ssl)->x509_store_pt : \ ((ssl)->ctx->x509_store_pt ? (ssl)->ctx->x509_store_pt : \ &(ssl)->ctx->x509_store)) +#define CTX_STORE(ctx) ((ctx)->x509_store_pt ? (ctx)->x509_store_pt : \ + &(ctx)->x509_store) #else #define SSL_CM(ssl) (ssl)->ctx->cm #endif diff --git a/wolfssl/openssl/bio.h b/wolfssl/openssl/bio.h index c2a0e9bc8c..e6f5a709ca 100644 --- a/wolfssl/openssl/bio.h +++ b/wolfssl/openssl/bio.h @@ -52,6 +52,9 @@ #define BIO_ctrl_pending wolfSSL_BIO_ctrl_pending #define BIO_wpending wolfSSL_BIO_wpending #define BIO_get_mem_ptr wolfSSL_BIO_get_mem_ptr +#ifdef OPENSSL_ALL +#define BIO_set_mem_buf wolfSSL_BIO_set_mem_buf +#endif #define BIO_int_ctrl wolfSSL_BIO_int_ctrl #define BIO_reset wolfSSL_BIO_reset #define BIO_s_file wolfSSL_BIO_s_file @@ -79,6 +82,8 @@ #define BIO_puts wolfSSL_BIO_puts #define BIO_should_retry wolfSSL_BIO_should_retry +#define BIO_should_read wolfSSL_BIO_should_read +#define BIO_should_write wolfSSL_BIO_should_write #define BIO_TYPE_FILE WOLFSSL_BIO_FILE #define BIO_TYPE_BIO WOLFSSL_BIO_BIO diff --git a/wolfssl/openssl/crypto.h b/wolfssl/openssl/crypto.h index 7a4e1d8a95..f57626f333 100644 --- a/wolfssl/openssl/crypto.h +++ b/wolfssl/openssl/crypto.h @@ -97,7 +97,7 @@ WOLFSSL_API int wolfSSL_OPENSSL_init_crypto(word64 opts, const OPENSSL_INIT_SETT #define SSLeay wolfSSLeay #define OpenSSL_version_num wolfSSL_OpenSSL_version_num -#ifdef WOLFSSL_QT +#if defined(WOLFSSL_QT) || defined(WOLFSSL_HITCH) #define SSLEAY_VERSION 0x10001000L #else #define SSLEAY_VERSION 0x0090600fL diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 0bfe1e6ef5..63ce513ed4 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -165,6 +165,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define CRYPTO_WRITE 0x08 #define CRYPTO_set_locking_callback wolfSSL_set_locking_callback +#define CRYPTO_get_locking_callback wolfSSL_get_locking_callback #define CRYPTO_set_dynlock_create_callback wolfSSL_set_dynlock_create_callback #define CRYPTO_set_dynlock_lock_callback wolfSSL_set_dynlock_lock_callback #define CRYPTO_set_dynlock_destroy_callback wolfSSL_set_dynlock_destroy_callback @@ -783,6 +784,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define BIO_method_type wolfSSL_BIO_method_type #define BIO_set_ssl wolfSSL_BIO_set_ssl #define BIO_get_ssl wolfSSL_BIO_get_ssl +#define BIO_new_ssl wolfSSL_BIO_new_ssl #define BIO_new_ssl_connect wolfSSL_BIO_new_ssl_connect #define BIO_set_conn_hostname wolfSSL_BIO_set_conn_hostname #define BIO_eof wolfSSL_BIO_eof @@ -899,6 +901,9 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define SSL_CTX_set_client_CA_list wolfSSL_CTX_set_client_CA_list #define SSL_CTX_set_client_cert_cb wolfSSL_CTX_set_client_cert_cb #define SSL_CTX_set_cert_store wolfSSL_CTX_set_cert_store +#ifdef OPENSSL_ALL +#define SSL_CTX_set1_verify_cert_store wolfSSL_CTX_set1_verify_cert_store +#endif #define SSL_set0_verify_cert_store wolfSSL_set0_verify_cert_store #define SSL_set1_verify_cert_store wolfSSL_set1_verify_cert_store #define SSL_CTX_get_cert_store(x) wolfSSL_CTX_get_cert_store ((WOLFSSL_CTX*) (x)) @@ -1269,6 +1274,7 @@ typedef WOLFSSL_SRTP_PROTECTION_PROFILE SRTP_PROTECTION_PROFILE; #define SSL_CTRL_SET_GROUPS 91 #define SSL_CTRL_GET_PEER_TMP_KEY 109 #define SSL_CTRL_GET_SERVER_TMP_KEY SSL_CTRL_GET_PEER_TMP_KEY +#define SSL_CTRL_GET_CHAIN_CERTS 115 #define SSL_CTRL_SET_MIN_PROTO_VERSION 123 #define SSL_CTRL_SET_MAX_PROTO_VERSION 124 #define SSL_CTRL_GET_MIN_PROTO_VERSION 125 diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 90f35b0f0e..42fc237f2d 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1740,6 +1740,8 @@ WOLFSSL_API void wolfSSL_BIO_set_shutdown(WOLFSSL_BIO* bio, int shut); WOLFSSL_API int wolfSSL_BIO_get_shutdown(WOLFSSL_BIO* bio); WOLFSSL_API void wolfSSL_BIO_clear_retry_flags(WOLFSSL_BIO* bio); WOLFSSL_API int wolfSSL_BIO_should_retry(WOLFSSL_BIO *bio); +WOLFSSL_API int wolfSSL_BIO_should_read(WOLFSSL_BIO *bio); +WOLFSSL_API int wolfSSL_BIO_should_write(WOLFSSL_BIO *bio); WOLFSSL_API WOLFSSL_BIO_METHOD *wolfSSL_BIO_meth_new(int type, const char* name); WOLFSSL_API void wolfSSL_BIO_meth_free(WOLFSSL_BIO_METHOD* biom); @@ -1775,6 +1777,7 @@ WOLFSSL_API long wolfSSL_BIO_set_conn_hostname(WOLFSSL_BIO* b, char* name); WOLFSSL_API long wolfSSL_BIO_set_conn_port(WOLFSSL_BIO *b, char* port); WOLFSSL_API long wolfSSL_BIO_do_connect(WOLFSSL_BIO *b); WOLFSSL_API int wolfSSL_BIO_do_accept(WOLFSSL_BIO *b); +WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_new_ssl(WOLFSSL_CTX* ctx, int client); WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_new_ssl_connect(WOLFSSL_CTX* ctx); WOLFSSL_API long wolfSSL_BIO_do_handshake(WOLFSSL_BIO *b); @@ -1797,6 +1800,10 @@ WOLFSSL_API int wolfSSL_BIO_tell(WOLFSSL_BIO* bio); WOLFSSL_API int wolfSSL_BIO_write_filename(WOLFSSL_BIO *bio, char *name); WOLFSSL_API long wolfSSL_BIO_set_mem_eof_return(WOLFSSL_BIO *bio, int v); WOLFSSL_API long wolfSSL_BIO_get_mem_ptr(WOLFSSL_BIO *bio, WOLFSSL_BUF_MEM **m); +#ifdef OPENSSL_ALL +WOLFSSL_API int wolfSSL_BIO_set_mem_buf(WOLFSSL_BIO* bio, WOLFSSL_BUF_MEM* bufMem, + int closeFlag); +#endif WOLFSSL_API int wolfSSL_BIO_get_len(WOLFSSL_BIO *bio); #endif @@ -1816,8 +1823,10 @@ WOLFSSL_API int wolfSSL_COMP_add_compression_method(int method, void* data); WOLFSSL_API unsigned long wolfSSL_thread_id(void); WOLFSSL_API void wolfSSL_set_id_callback(unsigned long (*f)(void)); -WOLFSSL_API void wolfSSL_set_locking_callback(void (*f)(int, int, const char*, - int)); +#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) +WOLFSSL_API void wolfSSL_set_locking_callback(mutex_cb* f); +WOLFSSL_API mutex_cb* wolfSSL_get_locking_callback(void); +#endif WOLFSSL_API void wolfSSL_set_dynlock_create_callback(WOLFSSL_dynlock_value* (*f) (const char*, int)); WOLFSSL_API void wolfSSL_set_dynlock_lock_callback(void (*f)(int, @@ -4349,6 +4358,10 @@ WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509) *wolfSSL_get0_verified_chain( const WOLFSSL *ssl); WOLFSSL_API void wolfSSL_CTX_set_cert_store(WOLFSSL_CTX* ctx, WOLFSSL_X509_STORE* str); +#ifdef OPENSSL_ALL +WOLFSSL_API int wolfSSL_CTX_set1_verify_cert_store(WOLFSSL_CTX* ctx, + WOLFSSL_X509_STORE* str); +#endif WOLFSSL_API int wolfSSL_set0_verify_cert_store(WOLFSSL *ssl, WOLFSSL_X509_STORE* str); WOLFSSL_API int wolfSSL_set1_verify_cert_store(WOLFSSL *ssl, diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index 6a6bf87bc2..01e144bc3d 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -447,6 +447,7 @@ typedef void (mutex_cb)(int flag, int type, const char* file, int line); WOLFSSL_API int wc_LockMutex_ex(int flag, int type, const char* file, int line); WOLFSSL_API int wc_SetMutexCb(mutex_cb* cb); +WOLFSSL_API mutex_cb* wc_GetMutexCb(void); #endif /* main crypto initialization function */