Jason Resch
2014-10-14 20:31:41 UTC
Hello,
I encountered an interesting stack trace which started when we began to install BouncyCastleProvider as the highest priority provider. To reproduce this required pairing a 1024-bit private key together with a larger 2048-bit public key and using a TLS cipher suite that uses RSA encryption. The stack trace we observed is as follows:
2014-10-11 09:54:31.430 WARN [New I/O worker #4] org.cleversafe.protocol.acceptor.netty.AcceptorHandler - Network exception occurred [Conn /192.168.9.218:5000:/192.168.9.230:60005]: Could not generate dummy secret
java.lang.RuntimeException: Could not generate dummy secret
at sun.security.ssl.Handshaker.checkThrown(Handshaker.java:1287) ~[?:1.7.0_55]
at sun.security.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:513) ~[?:1.7.0_55]
at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:793) ~[?:1.7.0_55]
at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:761) ~[?:1.7.0_55]
at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624) ~[?:1.7.0_55]
at org.jboss.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1229) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.handler.ssl.SslHandler.decode(SslHandler.java:914) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.handler.codec.frame.FrameDecoder.callDecode(FrameDecoder.java:425) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:303) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:88) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.process(AbstractNioWorker.java:109) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:312) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:90) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:178) ~[netty-3.7.0.Final.cs.1.jar:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [?:1.7.0_55]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [?:1.7.0_55]
at java.lang.Thread.run(Thread.java:744) [?:1.7.0_55]
Caused by: java.lang.RuntimeException: Could not generate dummy secret
at sun.security.ssl.RSAClientKeyExchange.<init>(RSAClientKeyExchange.java:163) ~[?:1.7.0_55]
at sun.security.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:190) ~[?:1.7.0_55]
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868) ~[?:1.7.0_55]
at sun.security.ssl.Handshaker$1.run(Handshaker.java:808) ~[?:1.7.0_55]
at sun.security.ssl.Handshaker$1.run(Handshaker.java:806) ~[?:1.7.0_55]
at java.security.AccessController.doPrivileged(Native Method) ~[?:1.7.0_55]
at sun.security.ssl.Handshaker$DelegatedTask.run(Handshaker.java:1227) ~[?:1.7.0_55]
at org.jboss.netty.handler.ssl.SslHandler$4.run(SslHandler.java:1371) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.handler.ssl.ImmediateExecutor.execute(ImmediateExecutor.java:31) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.handler.ssl.SslHandler.runDelegatedTasks(SslHandler.java:1368) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1255) ~[netty-3.7.0.Final.cs.1.jar:?]
... 13 more
Caused by: java.lang.ArrayIndexOutOfBoundsException: too much data for RSA block
at org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi.engineDoFinal(Unknown Source) ~[bcprov-jdk15on-1.50.jar:1.50.0]
at javax.crypto.Cipher.doFinal(Cipher.java:1922) ~[?:1.7.0_55]
at sun.security.ssl.RSAClientKeyExchange.<init>(RSAClientKeyExchange.java:149) ~[?:1.7.0_55]
at sun.security.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:190) ~[?:1.7.0_55]
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868) ~[?:1.7.0_55]
at sun.security.ssl.Handshaker$1.run(Handshaker.java:808) ~[?:1.7.0_55]
at sun.security.ssl.Handshaker$1.run(Handshaker.java:806) ~[?:1.7.0_55]
at java.security.AccessController.doPrivileged(Native Method) ~[?:1.7.0_55]
at sun.security.ssl.Handshaker$DelegatedTask.run(Handshaker.java:1227) ~[?:1.7.0_55]
at org.jboss.netty.handler.ssl.SslHandler$4.run(SslHandler.java:1371) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.handler.ssl.ImmediateExecutor.execute(ImmediateExecutor.java:31) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.handler.ssl.SslHandler.runDelegatedTasks(SslHandler.java:1368) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1255) ~[netty-3.7.0.Final.cs.1.jar:?]
... 13 more
Certainly, this failure occurs as the result of invalid configuration: the larger public key means the encrypted master secret will be 2048-bits long, which is longer than any message BouncyCastle allows to be decrypted with the shorter 1024-bit private key. BouncyCastle's RSA block cipher does not permit messages larger than one block to be encrypted or decrypted, which is why the runtime exception was thrown.
However, this raises a more serious question: could a malicious client purposely send an encrypted master secret larger than the size of the private key to cause the TLS server to crash? If so, this seems to be a remote exploit that any server using the JSSE for TLS and BC for RSA encryption would be vulnerable to.
Jason
I encountered an interesting stack trace which started when we began to install BouncyCastleProvider as the highest priority provider. To reproduce this required pairing a 1024-bit private key together with a larger 2048-bit public key and using a TLS cipher suite that uses RSA encryption. The stack trace we observed is as follows:
2014-10-11 09:54:31.430 WARN [New I/O worker #4] org.cleversafe.protocol.acceptor.netty.AcceptorHandler - Network exception occurred [Conn /192.168.9.218:5000:/192.168.9.230:60005]: Could not generate dummy secret
java.lang.RuntimeException: Could not generate dummy secret
at sun.security.ssl.Handshaker.checkThrown(Handshaker.java:1287) ~[?:1.7.0_55]
at sun.security.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:513) ~[?:1.7.0_55]
at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:793) ~[?:1.7.0_55]
at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:761) ~[?:1.7.0_55]
at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624) ~[?:1.7.0_55]
at org.jboss.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1229) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.handler.ssl.SslHandler.decode(SslHandler.java:914) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.handler.codec.frame.FrameDecoder.callDecode(FrameDecoder.java:425) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:303) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:88) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.process(AbstractNioWorker.java:109) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:312) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:90) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:178) ~[netty-3.7.0.Final.cs.1.jar:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [?:1.7.0_55]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [?:1.7.0_55]
at java.lang.Thread.run(Thread.java:744) [?:1.7.0_55]
Caused by: java.lang.RuntimeException: Could not generate dummy secret
at sun.security.ssl.RSAClientKeyExchange.<init>(RSAClientKeyExchange.java:163) ~[?:1.7.0_55]
at sun.security.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:190) ~[?:1.7.0_55]
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868) ~[?:1.7.0_55]
at sun.security.ssl.Handshaker$1.run(Handshaker.java:808) ~[?:1.7.0_55]
at sun.security.ssl.Handshaker$1.run(Handshaker.java:806) ~[?:1.7.0_55]
at java.security.AccessController.doPrivileged(Native Method) ~[?:1.7.0_55]
at sun.security.ssl.Handshaker$DelegatedTask.run(Handshaker.java:1227) ~[?:1.7.0_55]
at org.jboss.netty.handler.ssl.SslHandler$4.run(SslHandler.java:1371) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.handler.ssl.ImmediateExecutor.execute(ImmediateExecutor.java:31) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.handler.ssl.SslHandler.runDelegatedTasks(SslHandler.java:1368) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1255) ~[netty-3.7.0.Final.cs.1.jar:?]
... 13 more
Caused by: java.lang.ArrayIndexOutOfBoundsException: too much data for RSA block
at org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi.engineDoFinal(Unknown Source) ~[bcprov-jdk15on-1.50.jar:1.50.0]
at javax.crypto.Cipher.doFinal(Cipher.java:1922) ~[?:1.7.0_55]
at sun.security.ssl.RSAClientKeyExchange.<init>(RSAClientKeyExchange.java:149) ~[?:1.7.0_55]
at sun.security.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:190) ~[?:1.7.0_55]
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868) ~[?:1.7.0_55]
at sun.security.ssl.Handshaker$1.run(Handshaker.java:808) ~[?:1.7.0_55]
at sun.security.ssl.Handshaker$1.run(Handshaker.java:806) ~[?:1.7.0_55]
at java.security.AccessController.doPrivileged(Native Method) ~[?:1.7.0_55]
at sun.security.ssl.Handshaker$DelegatedTask.run(Handshaker.java:1227) ~[?:1.7.0_55]
at org.jboss.netty.handler.ssl.SslHandler$4.run(SslHandler.java:1371) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.handler.ssl.ImmediateExecutor.execute(ImmediateExecutor.java:31) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.handler.ssl.SslHandler.runDelegatedTasks(SslHandler.java:1368) ~[netty-3.7.0.Final.cs.1.jar:?]
at org.jboss.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1255) ~[netty-3.7.0.Final.cs.1.jar:?]
... 13 more
Certainly, this failure occurs as the result of invalid configuration: the larger public key means the encrypted master secret will be 2048-bits long, which is longer than any message BouncyCastle allows to be decrypted with the shorter 1024-bit private key. BouncyCastle's RSA block cipher does not permit messages larger than one block to be encrypted or decrypted, which is why the runtime exception was thrown.
However, this raises a more serious question: could a malicious client purposely send an encrypted master secret larger than the size of the private key to cause the TLS server to crash? If so, this seems to be a remote exploit that any server using the JSSE for TLS and BC for RSA encryption would be vulnerable to.
Jason