History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/security/ssl/SSLSocketImpl.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/security/ssl/SSLSocketImpl.java+2493−0
@@ -0,0 +1,2493 @@
1/*
2 * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26
27package sun.security.ssl;
28
29import java.io.*;
30import java.net.*;
31import java.security.GeneralSecurityException;
32import java.security.AccessController;
33import java.security.AccessControlContext;
34import java.security.PrivilegedAction;
35import java.security.AlgorithmConstraints;
36import java.util.*;
37import java.util.concurrent.TimeUnit;
38import java.util.concurrent.locks.ReentrantLock;
39
40import javax.crypto.BadPaddingException;
41
42import javax.net.ssl.*;
43
44import com.sun.net.ssl.internal.ssl.X509ExtendedTrustManager;
45
46/**
47 * Implementation of an SSL socket. This is a normal connection type
48 * socket, implementing SSL over some lower level socket, such as TCP.
49 * Because it is layered over some lower level socket, it MUST override
50 * all default socket methods.
51 *
52 * <P> This API offers a non-traditional option for establishing SSL
53 * connections. You may first establish the connection directly, then pass
54 * that connection to the SSL socket constructor with a flag saying which
55 * role should be taken in the handshake protocol. (The two ends of the
56 * connection must not choose the same role!) This allows setup of SSL
57 * proxying or tunneling, and also allows the kind of "role reversal"
58 * that is required for most FTP data transfers.
59 *
60 * @see javax.net.ssl.SSLSocket
61 * @see SSLServerSocket
62 *
63 * @author David Brownell
64 */
65final public class SSLSocketImpl extends BaseSSLSocketImpl {
66
67 /*
68 * ERROR HANDLING GUIDELINES
69 * (which exceptions to throw and catch and which not to throw and catch)
70 *
71 * . if there is an IOException (SocketException) when accessing the
72 * underlying Socket, pass it through
73 *
74 * . do not throw IOExceptions, throw SSLExceptions (or a subclass)
75 *
76 * . for internal errors (things that indicate a bug in JSSE or a
77 * grossly misconfigured J2RE), throw either an SSLException or
78 * a RuntimeException at your convenience.
79 *
80 * . handshaking code (Handshaker or HandshakeMessage) should generally
81 * pass through exceptions, but can handle them if they know what to
82 * do.
83 *
84 * . exception chaining should be used for all new code. If you happen
85 * to touch old code that does not use chaining, you should change it.
86 *
87 * . there is a top level exception handler that sits at all entry
88 * points from application code to SSLSocket read/write code. It
89 * makes sure that all errors are handled (see handleException()).
90 *
91 * . JSSE internal code should generally not call close(), call
92 * closeInternal().
93 */
94
95 /*
96 * There's a state machine associated with each connection, which
97 * among other roles serves to negotiate session changes.
98 *
99 * - START with constructor, until the TCP connection's around.
100 * - HANDSHAKE picks session parameters before allowing traffic.
101 * There are many substates due to sequencing requirements
102 * for handshake messages.
103 * - DATA may be transmitted.
104 * - RENEGOTIATE state allows concurrent data and handshaking
105 * traffic ("same" substates as HANDSHAKE), and terminates
106 * in selection of new session (and connection) parameters
107 * - ERROR state immediately precedes abortive disconnect.
108 * - SENT_CLOSE sent a close_notify to the peer. For layered,
109 * non-autoclose socket, must now read close_notify
110 * from peer before closing the connection. For nonlayered or
111 * non-autoclose socket, close connection and go onto
112 * cs_CLOSED state.
113 * - CLOSED after sending close_notify alert, & socket is closed.
114 * SSL connection objects are not reused.
115 * - APP_CLOSED once the application calls close(). Then it behaves like
116 * a closed socket, e.g.. getInputStream() throws an Exception.
117 *
118 * State affects what SSL record types may legally be sent:
119 *
120 * - Handshake ... only in HANDSHAKE and RENEGOTIATE states
121 * - App Data ... only in DATA and RENEGOTIATE states
122 * - Alert ... in HANDSHAKE, DATA, RENEGOTIATE
123 *
124 * Re what may be received: same as what may be sent, except that
125 * HandshakeRequest handshaking messages can come from servers even
126 * in the application data state, to request entry to RENEGOTIATE.
127 *
128 * The state machine within HANDSHAKE and RENEGOTIATE states controls
129 * the pending session, not the connection state, until the change
130 * cipher spec and "Finished" handshake messages are processed and
131 * make the "new" session become the current one.
132 *
133 * NOTE: details of the SMs always need to be nailed down better.
134 * The text above illustrates the core ideas.
135 *
136 * +---->-------+------>--------->-------+
137 * | | |
138 * <-----< ^ ^ <-----< v
139 *START>----->HANDSHAKE>----->DATA>----->RENEGOTIATE SENT_CLOSE
140 * v v v | |
141 * | | | | v
142 * +------------+---------------+ v ERROR
143 * | | |
144 * v | |
145 * ERROR>------>----->CLOSED<--------<----+-- +
146 * |
147 * v
148 * APP_CLOSED
149 *
150 * ALSO, note that the the purpose of handshaking (renegotiation is
151 * included) is to assign a different, and perhaps new, session to
152 * the connection. The SSLv3 spec is a bit confusing on that new
153 * protocol feature.
154 */
155 private static final int cs_START = 0;
156 private static final int cs_HANDSHAKE = 1;
157 private static final int cs_DATA = 2;
158 private static final int cs_RENEGOTIATE = 3;
159 private static final int cs_ERROR = 4;
160 private static final int cs_SENT_CLOSE = 5;
161 private static final int cs_CLOSED = 6;
162 private static final int cs_APP_CLOSED = 7;
163
164
165 /*
166 * Client authentication be off, requested, or required.
167 *
168 * Migrated to SSLEngineImpl:
169 * clauth_none/cl_auth_requested/clauth_required
170 */
171
172 /*
173 * Drives the protocol state machine.
174 */
175 private int connectionState;
176
177 /*
178 * Flag indicating if the next record we receive MUST be a Finished
179 * message. Temporarily set during the handshake to ensure that
180 * a change cipher spec message is followed by a finished message.
181 */
182 private boolean expectingFinished;
183
184 /*
185 * For improved diagnostics, we detail connection closure
186 * If the socket is closed (connectionState >= cs_ERROR),
187 * closeReason != null indicates if the socket was closed
188 * because of an error or because or normal shutdown.
189 */
190 private SSLException closeReason;
191
192 /*
193 * Per-connection private state that doesn't change when the
194 * session is changed.
195 */
196 private byte doClientAuth;
197 private boolean roleIsServer;
198 private boolean enableSessionCreation = true;
199 private String host;
200 private boolean autoClose = true;
201 private AccessControlContext acc;
202
203 /*
204 * We cannot use the hostname resolved from name services. For
205 * virtual hosting, multiple hostnames may be bound to the same IP
206 * address, so the hostname resolved from name services is not
207 * reliable.
208 */
209 private String rawHostname;
210
211 // The cipher suites enabled for use on this connection.
212 private CipherSuiteList enabledCipherSuites;
213
214 // The endpoint identification protocol
215 private String identificationProtocol = null;
216
217 // The cryptographic algorithm constraints
218 private AlgorithmConstraints algorithmConstraints = null;
219
220 /*
221 * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
222 * IMPORTANT STUFF TO UNDERSTANDING THE SYNCHRONIZATION ISSUES.
223 * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
224 *
225 * There are several locks here.
226 *
227 * The primary lock is the per-instance lock used by
228 * synchronized(this) and the synchronized methods. It controls all
229 * access to things such as the connection state and variables which
230 * affect handshaking. If we are inside a synchronized method, we
231 * can access the state directly, otherwise, we must use the
232 * synchronized equivalents.
233 *
234 * The handshakeLock is used to ensure that only one thread performs
235 * the *complete initial* handshake. If someone is handshaking, any
236 * stray application or startHandshake() requests who find the
237 * connection state is cs_HANDSHAKE will stall on handshakeLock
238 * until handshaking is done. Once the handshake is done, we either
239 * succeeded or failed, but we can never go back to the cs_HANDSHAKE
240 * or cs_START state again.
241 *
242 * Note that the read/write() calls here in SSLSocketImpl are not
243 * obviously synchronized. In fact, it's very nonintuitive, and
244 * requires careful examination of code paths. Grab some coffee,
245 * and be careful with any code changes.
246 *
247 * There can be only three threads active at a time in the I/O
248 * subsection of this class.
249 * 1. startHandshake
250 * 2. AppInputStream
251 * 3. AppOutputStream
252 * One thread could call startHandshake().
253 * AppInputStream/AppOutputStream read() and write() calls are each
254 * synchronized on 'this' in their respective classes, so only one
255 * app. thread will be doing a SSLSocketImpl.read() or .write()'s at
256 * a time.
257 *
258 * If handshaking is required (state cs_HANDSHAKE), and
259 * getConnectionState() for some/all threads returns cs_HANDSHAKE,
260 * only one can grab the handshakeLock, and the rest will stall
261 * either on getConnectionState(), or on the handshakeLock if they
262 * happen to successfully race through the getConnectionState().
263 *
264 * If a writer is doing the initial handshaking, it must create a
265 * temporary reader to read the responses from the other side. As a
266 * side-effect, the writer's reader will have priority over any
267 * other reader. However, the writer's reader is not allowed to
268 * consume any application data. When handshakeLock is finally
269 * released, we either have a cs_DATA connection, or a
270 * cs_CLOSED/cs_ERROR socket.
271 *
272 * The writeLock is held while writing on a socket connection and
273 * also to protect the MAC and cipher for their direction. The
274 * writeLock is package private for Handshaker which holds it while
275 * writing the ChangeCipherSpec message.
276 *
277 * To avoid the problem of a thread trying to change operational
278 * modes on a socket while handshaking is going on, we synchronize
279 * on 'this'. If handshaking has not started yet, we tell the
280 * handshaker to change its mode. If handshaking has started,
281 * we simply store that request until the next pending session
282 * is created, at which time the new handshaker's state is set.
283 *
284 * The readLock is held during readRecord(), which is responsible
285 * for reading an InputRecord, decrypting it, and processing it.
286 * The readLock ensures that these three steps are done atomically
287 * and that once started, no other thread can block on InputRecord.read.
288 * This is necessary so that processing of close_notify alerts
289 * from the peer are handled properly.
290 */
291 final private Object handshakeLock = new Object();
292 final ReentrantLock writeLock = new ReentrantLock();
293 final private Object readLock = new Object();
294
295 private InputRecord inrec;
296
297 /*
298 * Crypto state that's reinitialized when the session changes.
299 */
300 private MAC readMAC, writeMAC;
301 private CipherBox readCipher, writeCipher;
302 // NOTE: compression state would be saved here
303
304 /*
305 * security parameters for secure renegotiation.
306 */
307 private boolean secureRenegotiation;
308 private byte[] clientVerifyData;
309 private byte[] serverVerifyData;
310
311 /*
312 * The authentication context holds all information used to establish
313 * who this end of the connection is (certificate chains, private keys,
314 * etc) and who is trusted (e.g. as CAs or websites).
315 */
316 private SSLContextImpl sslContext;
317
318
319 /*
320 * This connection is one of (potentially) many associated with
321 * any given session. The output of the handshake protocol is a
322 * new session ... although all the protocol description talks
323 * about changing the cipher spec (and it does change), in fact
324 * that's incidental since it's done by changing everything that
325 * is associated with a session at the same time. (TLS/IETF may
326 * change that to add client authentication w/o new key exchg.)
327 */
328 private Handshaker handshaker;
329 private SSLSessionImpl sess;
330 private volatile SSLSessionImpl handshakeSession;
331
332
333 /*
334 * If anyone wants to get notified about handshake completions,
335 * they'll show up on this list.
336 */
337 private HashMap<HandshakeCompletedListener, AccessControlContext>
338 handshakeListeners;
339
340 /*
341 * Reuse the same internal input/output streams.
342 */
343 private InputStream sockInput;
344 private OutputStream sockOutput;
345
346
347 /*
348 * These input and output streams block their data in SSL records,
349 * and usually arrange integrity and privacy protection for those
350 * records. The guts of the SSL protocol are wrapped up in these
351 * streams, and in the handshaking that establishes the details of
352 * that integrity and privacy protection.
353 */
354 private AppInputStream input;
355 private AppOutputStream output;
356
357 /*
358 * The protocol versions enabled for use on this connection.
359 *
360 * Note: we support a pseudo protocol called SSLv2Hello which when
361 * set will result in an SSL v2 Hello being sent with SSL (version 3.0)
362 * or TLS (version 3.1, 3.2, etc.) version info.
363 */
364 private ProtocolList enabledProtocols;
365
366 /*
367 * The SSL version associated with this connection.
368 */
369 private ProtocolVersion protocolVersion = ProtocolVersion.DEFAULT;
370
371 /* Class and subclass dynamic debugging support */
372 private static final Debug debug = Debug.getInstance("ssl");
373
374 //
375 // CONSTRUCTORS AND INITIALIZATION CODE
376 //
377
378 /**
379 * Constructs an SSL connection to a named host at a specified port,
380 * using the authentication context provided. This endpoint acts as
381 * the client, and may rejoin an existing SSL session if appropriate.
382 *
383 * @param context authentication context to use
384 * @param host name of the host with which to connect
385 * @param port number of the server's port
386 */
387 SSLSocketImpl(SSLContextImpl context, String host, int port)
388 throws IOException, UnknownHostException {
389 super();
390 this.host = host;
391 this.rawHostname = host;
392 init(context, false);
393 SocketAddress socketAddress =
394 host != null ? new InetSocketAddress(host, port) :
395 new InetSocketAddress(InetAddress.getByName(null), port);
396 connect(socketAddress, 0);
397 }
398
399
400 /**
401 * Constructs an SSL connection to a server at a specified address.
402 * and TCP port, using the authentication context provided. This
403 * endpoint acts as the client, and may rejoin an existing SSL session
404 * if appropriate.
405 *
406 * @param context authentication context to use
407 * @param address the server's host
408 * @param port its port
409 */
410 SSLSocketImpl(SSLContextImpl context, InetAddress host, int port)
411 throws IOException {
412 super();
413 init(context, false);
414 SocketAddress socketAddress = new InetSocketAddress(host, port);
415 connect(socketAddress, 0);
416 }
417
418 /**
419 * Constructs an SSL connection to a named host at a specified port,
420 * using the authentication context provided. This endpoint acts as
421 * the client, and may rejoin an existing SSL session if appropriate.
422 *
423 * @param context authentication context to use
424 * @param host name of the host with which to connect
425 * @param port number of the server's port
426 * @param localAddr the local address the socket is bound to
427 * @param localPort the local port the socket is bound to
428 */
429 SSLSocketImpl(SSLContextImpl context, String host, int port,
430 InetAddress localAddr, int localPort)
431 throws IOException, UnknownHostException {
432 super();
433 this.host = host;
434 this.rawHostname = host;
435 init(context, false);
436 bind(new InetSocketAddress(localAddr, localPort));
437 SocketAddress socketAddress =
438 host != null ? new InetSocketAddress(host, port) :
439 new InetSocketAddress(InetAddress.getByName(null), port);
440 connect(socketAddress, 0);
441 }
442
443
444 /**
445 * Constructs an SSL connection to a server at a specified address.
446 * and TCP port, using the authentication context provided. This
447 * endpoint acts as the client, and may rejoin an existing SSL session
448 * if appropriate.
449 *
450 * @param context authentication context to use
451 * @param address the server's host
452 * @param port its port
453 * @param localAddr the local address the socket is bound to
454 * @param localPort the local port the socket is bound to
455 */
456 SSLSocketImpl(SSLContextImpl context, InetAddress host, int port,
457 InetAddress localAddr, int localPort)
458 throws IOException {
459 super();
460 init(context, false);
461 bind(new InetSocketAddress(localAddr, localPort));
462 SocketAddress socketAddress = new InetSocketAddress(host, port);
463 connect(socketAddress, 0);
464 }
465
466 /*
467 * Package-private constructor used ONLY by SSLServerSocket. The
468 * java.net package accepts the TCP connection after this call is
469 * made. This just initializes handshake state to use "server mode",
470 * giving control over the use of SSL client authentication.
471 */
472 SSLSocketImpl(SSLContextImpl context, boolean serverMode,
473 CipherSuiteList suites, byte clientAuth,
474 boolean sessionCreation, ProtocolList protocols,
475 String identificationProtocol,
476 AlgorithmConstraints algorithmConstraints) throws IOException {
477
478 super();
479 doClientAuth = clientAuth;
480 enableSessionCreation = sessionCreation;
481 this.identificationProtocol = identificationProtocol;
482 this.algorithmConstraints = algorithmConstraints;
483 init(context, serverMode);
484
485 /*
486 * Override what was picked out for us.
487 */
488 enabledCipherSuites = suites;
489 enabledProtocols = protocols;
490 }
491
492
493 /**
494 * Package-private constructor used to instantiate an unconnected
495 * socket. The java.net package will connect it, either when the
496 * connect() call is made by the application. This instance is
497 * meant to set handshake state to use "client mode".
498 */
499 SSLSocketImpl(SSLContextImpl context) {
500 super();
501 init(context, false);
502 }
503
504
505 /**
506 * Layer SSL traffic over an existing connection, rather than creating
507 * a new connection. The existing connection may be used only for SSL
508 * traffic (using this SSLSocket) until the SSLSocket.close() call
509 * returns. However, if a protocol error is detected, that existing
510 * connection is automatically closed.
511 *
512 * <P> This particular constructor always uses the socket in the
513 * role of an SSL client. It may be useful in cases which start
514 * using SSL after some initial data transfers, for example in some
515 * SSL tunneling applications or as part of some kinds of application
516 * protocols which negotiate use of a SSL based security.
517 *
518 * @param sock the existing connection
519 * @param context the authentication context to use
520 */
521 SSLSocketImpl(SSLContextImpl context, Socket sock, String host,
522 int port, boolean autoClose) throws IOException {
523 super(sock);
524 // We always layer over a connected socket
525 if (!sock.isConnected()) {
526 throw new SocketException("Underlying socket is not connected");
527 }
528 this.host = host;
529 this.rawHostname = host;
530 init(context, false);
531 this.autoClose = autoClose;
532 doneConnect();
533 }
534
535 /**
536 * Initializes the client socket.
537 */
538 private void init(SSLContextImpl context, boolean isServer) {
539 sslContext = context;
540 sess = SSLSessionImpl.nullSession;
541 handshakeSession = null;
542
543 /*
544 * role is as specified, state is START until after
545 * the low level connection's established.
546 */
547 roleIsServer = isServer;
548 connectionState = cs_START;
549
550 /*
551 * default read and write side cipher and MAC support
552 *
553 * Note: compression support would go here too
554 */
555 readCipher = CipherBox.NULL;
556 readMAC = MAC.NULL;
557 writeCipher = CipherBox.NULL;
558 writeMAC = MAC.NULL;
559
560 // initial security parameters for secure renegotiation
561 secureRenegotiation = false;
562 clientVerifyData = new byte[0];
563 serverVerifyData = new byte[0];
564
565 enabledCipherSuites =
566 sslContext.getDefaultCipherSuiteList(roleIsServer);
567 enabledProtocols =
568 sslContext.getDefaultProtocolList(roleIsServer);
569
570 inrec = null;
571
572 // save the acc
573 acc = AccessController.getContext();
574
575 input = new AppInputStream(this);
576 output = new AppOutputStream(this);
577 }
578
579 /**
580 * Connects this socket to the server with a specified timeout
581 * value.
582 *
583 * This method is either called on an unconnected SSLSocketImpl by the
584 * application, or it is called in the constructor of a regular
585 * SSLSocketImpl. If we are layering on top on another socket, then
586 * this method should not be called, because we assume that the
587 * underlying socket is already connected by the time it is passed to
588 * us.
589 *
590 * @param endpoint the <code>SocketAddress</code>
591 * @param timeout the timeout value to be used, 0 is no timeout
592 * @throws IOException if an error occurs during the connection
593 * @throws SocketTimeoutException if timeout expires before connecting
594 */
595 public void connect(SocketAddress endpoint, int timeout)
596 throws IOException {
597
598 if (self != this) {
599 throw new SocketException("Already connected");
600 }
601
602 if (!(endpoint instanceof InetSocketAddress)) {
603 throw new SocketException(
604 "Cannot handle non-Inet socket addresses.");
605 }
606
607 super.connect(endpoint, timeout);
608 doneConnect();
609 }
610
611 /**
612 * Initialize the handshaker and socket streams.
613 *
614 * Called by connect, the layered constructor, and SSLServerSocket.
615 */
616 void doneConnect() throws IOException {
617 /*
618 * Save the input and output streams. May be done only after
619 * java.net actually connects using the socket "self", else
620 * we get some pretty bizarre failure modes.
621 */
622 if (self == this) {
623 sockInput = super.getInputStream();
624 sockOutput = super.getOutputStream();
625 } else {
626 sockInput = self.getInputStream();
627 sockOutput = self.getOutputStream();
628 }
629
630 /*
631 * Move to handshaking state, with pending session initialized
632 * to defaults and the appropriate kind of handshaker set up.
633 */
634 initHandshaker();
635 }
636
637 synchronized private int getConnectionState() {
638 return connectionState;
639 }
640
641 synchronized private void setConnectionState(int state) {
642 connectionState = state;
643 }
644
645 AccessControlContext getAcc() {
646 return acc;
647 }
648
649 //
650 // READING AND WRITING RECORDS
651 //
652
653 /*
654 * Record Output. Application data can't be sent until the first
655 * handshake establishes a session.
656 *
657 * NOTE: we let empty records be written as a hook to force some
658 * TCP-level activity, notably handshaking, to occur.
659 */
660 void writeRecord(OutputRecord r) throws IOException {
661 /*
662 * The loop is in case of HANDSHAKE --> ERROR transitions, etc
663 */
664 loop:
665 while (r.contentType() == Record.ct_application_data) {
666 /*
667 * Not all states support passing application data. We
668 * synchronize access to the connection state, so that
669 * synchronous handshakes can complete cleanly.
670 */
671 switch (getConnectionState()) {
672
673 /*
674 * We've deferred the initial handshaking till just now,
675 * when presumably a thread's decided it's OK to block for
676 * longish periods of time for I/O purposes (as well as
677 * configured the cipher suites it wants to use).
678 */
679 case cs_HANDSHAKE:
680 performInitialHandshake();
681 break;
682
683 case cs_DATA:
684 case cs_RENEGOTIATE:
685 break loop;
686
687 case cs_ERROR:
688 fatal(Alerts.alert_close_notify,
689 "error while writing to socket");
690 break; // dummy
691
692 case cs_SENT_CLOSE:
693 case cs_CLOSED:
694 case cs_APP_CLOSED:
695 // we should never get here (check in AppOutputStream)
696 // this is just a fallback
697 if (closeReason != null) {
698 throw closeReason;
699 } else {
700 throw new SocketException("Socket closed");
701 }
702
703 /*
704 * Else something's goofy in this state machine's use.
705 */
706 default:
707 throw new SSLProtocolException("State error, send app data");
708 }
709 }
710
711 //
712 // Don't bother to really write empty records. We went this
713 // far to drive the handshake machinery, for correctness; not
714 // writing empty records improves performance by cutting CPU
715 // time and network resource usage. However, some protocol
716 // implementations are fragile and don't like to see empty
717 // records, so this also increases robustness.
718 //
719 if (!r.isEmpty()) {
720
721 // If the record is a close notify alert, we need to honor
722 // socket option SO_LINGER. Note that we will try to send
723 // the close notify even if the SO_LINGER set to zero.
724 if (r.isAlert(Alerts.alert_close_notify) && getSoLinger() >= 0) {
725
726 // keep and clear the current thread interruption status.
727 boolean interrupted = Thread.interrupted();
728 try {
729 if (writeLock.tryLock(getSoLinger(), TimeUnit.SECONDS)) {
730 try {
731 writeRecordInternal(r);
732 } finally {
733 writeLock.unlock();
734 }
735 } else {
736 SSLException ssle = new SSLException(
737 "SO_LINGER timeout," +
738 " close_notify message cannot be sent.");
739
740
741 // For layered, non-autoclose sockets, we are not
742 // able to bring them into a usable state, so we
743 // treat it as fatal error.
744 if (self != this && !autoClose) {
745 // Note that the alert description is
746 // specified as -1, so no message will be send
747 // to peer anymore.
748 fatal((byte)(-1), ssle);
749 } else if ((debug != null) && Debug.isOn("ssl")) {
750 System.out.println(threadName() +
751 ", received Exception: " + ssle);
752 }
753
754 // RFC2246 requires that the session becomes
755 // unresumable if any connection is terminated
756 // without proper close_notify messages with
757 // level equal to warning.
758 //
759 // RFC4346 no longer requires that a session not be
760 // resumed if failure to properly close a connection.
761 //
762 // We choose to make the session unresumable if
763 // failed to send the close_notify message.
764 //
765 sess.invalidate();
766 }
767 } catch (InterruptedException ie) {
768 // keep interrupted status
769 interrupted = true;
770 }
771
772 // restore the interrupted status
773 if (interrupted) {
774 Thread.currentThread().interrupt();
775 }
776 } else {
777 writeLock.lock();
778 try {
779 writeRecordInternal(r);
780 } finally {
781 writeLock.unlock();
782 }
783 }
784 }
785 }
786
787 private void writeRecordInternal(OutputRecord r) throws IOException {
788 // r.compress(c);
789 r.addMAC(writeMAC);
790 r.encrypt(writeCipher);
791 r.write(sockOutput);
792
793 /*
794 * Check the sequence number state
795 *
796 * Note that in order to maintain the connection I/O
797 * properly, we check the sequence number after the last
798 * record writing process. As we request renegotiation
799 * or close the connection for wrapped sequence number
800 * when there is enough sequence number space left to
801 * handle a few more records, so the sequence number
802 * of the last record cannot be wrapped.
803 */
804 if (connectionState < cs_ERROR) {
805 checkSequenceNumber(writeMAC, r.contentType());
806 }
807 }
808
809
810 /*
811 * Read an application data record. Alerts and handshake
812 * messages are handled directly.
813 */
814 void readDataRecord(InputRecord r) throws IOException {
815 if (getConnectionState() == cs_HANDSHAKE) {
816 performInitialHandshake();
817 }
818 readRecord(r, true);
819 }
820
821
822 /*
823 * Clear the pipeline of records from the peer, optionally returning
824 * application data. Caller is responsible for knowing that it's
825 * possible to do this kind of clearing, if they don't want app
826 * data -- e.g. since it's the initial SSL handshake.
827 *
828 * Don't synchronize (this) during a blocking read() since it
829 * protects data which is accessed on the write side as well.
830 */
831 private void readRecord(InputRecord r, boolean needAppData)
832 throws IOException {
833 int state;
834
835 // readLock protects reading and processing of an InputRecord.
836 // It keeps the reading from sockInput and processing of the record
837 // atomic so that no two threads can be blocked on the
838 // read from the same input stream at the same time.
839 // This is required for example when a reader thread is
840 // blocked on the read and another thread is trying to
841 // close the socket. For a non-autoclose, layered socket,
842 // the thread performing the close needs to read the close_notify.
843 //
844 // Use readLock instead of 'this' for locking because
845 // 'this' also protects data accessed during writing.
846 synchronized (readLock) {
847 /*
848 * Read and handle records ... return application data
849 * ONLY if it's needed.
850 */
851
852 while (((state = getConnectionState()) != cs_CLOSED) &&
853 (state != cs_ERROR) && (state != cs_APP_CLOSED)) {
854 /*
855 * Read a record ... maybe emitting an alert if we get a
856 * comprehensible but unsupported "hello" message during
857 * format checking (e.g. V2).
858 */
859 try {
860 r.setAppDataValid(false);
861 r.read(sockInput, sockOutput);
862 } catch (SSLProtocolException e) {
863 try {
864 fatal(Alerts.alert_unexpected_message, e);
865 } catch (IOException x) {
866 // discard this exception
867 }
868 throw e;
869 } catch (EOFException eof) {
870 boolean handshaking = (getConnectionState() <= cs_HANDSHAKE);
871 boolean rethrow = requireCloseNotify || handshaking;
872 if ((debug != null) && Debug.isOn("ssl")) {
873 System.out.println(threadName() +
874 ", received EOFException: "
875 + (rethrow ? "error" : "ignored"));
876 }
877 if (rethrow) {
878 SSLException e;
879 if (handshaking) {
880 e = new SSLHandshakeException
881 ("Remote host closed connection during handshake");
882 } else {
883 e = new SSLProtocolException
884 ("Remote host closed connection incorrectly");
885 }
886 e.initCause(eof);
887 throw e;
888 } else {
889 // treat as if we had received a close_notify
890 closeInternal(false);
891 continue;
892 }
893 }
894
895
896 /*
897 * The basic SSLv3 record protection involves (optional)
898 * encryption for privacy, and an integrity check ensuring
899 * data origin authentication. We do them both here, and
900 * throw a fatal alert if the integrity check fails.
901 */
902 try {
903 r.decrypt(readCipher);
904 } catch (BadPaddingException e) {
905 // RFC 2246 states that decryption_failed should be used
906 // for this purpose. However, that allows certain attacks,
907 // so we just send bad record MAC. We also need to make
908 // sure to always check the MAC to avoid a timing attack
909 // for the same issue. See paper by Vaudenay et al.
910 r.checkMAC(readMAC);
911 // use the same alert types as for MAC failure below
912 byte alertType = (r.contentType() == Record.ct_handshake)
913 ? Alerts.alert_handshake_failure
914 : Alerts.alert_bad_record_mac;
915 fatal(alertType, "Invalid padding", e);
916 }
917 if (!r.checkMAC(readMAC)) {
918 if (r.contentType() == Record.ct_handshake) {
919 fatal(Alerts.alert_handshake_failure,
920 "bad handshake record MAC");
921 } else {
922 fatal(Alerts.alert_bad_record_mac, "bad record MAC");
923 }
924 }
925
926
927 // if (!r.decompress(c))
928 // fatal(Alerts.alert_decompression_failure,
929 // "decompression failure");
930
931 /*
932 * Process the record.
933 */
934 synchronized (this) {
935 switch (r.contentType()) {
936 case Record.ct_handshake:
937 /*
938 * Handshake messages always go to a pending session
939 * handshaker ... if there isn't one, create one. This
940 * must work asynchronously, for renegotiation.
941 *
942 * NOTE that handshaking will either resume a session
943 * which was in the cache (and which might have other
944 * connections in it already), or else will start a new
945 * session (new keys exchanged) with just this connection
946 * in it.
947 */
948 initHandshaker();
949 if (!handshaker.activated()) {
950 // prior to handshaking, activate the handshake
951 if (connectionState == cs_RENEGOTIATE) {
952 // don't use SSLv2Hello when renegotiating
953 handshaker.activate(protocolVersion);
954 } else {
955 handshaker.activate(null);
956 }
957 }
958
959 /*
960 * process the handshake record ... may contain just
961 * a partial handshake message or multiple messages.
962 *
963 * The handshaker state machine will ensure that it's
964 * a finished message.
965 */
966 handshaker.process_record(r, expectingFinished);
967 expectingFinished = false;
968
969 if (handshaker.invalidated) {
970 handshaker = null;
971 // if state is cs_RENEGOTIATE, revert it to cs_DATA
972 if (connectionState == cs_RENEGOTIATE) {
973 connectionState = cs_DATA;
974 }
975 } else if (handshaker.isDone()) {
976 // reset the parameters for secure renegotiation.
977 secureRenegotiation =
978 handshaker.isSecureRenegotiation();
979 clientVerifyData = handshaker.getClientVerifyData();
980 serverVerifyData = handshaker.getServerVerifyData();
981
982 sess = handshaker.getSession();
983 handshakeSession = null;
984 handshaker = null;
985 connectionState = cs_DATA;
986
987 //
988 // Tell folk about handshake completion, but do
989 // it in a separate thread.
990 //
991 if (handshakeListeners != null) {
992 HandshakeCompletedEvent event =
993 new HandshakeCompletedEvent(this, sess);
994
995 Thread t = new NotifyHandshakeThread(
996 handshakeListeners.entrySet(), event);
997 t.start();
998 }
999 }
1000
1001 if (needAppData || connectionState != cs_DATA) {
1002 continue;
1003 }
1004 break;
1005
1006 case Record.ct_application_data:
1007 // Pass this right back up to the application.
1008 if (connectionState != cs_DATA
1009 && connectionState != cs_RENEGOTIATE
1010 && connectionState != cs_SENT_CLOSE) {
1011 throw new SSLProtocolException(
1012 "Data received in non-data state: " +
1013 connectionState);
1014 }
1015 if (expectingFinished) {
1016 throw new SSLProtocolException
1017 ("Expecting finished message, received data");
1018 }
1019 if (!needAppData) {
1020 throw new SSLException("Discarding app data");
1021 }
1022
1023 r.setAppDataValid(true);
1024 break;
1025
1026 case Record.ct_alert:
1027 recvAlert(r);
1028 continue;
1029
1030 case Record.ct_change_cipher_spec:
1031 if ((connectionState != cs_HANDSHAKE
1032 && connectionState != cs_RENEGOTIATE)
1033 || r.available() != 1
1034 || r.read() != 1) {
1035 fatal(Alerts.alert_unexpected_message,
1036 "illegal change cipher spec msg, state = "
1037 + connectionState);
1038 }
1039
1040 //
1041 // The first message after a change_cipher_spec
1042 // record MUST be a "Finished" handshake record,
1043 // else it's a protocol violation. We force this
1044 // to be checked by a minor tweak to the state
1045 // machine.
1046 //
1047 changeReadCiphers();
1048 // next message MUST be a finished message
1049 expectingFinished = true;
1050 continue;
1051
1052 default:
1053 //
1054 // TLS requires that unrecognized records be ignored.
1055 //
1056 if (debug != null && Debug.isOn("ssl")) {
1057 System.out.println(threadName() +
1058 ", Received record type: "
1059 + r.contentType());
1060 }
1061 continue;
1062 } // switch
1063
1064 /*
1065 * Check the sequence number state
1066 *
1067 * Note that in order to maintain the connection I/O
1068 * properly, we check the sequence number after the last
1069 * record reading process. As we request renegotiation
1070 * or close the connection for wrapped sequence number
1071 * when there is enough sequence number space left to
1072 * handle a few more records, so the sequence number
1073 * of the last record cannot be wrapped.
1074 */
1075 if (connectionState < cs_ERROR) {
1076 checkSequenceNumber(readMAC, r.contentType());
1077 }
1078
1079 return;
1080 } // synchronized (this)
1081 }
1082
1083 //
1084 // couldn't read, due to some kind of error
1085 //
1086 r.close();
1087 return;
1088 } // synchronized (readLock)
1089 }
1090
1091 /**
1092 * Check the sequence number state
1093 *
1094 * RFC 4346 states that, "Sequence numbers are of type uint64 and
1095 * may not exceed 2^64-1. Sequence numbers do not wrap. If a TLS
1096 * implementation would need to wrap a sequence number, it must
1097 * renegotiate instead."
1098 */
1099 private void checkSequenceNumber(MAC mac, byte type)
1100 throws IOException {
1101
1102 /*
1103 * Don't bother to check the sequence number for error or
1104 * closed connections, or NULL MAC.
1105 */
1106 if (connectionState >= cs_ERROR || mac == MAC.NULL) {
1107 return;
1108 }
1109
1110 /*
1111 * Conservatively, close the connection immediately when the
1112 * sequence number is close to overflow
1113 */
1114 if (mac.seqNumOverflow()) {
1115 /*
1116 * TLS protocols do not define a error alert for sequence
1117 * number overflow. We use handshake_failure error alert
1118 * for handshaking and bad_record_mac for other records.
1119 */
1120 if (debug != null && Debug.isOn("ssl")) {
1121 System.out.println(threadName() +
1122 ", sequence number extremely close to overflow " +
1123 "(2^64-1 packets). Closing connection.");
1124
1125 }
1126
1127 fatal(Alerts.alert_handshake_failure, "sequence number overflow");
1128 }
1129
1130 /*
1131 * Ask for renegotiation when need to renew sequence number.
1132 *
1133 * Don't bother to kickstart the renegotiation when the local is
1134 * asking for it.
1135 */
1136 if ((type != Record.ct_handshake) && mac.seqNumIsHuge()) {
1137 if (debug != null && Debug.isOn("ssl")) {
1138 System.out.println(threadName() + ", request renegotiation " +
1139 "to avoid sequence number overflow");
1140 }
1141
1142 startHandshake();
1143 }
1144 }
1145
1146 //
1147 // HANDSHAKE RELATED CODE
1148 //
1149
1150 /**
1151 * Return the AppInputStream. For use by Handshaker only.
1152 */
1153 AppInputStream getAppInputStream() {
1154 return input;
1155 }
1156
1157 /**
1158 * Return the AppOutputStream. For use by Handshaker only.
1159 */
1160 AppOutputStream getAppOutputStream() {
1161 return output;
1162 }
1163
1164 /**
1165 * Initialize the handshaker object. This means:
1166 *
1167 * . if a handshake is already in progress (state is cs_HANDSHAKE
1168 * or cs_RENEGOTIATE), do nothing and return
1169 *
1170 * . if the socket is already closed, throw an Exception (internal error)
1171 *
1172 * . otherwise (cs_START or cs_DATA), create the appropriate handshaker
1173 * object, and advance the connection state (to cs_HANDSHAKE or
1174 * cs_RENEGOTIATE, respectively).
1175 *
1176 * This method is called right after a new socket is created, when
1177 * starting renegotiation, or when changing client/ server mode of the
1178 * socket.
1179 */
1180 private void initHandshaker() {
1181 switch (connectionState) {
1182
1183 //
1184 // Starting a new handshake.
1185 //
1186 case cs_START:
1187 case cs_DATA:
1188 break;
1189
1190 //
1191 // We're already in the middle of a handshake.
1192 //
1193 case cs_HANDSHAKE:
1194 case cs_RENEGOTIATE:
1195 return;
1196
1197 //
1198 // Anyone allowed to call this routine is required to
1199 // do so ONLY if the connection state is reasonable...
1200 //
1201 default:
1202 throw new IllegalStateException("Internal error");
1203 }
1204
1205 // state is either cs_START or cs_DATA
1206 if (connectionState == cs_START) {
1207 connectionState = cs_HANDSHAKE;
1208 } else { // cs_DATA
1209 connectionState = cs_RENEGOTIATE;
1210 }
1211 if (roleIsServer) {
1212 handshaker = new ServerHandshaker(this, sslContext,
1213 enabledProtocols, doClientAuth,
1214 protocolVersion, connectionState == cs_HANDSHAKE,
1215 secureRenegotiation, clientVerifyData, serverVerifyData);
1216 } else {
1217 handshaker = new ClientHandshaker(this, sslContext,
1218 enabledProtocols,
1219 protocolVersion, connectionState == cs_HANDSHAKE,
1220 secureRenegotiation, clientVerifyData, serverVerifyData);
1221 }
1222 handshaker.setEnabledCipherSuites(enabledCipherSuites);
1223 handshaker.setEnableSessionCreation(enableSessionCreation);
1224 }
1225
1226 /**
1227 * Synchronously perform the initial handshake.
1228 *
1229 * If the handshake is already in progress, this method blocks until it
1230 * is completed. If the initial handshake has already been completed,
1231 * it returns immediately.
1232 */
1233 private void performInitialHandshake() throws IOException {
1234 // use handshakeLock and the state check to make sure only
1235 // one thread performs the handshake
1236 synchronized (handshakeLock) {
1237 if (getConnectionState() == cs_HANDSHAKE) {
1238 kickstartHandshake();
1239
1240 /*
1241 * All initial handshaking goes through this
1242 * InputRecord until we have a valid SSL connection.
1243 * Once initial handshaking is finished, AppInputStream's
1244 * InputRecord can handle any future renegotiation.
1245 *
1246 * Keep this local so that it goes out of scope and is
1247 * eventually GC'd.
1248 */
1249 if (inrec == null) {
1250 inrec = new InputRecord();
1251
1252 /*
1253 * Grab the characteristics already assigned to
1254 * AppInputStream's InputRecord. Enable checking for
1255 * SSLv2 hellos on this first handshake.
1256 */
1257 inrec.setHandshakeHash(input.r.getHandshakeHash());
1258 inrec.setHelloVersion(input.r.getHelloVersion());
1259 inrec.enableFormatChecks();
1260 }
1261
1262 readRecord(inrec, false);
1263 inrec = null;
1264 }
1265 }
1266 }
1267
1268 /**
1269 * Starts an SSL handshake on this connection.
1270 */
1271 public void startHandshake() throws IOException {
1272 // start an ssl handshake that could be resumed from timeout exception
1273 startHandshake(true);
1274 }
1275
1276 /**
1277 * Starts an ssl handshake on this connection.
1278 *
1279 * @param resumable indicates the handshake process is resumable from a
1280 * certain exception. If <code>resumable</code>, the socket will
1281 * be reserved for exceptions like timeout; otherwise, the socket
1282 * will be closed, no further communications could be done.
1283 */
1284 private void startHandshake(boolean resumable) throws IOException {
1285 checkWrite();
1286 try {
1287 if (getConnectionState() == cs_HANDSHAKE) {
1288 // do initial handshake
1289 performInitialHandshake();
1290 } else {
1291 // start renegotiation
1292 kickstartHandshake();
1293 }
1294 } catch (Exception e) {
1295 // shutdown and rethrow (wrapped) exception as appropriate
1296 handleException(e, resumable);
1297 }
1298 }
1299
1300 /**
1301 * Kickstart the handshake if it is not already in progress.
1302 * This means:
1303 *
1304 * . if handshaking is already underway, do nothing and return
1305 *
1306 * . if the socket is not connected or already closed, throw an
1307 * Exception.
1308 *
1309 * . otherwise, call initHandshake() to initialize the handshaker
1310 * object and progress the state. Then, send the initial
1311 * handshaking message if appropriate (always on clients and
1312 * on servers when renegotiating).
1313 */
1314 private synchronized void kickstartHandshake() throws IOException {
1315
1316 switch (connectionState) {
1317
1318 case cs_HANDSHAKE:
1319 // handshaker already setup, proceed
1320 break;
1321
1322 case cs_DATA:
1323 if (!secureRenegotiation && !Handshaker.allowUnsafeRenegotiation) {
1324 throw new SSLHandshakeException(
1325 "Insecure renegotiation is not allowed");
1326 }
1327
1328 if (!secureRenegotiation) {
1329 if (debug != null && Debug.isOn("handshake")) {
1330 System.out.println(
1331 "Warning: Using insecure renegotiation");
1332 }
1333 }
1334
1335 // initialize the handshaker, move to cs_RENEGOTIATE
1336 initHandshaker();
1337 break;
1338
1339 case cs_RENEGOTIATE:
1340 // handshaking already in progress, return
1341 return;
1342
1343 /*
1344 * The only way to get a socket in the state is when
1345 * you have an unconnected socket.
1346 */
1347 case cs_START:
1348 throw new SocketException(
1349 "handshaking attempted on unconnected socket");
1350
1351 default:
1352 throw new SocketException("connection is closed");
1353 }
1354
1355 //
1356 // Kickstart handshake state machine if we need to ...
1357 //
1358 // Note that handshaker.kickstart() writes the message
1359 // to its HandshakeOutStream, which calls back into
1360 // SSLSocketImpl.writeRecord() to send it.
1361 //
1362 if (!handshaker.activated()) {
1363 // prior to handshaking, activate the handshake
1364 if (connectionState == cs_RENEGOTIATE) {
1365 // don't use SSLv2Hello when renegotiating
1366 handshaker.activate(protocolVersion);
1367 } else {
1368 handshaker.activate(null);
1369 }
1370
1371 if (handshaker instanceof ClientHandshaker) {
1372 // send client hello
1373 handshaker.kickstart();
1374 } else {
1375 if (connectionState == cs_HANDSHAKE) {
1376 // initial handshake, no kickstart message to send
1377 } else {
1378 // we want to renegotiate, send hello request
1379 handshaker.kickstart();
1380 // hello request is not included in the handshake
1381 // hashes, reset them
1382 handshaker.handshakeHash.reset();
1383 }
1384 }
1385 }
1386 }
1387
1388 //
1389 // CLOSURE RELATED CALLS
1390 //
1391
1392 /**
1393 * Return whether the socket has been explicitly closed by the application.
1394 */
1395 public boolean isClosed() {
1396 return getConnectionState() == cs_APP_CLOSED;
1397 }
1398
1399 /**
1400 * Return whether we have reached end-of-file.
1401 *
1402 * If the socket is not connected, has been shutdown because of an error
1403 * or has been closed, throw an Exception.
1404 */
1405 boolean checkEOF() throws IOException {
1406 switch (getConnectionState()) {
1407 case cs_START:
1408 throw new SocketException("Socket is not connected");
1409
1410 case cs_HANDSHAKE:
1411 case cs_DATA:
1412 case cs_RENEGOTIATE:
1413 case cs_SENT_CLOSE:
1414 return false;
1415
1416 case cs_APP_CLOSED:
1417 throw new SocketException("Socket is closed");
1418
1419 case cs_ERROR:
1420 case cs_CLOSED:
1421 default:
1422 // either closed because of error, or normal EOF
1423 if (closeReason == null) {
1424 return true;
1425 }
1426 IOException e = new SSLException
1427 ("Connection has been shutdown: " + closeReason);
1428 e.initCause(closeReason);
1429 throw e;
1430
1431 }
1432 }
1433
1434 /**
1435 * Check if we can write data to this socket. If not, throw an IOException.
1436 */
1437 void checkWrite() throws IOException {
1438 if (checkEOF() || (getConnectionState() == cs_SENT_CLOSE)) {
1439 // we are at EOF, write must throw Exception
1440 throw new SocketException("Connection closed by remote host");
1441 }
1442 }
1443
1444 protected void closeSocket() throws IOException {
1445
1446 if ((debug != null) && Debug.isOn("ssl")) {
1447 System.out.println(threadName() + ", called closeSocket()");
1448 }
1449 if (self == this) {
1450 super.close();
1451 } else {
1452 self.close();
1453 }
1454 }
1455
1456 private void closeSocket(boolean selfInitiated) throws IOException {
1457 if ((debug != null) && Debug.isOn("ssl")) {
1458 System.out.println(threadName() + ", called closeSocket(selfInitiated)");
1459 }
1460 if (self == this) {
1461 super.close();
1462 } else if (autoClose) {
1463 self.close();
1464 } else if (selfInitiated) {
1465 // layered && non-autoclose
1466 // read close_notify alert to clear input stream
1467 waitForClose(false);
1468 }
1469 }
1470
1471 /*
1472 * Closing the connection is tricky ... we can't officially close the
1473 * connection until we know the other end is ready to go away too,
1474 * and if ever the connection gets aborted we must forget session
1475 * state (it becomes invalid).
1476 */
1477
1478 /**
1479 * Closes the SSL connection. SSL includes an application level
1480 * shutdown handshake; you should close SSL sockets explicitly
1481 * rather than leaving it for finalization, so that your remote
1482 * peer does not experience a protocol error.
1483 */
1484 public void close() throws IOException {
1485 if ((debug != null) && Debug.isOn("ssl")) {
1486 System.out.println(threadName() + ", called close()");
1487 }
1488 closeInternal(true); // caller is initiating close
1489 setConnectionState(cs_APP_CLOSED);
1490 }
1491
1492 /**
1493 * Don't synchronize the whole method because waitForClose()
1494 * (which calls readRecord()) might be called.
1495 *
1496 * @param selfInitiated Indicates which party initiated the close.
1497 * If selfInitiated, this side is initiating a close; for layered and
1498 * non-autoclose socket, wait for close_notify response.
1499 * If !selfInitiated, peer sent close_notify; we reciprocate but
1500 * no need to wait for response.
1501 */
1502 private void closeInternal(boolean selfInitiated) throws IOException {
1503 if ((debug != null) && Debug.isOn("ssl")) {
1504 System.out.println(threadName() + ", called closeInternal("
1505 + selfInitiated + ")");
1506 }
1507
1508 int state = getConnectionState();
1509 boolean closeSocketCalled = false;
1510 Throwable cachedThrowable = null;
1511 try {
1512 switch (state) {
1513 /*
1514 * java.net code sometimes closes sockets "early", when
1515 * we can't actually do I/O on them.
1516 */
1517 case cs_START:
1518 break;
1519
1520 /*
1521 * If we're closing down due to error, we already sent (or else
1522 * received) the fatal alert ... no niceties, blow the connection
1523 * away as quickly as possible (even if we didn't allocate the
1524 * socket ourselves; it's unusable, regardless).
1525 */
1526 case cs_ERROR:
1527 closeSocket();
1528 break;
1529
1530 /*
1531 * Sometimes close() gets called more than once.
1532 */
1533 case cs_CLOSED:
1534 case cs_APP_CLOSED:
1535 break;
1536
1537 /*
1538 * Otherwise we indicate clean termination.
1539 */
1540 // case cs_HANDSHAKE:
1541 // case cs_DATA:
1542 // case cs_RENEGOTIATE:
1543 // case cs_SENT_CLOSE:
1544 default:
1545 synchronized (this) {
1546 if (((state = getConnectionState()) == cs_CLOSED) ||
1547 (state == cs_ERROR) || (state == cs_APP_CLOSED)) {
1548 return; // connection was closed while we waited
1549 }
1550 if (state != cs_SENT_CLOSE) {
1551 try {
1552 warning(Alerts.alert_close_notify);
1553 connectionState = cs_SENT_CLOSE;
1554 } catch (Throwable th) {
1555 // we need to ensure socket is closed out
1556 // if we encounter any errors.
1557 connectionState = cs_ERROR;
1558 // cache this for later use
1559 cachedThrowable = th;
1560 closeSocketCalled = true;
1561 closeSocket(selfInitiated);
1562 }
1563 }
1564 }
1565 // If state was cs_SENT_CLOSE before, we don't do the actual
1566 // closing since it is already in progress.
1567 if (state == cs_SENT_CLOSE) {
1568 if (debug != null && Debug.isOn("ssl")) {
1569 System.out.println(threadName() +
1570 ", close invoked again; state = " +
1571 getConnectionState());
1572 }
1573 if (selfInitiated == false) {
1574 // We were called because a close_notify message was
1575 // received. This may be due to another thread calling
1576 // read() or due to our call to waitForClose() below.
1577 // In either case, just return.
1578 return;
1579 }
1580 // Another thread explicitly called close(). We need to
1581 // wait for the closing to complete before returning.
1582 synchronized (this) {
1583 while (connectionState < cs_CLOSED) {
1584 try {
1585 this.wait();
1586 } catch (InterruptedException e) {
1587 // ignore
1588 }
1589 }
1590 }
1591 if ((debug != null) && Debug.isOn("ssl")) {
1592 System.out.println(threadName() +
1593 ", after primary close; state = " +
1594 getConnectionState());
1595 }
1596 return;
1597 }
1598
1599 if (!closeSocketCalled) {
1600 closeSocketCalled = true;
1601 closeSocket(selfInitiated);
1602 }
1603
1604 break;
1605 }
1606 } finally {
1607 synchronized (this) {
1608 // Upon exit from this method, the state is always >= cs_CLOSED
1609 connectionState = (connectionState == cs_APP_CLOSED)
1610 ? cs_APP_CLOSED : cs_CLOSED;
1611 // notify any threads waiting for the closing to finish
1612 this.notifyAll();
1613 }
1614 if (closeSocketCalled) {
1615 // Dispose of ciphers since we've closed socket
1616 disposeCiphers();
1617 }
1618 if (cachedThrowable != null) {
1619 /*
1620 * Rethrow the error to the calling method
1621 * The Throwable caught can only be an Error or RuntimeException
1622 */
1623 if (cachedThrowable instanceof Error)
1624 throw (Error) cachedThrowable;
1625 if (cachedThrowable instanceof RuntimeException)
1626 throw (RuntimeException) cachedThrowable;
1627 }
1628 }
1629 }
1630
1631 /**
1632 * Reads a close_notify or a fatal alert from the input stream.
1633 * Keep reading records until we get a close_notify or until
1634 * the connection is otherwise closed. The close_notify or alert
1635 * might be read by another reader,
1636 * which will then process the close and set the connection state.
1637 */
1638 void waitForClose(boolean rethrow) throws IOException {
1639 if (debug != null && Debug.isOn("ssl")) {
1640 System.out.println(threadName() +
1641 ", waiting for close_notify or alert: state "
1642 + getConnectionState());
1643 }
1644
1645 try {
1646 int state;
1647
1648 while (((state = getConnectionState()) != cs_CLOSED) &&
1649 (state != cs_ERROR) && (state != cs_APP_CLOSED)) {
1650 // create the InputRecord if it isn't intialized.
1651 if (inrec == null) {
1652 inrec = new InputRecord();
1653 }
1654
1655 // Ask for app data and then throw it away
1656 try {
1657 readRecord(inrec, true);
1658 } catch (SocketTimeoutException e) {
1659 // if time out, ignore the exception and continue
1660 }
1661 }
1662 inrec = null;
1663 } catch (IOException e) {
1664 if (debug != null && Debug.isOn("ssl")) {
1665 System.out.println(threadName() +
1666 ", Exception while waiting for close " +e);
1667 }
1668 if (rethrow) {
1669 throw e; // pass exception up
1670 }
1671 }
1672 }
1673
1674 /**
1675 * Called by closeInternal() only. Be sure to consider the
1676 * synchronization locks carefully before calling it elsewhere.
1677 */
1678 private void disposeCiphers() {
1679 // See comment in changeReadCiphers()
1680 synchronized (readLock) {
1681 readCipher.dispose();
1682 }
1683 // See comment in changeReadCiphers()
1684 writeLock.lock();
1685 try {
1686 writeCipher.dispose();
1687 } finally {
1688 writeLock.unlock();
1689 }
1690 }
1691
1692 //
1693 // EXCEPTION AND ALERT HANDLING
1694 //
1695
1696 /**
1697 * Handle an exception. This method is called by top level exception
1698 * handlers (in read(), write()) to make sure we always shutdown the
1699 * connection correctly and do not pass runtime exception to the
1700 * application.
1701 */
1702 void handleException(Exception e) throws IOException {
1703 handleException(e, true);
1704 }
1705
1706 /**
1707 * Handle an exception. This method is called by top level exception
1708 * handlers (in read(), write(), startHandshake()) to make sure we
1709 * always shutdown the connection correctly and do not pass runtime
1710 * exception to the application.
1711 *
1712 * This method never returns normally, it always throws an IOException.
1713 *
1714 * We first check if the socket has already been shutdown because of an
1715 * error. If so, we just rethrow the exception. If the socket has not
1716 * been shutdown, we sent a fatal alert and remember the exception.
1717 *
1718 * @param e the Exception
1719 * @param resumable indicates the caller process is resumable from the
1720 * exception. If <code>resumable</code>, the socket will be
1721 * reserved for exceptions like timeout; otherwise, the socket
1722 * will be closed, no further communications could be done.
1723 */
1724 synchronized private void handleException(Exception e, boolean resumable)
1725 throws IOException {
1726 if ((debug != null) && Debug.isOn("ssl")) {
1727 System.out.println(threadName()
1728 + ", handling exception: " + e.toString());
1729 }
1730
1731 // don't close the Socket in case of timeouts or interrupts if
1732 // the process is resumable.
1733 if (e instanceof InterruptedIOException && resumable) {
1734 throw (IOException)e;
1735 }
1736
1737 // if we've already shutdown because of an error,
1738 // there is nothing to do except rethrow the exception
1739 if (closeReason != null) {
1740 if (e instanceof IOException) { // includes SSLException
1741 throw (IOException)e;
1742 } else {
1743 // this is odd, not an IOException.
1744 // normally, this should not happen
1745 // if closeReason has been already been set
1746 throw Alerts.getSSLException(Alerts.alert_internal_error, e,
1747 "Unexpected exception");
1748 }
1749 }
1750
1751 // need to perform error shutdown
1752 boolean isSSLException = (e instanceof SSLException);
1753 if ((isSSLException == false) && (e instanceof IOException)) {
1754 // IOException from the socket
1755 // this means the TCP connection is already dead
1756 // we call fatal just to set the error status
1757 try {
1758 fatal(Alerts.alert_unexpected_message, e);
1759 } catch (IOException ee) {
1760 // ignore (IOException wrapped in SSLException)
1761 }
1762 // rethrow original IOException
1763 throw (IOException)e;
1764 }
1765
1766 // must be SSLException or RuntimeException
1767 byte alertType;
1768 if (isSSLException) {
1769 if (e instanceof SSLHandshakeException) {
1770 alertType = Alerts.alert_handshake_failure;
1771 } else {
1772 alertType = Alerts.alert_unexpected_message;
1773 }
1774 } else {
1775 alertType = Alerts.alert_internal_error;
1776 }
1777 fatal(alertType, e);
1778 }
1779
1780 /*
1781 * Send a warning alert.
1782 */
1783 void warning(byte description) {
1784 sendAlert(Alerts.alert_warning, description);
1785 }
1786
1787 synchronized void fatal(byte description, String diagnostic)
1788 throws IOException {
1789 fatal(description, diagnostic, null);
1790 }
1791
1792 synchronized void fatal(byte description, Throwable cause)
1793 throws IOException {
1794 fatal(description, null, cause);
1795 }
1796
1797 /*
1798 * Send a fatal alert, and throw an exception so that callers will
1799 * need to stand on their heads to accidentally continue processing.
1800 */
1801 synchronized void fatal(byte description, String diagnostic,
1802 Throwable cause) throws IOException {
1803 if ((input != null) && (input.r != null)) {
1804 input.r.close();
1805 }
1806 sess.invalidate();
1807 if (handshakeSession != null) {
1808 handshakeSession.invalidate();
1809 }
1810
1811 int oldState = connectionState;
1812 if (connectionState < cs_ERROR) {
1813 connectionState = cs_ERROR;
1814 }
1815
1816 /*
1817 * Has there been an error received yet? If not, remember it.
1818 * By RFC 2246, we don't bother waiting for a response.
1819 * Fatal errors require immediate shutdown.
1820 */
1821 if (closeReason == null) {
1822 /*
1823 * Try to clear the kernel buffer to avoid TCP connection resets.
1824 */
1825 if (oldState == cs_HANDSHAKE) {
1826 sockInput.skip(sockInput.available());
1827 }
1828
1829 // If the description equals -1, the alert won't be sent to peer.
1830 if (description != -1) {
1831 sendAlert(Alerts.alert_fatal, description);
1832 }
1833 if (cause instanceof SSLException) { // only true if != null
1834 closeReason = (SSLException)cause;
1835 } else {
1836 closeReason =
1837 Alerts.getSSLException(description, cause, diagnostic);
1838 }
1839 }
1840
1841 /*
1842 * Clean up our side.
1843 */
1844 closeSocket();
1845 // Another thread may have disposed the ciphers during closing
1846 if (connectionState < cs_CLOSED) {
1847 connectionState = (oldState == cs_APP_CLOSED) ? cs_APP_CLOSED
1848 : cs_CLOSED;
1849
1850 // We should lock readLock and writeLock if no deadlock risks.
1851 // See comment in changeReadCiphers()
1852 readCipher.dispose();
1853 writeCipher.dispose();
1854 }
1855
1856 throw closeReason;
1857 }
1858
1859
1860 /*
1861 * Process an incoming alert ... caller must already have synchronized
1862 * access to "this".
1863 */
1864 private void recvAlert(InputRecord r) throws IOException {
1865 byte level = (byte)r.read();
1866 byte description = (byte)r.read();
1867 if (description == -1) { // check for short message
1868 fatal(Alerts.alert_illegal_parameter, "Short alert message");
1869 }
1870
1871 if (debug != null && (Debug.isOn("record") ||
1872 Debug.isOn("handshake"))) {
1873 synchronized (System.out) {
1874 System.out.print(threadName());
1875 System.out.print(", RECV " + protocolVersion + " ALERT: ");
1876 if (level == Alerts.alert_fatal) {
1877 System.out.print("fatal, ");
1878 } else if (level == Alerts.alert_warning) {
1879 System.out.print("warning, ");
1880 } else {
1881 System.out.print("<level " + (0x0ff & level) + ">, ");
1882 }
1883 System.out.println(Alerts.alertDescription(description));
1884 }
1885 }
1886
1887 if (level == Alerts.alert_warning) {
1888 if (description == Alerts.alert_close_notify) {
1889 if (connectionState == cs_HANDSHAKE) {
1890 fatal(Alerts.alert_unexpected_message,
1891 "Received close_notify during handshake");
1892 } else {
1893 closeInternal(false); // reply to close
1894 }
1895 } else {
1896
1897 //
1898 // The other legal warnings relate to certificates,
1899 // e.g. no_certificate, bad_certificate, etc; these
1900 // are important to the handshaking code, which can
1901 // also handle illegal protocol alerts if needed.
1902 //
1903 if (handshaker != null) {
1904 handshaker.handshakeAlert(description);
1905 }
1906 }
1907 } else { // fatal or unknown level
1908 String reason = "Received fatal alert: "
1909 + Alerts.alertDescription(description);
1910 if (closeReason == null) {
1911 closeReason = Alerts.getSSLException(description, reason);
1912 }
1913 fatal(Alerts.alert_unexpected_message, reason);
1914 }
1915 }
1916
1917
1918 /*
1919 * Emit alerts. Caller must have synchronized with "this".
1920 */
1921 private void sendAlert(byte level, byte description) {
1922 // the connectionState cannot be cs_START
1923 if (connectionState >= cs_SENT_CLOSE) {
1924 return;
1925 }
1926
1927 // For initial handshaking, don't send alert message to peer if
1928 // handshaker has not started.
1929 if (connectionState == cs_HANDSHAKE &&
1930 (handshaker == null || !handshaker.started())) {
1931 return;
1932 }
1933
1934 OutputRecord r = new OutputRecord(Record.ct_alert);
1935 r.setVersion(protocolVersion);
1936
1937 boolean useDebug = debug != null && Debug.isOn("ssl");
1938 if (useDebug) {
1939 synchronized (System.out) {
1940 System.out.print(threadName());
1941 System.out.print(", SEND " + protocolVersion + " ALERT: ");
1942 if (level == Alerts.alert_fatal) {
1943 System.out.print("fatal, ");
1944 } else if (level == Alerts.alert_warning) {
1945 System.out.print("warning, ");
1946 } else {
1947 System.out.print("<level = " + (0x0ff & level) + ">, ");
1948 }
1949 System.out.println("description = "
1950 + Alerts.alertDescription(description));
1951 }
1952 }
1953
1954 r.write(level);
1955 r.write(description);
1956 try {
1957 writeRecord(r);
1958 } catch (IOException e) {
1959 if (useDebug) {
1960 System.out.println(threadName() +
1961 ", Exception sending alert: " + e);
1962 }
1963 }
1964 }
1965
1966 //
1967 // VARIOUS OTHER METHODS
1968 //
1969
1970 /*
1971 * When a connection finishes handshaking by enabling use of a newly
1972 * negotiated session, each end learns about it in two halves (read,
1973 * and write). When both read and write ciphers have changed, and the
1974 * last handshake message has been read, the connection has joined
1975 * (rejoined) the new session.
1976 *
1977 * NOTE: The SSLv3 spec is rather unclear on the concepts here.
1978 * Sessions don't change once they're established (including cipher
1979 * suite and master secret) but connections can join them (and leave
1980 * them). They're created by handshaking, though sometime handshaking
1981 * causes connections to join up with pre-established sessions.
1982 */
1983 private void changeReadCiphers() throws SSLException {
1984 if (connectionState != cs_HANDSHAKE
1985 && connectionState != cs_RENEGOTIATE) {
1986 throw new SSLProtocolException(
1987 "State error, change cipher specs");
1988 }
1989
1990 // ... create decompressor
1991
1992 CipherBox oldCipher = readCipher;
1993
1994 try {
1995 readCipher = handshaker.newReadCipher();
1996 readMAC = handshaker.newReadMAC();
1997 } catch (GeneralSecurityException e) {
1998 // "can't happen"
1999 throw (SSLException)new SSLException
2000 ("Algorithm missing: ").initCause(e);
2001 }
2002
2003 /*
2004 * Dispose of any intermediate state in the underlying cipher.
2005 * For PKCS11 ciphers, this will release any attached sessions,
2006 * and thus make finalization faster.
2007 *
2008 * Since MAC's doFinal() is called for every SSL/TLS packet, it's
2009 * not necessary to do the same with MAC's.
2010 */
2011 oldCipher.dispose();
2012 }
2013
2014 // used by Handshaker
2015 void changeWriteCiphers() throws SSLException {
2016 if (connectionState != cs_HANDSHAKE
2017 && connectionState != cs_RENEGOTIATE) {
2018 throw new SSLProtocolException(
2019 "State error, change cipher specs");
2020 }
2021
2022 // ... create compressor
2023
2024 CipherBox oldCipher = writeCipher;
2025
2026 try {
2027 writeCipher = handshaker.newWriteCipher();
2028 writeMAC = handshaker.newWriteMAC();
2029 } catch (GeneralSecurityException e) {
2030 // "can't happen"
2031 throw (SSLException)new SSLException
2032 ("Algorithm missing: ").initCause(e);
2033 }
2034
2035 // See comment above.
2036 oldCipher.dispose();
2037 }
2038
2039 /*
2040 * Updates the SSL version associated with this connection.
2041 * Called from Handshaker once it has determined the negotiated version.
2042 */
2043 synchronized void setVersion(ProtocolVersion protocolVersion) {
2044 this.protocolVersion = protocolVersion;
2045 output.r.setVersion(protocolVersion);
2046 }
2047
2048 synchronized String getHost() {
2049 // Note that the host may be null or empty for localhost.
2050 if (host == null || host.length() == 0) {
2051 host = getInetAddress().getHostName();
2052 }
2053 return host;
2054 }
2055
2056 synchronized String getRawHostname() {
2057 return rawHostname;
2058 }
2059
2060 // ONLY used by HttpsClient to setup the URI specified hostname
2061 synchronized public void setHost(String host) {
2062 this.host = host;
2063 this.rawHostname = host;
2064 }
2065
2066 /**
2067 * Gets an input stream to read from the peer on the other side.
2068 * Data read from this stream was always integrity protected in
2069 * transit, and will usually have been confidentiality protected.
2070 */
2071 synchronized public InputStream getInputStream() throws IOException {
2072 if (isClosed()) {
2073 throw new SocketException("Socket is closed");
2074 }
2075
2076 /*
2077 * Can't call isConnected() here, because the Handshakers
2078 * do some initialization before we actually connect.
2079 */
2080 if (connectionState == cs_START) {
2081 throw new SocketException("Socket is not connected");
2082 }
2083
2084 return input;
2085 }
2086
2087 /**
2088 * Gets an output stream to write to the peer on the other side.
2089 * Data written on this stream is always integrity protected, and
2090 * will usually be confidentiality protected.
2091 */
2092 synchronized public OutputStream getOutputStream() throws IOException {
2093 if (isClosed()) {
2094 throw new SocketException("Socket is closed");
2095 }
2096
2097 /*
2098 * Can't call isConnected() here, because the Handshakers
2099 * do some initialization before we actually connect.
2100 */
2101 if (connectionState == cs_START) {
2102 throw new SocketException("Socket is not connected");
2103 }
2104
2105 return output;
2106 }
2107
2108 /**
2109 * Returns the the SSL Session in use by this connection. These can
2110 * be long lived, and frequently correspond to an entire login session
2111 * for some user.
2112 */
2113 public SSLSession getSession() {
2114 /*
2115 * Force a synchronous handshake, if appropriate.
2116 */
2117 if (getConnectionState() == cs_HANDSHAKE) {
2118 try {
2119 // start handshaking, if failed, the connection will be closed.
2120 startHandshake(false);
2121 } catch (IOException e) {
2122 // handshake failed. log and return a nullSession
2123 if (debug != null && Debug.isOn("handshake")) {
2124 System.out.println(threadName() +
2125 ", IOException in getSession(): " + e);
2126 }
2127 }
2128 }
2129 synchronized (this) {
2130 return sess;
2131 }
2132 }
2133
2134 @Override
2135 synchronized public SSLSession getHandshakeSession() {
2136 return handshakeSession;
2137 }
2138
2139 synchronized void setHandshakeSession(SSLSessionImpl session) {
2140 handshakeSession = session;
2141 }
2142
2143 /**
2144 * Controls whether new connections may cause creation of new SSL
2145 * sessions.
2146 *
2147 * As long as handshaking has not started, we can change
2148 * whether we enable session creations. Otherwise,
2149 * we will need to wait for the next handshake.
2150 */
2151 synchronized public void setEnableSessionCreation(boolean flag) {
2152 enableSessionCreation = flag;
2153
2154 if ((handshaker != null) && !handshaker.activated()) {
2155 handshaker.setEnableSessionCreation(enableSessionCreation);
2156 }
2157 }
2158
2159 /**
2160 * Returns true if new connections may cause creation of new SSL
2161 * sessions.
2162 */
2163 synchronized public boolean getEnableSessionCreation() {
2164 return enableSessionCreation;
2165 }
2166
2167
2168 /**
2169 * Sets the flag controlling whether a server mode socket
2170 * *REQUIRES* SSL client authentication.
2171 *
2172 * As long as handshaking has not started, we can change
2173 * whether client authentication is needed. Otherwise,
2174 * we will need to wait for the next handshake.
2175 */
2176 synchronized public void setNeedClientAuth(boolean flag) {
2177 doClientAuth = (flag ?
2178 SSLEngineImpl.clauth_required : SSLEngineImpl.clauth_none);
2179
2180 if ((handshaker != null) &&
2181 (handshaker instanceof ServerHandshaker) &&
2182 !handshaker.activated()) {
2183 ((ServerHandshaker) handshaker).setClientAuth(doClientAuth);
2184 }
2185 }
2186
2187 synchronized public boolean getNeedClientAuth() {
2188 return (doClientAuth == SSLEngineImpl.clauth_required);
2189 }
2190
2191 /**
2192 * Sets the flag controlling whether a server mode socket
2193 * *REQUESTS* SSL client authentication.
2194 *
2195 * As long as handshaking has not started, we can change
2196 * whether client authentication is requested. Otherwise,
2197 * we will need to wait for the next handshake.
2198 */
2199 synchronized public void setWantClientAuth(boolean flag) {
2200 doClientAuth = (flag ?
2201 SSLEngineImpl.clauth_requested : SSLEngineImpl.clauth_none);
2202
2203 if ((handshaker != null) &&
2204 (handshaker instanceof ServerHandshaker) &&
2205 !handshaker.activated()) {
2206 ((ServerHandshaker) handshaker).setClientAuth(doClientAuth);
2207 }
2208 }
2209
2210 synchronized public boolean getWantClientAuth() {
2211 return (doClientAuth == SSLEngineImpl.clauth_requested);
2212 }
2213
2214
2215 /**
2216 * Sets the flag controlling whether the socket is in SSL
2217 * client or server mode. Must be called before any SSL
2218 * traffic has started.
2219 */
2220 synchronized public void setUseClientMode(boolean flag) {
2221 switch (connectionState) {
2222
2223 case cs_START:
2224 /*
2225 * If we need to change the socket mode and the enabled
2226 * protocols haven't specifically been set by the user,
2227 * change them to the corresponding default ones.
2228 */
2229 if (roleIsServer != (!flag) &&
2230 sslContext.isDefaultProtocolList(enabledProtocols)) {
2231 enabledProtocols = sslContext.getDefaultProtocolList(!flag);
2232 }
2233 roleIsServer = !flag;
2234 break;
2235
2236 case cs_HANDSHAKE:
2237 /*
2238 * If we have a handshaker, but haven't started
2239 * SSL traffic, we can throw away our current
2240 * handshaker, and start from scratch. Don't
2241 * need to call doneConnect() again, we already
2242 * have the streams.
2243 */
2244 assert(handshaker != null);
2245 if (!handshaker.activated()) {
2246 /*
2247 * If we need to change the socket mode and the enabled
2248 * protocols haven't specifically been set by the user,
2249 * change them to the corresponding default ones.
2250 */
2251 if (roleIsServer != (!flag) &&
2252 sslContext.isDefaultProtocolList(enabledProtocols)) {
2253 enabledProtocols = sslContext.getDefaultProtocolList(!flag);
2254 }
2255 roleIsServer = !flag;
2256 connectionState = cs_START;
2257 initHandshaker();
2258 break;
2259 }
2260
2261 // If handshake has started, that's an error. Fall through...
2262
2263 default:
2264 if (debug != null && Debug.isOn("ssl")) {
2265 System.out.println(threadName() +
2266 ", setUseClientMode() invoked in state = " +
2267 connectionState);
2268 }
2269 throw new IllegalArgumentException(
2270 "Cannot change mode after SSL traffic has started");
2271 }
2272 }
2273
2274 synchronized public boolean getUseClientMode() {
2275 return !roleIsServer;
2276 }
2277
2278
2279 /**
2280 * Returns the names of the cipher suites which could be enabled for use
2281 * on an SSL connection. Normally, only a subset of these will actually
2282 * be enabled by default, since this list may include cipher suites which
2283 * do not support the mutual authentication of servers and clients, or
2284 * which do not protect data confidentiality. Servers may also need
2285 * certain kinds of certificates to use certain cipher suites.
2286 *
2287 * @return an array of cipher suite names
2288 */
2289 public String[] getSupportedCipherSuites() {
2290 return sslContext.getSuportedCipherSuiteList().toStringArray();
2291 }
2292
2293 /**
2294 * Controls which particular cipher suites are enabled for use on
2295 * this connection. The cipher suites must have been listed by
2296 * getCipherSuites() as being supported. Even if a suite has been
2297 * enabled, it might never be used if no peer supports it or the
2298 * requisite certificates (and private keys) are not available.
2299 *
2300 * @param suites Names of all the cipher suites to enable.
2301 */
2302 synchronized public void setEnabledCipherSuites(String[] suites) {
2303 enabledCipherSuites = new CipherSuiteList(suites);
2304 if ((handshaker != null) && !handshaker.activated()) {
2305 handshaker.setEnabledCipherSuites(enabledCipherSuites);
2306 }
2307 }
2308
2309 /**
2310 * Returns the names of the SSL cipher suites which are currently enabled
2311 * for use on this connection. When an SSL socket is first created,
2312 * all enabled cipher suites <em>(a)</em> protect data confidentiality,
2313 * by traffic encryption, and <em>(b)</em> can mutually authenticate
2314 * both clients and servers. Thus, in some environments, this value
2315 * might be empty.
2316 *
2317 * @return an array of cipher suite names
2318 */
2319 synchronized public String[] getEnabledCipherSuites() {
2320 return enabledCipherSuites.toStringArray();
2321 }
2322
2323
2324 /**
2325 * Returns the protocols that are supported by this implementation.
2326 * A subset of the supported protocols may be enabled for this connection
2327 * @return an array of protocol names.
2328 */
2329 public String[] getSupportedProtocols() {
2330 return sslContext.getSuportedProtocolList().toStringArray();
2331 }
2332
2333 /**
2334 * Controls which protocols are enabled for use on
2335 * this connection. The protocols must have been listed by
2336 * getSupportedProtocols() as being supported.
2337 *
2338 * @param protocols protocols to enable.
2339 * @exception IllegalArgumentException when one of the protocols
2340 * named by the parameter is not supported.
2341 */
2342 synchronized public void setEnabledProtocols(String[] protocols) {
2343 enabledProtocols = new ProtocolList(protocols);
2344 if ((handshaker != null) && !handshaker.activated()) {
2345 handshaker.setEnabledProtocols(enabledProtocols);
2346 }
2347 }
2348
2349 synchronized public String[] getEnabledProtocols() {
2350 return enabledProtocols.toStringArray();
2351 }
2352
2353 /**
2354 * Assigns the socket timeout.
2355 * @see java.net.Socket#setSoTimeout
2356 */
2357 public void setSoTimeout(int timeout) throws SocketException {
2358 if ((debug != null) && Debug.isOn("ssl")) {
2359 System.out.println(threadName() +
2360 ", setSoTimeout(" + timeout + ") called");
2361 }
2362 if (self == this) {
2363 super.setSoTimeout(timeout);
2364 } else {
2365 self.setSoTimeout(timeout);
2366 }
2367 }
2368
2369 /**
2370 * Registers an event listener to receive notifications that an
2371 * SSL handshake has completed on this connection.
2372 */
2373 public synchronized void addHandshakeCompletedListener(
2374 HandshakeCompletedListener listener) {
2375 if (listener == null) {
2376 throw new IllegalArgumentException("listener is null");
2377 }
2378 if (handshakeListeners == null) {
2379 handshakeListeners = new
2380 HashMap<HandshakeCompletedListener, AccessControlContext>(4);
2381 }
2382 handshakeListeners.put(listener, AccessController.getContext());
2383 }
2384
2385
2386 /**
2387 * Removes a previously registered handshake completion listener.
2388 */
2389 public synchronized void removeHandshakeCompletedListener(
2390 HandshakeCompletedListener listener) {
2391 if (handshakeListeners == null) {
2392 throw new IllegalArgumentException("no listeners");
2393 }
2394 if (handshakeListeners.remove(listener) == null) {
2395 throw new IllegalArgumentException("listener not registered");
2396 }
2397 if (handshakeListeners.isEmpty()) {
2398 handshakeListeners = null;
2399 }
2400 }
2401
2402 /**
2403 * Returns the SSLParameters in effect for this SSLSocket.
2404 */
2405 synchronized public SSLParameters getSSLParameters() {
2406 SSLParameters params = super.getSSLParameters();
2407
2408 // the super implementation does not handle the following parameters
2409 params.setEndpointIdentificationAlgorithm(identificationProtocol);
2410 params.setAlgorithmConstraints(algorithmConstraints);
2411
2412 return params;
2413 }
2414
2415 /**
2416 * Applies SSLParameters to this socket.
2417 */
2418 synchronized public void setSSLParameters(SSLParameters params) {
2419 super.setSSLParameters(params);
2420
2421 // the super implementation does not handle the following parameters
2422 identificationProtocol = params.getEndpointIdentificationAlgorithm();
2423 algorithmConstraints = params.getAlgorithmConstraints();
2424 if ((handshaker != null) && !handshaker.started()) {
2425 handshaker.setIdentificationProtocol(identificationProtocol);
2426 handshaker.setAlgorithmConstraints(algorithmConstraints);
2427 }
2428 }
2429
2430 //
2431 // We allocate a separate thread to deliver handshake completion
2432 // events. This ensures that the notifications don't block the
2433 // protocol state machine.
2434 //
2435 private static class NotifyHandshakeThread extends Thread {
2436
2437 private Set<Map.Entry<HandshakeCompletedListener,AccessControlContext>>
2438 targets; // who gets notified
2439 private HandshakeCompletedEvent event; // the notification
2440
2441 NotifyHandshakeThread(
2442 Set<Map.Entry<HandshakeCompletedListener,AccessControlContext>>
2443 entrySet, HandshakeCompletedEvent e) {
2444
2445 super("HandshakeCompletedNotify-Thread");
2446 targets = entrySet;
2447 event = e;
2448 }
2449
2450 public void run() {
2451 for (Map.Entry<HandshakeCompletedListener,AccessControlContext>
2452 entry : targets) {
2453
2454 final HandshakeCompletedListener l = entry.getKey();
2455 AccessControlContext acc = entry.getValue();
2456 AccessController.doPrivileged(new PrivilegedAction<Void>() {
2457 public Void run() {
2458 l.handshakeCompleted(event);
2459 return null;
2460 }
2461 }, acc);
2462 }
2463 }
2464 }
2465
2466 /**
2467 * Return the name of the current thread. Utility method.
2468 */
2469 private static String threadName() {
2470 return Thread.currentThread().getName();
2471 }
2472
2473 /**
2474 * Returns a printable representation of this end of the connection.
2475 */
2476 public String toString() {
2477 StringBuffer retval = new StringBuffer(80);
2478
2479 retval.append(Integer.toHexString(hashCode()));
2480 retval.append("[");
2481 retval.append(sess.getCipherSuite());
2482 retval.append(": ");
2483
2484 if (self == this) {
2485 retval.append(super.toString());
2486 } else {
2487 retval.append(self.toString());
2488 }
2489 retval.append("]");
2490
2491 return retval.toString();
2492 }
2493}