diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index ce0c7faa743..3be2bfaa0ae 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -916,6 +916,7 @@ WOLFSSL_IMX6_CAAM_BLOB WOLFSSL_IMX6_CAAM_RNG WOLFSSL_IMXRT_DCP WOLFSSL_ISOTP +WOLFSSL_KEEP_HOST_HEADER_PROBES WOLFSSL_KEIL WOLFSSL_KEIL_NET WOLFSSL_KYBER_NO_DECAPSULATE diff --git a/CMakeLists.txt b/CMakeLists.txt index bd80922b710..69375d09fba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -101,6 +101,7 @@ check_include_file("time.h" HAVE_TIME_H) check_include_file("sys/ioctl.h" HAVE_SYS_IOCTL_H) check_include_file("sys/socket.h" HAVE_SYS_SOCKET_H) check_include_file("sys/time.h" HAVE_SYS_TIME_H) +check_include_file("sys/un.h" HAVE_SYS_UN_H) check_include_file("errno.h" HAVE_ERRNO_H) check_include_file("dlfcn.h" HAVE_DLFCN_H) check_include_file("inttypes.h" HAVE_INTTYPES_H) @@ -113,13 +114,21 @@ check_include_file("sys/stat.h" HAVE_SYS_STAT_H) check_include_file("sys/types.h" HAVE_SYS_TYPES_H) check_include_file("unistd.h" HAVE_UNISTD_H) -# types.h depends on HAVE_LIMITS_H, and it is defined in options.h (rather than -# config.h) so that applications consuming wolfSSL headers see it. The in-tree -# build, however, is configured through config.h/compile definitions and does -# not include options.h, so define it here as well. +# types.h depends on HAVE_LIMITS_H, and callbacks.h sizes WOLFSSL_TIMEVAL with +# HAVE_SYS_TIME_H. Both are defined in options.h (rather than config.h) so that +# applications consuming wolfSSL headers see the same value the library was +# built with. The in-tree build, however, is configured through +# config.h/compile definitions and does not include options.h, so define them +# here as well. if(HAVE_LIMITS_H) add_definitions("-DHAVE_LIMITS_H") endif() +if(HAVE_SYS_TIME_H) + add_definitions("-DHAVE_SYS_TIME_H") +endif() +if(HAVE_SYS_UN_H) + add_definitions("-DHAVE_SYS_UN_H") +endif() include(CheckFunctionExists) diff --git a/cmake/config.in b/cmake/config.in index 6054b6dbe7b..c5a04f7c18a 100644 --- a/cmake/config.in +++ b/cmake/config.in @@ -34,9 +34,6 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STRING_H @HAVE_STRING_H@ -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_TIME_H @HAVE_SYS_TIME_H@ - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SECURITY_SECTRUSTSETTINGS_H @HAVE_SECURITY_SECTRUSTSETTINGS_H@ diff --git a/cmake/options.h.in b/cmake/options.h.in index 0c6de3c9d48..ac9bc57f4de 100644 --- a/cmake/options.h.in +++ b/cmake/options.h.in @@ -41,6 +41,12 @@ extern "C" { /* Since types.h depends on HAVE_LIMITS_H, we must define it in options.h. */ #undef HAVE_LIMITS_H #cmakedefine HAVE_LIMITS_H @HAVE_LIMITS_H@ +/* callbacks.h sizes WOLFSSL_TIMEVAL with HAVE_SYS_TIME_H, so it must be in + * options.h too. */ +#undef HAVE_SYS_TIME_H +#cmakedefine HAVE_SYS_TIME_H @HAVE_SYS_TIME_H@ +#undef HAVE_SYS_UN_H +#cmakedefine HAVE_SYS_UN_H @HAVE_SYS_UN_H@ #undef ASIO_USE_WOLFSSL #cmakedefine ASIO_USE_WOLFSSL #undef BOOST_ASIO_USE_WOLFSSL diff --git a/configure.ac b/configure.ac index 9bf3b9c245e..971249f17b1 100644 --- a/configure.ac +++ b/configure.ac @@ -224,6 +224,13 @@ fi AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stddef.h time.h sys/ioctl.h sys/socket.h sys/time.h errno.h sys/un.h ctype.h sys/random.h]) # Special case: Since types.h depends on HAVE_LIMITS_H, we must define it in options.h. AC_CHECK_HEADER([limits.h], [AM_CPPFLAGS="$AM_CPPFLAGS -DHAVE_LIMITS_H=1"], []) +# Special case: these gate the layout of public types in installed headers +# (union WOLFSSL_BIO_ADDR in wolfio.h, WOLFSSL_TIMEVAL in callbacks.h), so +# applications must see the same value the library was built with. These stay +# in AC_CHECK_HEADERS above as well: only the plural form defines them in +# confdefs.h, which the AC_CHECK_DECLS prologue below needs to see sys/time.h. +AC_CHECK_HEADER([sys/un.h], [AM_CPPFLAGS="$AM_CPPFLAGS -DHAVE_SYS_UN_H=1"], []) +AC_CHECK_HEADER([sys/time.h], [AM_CPPFLAGS="$AM_CPPFLAGS -DHAVE_SYS_TIME_H=1"], []) AC_CHECK_LIB([network],[socket]) AC_C_BIGENDIAN AC_C___ATOMIC diff --git a/src/internal.c b/src/internal.c index fb6c54b1bbf..cdfa6fb3cfc 100644 --- a/src/internal.c +++ b/src/internal.c @@ -14630,11 +14630,11 @@ int CheckHostName(DecodedCert* dCert, const char *domainName, return ret; } -int CheckIPAddr(DecodedCert* dCert, const char* ipasc) +int CheckIPAddr(DecodedCert* dCert, const char* ipasc, size_t ipascLen) { WOLFSSL_MSG("Checking IPAddr"); - return CheckHostName(dCert, ipasc, (size_t)XSTRLEN(ipasc), 0, 1); + return CheckHostName(dCert, ipasc, ipascLen, 0, 1); } @@ -16057,6 +16057,9 @@ int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int cert_err, #if defined(OPENSSL_EXTRA) /* Perform domain and IP check only for the leaf certificate */ if (args->certIdx == 0) { + size_t ipascLen = ((ssl != NULL) && (ssl->param != NULL)) ? + XSTRLEN(ssl->param->ipasc) : 0; + /* perform domain name check on the peer certificate */ if (args->dCertInit && args->dCert && (ssl != NULL) && ssl->param && ssl->param->hostName[0]) { @@ -16097,8 +16100,8 @@ int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int cert_err, /* perform IP address check on the peer certificate */ if ((args->dCertInit != 0) && (args->dCert != NULL) && (ssl != NULL) && - (ssl->param != NULL) && (XSTRLEN(ssl->param->ipasc) > 0)) { - if (CheckIPAddr(args->dCert, ssl->param->ipasc) != 0) { + (ssl->param != NULL) && (ipascLen > 0)) { + if (CheckIPAddr(args->dCert, ssl->param->ipasc, ipascLen) != 0) { if (cert_err == 0) { ret = IPADDR_MISMATCH; WOLFSSL_ERROR_VERBOSE(ret); @@ -18920,7 +18923,8 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, #ifndef OPENSSL_EXTRA if (!ssl->options.verifyNone && ssl->buffers.ipasc.buffer) { if (CheckIPAddr(args->dCert, - (const char*)ssl->buffers.ipasc.buffer) != 0) { + (const char*)ssl->buffers.ipasc.buffer, + (size_t)ssl->buffers.ipasc.length) != 0) { WOLFSSL_MSG("IPAddr match on alt names failed"); ret = IPADDR_MISMATCH; WOLFSSL_ERROR_VERBOSE(ret); diff --git a/src/x509.c b/src/x509.c index e177f78dbfb..d9e948fe943 100644 --- a/src/x509.c +++ b/src/x509.c @@ -15943,10 +15943,7 @@ int wolfSSL_X509_check_host(WOLFSSL_X509 *x, const char *chk, size_t chklen, } #ifdef WOLFSSL_IP_ALT_NAME - /* chk is length delimited and may not be NUL terminated, so check it - * against the iPAddress entries directly rather than through the - * NUL terminated CheckIPAddr helper. */ - ret = CheckHostName(dCert, (char *)chk, chklen, 0, 1); + ret = CheckIPAddr(dCert, (char *)chk, chklen); if (ret == 0) { goto out; } @@ -16001,7 +15998,7 @@ int wolfSSL_X509_check_ip_asc(WOLFSSL_X509 *x, const char *ipasc, ret = WOLFSSL_FAILURE; } else { - ret = CheckIPAddr(dCert, ipasc); + ret = CheckIPAddr(dCert, ipasc, (size_t)XSTRLEN(ipasc)); if (ret != 0) { ret = WOLFSSL_FAILURE; } diff --git a/tests/api/test_ossl_x509.c b/tests/api/test_ossl_x509.c index b262b721422..dabbe81a29c 100644 --- a/tests/api/test_ossl_x509.c +++ b/tests/api/test_ossl_x509.c @@ -422,6 +422,20 @@ int test_wolfSSL_X509_check_host(void) ExpectIntEQ(wolfSSL_X509_check_host(x509, altName, XSTRLEN(altName), WOLFSSL_MULTI_LABEL_WILDCARDS, NULL), WC_NO_ERR_TRACE(WOLFSSL_FAILURE)); + /* chk of exactly chklen bytes with no terminator - every consumer must + * stay within the caller's declared length. */ + { + char* bounded = (char*)XMALLOC(XSTRLEN(altName), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + ExpectNotNull(bounded); + if (bounded != NULL) { + XMEMCPY(bounded, altName, XSTRLEN(altName)); + ExpectIntEQ(X509_check_host(x509, bounded, XSTRLEN(altName), 0, + NULL), WOLFSSL_SUCCESS); + XFREE(bounded, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + } + X509_free(x509); ExpectIntEQ(X509_check_host(NULL, altName, XSTRLEN(altName), 0, NULL), diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index c5ed6f6fd2c..48f66734cbd 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -9631,6 +9631,11 @@ static int ecc_verify_hash(mp_int *r, mp_int *s, const byte* hash, u1 = u1tmp; u2 = u2tmp; #endif + /* zeroed so the cleanup below no-ops if the init is skipped */ + if (u1 != NULL) + XMEMSET(u1, 0, sizeof(mp_int)); + if (u2 != NULL) + XMEMSET(u2, 0, sizeof(mp_int)); #else u1 = e; u2 = w; @@ -14090,18 +14095,23 @@ static int accel_fp_mul2add(int idx1, int idx2, int first; #ifdef WOLFSSL_SMALL_STACK + /* each is zeroed on acquisition so the cleanup below no-ops if a later + * allocation fails and the init is skipped */ tka = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); if (tka == NULL) { err = MEMORY_E; goto done; } + XMEMSET(tka, 0, sizeof(mp_int)); tkb = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); if (tkb == NULL) { err = MEMORY_E; goto done; } + XMEMSET(tkb, 0, sizeof(mp_int)); order = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); if (order == NULL) { err = MEMORY_E; goto done; } + XMEMSET(order, 0, sizeof(mp_int)); #endif if (mp_init_multi(tka, tkb, order, NULL, NULL, NULL) != MP_OKAY) { diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index f5399560322..801fa037fb0 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -5461,6 +5461,7 @@ int wc_CheckProbablePrime_ex(const byte* pRaw, word32 pRawSz, } else ret = 0; + if (ret == 0) #endif ret = mp_init_multi(p, q, e, NULL, NULL, NULL); diff --git a/wolfcrypt/src/sakke.c b/wolfcrypt/src/sakke.c index 28a2e01bf08..f98f376f690 100644 --- a/wolfcrypt/src/sakke.c +++ b/wolfcrypt/src/sakke.c @@ -2089,6 +2089,16 @@ static int sakke_accumulate_line_add_one(mp_proj* v, mp_int* prime, mp_digit mp, t3 = (mp_int *)XMALLOC(sizeof(*t3), NULL, DYNAMIC_TYPE_TMP_BUFFER); if (t3 == NULL) err = 1; + + /* zeroed so the cleanup below no-ops if the init is skipped */ + if (h != NULL) + XMEMSET(h, 0, sizeof(*h)); + if (ty != NULL) + XMEMSET(ty, 0, sizeof(*ty)); + if (tz != NULL) + XMEMSET(tz, 0, sizeof(*tz)); + if (t3 != NULL) + XMEMSET(t3, 0, sizeof(*t3)); #else mp_int tmp[4]; mp_int* h = &tmp[0]; diff --git a/wolfcrypt/src/srp.c b/wolfcrypt/src/srp.c index 3409dbec434..44c48d45ef0 100644 --- a/wolfcrypt/src/srp.c +++ b/wolfcrypt/src/srp.c @@ -617,6 +617,11 @@ int wc_SrpGetPublic(Srp* srp, byte* pub, word32* size) if (((i = (mp_int *)XMALLOC(sizeof(*i), srp->heap, DYNAMIC_TYPE_TMP_BUFFER)) == NULL) || ((j = (mp_int *)XMALLOC(sizeof(*j), srp->heap, DYNAMIC_TYPE_TMP_BUFFER)) == NULL)) r = MEMORY_E; + /* zeroed so the cleanup below no-ops if the init is skipped */ + if (i != NULL) + XMEMSET(i, 0, sizeof(*i)); + if (j != NULL) + XMEMSET(j, 0, sizeof(*j)); if (!r) #endif { @@ -762,6 +767,16 @@ int wc_SrpComputeKey(Srp* srp, byte* clientPubKey, word32 clientPubKeySz, temp1 = (mp_int *)XMALLOC(sizeof *temp1, srp->heap, DYNAMIC_TYPE_SRP); temp2 = (mp_int *)XMALLOC(sizeof *temp2, srp->heap, DYNAMIC_TYPE_SRP); + /* zeroed so the cleanup below no-ops if the init is skipped */ + if (u != NULL) + XMEMSET(u, 0, sizeof *u); + if (s != NULL) + XMEMSET(s, 0, sizeof *s); + if (temp1 != NULL) + XMEMSET(temp1, 0, sizeof *temp1); + if (temp2 != NULL) + XMEMSET(temp2, 0, sizeof *temp2); + if ((hash == NULL) || (digest == NULL) || (u == NULL) || diff --git a/wolfssl/internal.h b/wolfssl/internal.h index dd20de7d6cb..7bfd1eb1d15 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2335,7 +2335,8 @@ WOLFSSL_TEST_VIS int MatchDomainName(const char* pattern, int len, WOLFSSL_LOCAL int CheckForAltNames(DecodedCert* dCert, const char* domain, word32 domainLen, int* checkCN, unsigned int flags, byte isIP); -WOLFSSL_LOCAL int CheckIPAddr(DecodedCert* dCert, const char* ipasc); +WOLFSSL_LOCAL int CheckIPAddr(DecodedCert* dCert, const char* ipasc, + size_t ipascLen); WOLFSSL_LOCAL void CopyDecodedName(WOLFSSL_X509_NAME* name, DecodedCert* dCert, int nameType); #endif WOLFSSL_LOCAL int SetupTicket(WOLFSSL* ssl); diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 461a2f3e839..bdd5018a418 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -407,6 +407,20 @@ #define WOLF_CRYPT_FIPS_H #endif +/* A configure-generated options.h is sometimes copied in as user_settings.h to + * seed a Windows build, carrying the POSIX host's header probes with it. Drop + * the ones naming a header the target lacks: MinGW ships (so only + * MSVC drops it) but not (so all of Windows does). + * WOLFSSL_KEEP_HOST_HEADER_PROBES skips this. */ +#ifndef WOLFSSL_KEEP_HOST_HEADER_PROBES + #ifdef _MSC_VER + #undef HAVE_SYS_TIME_H + #endif + #ifdef _WIN32 + #undef HAVE_SYS_UN_H + #endif +#endif + /* Microsoft's ARM64 compiler defines _M_ARM64 but not __aarch64__. The wolfSSL * ARMv8 assembly (WOLFSSL_ARMASM) and all of its C callers are gated on * __aarch64__, so map _M_ARM64 across when building that assembly with MSVC and