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");
|