From ae9b01c5b8131d2de128d326afd4cfd1bcb53ac1 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 11 Mar 2022 19:57:54 +0100 Subject: [PATCH 1/6] bind 9.18.0 fixes - return `1` from `wolfSSL_BIO_set_mem_eof_return` instead of `0` for success - bind requires ALPN - `OPENSSL_COMPATIBLE_DEFAULT` defined for bind - `WOLFSSL_ERROR_CODE_OPENSSL` defined when using compatibility layer - return `bio->eof` on no pending data to read in memory BIO (defaults to `WOLFSSL_BIO_ERROR`) - `flags` is no longer an input parameter in `wolfSSL_ERR_get_error_line_data` - allow lazy parameter loading in `wolfSSL_DH_set0_key` - implement reference counter in `WOLFSSL_EC_KEY` - load serial number from `x509->serialNumber` if `x509->serial` is empty --- configure.ac | 8 ++- src/bio.c | 17 ++++-- src/ssl.c | 84 ++++++++++++++++++--------- wolfcrypt/src/evp.c | 131 ++++++++++++++++--------------------------- wolfssl/openssl/ec.h | 8 +++ 5 files changed, 130 insertions(+), 118 deletions(-) diff --git a/configure.ac b/configure.ac index 668dd2f31..1b4c6e998 100644 --- a/configure.ac +++ b/configure.ac @@ -4241,6 +4241,11 @@ AC_ARG_ENABLE([alpn], [ ENABLED_ALPN=$enableval ], [ ENABLED_ALPN=no ] ) + +if test "$ENABLED_BIND" = "yes" +then + ENABLED_ALPN=yes +fi if test "x$ENABLED_ALPN" = "xyes" then @@ -4964,6 +4969,7 @@ then AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_BIND -DWOLFSSL_DSA_768_MODULUS" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AES_DIRECT -DHAVE_AES_ECB -DWOLFSSL_DES_ECB" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SHA224 -DWOLFSSL_SHA384 -DWOLFSSL_SHA512" + AM_CFLAGS="$AM_CFLAGS -DOPENSSL_COMPATIBLE_DEFAULTS" ENABLED_SHA224="yes" ENABLED_SHA384="yes" ENABLED_SHA512="yes" @@ -7181,7 +7187,7 @@ then AM_CFLAGS="$AM_CFLAGS -DOPENSSL_EXTRA -DWOLFSSL_ALWAYS_VERIFY_CB" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_VERIFY_CB_ALL_CERTS -DWOLFSSL_EXTRA_ALERTS" AM_CFLAGS="$AM_CFLAGS -DHAVE_EXT_CACHE -DWOLFSSL_FORCE_CACHE_ON_TICKET" - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AKID_NAME -DHAVE_CTS" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AKID_NAME -DHAVE_CTS -DWOLFSSL_ERROR_CODE_OPENSSL" fi if test "$ENABLED_OPENSSLEXTRA" = "x509small" diff --git a/src/bio.c b/src/bio.c index 5c832a674..af989e8b3 100644 --- a/src/bio.c +++ b/src/bio.c @@ -133,7 +133,12 @@ static int wolfSSL_BIO_MEMORY_read(WOLFSSL_BIO* bio, void* buf, int len) } } else { - return WOLFSSL_BIO_ERROR; + if (bio->eof < 0) /* Sanity check the eof value */ + return bio->eof; + else { + WOLFSSL_MSG("Weird bio->eof value. Returning default"); + return WOLFSSL_BIO_ERROR; + } } return sz; @@ -1583,13 +1588,13 @@ int wolfSSL_BIO_tell(WOLFSSL_BIO* bio) long wolfSSL_BIO_set_mem_eof_return(WOLFSSL_BIO *bio, int v) { - WOLFSSL_ENTER("wolfSSL_BIO_set_mem_eof_return"); + WOLFSSL_ENTER("wolfSSL_BIO_set_mem_eof_return"); - if (bio != NULL) { + if (bio != NULL) { bio->eof = v; - } + } - return 0; + return WOLFSSL_SUCCESS; } int wolfSSL_BIO_get_len(WOLFSSL_BIO *bio) @@ -2467,6 +2472,8 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) bio->shutdown = BIO_CLOSE; /* default to close things */ bio->num = WOLFSSL_BIO_ERROR; bio->init = 1; + if (method->type == WOLFSSL_BIO_MEMORY) + bio->eof = WOLFSSL_BIO_ERROR; /* Return value for empty buffer */ if (method->type == WOLFSSL_BIO_MEMORY || method->type == WOLFSSL_BIO_BIO) { bio->mem_buf =(WOLFSSL_BUF_MEM*)XMALLOC(sizeof(WOLFSSL_BUF_MEM), diff --git a/src/ssl.c b/src/ssl.c index 773c5ae05..31b5bbb8d 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -20872,7 +20872,7 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out, * file output pointer to file where error happened * line output to line number of error * data output data. Is a string if ERR_TXT_STRING flag is used - * flags bit flag to adjust data output + * flags output format of output * * Returns the error value or 0 if no errors are in the queue */ @@ -20884,24 +20884,10 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out, WOLFSSL_ENTER("wolfSSL_ERR_get_error_line_data"); - if (flags != NULL) { - if ((*flags & ERR_TXT_STRING) == ERR_TXT_STRING) { - ret = wc_PullErrorNode(file, data, line); - if (ret < 0) { - if (ret == BAD_STATE_E) return 0; /* no errors in queue */ - WOLFSSL_MSG("Error with pulling error node!"); - WOLFSSL_LEAVE("wolfSSL_ERR_get_error_line_data", ret); - ret = 0 - ret; /* return absolute value of error */ + if (flags != NULL) + *flags = ERR_TXT_STRING; /* Clear the flags */ - /* panic and try to clear out nodes */ - wc_ClearErrorNodes(); - } - - return (unsigned long)ret; - } - } - - ret = wc_PullErrorNode(file, NULL, line); + ret = wc_PullErrorNode(file, data, line); if (ret < 0) { if (ret == BAD_STATE_E) return 0; /* no errors in queue */ WOLFSSL_MSG("Error with pulling error node!"); @@ -34998,7 +34984,10 @@ int wolfSSL_DH_set0_key(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *pub_key, dh->priv_key = priv_key; } - return SetDhInternal(dh); + if (dh->p == NULL || dh->g == NULL) + return WOLFSSL_SUCCESS; /* Allow loading parameters afterwards */ + else + return SetDhInternal(dh); } /* See RFC 5114 section 2.3, "2048-bit MODP Group with 256-bit Prime Order @@ -38992,11 +38981,13 @@ void wolfSSL_EC_KEY_free(WOLFSSL_EC_KEY *key) WOLFSSL_ENTER("wolfSSL_EC_KEY_free"); if (key != NULL) { + int doFree = 0; void* heap = key->heap; #ifndef SINGLE_THREADED if (wc_LockMutex(&key->refMutex) != 0) { WOLFSSL_MSG("Could not lock EC_KEY mutex"); + return; } #endif @@ -39017,14 +39008,30 @@ void wolfSSL_EC_KEY_free(WOLFSSL_EC_KEY *key) wc_ecc_free((ecc_key*)key->internal); XFREE(key->internal, heap, DYNAMIC_TYPE_ECC); } - wolfSSL_BN_free(key->priv_key); - wolfSSL_EC_POINT_free(key->pub_key); - wolfSSL_EC_GROUP_free(key->group); - InitwolfSSL_ECKey(key); /* set back to NULLs for safety */ +#endif + /* only free if all references to it are done */ + key->refCount--; + if (key->refCount == 0) { + doFree = 1; + } +#ifndef SINGLE_THREADED + wc_UnLockMutex(&key->refMutex); +#endif - XFREE(key, heap, DYNAMIC_TYPE_ECC); - (void)heap; - /* key = NULL, don't try to access or double free it */ + if (doFree) { + if (key->internal != NULL) { + wc_ecc_free((ecc_key*)key->internal); + XFREE(key->internal, heap, DYNAMIC_TYPE_ECC); + } + wolfSSL_BN_free(key->priv_key); + wolfSSL_EC_POINT_free(key->pub_key); + wolfSSL_EC_GROUP_free(key->group); + InitwolfSSL_ECKey(key); /* set back to NULLs for safety */ + + XFREE(key, heap, DYNAMIC_TYPE_ECC); + (void)heap; + /* key = NULL, don't try to access or double free it */ + } } } @@ -39964,6 +39971,13 @@ int wolfSSL_i2o_ECPublicKey(const WOLFSSL_EC_KEY *in, unsigned char **out) return WOLFSSL_FAILURE; } + if (!in->exSet) { + if (SetECKeyExternal((WOLFSSL_EC_KEY*)in) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("SetECKeyExternal failure"); + return WOLFSSL_FAILURE; + } + } + #ifdef HAVE_COMP_KEY /* Default to compressed form if not set */ form = in->form == POINT_CONVERSION_UNCOMPRESSED ? @@ -44296,6 +44310,17 @@ void* wolfSSL_GetHKDFExtractCtx(WOLFSSL* ssl) XMEMCPY(cert->challengePw, x509->challengePw, CTC_NAME_SIZE); #endif + if (x509->serialSz == 0 && x509->serialNumber != NULL && + /* Check if the buffer contains more than just the + * ASN tag and length */ + x509->serialNumber->length > 2) { + if (wolfSSL_X509_set_serialNumber(x509, x509->serialNumber) + != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Failed to set serial number"); + return WOLFSSL_FAILURE; + } + } + /* set serial number */ if (x509->serialSz > 0) { #if defined(OPENSSL_EXTRA) @@ -56602,6 +56627,7 @@ void wolfSSL_RSA_free(WOLFSSL_RSA* rsa) #ifndef SINGLE_THREADED if (wc_LockMutex(&rsa->refMutex) != 0) { WOLFSSL_MSG("Couldn't lock rsa mutex"); + return; } #endif @@ -57242,8 +57268,10 @@ int wolfSSL_X509_set_serialNumber(WOLFSSL_X509* x509, WOLFSSL_ASN1_INTEGER* s) if (!x509 || !s || s->length >= EXTERNAL_SERIAL_SIZE) return WOLFSSL_FAILURE; - /* WOLFSSL_ASN1_INTEGER has type | size | data */ - if (s->length < 3) { + /* WOLFSSL_ASN1_INTEGER has type | size | data + * Sanity check that the data is actually in ASN format */ + if (s->length < 3 && s->data[0] != ASN_INTEGER && + s->data[1] != s->length - 2) { return WOLFSSL_FAILURE; } XMEMCPY(x509->serial, s->data + 2, s->length - 2); diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 864b468aa..39d306d09 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -6731,6 +6731,41 @@ const WOLFSSL_EVP_MD* wolfSSL_EVP_get_digestbynid(int id) return NULL; } +static void clearEVPPkeyKeys(WOLFSSL_EVP_PKEY *pkey) +{ + if(pkey == NULL) + return; + WOLFSSL_ENTER("clearEVPPkeyKeys"); +#ifndef NO_RSA + if (pkey->rsa != NULL && pkey->ownRsa == 1) { + wolfSSL_RSA_free(pkey->rsa); + pkey->rsa = NULL; + } + pkey->ownRsa = 0; +#endif +#ifndef NO_DSA + if (pkey->dsa != NULL && pkey->ownDsa == 1) { + wolfSSL_DSA_free(pkey->dsa); + pkey->dsa = NULL; + } + pkey->ownDsa = 0; +#endif +#ifndef NO_DH + if (pkey->dh != NULL && pkey->ownDh == 1) { + wolfSSL_DH_free(pkey->dh); + pkey->dh = NULL; + } + pkey->ownDh = 0; +#endif +#ifdef HAVE_ECC + if (pkey->ecc != NULL && pkey->ownEcc == 1) { + wolfSSL_EC_KEY_free(pkey->ecc); + pkey->ecc = NULL; + } + pkey->ownEcc = 0; +#endif +} + #ifndef NO_RSA #if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA) static int PopulateRSAEvpPkeyDer(WOLFSSL_EVP_PKEY *pkey) @@ -6779,7 +6814,7 @@ static int PopulateRSAEvpPkeyDer(WOLFSSL_EVP_PKEY *pkey) derBuf = (byte*)XREALLOC(pkey->pkey.ptr, derSz, pkey->heap, DYNAMIC_TYPE_DER); if (derBuf == NULL) { - WOLFSSL_MSG("EVP_PKEY_set1_RSA malloc failed"); + WOLFSSL_MSG("PopulateRSAEvpPkeyDer malloc failed"); return WOLFSSL_FAILURE; } /* Old pointer is invalid from this point on */ @@ -6866,9 +6901,7 @@ int wolfSSL_EVP_PKEY_set1_RSA(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_RSA *key) return WOLFSSL_FAILURE; } - if (pkey->rsa != NULL && pkey->ownRsa == 1) { - wolfSSL_RSA_free(pkey->rsa); - } + clearEVPPkeyKeys(pkey); pkey->rsa = key; pkey->ownRsa = 1; /* pkey does not own RSA but needs to call free on it */ pkey->type = EVP_PKEY_RSA; @@ -6914,9 +6947,7 @@ int wolfSSL_EVP_PKEY_set1_DSA(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_DSA *key) WOLFSSL_ENTER("wolfSSL_EVP_PKEY_set1_DSA"); if((pkey == NULL) || (key == NULL))return WOLFSSL_FAILURE; - if (pkey->dsa != NULL && pkey->ownDsa == 1) { - wolfSSL_DSA_free(pkey->dsa); - } + clearEVPPkeyKeys(pkey); pkey->dsa = key; pkey->ownDsa = 0; /* pkey does not own DSA */ pkey->type = EVP_PKEY_DSA; @@ -7020,7 +7051,7 @@ WOLFSSL_DSA* wolfSSL_EVP_PKEY_get1_DSA(WOLFSSL_EVP_PKEY* key) WOLFSSL_EC_KEY *wolfSSL_EVP_PKEY_get0_EC_KEY(WOLFSSL_EVP_PKEY *pkey) { WOLFSSL_EC_KEY *eckey = NULL; - if (pkey) { + if (pkey && pkey->type == EVP_PKEY_EC) { #ifdef HAVE_ECC eckey = pkey->ecc; #endif @@ -7030,10 +7061,9 @@ WOLFSSL_EC_KEY *wolfSSL_EVP_PKEY_get0_EC_KEY(WOLFSSL_EVP_PKEY *pkey) WOLFSSL_EC_KEY* wolfSSL_EVP_PKEY_get1_EC_KEY(WOLFSSL_EVP_PKEY* key) { - WOLFSSL_EC_KEY* local = NULL; WOLFSSL_ENTER("wolfSSL_EVP_PKEY_get1_EC_KEY"); - if (key == NULL) { + if (key == NULL || key->type != EVP_PKEY_EC) { return NULL; } if (key->type == EVP_PKEY_EC) { @@ -7050,27 +7080,12 @@ WOLFSSL_EC_KEY* wolfSSL_EVP_PKEY_get1_EC_KEY(WOLFSSL_EVP_PKEY* key) return NULL; } - if (wolfSSL_EC_KEY_LoadDer(local, - (const unsigned char*)key->pkey.ptr, - key->pkey_sz) != WOLFSSL_SUCCESS) { - /* now try public key */ - if (wolfSSL_EC_KEY_LoadDer_ex(local, - (const unsigned char*)key->pkey.ptr, key->pkey_sz, - WOLFSSL_EC_KEY_LOAD_PUBLIC) != WOLFSSL_SUCCESS) { - - wolfSSL_EC_KEY_free(local); - local = NULL; - } - } - } - } - else { - WOLFSSL_MSG("WOLFSSL_EVP_PKEY does not hold an EC key"); - wolfSSL_EC_KEY_free(local); - local = NULL; + if (wolfSSL_EC_KEY_up_ref(key->ecc) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_EC_KEY_up_ref error"); + return NULL; } - return local; + return key->ecc; } #endif /* HAVE_ECC */ @@ -7095,33 +7110,7 @@ int wolfSSL_EVP_PKEY_set1_DH(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_DH *key) if (pkey == NULL || key == NULL) return WOLFSSL_FAILURE; - /* free other types if needed */ -#ifndef NO_RSA - if (pkey->rsa != NULL && pkey->ownRsa == 1) { - wolfSSL_RSA_free(pkey->rsa); - } - pkey->ownRsa = 0; -#endif -#ifndef NO_DSA - if (pkey->dsa != NULL && pkey->ownDsa == 1) { - wolfSSL_DSA_free(pkey->dsa); - } - pkey->ownDsa = 0; -#endif -#ifdef HAVE_ECC - if (pkey->ecc != NULL && pkey->ownEcc == 1) { - wolfSSL_EC_KEY_free(pkey->ecc); - } - pkey->ownEcc = 0; -#endif - - if (wolfSSL_DH_up_ref(key) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("wolfSSL_DH_up_ref failed"); - return WOLFSSL_FAILURE; - } - - if (pkey->dh != NULL && pkey->ownDh == 1) - wolfSSL_DH_free(pkey->dh); + clearEVPPkeyKeys(pkey); pkey->dh = key; pkey->ownDh = 1; /* pkey does not own DH but needs to call free on it */ @@ -7358,39 +7347,13 @@ int wolfSSL_EVP_PKEY_set1_EC_KEY(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_EC_KEY *key) { #ifdef HAVE_ECC WOLFSSL_ENTER("wolfSSL_EVP_PKEY_set1_EC_KEY"); - - if (pkey == NULL || key == NULL) { - return WOLFSSL_FAILURE; - } -#ifndef NO_RSA - if (pkey->rsa != NULL && pkey->ownRsa == 1) { - wolfSSL_RSA_free(pkey->rsa); - } - pkey->ownRsa = 0; -#endif -#ifndef NO_DSA - if (pkey->dsa != NULL && pkey->ownDsa == 1) { - wolfSSL_DSA_free(pkey->dsa); - } - pkey->ownDsa = 0; -#endif -#ifndef NO_DH - if (pkey->dh != NULL && pkey->ownDh == 1) { - wolfSSL_DH_free(pkey->dh); - } - pkey->ownDh = 0; -#endif - + clearEVPPkeyKeys(pkey); if (wolfSSL_EC_KEY_up_ref(key) != WOLFSSL_SUCCESS) { WOLFSSL_MSG("wolfSSL_EC_KEY_up_ref failed"); return WOLFSSL_FAILURE; } - - if (pkey->ecc != NULL && pkey->ownEcc == 1) { - wolfSSL_EC_KEY_free(pkey->ecc); - } pkey->ecc = key; - pkey->ownEcc = 1; /* doesn't own EC_KEY but needs to call free on it */ + pkey->ownEcc = 1; /* pkey needs to call free on key */ pkey->type = EVP_PKEY_EC; return ECC_populate_EVP_PKEY(pkey, key); #else diff --git a/wolfssl/openssl/ec.h b/wolfssl/openssl/ec.h index fa0ac7a6b..6c57fc7c6 100644 --- a/wolfssl/openssl/ec.h +++ b/wolfssl/openssl/ec.h @@ -127,6 +127,11 @@ struct WOLFSSL_EC_KEY { /* option bits */ byte inSet:1; /* internal set from external ? */ byte exSet:1; /* external set from internal ? */ + +#ifndef SINGLE_THREADED + wolfSSL_Mutex refMutex; /* ref count mutex */ +#endif + int refCount; /* reference count */ }; struct WOLFSSL_EC_BUILTIN_CURVE { @@ -209,6 +214,8 @@ WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new_ex(void* heap, int devId); WOLFSSL_API WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new(void); WOLFSSL_API +int wolfSSL_EC_KEY_up_ref(WOLFSSL_EC_KEY* key); +WOLFSSL_API int wolfSSL_EC_KEY_set_group(WOLFSSL_EC_KEY *key, WOLFSSL_EC_GROUP *group); WOLFSSL_API int wolfSSL_EC_KEY_generate_key(WOLFSSL_EC_KEY *key); @@ -312,6 +319,7 @@ typedef WOLFSSL_EC_BUILTIN_CURVE EC_builtin_curve; #define EC_KEY_new wolfSSL_EC_KEY_new #define EC_KEY_free wolfSSL_EC_KEY_free +#define EC_KEY_up_ref wolfSSL_EC_KEY_up_ref #define EC_KEY_dup wolfSSL_EC_KEY_dup #define EC_KEY_up_ref wolfSSL_EC_KEY_up_ref #define EC_KEY_get0_public_key wolfSSL_EC_KEY_get0_public_key From 98bc8402db746778c082f1883d9d3371120ffbbe Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 16 Mar 2022 21:17:40 +0100 Subject: [PATCH 2/6] Refactor memory BIO - use the `WOLFSSL_BUF_MEM` struct to resize the internal memory buffer - add a `WOLFSSL_BIO_RESIZE_THRESHOLD` define that will be used to determine how often to shrink the internal buffer. This should cut down on the number of free/malloc calls made significantly. This should help with our inefficient 1 byte reads in `loadX509orX509REQFromPemBio`. - implement `wolfSSL_BUF_MEM_resize` which allows bi-directional buffer size manipulation --- src/bio.c | 190 ++++++++++++++++++++------------------- src/ssl.c | 59 ++++++++++-- tests/api.c | 4 + wolfssl/openssl/buffer.h | 3 + 4 files changed, 154 insertions(+), 102 deletions(-) diff --git a/src/bio.c b/src/bio.c index af989e8b3..791034980 100644 --- a/src/bio.c +++ b/src/bio.c @@ -36,6 +36,13 @@ #endif #else +/* + * WOLFSSL_BIO_RESIZE_THRESHOLD: + * The amount of data to return before we attempt to resize the internal + * buffers. After we have returned more than this define amount of bytes of + * data, we will resize the buffers to get rid of excess memory. + */ + /* Helper function to decode a base64 input * @@ -75,6 +82,9 @@ static int wolfSSL_BIO_BIO_read(WOLFSSL_BIO* bio, void* buf, int len) return sz; } +#ifndef WOLFSSL_BIO_RESIZE_THRESHOLD +#define WOLFSSL_BIO_RESIZE_THRESHOLD 100 +#endif /* Handles reading from a memory type BIO and advancing the state. * @@ -97,39 +107,56 @@ static int wolfSSL_BIO_MEMORY_read(WOLFSSL_BIO* bio, void* buf, int len) sz = wolfSSL_BIO_pending(bio); if (sz > 0) { - const unsigned char* pt = NULL; int memSz; + if (bio->mem_buf == NULL) { + WOLFSSL_MSG("bio->mem_buf is null"); + return WOLFSSL_BIO_ERROR; + } + if (sz > len) { sz = len; } - memSz = wolfSSL_BIO_get_mem_data(bio, (void*)&pt); - if (memSz >= sz && pt != NULL) { - byte* tmp; - XMEMCPY(buf, (void*)pt, sz); - if (memSz - sz > 0) { - tmp = (byte*)XMALLOC(memSz-sz, bio->heap, DYNAMIC_TYPE_OPENSSL); - if (tmp == NULL) { - WOLFSSL_MSG("Memory error"); - return WOLFSSL_BIO_ERROR; - } - XMEMCPY(tmp, (void*)(pt + sz), memSz - sz); - - /* reset internal bio->mem */ - XFREE(bio->ptr, bio->heap, DYNAMIC_TYPE_OPENSSL); - bio->ptr = tmp; - bio->num = memSz-sz; - if (bio->mem_buf != NULL) { - bio->mem_buf->data = (char*)bio->ptr; - bio->mem_buf->length = bio->num; - } - } - bio->wrSz -= sz; + memSz = bio->mem_buf->length - bio->rdIdx; + if (memSz < sz) { + WOLFSSL_MSG("Not enough memory for reading"); + return WOLFSSL_BIO_ERROR; } - else { - WOLFSSL_MSG("Issue with getting bio mem pointer"); - return 0; + + XMEMCPY(buf, bio->mem_buf->data + bio->rdIdx, sz); + bio->rdIdx += sz; + + if (bio->rdIdx >= bio->wrSz) { + /* All data read resize down to WOLFSSL_BIO_RESIZE_THRESHOLD */ + if (bio->mem_buf->max > WOLFSSL_BIO_RESIZE_THRESHOLD && + wolfSSL_BUF_MEM_resize(bio->mem_buf, + WOLFSSL_BIO_RESIZE_THRESHOLD) == 0) { + WOLFSSL_MSG("wolfSSL_BUF_MEM_resize error"); + return WOLFSSL_BIO_ERROR; + } + bio->wrSz = 0; + bio->rdIdx = 0; + bio->mem_buf->length = 0; + bio->ptr = bio->mem_buf->data; + } + else if (bio->rdIdx >= WOLFSSL_BIO_RESIZE_THRESHOLD) { + /* Resize the memory so we are not taking up more than necessary. + * memmove reverts internally to memcpy if areas don't overlap */ + XMEMMOVE(bio->mem_buf->data, bio->mem_buf->data + bio->rdIdx, + bio->wrSz - bio->rdIdx); + bio->wrSz -= bio->rdIdx; + bio->rdIdx = 0; + /* Resize down to WOLFSSL_BIO_RESIZE_THRESHOLD for fewer + * allocations. */ + if (wolfSSL_BUF_MEM_resize(bio->mem_buf, + bio->wrSz > WOLFSSL_BIO_RESIZE_THRESHOLD ? bio->wrSz : + WOLFSSL_BIO_RESIZE_THRESHOLD) == 0) { + WOLFSSL_MSG("wolfSSL_BUF_MEM_resize error"); + return WOLFSSL_BIO_ERROR; + } + bio->mem_buf->length = bio->wrSz; + bio->ptr = bio->mem_buf->data; } } else { @@ -483,53 +510,25 @@ static int wolfSSL_BIO_BIO_write(WOLFSSL_BIO* bio, const void* data, static int wolfSSL_BIO_MEMORY_write(WOLFSSL_BIO* bio, const void* data, int len) { - int sz; - const unsigned char* buf; - WOLFSSL_ENTER("wolfSSL_BIO_MEMORY_write"); - if (bio == NULL || data == NULL) { - return BAD_FUNC_ARG; + if (bio == NULL || bio->mem_buf == NULL || data == NULL) { + WOLFSSL_MSG("one of input parameters is null"); + return WOLFSSL_FAILURE; } - sz = wolfSSL_BIO_pending(bio); - if (sz < 0) { - WOLFSSL_MSG("Error getting memory data"); - return sz; + if (len == 0) + return WOLFSSL_SUCCESS; /* Return early to make logic simpler */ + + if (wolfSSL_BUF_MEM_grow_ex(bio->mem_buf, bio->wrSz + len, 0) + == 0) { + WOLFSSL_MSG("Error growing memory area"); + return WOLFSSL_FAILURE; } - if (bio->ptr == NULL) { - bio->ptr = (byte*)XMALLOC(len, bio->heap, DYNAMIC_TYPE_OPENSSL); - if (bio->ptr == NULL) { - WOLFSSL_MSG("Error on malloc"); - return WOLFSSL_FAILURE; - } - bio->num = len; - if (bio->mem_buf != NULL) { - bio->mem_buf->data = (char*)bio->ptr; - bio->mem_buf->length = bio->num; - } - } - - /* check if will fit in current buffer size */ - if (wolfSSL_BIO_get_mem_data(bio, (void*)&buf) < 0) { - return WOLFSSL_BIO_ERROR; - } - if (bio->num < sz + len) { - bio->ptr = (byte*)XREALLOC(bio->ptr, sz + len, bio->heap, - DYNAMIC_TYPE_OPENSSL); - if (bio->ptr == NULL) { - WOLFSSL_MSG("Error on realloc"); - return WOLFSSL_FAILURE; - } - bio->num = sz + len; - if (bio->mem_buf != NULL) { - bio->mem_buf->data = (char*)bio->ptr; - bio->mem_buf->length = bio->num; - } - } - - XMEMCPY((byte*)bio->ptr + sz, data, len); + XMEMCPY(bio->mem_buf->data + bio->wrSz, data, len); + bio->ptr = bio->mem_buf->data; + bio->num = bio->mem_buf->max; bio->wrSz += len; return len; @@ -1090,7 +1089,7 @@ size_t wolfSSL_BIO_ctrl_pending(WOLFSSL_BIO *bio) #endif if (bio->type == WOLFSSL_BIO_MEMORY) { - return bio->wrSz; + return bio->wrSz - bio->rdIdx; } /* type BIO_BIO then check paired buffer */ @@ -1157,7 +1156,7 @@ int wolfSSL_BIO_set_write_buf_size(WOLFSSL_BIO *bio, long size) { WOLFSSL_ENTER("wolfSSL_BIO_set_write_buf_size"); - if (bio == NULL || bio->type != WOLFSSL_BIO_BIO || size < 0) { + if (bio == NULL || bio->type != WOLFSSL_BIO_BIO || (int)size < 0) { return WOLFSSL_FAILURE; } @@ -1167,27 +1166,32 @@ int wolfSSL_BIO_set_write_buf_size(WOLFSSL_BIO *bio, long size) return WOLFSSL_FAILURE; } - bio->wrSz = (int)size; - if (bio->wrSz < 0) { - WOLFSSL_MSG("Unexpected negative size value"); - return WOLFSSL_FAILURE; - } - if (bio->ptr != NULL) { XFREE(bio->ptr, bio->heap, DYNAMIC_TYPE_OPENSSL); } - bio->ptr = (byte*)XMALLOC(bio->wrSz, bio->heap, DYNAMIC_TYPE_OPENSSL); + bio->ptr = (byte*)XMALLOC(size, bio->heap, DYNAMIC_TYPE_OPENSSL); if (bio->ptr == NULL) { WOLFSSL_MSG("Memory allocation error"); + bio->wrSz = 0; + bio->num = 0; + bio->wrIdx = 0; + bio->rdIdx = 0; + if (bio->mem_buf != NULL) { + bio->mem_buf->data = NULL; + bio->mem_buf->length = 0; + bio->mem_buf->max = 0; + } return WOLFSSL_FAILURE; } - bio->num = bio->wrSz; + bio->wrSz = (int)size; + bio->num = (int)size; bio->wrIdx = 0; bio->rdIdx = 0; if (bio->mem_buf != NULL) { bio->mem_buf->data = (char*)bio->ptr; bio->mem_buf->length = bio->num; + bio->mem_buf->max = bio->num; } return WOLFSSL_SUCCESS; @@ -1428,8 +1432,9 @@ int wolfSSL_BIO_reset(WOLFSSL_BIO *bio) bio->ptr = NULL; bio->num = 0; if (bio->mem_buf != NULL) { - bio->mem_buf->data = (char*)bio->ptr; - bio->mem_buf->length = bio->num; + bio->mem_buf->data = NULL; + bio->mem_buf->length = 0; + bio->mem_buf->max = 0; } return 0; @@ -1590,11 +1595,12 @@ long wolfSSL_BIO_set_mem_eof_return(WOLFSSL_BIO *bio, int v) { WOLFSSL_ENTER("wolfSSL_BIO_set_mem_eof_return"); - if (bio != NULL) { + if (bio != NULL && bio->type == WOLFSSL_BIO_MEMORY) { bio->eof = v; + return WOLFSSL_SUCCESS; } - - return WOLFSSL_SUCCESS; + else + return WOLFSSL_FAILURE; } int wolfSSL_BIO_get_len(WOLFSSL_BIO *bio) @@ -1889,10 +1895,10 @@ int wolfSSL_BIO_get_mem_data(WOLFSSL_BIO* bio, void* p) } if (p) { - *(byte**)p = (byte*)mem_bio->ptr; + *(byte**)p = (byte*)mem_bio->ptr + mem_bio->rdIdx; } - return mem_bio->num; + return mem_bio->wrSz - mem_bio->rdIdx; } int wolfSSL_BIO_pending(WOLFSSL_BIO* bio) @@ -2476,14 +2482,12 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) bio->eof = WOLFSSL_BIO_ERROR; /* Return value for empty buffer */ if (method->type == WOLFSSL_BIO_MEMORY || method->type == WOLFSSL_BIO_BIO) { - bio->mem_buf =(WOLFSSL_BUF_MEM*)XMALLOC(sizeof(WOLFSSL_BUF_MEM), - 0, DYNAMIC_TYPE_OPENSSL); + bio->mem_buf = wolfSSL_BUF_MEM_new(); if (bio->mem_buf == NULL) { WOLFSSL_MSG("Memory error"); wolfSSL_BIO_free(bio); return NULL; } - bio->mem_buf->data = (char*)bio->ptr; } if (method->type == WOLFSSL_BIO_MD) { @@ -2532,17 +2536,15 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) /* The length of the string including terminating null. */ len = (int)XSTRLEN((const char*)buf) + 1; } - bio->num = bio->wrSz = len; - bio->ptr = (byte*)XMALLOC(len, 0, DYNAMIC_TYPE_OPENSSL); - if (bio->ptr == NULL) { + + if (wolfSSL_BUF_MEM_resize(bio->mem_buf, len) == 0) { wolfSSL_BIO_free(bio); return NULL; } - if (bio->mem_buf != NULL) { - bio->mem_buf->data = (char*)bio->ptr; - bio->mem_buf->length = bio->num; - } + bio->num = bio->mem_buf->max; + bio->wrSz = len; + bio->ptr = bio->mem_buf->data; XMEMCPY(bio->ptr, buf, len); return bio; diff --git a/src/ssl.c b/src/ssl.c index 31b5bbb8d..bf25a3f1a 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -58506,12 +58506,14 @@ WOLFSSL_BUF_MEM* wolfSSL_BUF_MEM_new(void) return buf; } - -/* returns length of buffer on success */ -int wolfSSL_BUF_MEM_grow(WOLFSSL_BUF_MEM* buf, size_t len) +/* non-compat API returns length of buffer on success */ +int wolfSSL_BUF_MEM_grow_ex(WOLFSSL_BUF_MEM* buf, size_t len, + char zeroFill) { + int len_int = (int)len; int mx; + char* tmp; /* verify provided arguments */ if (buf == NULL || len_int < 0) { @@ -58526,7 +58528,7 @@ int wolfSSL_BUF_MEM_grow(WOLFSSL_BUF_MEM* buf, size_t len) /* check to see if fits in max buffer */ if (buf->max >= len) { - if (buf->data != NULL) { + if (buf->data != NULL && zeroFill) { XMEMSET(&buf->data[buf->length], 0, len - buf->length); } buf->length = len; @@ -58537,23 +58539,64 @@ int wolfSSL_BUF_MEM_grow(WOLFSSL_BUF_MEM* buf, size_t len) mx = (len_int + 3) / 3 * 4; /* use realloc */ - buf->data = (char*)XREALLOC(buf->data, mx, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (buf->data == NULL) { + tmp = (char*)XREALLOC(buf->data, mx, NULL, DYNAMIC_TYPE_OPENSSL); + if (tmp == NULL) { return 0; /* ERR_R_MALLOC_FAILURE; */ } + buf->data = tmp; buf->max = mx; - XMEMSET(&buf->data[buf->length], 0, len - buf->length); + if (zeroFill) + XMEMSET(&buf->data[buf->length], 0, len - buf->length); buf->length = len; return len_int; + +} + +/* returns length of buffer on success */ +int wolfSSL_BUF_MEM_grow(WOLFSSL_BUF_MEM* buf, size_t len) +{ + return wolfSSL_BUF_MEM_grow_ex(buf, len, 1); +} + +/* non-compat API returns length of buffer on success */ +int wolfSSL_BUF_MEM_resize(WOLFSSL_BUF_MEM* buf, size_t len) +{ + char* tmp; + int mx; + + /* verify provided arguments */ + if (buf == NULL || len == 0) { + return 0; /* BAD_FUNC_ARG; */ + } + + if (len == buf->length) + return (int)len; + + if (len > buf->length) + return wolfSSL_BUF_MEM_grow_ex(buf, len, 0); + + /* expand size, to handle growth */ + mx = (len + 3) / 3 * 4; + + /* We want to shrink the internal buffer */ + tmp = (char*)XREALLOC(buf->data, mx, NULL, DYNAMIC_TYPE_OPENSSL); + if (tmp == NULL) + return 0; + + buf->data = tmp; + buf->length = len; + buf->max = mx; + + return (int)len; } void wolfSSL_BUF_MEM_free(WOLFSSL_BUF_MEM* buf) { if (buf) { if (buf->data) { - XFREE(buf->data, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(buf->data, NULL, DYNAMIC_TYPE_OPENSSL); buf->data = NULL; } buf->max = 0; diff --git a/tests/api.c b/tests/api.c index bdba2a20f..f3ec3ff07 100644 --- a/tests/api.c +++ b/tests/api.c @@ -35341,8 +35341,11 @@ static void test_wolfSSL_PEM_read_bio(void) AssertNull(x509 = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL)); AssertNotNull(bio = BIO_new_mem_buf((void*)buff, bytes)); + AssertIntEQ(BIO_set_mem_eof_return(bio, -0xDEAD), 1); AssertNotNull(x509 = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL)); AssertIntEQ((int)BIO_set_fd(bio, 0, BIO_CLOSE), 1); + /* BIO should return the set EOF value */ + AssertIntEQ(BIO_read(bio, buff, sizeof(buff)), -0xDEAD); AssertIntEQ(BIO_set_close(bio, BIO_NOCLOSE), 1); AssertIntEQ(BIO_set_close(NULL, BIO_NOCLOSE), 1); AssertIntEQ(SSL_SUCCESS, BIO_get_mem_ptr(bio, &buf)); @@ -35542,6 +35545,7 @@ static void test_wolfSSL_BIO(void) AssertNotNull(f_bio1 = BIO_new(BIO_s_file())); AssertNotNull(f_bio2 = BIO_new(BIO_s_file())); + /* Failure due to wrong BIO type */ AssertIntEQ((int)BIO_set_mem_eof_return(f_bio1, -1), 0); AssertIntEQ((int)BIO_set_mem_eof_return(NULL, -1), 0); diff --git a/wolfssl/openssl/buffer.h b/wolfssl/openssl/buffer.h index 9ffd99e3f..864b5de34 100644 --- a/wolfssl/openssl/buffer.h +++ b/wolfssl/openssl/buffer.h @@ -33,6 +33,9 @@ WOLFSSL_API WOLFSSL_BUF_MEM* wolfSSL_BUF_MEM_new(void); WOLFSSL_API int wolfSSL_BUF_MEM_grow(WOLFSSL_BUF_MEM* buf, size_t len); +WOLFSSL_API int wolfSSL_BUF_MEM_grow_ex(WOLFSSL_BUF_MEM* buf, size_t len, + char zeroFill); +WOLFSSL_API int wolfSSL_BUF_MEM_resize(WOLFSSL_BUF_MEM* buf, size_t len); WOLFSSL_API void wolfSSL_BUF_MEM_free(WOLFSSL_BUF_MEM* buf); WOLFSSL_API size_t wolfSSL_strlcpy(char *dst, const char *src, size_t dstSize); WOLFSSL_API size_t wolfSSL_strlcat(char *dst, const char *src, size_t dstSize); From 88d5059c366b6dcaaa0eea7345b4e7a09882e01f Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 17 Mar 2022 11:56:35 +0100 Subject: [PATCH 3/6] Jenkins fixes `WS_RETURN_CODE` was not functioning properly in master --- src/bio.c | 6 +++--- src/ssl.c | 14 +++++++++----- tests/api.c | 28 ++++++++++++++++++++++++---- 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/bio.c b/src/bio.c index 791034980..921f3d496 100644 --- a/src/bio.c +++ b/src/bio.c @@ -118,7 +118,7 @@ static int wolfSSL_BIO_MEMORY_read(WOLFSSL_BIO* bio, void* buf, int len) sz = len; } - memSz = bio->mem_buf->length - bio->rdIdx; + memSz = (int)bio->mem_buf->length - bio->rdIdx; if (memSz < sz) { WOLFSSL_MSG("Not enough memory for reading"); return WOLFSSL_BIO_ERROR; @@ -528,7 +528,7 @@ static int wolfSSL_BIO_MEMORY_write(WOLFSSL_BIO* bio, const void* data, XMEMCPY(bio->mem_buf->data + bio->wrSz, data, len); bio->ptr = bio->mem_buf->data; - bio->num = bio->mem_buf->max; + bio->num = (int)bio->mem_buf->max; bio->wrSz += len; return len; @@ -2542,7 +2542,7 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) return NULL; } - bio->num = bio->mem_buf->max; + bio->num = (int)bio->mem_buf->max; bio->wrSz = len; bio->ptr = bio->mem_buf->data; XMEMCPY(bio->ptr, buf, len); diff --git a/src/ssl.c b/src/ssl.c index bf25a3f1a..1dea38ac8 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -27071,11 +27071,11 @@ int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP* lookup, const char* footer = NULL; if (type != X509_FILETYPE_PEM) - return WS_RETURN_CODE(BAD_FUNC_ARG,WOLFSSL_FAILURE); + return WS_RETURN_CODE(BAD_FUNC_ARG, (int)WOLFSSL_FAILURE); fp = XFOPEN(file, "rb"); if (fp == XBADFILE) - return WS_RETURN_CODE(BAD_FUNC_ARG,WOLFSSL_FAILURE); + return WS_RETURN_CODE(BAD_FUNC_ARG, (int)WOLFSSL_FAILURE); if(XFSEEK(fp, 0, XSEEK_END) != 0) { XFCLOSE(fp); @@ -27149,7 +27149,7 @@ end: if (pem != NULL) XFREE(pem, 0, DYNAMIC_TYPE_PEM); XFCLOSE(fp); - return WS_RETURN_CODE(ret,WOLFSSL_FAILURE); + return WS_RETURN_CODE(ret, (int)WOLFSSL_FAILURE); #else (void)lookup; (void)file; @@ -44310,6 +44310,9 @@ void* wolfSSL_GetHKDFExtractCtx(WOLFSSL* ssl) XMEMCPY(cert->challengePw, x509->challengePw, CTC_NAME_SIZE); #endif + /* Only makes sense to do this for OPENSSL_EXTRA because without + * this define the function will error out below */ + #ifdef OPENSSL_EXTRA if (x509->serialSz == 0 && x509->serialNumber != NULL && /* Check if the buffer contains more than just the * ASN tag and length */ @@ -44320,6 +44323,7 @@ void* wolfSSL_GetHKDFExtractCtx(WOLFSSL* ssl) return WOLFSSL_FAILURE; } } + #endif /* set serial number */ if (x509->serialSz > 0) { @@ -58567,7 +58571,7 @@ int wolfSSL_BUF_MEM_resize(WOLFSSL_BUF_MEM* buf, size_t len) int mx; /* verify provided arguments */ - if (buf == NULL || len == 0) { + if (buf == NULL || len == 0 || (int)len <= 0) { return 0; /* BAD_FUNC_ARG; */ } @@ -58578,7 +58582,7 @@ int wolfSSL_BUF_MEM_resize(WOLFSSL_BUF_MEM* buf, size_t len) return wolfSSL_BUF_MEM_grow_ex(buf, len, 0); /* expand size, to handle growth */ - mx = (len + 3) / 3 * 4; + mx = ((int)len + 3) / 3 * 4; /* We want to shrink the internal buffer */ tmp = (char*)XREALLOC(buf->data, mx, NULL, DYNAMIC_TYPE_OPENSSL); diff --git a/tests/api.c b/tests/api.c index f3ec3ff07..38e751562 100644 --- a/tests/api.c +++ b/tests/api.c @@ -46848,7 +46848,12 @@ static void test_EVP_PKEY_cmp(void) AssertIntEQ(EVP_PKEY_cmp(NULL, NULL), 0); AssertIntEQ(EVP_PKEY_cmp(a, NULL), 0); AssertIntEQ(EVP_PKEY_cmp(NULL, b), 0); +#ifdef NO_RSA + /* Type check will fail since RSA is the default EVP key type */ + AssertIntEQ(EVP_PKEY_cmp(a, b), -2); +#else AssertIntEQ(EVP_PKEY_cmp(a, b), 0); +#endif #else AssertIntNE(EVP_PKEY_cmp(NULL, NULL), 0); AssertIntNE(EVP_PKEY_cmp(a, NULL), 0); @@ -51246,7 +51251,8 @@ static int test_wolfSSL_CTX_set_ecdh_auto(void) return ret; } -#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_ERROR_CODE_OPENSSL) +#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_ERROR_CODE_OPENSSL) && \ + defined(HAVE_IO_TESTS_DEPENDENCIES) && !defined(WOLFSSL_NO_TLS12) static THREAD_RETURN WOLFSSL_THREAD SSL_read_test_server_thread(void* args) { callback_functions* callbacks = NULL; @@ -51290,6 +51296,13 @@ static THREAD_RETURN WOLFSSL_THREAD SSL_read_test_server_thread(void* args) wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, WOLFSSL_FILETYPE_PEM)); +#if !defined(NO_FILESYSTEM) && !defined(NO_DH) + AssertIntEQ(wolfSSL_CTX_SetTmpDH_file(ctx, dhParamFile, + WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS); +#elif !defined(NO_DH) + SetDHCtx(ctx); /* will repick suites with DHE, higher priority than PSK */ +#endif + if (callbacks->ctx_ready) callbacks->ctx_ready(ctx); @@ -51367,7 +51380,9 @@ static THREAD_RETURN WOLFSSL_THREAD SSL_read_test_server_thread(void* args) wolfSSL_free(ssl); wolfSSL_CTX_free(ctx); CloseSocket(cfd); - +#if defined(HAVE_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS) + wc_ecc_fp_free(); /* free per thread cache */ +#endif return 0; } static THREAD_RETURN WOLFSSL_THREAD SSL_read_test_client_thread(void* args) @@ -51435,9 +51450,13 @@ static THREAD_RETURN WOLFSSL_THREAD SSL_read_test_client_thread(void* args) wolfSSL_free(ssl); wolfSSL_CTX_free(ctx); CloseSocket(sfd); +#if defined(HAVE_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS) + wc_ecc_fp_free(); /* free per thread cache */ +#endif return 0; } -#endif /* OPENSSL_EXTRA && WOLFSSL_ERROR_CODE_OPENSSL */ +#endif /* OPENSSL_EXTRA && WOLFSSL_ERROR_CODE_OPENSSL && + HAVE_IO_TESTS_DEPENDENCIES && !WOLFSSL_NO_TLS12 */ /* This test is to check wolfSSL_read behaves as same as * openSSL when it is called after SSL_shutdown completes. @@ -51445,7 +51464,8 @@ static THREAD_RETURN WOLFSSL_THREAD SSL_read_test_client_thread(void* args) static int test_wolfSSL_read_detect_TCP_disconnect(void) { int ret = 0; -#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_ERROR_CODE_OPENSSL) +#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_ERROR_CODE_OPENSSL) && \ + defined(HAVE_IO_TESTS_DEPENDENCIES) && !defined(WOLFSSL_NO_TLS12) tcp_ready ready; func_args client_args; func_args server_args; From 850b8c5c3bbd08a6ae922b239c42d129c876daf5 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 21 Mar 2022 12:04:59 +0100 Subject: [PATCH 4/6] OpenSSL compatible API `WOLFSSL_ERROR_CODE_OPENSSL` breaks ABI compatiblity due to changing the expected return code. Let's only do this when building with the full compatibility layer. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 1b4c6e998..e02d02f4e 100644 --- a/configure.ac +++ b/configure.ac @@ -7165,7 +7165,7 @@ then fi AS_IF([test "x$ENABLED_OPENSSLALL" = "xyes"], - [AM_CFLAGS="$AM_CFLAGS -DOPENSSL_ALL -DWOLFSSL_EITHER_SIDE -DWC_RSA_NO_PADDING -DWC_RSA_PSS -DWOLFSSL_PSS_LONG_SALT -DWOLFSSL_TICKET_HAVE_ID"]) + [AM_CFLAGS="$AM_CFLAGS -DOPENSSL_ALL -DWOLFSSL_EITHER_SIDE -DWC_RSA_NO_PADDING -DWC_RSA_PSS -DWOLFSSL_PSS_LONG_SALT -DWOLFSSL_TICKET_HAVE_ID -DWOLFSSL_ERROR_CODE_OPENSSL"]) AS_IF([test "x$ENABLED_AESSIV" = "xyes"], [AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AES_SIV"]) @@ -7187,7 +7187,7 @@ then AM_CFLAGS="$AM_CFLAGS -DOPENSSL_EXTRA -DWOLFSSL_ALWAYS_VERIFY_CB" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_VERIFY_CB_ALL_CERTS -DWOLFSSL_EXTRA_ALERTS" AM_CFLAGS="$AM_CFLAGS -DHAVE_EXT_CACHE -DWOLFSSL_FORCE_CACHE_ON_TICKET" - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AKID_NAME -DHAVE_CTS -DWOLFSSL_ERROR_CODE_OPENSSL" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AKID_NAME -DHAVE_CTS" fi if test "$ENABLED_OPENSSLEXTRA" = "x509small" From 29c0c9bf48fbe841ea8a343c4f029cbd5f0f3d29 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 21 Mar 2022 12:17:48 +0100 Subject: [PATCH 5/6] Rebase fixes --- src/ssl.c | 31 +++++++------------------------ wolfcrypt/src/evp.c | 30 +++++++++++++++++++++++++----- wolfssl/openssl/ec.h | 7 ------- 3 files changed, 32 insertions(+), 36 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 1dea38ac8..1df36dcea 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -38981,7 +38981,6 @@ void wolfSSL_EC_KEY_free(WOLFSSL_EC_KEY *key) WOLFSSL_ENTER("wolfSSL_EC_KEY_free"); if (key != NULL) { - int doFree = 0; void* heap = key->heap; #ifndef SINGLE_THREADED @@ -39008,30 +39007,14 @@ void wolfSSL_EC_KEY_free(WOLFSSL_EC_KEY *key) wc_ecc_free((ecc_key*)key->internal); XFREE(key->internal, heap, DYNAMIC_TYPE_ECC); } -#endif - /* only free if all references to it are done */ - key->refCount--; - if (key->refCount == 0) { - doFree = 1; - } -#ifndef SINGLE_THREADED - wc_UnLockMutex(&key->refMutex); -#endif + wolfSSL_BN_free(key->priv_key); + wolfSSL_EC_POINT_free(key->pub_key); + wolfSSL_EC_GROUP_free(key->group); + InitwolfSSL_ECKey(key); /* set back to NULLs for safety */ - if (doFree) { - if (key->internal != NULL) { - wc_ecc_free((ecc_key*)key->internal); - XFREE(key->internal, heap, DYNAMIC_TYPE_ECC); - } - wolfSSL_BN_free(key->priv_key); - wolfSSL_EC_POINT_free(key->pub_key); - wolfSSL_EC_GROUP_free(key->group); - InitwolfSSL_ECKey(key); /* set back to NULLs for safety */ - - XFREE(key, heap, DYNAMIC_TYPE_ECC); - (void)heap; - /* key = NULL, don't try to access or double free it */ - } + XFREE(key, heap, DYNAMIC_TYPE_ECC); + (void)heap; + /* key = NULL, don't try to access or double free it */ } } diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 39d306d09..d910a2f3b 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -7061,6 +7061,7 @@ WOLFSSL_EC_KEY *wolfSSL_EVP_PKEY_get0_EC_KEY(WOLFSSL_EVP_PKEY *pkey) WOLFSSL_EC_KEY* wolfSSL_EVP_PKEY_get1_EC_KEY(WOLFSSL_EVP_PKEY* key) { + WOLFSSL_EC_KEY* local = NULL; WOLFSSL_ENTER("wolfSSL_EVP_PKEY_get1_EC_KEY"); if (key == NULL || key->type != EVP_PKEY_EC) { @@ -7074,18 +7075,30 @@ WOLFSSL_EC_KEY* wolfSSL_EVP_PKEY_get1_EC_KEY(WOLFSSL_EVP_PKEY* key) local = key->ecc; } else { - local = wolfSSL_EC_KEY_new(); + key->ecc = local = wolfSSL_EC_KEY_new(); if (local == NULL) { WOLFSSL_MSG("Error creating a new WOLFSSL_EC_KEY structure"); return NULL; } + if (wolfSSL_EC_KEY_LoadDer(local, + (const unsigned char*)key->pkey.ptr, + key->pkey_sz) != WOLFSSL_SUCCESS) { + /* now try public key */ + if (wolfSSL_EC_KEY_LoadDer_ex(local, + (const unsigned char*)key->pkey.ptr, key->pkey_sz, + WOLFSSL_EC_KEY_LOAD_PUBLIC) != WOLFSSL_SUCCESS) { - if (wolfSSL_EC_KEY_up_ref(key->ecc) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("wolfSSL_EC_KEY_up_ref error"); - return NULL; + wolfSSL_EC_KEY_free(local); + local = NULL; + } + } + } + } + else { + WOLFSSL_MSG("WOLFSSL_EVP_PKEY does not hold an EC key"); } - return key->ecc; + return local; } #endif /* HAVE_ECC */ @@ -7112,6 +7125,11 @@ int wolfSSL_EVP_PKEY_set1_DH(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_DH *key) clearEVPPkeyKeys(pkey); + if (wolfSSL_DH_up_ref(key) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Failed to increase dh key ref count"); + return WOLFSSL_FAILURE; + } + pkey->dh = key; pkey->ownDh = 1; /* pkey does not own DH but needs to call free on it */ pkey->type = EVP_PKEY_DH; @@ -7347,6 +7365,8 @@ int wolfSSL_EVP_PKEY_set1_EC_KEY(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_EC_KEY *key) { #ifdef HAVE_ECC WOLFSSL_ENTER("wolfSSL_EVP_PKEY_set1_EC_KEY"); + if (pkey == NULL || key == NULL) + return WOLFSSL_FAILURE; clearEVPPkeyKeys(pkey); if (wolfSSL_EC_KEY_up_ref(key) != WOLFSSL_SUCCESS) { WOLFSSL_MSG("wolfSSL_EC_KEY_up_ref failed"); diff --git a/wolfssl/openssl/ec.h b/wolfssl/openssl/ec.h index 6c57fc7c6..4b8aaac64 100644 --- a/wolfssl/openssl/ec.h +++ b/wolfssl/openssl/ec.h @@ -119,10 +119,6 @@ struct WOLFSSL_EC_KEY { char form; /* Either POINT_CONVERSION_UNCOMPRESSED or * POINT_CONVERSION_COMPRESSED */ word16 pkcs8HeaderSz; -#ifndef SINGLE_THREADED - wolfSSL_Mutex refMutex; /* ref count mutex */ -#endif - int refCount; /* reference count */ /* option bits */ byte inSet:1; /* internal set from external ? */ @@ -214,8 +210,6 @@ WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new_ex(void* heap, int devId); WOLFSSL_API WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new(void); WOLFSSL_API -int wolfSSL_EC_KEY_up_ref(WOLFSSL_EC_KEY* key); -WOLFSSL_API int wolfSSL_EC_KEY_set_group(WOLFSSL_EC_KEY *key, WOLFSSL_EC_GROUP *group); WOLFSSL_API int wolfSSL_EC_KEY_generate_key(WOLFSSL_EC_KEY *key); @@ -321,7 +315,6 @@ typedef WOLFSSL_EC_BUILTIN_CURVE EC_builtin_curve; #define EC_KEY_free wolfSSL_EC_KEY_free #define EC_KEY_up_ref wolfSSL_EC_KEY_up_ref #define EC_KEY_dup wolfSSL_EC_KEY_dup -#define EC_KEY_up_ref wolfSSL_EC_KEY_up_ref #define EC_KEY_get0_public_key wolfSSL_EC_KEY_get0_public_key #define EC_KEY_get0_group wolfSSL_EC_KEY_get0_group #define EC_KEY_set_private_key wolfSSL_EC_KEY_set_private_key From b509e174bbc8d50a9561e3be57ae26415906079f Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 24 Mar 2022 10:19:28 -0700 Subject: [PATCH 6/6] Whitespace fix. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index e02d02f4e..42918ab71 100644 --- a/configure.ac +++ b/configure.ac @@ -4241,7 +4241,7 @@ AC_ARG_ENABLE([alpn], [ ENABLED_ALPN=$enableval ], [ ENABLED_ALPN=no ] ) - + if test "$ENABLED_BIND" = "yes" then ENABLED_ALPN=yes