diff --git a/native/com_wolfssl_WolfSSLSession.c b/native/com_wolfssl_WolfSSLSession.c index 70028a92..915aa653 100644 --- a/native/com_wolfssl_WolfSSLSession.c +++ b/native/com_wolfssl_WolfSSLSession.c @@ -4221,33 +4221,47 @@ JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_WolfSSLSession_sslGet0AlpnSelected } JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_useALPN - (JNIEnv* jenv, jobject jcl, jlong ssl, jstring protocols, jint options) + (JNIEnv* jenv, jobject jcl, jlong sslPtr, jstring protocols, jint options) { int ret = SSL_FAILURE; #ifdef HAVE_ALPN - const char* protoList; + WOLFSSL* ssl = (WOLFSSL*)(uintptr_t)sslPtr; + char* protoList = NULL; + jsize protocolsLen = 0; (void)jcl; if (jenv == NULL || ssl == 0 || protocols == NULL || options < 0) { return BAD_FUNC_ARG; } - protoList = (*jenv)->GetStringUTFChars(jenv, protocols, 0); + protocolsLen = (*jenv)->GetStringUTFLength(jenv, protocols); + if (protocolsLen == 0) { + return BAD_FUNC_ARG; + } + + /* Allocate size + 1 to guarantee we are null terminated */ + protoList = (char*)XMALLOC(protocolsLen + 1, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (protoList == NULL) { + return MEMORY_E; + } - ret = (jint) wolfSSL_UseALPN((WOLFSSL*)(uintptr_t)ssl, (char*)protoList, - (unsigned int)XSTRLEN(protoList), (int)options); + /* GetStringUTFRegion() does not need to be freed/released */ + (*jenv)->GetStringUTFRegion(jenv, protocols, 0, protocolsLen, protoList); + protoList[protocolsLen] = '\0'; - (*jenv)->ReleaseStringUTFChars(jenv, protocols, protoList); + ret = wolfSSL_UseALPN(ssl, protoList, protocolsLen, (int)options); + + XFREE(protoList, NULL, DYNAMIC_TYPE_TMP_BUFFER); #else (void)jenv; (void)jcl; - (void)ssl; + (void)sslPtr; (void)protocols; (void)options; ret = NOT_COMPILED_IN; #endif - return ret; + return (jint)ret; } JNIEXPORT int JNICALL Java_com_wolfssl_WolfSSLSession_setALPNSelectCb diff --git a/src/java/com/wolfssl/WolfSSLSession.java b/src/java/com/wolfssl/WolfSSLSession.java index 3ecc4854..3606fb61 100644 --- a/src/java/com/wolfssl/WolfSSLSession.java +++ b/src/java/com/wolfssl/WolfSSLSession.java @@ -1165,6 +1165,8 @@ public synchronized void freeSSL() /* free Java resources */ this.active = false; this.sslPtr = 0; + this.clientSNIRequested = null; + this.ctx = null; } } } diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java b/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java index 497cac08..9109fa67 100644 --- a/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java @@ -1395,6 +1395,13 @@ protected synchronized int saveSession() { return WolfSSL.SSL_FAILURE; } + protected synchronized void clearObjectState() { + this.ssl = null; + this.session = null; + this.params = null; + this.authStore = null; + } + @SuppressWarnings("deprecation") @Override protected synchronized void finalize() throws Throwable { diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLInternalVerifyCb.java b/src/java/com/wolfssl/provider/jsse/WolfSSLInternalVerifyCb.java index d5cd6131..f0fae971 100644 --- a/src/java/com/wolfssl/provider/jsse/WolfSSLInternalVerifyCb.java +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLInternalVerifyCb.java @@ -359,15 +359,5 @@ else if ((preverify_ok == 1) && (x509certs.length == 0) && /* Continue handshake, verification succeeded */ return 1; } - - @SuppressWarnings("deprecation") - @Override - protected void finalize() throws Throwable { - this.callingSocket = null; - this.callingEngine = null; - this.tm = null; - this.params = null; - super.finalize(); - } } diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLServerSocket.java b/src/java/com/wolfssl/provider/jsse/WolfSSLServerSocket.java index f2ee750b..5639c72f 100644 --- a/src/java/com/wolfssl/provider/jsse/WolfSSLServerSocket.java +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLServerSocket.java @@ -375,5 +375,13 @@ synchronized public Socket accept() throws IOException { return socket; } + + @Override + public synchronized void close() throws IOException { + if (this.socket != null) { + this.socket.close(); + } + super.close(); + } } diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLSocket.java b/src/java/com/wolfssl/provider/jsse/WolfSSLSocket.java index c93e22aa..1f83442b 100644 --- a/src/java/com/wolfssl/provider/jsse/WolfSSLSocket.java +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLSocket.java @@ -1890,6 +1890,9 @@ public synchronized void close() throws IOException { this.connectionClosed = true; + /* Release native verify callback (JNI global) */ + this.EngineHelper.unsetVerifyCallback(); + /* Connection is closed, free native WOLFSSL session * to release native memory earlier than garbage * collector might with finalize(). */ @@ -1905,6 +1908,21 @@ public synchronized void close() throws IOException { "calling this.ssl.freeSSL()"); this.ssl.freeSSL(); this.ssl = null; + + /* Reset internal WolfSSLEngineHelper to null */ + this.EngineHelper.clearObjectState(); + this.EngineHelper = null; + + /* Release Input/OutputStream objects */ + if (this.inStream != null) { + this.inStream.close(); + this.inStream = null; + } + if (this.outStream != null) { + this.outStream.close(); + this.outStream = null; + } + } /* handshakeLock */ WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO, @@ -2066,6 +2084,8 @@ protected synchronized void finalize() throws Throwable { } this.ssl.freeSSL(); this.ssl = null; + this.EngineHelper = null; + this.params = null; } super.finalize(); } @@ -2326,13 +2346,20 @@ class WolfSSLInputStream extends InputStream { private WolfSSLSession ssl; private WolfSSLSocket socket; + private boolean isClosed = true; public WolfSSLInputStream(WolfSSLSession ssl, WolfSSLSocket socket) { this.ssl = ssl; this.socket = socket; /* parent socket */ + this.isClosed = false; } public synchronized void close() throws IOException { + + if (this.socket == null || this.isClosed) { + return; + } + if (this.socket.isClosed()) { WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO, "socket (input) already closed"); @@ -2343,6 +2370,10 @@ public synchronized void close() throws IOException { "socket (input) closed: " + this.socket); } + this.socket = null; + this.ssl = null; + this.isClosed = true; + return; } @@ -2381,7 +2412,7 @@ public synchronized int read(byte[] b, int off, int len) } /* check if socket is closed */ - if (socket.isClosed()) { + if (this.isClosed || socket == null || socket.isClosed()) { throw new SocketException("Socket is closed"); } @@ -2470,13 +2501,20 @@ class WolfSSLOutputStream extends OutputStream { private WolfSSLSession ssl; private WolfSSLSocket socket; + private boolean isClosed = true; public WolfSSLOutputStream(WolfSSLSession ssl, WolfSSLSocket socket) { this.ssl = ssl; this.socket = socket; /* parent socket */ + this.isClosed = false; } public synchronized void close() throws IOException { + + if (this.socket == null || this.isClosed) { + return; + } + if (this.socket.isClosed()) { WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO, "socket (output) already closed"); @@ -2487,6 +2525,10 @@ public synchronized void close() throws IOException { "socket (output) closed: " + this.socket); } + this.socket = null; + this.ssl = null; + this.isClosed = true; + return; } @@ -2510,6 +2552,10 @@ public synchronized void write(byte[] b, int off, int len) throw new NullPointerException("Input array is null"); } + if (this.socket == null || this.isClosed) { + throw new SocketException("Socket is closed"); + } + /* check if connection has already been closed/shutdown */ WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO, "trying to get socket.handshakeLock (write)");