Skip to content

Commit 115e93a

Browse files
committed
JSSE: unset native verify callback when SSLEngine is finished, allows garbage collection
1 parent a7031b3 commit 115e93a

3 files changed

Lines changed: 71 additions & 3 deletions

File tree

src/java/com/wolfssl/provider/jsse/WolfSSLEngine.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,12 @@ public synchronized SSLEngineResult wrap(ByteBuffer[] in, int ofst, int len,
606606
*/
607607
if (produced >= 0 &&
608608
(!outBoundOpen || (!inBoundOpen && this.closeNotifySent))) {
609+
/* Mark SSLEngine status as CLOSED */
609610
status = SSLEngineResult.Status.CLOSED;
611+
/* Handshake has finished and SSLEngine is closed, release
612+
* global JNI verify callback pointer */
613+
this.EngineHelper.unsetVerifyCallback();
614+
610615
try {
611616
ClosingConnection();
612617
} catch (SocketException e) {
@@ -962,7 +967,11 @@ else if (hs == SSLEngineResult.HandshakeStatus.NEED_WRAP &&
962967
if (outBoundOpen == false) {
963968
try {
964969
if (ClosingConnection() == WolfSSL.SSL_SUCCESS) {
970+
/* Mark SSLEngine status as CLOSED */
965971
status = SSLEngineResult.Status.CLOSED;
972+
/* Handshake has finished and SSLEngine is closed,
973+
* release, global JNI verify callback pointer */
974+
this.EngineHelper.unsetVerifyCallback();
966975
}
967976
} catch (SocketException e) {
968977
throw new SSLException(e);
@@ -1030,7 +1039,11 @@ else if (hs == SSLEngineResult.HandshakeStatus.NEED_WRAP &&
10301039
}
10311040

10321041
if (outBoundOpen == false || this.closeNotifySent) {
1042+
/* Mark SSLEngine status as CLOSED */
10331043
status = SSLEngineResult.Status.CLOSED;
1044+
/* Handshake has finished and SSLEngine is closed,
1045+
* release, global JNI verify callback pointer */
1046+
this.EngineHelper.unsetVerifyCallback();
10341047
}
10351048

10361049
int err = ssl.getError(ret);
@@ -1773,7 +1786,7 @@ protected synchronized void finalize() throws Throwable {
17731786
this.ssl.freeSSL();
17741787
this.ssl = null;
17751788
}
1776-
EngineHelper = null;
1789+
this.EngineHelper = null;
17771790
super.finalize();
17781791
}
17791792
}

src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ public class WolfSSLEngineHelper {
8787
/* Has setUseClientMode() been called on this object */
8888
private boolean modeSet = false;
8989

90+
/* wolfSSL verification mode, set inside setLocalAuth() */
91+
private int verifyMask = WolfSSL.SSL_VERIFY_PEER;
92+
9093
/* Internal Java verify callback, used when user/app is not using
9194
* com.wolfssl.provider.jsse.WolfSSLTrustX509 and instead using their
9295
* own TrustManager to perform verification via checkClientTrusted()
@@ -805,7 +808,7 @@ private void setLocalAuth(SSLSocket socket, SSLEngine engine) {
805808
* Algorithm has been set. To get this callback to be called,
806809
* native wolfSSL should be compiled with the following define:
807810
* WOLFSSL_ALWAYS_VERIFY_CB */
808-
this.ssl.setVerify(mask, wicb);
811+
this.verifyMask = mask;
809812

810813
} else {
811814
/* not our own TrustManager, set up callback so JSSE can use
@@ -814,8 +817,10 @@ private void setLocalAuth(SSLSocket socket, SSLEngine engine) {
814817
"X509TrustManager is not of type WolfSSLTrustX509");
815818
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
816819
"Using checkClientTrusted/ServerTrusted() for verification");
817-
this.ssl.setVerify(WolfSSL.SSL_VERIFY_PEER, wicb);
820+
this.verifyMask = WolfSSL.SSL_VERIFY_PEER;
818821
}
822+
823+
this.ssl.setVerify(this.verifyMask, wicb);
819824
}
820825

821826

@@ -1330,6 +1335,35 @@ else if (peerAddr != null) {
13301335
return ret;
13311336
}
13321337

1338+
/**
1339+
* Unset the native verify callback and reset internal verify
1340+
* callback state.
1341+
*
1342+
* This helper method is called by SSLEngine to reset the native
1343+
* wolfSSL verify callback back to null. Since a pointer to that verify
1344+
* callback is stored as a global JNI variable, it can prevent garbage
1345+
* collection from being done. This helper can be called when an SSLEngine
1346+
* or SSLSocket is closed/done to reset the verify callback.
1347+
*
1348+
* The verify callback will be set again if needed when
1349+
* initHandshake() is called.
1350+
*/
1351+
protected synchronized void unsetVerifyCallback() {
1352+
/* Set native callback to null, releases JNI global and allows for
1353+
* garbage collection if needed */
1354+
if (this.ssl != null) {
1355+
this.ssl.setVerify(this.verifyMask, null);
1356+
}
1357+
1358+
/* Reset internal state of WolfSSLInternalVerifyCallback, removes
1359+
* references to SSLSocket/SSLEngine to allow garbage collection if
1360+
* needed */
1361+
if (this.wicb != null) {
1362+
this.wicb.clearInternalVars();
1363+
this.wicb = null;
1364+
}
1365+
}
1366+
13331367
/**
13341368
* Saves session on connection close for resumption
13351369
*
@@ -1357,6 +1391,7 @@ protected synchronized void finalize() throws Throwable {
13571391
* may be used by wrapper object to WolfSSLEngineHelper and should
13581392
* be freed there */
13591393
this.ssl = null;
1394+
this.wicb = null;
13601395

13611396
this.session = null;
13621397
this.params = null;

src/java/com/wolfssl/provider/jsse/WolfSSLInternalVerifyCb.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,16 @@ public WolfSSLInternalVerifyCb(X509TrustManager xtm, boolean client,
6868
this.params = params;
6969
}
7070

71+
/**
72+
* Reset internal variables back to null/default.
73+
*/
74+
protected void clearInternalVars() {
75+
this.callingSocket = null;
76+
this.callingEngine = null;
77+
this.params = null;
78+
this.tm = null;
79+
}
80+
7181
/**
7282
* Verify hostname of provided peer certificate using
7383
* Endpoint Identification Algorithm if set in SSLParameters.
@@ -349,5 +359,15 @@ else if ((preverify_ok == 1) && (x509certs.length == 0) &&
349359
/* Continue handshake, verification succeeded */
350360
return 1;
351361
}
362+
363+
@SuppressWarnings("deprecation")
364+
@Override
365+
protected void finalize() throws Throwable {
366+
this.callingSocket = null;
367+
this.callingEngine = null;
368+
this.tm = null;
369+
this.params = null;
370+
super.finalize();
371+
}
352372
}
353373

0 commit comments

Comments
 (0)