JDK11 Bug with SSLv3

Jamil Nimeh jamil.j.nimeh at oracle.com
Tue Dec 11 17:16:41 UTC 2018


Quick follow up.  Thomas and I exchanged a couple messages off-alias but 
I wanted to summarize it here in case others were following this 
thread.  The short story: Based on what is in RFC 5246 with respect to 
the RSA client key exchange message, the Java client is putting the 
correct version in the PreMasterSecret.client_version field.

--Jamil

On 12/10/2018 3:44 PM, Thomas Lußnig wrote:
> Hi,
>
> here is an demo to show the problem.
> a) The problem is an problem between the key exchange message and the 
> enabled protocols and the server selected protocol.
> b) In this demo it only check if the protocol of the key exchange is 
> TLSv1.2 while SSLv3 is expected.
> c) It also show another issue that the jdk as server does not check if 
> the received messages matches the selected protocol version.
>     -> I think this does not open an security issue but should be 
> verified too, it maybe wanted for compatibility but than it should be 
> configurable per connection.
>
> Gruß Thomas Lußnig
>
> package demo;
>
> import java.io.ByteArrayInputStream;
> import java.io.InputStream;
> import java.io.OutputStream;
> import java.io.PrintStream;
> import java.net.ServerSocket;
> import java.security.KeyFactory;
> import java.security.KeyStore;
> import java.security.PrivateKey;
> import java.security.Security;
> import java.security.cert.Certificate;
> import java.security.cert.CertificateFactory;
> import java.security.spec.PKCS8EncodedKeySpec;
> import java.util.Arrays;
> import java.util.Base64;
>
> import javax.net.ssl.KeyManagerFactory;
> import javax.net.ssl.SSLContext;
> import javax.net.ssl.SSLServerSocket;
> import javax.net.ssl.SSLServerSocketFactory;
> import javax.net.ssl.SSLSocket;
> import javax.net.ssl.SSLSocketFactory;
> import javax.net.ssl.TrustManagerFactory;
>
> class CheckPrintStream extends PrintStream {
>     public CheckPrintStream() { super(System.out); }
>
>     @Override public void write(final byte[] buf, final int off, final 
> int len) {
>         final String t = new String(buf, off, len);
>         if(t.contains("RSA ClientKeyExchange")) {
>             if(t.contains("\"client_version\":  TLSv1.2")) {
>                 System.out.println("CHECK Failed");
>                 final int p = t.indexOf("TLSv1.2");
>                 super.write(buf, off, p+7);
>                 super.write('\n');
>             }
>             else super.write(buf, off, len);
>         }
>     }
> }
>
> public class SSLv3_TLSv12 {
>     static Base64.Decoder b64 = Base64.getDecoder();
>     static byte[] rsaKey = 
> b64.decode("MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAI64R+LgQkK7kAMRrJh8IbhwXjl0X579vTPJZGUwltqu5tKMpvQE7LDiPP3TAWD1m5ntXHFZKrhiI2QU5kSVGH8yggzK3eFcz8K8p56MpCcqykgM5R/Nt6LSKx/n3snNKuWIOdgOZzl75JXTLp3Mc4IXNFzut6fKopT7N9NRZaktAgMBAAECgYEAiXuD5E3cBqTgCdTQyuNpKF82pWoxYttTk7uBdujjqS2rNVBA0/iaeZq23lyRi3GNvy4kSxx2RsBjD1oCqDZoLUXRyxYqYr2STYZXdz3hKC7p3E7mT+0DgYFWe3nUSlXLGaSpwgXtiH1xLQZ7/jqCMWwDDTibsVcbJDz/Lb2x1xECQQDwku/XTLphWYaTEzw2MkYMxswYDGxIPEM+3hvpzF4Elr5hAOjSfSa66Og89hyokKn5/uRWZ08YbDIuY+BtihSjAkEAl98NN90Gky3p7Kto+39uT9ltzzzpv1+UCyqkY//Q6BrDzoixiNTQtdEnzkXZwYrqe35kIHHIv6gn0t03LDNX7wJBANkdIwuBmauF6mgNsgePc5zQRR1nCMpgaKfyN+rWn/swOHy/H1/nxu5kiEOMMe0HMgAGw/geoEmATAGF7eOt/FUCQHgTOvg4IMKtQo6E1/RAxI8NceywVH+iqgJKLL+Du0BIKRhaq0NsP7gBLl/AinKjytDpFXExhW9DHHlzvfOMhLECQQDmeLkRneJ/Hh5kK5vtpNgE9V+kLfnN2+QhCIWHztFR9VNNgf3JzfZFCruwldZJnCPIdxAi7CpECsk/Bf2zL6XD");
>     static byte[] rsaCer = 
> b64.decode("MIICHjCCAYegAwIBAgIBATANBgkqhkiG9w0BAQsFADBEMQ0wCwYDVQQLEwRDZXJ0MRIwEAYDVQQKEwlzdWNoZS5vcmcxCzAJBgNVBAYTAkRFMRIwEAYDVQQDEwlsb2NhbGhvc3QwHhcNMTgxMjA5MjIzMDIwWhcNMTgxMjIxMTIxNzAwWjBEMQ0wCwYDVQQLEwRDZXJ0MRIwEAYDVQQKEwlzdWNoZS5vcmcxCzAJBgNVBAYTAkRFMRIwEAYDVQQDEwlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAI64R+LgQkK7kAMRrJh8IbhwXjl0X579vTPJZGUwltqu5tKMpvQE7LDiPP3TAWD1m5ntXHFZKrhiI2QU5kSVGH8yggzK3eFcz8K8p56MpCcqykgM5R/Nt6LSKx/n3snNKuWIOdgOZzl75JXTLp3Mc4IXNFzut6fKopT7N9NRZaktAgMBAAGjIDAeMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgP4MA0GCSqGSIb3DQEBCwUAA4GBAGFzQL9URFabGys3clkqn6l/tdTzqn6ncG1dL/rhoO1jPAxqGdf7hJ9iPQjPRpdqJl5aawLx9BtWCkdCNXN+Vk4opaGmVNsmQ1eRbZREYEKVKPNquzDIcimDYveYNPRf9shUcU2Z7eAI/GX/uMSlm4XzL7sL4P0v8M/qfja8EQ46");
>
>     static {
>         Security.setProperty("jdk.tls.disabledAlgorithms", "");
>         System.setProperty("javax.net.debug","all");
>     }
>
>     static void server(final ServerSocket srv, final String[] suites) {
>         while(!srv.isClosed()) {
>             try(    SSLSocket s = (SSLSocket)srv.accept();
>                     InputStream  i = s.getInputStream();
>                     OutputStream o = s.getOutputStream()) {
>                 s.setUseClientMode(false);
>                 if(suites != null) s.setEnabledCipherSuites(suites);
>                 s.setEnabledProtocols(new String[]{"SSLv3"});
>                 o.write('s');
>                 i.read();
>                 suite = s.getSession().getCipherSuite();
>             } catch(final Throwable t) { t.printStackTrace(); }
>         }
>     }
>
>     static SSLContext context(final String keyType) throws Exception {
>         final PrivateKey key = 
> KeyFactory.getInstance(keyType).generatePrivate(new 
> PKCS8EncodedKeySpec(rsaKey));
>         final CertificateFactory fact = 
> CertificateFactory.getInstance("X.509");
>         final Certificate    cer = fact.generateCertificate(new 
> ByteArrayInputStream(rsaCer));
>         final KeyStore ks = 
> KeyStore.getInstance(KeyStore.getDefaultType());
>         ks.load(null, null);
>         final char[] pass = "test".toCharArray();
>         ks.setKeyEntry("a", key, pass, new Certificate[]{cer});
>         final TrustManagerFactory tmf = 
> TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
>         tmf.init(ks);
>         final KeyManagerFactory kmf = 
> KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
>         kmf.init(ks, pass);
>         final SSLContext c = SSLContext.getInstance("TLS");
>         c.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
>         return c;
>     }
>
>     static volatile String suite = null;
>
>     static void doCheck(final String[] suites) {
>         suite = null;
>         System.out.println("START Suites: "+Arrays.toString(suites));
>         try {
>             final SSLContext c = context("RSA");
>             final SSLSocketFactory       csf = c.getSocketFactory();
>             final SSLServerSocketFactory ssf = 
> c.getServerSocketFactory();
>             try(final SSLServerSocket srv = 
> (SSLServerSocket)ssf.createServerSocket(0, 16)) {
>                 if(suites != null) srv.setEnabledCipherSuites(suites);
>                 srv.setEnabledProtocols(new String[]{"SSLv3"});
>                 new Thread(()->server(srv, suites)).start();
>                 try(    SSLSocket s = 
> (SSLSocket)csf.createSocket("localhost", srv.getLocalPort());
>                         InputStream  i = s.getInputStream();
>                         OutputStream o = s.getOutputStream()) {
>                     if(suites != null) s.setEnabledCipherSuites(suites);
>                     s.setEnabledProtocols(new 
> String[]{"SSLv3","TLSv1","TLSv1.1","TLSv1.2"});
>                     o.write('c');
>                     i.read();
>                 } catch(final Throwable t) { 
> t.printStackTrace(System.out); }
>             }
>         } catch(final Throwable t) { t.printStackTrace(System.out);
>         } finally { System.out.println("DONE Suites: 
> "+Arrays.toString(suites)+" used "+suite); }
>     }
>
>     public static void main(final String[] argc) throws Exception {
>         try(final PrintStream check = new CheckPrintStream()) {
>             System.setErr(check);
>             doCheck(new 
> String[]{"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"}); // WORKS
>             doCheck(new String[]{"SSL_RSA_WITH_3DES_EDE_CBC_SHA"     
> }); // -> Wrong TLSv1.2 in "RSA ClientKeyExchange"
>         }
>     }
> }
>
>
> On 10.12.2018 20:58:45, Thomas Lußnig wrote:
>> Hi,
>>
>> i am not sure if there is already an bug opened. But i found an error 
>> in the SSL-Socket handling.
>> If the ssl client socket enabled SSLv3-TLSv1.2 and the server select 
>> SSLv3 the client later on send an
>> "RSA ClientKeyExchange" with version TLSv1.2. I added the relevant 
>> parts of the debug log.
>> If there is no bug opened yet i can provide an sample with 
>> client/server that demonstrate the bug
>> and can maybe used for regression tests.
>>
>> Gruß Thomas Lußnig
>>
>>
>> 2018-12-10T12:16:41.666 
>> javax.net.ssl|DEBUG|15|https://fqdn/path)|2018-12-10 12:16:41.666 
>> CET|ClientHello.java:651|Produced ClientHello handshake message (
>> "ClientHello": {
>>   "client version"      : "TLSv1.2",
>>   "random"              : "90 B4 FF B0 8E C8 FA 3F D8 15 A3 73 13 78 
>> 38 D5 3A FB 49 68 28 ED B1 95 3C 3E 24 0C DD 64 A2 95",
>>   "session id"          : "",
>>   "cipher suites"       : "[SSL_RSA_WITH_3DES_EDE_CBC_SHA(0x000A), 
>> TLS_EMPTY_RENEGOTIATION_INFO_SCSV(0x00FF)]",
>>   "compression methods" : "00",
>>   ...
>>
>> 2018-12-10T12:16:41.688 
>> javax.net.ssl|DEBUG|15|https://fqdn/path)|2018-12-10 12:16:41.688 
>> CET|ServerHello.java:866|Consuming ServerHello handshake message (
>> "ServerHello": {
>>   "server version"      : "SSLv3",
>>   "random"              : "5C 37 37 A9 EA DD D7 67 28 15 D3 DF 5F 3F 
>> 13 E2 34 88 93 67 16 FD 4F 76 A6 08 11 BE 36 E3 B4 26",
>>   "session id"          : "1D 5F B9 F7 EC DE 8E D9 38 52 AB FF 04 A1 
>> 24 1D",
>>   "cipher suite"        : "SSL_RSA_WITH_3DES_EDE_CBC_SHA(0x000A)",
>>   "compression methods" : "00",
>>   "extensions"          : [
>>     <no extension>
>>   ]
>> }
>> )
>>
>> 2018-12-10T12:16:41.699 
>> javax.net.ssl|DEBUG|15|https://fqdn/path)|2018-12-10 12:16:41.699 
>> CET|CertificateMessage.java:358|Consuming server Certificate 
>> handshake message (
>> "Certificates": [
>>   "certificate" : {
>>     "version"            : "v3",
>>     "serial number"      : "02 6F D4 BA 63 70 2F 13 00 91 5D E4",
>>     "signature algorithm": "SHA256withRSA",
>>     "issuer"             : "CN=VR IDENT CLASS 3 CA 2010, OU=VR IDENT, 
>> O=GAD EG, C=DE",
>>     "not before"         : "2017-07-20 01:33:58.000 CEST",
>>     ...
>>
>> 2018-12-10T12:16:41.854 
>> javax.net.ssl|DEBUG|15|https://fqdn/path)|2018-12-10 12:16:41.853 
>> CET|X509TrustManagerImpl.java:242|Found trusted certificate (
>>   "certificate" : {
>>     "version"            : "v3",
>>     "serial number"      : "02 6F D4 BA 63 70 2F 13 00 91 5D E4",
>>     ...
>>
>> 2018-12-10T12:16:41.856 
>> javax.net.ssl|DEBUG|15|https://fqdn/path)|2018-12-10 12:16:41.856 
>> CET|RSAClientKeyExchange.java:195|Produced RSA ClientKeyExchange 
>> handshake message (
>> "RSA ClientKeyExchange": {
>>   "client_version":  TLSv1.2
>>   "encncrypted": {
>>     0000: 52 2E C4 EB 8C 65 06 77   47 5D 9E 10 56 95 8A 6E 
>> R....e.wG]..V..n
>>     0010: 03 D0 70 8D 73 51 93 F7   8B F7 73 55 25 AC E4 0C 
>> ..p.sQ....sU%...
>>     0020: 34 68 26 01 E0 40 64 B5   82 C6 1C 7C 04 81 E3 15 
>> 4h&.. at d.........
>>     ...
>>
>>



More information about the security-dev mailing list