JDK11 Bug with SSLv3

Thomas Lußnig openjdk at suche.org
Mon Dec 10 23:44:03 UTC 2018


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