spring-boot: Using https with elliptic curves other than secp384r1 fails
Unable to use Elliptic Curve Self Signed Certificate in Spring boot
First Environment Details
JDK 17 Spring Boot 3.0.2 Spring Web Tomcat (inbuilt) Mac OS 13.x
Second Environment Details
JDK 17 Spring Boot 3.0.2 Spring Webflux Netty (inbuilt) Mac OS 13.x
Third Environment Details
JDK 17 Spring Boot 2.7.8 Spring Web Tomcat (inbuilt) Mac OS 13.x
For tomcat server I get below error:-
java.io.IOException: EOF during handshake.
at org.apache.tomcat.util.net.SecureNioChannel.handshakeUnwrap(SecureNioChannel.java:470) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
at org.apache.tomcat.util.net.SecureNioChannel.handshake(SecureNioChannel.java:213) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1709) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
2023-02-19T16:25:08.523+05:30 DEBUG 43160 --- [nio-8443-exec-5] o.apache.coyote.http11.Http11Processor : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@5e2b7fa0:org.apache.tomcat.util.net.SecureNioChannel@27f27fb1:java.nio.channels.SocketChannel[connected local=/[0:0:0:0:0:0:0:1]:8443 remote=/[0:0:0:0:0:0:0:1]:55280]], Status in: [CONNECT_FAIL], State out: [CLOSED]
2023-02-19T16:25:08.523+05:30 DEBUG 43160 --- [nio-8443-exec-5] o.apache.tomcat.util.threads.LimitLatch : Counting down[https-jsse-nio-8443-exec-5] latch=1
2023-02-19T16:25:08.523+05:30 DEBUG 43160 --- [nio-8443-exec-5] org.apache.tomcat.util.net.NioEndpoint : Calling [org.apache.tomcat.util.net.NioEndpoint@3f6fedae].closeSocket([org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@5e2b7fa0:org.apache.tomcat.util.net.SecureNioChannel@27f27fb1:java.nio.channels.SocketChannel[connected local=/[0:0:0:0:0:0:0:1]:8443 remote=/[0:0:0:0:0:0:0:1]:55280]])
2023-02-19T16:25:08.524+05:30 ERROR 43160 --- [nio-8443-exec-5] org.apache.tomcat.util.net.NioEndpoint : Failed to close channel
java.io.IOException: Invalid close state, will not send network data.
at org.apache.tomcat.util.net.SecureNioChannel.close(SecureNioChannel.java:540) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
at org.apache.tomcat.util.net.SecureNioChannel.close(SecureNioChannel.java:555) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.doClose(NioEndpoint.java:1208) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
at org.apache.tomcat.util.net.SocketWrapperBase.close(SocketWrapperBase.java:425) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-10.1.5.jar:10.1.5]
at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
For netty it is slightly different but almost same
ava.nio.channels.ClosedChannelException: null
at io.netty.handler.ssl.SslHandler.channelInactive(SslHandler.java:1065) ~[netty-handler-4.1.87.Final.jar:4.1.87.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:305) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final]
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1405) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:301) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:901) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final]
at io.netty.channel.AbstractChannel$AbstractUnsafe$7.run(AbstractChannel.java:813) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final]
at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174) ~[netty-common-4.1.87.Final.jar:4.1.87.Final]
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167) ~[netty-common-4.1.87.Final.jar:4.1.87.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470) ~[netty-common-4.1.87.Final.jar:4.1.87.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:566) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[netty-common-4.1.87.Final.jar:4.1.87.Final]
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.87.Final.jar:4.1.87.Final]
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.87.Final.jar:4.1.87.Final]
at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
2023-02-19T18:17:29.840+05:30 DEBUG 45870 --- [ctor-http-nio-3] r.netty.transport.ServerTransport : [2dbfdbf8, L:/[0:0:0:0:0:0:0:1]:8443 ! R:/[0:0:0:0:0:0:0:1]:56166] onUncaughtException(SimpleConnection{channel=[id: 0x2dbfdbf8, L:/[0:0:0:0:0:0:0:1]:8443 ! R:/[0:0:0:0:0:0:0:1]:56166]})
java.nio.channels.ClosedChannelException: null
at io.netty.handler.ssl.SslHandler.channelInactive(SslHandler.java:1065) ~[netty-handler-4.1.87.Final.jar:4.1.87.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:305) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final]
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1405) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:301) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:901) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final]
at io.netty.channel.AbstractChannel$AbstractUnsafe$7.run(AbstractChannel.java:813) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final]
at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174) ~[netty-common-4.1.87.Final.jar:4.1.87.Final]
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167) ~[netty-common-4.1.87.Final.jar:4.1.87.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470) ~[netty-common-4.1.87.Final.jar:4.1.87.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:566) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[netty-common-4.1.87.Final.jar:4.1.87.Final]
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.87.Final.jar:4.1.87.Final]
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.87.Final.jar:4.1.87.Final]
at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
spring boot application properties
server.ssl.enabled=true
server.port=8443
server.ssl.certificate=/path-to/cert.pem
server.ssl.certificate-private-key=/path-to/private-key.pem
steps to generate self signed cert were as below:-
openssl ecparam -name prime256v1 -genkey -noout -out private-key.pem
openssl ec -in private-key.pem -pubout -out public-key.pem
openssl req -new -x509 -key private-key.pem -out cert.pem -days 360
Example cert and key files are below:-
cert:-
-----BEGIN CERTIFICATE-----
MIIB5zCCAYwCCQDIZlhtOQc80jAKBggqhkjOPQQDAjB7MQswCQYDVQQGEwJJTjEL
MAkGA1UECAwCUEIxDzANBgNVBAcMBk1PSEFMSTENMAsGA1UECgwETmV1dzENMAsG
A1UECwwETmV1dzESMBAGA1UEAwwJbG9jYWxob3N0MRwwGgYJKoZIhvcNAQkBFg10
ZXN0QHRlc3QuY29tMB4XDTIzMDIxOTA5MjM0M1oXDTI0MDIxOTA5MjM0M1owezEL
MAkGA1UEBhMCSU4xCzAJBgNVBAgMAlBCMQ8wDQYDVQQHDAZNT0hBTEkxDTALBgNV
BAoMBE5ldXcxDTALBgNVBAsMBE5ldXcxEjAQBgNVBAMMCWxvY2FsaG9zdDEcMBoG
CSqGSIb3DQEJARYNdGVzdEB0ZXN0LmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEH
A0IABITJYdvCvlkdu+IyVISe+KqoplP1A8f26hpKecqxkS5U2VDd8JaqhsPWlC/Y
bLbBAg6DibTEWMTK8Ab5+aE/ZgIwCgYIKoZIzj0EAwIDSQAwRgIhANS1nxKGXevL
i9jkaXZiFh5IZ2DMTDwQ5ETduj7X/ZMaAiEAntNWKb+SF299sxA5Hv6i0oYK1Gl6
nh82yO5SqCvjECk=
-----END CERTIFICATE-----
key:-
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIDsXD9BbsGGOnFjbMCDIXjGPI4rqDKGqlRUH4oiWxOjboAoGCCqGSM49
AwEHoUQDQgAEhMlh28K+WR274jJUhJ74qqimU/UDx/bqGkp5yrGRLlTZN3wlqqG
w9aUL9hstsECDoOJtMRYxMrwBvn5oT9mAg==
-----END EC PRIVATE KEY-----
The other strange part is - the same cert works with nodejs - expressJS
If this is a bug, some missing config or JDK support issues relating to SSL?
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 18 (10 by maintainers)
Commits related to this issue
- Related to the Spring boot ISSUE - https://github.com/spring-projects/spring-boot/issues/34232 — committed to krnbr/spring-https-ec-curve-issue-34232 by krnbr a year ago
- Load algorithm parameters from PEM encoded 'EC PRIVATE KEY' files Update `PrivateKeyParser` implementations so that algorithm parameters for PEM encoded 'EC PRIVATE KEY' files are loaded from the inc... — committed to spring-projects/spring-boot by philwebb 10 months ago
The
secp384r1curve works.@aDramaQueen With the changes made in https://github.com/spring-projects/spring-boot/commit/fd8cb74b46f17c0d2e8ca0f302561d9a5378172b, we don’t believe there’s much to be gained by relying on Bouncy Castle as you should now be able to use any curve that’s supported by the JDK. While that support isn’t as broad as Bouncy Castle’s we haven’t seen demand for other curves that would justify pulling in a new dependency.
Sure, it’s here.
The OID
1.3.132.0.34is for the secp384r1 curve.Yes, the code for the EC parsing is the same in 2.7.x and 3.0.x, that’s why i labelled it as a 2.7.x bug.