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/SSLEngineImpl.java (1 of 18352 files). Show all

Unified · Split

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