I use Netty to implement a server with secure socket. My code of sslHandler is:
SslHandler sslHandler = SslContextBuilder
.forServer(certFile, keyFile)
.trustManager(trustFile)
.clientAuth(ClientAuth.REQUIRE)
.build()
.newHandler(channel.alloc());
trustFile is a File object which contains around 700 pieces of certificate text, like:
-----BEGIN CERTIFICATE-----
MIIEHDCCAwSgAwIBAgIJAOR6+3G8C6f7MA0GCSqGSIb3DQEBCwUAMIGNMQswCQYD
VQQGEwJVUzESMBAGA1UECAwJQ2FsaWZvbWlhMRwwGgYDVQQKDBNDaXNjbyBTeXN0
................................................................
igHdyc519KbYSMfhuM9gXw35LPmFWStBGYikBcMZJ1WmWxb/eZOK1SMjVQ/L/JVg
-----END CERTIFICATE-----
When I connect the server with
curl -k -v -E client.pem --key client.key.pem --cacert rootCA.pem https://10.140.28.33:31069
an exception pops up:
11:00:18.636 [nioEventLoopGroup-3-2] WARN io.netty.channel.DefaultChannelPipeline - An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
io.netty.handler.codec.DecoderException: java.lang.RuntimeException: Field length overflow, the field length (106142) should be less than 65536
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:459)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:644)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:579)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:496)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:458)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.RuntimeException: Field length overflow, the field length (106142) should be less than 65536
at sun.security.ssl.Handshaker.checkThrown(Handshaker.java:1476)
at sun.security.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:535)
at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:813)
at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:781)
at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624)
at io.netty.handler.ssl.SslHandler$SslEngineType$3.unwrap(SslHandler.java:255)
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1162)
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1084)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
... 16 common frames omitted
Caused by: java.lang.RuntimeException: Field length overflow, the field length (106142) should be less than 65536
at sun.security.ssl.HandshakeOutStream.checkOverflow(HandshakeOutStream.java:231)
at sun.security.ssl.HandshakeOutStream.putInt16(HandshakeOutStream.java:163)
at sun.security.ssl.HandshakeMessage$CertificateRequest.send(HandshakeMessage.java:1442)
at sun.security.ssl.HandshakeMessage.write(HandshakeMessage.java:143)
at sun.security.ssl.ServerHandshaker.clientHello(ServerHandshaker.java:971)
at sun.security.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:224)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026)
at sun.security.ssl.Handshaker$1.run(Handshaker.java:966)
at sun.security.ssl.Handshaker$1.run(Handshaker.java:963)
at java.security.AccessController.doPrivileged(Native Method)
at sun.security.ssl.Handshaker$DelegatedTask.run(Handshaker.java:1416)
at io.netty.handler.ssl.SslHandler.runDelegatedTasks(SslHandler.java:1301)
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1214)
... 19 common frames omitted
But if I trim the trust file with only a few certificates left, no error happen.
Is it a JDK bug? How can I avoid it?
It may be a bug that JSSE doesn't give a clearer alert, but there is a fundamental problem.
When an SSL/TLS server requests client authentication, it normally sends a list of the certificate authorities the client should use in the Certificate Request message, see rfc5246 7.4.4 or earlier. Since you trust a huge number of selfsigned certs, where each selfsigner effectively acts as a CA for itself, this means your server needs to send a huge list of CAs -- but this list is limited to 65535 bytes total. Your exception shows you are trying to send 106142 bytes which doesn't fit in 65535 bytes; this means your cert names (Subjects) average about 150 bytes, which seems to me a bit on the high side if these are used entirely within your enterprise and thus presumably don't need globally unique names like the public web (especially EV with its enhanced identity requirements).
One possible workaround, if all your clients know which cert to use without being prompted, is for the server to send the CA list as empty, which is permitted though not encouraged. JSSE simply populates CertReq.CAlist from the trustmanager's getAcceptedIssuers() method, and the TrustManager API is designed for customization, so you could just wrap the real X509TrustManager with one that validates the received cert chain normally, but returns getAcceptedIssuers() as an empty array. This is fairly easy with the actual Java classes (SSLContext et amici) but I'm not sure exactly where to look in Netty's 'improvements'.
But a better solution, as noted in comments by EJP, is not to individually trust a huge number of selfsigned certs but instead have a CA issue the client certs and then the server need only trust that CA (and transitively the certs it issues) and CertReq automatically specifies only that CA. If you don't already have a suitable established CA to use, there are many options to do your own CA, discussed in other Qs here and other Stacks (IME mostly security.SX unix.SX and serverfault), but given you are using Java remember that since j7 keytool -gencert does a minimal but usable CA function. (In addition to keypair and CSR generation which keytool has done back to the dark ages.)
Related
i am facing a problem, i want to config a ssl with GMTLS protocol,i have success config ssl with TLSV1.2.
the wireshark shows like that
TLSV1.2
GMTLSV1
For Wildfly/Jboss can establish GMTLS ssl connection , i have done
add some properties in standalone.xml
<tls>
<key-stores>
<key-store name="customKS">
<credential-reference clear-text="password"/>
<implementation type="PKCS12"/>
<file path="sm2.localhost.both.pfx" relative-to="jboss.server.config.dir"/>
</key-store>
</key-stores>
<key-managers>
<key-manager name="customKM" key-store="customKS" provider-name="GMJCE" algorithm="SunX509">
<credential-reference clear-text="passowrd"/>
</key-manager>
</key-managers>
<server-ssl-context name="customSSC" key-manager="customKM" provider-name="GMJSSE" protocols="GMSSLv1.1" />
</server-ssl-contexts>
</tls>
...
<https-listener name="https" socket-binding="https" ssl-context="customSSC" enable-http2="true"/>
let wildfly source code support GMSSLV1.1 protocol
IN class SSLDefinitions ALLOWED_PROTOCOLS add string "GMSSLv1.1"
line 231
private static final String[] ALLOWED_PROTOCOLS = { "SSLv2", "SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3" , "GMSSLv1.1" };
In enum class Protocol add a constant
line 15
SSLv2("SSLV2"),
SSLv3("SSLV3"),
TLSv1("TLSV1"),
TLSv1_1("TLSV1.1"),
TLSv1_2("TLSV1.2"),
TLSv1_3("TLSV1.3"),
GMSSLv1_1("GMSSLV1.1"),
SSLv2Hello("SSLV2HELLO");
when i have finish above things, the server start normally. The http uri visited successfully,but the https uri can't arrive, i use wireshark to capture package it show handshake failure. i don't know what's wrrog have happened!
I have solved this problem.
The core problem is handshake failure.
To build an SSL channel, we need a keystore and a GMSSL type of SSLContext. Then we need to perform the handshake, but it fails. The problem is happening in ciphersuite. At WildFly Core 17.0.3.Final, the default ciphersuite is for TLS1.3, but what I need is GMTSL. So I need to add my own ciphersuite.
Add ciphersuite in TLS13MechanismDatabase.properties
ECC_SM4_CBC_SM3 = ECC_SM4_CBC_SM3,ANY,ANY,AES128CCM8,AEAD,TLSv1.3,false,HIGH,false,128,128,13,05
Edit standalone.xml: add cipher-suite-names
<server-ssl-context name="customSSC" key-manager="customKM" provider-name="GMJSSE" protocols="GMSSLv1.1" cipher-suite-names="ECC_SM4_CBC_SM3"/>
Run the server
Wireshark output:
I am currently new in grpc.
I wanted to provide ssl for my grpc server
the javav code for starting looks like this:
InputStream publicKey = ServerStarter.class.getResourceAsStream("/my-public-key-cert.pem");
InputStream privateKey = ServerStarter.class.getResourceAsStream("/my-private-key.pem");
SslContext sslContext = GrpcSslContexts.forServer(publicKey, privateKey).build();
Server server = NettyServerBuilder.forPort(5555)
.sslContext(sslContext)
.addService(new RedirectService())
.intercept(new AuthorizationInterceptor())
.build();
server.start();
SSL certificates were generated with openssl. And here how openssl command looks like:
openssl req -x509 -newkey rsa:4096 -keyout ./grpc-server/src/main/resources/my-private-key.pem -out ./grpc-server/src/main/resources/my-public-key-cert.pem -days 365 -nodes -subj "/CN=192.168.88.132" -addext "subjectAltName = DNS.1:192.168.88.132, DNS.2:localhost"
Server runs fine.
But I can't connect to server.
My clients code looks like this:
InputStream certificate = GalamatClient.class.getResourceAsStream("/my-public-key-cert.pem");
SslContext context = GrpcSslContexts.forClient().trustManager(certificate).build();
ManagedChannel channel = NettyChannelBuilder.forTarget("192.168.88.132:5555")
.sslContext(context)
.build();
GreetingServiceGrpc.GreetingServiceBlockingStub stub = GreetingServiceGrpc.newBlockingStub(channel)
GreetingService.GreetingRequest request = GreetingService.GreetingRequest.newBuilder().setMessage("Hi").build();
GreetingService.GreetingResponse response = stub.greet(request);
channel.shutdownNow();
And when I try to run client next Error occurs:
Exception in thread "main" io.grpc.StatusRuntimeException: UNAVAILABLE: io exception
Channel Pipeline: [SslHandler#0, ProtocolNegotiators$ClientTlsHandler#0, WriteBufferingAndExceptionHandler#0, DefaultChannelPipeline$TailContext#0]
at io.grpc.stub.ClientCalls.toStatusRuntimeException(ClientCalls.java:262)
at io.grpc.stub.ClientCalls.getUnchecked(ClientCalls.java:243)
at io.grpc.stub.ClientCalls.blockingUnaryCall(ClientCalls.java:156)
at com.example.GreetingServiceGrpc$GreetingServiceBlockingStub.recognize(SpeechRecognitionGrpc.java:246)
at com.example.main(Client.java:59)
Caused by: javax.net.ssl.SSLHandshakeException: General OpenSslEngine problem
at io.grpc.netty.shaded.io.netty.handler.ssl.ReferenceCountedOpenSslEngine.handshakeException(ReferenceCountedOpenSslEngine.java:1772)
at io.grpc.netty.shaded.io.netty.handler.ssl.ReferenceCountedOpenSslEngine.wrap(ReferenceCountedOpenSslEngine.java:777)
at javax.net.ssl.SSLEngine.wrap(SSLEngine.java:509)
at io.grpc.netty.shaded.io.netty.handler.ssl.SslHandler.wrap(SslHandler.java:1079)
at io.grpc.netty.shaded.io.netty.handler.ssl.SslHandler.wrapNonAppData(SslHandler.java:970)
at io.grpc.netty.shaded.io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1443)
at io.grpc.netty.shaded.io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1275)
at io.grpc.netty.shaded.io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1322)
at io.grpc.netty.shaded.io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:501)
at io.grpc.netty.shaded.io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:440)
at io.grpc.netty.shaded.io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)
at io.grpc.netty.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.grpc.netty.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.grpc.netty.shaded.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.grpc.netty.shaded.io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
at io.grpc.netty.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.grpc.netty.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.grpc.netty.shaded.io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at io.grpc.netty.shaded.io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
at io.grpc.netty.shaded.io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
at io.grpc.netty.shaded.io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
at io.grpc.netty.shaded.io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
at io.grpc.netty.shaded.io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
at io.grpc.netty.shaded.io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
at io.grpc.netty.shaded.io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.grpc.netty.shaded.io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.security.cert.CertificateException: No subject alternative names matching IP address 192.168.88.132 found
at sun.security.util.HostnameChecker.matchIP(HostnameChecker.java:168)
at sun.security.util.HostnameChecker.match(HostnameChecker.java:94)
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:459)
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:440)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:261)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:144)
at io.grpc.netty.shaded.io.netty.handler.ssl.OpenSslTlsv13X509ExtendedTrustManager.checkServerTrusted(OpenSslTlsv13X509ExtendedTrustManager.java:223)
at io.grpc.netty.shaded.io.netty.handler.ssl.ReferenceCountedOpenSslClientContext$ExtendedTrustManagerVerifyCallback.verify(ReferenceCountedOpenSslClientContext.java:261)
at io.grpc.netty.shaded.io.netty.handler.ssl.ReferenceCountedOpenSslContext$AbstractCertificateVerifier.verify(ReferenceCountedOpenSslContext.java:698)
at io.grpc.netty.shaded.io.netty.internal.tcnative.SSL.readFromSSL(Native Method)
at io.grpc.netty.shaded.io.netty.handler.ssl.ReferenceCountedOpenSslEngine.readPlaintextData(ReferenceCountedOpenSslEngine.java:596)
at io.grpc.netty.shaded.io.netty.handler.ssl.ReferenceCountedOpenSslEngine.unwrap(ReferenceCountedOpenSslEngine.java:1203)
at io.grpc.netty.shaded.io.netty.handler.ssl.ReferenceCountedOpenSslEngine.unwrap(ReferenceCountedOpenSslEngine.java:1325)
at io.grpc.netty.shaded.io.netty.handler.ssl.SslHandler$SslEngineType$1.unwrap(SslHandler.java:201)
at io.grpc.netty.shaded.io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1380)
... 21 more
Suppressed: javax.net.ssl.SSLHandshakeException: error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED
at io.grpc.netty.shaded.io.netty.handler.ssl.ReferenceCountedOpenSslEngine.sslReadErrorResult(ReferenceCountedOpenSslEngine.java:1288)
at io.grpc.netty.shaded.io.netty.handler.ssl.ReferenceCountedOpenSslEngine.unwrap(ReferenceCountedOpenSslEngine.java:1249)
... 24 more
Error says that I don't provide needed Ip in subject alternative names:
No subject alternative names matching IP address 192.168.88.132 found
but I provided it in command of creation certificate.
I will apreciate if you could help with that.
Use overrideAuthority(String authority) to match what the certificate has in its SAN. Use an OpenSsl command to display what you have in your server cert.
I am seeing a weird issue with SSLEngine and wondering if there is an issue with my code or SSLEngine. Here is the order in which I see things
HandshakeStatus is NEED_WRAP
We call SSLEngine.WRAP
after, there is ZERO data written to the buffer, and SSLEngineResult.result=OK(not overflow nor underflow :( ) and HandshakeStatus is STILL NEED_WRAP
Most important question: How to debug thoroughly? How to 'see' each message somehow? I can capture the byte stream easily enough but is there some library that can parse that into SSL handshake objects?
line 298 (recording previous handshake status) to line 328(where we throw the exception with info) is the relevant code here
https://github.com/deanhiller/webpieces/blob/sslEngineFartingExample/core/core-ssl/src/main/java/org/webpieces/ssl/impl/AsyncSSLEngine3Impl.java
The stack trace was
2019-06-21 08:58:24,562 [-] [webpiecesThreadPool6] Caller+1 at org.webpieces.util.threading.SessionExecutorImpl$RunnableWithKey.run(SessionExecutorImpl.java:123)
ERROR: Uncaught Exception
java.lang.IllegalStateException: Engine issue. hsStatus=NEED_WRAP status=OK previous hsStatus=NEED_WRAP
at org.webpieces.ssl.impl.AsyncSSLEngine3Impl.sendHandshakeMessageImpl(AsyncSSLEngine3Impl.java:328)
at org.webpieces.ssl.impl.AsyncSSLEngine3Impl.sendHandshakeMessage(AsyncSSLEngine3Impl.java:286)
at org.webpieces.ssl.impl.AsyncSSLEngine3Impl.doHandshakeWork(AsyncSSLEngine3Impl.java:133)
at org.webpieces.ssl.impl.AsyncSSLEngine3Impl.doHandshakeLoop(AsyncSSLEngine3Impl.java:246)
at org.webpieces.ssl.impl.AsyncSSLEngine3Impl.unwrapPacket(AsyncSSLEngine3Impl.java:210)
at org.webpieces.ssl.impl.AsyncSSLEngine3Impl.doWork(AsyncSSLEngine3Impl.java:109)
at org.webpieces.ssl.impl.AsyncSSLEngine3Impl.feedEncryptedPacket(AsyncSSLEngine3Impl.java:82)
at org.webpieces.nio.impl.ssl.SslTCPChannel$SocketDataListener.incomingData(SslTCPChannel.java:175)
at org.webpieces.nio.impl.threading.ThreadDataListener$1.run(ThreadDataListener.java:26)
at org.webpieces.util.threading.SessionExecutorImpl$RunnableWithKey.run(SessionExecutorImpl.java:121)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
any ideas? How can I really dig into this further? My preference is a library that takes bytes and spits out ssl objects representing each handshake message or decrypted packet(with any header info that comes with the original encrypted thing).
Specifically, here is the code mentioned above
HandshakeStatus previousStatus = sslEngine.getHandshakeStatus();
//CLOSE and all the threads that call feedPlainPacket can have contention on wrapping to encrypt and
//must synchronize on sslEngine.wrap
Status lastStatus;
HandshakeStatus hsStatus;
synchronized (wrapLock ) {
HandshakeStatus beforeWrapHandshakeStatus = sslEngine.getHandshakeStatus();
if (beforeWrapHandshakeStatus != HandshakeStatus.NEED_WRAP)
throw new IllegalStateException("we should only be calling this method when hsStatus=NEED_WRAP. hsStatus=" + beforeWrapHandshakeStatus);
//KEEEEEP This very small. wrap and then listener.packetEncrypted
SSLEngineResult result = sslEngine.wrap(SslMementoImpl.EMPTY, engineToSocketData);
lastStatus = result.getStatus();
hsStatus = result.getHandshakeStatus();
}
log.trace(()->mem+"write packet pos="+engineToSocketData.position()+" lim="+
engineToSocketData.limit()+" status="+lastStatus+" hs="+hsStatus);
if(lastStatus == Status.BUFFER_OVERFLOW || lastStatus == Status.BUFFER_UNDERFLOW)
throw new RuntimeException("status not right, status="+lastStatus+" even though we sized the buffer to consume all?");
boolean readNoData = engineToSocketData.position() == 0;
engineToSocketData.flip();
try {
CompletableFuture<Void> sentMsgFuture;
if(readNoData) {
log.trace(() -> "ssl engine is farting. READ 0 data. hsStatus="+hsStatus+" status="+lastStatus);
throw new IllegalStateException("Engine issue. hsStatus="+hsStatus+" status="+lastStatus+" previous hsStatus="+previousStatus);
//A big hack since the Engine was not working in live testing with FireFox and it would tell us to wrap
//and NOT output any data AND not BufferOverflow.....you have to do 1 or the other, right!
//instead cut out of looping since there seems to be no data
//sslEngineIsFarting = true;
//sentMsgFuture = CompletableFuture.completedFuture(null);
thanks,
Dean
System.setProperty("jdk.tls.server.protocols", "TLSv1.2");
System.setProperty("jdk.tls.client.protocols", "TLSv1.2");
The system property should be set before the JSSE get loaded. For example, set the property within command line. Is it the cause that the system property does not work for you?
... the SSLEngine tells us we need to WRAP which is correct as we need to be replying with a close_notify as well to prevent truncation attacks BUT instead the engine returns 0 bytes and tells us the state of the engine is still NEED_WRAP.
TLS 1.3 is using a half-close policy (See RFC 8446). When receiving the close_notify, the inbound side will be closed and the outbound side keeps open. The local side cannot receive any data, but is allowed to send more application data.
There are a few compatibility impact by the half-close policy (See JDK 11 release note, https://www.oracle.com/technetwork/java/javase/11-relnote-issues-5012449.html). The system property, "jdk.tls.acknowledgeCloseNotify", can be used as a workaround. For more details, please refer to the JDK 11 release note.
oh, even better, downgrading to 1.8.0_111 yields success
2019-06-30 00:11:54,813 [main] Caller+1 at
WEBPIECESxPACKAGE.DevelopmentServer.main(DevelopmentServer.java:32)
INFO: Starting Development Server under java version=1.8.0_111
webpiecesThreadPool5, READ: TLSv1.2 Alert, length = 26
webpiecesThreadPool2, RECV TLSv1.2 ALERT: warning, close_notify
webpiecesThreadPool2, closeInboundInternal()
webpiecesThreadPool2, closeOutboundInternal()
webpiecesThreadPool5, RECV TLSv1.2 ALERT: warning, close_notify
webpiecesThreadPool5, closeInboundInternal()
webpiecesThreadPool5, closeOutboundInternal()
webpiecesThreadPool2, SEND TLSv1.2 ALERT: warning, description = close_notify
webpiecesThreadPool5, SEND TLSv1.2 ALERT: warning, description = close_notify
webpiecesThreadPool2, WRITE: TLSv1.2 Alert, length = 26
webpiecesThreadPool5, WRITE: TLSv1.2 Alert, length = 26
Ok, more and more this seems like a jdk bug and this seems to prove it now. My log shows I was on jdk11.0.3(on a MAC)
2019-06-29 23:37:18,793 [main][] [-] Caller+1 at
WEBPIECESxPACKAGE.DevelopmentServer.main(DevelopmentServer.java:32)
INFO: Starting Development Server under java version=11.0.3
I used debug ssl flag settings of
-Djavax.net.debug=ssl:handshake:verbose:keymanager:trustmanager -Djava.security.debug=access:stack
I surrounded all my calls to sslEngine.wrap and sslEngine.unwrap with my own logs as well and thankfully everyone had the thread name in their logs as well.
It seems when clients send a warning of this
javax.net.ssl|DEBUG|14|webpiecesThreadPool1|2019-06-29 23:27:14.860
MDT|Alert.java:232|Received alert message (
"Alert": {
"level" : "warning",
"description": "close_notify"
}
)
the SSLEngine tells us we need to WRAP which is correct as we need to be replying with a close_notify as well to prevent truncation attacks BUT instead the engine returns 0 bytes and tells us the state of the engine is still NEED_WRAP.
ALSO, there was ZERO ssl debug logs from java between my logs before and after the sslEngine.wrap call almost like the sslEngine farted and did nothing.
Then, I thought I would be really cool and added this as the first lines in main() method
System.setProperty("jdk.tls.server.protocols", "TLSv1.2");
System.setProperty("jdk.tls.client.protocols", "TLSv1.2");
but the selected version in the debug info was still TLSv1.3....grrrrrr...oh well, I give up.
This question already has answers here:
Why does SSL handshake give 'Could not generate DH keypair' exception?
(22 answers)
Closed 4 years ago.
I have a java program and it send mails to the users. Since 1 week the mails doesn't been send anymore. I didn't change anything, but now I get this error:
connexion failed: Exception reading response;
nested exception is:
javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair
Exception in thread "main" java.lang.RuntimeException: javax.mail.MessagingException: Exception reading response;
nested exception is:
javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair
at Launcher$Connexion.<init>(Launcher.java:33)
at Launcher.main(Launcher.java:52)
Caused by: javax.mail.MessagingException: Exception reading response;
nested exception is:
javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair
at com.sun.mail.smtp.SMTPTransport.readServerResponse(SMTPTransport.java:1407)
at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1205)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:322)
at javax.mail.Service.connect(Service.java:236)
at javax.mail.Service.connect(Service.java:137)
at Launcher$Connexion.<init>(Launcher.java:28)
I contacted fastmail (mailing server) and they say that the insecure cert is self-signed, and does not expire until 2021.
So I don't know what the problem is.
Please add DH parameter limits to the certificate of target server. Custom DH parameters by using openssl dhparam command should be generated and applied with the SSLCertificateFile directive. Please note that the custom DH parameters with a 1024-bit prime will always have precedence over any of the built-in DH parameters.
You should update your Java version to at least version 8 as the 1024-bit restriction should have been lifted to accept 2048-bit parameters.
Please see: Java: Why does SSL handshake give 'Could not generate DH keypair' exception?
I have issue to accept all certs while using the VCloud SDK.
The problem is that there is a self signed cert on the machine and even with the FakeSSL object it is not working, it cannot accept all certs, how do I make a workaround to make it work?
VcloudClient.setLogLevel(Level.OFF);
vcloudClient = new VcloudClient(arg[0], Version.V5_5);
vcloudClient.registerScheme("<https>", 443, FakeSSLSocketFactory.getInstance());
vcloudClient.login(arg[1], arg[2]);
extension = vcloudClient.getVcloudAdminExtension();
Exception in thread "main" com.vmware.vcloud.sdk.VCloudRuntimeException: com.vmware.vcloud.sdk.VCloudRuntimeException: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
at com.vmware.vcloud.sdk.VcloudClient.getSupportedVersions(VcloudClient.java:231)
at com.vmware.vcloud.sdk.VcloudClient.login(VcloudClient.java:329)
at sdt.ericsson.capacity.main.Main.main(Main.java:155)
Caused by: com.vmware.vcloud.sdk.VCloudRuntimeException: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
at com.vmware.vcloud.sdk.RestUtil.getSupportedVersions(RestUtil.java:431)
at com.vmware.vcloud.sdk.VcloudClient.getSupportedVersions(VcloudClient.java:227)
... 2 more
Caused by: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
at sun.security.ssl.SSLSessionImpl.getPeerCertificates(Unknown Source)
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128)
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:572)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:151)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:125)
at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:641)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:480)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:784)
at com.vmware.vcloud.sdk.RestUtil.getSupportedVersions(RestUtil.java:408)
... 3 more
There is my FakeSSLSocketFactory object (from the VMWere samples).
http://wklej.to/2nIV7/text
Any advice?
I switched to use the PERL SDK since it is working perfectly without http/s and API handling is even working for IP address instead, perfectly documented as well, and it pretty fast.