src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/SSLDelegate.java
changeset 48083 b1c1b4ef4be2
parent 47216 71c04702a3d5
child 55973 4d9b002587db
equal deleted inserted replaced
48081:89829dd3cc54 48083:b1c1b4ef4be2
    26 package jdk.incubator.http;
    26 package jdk.incubator.http;
    27 
    27 
    28 import java.io.IOException;
    28 import java.io.IOException;
    29 import java.nio.ByteBuffer;
    29 import java.nio.ByteBuffer;
    30 import java.nio.channels.SocketChannel;
    30 import java.nio.channels.SocketChannel;
    31 import java.util.Arrays;
       
    32 import java.util.List;
       
    33 import java.util.concurrent.locks.Lock;
    31 import java.util.concurrent.locks.Lock;
    34 import java.util.concurrent.locks.ReentrantLock;
    32 import java.util.concurrent.locks.ReentrantLock;
    35 import javax.net.ssl.SSLEngineResult.HandshakeStatus;
    33 import javax.net.ssl.SSLEngineResult.HandshakeStatus;
    36 import javax.net.ssl.SSLEngineResult.Status;
    34 import javax.net.ssl.SSLEngineResult.Status;
    37 import javax.net.ssl.*;
    35 import javax.net.ssl.*;
    39 import jdk.incubator.http.internal.common.Utils;
    37 import jdk.incubator.http.internal.common.Utils;
    40 import static javax.net.ssl.SSLEngineResult.HandshakeStatus.*;
    38 import static javax.net.ssl.SSLEngineResult.HandshakeStatus.*;
    41 
    39 
    42 /**
    40 /**
    43  * Implements the mechanics of SSL by managing an SSLEngine object.
    41  * Implements the mechanics of SSL by managing an SSLEngine object.
    44  * One of these is associated with each SSLConnection.
    42  * <p>
       
    43  * This class is only used to implement the {@link
       
    44  * AbstractAsyncSSLConnection.SSLConnectionChannel} which is handed of
       
    45  * to RawChannelImpl when creating a WebSocket.
    45  */
    46  */
    46 class SSLDelegate {
    47 class SSLDelegate {
    47 
    48 
    48     final SSLEngine engine;
    49     final SSLEngine engine;
    49     final EngineWrapper wrapper;
    50     final EngineWrapper wrapper;
    50     final Lock handshaking = new ReentrantLock();
    51     final Lock handshaking = new ReentrantLock();
    51     final SSLParameters sslParameters;
       
    52     final SocketChannel chan;
    52     final SocketChannel chan;
    53     final HttpClientImpl client;
    53 
    54     final String serverName;
    54     SSLDelegate(SSLEngine eng, SocketChannel chan)
    55 
       
    56     SSLDelegate(SSLEngine eng, SocketChannel chan, HttpClientImpl client, String sn)
       
    57     {
    55     {
    58         this.engine = eng;
    56         this.engine = eng;
    59         this.chan = chan;
    57         this.chan = chan;
    60         this.client = client;
       
    61         this.wrapper = new EngineWrapper(chan, engine);
    58         this.wrapper = new EngineWrapper(chan, engine);
    62         this.sslParameters = engine.getSSLParameters();
       
    63         this.serverName = sn;
       
    64     }
    59     }
    65 
    60 
    66     // alpn[] may be null
    61     // alpn[] may be null
    67     SSLDelegate(SocketChannel chan, HttpClientImpl client, String[] alpn, String sn)
    62 //    SSLDelegate(SocketChannel chan, HttpClientImpl client, String[] alpn, String sn)
    68         throws IOException
    63 //        throws IOException
    69     {
    64 //    {
    70         serverName = sn;
    65 //        serverName = sn;
    71         SSLContext context = client.sslContext();
    66 //        SSLContext context = client.sslContext();
    72         engine = context.createSSLEngine();
    67 //        engine = context.createSSLEngine();
    73         engine.setUseClientMode(true);
    68 //        engine.setUseClientMode(true);
    74         SSLParameters sslp = client.sslParameters()
    69 //        SSLParameters sslp = client.sslParameters();
    75                                    .orElseGet(context::getSupportedSSLParameters);
    70 //        sslParameters = Utils.copySSLParameters(sslp);
    76         sslParameters = Utils.copySSLParameters(sslp);
    71 //        if (sn != null) {
    77         if (sn != null) {
    72 //            SNIHostName sni = new SNIHostName(sn);
    78             SNIHostName sni = new SNIHostName(sn);
    73 //            sslParameters.setServerNames(List.of(sni));
    79             sslParameters.setServerNames(List.of(sni));
    74 //        }
    80         }
    75 //        if (alpn != null) {
    81         if (alpn != null) {
    76 //            sslParameters.setApplicationProtocols(alpn);
    82             sslParameters.setApplicationProtocols(alpn);
    77 //            Log.logSSL("SSLDelegate: Setting application protocols: {0}" + Arrays.toString(alpn));
    83             Log.logSSL("SSLDelegate: Setting application protocols: {0}" + Arrays.toString(alpn));
    78 //        } else {
    84         } else {
    79 //            Log.logSSL("SSLDelegate: No application protocols proposed");
    85             Log.logSSL("SSLDelegate: No application protocols proposed");
    80 //        }
    86         }
    81 //        engine.setSSLParameters(sslParameters);
    87         engine.setSSLParameters(sslParameters);
    82 //        wrapper = new EngineWrapper(chan, engine);
    88         wrapper = new EngineWrapper(chan, engine);
    83 //        this.chan = chan;
    89         this.chan = chan;
    84 //        this.client = client;
    90         this.client = client;
    85 //    }
    91     }
    86 
    92 
    87 //    SSLParameters getSSLParameters() {
    93     SSLParameters getSSLParameters() {
    88 //        return sslParameters;
    94         return sslParameters;
    89 //    }
    95     }
    90 
    96 
    91     static long countBytes(ByteBuffer[] buffers, int start, int number) {
    97     private static long countBytes(ByteBuffer[] buffers, int start, int number) {
       
    98         long c = 0;
    92         long c = 0;
    99         for (int i=0; i<number; i++) {
    93         for (int i=0; i<number; i++) {
   100             c+= buffers[start+i].remaining();
    94             c+= buffers[start+i].remaining();
   101         }
    95         }
   102         return c;
    96         return c;
   189      */
   183      */
   190     class EngineWrapper {
   184     class EngineWrapper {
   191 
   185 
   192         SocketChannel chan;
   186         SocketChannel chan;
   193         SSLEngine engine;
   187         SSLEngine engine;
   194         Object wrapLock, unwrapLock;
   188         final Object wrapLock;
       
   189         final Object unwrapLock;
   195         ByteBuffer unwrap_src, wrap_dst;
   190         ByteBuffer unwrap_src, wrap_dst;
   196         boolean closed = false;
   191         boolean closed = false;
   197         int u_remaining; // the number of bytes left in unwrap_src after an unwrap()
   192         int u_remaining; // the number of bytes left in unwrap_src after an unwrap()
   198 
   193 
   199         EngineWrapper (SocketChannel chan, SSLEngine engine) {
   194         EngineWrapper (SocketChannel chan, SSLEngine engine) {
   203             unwrapLock = new Object();
   198             unwrapLock = new Object();
   204             unwrap_src = allocate(BufType.PACKET);
   199             unwrap_src = allocate(BufType.PACKET);
   205             wrap_dst = allocate(BufType.PACKET);
   200             wrap_dst = allocate(BufType.PACKET);
   206         }
   201         }
   207 
   202 
   208         void close () throws IOException {
   203 //        void close () throws IOException {
   209         }
   204 //        }
   210 
   205 
   211         WrapperResult wrapAndSend(ByteBuffer src, boolean ignoreClose)
   206         WrapperResult wrapAndSend(ByteBuffer src, boolean ignoreClose)
   212             throws IOException
   207             throws IOException
   213         {
   208         {
   214             ByteBuffer[] buffers = new ByteBuffer[1];
   209             ByteBuffer[] buffers = new ByteBuffer[1];
   318             u_remaining = unwrap_src.remaining();
   313             u_remaining = unwrap_src.remaining();
   319             return r;
   314             return r;
   320         }
   315         }
   321     }
   316     }
   322 
   317 
   323     WrapperResult sendData (ByteBuffer src) throws IOException {
   318 //    WrapperResult sendData (ByteBuffer src) throws IOException {
   324         ByteBuffer[] buffers = new ByteBuffer[1];
   319 //        ByteBuffer[] buffers = new ByteBuffer[1];
   325         buffers[0] = src;
   320 //        buffers[0] = src;
   326         return sendData(buffers, 0, 1);
   321 //        return sendData(buffers, 0, 1);
   327     }
   322 //    }
   328 
   323 
   329     /**
   324     /**
   330      * send the data in the given ByteBuffer. If a handshake is needed
   325      * send the data in the given ByteBuffer. If a handshake is needed
   331      * then this is handled within this method. When this call returns,
   326      * then this is handled within this method. When this call returns,
   332      * all of the given user data has been sent and any handshake has been
   327      * all of the given user data has been sent and any handshake has been
   405      * on the wrapper methods being idempotent. eg. if wrapAndSend()
   400      * on the wrapper methods being idempotent. eg. if wrapAndSend()
   406      * is called with no data to send then there must be no problem
   401      * is called with no data to send then there must be no problem
   407      */
   402      */
   408     @SuppressWarnings("fallthrough")
   403     @SuppressWarnings("fallthrough")
   409     void doHandshake (HandshakeStatus hs_status) throws IOException {
   404     void doHandshake (HandshakeStatus hs_status) throws IOException {
   410         boolean wasBlocking = false;
   405         boolean wasBlocking;
   411         try {
   406         try {
   412             wasBlocking = chan.isBlocking();
   407             wasBlocking = chan.isBlocking();
   413             handshaking.lock();
   408             handshaking.lock();
   414             chan.configureBlocking(true);
   409             chan.configureBlocking(true);
   415             ByteBuffer tmp = allocate(BufType.APPLICATION);
   410             ByteBuffer tmp = allocate(BufType.APPLICATION);
   451         } finally {
   446         } finally {
   452             handshaking.unlock();
   447             handshaking.unlock();
   453         }
   448         }
   454     }
   449     }
   455 
   450 
   456     static void printParams(SSLParameters p) {
   451 //    static void printParams(SSLParameters p) {
   457         System.out.println("SSLParameters:");
   452 //        System.out.println("SSLParameters:");
   458         if (p == null) {
   453 //        if (p == null) {
   459             System.out.println("Null params");
   454 //            System.out.println("Null params");
   460             return;
   455 //            return;
   461         }
   456 //        }
   462         for (String cipher : p.getCipherSuites()) {
   457 //        for (String cipher : p.getCipherSuites()) {
   463                 System.out.printf("cipher: %s\n", cipher);
   458 //                System.out.printf("cipher: %s\n", cipher);
   464         }
   459 //        }
   465         // JDK 8 EXCL START
   460 //        // JDK 8 EXCL START
   466         for (String approto : p.getApplicationProtocols()) {
   461 //        for (String approto : p.getApplicationProtocols()) {
   467                 System.out.printf("application protocol: %s\n", approto);
   462 //                System.out.printf("application protocol: %s\n", approto);
   468         }
   463 //        }
   469         // JDK 8 EXCL END
   464 //        // JDK 8 EXCL END
   470         for (String protocol : p.getProtocols()) {
   465 //        for (String protocol : p.getProtocols()) {
   471                 System.out.printf("protocol: %s\n", protocol);
   466 //                System.out.printf("protocol: %s\n", protocol);
   472         }
   467 //        }
   473         if (p.getServerNames() != null) {
   468 //        if (p.getServerNames() != null) {
   474             for (SNIServerName sname : p.getServerNames()) {
   469 //            for (SNIServerName sname : p.getServerNames()) {
   475                 System.out.printf("server name: %s\n", sname.toString());
   470 //                System.out.printf("server name: %s\n", sname.toString());
   476             }
   471 //            }
   477         }
   472 //        }
   478     }
   473 //    }
   479 
   474 
   480     String getSessionInfo() {
   475     String getSessionInfo() {
   481         StringBuilder sb = new StringBuilder();
   476         StringBuilder sb = new StringBuilder();
   482         String application = engine.getApplicationProtocol();
   477         String application = engine.getApplicationProtocol();
   483         SSLSession sess = engine.getSession();
   478         SSLSession sess = engine.getSession();