src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java

Print this page
rev 10851 : Implement TLS_FALLBACK_SCSV


 286     final private Object        handshakeLock = new Object();
 287     final ReentrantLock         writeLock = new ReentrantLock();
 288     final private Object        readLock = new Object();
 289 
 290     private InputRecord         inrec;
 291 
 292     /*
 293      * Crypto state that's reinitialized when the session changes.
 294      */
 295     private Authenticator       readAuthenticator, writeAuthenticator;
 296     private CipherBox           readCipher, writeCipher;
 297     // NOTE: compression state would be saved here
 298 
 299     /*
 300      * security parameters for secure renegotiation.
 301      */
 302     private boolean             secureRenegotiation;
 303     private byte[]              clientVerifyData;
 304     private byte[]              serverVerifyData;
 305 



 306     /*
 307      * The authentication context holds all information used to establish
 308      * who this end of the connection is (certificate chains, private keys,
 309      * etc) and who is trusted (e.g. as CAs or websites).
 310      */
 311     private SSLContextImpl      sslContext;
 312 
 313 
 314     /*
 315      * This connection is one of (potentially) many associated with
 316      * any given session.  The output of the handshake protocol is a
 317      * new session ... although all the protocol description talks
 318      * about changing the cipher spec (and it does change), in fact
 319      * that's incidental since it's done by changing everything that
 320      * is associated with a session at the same time.  (TLS/IETF may
 321      * change that to add client authentication w/o new key exchg.)
 322      */
 323     private Handshaker                  handshaker;
 324     private SSLSessionImpl              sess;
 325     private volatile SSLSessionImpl     handshakeSession;


