Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8019284

Intermittent SSLHandshakeException when connecting to a Java SSL Server

XMLWordPrintable

      FULL PRODUCT VERSION :
      java version " 1.7.0_15 "
      Java(TM) SE Runtime Environment (build 1.7.0_15-b03)
      Java HotSpot(TM) 64-Bit Server VM (build 23.7-b01, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Linux nds-d1.calnet.1918.berkeley.edu 2.6.32-358.el6.x86_64 #1 SMP Tue Jan 29 11:47:41 EST 2013 x86_64 x86_64 x86_64 GNU/Linux

      A DESCRIPTION OF THE PROBLEM :
      I discovered this problem while using a Perl script to communicate with a Java LDAP server on SSL. I have been able to replicate the problem with a minimalistic Java SSL server and a Perl or bash+openssl client.

      When you repeatedly open a SSL socket to the Java server, exhange some data and then close the socket, after a variable number of tries (in the hundreds) you get a SSL handshake error.

      This used to work just fine with JDK 1.6.

      The same problem is present both in Oracle JDK 1.7 and OpenJDK 1.7

      REGRESSION. Last worked in version 6u31

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Execute the EchoServer java server with the command

      java -Djavax.net.ssl.keyStore=$HOME/keystore.jks -Djavax.net.ssl.keyStorePassword=changeme EchoServer

      While the server is running, on another terminal (or another machine, it doesn't matter) run either

      perl ssl-client.pl

      (Perl client), or

      ./ssl-client.sh b

      (bash script). Let it run, after a few hundreds of iterations the client will get an error and you will see an exception on the server.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      I'd expect arriving at least to 2000 iterations without any problem
      ACTUAL -
      After a few hundreds iteration, I get an error on the client and an exception on the server.


      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      Perl client:

      failed connect or ssl handshake: ,IO::Socket::INET configuration failederror:00000000:lib(0):func(0):reason(0) at ssl-client.pl line 6.

      bash/openssl client:

      139899289216840:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:1193:SSL alert number 40
      139899289216840:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:184:

      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)
      ... 11 more


      (the number after the " Invalid padding length " message varies from one execution to another)

      REPRODUCIBILITY :
      This bug can be reproduced often.

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

      import javax.net.ssl.SSLServerSocket;
      import javax.net.ssl.SSLServerSocketFactory;
      import javax.net.ssl.SSLSocket;
      import java.io.BufferedReader;
      import java.io.InputStream;
      import java.io.InputStreamReader;

      public
      class EchoServer {
          public
                  static
          void
                  main(String[] arstring) {
              try {
                  SSLServerSocketFactory sslserversocketfactory =
                          (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
                  SSLServerSocket sslserversocket =
                          (SSLServerSocket) sslserversocketfactory.createServerSocket(9999);
      while (true) {
                  SSLSocket sslsocket = (SSLSocket) sslserversocket.accept();

                  InputStream inputstream = sslsocket.getInputStream();
                  InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
                  BufferedReader bufferedreader = new BufferedReader(inputstreamreader);

                  String string = null;
                  while ((string = bufferedreader.readLine()) != null) {
                      System.out.println(string);
                      System.out.flush();
      }

                  }
              } catch (Exception exception) {
                  exception.printStackTrace();
              }
          }
      }

      Perl client:

      use strict;
      use IO::Socket::SSL;
      my $count=0;
      while (1) {
          # simple HTTP client -----------------------------------------------
          my $sock = IO::Socket::SSL->new(
              # where to connect
              PeerHost => " nds-d1.calnet.1918.berkeley.edu " ,
              PeerPort => " 9999 " ,

              # certificate verification
              SSL_verify_mode => SSL_VERIFY_NONE,

          ) or die " failed connect or ssl handshake: $!,$SSL_ERROR " ;

          print $sock " Hello " ;
          $sock->close();
          $count++;
          print " $count
       " ;
      }

      Bash client:

      count=0
      while [ 1 -eq 1 ]
      do
      openssl s_client -connect nds-d1.calnet.1918.berkeley.edu:9999 <hello.txt >/dev/null
      if [ $? -ne 0 ]; then
      exit 1
      fi
      ((count+=1))
      echo $count
      done

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

      CUSTOMER SUBMITTED WORKAROUND :
      No workaround found

            xuelei Xuelei Fan
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: