Architecture: Java OpenJDK 21, Tomcat 10, Linux, x86 Architecture
Version: Lucee 7.0.4.34
Error:
cfimap tag throws SSLHandshakeException: No appropriate protocol when connecting to IMAPS (port 993) [eg: GMail]
Description
cfimap with secure=true on port 993 fails with SSLHandshakeException: No appropriate protocol on Java 21 x86 Linux.
The same Lucee build and Java version on ARM Ubuntu 24.04 does not exhibit the problem.
Using JavaMail Session API directly with mail.imaps.ssl.protocols explicitly set does work correctly.
Trace
javax.mail.MessagingException: No appropriate protocol
(protocol is disabled or cipher suites are inappropriate)
nested: javax.net.ssl.SSLHandshakeException: No appropriate protocol
at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:549)
at lucee.runtime.net.mail.MailClient.start(MailClient.java:296)
at lucee.runtime.tag._Mail.doStartTag(_Mail.java:259)
Caused by: javax.net.ssl.SSLHandshakeException: No appropriate protocol
at sun.security.ssl.HandshakeContext.(HandshakeContext.java:163)
Analysis
MailClient.start() in lucee.core (bundle47) constructs a new Properties() with no parent and never sets mail.imaps.ssl.protocols. This means:
- The
-Dmail.imaps.ssl.protocolsJVM system property has no effect (JVM system properties do not flow into a parentlessPropertiesobject). - Lucee admin mail server config has no field to set this value.
JavaMail’s SocketFetcher.configureSSLSocket() then calls SSLSocket.getEnabledProtocols().
On x86 OpenJDK 21 within the OSGi bundle classloader, this returns [TLSv1.3, TLSv1.2, TLSv1.1, TLSv1] — including protocols that are globally disabled by jdk.tls.disabledAlgorithms.
Passing this list to setEnabledProtocols() followed by startHandshake() causes the JVM to throw No appropriate protocol because TLSv1 and TLSv1.1 are disabled at the security policy level.
When mail.imaps.ssl.protocols=TLSv1.3 TLSv1.2 is present in the session Properties, SocketFetcher instead calls setEnabledProtocols([TLSv1.3, TLSv1.2]) and the handshake succeeds.
Platform note: On ARM Ubuntu 24.04 with the same OpenJDK 21.0.11 and identical jdk.tls.disabledAlgorithms, getEnabledProtocols() correctly returns only [TLSv1.3, TLSv1.2] (disabled protocols are already filtered at the socket level). The bug does not manifest there. This indicates an x86 vs ARM difference in how the JVM applies jdk.tls.disabledAlgorithms within an OSGi classloader context.
Steps to Reproduce
- Run Lucee 7.0.4.34 on Java 21 x86 Linux with
jdk.tls.disabledAlgorithmsincludingTLSv1, TLSv1.1(default on Ubuntu 24.04 / Debian Bookworm OpenJDK 21 packages). - Call
<cfimap action="getHeaderOnly" server="imap.gmail.com" port="993" secure="true" ...>. - Observe
SSLHandshakeException: No appropriate protocol.
Potential Fix
In lucee.runtime.net.mail.MailClient.start(), after constructing the session Properties, add:
if (props.getProperty("mail." + type + ".ssl.protocols") == null) {
props.setProperty("mail." + type + ".ssl.protocols", "TLSv1.3 TLSv1.2");
}
Where type resolves to imaps for secure IMAP connections. This mirrors what configureSSLSocket() would receive if the property were set, and avoids the JVM attempting to negotiate disabled protocol versions.
Alternatively, expose an sslProtocols attribute on <cfimap> or a corresponding Lucee admin mail server setting so administrators can configure this without modifying application code.