diff --git a/native/com_wolfssl_WolfSSLContext.c b/native/com_wolfssl_WolfSSLContext.c index b0a3faf..75f5f7f 100644 --- a/native/com_wolfssl_WolfSSLContext.c +++ b/native/com_wolfssl_WolfSSLContext.c @@ -804,7 +804,7 @@ int NativeVerifyCallback(int preverify_ok, WOLFSSL_X509_STORE_CTX* store) { JNIEnv* jenv; jint vmret = 0; - jint retval = -1; + jint retval = 0; int needsDetach = 0; jclass excClass = NULL; jclass verifyClass = NULL; @@ -828,11 +828,11 @@ int NativeVerifyCallback(int preverify_ok, WOLFSSL_X509_STORE_CTX* store) vmret = (*g_vm)->AttachCurrentThread(g_vm, (void**) &jenv, NULL); #endif if (vmret) { - return -101; /* failed to attach JNIEnv to thread */ + return 0; /* failed to attach JNIEnv to thread */ } needsDetach = 1; } else if (vmret != JNI_OK) { - return -102; /* unable to get JNIEnv from JavaVM */ + return 0; /* unable to get JNIEnv from JavaVM */ } /* find exception class */ @@ -843,7 +843,7 @@ int NativeVerifyCallback(int preverify_ok, WOLFSSL_X509_STORE_CTX* store) freeNativeVerifyCbLocalRefs(jenv, excClass, verifyClass, verifyCbObj); if (needsDetach) (*g_vm)->DetachCurrentThread(g_vm); - return -103; + return 0; } /* Locate the per-context verify callback jobject via @@ -896,7 +896,7 @@ int NativeVerifyCallback(int preverify_ok, WOLFSSL_X509_STORE_CTX* store) verifyCbObj); if (needsDetach) (*g_vm)->DetachCurrentThread(g_vm); - return -104; + return 0; } verifyMethod = (*jenv)->GetMethodID(jenv, verifyClass, @@ -913,7 +913,7 @@ int NativeVerifyCallback(int preverify_ok, WOLFSSL_X509_STORE_CTX* store) verifyCbObj); if (needsDetach) (*g_vm)->DetachCurrentThread(g_vm); - return -105; + return 0; } retval = (*jenv)->CallIntMethod(jenv, verifyCbObj, @@ -927,7 +927,7 @@ int NativeVerifyCallback(int preverify_ok, WOLFSSL_X509_STORE_CTX* store) verifyCbObj); if (needsDetach) (*g_vm)->DetachCurrentThread(g_vm); - return -106; + return 0; } } else { @@ -941,14 +941,19 @@ int NativeVerifyCallback(int preverify_ok, WOLFSSL_X509_STORE_CTX* store) freeNativeVerifyCbLocalRefs(jenv, excClass, verifyClass, verifyCbObj); if (needsDetach) (*g_vm)->DetachCurrentThread(g_vm); - return -1; + return 0; } freeNativeVerifyCbLocalRefs(jenv, excClass, verifyClass, verifyCbObj); if (needsDetach) (*g_vm)->DetachCurrentThread(g_vm); - return retval; + /* Accept only on an explicit callback success (1), reject otherwise. */ + if (retval == 1) { + return 1; + } + + return 0; } JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLContext_setOptions diff --git a/native/com_wolfssl_WolfSSLSession.c b/native/com_wolfssl_WolfSSLSession.c index 8d26e12..322723e 100644 --- a/native/com_wolfssl_WolfSSLSession.c +++ b/native/com_wolfssl_WolfSSLSession.c @@ -107,7 +107,7 @@ int NativeSSLVerifyCallback(int preverify_ok, WOLFSSL_X509_STORE_CTX* store) { JNIEnv* jenv; jint vmret = 0; - jint retval = -1; + jint retval = 0; int needsDetach = 0; jobjectRefType refcheck; SSLAppData* appData; /* WOLFSSL app data, stored verify cb obj */ @@ -128,11 +128,11 @@ int NativeSSLVerifyCallback(int preverify_ok, WOLFSSL_X509_STORE_CTX* store) vmret = (*g_vm)->AttachCurrentThread(g_vm, (void**) &jenv, NULL); #endif if (vmret) { - return -101; /* failed to attach JNIEnv to thread */ + return 0; /* failed to attach JNIEnv to thread */ } needsDetach = 1; } else if (vmret != JNI_OK) { - return -102; /* unable to get JNIEnv from JavaVM */ + return 0; /* unable to get JNIEnv from JavaVM */ } /* get app data to retrieve stored Java jobject callback object */ @@ -143,7 +143,7 @@ int NativeSSLVerifyCallback(int preverify_ok, WOLFSSL_X509_STORE_CTX* store) if (needsDetach) { (*g_vm)->DetachCurrentThread(g_vm); } - return -105; + return 0; } /* Promote stored global callback ref to a local ref under g_verifyCbMutex @@ -161,7 +161,7 @@ int NativeSSLVerifyCallback(int preverify_ok, WOLFSSL_X509_STORE_CTX* store) if (needsDetach) { (*g_vm)->DetachCurrentThread(g_vm); } - return -106; + return 0; } /* valid ref check: non-zero type covers local/global/weak, and verifyCbObj @@ -180,7 +180,7 @@ int NativeSSLVerifyCallback(int preverify_ok, WOLFSSL_X509_STORE_CTX* store) if (needsDetach) { (*g_vm)->DetachCurrentThread(g_vm); } - return -107; + return 0; } retval = (*jenv)->CallIntMethod(jenv, verifyCbObj, @@ -194,7 +194,7 @@ int NativeSSLVerifyCallback(int preverify_ok, WOLFSSL_X509_STORE_CTX* store) (*jenv)->DeleteLocalRef(jenv, verifyCbObj); if (needsDetach) (*g_vm)->DetachCurrentThread(g_vm); - return -109; + return 0; } } else { @@ -208,7 +208,7 @@ int NativeSSLVerifyCallback(int preverify_ok, WOLFSSL_X509_STORE_CTX* store) (*jenv)->DeleteLocalRef(jenv, verifyCbObj); if (needsDetach) (*g_vm)->DetachCurrentThread(g_vm); - return -1; + return 0; } (*jenv)->DeleteLocalRef(jenv, verifyCbObj); @@ -216,7 +216,12 @@ int NativeSSLVerifyCallback(int preverify_ok, WOLFSSL_X509_STORE_CTX* store) if (needsDetach) (*g_vm)->DetachCurrentThread(g_vm); - return retval; + /* Accept only on an explicit callback success (1), reject otherwise. */ + if (retval == 1) { + return 1; + } + + return 0; } #ifndef USE_WINDOWS_API diff --git a/src/java/com/wolfssl/WolfSSLVerifyCallback.java b/src/java/com/wolfssl/WolfSSLVerifyCallback.java index fd247b2..2c00f7e 100644 --- a/src/java/com/wolfssl/WolfSSLVerifyCallback.java +++ b/src/java/com/wolfssl/WolfSSLVerifyCallback.java @@ -27,7 +27,7 @@ package com.wolfssl; * callback class to be used by wolfSSL during the handshake process. *
* After implementing this interface, it should be passed as a parameter
- * to the {@link WolfSSLContext#setVerify(long, int, WolfSSLVerifyCallback)
+ * to the {@link WolfSSLContext#setVerify(int, WolfSSLVerifyCallback)
* WolfSSLContext.setVerify()} method to be registered with the native wolfSSL
* library.
*
@@ -45,10 +45,9 @@ public interface WolfSSLVerifyCallback {
* already passed. 0 if failed, 1 if passed.
* @param x509StorePtr pointer to the context used for certificate
* chain verification.
- * @return 0 if the verification process should
- * stop immediately with an error. 1 if
- * the verification process should continue with the
- * rest of the handshake.
+ * @return 1 to accept and continue the handshake.
+ * Any other return value or exception thrown is
+ * treated as verification failure and aborts handshake.
*/
public int verifyCallback(int preverify_ok, long x509StorePtr);
diff --git a/src/test/com/wolfssl/test/WolfSSLSessionTest.java b/src/test/com/wolfssl/test/WolfSSLSessionTest.java
index 2cb4eb7..fcad33a 100644
--- a/src/test/com/wolfssl/test/WolfSSLSessionTest.java
+++ b/src/test/com/wolfssl/test/WolfSSLSessionTest.java
@@ -721,6 +721,202 @@ public class WolfSSLSessionTest {
}
}
+ /* Accept one TLS connection on a background thread. A server-side
+ * handshake failure is expected once the client rejects the cert. */
+ private Future