• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2003, 2013, 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 package sun.security.ssl;
27 
28 import java.io.*;
29 import java.nio.*;
30 import java.nio.ReadOnlyBufferException;
31 import java.util.LinkedList;
32 import java.security.*;
33 
34 import javax.crypto.BadPaddingException;
35 
36 import javax.net.ssl.*;
37 import javax.net.ssl.SSLEngineResult.*;
38 
39 import com.sun.net.ssl.internal.ssl.X509ExtendedTrustManager;
40 
41 /**
42  * Implementation of an non-blocking SSLEngine.
43  *
44  * *Currently*, the SSLEngine code exists in parallel with the current
45  * SSLSocket.  As such, the current implementation is using legacy code
46  * with many of the same abstractions.  However, it varies in many
47  * areas, most dramatically in the IO handling.
48  *
49  * There are three main I/O threads that can be existing in parallel:
50  * wrap(), unwrap(), and beginHandshake().  We are encouraging users to
51  * not call multiple instances of wrap or unwrap, because the data could
52  * appear to flow out of the SSLEngine in a non-sequential order.  We
53  * take all steps we can to at least make sure the ordering remains
54  * consistent, but once the calls returns, anything can happen.  For
55  * example, thread1 and thread2 both call wrap, thread1 gets the first
56  * packet, thread2 gets the second packet, but thread2 gets control back
57  * before thread1, and sends the data.  The receiving side would see an
58  * out-of-order error.
59  *
60  * Handshaking is still done the same way as SSLSocket using the normal
61  * InputStream/OutputStream abstactions.  We create
62  * ClientHandshakers/ServerHandshakers, which produce/consume the
63  * handshaking data.  The transfer of the data is largely handled by the
64  * HandshakeInStream/HandshakeOutStreams.  Lastly, the
65  * InputRecord/OutputRecords still have the same functionality, except
66  * that they are overridden with EngineInputRecord/EngineOutputRecord,
67  * which provide SSLEngine-specific functionality.
68  *
69  * Some of the major differences are:
70  *
71  * EngineInputRecord/EngineOutputRecord/EngineWriter:
72  *
73  *      In order to avoid writing whole new control flows for
74  *      handshaking, and to reuse most of the same code, we kept most
75  *      of the actual handshake code the same.  As usual, reading
76  *      handshake data may trigger output of more handshake data, so
77  *      what we do is write this data to internal buffers, and wait for
78  *      wrap() to be called to give that data a ride.
79  *
80  *      All data is routed through
81  *      EngineInputRecord/EngineOutputRecord.  However, all handshake
82  *      data (ct_alert/ct_change_cipher_spec/ct_handshake) are passed
83  *      through to the the underlying InputRecord/OutputRecord, and
84  *      the data uses the internal buffers.
85  *
86  *      Application data is handled slightly different, we copy the data
87  *      directly from the src to the dst buffers, and do all operations
88  *      on those buffers, saving the overhead of multiple copies.
89  *
90  *      In the case of an inbound record, unwrap passes the inbound
91  *      ByteBuffer to the InputRecord.  If the data is handshake data,
92  *      the data is read into the InputRecord's internal buffer.  If
93  *      the data is application data, the data is decoded directly into
94  *      the dst buffer.
95  *
96  *      In the case of an outbound record, when the write to the
97  *      "real" OutputStream's would normally take place, instead we
98  *      call back up to the EngineOutputRecord's version of
99  *      writeBuffer, at which time we capture the resulting output in a
100  *      ByteBuffer, and send that back to the EngineWriter for internal
101  *      storage.
102  *
103  *      EngineWriter is responsible for "handling" all outbound
104  *      data, be it handshake or app data, and for returning the data
105  *      to wrap() in the proper order.
106  *
107  * ClientHandshaker/ServerHandshaker/Handshaker:
108  *      Methods which relied on SSLSocket now have work on either
109  *      SSLSockets or SSLEngines.
110  *
111  * @author Brad Wetmore
112  */
113 final public class SSLEngineImpl extends SSLEngine {
114 
115     //
116     // Fields and global comments
117     //
118 
119     /*
120      * There's a state machine associated with each connection, which
121      * among other roles serves to negotiate session changes.
122      *
123      * - START with constructor, until the TCP connection's around.
124      * - HANDSHAKE picks session parameters before allowing traffic.
125      *          There are many substates due to sequencing requirements
126      *          for handshake messages.
127      * - DATA may be transmitted.
128      * - RENEGOTIATE state allows concurrent data and handshaking
129      *          traffic ("same" substates as HANDSHAKE), and terminates
130      *          in selection of new session (and connection) parameters
131      * - ERROR state immediately precedes abortive disconnect.
132      * - CLOSED when one side closes down, used to start the shutdown
133      *          process.  SSL connection objects are not reused.
134      *
135      * State affects what SSL record types may legally be sent:
136      *
137      * - Handshake ... only in HANDSHAKE and RENEGOTIATE states
138      * - App Data ... only in DATA and RENEGOTIATE states
139      * - Alert ... in HANDSHAKE, DATA, RENEGOTIATE
140      *
141      * Re what may be received:  same as what may be sent, except that
142      * HandshakeRequest handshaking messages can come from servers even
143      * in the application data state, to request entry to RENEGOTIATE.
144      *
145      * The state machine within HANDSHAKE and RENEGOTIATE states controls
146      * the pending session, not the connection state, until the change
147      * cipher spec and "Finished" handshake messages are processed and
148      * make the "new" session become the current one.
149      *
150      * NOTE: details of the SMs always need to be nailed down better.
151      * The text above illustrates the core ideas.
152      *
153      *                +---->-------+------>--------->-------+
154      *                |            |                        |
155      *     <-----<    ^            ^  <-----<               |
156      *START>----->HANDSHAKE>----->DATA>----->RENEGOTIATE    |
157      *                v            v               v        |
158      *                |            |               |        |
159      *                +------------+---------------+        |
160      *                |                                     |
161      *                v                                     |
162      *               ERROR>------>----->CLOSED<--------<----+
163      *
164      * ALSO, note that the the purpose of handshaking (renegotiation is
165      * included) is to assign a different, and perhaps new, session to
166      * the connection.  The SSLv3 spec is a bit confusing on that new
167      * protocol feature.
168      */
169     private int                 connectionState;
170 
171     private static final int    cs_START = 0;
172     private static final int    cs_HANDSHAKE = 1;
173     private static final int    cs_DATA = 2;
174     private static final int    cs_RENEGOTIATE = 3;
175     private static final int    cs_ERROR = 4;
176     private static final int    cs_CLOSED = 6;
177 
178     /*
179      * Once we're in state cs_CLOSED, we can continue to
180      * wrap/unwrap until we finish sending/receiving the messages
181      * for close_notify.  EngineWriter handles outboundDone.
182      */
183     private boolean             inboundDone = false;
184 
185     EngineWriter                writer;
186 
187     /*
188      * The authentication context holds all information used to establish
189      * who this end of the connection is (certificate chains, private keys,
190      * etc) and who is trusted (e.g. as CAs or websites).
191      */
192     private SSLContextImpl      sslContext;
193 
194     /*
195      * This connection is one of (potentially) many associated with
196      * any given session.  The output of the handshake protocol is a
197      * new session ... although all the protocol description talks
198      * about changing the cipher spec (and it does change), in fact
199      * that's incidental since it's done by changing everything that
200      * is associated with a session at the same time.  (TLS/IETF may
201      * change that to add client authentication w/o new key exchg.)
202      */
203     private Handshaker                  handshaker;
204     private SSLSessionImpl              sess;
205     private volatile SSLSessionImpl     handshakeSession;
206 
207 
208     /*
209      * Client authentication be off, requested, or required.
210      *
211      * This will be used by both this class and SSLSocket's variants.
212      */
213     static final byte           clauth_none = 0;
214     static final byte           clauth_requested = 1;
215     static final byte           clauth_required = 2;
216 
217     /*
218      * Flag indicating if the next record we receive MUST be a Finished
219      * message. Temporarily set during the handshake to ensure that
220      * a change cipher spec message is followed by a finished message.
221      */
222     private boolean             expectingFinished;
223 
224 
225     /*
226      * If someone tries to closeInbound() (say at End-Of-Stream)
227      * our engine having received a close_notify, we need to
228      * notify the app that we may have a truncation attack underway.
229      */
230     private boolean             recvCN;
231 
232     /*
233      * For improved diagnostics, we detail connection closure
234      * If the engine is closed (connectionState >= cs_ERROR),
235      * closeReason != null indicates if the engine was closed
236      * because of an error or because or normal shutdown.
237      */
238     private SSLException        closeReason;
239 
240     /*
241      * Per-connection private state that doesn't change when the
242      * session is changed.
243      */
244     private byte                        doClientAuth;
245     private boolean                     enableSessionCreation = true;
246     EngineInputRecord                   inputRecord;
247     EngineOutputRecord                  outputRecord;
248     private AccessControlContext        acc;
249 
250     // The cipher suites enabled for use on this connection.
251     private CipherSuiteList             enabledCipherSuites;
252 
253     // the endpoint identification protocol
254     private String                      identificationProtocol = null;
255 
256     // The cryptographic algorithm constraints
257     private AlgorithmConstraints        algorithmConstraints = null;
258 
259     // Have we been told whether we're client or server?
260     private boolean                     serverModeSet = false;
261     private boolean                     roleIsServer;
262 
263     /*
264      * The protocol versions enabled for use on this connection.
265      *
266      * Note: we support a pseudo protocol called SSLv2Hello which when
267      * set will result in an SSL v2 Hello being sent with SSL (version 3.0)
268      * or TLS (version 3.1, 3.2, etc.) version info.
269      */
270     private ProtocolList        enabledProtocols;
271 
272     /*
273      * The SSL version associated with this connection.
274      */
275     private ProtocolVersion     protocolVersion = ProtocolVersion.DEFAULT;
276 
277     /*
278      * Crypto state that's reinitialized when the session changes.
279      */
280     private MAC                 readMAC, writeMAC;
281     private CipherBox           readCipher, writeCipher;
282     // NOTE: compression state would be saved here
283 
284     /*
285      * security parameters for secure renegotiation.
286      */
287     private boolean             secureRenegotiation;
288     private byte[]              clientVerifyData;
289     private byte[]              serverVerifyData;
290 
291     /*
292      * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
293      * IMPORTANT STUFF TO UNDERSTANDING THE SYNCHRONIZATION ISSUES.
294      * READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
295      *
296      * There are several locks here.
297      *
298      * The primary lock is the per-instance lock used by
299      * synchronized(this) and the synchronized methods.  It controls all
300      * access to things such as the connection state and variables which
301      * affect handshaking.  If we are inside a synchronized method, we
302      * can access the state directly, otherwise, we must use the
303      * synchronized equivalents.
304      *
305      * Note that we must never acquire the <code>this</code> lock after
306      * <code>writeLock</code> or run the risk of deadlock.
307      *
308      * Grab some coffee, and be careful with any code changes.
309      */
310     private Object              wrapLock;
311     private Object              unwrapLock;
312     Object                      writeLock;
313 
314     /*
315      * Is it the first application record to write?
316      */
317     private boolean isFirstAppOutputRecord = true;
318 
319     /*
320      * Class and subclass dynamic debugging support
321      */
322     private static final Debug debug = Debug.getInstance("ssl");
323 
324     //
325     // Initialization/Constructors
326     //
327 
328     /**
329      * Constructor for an SSLEngine from SSLContext, without
330      * host/port hints.  This Engine will not be able to cache
331      * sessions, but must renegotiate everything by hand.
332      */
SSLEngineImpl(SSLContextImpl ctx)333     SSLEngineImpl(SSLContextImpl ctx) {
334         super();
335         init(ctx);
336     }
337 
338     /**
339      * Constructor for an SSLEngine from SSLContext.
340      */
SSLEngineImpl(SSLContextImpl ctx, String host, int port)341     SSLEngineImpl(SSLContextImpl ctx, String host, int port) {
342         super(host, port);
343         init(ctx);
344     }
345 
346     /**
347      * Initializes the Engine
348      */
init(SSLContextImpl ctx)349     private void init(SSLContextImpl ctx) {
350         if (debug != null && Debug.isOn("ssl")) {
351             System.out.println("Using SSLEngineImpl.");
352         }
353 
354         sslContext = ctx;
355         sess = SSLSessionImpl.nullSession;
356         handshakeSession = null;
357 
358         /*
359          * State is cs_START until we initialize the handshaker.
360          *
361          * Apps using SSLEngine are probably going to be server.
362          * Somewhat arbitrary choice.
363          */
364         roleIsServer = true;
365         connectionState = cs_START;
366 
367         /*
368          * default read and write side cipher and MAC support
369          *
370          * Note:  compression support would go here too
371          */
372         readCipher = CipherBox.NULL;
373         readMAC = MAC.NULL;
374         writeCipher = CipherBox.NULL;
375         writeMAC = MAC.NULL;
376 
377         // default security parameters for secure renegotiation
378         secureRenegotiation = false;
379         clientVerifyData = new byte[0];
380         serverVerifyData = new byte[0];
381 
382         enabledCipherSuites =
383                 sslContext.getDefaultCipherSuiteList(roleIsServer);
384         enabledProtocols =
385                 sslContext.getDefaultProtocolList(roleIsServer);
386 
387         wrapLock = new Object();
388         unwrapLock = new Object();
389         writeLock = new Object();
390 
391         /*
392          * Save the Access Control Context.  This will be used later
393          * for a couple of things, including providing a context to
394          * run tasks in, and for determining which credentials
395          * to use for Subject based (JAAS) decisions
396          */
397         acc = AccessController.getContext();
398 
399         /*
400          * All outbound application data goes through this OutputRecord,
401          * other data goes through their respective records created
402          * elsewhere.  All inbound data goes through this one
403          * input record.
404          */
405         outputRecord =
406             new EngineOutputRecord(Record.ct_application_data, this);
407         inputRecord = new EngineInputRecord(this);
408         inputRecord.enableFormatChecks();
409 
410         writer = new EngineWriter();
411     }
412 
413     /**
414      * Initialize the handshaker object. This means:
415      *
416      *  . if a handshake is already in progress (state is cs_HANDSHAKE
417      *    or cs_RENEGOTIATE), do nothing and return
418      *
419      *  . if the engine is already closed, throw an Exception (internal error)
420      *
421      *  . otherwise (cs_START or cs_DATA), create the appropriate handshaker
422      *    object and advance the connection state (to cs_HANDSHAKE or
423      *    cs_RENEGOTIATE, respectively).
424      *
425      * This method is called right after a new engine is created, when
426      * starting renegotiation, or when changing client/server mode of the
427      * engine.
428      */
initHandshaker()429     private void initHandshaker() {
430         switch (connectionState) {
431 
432         //
433         // Starting a new handshake.
434         //
435         case cs_START:
436         case cs_DATA:
437             break;
438 
439         //
440         // We're already in the middle of a handshake.
441         //
442         case cs_HANDSHAKE:
443         case cs_RENEGOTIATE:
444             return;
445 
446         //
447         // Anyone allowed to call this routine is required to
448         // do so ONLY if the connection state is reasonable...
449         //
450         default:
451             throw new IllegalStateException("Internal error");
452         }
453 
454         // state is either cs_START or cs_DATA
455         if (connectionState == cs_START) {
456             connectionState = cs_HANDSHAKE;
457         } else { // cs_DATA
458             connectionState = cs_RENEGOTIATE;
459         }
460         if (roleIsServer) {
461             handshaker = new ServerHandshaker(this, sslContext,
462                     enabledProtocols, doClientAuth,
463                     protocolVersion, connectionState == cs_HANDSHAKE,
464                     secureRenegotiation, clientVerifyData, serverVerifyData);
465         } else {
466             handshaker = new ClientHandshaker(this, sslContext,
467                     enabledProtocols,
468                     protocolVersion, connectionState == cs_HANDSHAKE,
469                     secureRenegotiation, clientVerifyData, serverVerifyData);
470         }
471         handshaker.setEnabledCipherSuites(enabledCipherSuites);
472         handshaker.setEnableSessionCreation(enableSessionCreation);
473     }
474 
475     /*
476      * Report the current status of the Handshaker
477      */
getHSStatus(HandshakeStatus hss)478     private HandshakeStatus getHSStatus(HandshakeStatus hss) {
479 
480         if (hss != null) {
481             return hss;
482         }
483 
484         synchronized (this) {
485             if (writer.hasOutboundData()) {
486                 return HandshakeStatus.NEED_WRAP;
487             } else if (handshaker != null) {
488                 if (handshaker.taskOutstanding()) {
489                     return HandshakeStatus.NEED_TASK;
490                 } else {
491                     return HandshakeStatus.NEED_UNWRAP;
492                 }
493             } else if (connectionState == cs_CLOSED) {
494                 /*
495                  * Special case where we're closing, but
496                  * still need the close_notify before we
497                  * can officially be closed.
498                  *
499                  * Note isOutboundDone is taken care of by
500                  * hasOutboundData() above.
501                  */
502                 if (!isInboundDone()) {
503                     return HandshakeStatus.NEED_UNWRAP;
504                 } // else not handshaking
505             }
506 
507             return HandshakeStatus.NOT_HANDSHAKING;
508         }
509     }
510 
checkTaskThrown()511     synchronized private void checkTaskThrown() throws SSLException {
512         if (handshaker != null) {
513             handshaker.checkThrown();
514         }
515     }
516 
517     //
518     // Handshaking and connection state code
519     //
520 
521     /*
522      * Provides "this" synchronization for connection state.
523      * Otherwise, you can access it directly.
524      */
getConnectionState()525     synchronized private int getConnectionState() {
526         return connectionState;
527     }
528 
setConnectionState(int state)529     synchronized private void setConnectionState(int state) {
530         connectionState = state;
531     }
532 
533     /*
534      * Get the Access Control Context.
535      *
536      * Used for a known context to
537      * run tasks in, and for determining which credentials
538      * to use for Subject-based (JAAS) decisions.
539      */
getAcc()540     AccessControlContext getAcc() {
541         return acc;
542     }
543 
544     /*
545      * Is a handshake currently underway?
546      */
getHandshakeStatus()547     public SSLEngineResult.HandshakeStatus getHandshakeStatus() {
548         return getHSStatus(null);
549     }
550 
551     /*
552      * When a connection finishes handshaking by enabling use of a newly
553      * negotiated session, each end learns about it in two halves (read,
554      * and write).  When both read and write ciphers have changed, and the
555      * last handshake message has been read, the connection has joined
556      * (rejoined) the new session.
557      *
558      * NOTE:  The SSLv3 spec is rather unclear on the concepts here.
559      * Sessions don't change once they're established (including cipher
560      * suite and master secret) but connections can join them (and leave
561      * them).  They're created by handshaking, though sometime handshaking
562      * causes connections to join up with pre-established sessions.
563      *
564      * Synchronized on "this" from readRecord.
565      */
changeReadCiphers()566     private void changeReadCiphers() throws SSLException {
567         if (connectionState != cs_HANDSHAKE
568                 && connectionState != cs_RENEGOTIATE) {
569             throw new SSLProtocolException(
570                 "State error, change cipher specs");
571         }
572 
573         // ... create decompressor
574 
575         CipherBox oldCipher = readCipher;
576 
577         try {
578             readCipher = handshaker.newReadCipher();
579             readMAC = handshaker.newReadMAC();
580         } catch (GeneralSecurityException e) {
581             // "can't happen"
582             throw (SSLException)new SSLException
583                                 ("Algorithm missing:  ").initCause(e);
584         }
585 
586         /*
587          * Dispose of any intermediate state in the underlying cipher.
588          * For PKCS11 ciphers, this will release any attached sessions,
589          * and thus make finalization faster.
590          *
591          * Since MAC's doFinal() is called for every SSL/TLS packet, it's
592          * not necessary to do the same with MAC's.
593          */
594         oldCipher.dispose();
595     }
596 
597     /*
598      * used by Handshaker to change the active write cipher, follows
599      * the output of the CCS message.
600      *
601      * Also synchronized on "this" from readRecord/delegatedTask.
602      */
changeWriteCiphers()603     void changeWriteCiphers() throws SSLException {
604         if (connectionState != cs_HANDSHAKE
605                 && connectionState != cs_RENEGOTIATE) {
606             throw new SSLProtocolException(
607                 "State error, change cipher specs");
608         }
609 
610         // ... create compressor
611 
612         CipherBox oldCipher = writeCipher;
613 
614         try {
615             writeCipher = handshaker.newWriteCipher();
616             writeMAC = handshaker.newWriteMAC();
617         } catch (GeneralSecurityException e) {
618             // "can't happen"
619             throw (SSLException)new SSLException
620                                 ("Algorithm missing:  ").initCause(e);
621         }
622 
623         // See comment above.
624         oldCipher.dispose();
625 
626         // reset the flag of the first application record
627         isFirstAppOutputRecord = true;
628     }
629 
630     /*
631      * Updates the SSL version associated with this connection.
632      * Called from Handshaker once it has determined the negotiated version.
633      */
setVersion(ProtocolVersion protocolVersion)634     synchronized void setVersion(ProtocolVersion protocolVersion) {
635         this.protocolVersion = protocolVersion;
636         outputRecord.setVersion(protocolVersion);
637     }
638 
639 
640     /**
641      * Kickstart the handshake if it is not already in progress.
642      * This means:
643      *
644      *  . if handshaking is already underway, do nothing and return
645      *
646      *  . if the engine is not connected or already closed, throw an
647      *    Exception.
648      *
649      *  . otherwise, call initHandshake() to initialize the handshaker
650      *    object and progress the state. Then, send the initial
651      *    handshaking message if appropriate (always on clients and
652      *    on servers when renegotiating).
653      */
kickstartHandshake()654     private synchronized void kickstartHandshake() throws IOException {
655         switch (connectionState) {
656 
657         case cs_START:
658             if (!serverModeSet) {
659                 throw new IllegalStateException(
660                     "Client/Server mode not yet set.");
661             }
662             initHandshaker();
663             break;
664 
665         case cs_HANDSHAKE:
666             // handshaker already setup, proceed
667             break;
668 
669         case cs_DATA:
670             if (!secureRenegotiation && !Handshaker.allowUnsafeRenegotiation) {
671                 throw new SSLHandshakeException(
672                         "Insecure renegotiation is not allowed");
673             }
674 
675             if (!secureRenegotiation) {
676                 if (debug != null && Debug.isOn("handshake")) {
677                     System.out.println(
678                         "Warning: Using insecure renegotiation");
679                 }
680             }
681 
682             // initialize the handshaker, move to cs_RENEGOTIATE
683             initHandshaker();
684             break;
685 
686         case cs_RENEGOTIATE:
687             // handshaking already in progress, return
688             return;
689 
690         default:
691             // cs_ERROR/cs_CLOSED
692             throw new SSLException("SSLEngine is closing/closed");
693         }
694 
695         //
696         // Kickstart handshake state machine if we need to ...
697         //
698         // Note that handshaker.kickstart() writes the message
699         // to its HandshakeOutStream, which calls back into
700         // SSLSocketImpl.writeRecord() to send it.
701         //
702         if (!handshaker.activated()) {
703              // prior to handshaking, activate the handshake
704             if (connectionState == cs_RENEGOTIATE) {
705                 // don't use SSLv2Hello when renegotiating
706                 handshaker.activate(protocolVersion);
707             } else {
708                 handshaker.activate(null);
709             }
710 
711             if (handshaker instanceof ClientHandshaker) {
712                 // send client hello
713                 handshaker.kickstart();
714             } else {    // instanceof ServerHandshaker
715                 if (connectionState == cs_HANDSHAKE) {
716                     // initial handshake, no kickstart message to send
717                 } else {
718                     // we want to renegotiate, send hello request
719                     handshaker.kickstart();
720 
721                     // hello request is not included in the handshake
722                     // hashes, reset them
723                     handshaker.handshakeHash.reset();
724                 }
725             }
726         }
727     }
728 
729     /*
730      * Start a SSLEngine handshake
731      */
beginHandshake()732     public void beginHandshake() throws SSLException {
733         try {
734             kickstartHandshake();
735         } catch (Exception e) {
736             fatal(Alerts.alert_handshake_failure,
737                 "Couldn't kickstart handshaking", e);
738         }
739     }
740 
741 
742     //
743     // Read/unwrap side
744     //
745 
746 
747     /**
748      * Unwraps a buffer.  Does a variety of checks before grabbing
749      * the unwrapLock, which blocks multiple unwraps from occuring.
750      */
unwrap(ByteBuffer netData, ByteBuffer [] appData, int offset, int length)751     public SSLEngineResult unwrap(ByteBuffer netData, ByteBuffer [] appData,
752             int offset, int length) throws SSLException {
753 
754         EngineArgs ea = new EngineArgs(netData, appData, offset, length);
755 
756         try {
757             synchronized (unwrapLock) {
758                 return readNetRecord(ea);
759             }
760         } catch (Exception e) {
761             /*
762              * Don't reset position so it looks like we didn't
763              * consume anything.  We did consume something, and it
764              * got us into this situation, so report that much back.
765              * Our days of consuming are now over anyway.
766              */
767             fatal(Alerts.alert_internal_error,
768                 "problem unwrapping net record", e);
769             return null;  // make compiler happy
770         } finally {
771             /*
772              * Just in case something failed to reset limits properly.
773              */
774             ea.resetLim();
775         }
776     }
777 
778     /*
779      * Makes additional checks for unwrap, but this time more
780      * specific to this packet and the current state of the machine.
781      */
readNetRecord(EngineArgs ea)782     private SSLEngineResult readNetRecord(EngineArgs ea) throws IOException {
783 
784         Status status = null;
785         HandshakeStatus hsStatus = null;
786 
787         /*
788          * See if the handshaker needs to report back some SSLException.
789          */
790         checkTaskThrown();
791 
792         /*
793          * Check if we are closing/closed.
794          */
795         if (isInboundDone()) {
796             return new SSLEngineResult(Status.CLOSED, getHSStatus(null), 0, 0);
797         }
798 
799         /*
800          * If we're still in cs_HANDSHAKE, make sure it's been
801          * started.
802          */
803         synchronized (this) {
804             if ((connectionState == cs_HANDSHAKE) ||
805                     (connectionState == cs_START)) {
806                 kickstartHandshake();
807 
808                 /*
809                  * If there's still outbound data to flush, we
810                  * can return without trying to unwrap anything.
811                  */
812                 hsStatus = getHSStatus(null);
813 
814                 if (hsStatus == HandshakeStatus.NEED_WRAP) {
815                     return new SSLEngineResult(Status.OK, hsStatus, 0, 0);
816                 }
817             }
818         }
819 
820         /*
821          * Grab a copy of this if it doesn't already exist,
822          * and we can use it several places before anything major
823          * happens on this side.  Races aren't critical
824          * here.
825          */
826         if (hsStatus == null) {
827             hsStatus = getHSStatus(null);
828         }
829 
830         /*
831          * If we have a task outstanding, this *MUST* be done before
832          * doing any more unwrapping, because we could be in the middle
833          * of receiving a handshake message, for example, a finished
834          * message which would change the ciphers.
835          */
836         if (hsStatus == HandshakeStatus.NEED_TASK) {
837             return new SSLEngineResult(
838                 Status.OK, hsStatus, 0, 0);
839         }
840 
841         /*
842          * Check the packet to make sure enough is here.
843          * This will also indirectly check for 0 len packets.
844          */
845         int packetLen = inputRecord.bytesInCompletePacket(ea.netData);
846 
847         // Is this packet bigger than SSL/TLS normally allows?
848         if (packetLen > sess.getPacketBufferSize()) {
849             if (packetLen > Record.maxLargeRecordSize) {
850                 throw new SSLProtocolException(
851                     "Input SSL/TLS record too big: max = " +
852                     Record.maxLargeRecordSize +
853                     " len = " + packetLen);
854             } else {
855                 // Expand the expected maximum packet/application buffer
856                 // sizes.
857                 sess.expandBufferSizes();
858             }
859         }
860 
861         /*
862          * Check for OVERFLOW.
863          *
864          * To be considered: We could delay enforcing the application buffer
865          * free space requirement until after the initial handshaking.
866          */
867         if ((packetLen - Record.headerSize) > ea.getAppRemaining()) {
868             return new SSLEngineResult(Status.BUFFER_OVERFLOW, hsStatus, 0, 0);
869         }
870 
871         // check for UNDERFLOW.
872         if ((packetLen == -1) || (ea.netData.remaining() < packetLen)) {
873             return new SSLEngineResult(
874                 Status.BUFFER_UNDERFLOW, hsStatus, 0, 0);
875         }
876 
877         /*
878          * We're now ready to actually do the read.
879          * The only result code we really need to be exactly
880          * right is the HS finished, for signaling to
881          * HandshakeCompletedListeners.
882          */
883         try {
884             hsStatus = readRecord(ea);
885         } catch (SSLException e) {
886             throw e;
887         } catch (IOException e) {
888             SSLException ex = new SSLException("readRecord");
889             ex.initCause(e);
890             throw ex;
891         }
892 
893         /*
894          * Check the various condition that we could be reporting.
895          *
896          * It's *possible* something might have happened between the
897          * above and now, but it was better to minimally lock "this"
898          * during the read process.  We'll return the current
899          * status, which is more representative of the current state.
900          *
901          * status above should cover:  FINISHED, NEED_TASK
902          */
903         status = (isInboundDone() ? Status.CLOSED : Status.OK);
904         hsStatus = getHSStatus(hsStatus);
905 
906         return new SSLEngineResult(status, hsStatus,
907             ea.deltaNet(), ea.deltaApp());
908     }
909 
910     /*
911      * Actually do the read record processing.
912      *
913      * Returns a Status if it can make specific determinations
914      * of the engine state.  In particular, we need to signal
915      * that a handshake just completed.
916      *
917      * It would be nice to be symmetrical with the write side and move
918      * the majority of this to EngineInputRecord, but there's too much
919      * SSLEngine state to do that cleanly.  It must still live here.
920      */
readRecord(EngineArgs ea)921     private HandshakeStatus readRecord(EngineArgs ea) throws IOException {
922 
923         HandshakeStatus hsStatus = null;
924 
925         /*
926          * The various operations will return new sliced BB's,
927          * this will avoid having to worry about positions and
928          * limits in the netBB.
929          */
930         ByteBuffer readBB = null;
931         ByteBuffer decryptedBB = null;
932 
933         if (getConnectionState() != cs_ERROR) {
934 
935             /*
936              * Read a record ... maybe emitting an alert if we get a
937              * comprehensible but unsupported "hello" message during
938              * format checking (e.g. V2).
939              */
940             try {
941                 readBB = inputRecord.read(ea.netData);
942             } catch (IOException e) {
943                 fatal(Alerts.alert_unexpected_message, e);
944             }
945 
946             /*
947              * The basic SSLv3 record protection involves (optional)
948              * encryption for privacy, and an integrity check ensuring
949              * data origin authentication.  We do them both here, and
950              * throw a fatal alert if the integrity check fails.
951              */
952             try {
953                 decryptedBB = inputRecord.decrypt(readMAC, readCipher, readBB);
954             } catch (BadPaddingException e) {
955                 byte alertType = (inputRecord.contentType() ==
956                     Record.ct_handshake) ?
957                         Alerts.alert_handshake_failure :
958                         Alerts.alert_bad_record_mac;
959                 fatal(alertType, e.getMessage(), e);
960             }
961 
962 
963             // if (!inputRecord.decompress(c))
964             //     fatal(Alerts.alert_decompression_failure,
965             //     "decompression failure");
966 
967 
968             /*
969              * Process the record.
970              */
971 
972             synchronized (this) {
973                 switch (inputRecord.contentType()) {
974                 case Record.ct_handshake:
975                     /*
976                      * Handshake messages always go to a pending session
977                      * handshaker ... if there isn't one, create one.  This
978                      * must work asynchronously, for renegotiation.
979                      *
980                      * NOTE that handshaking will either resume a session
981                      * which was in the cache (and which might have other
982                      * connections in it already), or else will start a new
983                      * session (new keys exchanged) with just this connection
984                      * in it.
985                      */
986                     initHandshaker();
987                     if (!handshaker.activated()) {
988                         // prior to handshaking, activate the handshake
989                         if (connectionState == cs_RENEGOTIATE) {
990                             // don't use SSLv2Hello when renegotiating
991                             handshaker.activate(protocolVersion);
992                         } else {
993                             handshaker.activate(null);
994                         }
995                     }
996 
997                     /*
998                      * process the handshake record ... may contain just
999                      * a partial handshake message or multiple messages.
1000                      *
1001                      * The handshaker state machine will ensure that it's
1002                      * a finished message.
1003                      */
1004                     handshaker.process_record(inputRecord, expectingFinished);
1005                     expectingFinished = false;
1006 
1007                     if (handshaker.invalidated) {
1008                         handshaker = null;
1009                         // if state is cs_RENEGOTIATE, revert it to cs_DATA
1010                         if (connectionState == cs_RENEGOTIATE) {
1011                             connectionState = cs_DATA;
1012                         }
1013                     } else if (handshaker.isDone()) {
1014                         // reset the parameters for secure renegotiation.
1015                         secureRenegotiation =
1016                                         handshaker.isSecureRenegotiation();
1017                         clientVerifyData = handshaker.getClientVerifyData();
1018                         serverVerifyData = handshaker.getServerVerifyData();
1019 
1020                         sess = handshaker.getSession();
1021                         handshakeSession = null;
1022                         if (!writer.hasOutboundData()) {
1023                             hsStatus = HandshakeStatus.FINISHED;
1024                         }
1025                         handshaker = null;
1026                         connectionState = cs_DATA;
1027 
1028                         // No handshakeListeners here.  That's a
1029                         // SSLSocket thing.
1030                     } else if (handshaker.taskOutstanding()) {
1031                         hsStatus = HandshakeStatus.NEED_TASK;
1032                     }
1033                     break;
1034 
1035                 case Record.ct_application_data:
1036                     // Pass this right back up to the application.
1037                     if ((connectionState != cs_DATA)
1038                             && (connectionState != cs_RENEGOTIATE)
1039                             && (connectionState != cs_CLOSED)) {
1040                         throw new SSLProtocolException(
1041                             "Data received in non-data state: " +
1042                             connectionState);
1043                     }
1044 
1045                     if (expectingFinished) {
1046                         throw new SSLProtocolException
1047                                 ("Expecting finished message, received data");
1048                     }
1049 
1050                     /*
1051                      * Don't return data once the inbound side is
1052                      * closed.
1053                      */
1054                     if (!inboundDone) {
1055                         ea.scatter(decryptedBB.slice());
1056                     }
1057                     break;
1058 
1059                 case Record.ct_alert:
1060                     recvAlert();
1061                     break;
1062 
1063                 case Record.ct_change_cipher_spec:
1064                     if ((connectionState != cs_HANDSHAKE
1065                                 && connectionState != cs_RENEGOTIATE)
1066                             || inputRecord.available() != 1
1067                             || inputRecord.read() != 1) {
1068                         fatal(Alerts.alert_unexpected_message,
1069                             "illegal change cipher spec msg, state = "
1070                             + connectionState);
1071                     }
1072 
1073                     //
1074                     // The first message after a change_cipher_spec
1075                     // record MUST be a "Finished" handshake record,
1076                     // else it's a protocol violation.  We force this
1077                     // to be checked by a minor tweak to the state
1078                     // machine.
1079                     //
1080                     changeReadCiphers();
1081                     // next message MUST be a finished message
1082                     expectingFinished = true;
1083                     break;
1084 
1085                 default:
1086                     //
1087                     // TLS requires that unrecognized records be ignored.
1088                     //
1089                     if (debug != null && Debug.isOn("ssl")) {
1090                         System.out.println(threadName() +
1091                             ", Received record type: "
1092                             + inputRecord.contentType());
1093                     }
1094                     break;
1095                 } // switch
1096 
1097                 /*
1098                  * We only need to check the sequence number state for
1099                  * non-handshaking record.
1100                  *
1101                  * Note that in order to maintain the handshake status
1102                  * properly, we check the sequence number after the last
1103                  * record reading process. As we request renegotiation
1104                  * or close the connection for wrapped sequence number
1105                  * when there is enough sequence number space left to
1106                  * handle a few more records, so the sequence number
1107                  * of the last record cannot be wrapped.
1108                  */
1109                 if (connectionState < cs_ERROR && !isInboundDone() &&
1110                         (hsStatus == HandshakeStatus.NOT_HANDSHAKING)) {
1111                     if (checkSequenceNumber(readMAC,
1112                             inputRecord.contentType())) {
1113                         hsStatus = getHSStatus(null);
1114                     }
1115                 }
1116             } // synchronized (this)
1117         }
1118 
1119         return hsStatus;
1120     }
1121 
1122 
1123     //
1124     // write/wrap side
1125     //
1126 
1127 
1128     /**
1129      * Wraps a buffer.  Does a variety of checks before grabbing
1130      * the wrapLock, which blocks multiple wraps from occuring.
1131      */
wrap(ByteBuffer [] appData, int offset, int length, ByteBuffer netData)1132     public SSLEngineResult wrap(ByteBuffer [] appData,
1133             int offset, int length, ByteBuffer netData) throws SSLException {
1134 
1135         EngineArgs ea = new EngineArgs(appData, offset, length, netData);
1136 
1137         /*
1138          * We can be smarter about using smaller buffer sizes later.
1139          * For now, force it to be large enough to handle any
1140          * valid SSL/TLS record.
1141          */
1142         if (netData.remaining() < outputRecord.maxRecordSize) {
1143             return new SSLEngineResult(
1144                 Status.BUFFER_OVERFLOW, getHSStatus(null), 0, 0);
1145         }
1146 
1147         try {
1148             synchronized (wrapLock) {
1149                 return writeAppRecord(ea);
1150             }
1151         } catch (Exception e) {
1152             ea.resetPos();
1153 
1154             fatal(Alerts.alert_internal_error,
1155                 "problem wrapping app data", e);
1156             return null;  // make compiler happy
1157         } finally {
1158             /*
1159              * Just in case something didn't reset limits properly.
1160              */
1161             ea.resetLim();
1162         }
1163     }
1164 
1165     /*
1166      * Makes additional checks for unwrap, but this time more
1167      * specific to this packet and the current state of the machine.
1168      */
writeAppRecord(EngineArgs ea)1169     private SSLEngineResult writeAppRecord(EngineArgs ea) throws IOException {
1170 
1171         Status status = null;
1172         HandshakeStatus hsStatus = null;
1173 
1174         /*
1175          * See if the handshaker needs to report back some SSLException.
1176          */
1177         checkTaskThrown();
1178 
1179         /*
1180          * short circuit if we're closed/closing.
1181          */
1182         if (writer.isOutboundDone()) {
1183             return new SSLEngineResult(Status.CLOSED, getHSStatus(null), 0, 0);
1184         }
1185 
1186         /*
1187          * If we're still in cs_HANDSHAKE, make sure it's been
1188          * started.
1189          */
1190         synchronized (this) {
1191             if ((connectionState == cs_HANDSHAKE) ||
1192                     (connectionState == cs_START)) {
1193                 kickstartHandshake();
1194 
1195                 /*
1196                  * If there's no HS data available to write, we can return
1197                  * without trying to wrap anything.
1198                  */
1199                 hsStatus = getHSStatus(null);
1200 
1201                 if (hsStatus == HandshakeStatus.NEED_UNWRAP) {
1202                     return new SSLEngineResult(Status.OK, hsStatus, 0, 0);
1203                 }
1204             }
1205         }
1206 
1207         /*
1208          * Grab a copy of this if it doesn't already exist,
1209          * and we can use it several places before anything major
1210          * happens on this side.  Races aren't critical
1211          * here.
1212          */
1213         if (hsStatus == null) {
1214             hsStatus = getHSStatus(null);
1215         }
1216 
1217         /*
1218          * If we have a task outstanding, this *MUST* be done before
1219          * doing any more wrapping, because we could be in the middle
1220          * of receiving a handshake message, for example, a finished
1221          * message which would change the ciphers.
1222          */
1223         if (hsStatus == HandshakeStatus.NEED_TASK) {
1224             return new SSLEngineResult(
1225                 Status.OK, hsStatus, 0, 0);
1226         }
1227 
1228         /*
1229          * This will obtain any waiting outbound data, or will
1230          * process the outbound appData.
1231          */
1232         try {
1233             synchronized (writeLock) {
1234                 hsStatus = writeRecord(outputRecord, ea);
1235             }
1236         } catch (SSLException e) {
1237             throw e;
1238         } catch (IOException e) {
1239             SSLException ex = new SSLException("Write problems");
1240             ex.initCause(e);
1241             throw ex;
1242         }
1243 
1244         /*
1245          * writeRecord might have reported some status.
1246          * Now check for the remaining cases.
1247          *
1248          * status above should cover:  NEED_WRAP/FINISHED
1249          */
1250         status = (isOutboundDone() ? Status.CLOSED : Status.OK);
1251         hsStatus = getHSStatus(hsStatus);
1252 
1253         return new SSLEngineResult(status, hsStatus,
1254             ea.deltaApp(), ea.deltaNet());
1255     }
1256 
1257     /*
1258      * Central point to write/get all of the outgoing data.
1259      */
writeRecord(EngineOutputRecord eor, EngineArgs ea)1260     private HandshakeStatus writeRecord(EngineOutputRecord eor,
1261             EngineArgs ea) throws IOException {
1262 
1263         // eventually compress as well.
1264         HandshakeStatus hsStatus =
1265                 writer.writeRecord(eor, ea, writeMAC, writeCipher);
1266 
1267         /*
1268          * We only need to check the sequence number state for
1269          * non-handshaking record.
1270          *
1271          * Note that in order to maintain the handshake status
1272          * properly, we check the sequence number after the last
1273          * record writing process. As we request renegotiation
1274          * or close the connection for wrapped sequence number
1275          * when there is enough sequence number space left to
1276          * handle a few more records, so the sequence number
1277          * of the last record cannot be wrapped.
1278          */
1279         if (connectionState < cs_ERROR && !isOutboundDone() &&
1280                 (hsStatus == HandshakeStatus.NOT_HANDSHAKING)) {
1281             if (checkSequenceNumber(writeMAC, eor.contentType())) {
1282                 hsStatus = getHSStatus(null);
1283             }
1284         }
1285 
1286         /*
1287          * turn off the flag of the first application record if we really
1288          * consumed at least byte.
1289          */
1290         if (isFirstAppOutputRecord && ea.deltaApp() > 0) {
1291             isFirstAppOutputRecord = false;
1292         }
1293 
1294         return hsStatus;
1295     }
1296 
1297     /*
1298      * Need to split the payload except the following cases:
1299      *
1300      * 1. protocol version is TLS 1.1 or later;
1301      * 2. bulk cipher does not use CBC mode, including null bulk cipher suites.
1302      * 3. the payload is the first application record of a freshly
1303      *    negotiated TLS session.
1304      * 4. the CBC protection is disabled;
1305      *
1306      * More details, please refer to
1307      * EngineOutputRecord.write(EngineArgs, MAC, CipherBox).
1308      */
needToSplitPayload(CipherBox cipher, ProtocolVersion protocol)1309     boolean needToSplitPayload(CipherBox cipher, ProtocolVersion protocol) {
1310         return (protocol.v <= ProtocolVersion.TLS10.v) &&
1311                 cipher.isCBCMode() && !isFirstAppOutputRecord &&
1312                 Record.enableCBCProtection;
1313     }
1314 
1315     /*
1316      * Non-application OutputRecords go through here.
1317      */
writeRecord(EngineOutputRecord eor)1318     void writeRecord(EngineOutputRecord eor) throws IOException {
1319         // eventually compress as well.
1320         writer.writeRecord(eor, writeMAC, writeCipher);
1321 
1322         /*
1323          * Check the sequence number state
1324          *
1325          * Note that in order to maintain the connection I/O
1326          * properly, we check the sequence number after the last
1327          * record writing process. As we request renegotiation
1328          * or close the connection for wrapped sequence number
1329          * when there is enough sequence number space left to
1330          * handle a few more records, so the sequence number
1331          * of the last record cannot be wrapped.
1332          */
1333         if ((connectionState < cs_ERROR) && !isOutboundDone()) {
1334             checkSequenceNumber(writeMAC, eor.contentType());
1335         }
1336     }
1337 
1338     //
1339     // Close code
1340     //
1341 
1342     /**
1343      * Check the sequence number state
1344      *
1345      * RFC 4346 states that, "Sequence numbers are of type uint64 and
1346      * may not exceed 2^64-1.  Sequence numbers do not wrap. If a TLS
1347      * implementation would need to wrap a sequence number, it must
1348      * renegotiate instead."
1349      *
1350      * Return true if the handshake status may be changed.
1351      */
checkSequenceNumber(MAC mac, byte type)1352     private boolean checkSequenceNumber(MAC mac, byte type)
1353             throws IOException {
1354 
1355         /*
1356          * Don't bother to check the sequence number for error or
1357          * closed connections, or NULL MAC
1358          */
1359         if (connectionState >= cs_ERROR || mac == MAC.NULL) {
1360             return false;
1361         }
1362 
1363         /*
1364          * Conservatively, close the connection immediately when the
1365          * sequence number is close to overflow
1366          */
1367         if (mac.seqNumOverflow()) {
1368             /*
1369              * TLS protocols do not define a error alert for sequence
1370              * number overflow. We use handshake_failure error alert
1371              * for handshaking and bad_record_mac for other records.
1372              */
1373             if (debug != null && Debug.isOn("ssl")) {
1374                 System.out.println(threadName() +
1375                     ", sequence number extremely close to overflow " +
1376                     "(2^64-1 packets). Closing connection.");
1377             }
1378 
1379             fatal(Alerts.alert_handshake_failure, "sequence number overflow");
1380 
1381             return true; // make the compiler happy
1382         }
1383 
1384         /*
1385          * Ask for renegotiation when need to renew sequence number.
1386          *
1387          * Don't bother to kickstart the renegotiation when the local is
1388          * asking for it.
1389          */
1390         if ((type != Record.ct_handshake) && mac.seqNumIsHuge()) {
1391             if (debug != null && Debug.isOn("ssl")) {
1392                 System.out.println(threadName() + ", request renegotiation " +
1393                         "to avoid sequence number overflow");
1394             }
1395 
1396             beginHandshake();
1397             return true;
1398         }
1399 
1400         return false;
1401     }
1402 
1403     /**
1404      * Signals that no more outbound application data will be sent
1405      * on this <code>SSLEngine</code>.
1406      */
closeOutboundInternal()1407     private void closeOutboundInternal() {
1408 
1409         if ((debug != null) && Debug.isOn("ssl")) {
1410             System.out.println(threadName() + ", closeOutboundInternal()");
1411         }
1412 
1413         /*
1414          * Already closed, ignore
1415          */
1416         if (writer.isOutboundDone()) {
1417             return;
1418         }
1419 
1420         switch (connectionState) {
1421 
1422         /*
1423          * If we haven't even started yet, don't bother reading inbound.
1424          */
1425         case cs_START:
1426             writer.closeOutbound();
1427             inboundDone = true;
1428             break;
1429 
1430         case cs_ERROR:
1431         case cs_CLOSED:
1432             break;
1433 
1434         /*
1435          * Otherwise we indicate clean termination.
1436          */
1437         // case cs_HANDSHAKE:
1438         // case cs_DATA:
1439         // case cs_RENEGOTIATE:
1440         default:
1441             warning(Alerts.alert_close_notify);
1442             writer.closeOutbound();
1443             break;
1444         }
1445 
1446         // See comment in changeReadCiphers()
1447         writeCipher.dispose();
1448 
1449         connectionState = cs_CLOSED;
1450     }
1451 
closeOutbound()1452     synchronized public void closeOutbound() {
1453         /*
1454          * Dump out a close_notify to the remote side
1455          */
1456         if ((debug != null) && Debug.isOn("ssl")) {
1457             System.out.println(threadName() + ", called closeOutbound()");
1458         }
1459 
1460         closeOutboundInternal();
1461     }
1462 
1463     /**
1464      * Returns the outbound application data closure state
1465      */
isOutboundDone()1466     public boolean isOutboundDone() {
1467         return writer.isOutboundDone();
1468     }
1469 
1470     /**
1471      * Signals that no more inbound network data will be sent
1472      * to this <code>SSLEngine</code>.
1473      */
closeInboundInternal()1474     private void closeInboundInternal() {
1475 
1476         if ((debug != null) && Debug.isOn("ssl")) {
1477             System.out.println(threadName() + ", closeInboundInternal()");
1478         }
1479 
1480         /*
1481          * Already closed, ignore
1482          */
1483         if (inboundDone) {
1484             return;
1485         }
1486 
1487         closeOutboundInternal();
1488         inboundDone = true;
1489 
1490         // See comment in changeReadCiphers()
1491         readCipher.dispose();
1492 
1493         connectionState = cs_CLOSED;
1494     }
1495 
1496     /*
1497      * Close the inbound side of the connection.  We grab the
1498      * lock here, and do the real work in the internal verison.
1499      * We do check for truncation attacks.
1500      */
closeInbound()1501     synchronized public void closeInbound() throws SSLException {
1502         /*
1503          * Currently closes the outbound side as well.  The IETF TLS
1504          * working group has expressed the opinion that 1/2 open
1505          * connections are not allowed by the spec.  May change
1506          * someday in the future.
1507          */
1508         if ((debug != null) && Debug.isOn("ssl")) {
1509             System.out.println(threadName() + ", called closeInbound()");
1510         }
1511 
1512         /*
1513          * No need to throw an Exception if we haven't even started yet.
1514          */
1515         if ((connectionState != cs_START) && !recvCN) {
1516             recvCN = true;  // Only receive the Exception once
1517             fatal(Alerts.alert_internal_error,
1518                 "Inbound closed before receiving peer's close_notify: " +
1519                 "possible truncation attack?");
1520         } else {
1521             /*
1522              * Currently, this is a no-op, but in case we change
1523              * the close inbound code later.
1524              */
1525             closeInboundInternal();
1526         }
1527     }
1528 
1529     /**
1530      * Returns the network inbound data closure state
1531      */
isInboundDone()1532     synchronized public boolean isInboundDone() {
1533         return inboundDone;
1534     }
1535 
1536 
1537     //
1538     // Misc stuff
1539     //
1540 
1541 
1542     /**
1543      * Returns the current <code>SSLSession</code> for this
1544      * <code>SSLEngine</code>
1545      * <P>
1546      * These can be long lived, and frequently correspond to an
1547      * entire login session for some user.
1548      */
getSession()1549     synchronized public SSLSession getSession() {
1550         return sess;
1551     }
1552 
1553     @Override
getHandshakeSession()1554     synchronized public SSLSession getHandshakeSession() {
1555         return handshakeSession;
1556     }
1557 
setHandshakeSession(SSLSessionImpl session)1558     synchronized void setHandshakeSession(SSLSessionImpl session) {
1559         handshakeSession = session;
1560     }
1561 
1562     /**
1563      * Returns a delegated <code>Runnable</code> task for
1564      * this <code>SSLEngine</code>.
1565      */
getDelegatedTask()1566     synchronized public Runnable getDelegatedTask() {
1567         if (handshaker != null) {
1568             return handshaker.getTask();
1569         }
1570         return null;
1571     }
1572 
1573 
1574     //
1575     // EXCEPTION AND ALERT HANDLING
1576     //
1577 
1578     /*
1579      * Send a warning alert.
1580      */
warning(byte description)1581     void warning(byte description) {
1582         sendAlert(Alerts.alert_warning, description);
1583     }
1584 
fatal(byte description, String diagnostic)1585     synchronized void fatal(byte description, String diagnostic)
1586             throws SSLException {
1587         fatal(description, diagnostic, null);
1588     }
1589 
fatal(byte description, Throwable cause)1590     synchronized void fatal(byte description, Throwable cause)
1591             throws SSLException {
1592         fatal(description, null, cause);
1593     }
1594 
1595     /*
1596      * We've got a fatal error here, so start the shutdown process.
1597      *
1598      * Because of the way the code was written, we have some code
1599      * calling fatal directly when the "description" is known
1600      * and some throwing Exceptions which are then caught by higher
1601      * levels which then call here.  This code needs to determine
1602      * if one of the lower levels has already started the process.
1603      *
1604      * We won't worry about Error's, if we have one of those,
1605      * we're in worse trouble.  Note:  the networking code doesn't
1606      * deal with Errors either.
1607      */
fatal(byte description, String diagnostic, Throwable cause)1608     synchronized void fatal(byte description, String diagnostic,
1609             Throwable cause) throws SSLException {
1610 
1611         /*
1612          * If we have no further information, make a general-purpose
1613          * message for folks to see.  We generally have one or the other.
1614          */
1615         if (diagnostic == null) {
1616             diagnostic = "General SSLEngine problem";
1617         }
1618         if (cause == null) {
1619             cause = Alerts.getSSLException(description, cause, diagnostic);
1620         }
1621 
1622         /*
1623          * If we've already shutdown because of an error,
1624          * there is nothing we can do except rethrow the exception.
1625          *
1626          * Most exceptions seen here will be SSLExceptions.
1627          * We may find the occasional Exception which hasn't been
1628          * converted to a SSLException, so we'll do it here.
1629          */
1630         if (closeReason != null) {
1631             if ((debug != null) && Debug.isOn("ssl")) {
1632                 System.out.println(threadName() +
1633                     ", fatal: engine already closed.  Rethrowing " +
1634                     cause.toString());
1635             }
1636             if (cause instanceof RuntimeException) {
1637                 throw (RuntimeException)cause;
1638             } else if (cause instanceof SSLException) {
1639                 throw (SSLException)cause;
1640             } else if (cause instanceof Exception) {
1641                 SSLException ssle = new SSLException(
1642                     "fatal SSLEngine condition");
1643                 ssle.initCause(cause);
1644                 throw ssle;
1645             }
1646         }
1647 
1648         if ((debug != null) && Debug.isOn("ssl")) {
1649             System.out.println(threadName()
1650                         + ", fatal error: " + description +
1651                         ": " + diagnostic + "\n" + cause.toString());
1652         }
1653 
1654         /*
1655          * Ok, this engine's going down.
1656          */
1657         int oldState = connectionState;
1658         connectionState = cs_ERROR;
1659 
1660         inboundDone = true;
1661 
1662         sess.invalidate();
1663         if (handshakeSession != null) {
1664             handshakeSession.invalidate();
1665         }
1666 
1667         /*
1668          * If we haven't even started handshaking yet, no need
1669          * to generate the fatal close alert.
1670          */
1671         if (oldState != cs_START) {
1672             sendAlert(Alerts.alert_fatal, description);
1673         }
1674 
1675         if (cause instanceof SSLException) { // only true if != null
1676             closeReason = (SSLException)cause;
1677         } else {
1678             /*
1679              * Including RuntimeExceptions, but we'll throw those
1680              * down below.  The closeReason isn't used again,
1681              * except for null checks.
1682              */
1683             closeReason =
1684                 Alerts.getSSLException(description, cause, diagnostic);
1685         }
1686 
1687         writer.closeOutbound();
1688 
1689         connectionState = cs_CLOSED;
1690 
1691         // See comment in changeReadCiphers()
1692         readCipher.dispose();
1693         writeCipher.dispose();
1694 
1695         if (cause instanceof RuntimeException) {
1696             throw (RuntimeException)cause;
1697         } else {
1698             throw closeReason;
1699         }
1700     }
1701 
1702     /*
1703      * Process an incoming alert ... caller must already have synchronized
1704      * access to "this".
1705      */
recvAlert()1706     private void recvAlert() throws IOException {
1707         byte level = (byte)inputRecord.read();
1708         byte description = (byte)inputRecord.read();
1709         if (description == -1) { // check for short message
1710             fatal(Alerts.alert_illegal_parameter, "Short alert message");
1711         }
1712 
1713         if (debug != null && (Debug.isOn("record") ||
1714                 Debug.isOn("handshake"))) {
1715             synchronized (System.out) {
1716                 System.out.print(threadName());
1717                 System.out.print(", RECV " + protocolVersion + " ALERT:  ");
1718                 if (level == Alerts.alert_fatal) {
1719                     System.out.print("fatal, ");
1720                 } else if (level == Alerts.alert_warning) {
1721                     System.out.print("warning, ");
1722                 } else {
1723                     System.out.print("<level " + (0x0ff & level) + ">, ");
1724                 }
1725                 System.out.println(Alerts.alertDescription(description));
1726             }
1727         }
1728 
1729         if (level == Alerts.alert_warning) {
1730             if (description == Alerts.alert_close_notify) {
1731                 if (connectionState == cs_HANDSHAKE) {
1732                     fatal(Alerts.alert_unexpected_message,
1733                                 "Received close_notify during handshake");
1734                 } else {
1735                     recvCN = true;
1736                     closeInboundInternal();  // reply to close
1737                 }
1738             } else {
1739 
1740                 //
1741                 // The other legal warnings relate to certificates,
1742                 // e.g. no_certificate, bad_certificate, etc; these
1743                 // are important to the handshaking code, which can
1744                 // also handle illegal protocol alerts if needed.
1745                 //
1746                 if (handshaker != null) {
1747                     handshaker.handshakeAlert(description);
1748                 }
1749             }
1750         } else { // fatal or unknown level
1751             String reason = "Received fatal alert: "
1752                 + Alerts.alertDescription(description);
1753             if (closeReason == null) {
1754                 closeReason = Alerts.getSSLException(description, reason);
1755             }
1756             fatal(Alerts.alert_unexpected_message, reason);
1757         }
1758     }
1759 
1760 
1761     /*
1762      * Emit alerts.  Caller must have synchronized with "this".
1763      */
sendAlert(byte level, byte description)1764     private void sendAlert(byte level, byte description) {
1765         // the connectionState cannot be cs_START
1766         if (connectionState >= cs_CLOSED) {
1767             return;
1768         }
1769 
1770         // For initial handshaking, don't send alert message to peer if
1771         // handshaker has not started.
1772         if (connectionState == cs_HANDSHAKE &&
1773             (handshaker == null || !handshaker.started())) {
1774             return;
1775         }
1776 
1777         EngineOutputRecord r = new EngineOutputRecord(Record.ct_alert, this);
1778         r.setVersion(protocolVersion);
1779 
1780         boolean useDebug = debug != null && Debug.isOn("ssl");
1781         if (useDebug) {
1782             synchronized (System.out) {
1783                 System.out.print(threadName());
1784                 System.out.print(", SEND " + protocolVersion + " ALERT:  ");
1785                 if (level == Alerts.alert_fatal) {
1786                     System.out.print("fatal, ");
1787                 } else if (level == Alerts.alert_warning) {
1788                     System.out.print("warning, ");
1789                 } else {
1790                     System.out.print("<level = " + (0x0ff & level) + ">, ");
1791                 }
1792                 System.out.println("description = "
1793                         + Alerts.alertDescription(description));
1794             }
1795         }
1796 
1797         r.write(level);
1798         r.write(description);
1799         try {
1800             writeRecord(r);
1801         } catch (IOException e) {
1802             if (useDebug) {
1803                 System.out.println(threadName() +
1804                     ", Exception sending alert: " + e);
1805             }
1806         }
1807     }
1808 
1809 
1810     //
1811     // VARIOUS OTHER METHODS (COMMON TO SSLSocket)
1812     //
1813 
1814 
1815     /**
1816      * Controls whether new connections may cause creation of new SSL
1817      * sessions.
1818      *
1819      * As long as handshaking has not started, we can change
1820      * whether we enable session creations.  Otherwise,
1821      * we will need to wait for the next handshake.
1822      */
setEnableSessionCreation(boolean flag)1823     synchronized public void setEnableSessionCreation(boolean flag) {
1824         enableSessionCreation = flag;
1825 
1826         if ((handshaker != null) && !handshaker.activated()) {
1827             handshaker.setEnableSessionCreation(enableSessionCreation);
1828         }
1829     }
1830 
1831     /**
1832      * Returns true if new connections may cause creation of new SSL
1833      * sessions.
1834      */
getEnableSessionCreation()1835     synchronized public boolean getEnableSessionCreation() {
1836         return enableSessionCreation;
1837     }
1838 
1839 
1840     /**
1841      * Sets the flag controlling whether a server mode engine
1842      * *REQUIRES* SSL client authentication.
1843      *
1844      * As long as handshaking has not started, we can change
1845      * whether client authentication is needed.  Otherwise,
1846      * we will need to wait for the next handshake.
1847      */
setNeedClientAuth(boolean flag)1848     synchronized public void setNeedClientAuth(boolean flag) {
1849         doClientAuth = (flag ?
1850             SSLEngineImpl.clauth_required : SSLEngineImpl.clauth_none);
1851 
1852         if ((handshaker != null) &&
1853                 (handshaker instanceof ServerHandshaker) &&
1854                 !handshaker.activated()) {
1855             ((ServerHandshaker) handshaker).setClientAuth(doClientAuth);
1856         }
1857     }
1858 
getNeedClientAuth()1859     synchronized public boolean getNeedClientAuth() {
1860         return (doClientAuth == SSLEngineImpl.clauth_required);
1861     }
1862 
1863     /**
1864      * Sets the flag controlling whether a server mode engine
1865      * *REQUESTS* SSL client authentication.
1866      *
1867      * As long as handshaking has not started, we can change
1868      * whether client authentication is requested.  Otherwise,
1869      * we will need to wait for the next handshake.
1870      */
setWantClientAuth(boolean flag)1871     synchronized public void setWantClientAuth(boolean flag) {
1872         doClientAuth = (flag ?
1873             SSLEngineImpl.clauth_requested : SSLEngineImpl.clauth_none);
1874 
1875         if ((handshaker != null) &&
1876                 (handshaker instanceof ServerHandshaker) &&
1877                 !handshaker.activated()) {
1878             ((ServerHandshaker) handshaker).setClientAuth(doClientAuth);
1879         }
1880     }
1881 
getWantClientAuth()1882     synchronized public boolean getWantClientAuth() {
1883         return (doClientAuth == SSLEngineImpl.clauth_requested);
1884     }
1885 
1886 
1887     /**
1888      * Sets the flag controlling whether the engine is in SSL
1889      * client or server mode.  Must be called before any SSL
1890      * traffic has started.
1891      */
setUseClientMode(boolean flag)1892     synchronized public void setUseClientMode(boolean flag) {
1893         switch (connectionState) {
1894 
1895         case cs_START:
1896             /*
1897              * If we need to change the engine mode and the enabled
1898              * protocols haven't specifically been set by the user,
1899              * change them to the corresponding default ones.
1900              */
1901             if (roleIsServer != (!flag) &&
1902                     sslContext.isDefaultProtocolList(enabledProtocols)) {
1903                 enabledProtocols = sslContext.getDefaultProtocolList(!flag);
1904             }
1905 
1906             roleIsServer = !flag;
1907             serverModeSet = true;
1908             break;
1909 
1910         case cs_HANDSHAKE:
1911             /*
1912              * If we have a handshaker, but haven't started
1913              * SSL traffic, we can throw away our current
1914              * handshaker, and start from scratch.  Don't
1915              * need to call doneConnect() again, we already
1916              * have the streams.
1917              */
1918             assert(handshaker != null);
1919             if (!handshaker.activated()) {
1920                 /*
1921                  * If we need to change the engine mode and the enabled
1922                  * protocols haven't specifically been set by the user,
1923                  * change them to the corresponding default ones.
1924                  */
1925                 if (roleIsServer != (!flag) &&
1926                         sslContext.isDefaultProtocolList(enabledProtocols)) {
1927                     enabledProtocols = sslContext.getDefaultProtocolList(!flag);
1928                 }
1929 
1930                 roleIsServer = !flag;
1931                 connectionState = cs_START;
1932                 initHandshaker();
1933                 break;
1934             }
1935 
1936             // If handshake has started, that's an error.  Fall through...
1937 
1938         default:
1939             if (debug != null && Debug.isOn("ssl")) {
1940                 System.out.println(threadName() +
1941                     ", setUseClientMode() invoked in state = " +
1942                     connectionState);
1943             }
1944 
1945             /*
1946              * We can let them continue if they catch this correctly,
1947              * we don't need to shut this down.
1948              */
1949             throw new IllegalArgumentException(
1950                 "Cannot change mode after SSL traffic has started");
1951         }
1952     }
1953 
getUseClientMode()1954     synchronized public boolean getUseClientMode() {
1955         return !roleIsServer;
1956     }
1957 
1958 
1959     /**
1960      * Returns the names of the cipher suites which could be enabled for use
1961      * on an SSL connection.  Normally, only a subset of these will actually
1962      * be enabled by default, since this list may include cipher suites which
1963      * do not support the mutual authentication of servers and clients, or
1964      * which do not protect data confidentiality.  Servers may also need
1965      * certain kinds of certificates to use certain cipher suites.
1966      *
1967      * @return an array of cipher suite names
1968      */
getSupportedCipherSuites()1969     public String[] getSupportedCipherSuites() {
1970         return sslContext.getSupportedCipherSuiteList().toStringArray();
1971     }
1972 
1973     /**
1974      * Controls which particular cipher suites are enabled for use on
1975      * this connection.  The cipher suites must have been listed by
1976      * getCipherSuites() as being supported.  Even if a suite has been
1977      * enabled, it might never be used if no peer supports it or the
1978      * requisite certificates (and private keys) are not available.
1979      *
1980      * @param suites Names of all the cipher suites to enable.
1981      */
setEnabledCipherSuites(String[] suites)1982     synchronized public void setEnabledCipherSuites(String[] suites) {
1983         enabledCipherSuites = new CipherSuiteList(suites);
1984         if ((handshaker != null) && !handshaker.activated()) {
1985             handshaker.setEnabledCipherSuites(enabledCipherSuites);
1986         }
1987     }
1988 
1989     /**
1990      * Returns the names of the SSL cipher suites which are currently enabled
1991      * for use on this connection.  When an SSL engine is first created,
1992      * all enabled cipher suites <em>(a)</em> protect data confidentiality,
1993      * by traffic encryption, and <em>(b)</em> can mutually authenticate
1994      * both clients and servers.  Thus, in some environments, this value
1995      * might be empty.
1996      *
1997      * @return an array of cipher suite names
1998      */
getEnabledCipherSuites()1999     synchronized public String[] getEnabledCipherSuites() {
2000         return enabledCipherSuites.toStringArray();
2001     }
2002 
2003 
2004     /**
2005      * Returns the protocols that are supported by this implementation.
2006      * A subset of the supported protocols may be enabled for this connection
2007      * @return an array of protocol names.
2008      */
getSupportedProtocols()2009     public String[] getSupportedProtocols() {
2010         return sslContext.getSuportedProtocolList().toStringArray();
2011     }
2012 
2013     /**
2014      * Controls which protocols are enabled for use on
2015      * this connection.  The protocols must have been listed by
2016      * getSupportedProtocols() as being supported.
2017      *
2018      * @param protocols protocols to enable.
2019      * @exception IllegalArgumentException when one of the protocols
2020      *  named by the parameter is not supported.
2021      */
setEnabledProtocols(String[] protocols)2022     synchronized public void setEnabledProtocols(String[] protocols) {
2023         enabledProtocols = new ProtocolList(protocols);
2024         if ((handshaker != null) && !handshaker.activated()) {
2025             handshaker.setEnabledProtocols(enabledProtocols);
2026         }
2027     }
2028 
getEnabledProtocols()2029     synchronized public String[] getEnabledProtocols() {
2030         return enabledProtocols.toStringArray();
2031     }
2032 
2033     /**
2034      * Returns the SSLParameters in effect for this SSLEngine.
2035      */
getSSLParameters()2036     synchronized public SSLParameters getSSLParameters() {
2037         SSLParameters params = super.getSSLParameters();
2038 
2039         // the super implementation does not handle the following parameters
2040         params.setEndpointIdentificationAlgorithm(identificationProtocol);
2041         params.setAlgorithmConstraints(algorithmConstraints);
2042 
2043         return params;
2044     }
2045 
2046     /**
2047      * Applies SSLParameters to this engine.
2048      */
setSSLParameters(SSLParameters params)2049     synchronized public void setSSLParameters(SSLParameters params) {
2050         super.setSSLParameters(params);
2051 
2052         // the super implementation does not handle the following parameters
2053         identificationProtocol = params.getEndpointIdentificationAlgorithm();
2054         algorithmConstraints = params.getAlgorithmConstraints();
2055         if ((handshaker != null) && !handshaker.started()) {
2056             handshaker.setIdentificationProtocol(identificationProtocol);
2057             handshaker.setAlgorithmConstraints(algorithmConstraints);
2058         }
2059     }
2060 
2061     /**
2062      * Return the name of the current thread. Utility method.
2063      */
threadName()2064     private static String threadName() {
2065         return Thread.currentThread().getName();
2066     }
2067 
2068     /**
2069      * Returns a printable representation of this end of the connection.
2070      */
toString()2071     public String toString() {
2072         StringBuilder retval = new StringBuilder(80);
2073 
2074         retval.append(Integer.toHexString(hashCode()));
2075         retval.append("[");
2076         retval.append("SSLEngine[hostname=");
2077         String host = getPeerHost();
2078         retval.append((host == null) ? "null" : host);
2079         retval.append(" port=");
2080         retval.append(Integer.toString(getPeerPort()));
2081         retval.append("] ");
2082         retval.append(getSession().getCipherSuite());
2083         retval.append("]");
2084 
2085         return retval.toString();
2086     }
2087 }
2088