Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,16 @@ 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.

**jdk.tls.allowLegacyMasterSecret (boolean)** - Set to "false" to require the
Extended Master Secret (EMS) extension. A TLS 1.2 (or earlier) handshake that
does not negotiate EMS then fails instead of falling back to a legacy master
secret. TLS 1.3 is not affected. Default is "true". Only "true" and "false" are
accepted values - on other values handshakes will fail with an `SSLException`.
A "false" value is ignored when `jdk.tls.useExtendedMasterSecret` is "false".
Needs native wolfSSL 5.9.4 or later. With older versions, or when EMS is not
compiled in, setting it to "false" makes handshakes fail with an `SSLException`
when a protocol below TLS 1.3 can be negotiated, since EMS cannot be required.

**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
Expand Down
19 changes: 19 additions & 0 deletions native/com_wolfssl_WolfSSLSession.c
Original file line number Diff line number Diff line change
Expand Up @@ -6919,6 +6919,25 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_disableExtendedMasterSecr
#endif
}

JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_requireExtendedMasterSecret
(JNIEnv* jenv, jobject jcl, jlong sslPtr)
{
#if defined(HAVE_EXTENDED_MASTER) && !defined(WOLFSSL_NO_TLS12) && \
(LIBWOLFSSL_VERSION_HEX >= 0x05009004)
WOLFSSL* ssl = (WOLFSSL*)(uintptr_t)sslPtr;
(void)jenv;
(void)jcl;

/* Checks ssl for null internally */
return (jint)wolfSSL_RequireExtendedMasterSecret(ssl);
#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)
{
Expand Down
8 changes: 8 additions & 0 deletions native/com_wolfssl_WolfSSLSession.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions src/java/com/wolfssl/WolfSSLSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,7 @@ private native int useALPNByteArray(long ssl, byte[] protocols,
private native int useSupportedCurve(long ssl, int name);
private native int useKeyShare(long ssl, int group);
private native int disableExtendedMasterSecret(long ssl);
private native int requireExtendedMasterSecret(long ssl);
private native int hasTicket(long session);
private native int useClientSuites(long ssl);
private native int interruptBlockedIO(long ssl);
Expand Down Expand Up @@ -3000,6 +3001,28 @@ public int disableExtendedMasterSecret()
}
}

/**
* Require TLS Extended Master Secret (RFC 7627).
*
* A TLS 1.2 or earlier handshake that does not negotiate it fails with
* EXT_MASTER_SECRET_NEEDED_E. TLS 1.3 is not affected. Call before the
* handshake starts. Needs native wolfSSL 5.9.4 or later.
*
* @return <code>WolfSSL.SSL_SUCCESS</code> on success,
* <code>WolfSSL.NOT_COMPILED_IN</code> if native wolfSSL does not
* support it, otherwise negative on error.
* @throws IllegalStateException WolfSSLSession has been freed
*/
public int requireExtendedMasterSecret()
throws IllegalStateException {

confirmObjectIsActive();

synchronized (sslLock) {
return requireExtendedMasterSecret(this.sslPtr);
}
}

/* ---------------- Nonblocking DTLS helper functions -------------- */

/**
Expand Down
84 changes: 76 additions & 8 deletions src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,10 @@ public class WolfSSLEngineHelper {
private WolfSSLInternalVerifyCb wicb = null;

/* Effective enabled protocols for this session, computed by
* applyConfiguredCipherProtocolSettings() during session setup
* (after jdk.tls.disabledAlgorithms sanitization and cipher-suite-based
* protocol filtering). Read by isTLS13Enabled() for PQC named-group
* decisions. */
* applyConfiguredCipherProtocolSettings() during session setup (after
* jdk.tls.disabledAlgorithms sanitization and cipher-suite-based protocol
* filtering). Read by isTLS13Enabled() for PQC named-group decisions and
* by isPreTLS13Enabled() for the Extended Master Secret requirement. */
private String[] effectiveProtocols = null;

/* Cache of per-token native wolfSSL_set1_sigalgs_list() probe results,
Expand Down Expand Up @@ -1790,6 +1790,42 @@ private boolean isTLS13Enabled() {
return false;
}

/**
* Returns true if a protocol below (D)TLS 1.3, which derives a master
* secret, is part of the effective enabled protocols list for this
* session and compiled into native wolfSSL.
*/
private boolean isPreTLS13Enabled() {

String[] enabled = this.effectiveProtocols;
WolfSSL.TLS_VERSION ctxVersion = this.authStore.getProtocolVersion();

/* A (D)TLS 1.3-only context can never negotiate lower */
if (ctxVersion == WolfSSL.TLS_VERSION.TLSv1_3 ||
ctxVersion == WolfSSL.TLS_VERSION.DTLSv1_3) {
return false;
}

if (!WolfSSL.TLSv12Enabled() && !WolfSSL.TLSv11Enabled() &&
!WolfSSL.TLSv1Enabled()) {
return false;
}

if (enabled == null || enabled.length == 0) {
/* Effective protocol list not computed or empty, assume a
* protocol below TLS 1.3 can be negotiated */
return true;
}

for (String p : enabled) {
if (!"TLSv1.3".equals(p) && !"DTLSv1.3".equals(p)) {
return true;
}
}

return false;
}

private void setLocalMaximumPacketSize() {
/* Set maximum packet size, currently only makes a differnce if
* DTLS is enabled and used. Calling application will set this via
Expand Down Expand Up @@ -1821,12 +1857,19 @@ else if (ret == WolfSSL.NOT_COMPILED_IN) {
}
}

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. */
/**
* Set TLS Extended Master Secret behavior.
*
* Native wolfSSL enables TLS Extended Master Secret by default.
* jdk.tls.useExtendedMasterSecret=false disables it.
* jdk.tls.allowLegacyMasterSecret=false requires it, and is ignored
* when EMS is disabled.
*/
private void setLocalExtendedMasterSecret() throws SSLException {

int ret;
boolean useEMS = WolfSSLUtil.useExtendedMasterSecret();
boolean allowLegacy = WolfSSLUtil.allowLegacyMasterSecret();

if (!useEMS) {
ret = this.ssl.disableExtendedMasterSecret();
Expand All @@ -1840,6 +1883,31 @@ private void setLocalExtendedMasterSecret() {
() -> "Failed to disable TLS Extended Master Secret, " +
"ret = " + ret);
}
if (!allowLegacy) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
() -> "Ignoring jdk.tls.allowLegacyMasterSecret=false, " +
"TLS Extended Master Secret is disabled");
}
}
else if (!allowLegacy) {
/* Fail closed: do not fall back to a legacy master secret */
ret = this.ssl.requireExtendedMasterSecret();
if (ret == WolfSSL.SSL_SUCCESS) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
() -> "TLS Extended Master Secret required due to " +
"jdk.tls.allowLegacyMasterSecret System property");
}
else if (isPreTLS13Enabled()) {
throw new SSLException("Unable to require TLS Extended " +
"Master Secret (jdk.tls.allowLegacyMasterSecret=false), " +
"ret = " + ret);
}
else {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
() -> "Unable to require TLS Extended Master Secret " +
"(ret = " + ret + "), not needed since only (D)TLS 1.3 " +
"is enabled");
}
}
else {
if (WolfSSL.isEnabledTLSExtendedMasterSecret() == 1) {
Expand Down
30 changes: 30 additions & 0 deletions src/java/com/wolfssl/provider/jsse/WolfSSLUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import javax.net.ssl.SSLException;

import com.wolfssl.WolfSSL;
import com.wolfssl.WolfSSLCertificate;
Expand Down Expand Up @@ -581,6 +582,35 @@ protected static boolean useExtendedMasterSecret() {
return true;
}

/**
* Return if a legacy (non-Extended) TLS master secret is allowed, set
* by the following System property:
*
* jdk.tls.allowLegacyMasterSecret
*
* If property is not set (null), we default to allowing it. A set value
* must be "true" or "false" (case insensitive).
*
* @return false if the property is "false", true if it is "true" or not set
* @throws SSLException if the property is set to any other value
*/
protected static boolean allowLegacyMasterSecret() throws SSLException {

String allowLegacy =
System.getProperty("jdk.tls.allowLegacyMasterSecret");

if (allowLegacy == null || allowLegacy.equalsIgnoreCase("true")) {
return true;
}

if (allowLegacy.equalsIgnoreCase("false")) {
return false;
}

throw new SSLException("Value of jdk.tls.allowLegacyMasterSecret " +
"must be either 'true' or 'false'");
}

/**
* Check given KeyStore against any pre-defind requirements for
* KeyStore use, including the following.
Expand Down
Loading
Loading