From db10d01ac1444d6e0ffd8c43453c0d7b50cff2f1 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Tue, 28 Sep 2021 19:02:14 -0600 Subject: [PATCH 01/15] fix memory leak of internal verify callback, add support for multiple simultaneous session callbacks --- native/com_wolfssl_WolfSSLSession.c | 162 ++++++++++++++---- .../provider/jsse/WolfSSLEngineHelper.java | 94 ++-------- .../jsse/WolfSSLInternalVerifyCb.java | 103 +++++++++++ .../provider/jsse/WolfSSLSNIServerName.java | 4 + 4 files changed, 256 insertions(+), 107 deletions(-) create mode 100644 src/java/com/wolfssl/provider/jsse/WolfSSLInternalVerifyCb.java diff --git a/native/com_wolfssl_WolfSSLSession.c b/native/com_wolfssl_WolfSSLSession.c index 2efdcd96..16b930d9 100644 --- a/native/com_wolfssl_WolfSSLSession.c +++ b/native/com_wolfssl_WolfSSLSession.c @@ -34,12 +34,21 @@ /* custom I/O native fn prototypes */ int NativeSSLIORecvCb(WOLFSSL *ssl, char *buf, int sz, void *ctx); int NativeSSLIOSendCb(WOLFSSL *ssl, char *buf, int sz, void *ctx); -static jobject g_verifySSLCbIfaceObj; #ifdef HAVE_CRL /* global object refs for CRL callback */ static jobject g_crlCbIfaceObj; #endif +/* Data used per-WOLFSSL session that needs to be stored across native + * function calls. Stored inside WOLFSSL app data, set with + * wolfSSL_set_app_data(), retrieved with wolfSSL_get_app_data(). + * Global callback objects are created with NewGlobalRef(), then freed + * inside freeSSL() with DeleteGlobalRef(). */ +typedef struct SSLAppData { + wolfSSL_Mutex* jniSessLock; /* WOLFSSL session lock */ + jobject* g_verifySSLCbIfaceObj; /* Java verify callback [global ref] */ +} SSLAppData; + /* custom native fn prototypes */ void NativeMissingCRLCallback(const char* url); int NativeSSLVerifyCallback(int preverify_ok, WOLFSSL_X509_STORE_CTX* store); @@ -52,6 +61,8 @@ int NativeSSLVerifyCallback(int preverify_ok, WOLFSSL_X509_STORE_CTX* store) jclass excClass; jmethodID verifyMethod; jobjectRefType refcheck; + SSLAppData* appData; /* WOLFSSL app data, stored verify cb obj */ + jobject* g_verifySSLCbIfaceObj; /* Global jobject, stored in app data */ if (!g_vm) { /* we can't throw an exception yet, so just return 0 (failure) */ @@ -81,12 +92,28 @@ int NativeSSLVerifyCallback(int preverify_ok, WOLFSSL_X509_STORE_CTX* store) return -103; } + /* get app data to retrieve stored Java jobject callback object */ + appData = (SSLAppData*)wolfSSL_get_app_data( + wolfSSL_X509_STORE_CTX_get_ex_data(store, 0)); + if (appData == NULL) { + printf("Error getting app data from WOLFSSL\n"); + return -105; + } + + /* get global Java verify callback object */ + g_verifySSLCbIfaceObj = appData->g_verifySSLCbIfaceObj; + if (g_verifySSLCbIfaceObj == NULL || *g_verifySSLCbIfaceObj == NULL) { + printf("Error getting g_verifySSLCbIfaceObj from appData\n"); + return -106; + } + /* check if our stored object reference is valid */ - refcheck = (*jenv)->GetObjectRefType(jenv, g_verifySSLCbIfaceObj); + refcheck = (*jenv)->GetObjectRefType(jenv, *g_verifySSLCbIfaceObj); if (refcheck == 2) { /* lookup WolfSSLVerifyCallback class from global object ref */ - jclass verifyClass = (*jenv)->GetObjectClass(jenv, g_verifySSLCbIfaceObj); + jclass verifyClass = (*jenv)->GetObjectClass(jenv, + *g_verifySSLCbIfaceObj); if (!verifyClass) { if ((*jenv)->ExceptionOccurred(jenv)) { (*jenv)->ExceptionDescribe(jenv); @@ -95,7 +122,7 @@ int NativeSSLVerifyCallback(int preverify_ok, WOLFSSL_X509_STORE_CTX* store) (*jenv)->ThrowNew(jenv, excClass, "Can't get native WolfSSLVerifyCallback class reference"); - return -104; + return -107; } verifyMethod = (*jenv)->GetMethodID(jenv, verifyClass, @@ -108,17 +135,17 @@ int NativeSSLVerifyCallback(int preverify_ok, WOLFSSL_X509_STORE_CTX* store) (*jenv)->ThrowNew(jenv, excClass, "Error getting verifyCallback method from JNI"); - return -105; + return -108; } - retval = (*jenv)->CallIntMethod(jenv, g_verifySSLCbIfaceObj, + retval = (*jenv)->CallIntMethod(jenv, *g_verifySSLCbIfaceObj, verifyMethod, preverify_ok, (jlong)(uintptr_t)store); if ((*jenv)->ExceptionOccurred(jenv)) { /* exception occurred on the Java side during method call */ (*jenv)->ExceptionDescribe(jenv); (*jenv)->ExceptionClear(jenv); - return -106; + return -109; } } else { @@ -145,6 +172,7 @@ JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLSession_newSSL jlong sslPtr; jobject* g_cachedObj; wolfSSL_Mutex* jniSessLock; + SSLAppData* appData; if (!jenv) return SSL_FAILURE; @@ -175,21 +203,34 @@ JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLSession_newSSL return SSL_FAILURE; } + appData = (SSLAppData*)XMALLOC(sizeof(SSLAppData), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (appData == NULL) { + printf("error allocating memory in newSSL for SSLAppData\n"); + wolfSSL_free((WOLFSSL*)(uintptr_t)sslPtr); + return SSL_FAILURE; + } + XMEMSET(appData, 0, sizeof(SSLAppData)); + /* store mutex lock in SSL app data, used for I/O and session lock. * This is freed in freeSSL. */ jniSessLock = (wolfSSL_Mutex*)XMALLOC(sizeof(wolfSSL_Mutex), NULL, DYNAMIC_TYPE_TMP_BUFFER); if (!jniSessLock) { printf("error mallocing memory in newSSL for jniSessLock\n"); + XFREE(appData, NULL, DYNAMIC_TYPE_TMP_BUFFER); wolfSSL_free((WOLFSSL*)(uintptr_t)sslPtr); return SSL_FAILURE; } wc_InitMutex(jniSessLock); + appData->jniSessLock = jniSessLock; + if (wolfSSL_set_app_data( - (WOLFSSL*)(uintptr_t)sslPtr, jniSessLock) != SSL_SUCCESS) { + (WOLFSSL*)(uintptr_t)sslPtr, appData) != SSL_SUCCESS) { printf("error setting WOLFSSL app data in newSSL\n"); XFREE(jniSessLock, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(appData, NULL, DYNAMIC_TYPE_TMP_BUFFER); wolfSSL_free((WOLFSSL*)(uintptr_t)sslPtr); return SSL_FAILURE; } @@ -516,6 +557,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_connect int ret = 0, err = 0, sockfd = 0; WOLFSSL* ssl = NULL; wolfSSL_Mutex* jniSessLock = NULL; + SSLAppData* appData = NULL; (void)jcl; @@ -532,9 +574,14 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_connect } /* get session mutex from SSL app data */ - jniSessLock = (wolfSSL_Mutex*)wolfSSL_get_app_data(ssl); + appData = (SSLAppData*)wolfSSL_get_app_data(ssl); + if (appData == NULL) { + return WOLFSSL_FAILURE; + } + + jniSessLock = appData->jniSessLock; if (jniSessLock == NULL) { - return SSL_FAILURE; + return WOLFSSL_FAILURE; } do { @@ -592,6 +639,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_write(JNIEnv* jenv, int ret = SSL_FAILURE, err, sockfd; WOLFSSL* ssl = NULL; wolfSSL_Mutex* jniSessLock = NULL; + SSLAppData* appData = NULL; (void)jcl; @@ -609,7 +657,12 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_write(JNIEnv* jenv, } /* get session mutex from SSL app data */ - jniSessLock = (wolfSSL_Mutex*)wolfSSL_get_app_data(ssl); + appData = (SSLAppData*)wolfSSL_get_app_data(ssl); + if (appData == NULL) { + return WOLFSSL_FAILURE; + } + + jniSessLock = appData->jniSessLock; if (jniSessLock == NULL) { (*jenv)->ReleaseByteArrayElements(jenv, raw, (jbyte*)data, JNI_ABORT); @@ -671,6 +724,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read(JNIEnv* jenv, int size = 0, ret, err, sockfd; WOLFSSL* ssl = NULL; wolfSSL_Mutex* jniSessLock = NULL; + SSLAppData* appData = NULL; (void)jcl; @@ -688,7 +742,12 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read(JNIEnv* jenv, } /* get session mutex from SSL app data */ - jniSessLock = (wolfSSL_Mutex*)wolfSSL_get_app_data(ssl); + appData = (SSLAppData*)wolfSSL_get_app_data(ssl); + if (appData == NULL) { + return WOLFSSL_FAILURE; + } + + jniSessLock = appData->jniSessLock; if (jniSessLock == NULL) { (*jenv)->ReleaseByteArrayElements(jenv, raw, (jbyte*)data, JNI_ABORT); @@ -748,6 +807,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_accept int ret = 0, err, sockfd; WOLFSSL* ssl = NULL; wolfSSL_Mutex* jniSessLock = NULL; + SSLAppData* appData = NULL; (void)jcl; @@ -764,7 +824,12 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_accept } /* get session mutex from SSL app data */ - jniSessLock = (wolfSSL_Mutex*)wolfSSL_get_app_data(ssl); + appData = (SSLAppData*)wolfSSL_get_app_data(ssl); + if (appData == NULL) { + return WOLFSSL_FAILURE; + } + + jniSessLock = appData->jniSessLock; if (jniSessLock == NULL) { return SSL_FAILURE; } @@ -821,8 +886,9 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_freeSSL (JNIEnv* jenv, jobject jcl, jlong ssl) { jobject* g_cachedSSLObj; + jobject* g_cachedVerifyCb; jclass excClass; - wolfSSL_Mutex* jniSessLock; + SSLAppData* appData; (void)jcl; excClass = (*jenv)->FindClass(jenv, "com/wolfssl/WolfSSLException"); @@ -839,11 +905,22 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_freeSSL } /* free session mutex lock */ - jniSessLock = (wolfSSL_Mutex*)wolfSSL_get_app_data((WOLFSSL*)(uintptr_t)ssl); - if (jniSessLock != NULL) { - wc_FreeMutex(jniSessLock); - XFREE(jniSessLock, NULL, DYNAMIC_TYPE_TMP_BUFFER); - jniSessLock = NULL; + appData = (SSLAppData*)wolfSSL_get_app_data((WOLFSSL*)(uintptr_t)ssl); + if (appData != NULL) { + if (appData->jniSessLock != NULL) { + wc_FreeMutex(appData->jniSessLock); + XFREE(appData->jniSessLock, NULL, DYNAMIC_TYPE_TMP_BUFFER); + appData->jniSessLock = NULL; + } + g_cachedVerifyCb = appData->g_verifySSLCbIfaceObj; + if (g_cachedVerifyCb != NULL) { + (*jenv)->DeleteGlobalRef(jenv, (jobject)(*g_cachedVerifyCb)); + XFREE(g_cachedVerifyCb, NULL, DYNAMIC_TYPE_TMP_BUFFER); + g_cachedVerifyCb = NULL; + } + /* free appData */ + XFREE(appData, NULL, DYNAMIC_TYPE_TMP_BUFFER); + appData = NULL; } /* delete global WolfSSLSession object reference */ @@ -877,6 +954,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_shutdownSSL int ret = 0, err, sockfd; WOLFSSL* ssl = NULL; wolfSSL_Mutex* jniSessLock; + SSLAppData* appData = NULL; (void)jcl; if (jenv == NULL) { @@ -892,9 +970,14 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_shutdownSSL } /* get session mutex from SSL app data */ - jniSessLock = (wolfSSL_Mutex*)wolfSSL_get_app_data(ssl); + appData = (SSLAppData*)wolfSSL_get_app_data(ssl); + if (appData == NULL) { + return WOLFSSL_FAILURE; + } + + jniSessLock = appData->jniSessLock; if (jniSessLock == NULL) { - return SSL_FAILURE; + return WOLFSSL_FAILURE; } do { @@ -3273,23 +3356,44 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_setVerify (JNIEnv* jenv, jobject jcl, jlong ssl, jint mode, jobject callbackIface) { (void)jcl; + jobject* verifyCb; + SSLAppData* appData; if (!jenv || !ssl) return; if (!callbackIface) { wolfSSL_set_verify((WOLFSSL*)(uintptr_t)ssl, mode, NULL); - } else { + } + else { + /* get app data to store verify callback jobject */ + appData = (SSLAppData*)wolfSSL_get_app_data((WOLFSSL*)(uintptr_t)ssl); + if (appData == NULL) { + printf("Error getting app data from WOLFSSL\n"); + } - /* store Java verify Interface object */ - g_verifySSLCbIfaceObj = (*jenv)->NewGlobalRef(jenv, callbackIface); - if (!g_verifySSLCbIfaceObj) { - printf("error storing global callback interface\n"); + if (appData) { + verifyCb = (jobject*)XMALLOC(sizeof(jobject), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (verifyCb == NULL) { + printf("Error allocating memory for verifyCb\n"); + } } - /* set verify mode, register Java callback with wolfSSL */ - wolfSSL_set_verify((WOLFSSL*)(uintptr_t)ssl, mode, - NativeSSLVerifyCallback); + if (appData && verifyCb) { + /* store Java verify Interface object */ + *verifyCb = (*jenv)->NewGlobalRef(jenv, callbackIface); + if (*verifyCb == NULL) { + printf("error storing global callback interface\n"); + } + else { + appData->g_verifySSLCbIfaceObj = verifyCb; + + /* set verify mode, register Java callback with wolfSSL */ + wolfSSL_set_verify((WOLFSSL*)(uintptr_t)ssl, mode, + NativeSSLVerifyCallback); + } + } } } diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java b/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java index 26c7a270..d51f3dc8 100644 --- a/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java @@ -57,6 +57,18 @@ public class WolfSSLEngineHelper { private boolean sessionCreation = true; private boolean modeSet = false; + /* Internal Java verify callback, used when user/app is not using + * com.wolfssl.provider.jsse.WolfSSLTrustX509 and instead using their + * own TrustManager to perform verification via checkClientTrusted() + * and/or checkServerTrusted(). + * + * This object is stored at the native level as a global reference + * created in Java_com_wolfssl_WolfSSLSession_setVerify() + * of com_wolfssl_WolfSSLSession.c and deleted in native + * Java_com_wolfssl_WolfSSLSession_freeSSL(). Deleting the native + * global reference allows the Java object to be garbage collected. */ + private WolfSSLInternalVerifyCb wicb = null; + /** * Always creates a new session * @param ssl WOLFSSL session @@ -352,8 +364,9 @@ private void setLocalAuth() { } else { /* not our own TrustManager, set up callback so JSSE can use * TrustManager.checkClientTrusted/checkServerTrusted() */ - this.ssl.setVerify(WolfSSL.SSL_VERIFY_PEER, - new WolfSSLInternalVerifyCb()); + wicb = new WolfSSLInternalVerifyCb(authStore.getX509TrustManager(), + this.clientMode); + this.ssl.setVerify(WolfSSL.SSL_VERIFY_PEER, wicb); } } @@ -576,80 +589,5 @@ protected void saveSession() { this.session.setResume(); } } - - /* Internal verify callback. This is used when a user registers a - * TrustManager which is NOT com.wolfssl.provider.jsse.WolfSSLTrustManager - * and is used to call TrustManager checkClientTrusted() or - * checkServerTrusted(). If wolfJSSE TrustManager is used, native wolfSSL - * does certificate verification internally. */ - public class WolfSSLInternalVerifyCb implements WolfSSLVerifyCallback { - public int verifyCallback(int preverify_ok, long x509StorePtr) { - - X509TrustManager tm = authStore.getX509TrustManager(); - WolfSSLCertificate[] certs = null; - X509Certificate[] x509certs = null; - String authType = null; - - if (preverify_ok == 1) { - WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO, - "Native wolfSSL peer verification passed"); - } else { - WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO, - "WARNING: Native wolfSSL peer verification failed!"); - } - - try { - /* get WolfSSLCertificate[] from x509StorePtr */ - WolfSSLX509StoreCtx store = - new WolfSSLX509StoreCtx(x509StorePtr); - certs = store.getCerts(); - - } catch (WolfSSLException e) { - /* failed to get certs from native, give app null array */ - certs = null; - } - - if (certs != null && certs.length > 0) { - try { - /* Convert WolfSSLCertificate[] to X509Certificate[] */ - x509certs = new X509Certificate[certs.length]; - for (int i = 0; i < certs.length; i++) { - x509certs[i] = certs[i].getX509Certificate(); - } - } catch (CertificateException | IOException ce) { - /* failed to get cert array, give app null array */ - x509certs = null; - } - - /* get authType, use first cert */ - String sigType = certs[0].getSignatureType(); - if (sigType.contains("RSA")) { - authType = "RSA"; - } else if (sigType.contains("ECDSA")) { - authType = "ECDSA"; - } else if (sigType.contains("DSA")) { - authType = "DSA"; - } else if (sigType.contains("ED25519")) { - authType = "ED25519"; - } - } - - - try { - /* poll TrustManager for cert verification, should throw - * CertificateException if verification fails */ - if (clientMode) { - tm.checkServerTrusted(x509certs, authType); - } else { - tm.checkClientTrusted(x509certs, authType); - } - } catch (Exception e) { - /* TrustManager rejected certificate, not valid */ - return 0; - } - - /* continue handshake, verification succeeded */ - return 1; - } - } } + diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLInternalVerifyCb.java b/src/java/com/wolfssl/provider/jsse/WolfSSLInternalVerifyCb.java new file mode 100644 index 00000000..698248e1 --- /dev/null +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLInternalVerifyCb.java @@ -0,0 +1,103 @@ +package com.wolfssl.provider.jsse; + +import com.wolfssl.WolfSSL; +import com.wolfssl.WolfSSLVerifyCallback; +import com.wolfssl.WolfSSLException; +import com.wolfssl.WolfSSLSession; +import com.wolfssl.WolfSSLCertificate; +import com.wolfssl.WolfSSLX509StoreCtx; +import com.wolfssl.provider.jsse.WolfSSLInternalVerifyCb; +import java.util.Arrays; +import java.util.List; +import java.security.cert.X509Certificate; +import java.security.cert.CertificateException; +import javax.net.ssl.SSLException; +import javax.net.ssl.SSLParameters; +import javax.net.ssl.X509TrustManager; +import javax.net.ssl.SSLHandshakeException; +import java.io.IOException; + +/* Internal verify callback. This is used when a user registers a + * TrustManager which is NOT com.wolfssl.provider.jsse.WolfSSLTrustManager + * and is used to call TrustManager checkClientTrusted() or + * checkServerTrusted(). If wolfJSSE TrustManager is used, native wolfSSL + * does certificate verification internally. Used by WolfSSLEngineHelper. */ +public class WolfSSLInternalVerifyCb implements WolfSSLVerifyCallback { + + private X509TrustManager tm = null; + private boolean clientMode; + + public WolfSSLInternalVerifyCb(X509TrustManager xtm, boolean client) { + this.tm = xtm; + this.clientMode = client; + } + + public int verifyCallback(int preverify_ok, long x509StorePtr) { + + WolfSSLCertificate[] certs = null; + X509Certificate[] x509certs = null; + String authType = null; + + if (preverify_ok == 1) { + WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO, + "Native wolfSSL peer verification passed"); + } else { + WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO, + "WARNING: Native wolfSSL peer verification failed!"); + } + + try { + /* get WolfSSLCertificate[] from x509StorePtr */ + WolfSSLX509StoreCtx store = + new WolfSSLX509StoreCtx(x509StorePtr); + certs = store.getCerts(); + + } catch (WolfSSLException e) { + /* failed to get certs from native, give app null array */ + certs = null; + } + + if (certs != null && certs.length > 0) { + try { + /* Convert WolfSSLCertificate[] to X509Certificate[] */ + x509certs = new X509Certificate[certs.length]; + for (int i = 0; i < certs.length; i++) { + x509certs[i] = certs[i].getX509Certificate(); + } + } catch (CertificateException | IOException ce) { + /* failed to get cert array, give app null array */ + x509certs = null; + } + + /* get authType, use first cert */ + String sigType = certs[0].getSignatureType(); + if (sigType.contains("RSA")) { + authType = "RSA"; + } else if (sigType.contains("ECDSA")) { + authType = "ECDSA"; + } else if (sigType.contains("DSA")) { + authType = "DSA"; + } else if (sigType.contains("ED25519")) { + authType = "ED25519"; + } + } + + + try { + /* poll TrustManager for cert verification, should throw + * CertificateException if verification fails */ + if (clientMode) { + tm.checkServerTrusted(x509certs, authType); + } else { + tm.checkClientTrusted(x509certs, authType); + } + } catch (Exception e) { + /* TrustManager rejected certificate, not valid */ + return 0; + } + + /* continue handshake, verification succeeded */ + return 1; + } +} + diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLSNIServerName.java b/src/java/com/wolfssl/provider/jsse/WolfSSLSNIServerName.java index d0bbad93..5e54a385 100644 --- a/src/java/com/wolfssl/provider/jsse/WolfSSLSNIServerName.java +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLSNIServerName.java @@ -62,6 +62,10 @@ public final byte[] getEncoded() { } public boolean equals(Object other) { + if (other == null) { + return false; + } + if (!(other instanceof WolfSSLSNIServerName)) { return false; } From 30e7ec6f03b5c46466fc1042897ab6b392ff4bb2 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Wed, 29 Sep 2021 13:53:01 -0600 Subject: [PATCH 02/15] add call to WolfSSL.cleanup() in finalizer --- src/java/com/wolfssl/WolfSSL.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/java/com/wolfssl/WolfSSL.java b/src/java/com/wolfssl/WolfSSL.java index d59bdb2a..be982407 100644 --- a/src/java/com/wolfssl/WolfSSL.java +++ b/src/java/com/wolfssl/WolfSSL.java @@ -228,6 +228,9 @@ public class WolfSSL { public final static int ECDSAk = 518; public final static int ED25519k = 256; + /* is this object active, or has it been cleaned up? */ + private boolean active = false; + /* ------------------------ constructors ---------------------------- */ /** @@ -256,6 +259,8 @@ public WolfSSL() throws WolfSSLException { wolfssl_aes_ccm = getBulkCipherAlgorithmEnumAESCCM(); wolfssl_hc128 = getBulkCipherAlgorithmEnumHC128(); wolfssl_rabbit = getBulkCipherAlgorithmEnumRABBIT(); + + this.active = true; } /* ------------------- private/protected methods -------------------- */ @@ -942,5 +947,17 @@ public static String[] getCiphersIana() { */ public static native String[] getProtocolsMask(long mask); + @SuppressWarnings("deprecation") + @Override + protected void finalize() throws Throwable + { + if (this.active == true) { + /* free resources, set state */ + this.cleanup(); + this.active = false; + } + super.finalize(); + } + } /* end WolfSSL */ From cda657839ba9399aaaea065c75706463095cd3ab Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Wed, 29 Sep 2021 13:54:13 -0600 Subject: [PATCH 03/15] free native WOLFSSL when WolfSSLSocket is closed, earlier than finalize --- src/java/com/wolfssl/provider/jsse/WolfSSLSocket.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLSocket.java b/src/java/com/wolfssl/provider/jsse/WolfSSLSocket.java index 916b680d..06f8d254 100644 --- a/src/java/com/wolfssl/provider/jsse/WolfSSLSocket.java +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLSocket.java @@ -1371,6 +1371,12 @@ synchronized public void close() throws IOException { synchronized (handshakeLock) { this.connectionClosed = true; + + /* Connection is closed, free native WOLFSSL session + * to release native memory earlier than garbage collector + * might with finalize(). */ + this.ssl.freeSSL(); + this.ssl = null; } } @@ -1396,6 +1402,8 @@ synchronized public void close() throws IOException { } catch (IllegalStateException e) { throw new IOException(e); + } catch (WolfSSLJNIException jnie) { + throw new IOException(jnie); } } From 30cab26c4fc0b9f185cc3c0955382317f4786be5 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Thu, 30 Sep 2021 14:06:09 -0600 Subject: [PATCH 04/15] more diligent about feeing native certificate memory when possible --- .../provider/jsse/WolfSSLEngineHelper.java | 2 - .../jsse/WolfSSLImplementSSLSession.java | 73 ++++++++++++++++--- .../jsse/WolfSSLInternalVerifyCb.java | 7 +- .../wolfssl/provider/jsse/WolfSSLKeyX509.java | 43 ++++++----- .../provider/jsse/test/WolfSSLX509Test.java | 10 ++- 5 files changed, 99 insertions(+), 36 deletions(-) diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java b/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java index d51f3dc8..85af5877 100644 --- a/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java @@ -24,8 +24,6 @@ import com.wolfssl.WolfSSLVerifyCallback; import com.wolfssl.WolfSSLException; import com.wolfssl.WolfSSLSession; -import com.wolfssl.WolfSSLCertificate; -import com.wolfssl.WolfSSLX509StoreCtx; import java.util.Arrays; import java.util.List; import java.security.cert.X509Certificate; diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLImplementSSLSession.java b/src/java/com/wolfssl/provider/jsse/WolfSSLImplementSSLSession.java index ab73ab2c..baffba00 100644 --- a/src/java/com/wolfssl/provider/jsse/WolfSSLImplementSSLSession.java +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLImplementSSLSession.java @@ -26,17 +26,22 @@ import com.wolfssl.WolfSSLSession; import java.security.Principal; import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateEncodingException; import java.util.Date; import java.util.HashMap; import java.util.logging.Level; import java.util.logging.Logger; +import java.io.InputStream; +import java.io.ByteArrayInputStream; import javax.net.ssl.SSLPeerUnverifiedException; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSessionBindingEvent; import javax.net.ssl.SSLSessionBindingListener; import javax.net.ssl.SSLSessionContext; import javax.net.ssl.X509KeyManager; -import javax.security.cert.*; /** * wolfSSL Session @@ -234,7 +239,39 @@ public synchronized Certificate[] getPeerCertificates() throw new SSLPeerUnverifiedException("Error creating certificate"); } - return new Certificate[] { cert }; + /* convert WolfSSLX509 into X509Certificate so we can release + * our native memory */ + CertificateFactory cf; + ByteArrayInputStream der; + X509Certificate exportCert; + try { + cf = CertificateFactory.getInstance("X.509"); + } catch (CertificateException ex) { + cert.free(); + throw new SSLPeerUnverifiedException( + "Error getting CertificateFactory instance"); + } + + try { + der = new ByteArrayInputStream(cert.getEncoded()); + } catch (CertificateEncodingException ex) { + cert.free(); + throw new SSLPeerUnverifiedException( + "Error getting encoded DER from WolfSSLX509 object"); + } + + try { + exportCert = (X509Certificate)cf.generateCertificate(der); + } catch (CertificateException ex) { + cert.free(); + throw new SSLPeerUnverifiedException( + "Error generating X509Certificdate from DER encoding"); + } + + /* release native memory */ + cert.free(); + + return new Certificate[] { exportCert }; } @Override @@ -244,7 +281,7 @@ public Certificate[] getLocalCertificates() { } @Override - public synchronized X509Certificate[] getPeerCertificateChain() + public synchronized javax.security.cert.X509Certificate[] getPeerCertificateChain() throws SSLPeerUnverifiedException { WolfSSLX509X x509; @@ -254,7 +291,9 @@ public synchronized X509Certificate[] getPeerCertificateChain() try { x509 = new WolfSSLX509X(this.ssl.getPeerCertificate()); - return new X509Certificate[]{ (X509Certificate)x509 }; + return new javax.security.cert.X509Certificate[] { + (javax.security.cert.X509Certificate)x509 }; + } catch (IllegalStateException | WolfSSLJNIException | WolfSSLException ex) { Logger.getLogger( @@ -272,8 +311,13 @@ public synchronized Principal getPeerPrincipal() } try { + Principal peerPrincipal = null; WolfSSLX509 x509 = new WolfSSLX509(this.ssl.getPeerCertificate()); - return x509.getSubjectDN(); + peerPrincipal = x509.getSubjectDN(); + x509.free(); + + return peerPrincipal; + } catch (IllegalStateException | WolfSSLJNIException | WolfSSLException ex) { Logger.getLogger( @@ -285,23 +329,34 @@ public synchronized Principal getPeerPrincipal() @Override public Principal getLocalPrincipal() { - int i; X509KeyManager km = authStore.getX509KeyManager(); java.security.cert.X509Certificate[] certs = km.getCertificateChain(authStore.getCertAlias()); + Principal localPrincipal = null; if (certs == null) { return null; } - for (i = 0; i < certs.length; i++) { + for (int i = 0; i < certs.length; i++) { if (certs[i].getBasicConstraints() < 0) { /* is not a CA treat as end of chain */ - return certs[i].getSubjectDN(); + localPrincipal = certs[i].getSubjectDN(); + break; } } - return null; + + /* free native resources earlier than garbage collection if + * X509Certificate is WolfSSLX509 */ + for (int i = 0; i < certs.length; i++) { + if (certs[i] instanceof WolfSSLX509) { + ((WolfSSLX509)certs[i]).free(); + } + } + + /* return principal, or null if not set */ + return localPrincipal; } @Override diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLInternalVerifyCb.java b/src/java/com/wolfssl/provider/jsse/WolfSSLInternalVerifyCb.java index 698248e1..7f4e03eb 100644 --- a/src/java/com/wolfssl/provider/jsse/WolfSSLInternalVerifyCb.java +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLInternalVerifyCb.java @@ -80,8 +80,13 @@ public int verifyCallback(int preverify_ok, long x509StorePtr) { } else if (sigType.contains("ED25519")) { authType = "ED25519"; } - } + /* Free native WolfSSLCertificate memory. At this + * point x509certs[] is all Java managed memory now. */ + for (int i = 0; i < certs.length; i++) { + certs[i].free(); + } + } try { /* poll TrustManager for cert verification, should throw diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLKeyX509.java b/src/java/com/wolfssl/provider/jsse/WolfSSLKeyX509.java index 23456609..46cfd8d9 100644 --- a/src/java/com/wolfssl/provider/jsse/WolfSSLKeyX509.java +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLKeyX509.java @@ -96,6 +96,13 @@ private String[] getAliases(String type, Principal[] issuers) { if (type != null && cert != null && !cert.getPublicKey().getAlgorithm().equals(type)) { + + /* free native memory early if X509Certificate is WolfSSLX509 */ + if (cert instanceof WolfSSLX509) { + ((WolfSSLX509)cert).free(); + } + cert = null; + /* different public key type, skip */ continue; } @@ -196,32 +203,28 @@ public X509Certificate[] getCertificateChain(String alias) { try { Certificate[] certs = this.store.getCertificateChain(alias); if (certs != null) { - int i; + int x509Cnt = 0; - /* @TODO this conversion from Certificate to WolfX509X - * adds overhead */ - ret = new X509Certificate[certs.length]; - for (i = 0; i < certs.length; i++) { - ret[i] = new WolfSSLX509(certs[i].getEncoded()); + /* count up X509Certificate type in certs[] */ + for (int i = 0; i < certs.length; i++) { + if (certs[i] instanceof X509Certificate) { + x509Cnt++; + } } - } - } catch (KeyStoreException | CertificateEncodingException | - WolfSSLException ex) { - return null; - } - if (ret == null) { - try { - Certificate cert = this.store.getCertificate(alias); - if (cert != null) { - ret = new X509Certificate[1]; - ret[0] = new WolfSSLX509(cert.getEncoded()); + /* store into X509Certificate array */ + ret = new X509Certificate[x509Cnt]; + for (int i = 0; i < certs.length; i++) { + if (certs[i] instanceof X509Certificate) { + ret[i] = (X509Certificate)certs[i]; + } } - } catch (KeyStoreException | CertificateEncodingException | - WolfSSLException ex) { - return null; } + + } catch (KeyStoreException ex) { + return null; } + return ret; } diff --git a/src/test/com/wolfssl/provider/jsse/test/WolfSSLX509Test.java b/src/test/com/wolfssl/provider/jsse/test/WolfSSLX509Test.java index 4a9ade0f..c17007ad 100644 --- a/src/test/com/wolfssl/provider/jsse/test/WolfSSLX509Test.java +++ b/src/test/com/wolfssl/provider/jsse/test/WolfSSLX509Test.java @@ -486,7 +486,9 @@ public void testGetters() { fail("failed to get cert string"); } - /* check encoding can be parsed (throws exception if not) */ + /* check encoding can be parsed (throws exception if not). + * Use WolfSSLX509 for tests below to ensure we are using our + * implementation of X509Certificate. */ WolfSSLX509 tmp; tmp = new WolfSSLX509(peer.getEncoded()); tmp = new WolfSSLX509(x509.getEncoded()); @@ -499,7 +501,7 @@ public void testGetters() { } try { - x509.getIssuerUniqueID(); + tmp.getIssuerUniqueID(); error("\t\t... failed: A test case for getIssuerUniqueID is needed"); fail("getIssuerUniqueID implemented without test case"); } catch (Exception ex) { @@ -507,7 +509,7 @@ public void testGetters() { } try { - x509.getSubjectUniqueID(); + tmp.getSubjectUniqueID(); error("\t\t... failed: A test case for getSubjectUniqueID is needed"); fail("getSubjectUniqueID implemented without test case"); } catch (Exception ex) { @@ -515,7 +517,7 @@ public void testGetters() { } try { - x509.getSigAlgParams(); + tmp.getSigAlgParams(); error("\t\t... failed: A test case for getSigAlgParams is needed"); fail("getSigAlgParams implemented without test case"); } catch (Exception ex) { From b5d5ffd5fbec56668ba87367d2a5cbc53575adf6 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Thu, 30 Sep 2021 14:18:41 -0600 Subject: [PATCH 05/15] add call to DeleteGlobalRef for native logging callback object --- native/com_wolfssl_WolfSSL.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/native/com_wolfssl_WolfSSL.c b/native/com_wolfssl_WolfSSL.c index fcdda625..83845f66 100644 --- a/native/com_wolfssl_WolfSSL.c +++ b/native/com_wolfssl_WolfSSL.c @@ -555,6 +555,12 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_cleanup (void)jenv; (void)jcl; + /* release global logging callback object if registered */ + if (g_loggingCbIfaceObj != NULL) { + (*jenv)->DeleteGlobalRef(jenv, g_loggingCbIfaceObj); + g_loggingCbIfaceObj = NULL; + } + return wolfSSL_Cleanup(); } @@ -583,18 +589,26 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_setLoggingCb (void)jcl; - if (!jenv || !callback) { + if (jenv == NULL) { return BAD_FUNC_ARG; } - /* store Java logging callback Interface object */ - g_loggingCbIfaceObj = (*jenv)->NewGlobalRef(jenv, callback); - if (!g_loggingCbIfaceObj) { - printf("error storing global logging callback interface\n"); - return SSL_FAILURE; + /* release existing logging callback object if registered */ + if (g_loggingCbIfaceObj != NULL) { + (*jenv)->DeleteGlobalRef(jenv, g_loggingCbIfaceObj); + g_loggingCbIfaceObj = NULL; } - ret = wolfSSL_SetLoggingCb(NativeLoggingCallback); + if (callback != NULL) { + /* store Java logging callback Interface object */ + g_loggingCbIfaceObj = (*jenv)->NewGlobalRef(jenv, callback); + if (g_loggingCbIfaceObj == NULL) { + printf("error storing global logging callback interface\n"); + return SSL_FAILURE; + } + + ret = wolfSSL_SetLoggingCb(NativeLoggingCallback); + } return ret; } From d0e2ceaa9e035e56a8a9c9957123c64a3a6c4e69 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Thu, 30 Sep 2021 14:23:31 -0600 Subject: [PATCH 06/15] add call to DeleteGlobalRef for native FIPS callback object (HAVE_FIPS builds only) --- native/com_wolfssl_WolfSSL.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/native/com_wolfssl_WolfSSL.c b/native/com_wolfssl_WolfSSL.c index 83845f66..11117685 100644 --- a/native/com_wolfssl_WolfSSL.c +++ b/native/com_wolfssl_WolfSSL.c @@ -561,6 +561,14 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_cleanup g_loggingCbIfaceObj = NULL; } +#ifdef HAVE_FIPS + /* release existing FIPS callback object if set */ + if (g_fipsCbIfaceObj != NULL) { + (*jenv)->DeleteGlobalRef(jenv, g_fipsCbIfaceObj); + g_fipsCbIfaceObj = NULL; + } +#endif + return wolfSSL_Cleanup(); } @@ -800,21 +808,29 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_setFIPSCb (void)jcl; #ifdef HAVE_FIPS - if (jenv == NULL || callback == NULL) { + if (jenv == NULL) { return BAD_FUNC_ARG; } - /* store Java FIPS callback Interface object */ - g_fipsCbIfaceObj = (*jenv)->NewGlobalRef(jenv, callback); - if (!g_fipsCbIfaceObj) { - printf("error storing global wolfCrypt FIPS callback interface\n"); - return SSL_FAILURE; + /* release existing FIPS callback object if set */ + if (g_fipsCbIfaceObj != NULL) { + (*jenv)->DeleteGlobalRef(jenv, g_fipsCbIfaceObj); + g_fipsCbIfaceObj = NULL; } - /* register NativeFIPSErrorCallback, wraps Java callback */ - ret = wolfCrypt_SetCb_fips(NativeFIPSErrorCallback); - if (ret == 0) { - ret = SSL_SUCCESS; + if (callback != NULL) { + /* store Java FIPS callback Interface object */ + g_fipsCbIfaceObj = (*jenv)->NewGlobalRef(jenv, callback); + if (g_fipsCbIfaceObj == NULL) { + printf("error storing global wolfCrypt FIPS callback interface\n"); + return SSL_FAILURE; + } + + /* register NativeFIPSErrorCallback, wraps Java callback */ + ret = wolfCrypt_SetCb_fips(NativeFIPSErrorCallback); + if (ret == 0) { + ret = SSL_SUCCESS; + } } #else (void)jenv; From 062a63e8da46cdde23e322b3feb990162a90ffe3 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Thu, 30 Sep 2021 14:30:41 -0600 Subject: [PATCH 07/15] add call to DeleteGlobalRef for native CTX-level verify callback, only affects JNI not JSSE --- native/com_wolfssl_WolfSSLContext.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/native/com_wolfssl_WolfSSLContext.c b/native/com_wolfssl_WolfSSLContext.c index 671a4af2..0578d7bc 100644 --- a/native/com_wolfssl_WolfSSLContext.c +++ b/native/com_wolfssl_WolfSSLContext.c @@ -324,6 +324,12 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLContext_freeContext (void)jenv; (void)jcl; + /* release verify callback object if set */ + if (g_verifyCbIfaceObj != NULL) { + (*jenv)->DeleteGlobalRef(jenv, g_verifyCbIfaceObj); + g_verifyCbIfaceObj = NULL; + } + /* wolfSSL checks for null pointer */ wolfSSL_CTX_free((WOLFSSL_CTX*)(uintptr_t)ctx); } @@ -333,13 +339,23 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLContext_setVerify(JNIEnv* jenv, { (void)jcl; + if (jenv == NULL) { + return; + } + + /* release verify callback object if set before */ + if (g_verifyCbIfaceObj != NULL) { + (*jenv)->DeleteGlobalRef(jenv, g_verifyCbIfaceObj); + g_verifyCbIfaceObj = NULL; + } + if (!callbackIface) { wolfSSL_CTX_set_verify((WOLFSSL_CTX*)(uintptr_t)ctx, mode, NULL); - } else { - + } + else { /* store Java verify Interface object */ g_verifyCbIfaceObj = (*jenv)->NewGlobalRef(jenv, callbackIface); - if (!g_verifyCbIfaceObj) { + if (g_verifyCbIfaceObj == NULL) { printf("error storing global callback interface\n"); } From c7925f45dcbfeaaf3dd493a95c4d755fd1440ef3 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Thu, 30 Sep 2021 14:36:49 -0600 Subject: [PATCH 08/15] add call to DeleteGlobalRef for native CTX-level CRL callback, only affects JNI not JSSE --- native/com_wolfssl_WolfSSLContext.c | 41 ++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/native/com_wolfssl_WolfSSLContext.c b/native/com_wolfssl_WolfSSLContext.c index 0578d7bc..677005fd 100644 --- a/native/com_wolfssl_WolfSSLContext.c +++ b/native/com_wolfssl_WolfSSLContext.c @@ -330,6 +330,12 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLContext_freeContext g_verifyCbIfaceObj = NULL; } + /* release global CRL callback object if set */ + if (g_crlCtxCbIfaceObj != NULL) { + (*jenv)->DeleteGlobalRef(jenv, g_crlCtxCbIfaceObj); + g_crlCtxCbIfaceObj = NULL; + } + /* wolfSSL checks for null pointer */ wolfSSL_CTX_free((WOLFSSL_CTX*)(uintptr_t)ctx); } @@ -1528,25 +1534,34 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLContext_setCRLCb (void)jcl; - if (!jenv || !ctx || !cb) { + if (jenv == NULL || ctx == 0) { return BAD_FUNC_ARG; } - /* store Java CRL callback Interface object */ - g_crlCtxCbIfaceObj = (*jenv)->NewGlobalRef(jenv, cb); + /* release global CRL callback object if set */ + if (g_crlCtxCbIfaceObj != NULL) { + (*jenv)->DeleteGlobalRef(jenv, g_crlCtxCbIfaceObj); + g_crlCtxCbIfaceObj = NULL; + } - if (!g_crlCtxCbIfaceObj) { - excClass = (*jenv)->FindClass(jenv, "com/wolfssl/WolfSSLJNIException"); - if ((*jenv)->ExceptionOccurred(jenv)) { - (*jenv)->ExceptionDescribe(jenv); - (*jenv)->ExceptionClear(jenv); + if (cb != NULL) { + /* store Java CRL callback Interface object */ + g_crlCtxCbIfaceObj = (*jenv)->NewGlobalRef(jenv, cb); + + if (!g_crlCtxCbIfaceObj) { + excClass = (*jenv)->FindClass(jenv, + "com/wolfssl/WolfSSLJNIException"); + if ((*jenv)->ExceptionOccurred(jenv)) { + (*jenv)->ExceptionDescribe(jenv); + (*jenv)->ExceptionClear(jenv); + } + (*jenv)->ThrowNew(jenv, excClass, + "error storing global missing CTX CRL callback interface"); } - (*jenv)->ThrowNew(jenv, excClass, - "error storing global missing CTX CRL callback interface"); - } - ret = wolfSSL_CTX_SetCRL_Cb((WOLFSSL_CTX*)(uintptr_t)ctx, - NativeCtxMissingCRLCallback); + ret = wolfSSL_CTX_SetCRL_Cb((WOLFSSL_CTX*)(uintptr_t)ctx, + NativeCtxMissingCRLCallback); + } return ret; #else From 7597b5e35a214bf75ddc1ded0a580d09067993c8 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Thu, 30 Sep 2021 15:01:31 -0600 Subject: [PATCH 09/15] make sure to DeleteGlobalRef on g_cachedSSLObj in error cases when setting up in newSSL() --- native/com_wolfssl_WolfSSLSession.c | 46 +++++++++++++++++++---------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/native/com_wolfssl_WolfSSLSession.c b/native/com_wolfssl_WolfSSLSession.c index 16b930d9..1c346674 100644 --- a/native/com_wolfssl_WolfSSLSession.c +++ b/native/com_wolfssl_WolfSSLSession.c @@ -169,36 +169,31 @@ JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLSession_newSSL (JNIEnv* jenv, jobject jcl, jlong ctx) { int ret; - jlong sslPtr; - jobject* g_cachedObj; - wolfSSL_Mutex* jniSessLock; - SSLAppData* appData; + jlong sslPtr = 0; + jobject* g_cachedSSLObj = NULL; + wolfSSL_Mutex* jniSessLock = NULL; + SSLAppData* appData = NULL; - if (!jenv) + if (jenv == NULL) { return SSL_FAILURE; + } /* wolfSSL java caller checks for null pointer */ sslPtr = (jlong)(uintptr_t)wolfSSL_new((WOLFSSL_CTX*)(uintptr_t)ctx); if (sslPtr != 0) { /* create global reference to WolfSSLSession jobject */ - g_cachedObj = (jobject*)XMALLOC(sizeof(jobject), NULL, + g_cachedSSLObj = (jobject*)XMALLOC(sizeof(jobject), NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (!g_cachedObj) { + if (g_cachedSSLObj == NULL) { printf("error mallocing memory in newSSL\n"); wolfSSL_free((WOLFSSL*)(uintptr_t)sslPtr); return SSL_FAILURE; } - *g_cachedObj = (*jenv)->NewGlobalRef(jenv, jcl); - if (!*g_cachedObj) { + *g_cachedSSLObj = (*jenv)->NewGlobalRef(jenv, jcl); + if (*g_cachedSSLObj == NULL) { printf("error storing global WolfSSLSession object\n"); - wolfSSL_free((WOLFSSL*)(uintptr_t)sslPtr); - return SSL_FAILURE; - } - /* cache associated WolfSSLSession jobject in native WOLFSSL */ - ret = wolfSSL_set_jobject((WOLFSSL*)(uintptr_t)sslPtr, g_cachedObj); - if (ret != SSL_SUCCESS) { - printf("error storing jobject in wolfSSL native session\n"); + XFREE(g_cachedSSLObj, NULL, DYNAMIC_TYPE_TMP_BUFFER); wolfSSL_free((WOLFSSL*)(uintptr_t)sslPtr); return SSL_FAILURE; } @@ -207,6 +202,8 @@ JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLSession_newSSL DYNAMIC_TYPE_TMP_BUFFER); if (appData == NULL) { printf("error allocating memory in newSSL for SSLAppData\n"); + (*jenv)->DeleteGlobalRef(jenv, *g_cachedSSLObj); + XFREE(g_cachedSSLObj, NULL, DYNAMIC_TYPE_TMP_BUFFER); wolfSSL_free((WOLFSSL*)(uintptr_t)sslPtr); return SSL_FAILURE; } @@ -218,7 +215,9 @@ JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLSession_newSSL DYNAMIC_TYPE_TMP_BUFFER); if (!jniSessLock) { printf("error mallocing memory in newSSL for jniSessLock\n"); + (*jenv)->DeleteGlobalRef(jenv, *g_cachedSSLObj); XFREE(appData, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(g_cachedSSLObj, NULL, DYNAMIC_TYPE_TMP_BUFFER); wolfSSL_free((WOLFSSL*)(uintptr_t)sslPtr); return SSL_FAILURE; } @@ -226,11 +225,26 @@ JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLSession_newSSL wc_InitMutex(jniSessLock); appData->jniSessLock = jniSessLock; + /* cache associated WolfSSLSession jobject in native WOLFSSL */ + ret = wolfSSL_set_jobject((WOLFSSL*)(uintptr_t)sslPtr, g_cachedSSLObj); + if (ret != SSL_SUCCESS) { + printf("error storing jobject in wolfSSL native session\n"); + (*jenv)->DeleteGlobalRef(jenv, *g_cachedSSLObj); + XFREE(appData, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(g_cachedSSLObj, NULL, DYNAMIC_TYPE_TMP_BUFFER); + wolfSSL_free((WOLFSSL*)(uintptr_t)sslPtr); + return SSL_FAILURE; + } + + /* cache SSLAppData into native WOLFSSL */ if (wolfSSL_set_app_data( (WOLFSSL*)(uintptr_t)sslPtr, appData) != SSL_SUCCESS) { printf("error setting WOLFSSL app data in newSSL\n"); + (*jenv)->DeleteGlobalRef(jenv, *g_cachedSSLObj); XFREE(jniSessLock, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(appData, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(g_cachedSSLObj, NULL, DYNAMIC_TYPE_TMP_BUFFER); + wolfSSL_set_jobject((WOLFSSL*)(uintptr_t)sslPtr, NULL); wolfSSL_free((WOLFSSL*)(uintptr_t)sslPtr); return SSL_FAILURE; } From 8c01c9c93f0513758c8f3c9497506c6f735fb6b3 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Thu, 30 Sep 2021 15:07:51 -0600 Subject: [PATCH 10/15] add call to DeleteGlobalRef for native WOLFSSL CRL callback, only currently applies to JNI not JSSE-only --- native/com_wolfssl_WolfSSLSession.c | 33 ++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/native/com_wolfssl_WolfSSLSession.c b/native/com_wolfssl_WolfSSLSession.c index 1c346674..32c05116 100644 --- a/native/com_wolfssl_WolfSSLSession.c +++ b/native/com_wolfssl_WolfSSLSession.c @@ -957,6 +957,14 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_freeSSL return; } +#ifdef HAVE_CRL + /* release global CRL callback ref if registered */ + if (g_crlCbIfaceObj != NULL) { + (*jenv)->DeleteGlobalRef(jenv, g_crlCbIfaceObj); + g_crlCbIfaceObj = NULL; + } +#endif + /* native cleanup */ wolfSSL_free((WOLFSSL*)(uintptr_t)ssl); ssl = 0; @@ -2037,7 +2045,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_setCRLCb (void)jcl; - if (!jenv || !cb) { + if (jenv == NULL) { return BAD_FUNC_ARG; } @@ -2049,21 +2057,30 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_setCRLCb return SSL_FAILURE; } - if (!ssl) { + if (ssl == 0) { (*jenv)->ThrowNew(jenv, excClass, "Input WolfSSLSession object was null in " "setCRLCb"); return SSL_FAILURE; } - /* store Java CRL callback Interface object */ - g_crlCbIfaceObj = (*jenv)->NewGlobalRef(jenv, cb); - if (!g_crlCbIfaceObj) { - (*jenv)->ThrowNew(jenv, excClass, - "Error storing global missingCRLCallback interface"); + /* release global CRL callback ref if already registered */ + if (g_crlCbIfaceObj != NULL) { + (*jenv)->DeleteGlobalRef(jenv, g_crlCbIfaceObj); + g_crlCbIfaceObj = NULL; } - ret = wolfSSL_SetCRL_Cb((WOLFSSL*)(uintptr_t)ssl, NativeMissingCRLCallback); + if (cb != NULL) { + /* store Java CRL callback Interface object */ + g_crlCbIfaceObj = (*jenv)->NewGlobalRef(jenv, cb); + if (g_crlCbIfaceObj == NULL) { + (*jenv)->ThrowNew(jenv, excClass, + "Error storing global missingCRLCallback interface"); + } + + ret = wolfSSL_SetCRL_Cb((WOLFSSL*)(uintptr_t)ssl, + NativeMissingCRLCallback); + } return ret; #else From b226e7d045a5e479a0f0d08e2d84ee7cc0688dbb Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Thu, 30 Sep 2021 15:57:03 -0600 Subject: [PATCH 11/15] free native WOLFSSL PK callback ctx global jni refs in wolfSSL_free() --- native/com_wolfssl_WolfSSLSession.c | 137 +++++++++++++++++++++++----- 1 file changed, 112 insertions(+), 25 deletions(-) diff --git a/native/com_wolfssl_WolfSSLSession.c b/native/com_wolfssl_WolfSSLSession.c index 32c05116..a3bf3323 100644 --- a/native/com_wolfssl_WolfSSLSession.c +++ b/native/com_wolfssl_WolfSSLSession.c @@ -904,6 +904,9 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_freeSSL jclass excClass; SSLAppData* appData; (void)jcl; +#if defined(HAVE_PK_CALLBACKS) && (defined(HAVE_ECC) || !defined(NO_RSA)) + internCtx* pkCtx = NULL; +#endif excClass = (*jenv)->FindClass(jenv, "com/wolfssl/WolfSSLException"); @@ -965,6 +968,76 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_freeSSL } #endif +#if defined(HAVE_PK_CALLBACKS) + #ifdef HAVE_ECC + /* free ECC sign callback CTX global reference if set */ + pkCtx = (internCtx*) wolfSSL_GetEccSignCtx((WOLFSSL*)(uintptr_t)ssl); + if (pkCtx != NULL) { + if (pkCtx->obj != NULL) { + (*jenv)->DeleteGlobalRef(jenv, pkCtx->obj); + } + XFREE(pkCtx, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + + /* free ECC verify callback CTX global reference if set */ + pkCtx = (internCtx*)wolfSSL_GetEccVerifyCtx((WOLFSSL*)(uintptr_t)ssl); + if (pkCtx != NULL) { + if (pkCtx->obj != NULL) { + (*jenv)->DeleteGlobalRef(jenv, pkCtx->obj); + } + XFREE(pkCtx, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + + /* free ECC shared secret callback CTX global reference if set */ + pkCtx = (internCtx*)wolfSSL_GetEccSharedSecretCtx( + (WOLFSSL*)(uintptr_t)ssl); + if (pkCtx != NULL) { + if (pkCtx->obj != NULL) { + (*jenv)->DeleteGlobalRef(jenv, pkCtx->obj); + } + XFREE(pkCtx, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + #endif /* HAVE_ECC */ + + #ifndef NO_RSA + /* free RSA sign callback CTX global reference if set */ + pkCtx = (internCtx*) wolfSSL_GetRsaSignCtx((WOLFSSL*)(uintptr_t)ssl); + if (pkCtx != NULL) { + if (pkCtx->obj != NULL) { + (*jenv)->DeleteGlobalRef(jenv, pkCtx->obj); + } + XFREE(pkCtx, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + + /* free RSA verify callback CTX global reference if set */ + pkCtx = (internCtx*)wolfSSL_GetRsaVerifyCtx((WOLFSSL*)(uintptr_t)ssl); + if (pkCtx != NULL) { + if (pkCtx->obj != NULL) { + (*jenv)->DeleteGlobalRef(jenv, pkCtx->obj); + } + XFREE(pkCtx, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + + /* free RSA encrypt callback CTX global reference if set */ + pkCtx = (internCtx*) wolfSSL_GetRsaEncCtx((WOLFSSL*)(uintptr_t)ssl); + if (pkCtx != NULL) { + if (pkCtx->obj != NULL) { + (*jenv)->DeleteGlobalRef(jenv, pkCtx->obj); + } + XFREE(pkCtx, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + + /* free RSA decrypt callback CTX global reference if set */ + pkCtx = (internCtx*) wolfSSL_GetRsaDecCtx((WOLFSSL*)(uintptr_t)ssl); + if (pkCtx != NULL) { + if (pkCtx->obj != NULL) { + (*jenv)->DeleteGlobalRef(jenv, pkCtx->obj); + } + XFREE(pkCtx, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + #endif /* !NO_RSA */ +#endif /* HAVE_PK_CALLBACKS */ + /* native cleanup */ wolfSSL_free((WOLFSSL*)(uintptr_t)ssl); ssl = 0; @@ -2729,8 +2802,10 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_setEccSignCtx /* note: if CTX has not been set up yet, wolfSSL defaults to NULL */ if (eccSignCtx != NULL) { myCtx = (internCtx*)eccSignCtx; - if (myCtx->active == 1) { - (*jenv)->DeleteGlobalRef(jenv, myCtx->obj); + if (myCtx != NULL) { + if (myCtx->active == 1) { + (*jenv)->DeleteGlobalRef(jenv, myCtx->obj); + } XFREE(myCtx, NULL, DYNAMIC_TYPE_TMP_BUFFER); } } @@ -2805,8 +2880,10 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_setEccVerifyCtx /* note: if CTX has not been set up yet, wolfSSL defaults to NULL */ if (eccVerifyCtx != NULL) { myCtx = (internCtx*)eccVerifyCtx; - if (myCtx->active == 1) { - (*jenv)->DeleteGlobalRef(jenv, myCtx->obj); + if (myCtx != NULL) { + if (myCtx->active == 1) { + (*jenv)->DeleteGlobalRef(jenv, myCtx->obj); + } XFREE(myCtx, NULL, DYNAMIC_TYPE_TMP_BUFFER); } } @@ -2824,7 +2901,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_setEccVerifyCtx /* store global ref to WolfSSLSession object */ myCtx->obj = (*jenv)->NewGlobalRef(jenv, jcl); - if (!myCtx->obj) { + if (myCtx->obj == NULL) { (*jenv)->ThrowNew(jenv, excClass, "Unable to store WolfSSLSession object as global reference"); return; @@ -2881,15 +2958,17 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_setEccSharedSecretCtx /* note: if CTX has not been set up yet, wolfSSL defaults to NULL */ if (eccSharedSecretCtx != NULL) { myCtx = (internCtx*)eccSharedSecretCtx; - if (myCtx->active == 1) { - (*jenv)->DeleteGlobalRef(jenv, myCtx->obj); + if (myCtx != NULL) { + if (myCtx->active == 1) { + (*jenv)->DeleteGlobalRef(jenv, myCtx->obj); + } XFREE(myCtx, NULL, DYNAMIC_TYPE_TMP_BUFFER); } } /* allocate memory for internal JNI object reference */ myCtx = XMALLOC(sizeof(internCtx), NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (!myCtx) { + if (myCtx == NULL) { (*jenv)->ThrowNew(jenv, excClass, "Unable to allocate memory for ECC shared secret context\n"); return; @@ -2900,7 +2979,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_setEccSharedSecretCtx /* store global ref to WolfSSLSession object */ myCtx->obj = (*jenv)->NewGlobalRef(jenv, jcl); - if (!myCtx->obj) { + if (myCtx->obj == NULL) { (*jenv)->ThrowNew(jenv, excClass, "Unable to store WolfSSLSession object as global reference"); return; @@ -2956,15 +3035,17 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_setRsaSignCtx /* note: if CTX has not been set up yet, wolfSSL defaults to NULL */ if (rsaSignCtx != NULL) { myCtx = (internCtx*)rsaSignCtx; - if (myCtx->active == 1) { - (*jenv)->DeleteGlobalRef(jenv, myCtx->obj); + if (myCtx != NULL) { + if (myCtx->active == 1) { + (*jenv)->DeleteGlobalRef(jenv, myCtx->obj); + } XFREE(myCtx, NULL, DYNAMIC_TYPE_TMP_BUFFER); } } /* allocate memory for internal JNI object reference */ myCtx = XMALLOC(sizeof(internCtx), NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (!myCtx) { + if (myCtx == NULL) { (*jenv)->ThrowNew(jenv, excClass, "Unable to allocate memory for RSA sign context\n"); return; @@ -2975,7 +3056,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_setRsaSignCtx /* store global ref to WolfSSLSession object */ myCtx->obj = (*jenv)->NewGlobalRef(jenv, jcl); - if (!myCtx->obj) { + if (myCtx->obj == NULL) { (*jenv)->ThrowNew(jenv, excClass, "Unable to store WolfSSLSession object as global reference"); return; @@ -3032,15 +3113,17 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_setRsaVerifyCtx /* note: if CTX has not been set up yet, wolfSSL defaults to NULL */ if (rsaVerifyCtx != NULL) { myCtx = (internCtx*)rsaVerifyCtx; - if (myCtx->active == 1) { - (*jenv)->DeleteGlobalRef(jenv, myCtx->obj); + if (myCtx != NULL) { + if (myCtx->active == 1) { + (*jenv)->DeleteGlobalRef(jenv, myCtx->obj); + } XFREE(myCtx, NULL, DYNAMIC_TYPE_TMP_BUFFER); } } /* allocate memory for internal JNI object reference */ myCtx = XMALLOC(sizeof(internCtx), NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (!myCtx) { + if (myCtx == NULL) { (*jenv)->ThrowNew(jenv, excClass, "Unable to allocate memory for RSA verify context\n"); return; @@ -3051,7 +3134,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_setRsaVerifyCtx /* store global ref to WolfSSLSession object */ myCtx->obj = (*jenv)->NewGlobalRef(jenv, jcl); - if (!myCtx->obj) { + if (myCtx->obj == NULL) { (*jenv)->ThrowNew(jenv, excClass, "Unable to store WolfSSLSession object as global reference"); return; @@ -3107,15 +3190,17 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_setRsaEncCtx /* note: if CTX has not been set up yet, wolfSSL defaults to NULL */ if (rsaEncCtx != NULL) { myCtx = (internCtx*)rsaEncCtx; - if (myCtx->active == 1) { - (*jenv)->DeleteGlobalRef(jenv, myCtx->obj); + if (myCtx != NULL) { + if (myCtx->active == 1) { + (*jenv)->DeleteGlobalRef(jenv, myCtx->obj); + } XFREE(myCtx, NULL, DYNAMIC_TYPE_TMP_BUFFER); } } /* allocate memory for internal JNI object reference */ myCtx = XMALLOC(sizeof(internCtx), NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (!myCtx) { + if (myCtx == NULL) { (*jenv)->ThrowNew(jenv, excClass, "Unable to allocate memory for RSA encrypt context\n"); return; @@ -3126,7 +3211,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_setRsaEncCtx /* store global ref to WolfSSLSession object */ myCtx->obj = (*jenv)->NewGlobalRef(jenv, jcl); - if (!myCtx->obj) { + if (myCtx->obj == NULL) { (*jenv)->ThrowNew(jenv, excClass, "Unable to store WolfSSLSession object as global reference"); return; @@ -3182,15 +3267,17 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_setRsaDecCtx /* note: if CTX has not been set up yet, wolfSSL defaults to NULL */ if (rsaDecCtx != NULL) { myCtx = (internCtx*)rsaDecCtx; - if (myCtx->active == 1) { - (*jenv)->DeleteGlobalRef(jenv, myCtx->obj); + if (myCtx != NULL) { + if (myCtx->active == 1) { + (*jenv)->DeleteGlobalRef(jenv, myCtx->obj); + } XFREE(myCtx, NULL, DYNAMIC_TYPE_TMP_BUFFER); } } /* allocate memory for internal JNI object reference */ myCtx = XMALLOC(sizeof(internCtx), NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (!myCtx) { + if (myCtx == NULL) { (*jenv)->ThrowNew(jenv, excClass, "Unable to allocate memory for RSA decrypt context\n"); return; @@ -3201,7 +3288,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_setRsaDecCtx /* store global ref to WolfSSLSession object */ myCtx->obj = (*jenv)->NewGlobalRef(jenv, jcl); - if (!myCtx->obj) { + if (myCtx->obj == NULL) { (*jenv)->ThrowNew(jenv, excClass, "Unable to store WolfSSLSession object as global reference"); return; From da5dc9df420624ea37084098186131ce2539da62 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Thu, 30 Sep 2021 16:10:22 -0600 Subject: [PATCH 12/15] remove extraneous XFREE calls in WolfSSLCertificate.c --- native/com_wolfssl_WolfSSLCertificate.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/native/com_wolfssl_WolfSSLCertificate.c b/native/com_wolfssl_WolfSSLCertificate.c index 87695eec..747032ae 100644 --- a/native/com_wolfssl_WolfSSLCertificate.c +++ b/native/com_wolfssl_WolfSSLCertificate.c @@ -332,7 +332,6 @@ JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1get_1sign (*jenv)->ExceptionDescribe(jenv); (*jenv)->ExceptionClear(jenv); (*jenv)->DeleteLocalRef(jenv, ret); - XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); return NULL; } @@ -547,7 +546,6 @@ JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1get_1pubk (*jenv)->ExceptionDescribe(jenv); (*jenv)->ExceptionClear(jenv); (*jenv)->DeleteLocalRef(jenv, ret); - XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); return NULL; } From 42b86b6e4402d404b23be6bad2a81ff18e948e39 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Fri, 1 Oct 2021 17:34:32 -0600 Subject: [PATCH 13/15] fix unused variable warnings when HAVE_FIPS not defined --- native/com_wolfssl_WolfSSL.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/native/com_wolfssl_WolfSSL.c b/native/com_wolfssl_WolfSSL.c index 11117685..edcc5a9e 100644 --- a/native/com_wolfssl_WolfSSL.c +++ b/native/com_wolfssl_WolfSSL.c @@ -798,6 +798,10 @@ void NativeFIPSErrorCallback(const int ok, const int err, (*jenv)->ThrowNew(jenv, excClass, "Object reference invalid in NativeFIPSErrorCallback"); } +#else + (void)ok; + (void)err; + (void)hash; #endif } @@ -847,6 +851,8 @@ JNIEXPORT jstring JNICALL Java_com_wolfssl_WolfSSL_getWolfCryptFIPSCoreHash #ifdef HAVE_FIPS return (*jenv)->NewStringUTF(jenv, wolfCrypt_GetCoreHash_fips()); #else + (void)jenv; + (void)jcl; return NULL; #endif } From 4db73ba28ddc93fbd3dfdf04882dd27ef38f0999 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Thu, 7 Oct 2021 09:49:14 -0600 Subject: [PATCH 14/15] make WolfSSL object a static class variable in WolfSSLProvider --- src/java/com/wolfssl/provider/jsse/WolfSSLProvider.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLProvider.java b/src/java/com/wolfssl/provider/jsse/WolfSSLProvider.java index 6b525b88..23571b04 100644 --- a/src/java/com/wolfssl/provider/jsse/WolfSSLProvider.java +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLProvider.java @@ -34,6 +34,10 @@ */ public final class WolfSSLProvider extends Provider { + /* Keep one static reference to native wolfSSL library across + * all WolfSSLProvider objects. */ + private static WolfSSL sslLib = null; + public class JSSEFIPSErrorCallback implements WolfSSLFIPSErrorCallback { public void errorCallback(int ok, int err, String hash) { WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO, @@ -75,7 +79,7 @@ public WolfSSLProvider() { try { /* initialize native wolfSSL */ - WolfSSL sslLib = new WolfSSL(); + sslLib = new WolfSSL(); } catch (WolfSSLException e) { WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO, "Failed to initialize native wolfSSL library"); From 393035953c16f4355e3b66b6c812df68ffa4d7dd Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Thu, 4 Nov 2021 11:32:40 -0600 Subject: [PATCH 15/15] move WolfSSLImplementSSLSession variables to top of scope, add license header to WolfSSLInternalVerifyCb.java --- .../jsse/WolfSSLImplementSSLSession.java | 6 +++--- .../jsse/WolfSSLInternalVerifyCb.java | 20 +++++++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLImplementSSLSession.java b/src/java/com/wolfssl/provider/jsse/WolfSSLImplementSSLSession.java index baffba00..31821361 100644 --- a/src/java/com/wolfssl/provider/jsse/WolfSSLImplementSSLSession.java +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLImplementSSLSession.java @@ -214,6 +214,9 @@ public synchronized Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException { long x509; WolfSSLX509 cert; + CertificateFactory cf; + ByteArrayInputStream der; + X509Certificate exportCert; if (ssl == null) { throw new SSLPeerUnverifiedException("handshake not complete"); @@ -241,9 +244,6 @@ public synchronized Certificate[] getPeerCertificates() /* convert WolfSSLX509 into X509Certificate so we can release * our native memory */ - CertificateFactory cf; - ByteArrayInputStream der; - X509Certificate exportCert; try { cf = CertificateFactory.getInstance("X.509"); } catch (CertificateException ex) { diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLInternalVerifyCb.java b/src/java/com/wolfssl/provider/jsse/WolfSSLInternalVerifyCb.java index 7f4e03eb..0982755d 100644 --- a/src/java/com/wolfssl/provider/jsse/WolfSSLInternalVerifyCb.java +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLInternalVerifyCb.java @@ -1,3 +1,23 @@ +/* WolfSSLInternalVerifyCb.java + * + * Copyright (C) 2006-2021 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ package com.wolfssl.provider.jsse; import com.wolfssl.WolfSSL;