United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-8014618 : Need to strip leading zeros in TlsPremasterSecret of DHKeyAgreement

Details
Type:
Bug
Submit Date:
2013-03-26
Status:
Closed
Updated Date:
2014-06-30
Project Name:
JDK
Resolved Date:
2013-05-31
Component:
security-libs
OS:
Sub-Component:
javax.net.ssl
CPU:
Priority:
P3
Resolution:
Fixed
Affected Versions:
7u17,8
Fixed Versions:

Related Reports
Backport:
Backport:
Backport:
Backport:
Duplicate:
Duplicate:
Duplicate:
Relates:

Sub Tasks

Description
FULL PRODUCT VERSION :
java version  " 1.7.0_17 " 
Java(TM) SE Runtime Environment (build 1.7.0_17-b02)
Java HotSpot(TM) Client VM (build 23.7-b01, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Tested on Windows 7 (Microsoft Windows [Version 6.1.7601]), but occurs in e..g OpenJDK 7 as well.

A DESCRIPTION OF THE PROBLEM :
When performing Diffie-Hellman key agreement for SSL/TLS, the TLS specification (RFC 5246) says that  " Leading bytes of Z that contain all zero bits are stripped before it is used as the pre_master_secret. " 

However, com.sun.crypto.provider.DHKeyAgreement.java does not strip leading zero bytes. This causes approximately 1 out 256 SSL/TLS  handshakes with DH/DHE cipher suites to fail (when the leading byte happens, by chance, to be zero).


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Start a simple JSSE socket server with -Djavax.net.debug=all.

2. Connect to the server with e.g. OpenSSL command line tool, ensuring that DHE cipher suite gets selected (e.g.  " openssl s_client -cipher DHE-RSA-AES128-SHA -connect 192.168.81.1:9999 " ) repeatedly.  Other SSL clients can be used -- this is not an OpenSSL bug (see below).

3. Repeat the connection. After a couple of hundred successful connections, the connection will fail with handshake_failure alert.

4. Examine the JSSE debug logs produced by the server: the failed connection will have a PreMaster secret that begins with zero byte
(while all other connections have non-zero byte here). For example:

SESSION KEYGEN:
PreMaster Secret:
0000: 00 70 C5 7E 91 38 C8 DE   ED 75 3D 76 8A B5 44 69  .p...8...u=v..Di
0010: E7 32 1C EE 80 77 50 C7   A9 51 24 2E E3 15 11 30  .2...wP..Q$....0
0020: 9D F6 9F BC 9D EB 5C 18   F7 A4 19 ED 1A AC 2E 0C  ......\.........
0030: E3 18 C5 11 B1 80 07 7D   B1 C6 70 A8 D7 EB CF DD  ..........p.....
0040: 2D B5 1D BC 01 3E 28 2A   2B 5B 38 8F EB 20 F2 A2  -....>(*+[8.. ..
0050: 00 07 47 F7 87 B8 99 CB   EF B4 13 04 C8 8B 82 FB  ..G.............


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Expected result is that every connection succeed.
ACTUAL -
Roughly one out of 256 connections fail.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
Java server:

import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;

public class TestServer {
    public static void main(String args[]) throws Exception {
SSLServerSocketFactory ssf = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
SSLServerSocket ss = (SSLServerSocket) ssf.createServerSocket(9999);
System.out.println( " Listening on port 9999 " );
for (String cs : ss.getEnabledCipherSuites()) {
    System.out.println(cs);
}
while (true) {
    SSLSocket s = (SSLSocket) ss.accept();
    System.out.println( " Connected with  " +s.getSession().getCipherSuite());
    s.close();
}
    }
}

Run as as follows:

keytool -storepass  " password "  -keypass  " password "  -genkey -keyalg RSA -keystore test_keystore.jks -dname CN=test
javac TestServer.java
java -Djavax.net.debug=all -Djavax.net.ssl.keyStore=./test_keystore.jks -Djavax.net.ssl.keyStorePassword=password TestServer

OpenSSL client:

set -e
while true; do
  openssl s_client -cipher DHE-RSA-AES128-SHA -connect 127.0.0.1:9999 -quiet -no_ign_eof < /dev/null
done



---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Disable Diffie-Hellman cipher suites.
                                    

Comments
Example stacktrace when error is seen (we should always include a stacktrace example for search ability)

Java server:

javax.net.ssl.SSLHandshakeException: Invalid Padding length: 121
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1886)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:974)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:882)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:102)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:154)
at java.io.BufferedReader.readLine(BufferedReader.java:317)
at java.io.BufferedReader.readLine(BufferedReader.java:382)
at EchoServer.main(EchoServer.java:27)
Caused by: javax.crypto.BadPaddingException: Invalid Padding length: 121
at sun.security.ssl.CipherBox.removePadding(CipherBox.java:684)
at sun.security.ssl.CipherBox.decrypt(CipherBox.java:423)
at sun.security.ssl.InputRecord.decrypt(InputRecord.java:154)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:969)

I've just seen JDK-8013059 - I believe that's a duplicate and will close it out.
                                     
2013-10-25
com/sun/crypto/provider/TLS/TestLeadingZeroes.java
sun/security/pkcs11/tls/TestLeadingZeroesP11.java

have passed from B94 - B96
                                     
2013-07-01
URL:   http://hg.openjdk.java.net/jdk8/jdk8/jdk/rev/6407106f1b1c
User:  lana
Date:  2013-06-11 18:41:37 +0000

                                     
2013-06-11
URL:   http://hg.openjdk.java.net/jdk8/tl/jdk/rev/6407106f1b1c
User:  xuelei
Date:  2013-05-31 05:04:04 +0000

                                     
2013-05-31
The submitter has also submitted a patch to the bugzilla instance.  OCA has been signed.

    https://bugs.openjdk.java.net/show_bug.cgi?id=100316

                                     
2013-05-15



Hardware and Software, Engineered to Work Together