mockserver
mockserver copied to clipboard
Certificate Chain for server authentication
I would use a Certificate Chain (multiple PEM file merged in one file - end-entity certificate + Intermediate certificate) to do server authentication. I'm using the following env variable:
MOCKSERVER_TLS_X509_CERTIFICATE_PATH
pointing to a file with multiple certificates inside.
The mockserver shows the following error:
`2022-05-06 13:40:57 5.11.2 FINE using command line options:
serverPort=1080
2022-05-06 13:41:00 5.11.2 INFO created expectation file watcher for
2022-05-06 13:41:03 5.11.2 FINE logger level is DEBUG, change using:
- 'ConfigurationProperties.logLevel(String level)' in Java code,
- '-logLevel' command line argument,
- 'mockserver.logLevel' JVM system property or,
- 'mockserver.logLevel' property value in 'mockserver.properties'
2022-05-06 13:41:03 5.11.2 INFO 1080 started on port: 1080
2022-05-06 13:41:20 5.11.2 SEVERE TSL handshake failure while a client attempted to connect to [id: 0xad8bc00f, L:0.0.0.0/0.0.0.0:1080]
io.netty.handler.codec.DecoderException: javax.net.ssl.SSLHandshakeException: Insufficient buffer remaining for AEAD cipher fragment (2). Needs to be more than tag size (16)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:471)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: javax.net.ssl.SSLHandshakeException: Insufficient buffer remaining for AEAD cipher fragment (2). Needs to be more than tag size (16)
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:320)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:263)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:258)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:129)
at java.base/sun.security.ssl.SSLEngineImpl.decode(SSLEngineImpl.java:668)
at java.base/sun.security.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:623)
at java.base/sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:441)
at java.base/sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:420)
at java.base/javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:634)
at io.netty.handler.ssl.SslHandler$SslEngineType$3.unwrap(SslHandler.java:282)
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1387)
at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1282)
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1329)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:501)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:440)
... 16 more
Caused by: javax.crypto.BadPaddingException: Insufficient buffer remaining for AEAD cipher fragment (2). Needs to be more than tag size (16)
at java.base/sun.security.ssl.SSLCipher$T13GcmReadCipherGenerator$GcmReadCipher.decrypt(SSLCipher.java:1868)
at java.base/sun.security.ssl.SSLEngineInputRecord.decodeInputRecord(SSLEngineInputRecord.java:240)
at java.base/sun.security.ssl.SSLEngineInputRecord.decode(SSLEngineInputRecord.java:197)
at java.base/sun.security.ssl.SSLEngineInputRecord.decode(SSLEngineInputRecord.java:160)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:108)
... 27 more
`
when I perform the following curl:
curl -L https://localhost:1080 --cacert rest-ms-certs/myRootCA.pem -v
the output of curl is:
* Trying 127.0.0.1:1080...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 1080 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: rest-ms-certs/myRootCA.pem
CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (OUT), TLS alert, unsupported certificate (555):
* SSL certificate problem: unsupported certificate purpose
* Closing connection 0
curl: (60) SSL certificate problem: unsupported certificate purpose
More details here: https://curl.haxx.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
I believe is you upgrade your version MockServer to 5.13.2 this issue should be resolved.
Please confirm
I upgraded mockserver version to 5.13.2 but the issue is still present:
and certificate serial:
12345678
issuer:
C=XX, O=MyCompany, CN=myRootCA
subject:
C=XX, O=MyCompany, CN=mySubCA
2022-05-06 15:08:51 5.13.2 SEVERE TLS handshake failure while a client attempted to connect to [id: 0x40335f25, L:/192.168.144.4:1080 ! R:/192.168.144.1:35168]
shaded_package.io.netty.handler.codec.DecoderException: javax.net.ssl.SSLHandshakeException: Received fatal alert: unsupported_certificate
at shaded_package.io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:480)
at shaded_package.io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:279)
at shaded_package.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at shaded_package.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at shaded_package.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at shaded_package.io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
at shaded_package.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at shaded_package.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at shaded_package.io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at shaded_package.io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
at shaded_package.io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:722)
at shaded_package.io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:658)
at shaded_package.io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:584)
at shaded_package.io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:496)
at shaded_package.io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
at shaded_package.io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: unsupported_certificate
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:358)
at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:293)
at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:204)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:172)
at java.base/sun.security.ssl.SSLEngineImpl.decode(SSLEngineImpl.java:736)
at java.base/sun.security.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:691)
at java.base/sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:506)
at java.base/sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:482)
at java.base/javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:679)
at shaded_package.io.netty.handler.ssl.SslHandler$SslEngineType$3.unwrap(SslHandler.java:295)
at shaded_package.io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1342)
at shaded_package.io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1235)
at shaded_package.io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1284)
at shaded_package.io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:510)
at shaded_package.io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:449)
... 16 more
it seems that mockserver reads the Intermediate certificate correctly but after is not able to read the end-entity certificate from the file.
I'm using the env variable MOCKSERVER_TLS_X509_CERTIFICATE_PATH with a PEM file composed by Intermediate certificate (first position) cuncatenated with end-entity certificate (last position). Is it correct? There is another env variable to use for a chain?
It looks like the format of the certificate is not valid, the exception is indicating that. Have you verified all the certificates in your file can be read by another tool?
Yes, the certificates in the chain are correct. My dubt is about the position in the file. Currently I have the Intermediate certificate in the first position and the end-entity certificate in the second position. Should they be inverted?
UPDATE: I tried to invert the position of certificates in the chain (end-entity certificate in first position and Intermediate in second position) but an error is still present, even if different:
and certificate serial:
326876675864010758
issuer:
C=XX, O=MyCompany, CN=mySubCA
subject:
C=XX, O=MyCompany, CN=server.mydomain.net
2022-05-07 09:57:28 5.13.2 SEVERE exception creating SSL context for serverfailed to initialize the server-side SSL context
javax.net.ssl.SSLException: failed to initialize the server-side SSL context
at shaded_package.io.netty.handler.ssl.JdkSslServerContext.newSSLContext(JdkSslServerContext.java:289)
at shaded_package.io.netty.handler.ssl.JdkSslServerContext.<init>(JdkSslServerContext.java:247)
at shaded_package.io.netty.handler.ssl.SslContext.newServerContextInternal(SslContext.java:467)
at shaded_package.io.netty.handler.ssl.SslContextBuilder.build(SslContextBuilder.java:606)
at org.mockserver.socket.tls.NettySslContextFactory.createServerSslContext(NettySslContextFactory.java:207)
at org.mockserver.socket.tls.SniHandler.lookup(SniHandler.java:46)
at shaded_package.io.netty.handler.ssl.AbstractSniHandler.lookup(AbstractSniHandler.java:126)
at shaded_package.io.netty.handler.ssl.SslClientHelloHandler.select(SslClientHelloHandler.java:188)
at shaded_package.io.netty.handler.ssl.SslClientHelloHandler.decode(SslClientHelloHandler.java:169)
at shaded_package.io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:510)
at shaded_package.io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:449)
at shaded_package.io.netty.handler.codec.ByteToMessageDecoder.channelInputClosed(ByteToMessageDecoder.java:407)
at shaded_package.io.netty.handler.codec.ByteToMessageDecoder.channelInputClosed(ByteToMessageDecoder.java:374)
at shaded_package.io.netty.handler.codec.ByteToMessageDecoder.channelInactive(ByteToMessageDecoder.java:357)
at shaded_package.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262)
at shaded_package.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248)
at shaded_package.io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:241)
at shaded_package.io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1405)
at shaded_package.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262)
at shaded_package.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248)
at shaded_package.io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:901)
at shaded_package.io.netty.channel.AbstractChannel$AbstractUnsafe$7.run(AbstractChannel.java:813)
at shaded_package.io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
at shaded_package.io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469)
at shaded_package.io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
at shaded_package.io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
at shaded_package.io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.security.KeyStoreException: Certificate chain is not valid
at java.base/sun.security.pkcs12.PKCS12KeyStore.setKeyEntry(PKCS12KeyStore.java:646)
at java.base/sun.security.pkcs12.PKCS12KeyStore.engineSetKeyEntry(PKCS12KeyStore.java:589)
at java.base/sun.security.util.KeyStoreDelegator.engineSetKeyEntry(KeyStoreDelegator.java:112)
at java.base/java.security.KeyStore.setKeyEntry(KeyStore.java:1167)
at shaded_package.io.netty.handler.ssl.SslContext.buildKeyStore(SslContext.java:1112)
at shaded_package.io.netty.handler.ssl.SslContext.buildKeyManagerFactory(SslContext.java:1280)
at shaded_package.io.netty.handler.ssl.JdkSslServerContext.newSSLContext(JdkSslServerContext.java:266)
... 27 more
and from curl:
riccardo@riccardo-VirtualBox:~/git/app$ curl -L https://localhost:1080 --cacert rest-ms-certs/myRootCA.pem -v
* Trying 127.0.0.1:1080...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 1080 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: myRootCA.pem
CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to localhost:1080
* Closing connection 0
curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to localhost:1080
However, here the env variable I'm using to set TLS without mutual authentication:
MOCKSERVER_TLS_MUTUAL_AUTHENTICATION_REQUIRED: "false"
MOCKSERVER_WATCH_INITIALIZATION_JSON: "true"
MOCKSERVER_LOG_LEVEL: DEBUG
MOCKSERVER_TLS_PRIVATE_KEY_PATH: /certs/endentitykey.pem
MOCKSERVER_TLS_X509_CERTIFICATE_PATH: /certs/endentitychain.pem
MOCKSERVER_CERTIFICATE_AUTHORITY_X509_CERTIFICATE: /certs/myRootCA.pem
It's not clear to me env var MOCKSERVER_CERTIFICATE_AUTHORITY_PRIVATE_KEY, it should be used? If yes, how I have to set it?
Can you please show how you are creating your certificates. Are you specifying EC certificates for example as these are not currently supported but will be very soon.
Please re-test as EC certificates are now supported in MockServer