From b00f14ebbb136480865bcd0228f9e22a104bf99a Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Thu, 14 Nov 2024 17:39:04 -0700 Subject: [PATCH] JNI/JSSE: wrap wolfSSL_DisableExtendedMasterSecret(), add support for System property jdk.tls.useExtendedMasterSecret --- README.md | 5 +++ native/com_wolfssl_WolfSSL.c | 13 ++++++++ native/com_wolfssl_WolfSSL.h | 8 +++++ native/com_wolfssl_WolfSSLSession.c | 20 +++++++++++ native/com_wolfssl_WolfSSLSession.h | 8 +++++ src/java/com/wolfssl/WolfSSL.java | 8 +++++ src/java/com/wolfssl/WolfSSLSession.java | 18 ++++++++++ .../provider/jsse/WolfSSLEngineHelper.java | 33 +++++++++++++++++++ .../wolfssl/provider/jsse/WolfSSLUtil.java | 29 ++++++++++++++++ 9 files changed, 142 insertions(+) diff --git a/README.md b/README.md index d79076c..b178bf1 100644 --- a/README.md +++ b/README.md @@ -534,6 +534,11 @@ are enabled in different ways depending on the JDK implementation. For Oracle/OpenJDK and variants, this System property enables session tickets and was added in Java 13. Should be set to "true" to enable. +**jdk.tls.useExtendedMasterSecret (boolean)** - Can be used to enable or +disable the use of the Extended Master Secret (EMS) extension. This extension +is enabled by default, unless explicitly disabled by setting this property to +false. + **wolfjsse.autoSNI (boolean)** - Controls automatic Server Name Indication (SNI) extension setting based on hostname or peer address. When set to "true", enables legacy behavior where SNI is automatically configured from hostname/peer information diff --git a/native/com_wolfssl_WolfSSL.c b/native/com_wolfssl_WolfSSL.c index 4de663d..e5e3f5c 100644 --- a/native/com_wolfssl_WolfSSL.c +++ b/native/com_wolfssl_WolfSSL.c @@ -1995,6 +1995,19 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_isEnabledPKCallbacks #endif } +JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_isEnabledTLSExtendedMasterSecret + (JNIEnv* jenv, jclass jcl) +{ + (void)jenv; + (void)jcl; + +#if defined(HAVE_EXTENDED_MASTER) && !defined(NO_WOLFSSL_CLIENT) + return 1; +#else + return 0; +#endif +} + JNIEXPORT jobjectArray JNICALL Java_com_wolfssl_WolfSSL_getProtocols (JNIEnv* jenv, jclass jcl) { diff --git a/native/com_wolfssl_WolfSSL.h b/native/com_wolfssl_WolfSSL.h index a052493..427ff9d 100644 --- a/native/com_wolfssl_WolfSSL.h +++ b/native/com_wolfssl_WolfSSL.h @@ -1113,6 +1113,14 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_isEnabledAtomicUser JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_isEnabledPKCallbacks (JNIEnv *, jclass); +/* + * Class: com_wolfssl_WolfSSL + * Method: isEnabledTLSExtendedMasterSecret + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_isEnabledTLSExtendedMasterSecret + (JNIEnv *, jclass); + /* * Class: com_wolfssl_WolfSSL * Method: getProtocols diff --git a/native/com_wolfssl_WolfSSLSession.c b/native/com_wolfssl_WolfSSLSession.c index fac9ea7..86b0372 100644 --- a/native/com_wolfssl_WolfSSLSession.c +++ b/native/com_wolfssl_WolfSSLSession.c @@ -5765,6 +5765,26 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_useSupportedCurve #endif } +JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_disableExtendedMasterSecret + (JNIEnv* jenv, jobject jcl, jlong sslPtr) +{ +#if defined(HAVE_EXTENDED_MASTER) && !defined(NO_WOLFSSL_CLIENT) + int ret = 0; + WOLFSSL* ssl = (WOLFSSL*)(uintptr_t)sslPtr; + (void)jcl; + + /* Checks ssl for null internally */ + ret = wolfSSL_DisableExtendedMasterSecret(ssl); + + return (jint)ret; +#else + (void)jenv; + (void)jcl; + (void)sslPtr; + return (jint)NOT_COMPILED_IN; +#endif +} + JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_hasTicket (JNIEnv* jenv, jobject jcl, jlong sessionPtr) { diff --git a/native/com_wolfssl_WolfSSLSession.h b/native/com_wolfssl_WolfSSLSession.h index 7c7e8eb..0e9abec 100644 --- a/native/com_wolfssl_WolfSSLSession.h +++ b/native/com_wolfssl_WolfSSLSession.h @@ -887,6 +887,14 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_set1SigAlgsList JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_useSupportedCurve (JNIEnv *, jobject, jlong, jint); +/* + * Class: com_wolfssl_WolfSSLSession + * Method: disableExtendedMasterSecret + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_disableExtendedMasterSecret + (JNIEnv *, jobject, jlong); + /* * Class: com_wolfssl_WolfSSLSession * Method: hasTicket diff --git a/src/java/com/wolfssl/WolfSSL.java b/src/java/com/wolfssl/WolfSSL.java index 7f76971..6f6140c 100644 --- a/src/java/com/wolfssl/WolfSSL.java +++ b/src/java/com/wolfssl/WolfSSL.java @@ -1662,6 +1662,14 @@ public class WolfSSL { */ public static native int isEnabledPKCallbacks(); + /** + * Checks if TLS Extended Master Secret support has been compiled into + * native wolfSSL library. + * + * @return 1 if available, 0 if not compiled in. + */ + public static native int isEnabledTLSExtendedMasterSecret(); + /** * Checks which protocols where built into wolfSSL * diff --git a/src/java/com/wolfssl/WolfSSLSession.java b/src/java/com/wolfssl/WolfSSLSession.java index 22f1ed0..e075d97 100644 --- a/src/java/com/wolfssl/WolfSSLSession.java +++ b/src/java/com/wolfssl/WolfSSLSession.java @@ -418,6 +418,7 @@ public class WolfSSLSession { private native int rehandshake(long ssl); private native int set1SigAlgsList(long ssl, String list); private native int useSupportedCurve(long ssl, int name); + private native int disableExtendedMasterSecret(long ssl); private native int hasTicket(long session); private native int interruptBlockedIO(long ssl); private native int getThreadsBlockedInPoll(long ssl); @@ -2241,6 +2242,23 @@ public class WolfSSLSession { return ret; } + /** + * Disable TLS Extended Master Secret usage. + * + * @return WolfSSL.SSL_SUCCESS on success, otherwise + * negative on error. + * @throws IllegalStateException WolfSSLSession has been freed + */ + public int disableExtendedMasterSecret() + throws IllegalStateException { + + confirmObjectIsActive(); + + synchronized (sslLock) { + return disableExtendedMasterSecret(this.sslPtr); + } + } + /* ---------------- Nonblocking DTLS helper functions -------------- */ /** diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java b/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java index d6fab69..cff3424 100644 --- a/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java @@ -1176,6 +1176,38 @@ public class WolfSSLEngineHelper { } } + private void setLocalExtendedMasterSecret() { + /* Native wolfSSL enables TLS Extended Master Secret by default. + * Check the Java System property (jdk.tls.useExtendedMasterSecret) + * to see if the user has explicitly disabled it. */ + int ret; + boolean useEMS = WolfSSLUtil.useExtendedMasterSecret(); + + if (!useEMS) { + ret = this.ssl.disableExtendedMasterSecret(); + if (ret == WolfSSL.SSL_SUCCESS) { + WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO, + "TLS Extended Master Secret disabled due to " + + "jdk.tls.useExtendedMasterSecret System property"); + } + else { + WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO, + "Failed to disable TLS Extended Master Secret, " + + "ret = " + ret); + } + } + else { + if (WolfSSL.isEnabledTLSExtendedMasterSecret() == 1) { + WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO, + "using TLS Extended Master Secret"); + } + else { + WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO, + "not using TLS Extended Master Secret, not compiled in"); + } + } + } + private void setLocalParams(SSLSocket socket, SSLEngine engine) throws SSLException { @@ -1192,6 +1224,7 @@ public class WolfSSLEngineHelper { this.setLocalSigAlgorithms(); this.setLocalSupportedCurves(); this.setLocalMaximumPacketSize(); + this.setLocalExtendedMasterSecret(); } /** diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLUtil.java b/src/java/com/wolfssl/provider/jsse/WolfSSLUtil.java index c2c9805..c60a888 100644 --- a/src/java/com/wolfssl/provider/jsse/WolfSSLUtil.java +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLUtil.java @@ -286,6 +286,35 @@ public class WolfSSLUtil { return false; } + /** + * Return if TLS Extended Master Secret support has been enabled or + * disabled via the following System property: + * + * jdk.tls.useExtendedMasterSecret + * + * If property is not set (null) or an empty string, we default to + * leaving TLS Extended Master Secret enabled. + * + * @return true if enabled, otherwise false + */ + protected static boolean useExtendedMasterSecret() { + + String useEMS = + System.getProperty("jdk.tls.useExtendedMasterSecret"); + + /* Native wolfSSL defaults to having extended master secret support + * enabled. Do the same here if property not set or empty. */ + if (useEMS == null || useEMS.isEmpty()) { + return true; + } + + if (useEMS.equalsIgnoreCase("false")) { + return false; + } + + return true; + } + /** * Check given KeyStore against any pre-defind requirements for * KeyStore use, including the following.