1282 
1283         // state is either cs_START or cs_DATA
1284         if (connectionState == cs_START) {
1285             connectionState = cs_HANDSHAKE;
1286         } else { // cs_DATA
1287             connectionState = cs_RENEGOTIATE;
1288         }
1289         if (roleIsServer) {
1290             handshaker = new ServerHandshaker(this, sslContext,
1291                     enabledProtocols, doClientAuth,
1292                     protocolVersion, connectionState == cs_HANDSHAKE,
1293                     secureRenegotiation, clientVerifyData, serverVerifyData);
1294             handshaker.setSNIMatchers(sniMatchers);
1295             handshaker.setUseCipherSuitesOrder(preferLocalCipherSuites);
1296         } else {
1297             handshaker = new ClientHandshaker(this, sslContext,
1298                     enabledProtocols,
1299                     protocolVersion, connectionState == cs_HANDSHAKE,
1300                     secureRenegotiation, clientVerifyData, serverVerifyData);
1301             handshaker.setSNIServerNames(serverNames);

1302         }
1303         handshaker.setEnabledCipherSuites(enabledCipherSuites);
1304         handshaker.setEnableSessionCreation(enableSessionCreation);
1305     }
1306 
1307     /**
1308      * Synchronously perform the initial handshake.
1309      *
1310      * If the handshake is already in progress, this method blocks until it
1311      * is completed. If the initial handshake has already been completed,
1312      * it returns immediately.
1313      */
1314     private void performInitialHandshake() throws IOException {
1315         // use handshakeLock and the state check to make sure only
1316         // one thread performs the handshake
1317         synchronized (handshakeLock) {
1318             if (getConnectionState() == cs_HANDSHAKE) {
1319                 kickstartHandshake();
1320 
1321                 /*


2495             throw new IllegalArgumentException("listener not registered");
2496         }
2497         if (handshakeListeners.isEmpty()) {
2498             handshakeListeners = null;
2499         }
2500     }
2501 
2502     /**
2503      * Returns the SSLParameters in effect for this SSLSocket.
2504      */
2505     @Override
2506     synchronized public SSLParameters getSSLParameters() {
2507         SSLParameters params = super.getSSLParameters();
2508 
2509         // the super implementation does not handle the following parameters
2510         params.setEndpointIdentificationAlgorithm(identificationProtocol);
2511         params.setAlgorithmConstraints(algorithmConstraints);
2512         params.setSNIMatchers(sniMatchers);
2513         params.setServerNames(serverNames);
2514         params.setUseCipherSuitesOrder(preferLocalCipherSuites);

2515 
2516         return params;
2517     }
2518 
2519     /**
2520      * Applies SSLParameters to this socket.
2521      */
2522     @Override
2523     synchronized public void setSSLParameters(SSLParameters params) {
2524         super.setSSLParameters(params);
2525 
2526         // the super implementation does not handle the following parameters
2527         identificationProtocol = params.getEndpointIdentificationAlgorithm();
2528         algorithmConstraints = params.getAlgorithmConstraints();
2529         preferLocalCipherSuites = params.getUseCipherSuitesOrder();

2530 
2531         List<SNIServerName> sniNames = params.getServerNames();
2532         if (sniNames != null) {
2533             serverNames = sniNames;
2534         }
2535 
2536         Collection<SNIMatcher> matchers = params.getSNIMatchers();
2537         if (matchers != null) {
2538             sniMatchers = matchers;
2539         }
2540 
2541         if ((handshaker != null) && !handshaker.started()) {
2542             handshaker.setIdentificationProtocol(identificationProtocol);
2543             handshaker.setAlgorithmConstraints(algorithmConstraints);
2544             if (roleIsServer) {
2545                 handshaker.setSNIMatchers(sniMatchers);
2546                 handshaker.setUseCipherSuitesOrder(preferLocalCipherSuites);
2547             } else {
2548                 handshaker.setSNIServerNames(serverNames);

2549             }
2550         }
2551     }
2552 
2553     //
2554     // We allocate a separate thread to deliver handshake completion
2555     // events.  This ensures that the notifications don't block the
2556     // protocol state machine.
2557     //
2558     private static class NotifyHandshakeThread extends Thread {
2559 
2560         private Set<Map.Entry<HandshakeCompletedListener,AccessControlContext>>
2561                 targets;        // who gets notified
2562         private HandshakeCompletedEvent event;          // the notification
2563 
2564         NotifyHandshakeThread(
2565             Set<Map.Entry<HandshakeCompletedListener,AccessControlContext>>
2566             entrySet, HandshakeCompletedEvent e) {
2567 
2568             super("HandshakeCompletedNotify-Thread");




 286     final private Object        handshakeLock = new Object();
 287     final ReentrantLock         writeLock = new ReentrantLock();
 288     final private Object        readLock = new Object();
 289 
 290     private InputRecord         inrec;
 291 
 292     /*
 293      * Crypto state that's reinitialized when the session changes.
 294      */
 295     private Authenticator       readAuthenticator, writeAuthenticator;
 296     private CipherBox           readCipher, writeCipher;
 297     // NOTE: compression state would be saved here
 298 
 299     /*
 300      * security parameters for secure renegotiation.
 301      */
 302     private boolean             secureRenegotiation;
 303     private byte[]              clientVerifyData;
 304     private byte[]              serverVerifyData;
 305 
 306     // Whether to send TLS_FALLBACK_SCSV as part of the cipher suite list.
 307     private boolean sendFallbackSCSV;
 308 
 309     /*
 310      * The authentication context holds all information used to establish
 311      * who this end of the connection is (certificate chains, private keys,
 312      * etc) and who is trusted (e.g. as CAs or websites).
 313      */
 314     private SSLContextImpl      sslContext;
 315 
 316 
 317     /*
 318      * This connection is one of (potentially) many associated with
 319      * any given session.  The output of the handshake protocol is a
 320      * new session ... although all the protocol description talks
 321      * about changing the cipher spec (and it does change), in fact
 322      * that's incidental since it's done by changing everything that
 323      * is associated with a session at the same time.  (TLS/IETF may
 324      * change that to add client authentication w/o new key exchg.)
 325      */
 326     private Handshaker                  handshaker;
 327     private SSLSessionImpl              sess;
 328     private volatile SSLSessionImpl     handshakeSession;


1285 
1286         // state is either cs_START or cs_DATA
1287         if (connectionState == cs_START) {
1288             connectionState = cs_HANDSHAKE;
1289         } else { // cs_DATA
1290             connectionState = cs_RENEGOTIATE;
1291         }
1292         if (roleIsServer) {
1293             handshaker = new ServerHandshaker(this, sslContext,
1294                     enabledProtocols, doClientAuth,
1295                     protocolVersion, connectionState == cs_HANDSHAKE,
1296                     secureRenegotiation, clientVerifyData, serverVerifyData);
1297             handshaker.setSNIMatchers(sniMatchers);
1298             handshaker.setUseCipherSuitesOrder(preferLocalCipherSuites);
1299         } else {
1300             handshaker = new ClientHandshaker(this, sslContext,
1301                     enabledProtocols,
1302                     protocolVersion, connectionState == cs_HANDSHAKE,
1303                     secureRenegotiation, clientVerifyData, serverVerifyData);
1304             handshaker.setSNIServerNames(serverNames);
1305             handshaker.setSendFallbackSCSV(sendFallbackSCSV);
1306         }
1307         handshaker.setEnabledCipherSuites(enabledCipherSuites);
1308         handshaker.setEnableSessionCreation(enableSessionCreation);
1309     }
1310 
1311     /**
1312      * Synchronously perform the initial handshake.
1313      *
1314      * If the handshake is already in progress, this method blocks until it
1315      * is completed. If the initial handshake has already been completed,
1316      * it returns immediately.
1317      */
1318     private void performInitialHandshake() throws IOException {
1319         // use handshakeLock and the state check to make sure only
1320         // one thread performs the handshake
1321         synchronized (handshakeLock) {
1322             if (getConnectionState() == cs_HANDSHAKE) {
1323                 kickstartHandshake();
1324 
1325                 /*


2499             throw new IllegalArgumentException("listener not registered");
2500         }
2501         if (handshakeListeners.isEmpty()) {
2502             handshakeListeners = null;
2503         }
2504     }
2505 
2506     /**
2507      * Returns the SSLParameters in effect for this SSLSocket.
2508      */
2509     @Override
2510     synchronized public SSLParameters getSSLParameters() {
2511         SSLParameters params = super.getSSLParameters();
2512 
2513         // the super implementation does not handle the following parameters
2514         params.setEndpointIdentificationAlgorithm(identificationProtocol);
2515         params.setAlgorithmConstraints(algorithmConstraints);
2516         params.setSNIMatchers(sniMatchers);
2517         params.setServerNames(serverNames);
2518         params.setUseCipherSuitesOrder(preferLocalCipherSuites);
2519         params.setSendFallbackSCSV(sendFallbackSCSV);
2520 
2521         return params;
2522     }
2523 
2524     /**
2525      * Applies SSLParameters to this socket.
2526      */
2527     @Override
2528     synchronized public void setSSLParameters(SSLParameters params) {
2529         super.setSSLParameters(params);
2530 
2531         // the super implementation does not handle the following parameters
2532         identificationProtocol = params.getEndpointIdentificationAlgorithm();
2533         algorithmConstraints = params.getAlgorithmConstraints();
2534         preferLocalCipherSuites = params.getUseCipherSuitesOrder();
2535         sendFallbackSCSV = params.getSendFallbackSCSV();
2536 
2537         List<SNIServerName> sniNames = params.getServerNames();
2538         if (sniNames != null) {
2539             serverNames = sniNames;
2540         }
2541 
2542         Collection<SNIMatcher> matchers = params.getSNIMatchers();
2543         if (matchers != null) {
2544             sniMatchers = matchers;
2545         }
2546 
2547         if ((handshaker != null) && !handshaker.started()) {
2548             handshaker.setIdentificationProtocol(identificationProtocol);
2549             handshaker.setAlgorithmConstraints(algorithmConstraints);
2550             if (roleIsServer) {
2551                 handshaker.setSNIMatchers(sniMatchers);
2552                 handshaker.setUseCipherSuitesOrder(preferLocalCipherSuites);
2553             } else {
2554                 handshaker.setSNIServerNames(serverNames);
2555                 handshaker.setSendFallbackSCSV(sendFallbackSCSV);
2556             }
2557         }
2558     }
2559 
2560     //
2561     // We allocate a separate thread to deliver handshake completion
2562     // events.  This ensures that the notifications don't block the
2563     // protocol state machine.
2564     //
2565     private static class NotifyHandshakeThread extends Thread {
2566 
2567         private Set<Map.Entry<HandshakeCompletedListener,AccessControlContext>>
2568                 targets;        // who gets notified
2569         private HandshakeCompletedEvent event;          // the notification
2570 
2571         NotifyHandshakeThread(
2572             Set<Map.Entry<HandshakeCompletedListener,AccessControlContext>>
2573             entrySet, HandshakeCompletedEvent e) {
2574 
2575             super("HandshakeCompletedNotify-Thread");