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

Interrupts are not handled correctly by SSLSocket

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P2 P2
    • unknown
    • 1.0.2
    • security-libs
    • None
    • ventura
    • generic
    • generic

      When Thread.interrupt is called on a thread which is blocked on an
      SSLSocket.read then the interrupt exception is masked by JSSE and
      the read method returns with an end-of-stream error. I expect the
      interrupt exception to be thrown, as is done for non-SSL sockets.

      The LDAP provider in JNDI depends on JSSE and has a requirement to
      interrupt an SSLSocket.read operation in order to switch input streams.
      This can occur, for example, when a TLS connection has been established
      over an existing socket (without client authentication) and the JNDI user
      wishes to perform client authentication using a public key certificate.

      The problem can be demonstrated using the program below.


      Here is a trace of the plain socket case: the interrupt is thrown,
      as expected.

      % /usr/local/java/jdk1.4/solsparc/bin/java
        TestSocketInterrupt oasis.ireland.sun.com 389

      Establishing a plain connection ...
      Connected to: oasis.ireland.sun.com:389
      Pausing for 5 seconds ...
      Reading from input stream ...
      Interrupting reader thread
      java.io.InterruptedIOException: Interrupted system call
              at java.net.SocketInputStream.socketRead(Native Method)
              at java.net.SocketInputStream.read(SocketInputStream.java:99)
              at java.net.SocketInputStream.read(SocketInputStream.java:115)
              at TestSocketInterrupt$Reader.run(TestSocketInterrupt.java:84)




      Here is a trace of the SSL socket case: the interrupt is masked.

      % /usr/local/java/jdk1.4/solsparc/bin/java
        TestSocketInterrupt -ssl oasis.ireland.sun.com 636

      Establishing an SSL connection ...
      Connected to: oasis.ireland.sun.com:636
      Pausing for 5 seconds ...
      Reading from input stream ...
      Interrupting reader thread
      End-of-stream detected



      /*
       * Copyright (c) 2000. Sun Microsystems, Inc. All rights reserved.
       */

      import java.io.InputStream;
      import java.net.Socket;
      import javax.net.ssl.SSLContext;
      import javax.net.ssl.SSLSocketFactory;

      /**
       * Demonstrate that an SSL socket blocked on a read cannot be
       * interrupted correctly.
       *
       * Usage: java TestSocketInterrupt [-ssl] <hostname> <port number>
       *
       * Example: java TestSocketInterrupt -ssl oasis.ireland.sun.com 636
       *
       * Requires: JDK 1.4 (Merlin)
       */

      public class TestSocketInterrupt {

          public static void main(String[] args) {

              boolean useSSL;
              String host;
              int port;
              Socket socket;

              if (args[0].equals("-ssl")) {
                  useSSL = true;
                  host = args[1];
                  port = Integer.parseInt(args[2]);
              } else {
                  useSSL = false;
                  host = args[0];
                  port = Integer.parseInt(args[1]);
              }

              try {
                  if (useSSL) {
                      System.out.println("Establishing an SSL connection ...");
                      SSLContext sslCtx = SSLContext.getInstance("TLS");
                      sslCtx.init(null, null, null);
                      SSLSocketFactory factory = sslCtx.getSocketFactory();
                      socket = (Socket) factory.createSocket(host, port);
                  } else {
                      System.out.println("Establishing a plain connection ...");
                      socket = new Socket(host, port);
                  }

                  InputStream inStream = socket.getInputStream();
                  System.out.println("Connected to: " + host + ":" + port);

                  Reader reader = new Reader(inStream);
                  reader.start();

                  // sleep for 5 seconds
                  System.out.println("Pausing for 5 seconds ...");
                  try {
                      Thread.sleep(5 * 1000);
                  } catch (Exception e) {
                      e.printStackTrace();
                  }

                  System.out.println("Interrupting reader thread");
                  reader.interrupt();

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

          static class Reader extends Thread {
              private InputStream inStream;

              public Reader(InputStream inStream) {
                  this.inStream = inStream;
              }

              public void run() {
                  try {
                      System.out.println("Reading from input stream ...");
                      if (inStream.read() == -1) {
                          System.out.println("End-of-stream detected");
                      }
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
              }
          }
      }

            mupadhyasunw Mayank Upadhyay (Inactive)
            vinnie Vincent Ryan
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: