From dcdfac72ff44d669875597fd623a955ed4df1700 Mon Sep 17 00:00:00 2001 From: Jeremiah Mackey Date: Mon, 23 Mar 2026 15:43:48 +0000 Subject: [PATCH 01/11] Bounds-check PSK identity strcpy --- native/com_wolfssl_WolfSSLContext.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/native/com_wolfssl_WolfSSLContext.c b/native/com_wolfssl_WolfSSLContext.c index 3795fada..84d4fd4c 100644 --- a/native/com_wolfssl_WolfSSLContext.c +++ b/native/com_wolfssl_WolfSSLContext.c @@ -6238,7 +6238,21 @@ unsigned int NativePskClientCb(WOLFSSL* ssl, const char* hint, char* identity, } return 0; } - strcpy(identity, tmpString); + if (XSTRLEN(tmpString) >= id_max_len) { + (*jenv)->ReleaseStringUTFChars(jenv, bufString, + tmpString); + (*jenv)->DeleteLocalRef(jenv, ctxRef); + (*jenv)->DeleteLocalRef(jenv, hintString); + (*jenv)->DeleteLocalRef(jenv, strBufObj); + (*jenv)->DeleteLocalRef(jenv, keyArray); + (*jenv)->DeleteLocalRef(jenv, bufString); + if (needsDetach) { + (*g_vm)->DetachCurrentThread(g_vm); + } + return 0; + } + XMEMCPY(identity, tmpString, XSTRLEN(tmpString)); + identity[XSTRLEN(tmpString)] = '\0'; (*jenv)->ReleaseStringUTFChars(jenv, bufString, tmpString); (*jenv)->DeleteLocalRef(jenv, bufString); } From ab84a47597f7a7b789315974065eaa894eec165e Mon Sep 17 00:00:00 2001 From: Jeremiah Mackey Date: Mon, 23 Mar 2026 15:46:26 +0000 Subject: [PATCH 02/11] Validate PSK key length bounds --- native/com_wolfssl_WolfSSLContext.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/native/com_wolfssl_WolfSSLContext.c b/native/com_wolfssl_WolfSSLContext.c index 84d4fd4c..0b18fd47 100644 --- a/native/com_wolfssl_WolfSSLContext.c +++ b/native/com_wolfssl_WolfSSLContext.c @@ -6170,7 +6170,7 @@ unsigned int NativePskClientCb(WOLFSSL* ssl, const char* hint, char* identity, } } - if (retval > 0) { + if (retval > 0 && retval <= (jlong)max_key_len) { /* copy jbyteArray into char key array */ (*jenv)->GetByteArrayRegion(jenv, keyArray, 0, retval, (jbyte*)key); @@ -6256,6 +6256,9 @@ unsigned int NativePskClientCb(WOLFSSL* ssl, const char* hint, char* identity, (*jenv)->ReleaseStringUTFChars(jenv, bufString, tmpString); (*jenv)->DeleteLocalRef(jenv, bufString); } + else { + retval = 0; + } /* delete local obj refs, detach JNIEnv from thread */ (*jenv)->DeleteLocalRef(jenv, ctxRef); @@ -6559,7 +6562,7 @@ unsigned int NativePskServerCb(WOLFSSL* ssl, const char* identity, } } - if (retval > 0) { + if (retval > 0 && retval <= (jlong)max_key_len) { /* copy jbyteArray into char key array */ (*jenv)->GetByteArrayRegion(jenv, keyArray, 0, retval, (jbyte*)key); @@ -6575,6 +6578,9 @@ unsigned int NativePskServerCb(WOLFSSL* ssl, const char* identity, return 0; } } + else { + retval = 0; + } /* delete local obj refs, detach JNIEnv from thread */ (*jenv)->DeleteLocalRef(jenv, ctxRef); From 4bda445e3d9f6a34761bfa02c304bdf6ff5f661b Mon Sep 17 00:00:00 2001 From: Jeremiah Mackey Date: Mon, 23 Mar 2026 15:48:07 +0000 Subject: [PATCH 03/11] Fix ALPN OOB read, parse wire format --- native/com_wolfssl_WolfSSLSession.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/native/com_wolfssl_WolfSSLSession.c b/native/com_wolfssl_WolfSSLSession.c index a30decdd..7be0da79 100644 --- a/native/com_wolfssl_WolfSSLSession.c +++ b/native/com_wolfssl_WolfSSLSession.c @@ -5850,26 +5850,27 @@ int NativeALPNSelectCb(WOLFSSL *ssl, const unsigned char **out, selectedProto, 0); selectedProtoCharArrSz = (int)XSTRLEN(selectedProtoCharArr); - /* see if selected ALPN protocol is in original sent list */ + /* see if selected ALPN protocol is in original sent list. + * Wire format is length-prefixed: (LEN|PROTO|LEN|PROTO|...) */ if (selectedProtoCharArr != NULL) { - for (idx = 0; idx < inlen; idx++) { - if (idx + selectedProtoCharArrSz > inlen) { - /* No match found, fatal error. in not long enough for - * search. Reset ret to error condition, match not set - * correctly */ + idx = 0; + while (idx < inlen) { + unsigned char protoLen = in[idx]; + if (idx + 1 + protoLen > inlen) { ret = SSL_TLSEXT_ERR_ALERT_FATAL; break; } - if (XMEMCMP(in + idx, selectedProtoCharArr, + if (protoLen == selectedProtoCharArrSz && + XMEMCMP(in + idx + 1, selectedProtoCharArr, selectedProtoCharArrSz) == 0) { - /* Match found. Format of input array is length byte of - * ALPN protocol, followed by ALPN protocol, - * ie (LEN+ALPN|LEN+ALPN|...) We set *out to ALPN selected - * protocol and *outlen to length of protocol (idx - 1) */ - *out = in + idx; - *outlen = in[idx - 1]; + *out = in + idx + 1; + *outlen = protoLen; break; } + idx += 1 + protoLen; + } + if (idx >= inlen && ret != SSL_TLSEXT_ERR_ALERT_FATAL) { + ret = SSL_TLSEXT_ERR_ALERT_FATAL; } } else { From 2e36f1f04004b7fa070f7e63ab8cd6a304e8f88f Mon Sep 17 00:00:00 2001 From: Jeremiah Mackey Date: Mon, 23 Mar 2026 15:50:24 +0000 Subject: [PATCH 04/11] Fix NULL deref in ALPN callback --- native/com_wolfssl_WolfSSLSession.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/native/com_wolfssl_WolfSSLSession.c b/native/com_wolfssl_WolfSSLSession.c index 7be0da79..4041d6fa 100644 --- a/native/com_wolfssl_WolfSSLSession.c +++ b/native/com_wolfssl_WolfSSLSession.c @@ -5848,11 +5848,10 @@ int NativeALPNSelectCb(WOLFSSL *ssl, const unsigned char **out, /* get char* from jstring */ selectedProtoCharArr = (*jenv)->GetStringUTFChars(jenv, selectedProto, 0); - selectedProtoCharArrSz = (int)XSTRLEN(selectedProtoCharArr); - /* see if selected ALPN protocol is in original sent list. * Wire format is length-prefixed: (LEN|PROTO|LEN|PROTO|...) */ if (selectedProtoCharArr != NULL) { + selectedProtoCharArrSz = (int)XSTRLEN(selectedProtoCharArr); idx = 0; while (idx < inlen) { unsigned char protoLen = in[idx]; From 8086cee82f729cff7483e59aaf81ac8a4021ddeb Mon Sep 17 00:00:00 2001 From: Jeremiah Mackey Date: Mon, 23 Mar 2026 15:56:32 +0000 Subject: [PATCH 05/11] Fix ALPN string memory leak --- native/com_wolfssl_WolfSSLSession.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/native/com_wolfssl_WolfSSLSession.c b/native/com_wolfssl_WolfSSLSession.c index 4041d6fa..7e23d293 100644 --- a/native/com_wolfssl_WolfSSLSession.c +++ b/native/com_wolfssl_WolfSSLSession.c @@ -5876,6 +5876,11 @@ int NativeALPNSelectCb(WOLFSSL *ssl, const unsigned char **out, /* Not able to get selected ALPN protocol from Java, fatal error */ ret = SSL_TLSEXT_ERR_ALERT_FATAL; } + + if (selectedProtoCharArr != NULL) { + (*jenv)->ReleaseStringUTFChars(jenv, selectedProto, + selectedProtoCharArr); + } } return ret; From 85581209b47eb544da0b522bfe14f54dfd95150f Mon Sep 17 00:00:00 2001 From: Jeremiah Mackey Date: Mon, 23 Mar 2026 16:00:34 +0000 Subject: [PATCH 06/11] Return early on JNI attach failure --- native/com_wolfssl_WolfSSLContext.c | 2 ++ native/com_wolfssl_WolfSSLSession.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/native/com_wolfssl_WolfSSLContext.c b/native/com_wolfssl_WolfSSLContext.c index 0b18fd47..13ecc9a7 100644 --- a/native/com_wolfssl_WolfSSLContext.c +++ b/native/com_wolfssl_WolfSSLContext.c @@ -1793,9 +1793,11 @@ void NativeCtxMissingCRLCallback(const char* url) #endif if (vmret) { printf("Failed to attach JNIEnv to thread\n"); + return; } } else if (vmret != JNI_OK) { printf("Unable to get JNIEnv from JavaVM\n"); + return; } /* find exception class */ diff --git a/native/com_wolfssl_WolfSSLSession.c b/native/com_wolfssl_WolfSSLSession.c index 7e23d293..ad1eb14d 100644 --- a/native/com_wolfssl_WolfSSLSession.c +++ b/native/com_wolfssl_WolfSSLSession.c @@ -3883,9 +3883,11 @@ void NativeMissingCRLCallback(const char* url) #endif if (vmret) { printf("Failed to attach JNIEnv to thread\n"); + return; } } else if (vmret != JNI_OK) { printf("Unable to get JNIEnv from JavaVM\n"); + return; } /* check if our stored object reference is valid */ From d103efcf31dbf6b1cbc48d65f7811bdcb4fc6f3c Mon Sep 17 00:00:00 2001 From: Jeremiah Mackey Date: Mon, 23 Mar 2026 16:01:12 +0000 Subject: [PATCH 07/11] Fix XMEMSET using wrong size arg --- native/com_wolfssl_WolfSSL.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/native/com_wolfssl_WolfSSL.c b/native/com_wolfssl_WolfSSL.c index 1d46dc7b..0d44a32e 100644 --- a/native/com_wolfssl_WolfSSL.c +++ b/native/com_wolfssl_WolfSSL.c @@ -1989,7 +1989,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_getPkcs8TraditionalOffset if (inBuf == NULL) { return MEMORY_E; } - XMEMSET(inBuf, 0, DYNAMIC_TYPE_TMP_BUFFER); + XMEMSET(inBuf, 0, (long)sz); (*jenv)->GetByteArrayRegion(jenv, in, 0, (jsize)sz, (jbyte*)inBuf); if ((*jenv)->ExceptionOccurred(jenv)) { From f3e8cc019b0607ae4cf1b35c3b06067eeaf5d103 Mon Sep 17 00:00:00 2001 From: Jeremiah Mackey Date: Mon, 23 Mar 2026 16:02:54 +0000 Subject: [PATCH 08/11] Zero private key before free --- native/com_wolfssl_WolfSSLSession.c | 1 + 1 file changed, 1 insertion(+) diff --git a/native/com_wolfssl_WolfSSLSession.c b/native/com_wolfssl_WolfSSLSession.c index ad1eb14d..e09bf3f6 100644 --- a/native/com_wolfssl_WolfSSLSession.c +++ b/native/com_wolfssl_WolfSSLSession.c @@ -3640,6 +3640,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_usePrivateKeyBuffer ret = wolfSSL_use_PrivateKey_buffer(ssl, buff, (long)sz, format); + XMEMSET(buff, 0, (long)sz); XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER); return ret; From b3243b734a68ec86146274757b8c1e15fa9872e5 Mon Sep 17 00:00:00 2001 From: Jeremiah Mackey Date: Tue, 24 Mar 2026 15:51:12 +0000 Subject: [PATCH 09/11] Fix CRL callback thread leak --- native/com_wolfssl_WolfSSLContext.c | 12 +++++++++++- native/com_wolfssl_WolfSSLSession.c | 10 +++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/native/com_wolfssl_WolfSSLContext.c b/native/com_wolfssl_WolfSSLContext.c index 13ecc9a7..9295d934 100644 --- a/native/com_wolfssl_WolfSSLContext.c +++ b/native/com_wolfssl_WolfSSLContext.c @@ -1777,6 +1777,7 @@ void NativeCtxMissingCRLCallback(const char* url) { JNIEnv* jenv; jint vmret = 0; + int needsDetach = 0; jclass excClass; jclass crlClass = NULL; jmethodID crlMethod; @@ -1795,6 +1796,7 @@ void NativeCtxMissingCRLCallback(const char* url) printf("Failed to attach JNIEnv to thread\n"); return; } + needsDetach = 1; } else if (vmret != JNI_OK) { printf("Unable to get JNIEnv from JavaVM\n"); return; @@ -1805,6 +1807,8 @@ void NativeCtxMissingCRLCallback(const char* url) if ((*jenv)->ExceptionOccurred(jenv)) { (*jenv)->ExceptionDescribe(jenv); (*jenv)->ExceptionClear(jenv); + if (needsDetach) + (*g_vm)->DetachCurrentThread(g_vm); return; } @@ -1817,6 +1821,8 @@ void NativeCtxMissingCRLCallback(const char* url) if (!crlClass) { (*jenv)->ThrowNew(jenv, excClass, "Can't get native WolfSSLMissingCRLCallback class reference"); + if (needsDetach) + (*g_vm)->DetachCurrentThread(g_vm); return; } @@ -1831,6 +1837,8 @@ void NativeCtxMissingCRLCallback(const char* url) (*jenv)->ThrowNew(jenv, excClass, "Error getting missingCRLCallback method from JNI"); + if (needsDetach) + (*g_vm)->DetachCurrentThread(g_vm); return; } @@ -1843,7 +1851,6 @@ void NativeCtxMissingCRLCallback(const char* url) if ((*jenv)->ExceptionOccurred(jenv)) { (*jenv)->ExceptionDescribe(jenv); (*jenv)->ExceptionClear(jenv); - return; } } else { @@ -1855,6 +1862,9 @@ void NativeCtxMissingCRLCallback(const char* url) (*jenv)->ThrowNew(jenv, excClass, "Object reference invalid in NativeMissingCRLCallback"); } + + if (needsDetach) + (*g_vm)->DetachCurrentThread(g_vm); } #endif /* HAVE_CRL */ diff --git a/native/com_wolfssl_WolfSSLSession.c b/native/com_wolfssl_WolfSSLSession.c index e09bf3f6..ad46810b 100644 --- a/native/com_wolfssl_WolfSSLSession.c +++ b/native/com_wolfssl_WolfSSLSession.c @@ -3869,6 +3869,7 @@ void NativeMissingCRLCallback(const char* url) { JNIEnv* jenv; jint vmret = 0; + int needsDetach = 0; jclass crlClass = NULL; jmethodID crlMethod = NULL; jobjectRefType refcheck; @@ -3886,6 +3887,7 @@ void NativeMissingCRLCallback(const char* url) printf("Failed to attach JNIEnv to thread\n"); return; } + needsDetach = 1; } else if (vmret != JNI_OK) { printf("Unable to get JNIEnv from JavaVM\n"); return; @@ -3900,6 +3902,8 @@ void NativeMissingCRLCallback(const char* url) if (!crlClass) { throwWolfSSLException(jenv, "Can't get native WolfSSLMissingCRLCallback class reference"); + if (needsDetach) + (*g_vm)->DetachCurrentThread(g_vm); return; } @@ -3914,6 +3918,8 @@ void NativeMissingCRLCallback(const char* url) throwWolfSSLException(jenv, "Error getting missingCRLCallback method from JNI"); + if (needsDetach) + (*g_vm)->DetachCurrentThread(g_vm); return; } @@ -3925,7 +3931,6 @@ void NativeMissingCRLCallback(const char* url) if ((*jenv)->ExceptionOccurred(jenv)) { (*jenv)->ExceptionDescribe(jenv); (*jenv)->ExceptionClear(jenv); - return; } } else { @@ -3937,6 +3942,9 @@ void NativeMissingCRLCallback(const char* url) throwWolfSSLException(jenv, "Object reference invalid in NativeMissingCRLCallback"); } + + if (needsDetach) + (*g_vm)->DetachCurrentThread(g_vm); } #endif /* HAVE_CRL */ From 14d3ceba8e4e53a755217c9e633328ed0947f589 Mon Sep 17 00:00:00 2001 From: Jeremiah Mackey Date: Tue, 24 Mar 2026 15:53:02 +0000 Subject: [PATCH 10/11] Fix setGroups JNI array leak --- native/com_wolfssl_WolfSSLContext.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/native/com_wolfssl_WolfSSLContext.c b/native/com_wolfssl_WolfSSLContext.c index 9295d934..849f50ce 100644 --- a/native/com_wolfssl_WolfSSLContext.c +++ b/native/com_wolfssl_WolfSSLContext.c @@ -6679,6 +6679,10 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLContext_setGroups if (groupsSz == 0 || groupsSz > WOLFSSL_MAX_GROUP_COUNT || jniGroups == NULL) { + if (jniGroups != NULL) { + (*jenv)->ReleaseIntArrayElements(jenv, groups, + jniGroups, JNI_ABORT); + } return (jint)BAD_FUNC_ARG; } From c4ebc616e6c3cfd15b3679258673925d5bf65cc3 Mon Sep 17 00:00:00 2001 From: Jeremiah Mackey Date: Wed, 25 Mar 2026 15:04:23 +0000 Subject: [PATCH 11/11] Exclude asn_orig.c from Android build --- IDE/Android/app/src/main/cpp/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/IDE/Android/app/src/main/cpp/CMakeLists.txt b/IDE/Android/app/src/main/cpp/CMakeLists.txt index 12c3da47..574a17a5 100644 --- a/IDE/Android/app/src/main/cpp/CMakeLists.txt +++ b/IDE/Android/app/src/main/cpp/CMakeLists.txt @@ -276,6 +276,7 @@ if ("${WOLFSSL_PKG_TYPE}" MATCHES "normal") list(REMOVE_ITEM CRYPTO_SOURCES ${wolfssl_DIR}/wolfcrypt/src/evp.c) list(REMOVE_ITEM CRYPTO_SOURCES ${wolfssl_DIR}/wolfcrypt/src/evp_pk.c) list(REMOVE_ITEM CRYPTO_SOURCES ${wolfssl_DIR}/wolfcrypt/src/misc.c) + list(REMOVE_ITEM CRYPTO_SOURCES ${wolfssl_DIR}/wolfcrypt/src/asn_orig.c) elseif("${WOLFSSL_PKG_TYPE}" MATCHES "fipsready") # FIPS Ready needs to explicitly order files for in-core integrity check to work properly.