2493 lines · 91.5 KB · Java
RawDownload
        }         /*         * Dispose of any intermediate state in the underlying cipher.         * For PKCS11 ciphers, this will release any attached sessions,         * and thus make finalization faster.         *         * Since MAC's doFinal() is called for every SSL/TLS packet, it's         * not necessary to do the same with MAC's.         */        oldCipher.dispose();    }     // used by Handshaker    void changeWriteCiphers() throws SSLException {        if (connectionState != cs_HANDSHAKE                && connectionState != cs_RENEGOTIATE) {            throw new SSLProtocolException(                "State error, change cipher specs");        }         // ... create compressor         CipherBox oldCipher = writeCipher;         try {            writeCipher = handshaker.newWriteCipher();            writeMAC = handshaker.newWriteMAC();        } catch (GeneralSecurityException e) {            // "can't happen"            throw (SSLException)new SSLException                                ("Algorithm missing:  ").initCause(e);        }         // See comment above.        oldCipher.dispose();    }     /*     * Updates the SSL version associated with this connection.     * Called from Handshaker once it has determined the negotiated version.     */    synchronized void setVersion(ProtocolVersion protocolVersion) {        this.protocolVersion = protocolVersion;        output.r.setVersion(protocolVersion);    }     synchronized String getHost() {        // Note that the host may be null or empty for localhost.        if (host == null || host.length() == 0) {            host = getInetAddress().getHostName();        }        return host;    }     synchronized String getRawHostname() {        return rawHostname;    }     // ONLY used by HttpsClient to setup the URI specified hostname    synchronized public void setHost(String host) {        this.host = host;        this.rawHostname = host;    }     /**     * Gets an input stream to read from the peer on the other side.     * Data read from this stream was always integrity protected in     * transit, and will usually have been confidentiality protected.     */    synchronized public InputStream getInputStream() throws IOException {        if (isClosed()) {            throw new SocketException("Socket is closed");        }         /*         * Can't call isConnected() here, because the Handshakers         * do some initialization before we actually connect.         */        if (connectionState == cs_START) {            throw new SocketException("Socket is not connected");        }         return input;    }     /**     * Gets an output stream to write to the peer on the other side.     * Data written on this stream is always integrity protected, and     * will usually be confidentiality protected.     */    synchronized public OutputStream getOutputStream() throws IOException {        if (isClosed()) {            throw new SocketException("Socket is closed");        }         /*         * Can't call isConnected() here, because the Handshakers         * do some initialization before we actually connect.         */        if (connectionState == cs_START) {            throw new SocketException("Socket is not connected");        }         return output;    }     /**     * Returns the the SSL Session in use by this connection.  These can     * be long lived, and frequently correspond to an entire login session     * for some user.     */    public SSLSession getSession() {        /*         * Force a synchronous handshake, if appropriate.         */        if (getConnectionState() == cs_HANDSHAKE) {            try {                // start handshaking, if failed, the connection will be closed.                startHandshake(false);            } catch (IOException e) {                // handshake failed. log and return a nullSession                if (debug != null && Debug.isOn("handshake")) {                      System.out.println(threadName() +                          ", IOException in getSession():  " + e);                }            }        }        synchronized (this) {            return sess;        }    }     @Override    synchronized public SSLSession getHandshakeSession() {        return handshakeSession;    }     synchronized void setHandshakeSession(SSLSessionImpl session) {        handshakeSession = session;    }     /**     * Controls whether new connections may cause creation of new SSL     * sessions.     *     * As long as handshaking has not started, we can change     * whether we enable session creations.  Otherwise,     * we will need to wait for the next handshake.     */    synchronized public void setEnableSessionCreation(boolean flag) {        enableSessionCreation = flag;         if ((handshaker != null) && !handshaker.activated()) {            handshaker.setEnableSessionCreation(enableSessionCreation);        }    }     /**     * Returns true if new connections may cause creation of new SSL     * sessions.     */    synchronized public boolean getEnableSessionCreation() {        return enableSessionCreation;    }      /**     * Sets the flag controlling whether a server mode socket     * *REQUIRES* SSL client authentication.     *     * As long as handshaking has not started, we can change     * whether client authentication is needed.  Otherwise,     * we will need to wait for the next handshake.     */    synchronized public void setNeedClientAuth(boolean flag) {        doClientAuth = (flag ?            SSLEngineImpl.clauth_required : SSLEngineImpl.clauth_none);         if ((handshaker != null) &&                (handshaker instanceof ServerHandshaker) &&                !handshaker.activated()) {            ((ServerHandshaker) handshaker).setClientAuth(doClientAuth);        }    }     synchronized public boolean getNeedClientAuth() {        return (doClientAuth == SSLEngineImpl.clauth_required);    }     /**     * Sets the flag controlling whether a server mode socket     * *REQUESTS* SSL client authentication.     *     * As long as handshaking has not started, we can change     * whether client authentication is requested.  Otherwise,     * we will need to wait for the next handshake.     */    synchronized public void setWantClientAuth(boolean flag) {        doClientAuth = (flag ?            SSLEngineImpl.clauth_requested : SSLEngineImpl.clauth_none);         if ((handshaker != null) &&                (handshaker instanceof ServerHandshaker) &&                !handshaker.activated()) {            ((ServerHandshaker) handshaker).setClientAuth(doClientAuth);        }    }     synchronized public boolean getWantClientAuth() {        return (doClientAuth == SSLEngineImpl.clauth_requested);    }      /**     * Sets the flag controlling whether the socket is in SSL     * client or server mode.  Must be called before any SSL     * traffic has started.     */    synchronized public void setUseClientMode(boolean flag) {        switch (connectionState) {         case cs_START:            /*             * If we need to change the socket mode and the enabled             * protocols haven't specifically been set by the user,             * change them to the corresponding default ones.             */            if (roleIsServer != (!flag) &&                    sslContext.isDefaultProtocolList(enabledProtocols)) {                enabledProtocols = sslContext.getDefaultProtocolList(!flag);            }            roleIsServer = !flag;            break;         case cs_HANDSHAKE:            /*             * If we have a handshaker, but haven't started             * SSL traffic, we can throw away our current             * handshaker, and start from scratch.  Don't             * need to call doneConnect() again, we already             * have the streams.             */            assert(handshaker != null);            if (!handshaker.activated()) {                /*                 * If we need to change the socket mode and the enabled                 * protocols haven't specifically been set by the user,                 * change them to the corresponding default ones.                 */                if (roleIsServer != (!flag) &&                        sslContext.isDefaultProtocolList(enabledProtocols)) {                    enabledProtocols = sslContext.getDefaultProtocolList(!flag);                }                roleIsServer = !flag;                connectionState = cs_START;                initHandshaker();                break;            }             // If handshake has started, that's an error.  Fall through...         default:            if (debug != null && Debug.isOn("ssl")) {                System.out.println(threadName() +                    ", setUseClientMode() invoked in state = " +                    connectionState);            }            throw new IllegalArgumentException(                "Cannot change mode after SSL traffic has started");        }    }     synchronized public boolean getUseClientMode() {        return !roleIsServer;    }      /**     * Returns the names of the cipher suites which could be enabled for use     * on an SSL connection.  Normally, only a subset of these will actually     * be enabled by default, since this list may include cipher suites which     * do not support the mutual authentication of servers and clients, or     * which do not protect data confidentiality.  Servers may also need     * certain kinds of certificates to use certain cipher suites.     *     * @return an array of cipher suite names     */    public String[] getSupportedCipherSuites() {        return sslContext.getSuportedCipherSuiteList().toStringArray();    }     /**     * Controls which particular cipher suites are enabled for use on     * this connection.  The cipher suites must have been listed by     * getCipherSuites() as being supported.  Even if a suite has been     * enabled, it might never be used if no peer supports it or the     * requisite certificates (and private keys) are not available.     *     * @param suites Names of all the cipher suites to enable.     */    synchronized public void setEnabledCipherSuites(String[] suites) {        enabledCipherSuites = new CipherSuiteList(suites);        if ((handshaker != null) && !handshaker.activated()) {            handshaker.setEnabledCipherSuites(enabledCipherSuites);        }    }     /**     * Returns the names of the SSL cipher suites which are currently enabled     * for use on this connection.  When an SSL socket is first created,     * all enabled cipher suites <em>(a)</em> protect data confidentiality,     * by traffic encryption, and <em>(b)</em> can mutually authenticate     * both clients and servers.  Thus, in some environments, this value     * might be empty.     *     * @return an array of cipher suite names     */    synchronized public String[] getEnabledCipherSuites() {        return enabledCipherSuites.toStringArray();    }      /**     * Returns the protocols that are supported by this implementation.     * A subset of the supported protocols may be enabled for this connection     * @return an array of protocol names.     */    public String[] getSupportedProtocols() {        return sslContext.getSuportedProtocolList().toStringArray();    }     /**     * Controls which protocols are enabled for use on     * this connection.  The protocols must have been listed by     * getSupportedProtocols() as being supported.     *     * @param protocols protocols to enable.     * @exception IllegalArgumentException when one of the protocols     *  named by the parameter is not supported.     */    synchronized public void setEnabledProtocols(String[] protocols) {        enabledProtocols = new ProtocolList(protocols);        if ((handshaker != null) && !handshaker.activated()) {            handshaker.setEnabledProtocols(enabledProtocols);        }    }     synchronized public String[] getEnabledProtocols() {        return enabledProtocols.toStringArray();    }     /**     * Assigns the socket timeout.     * @see java.net.Socket#setSoTimeout     */    public void setSoTimeout(int timeout) throws SocketException {        if ((debug != null) && Debug.isOn("ssl")) {            System.out.println(threadName() +                ", setSoTimeout(" + timeout + ") called");        }        if (self == this) {            super.setSoTimeout(timeout);        } else {            self.setSoTimeout(timeout);        }    }     /**     * Registers an event listener to receive notifications that an     * SSL handshake has completed on this connection.     */    public synchronized void addHandshakeCompletedListener(            HandshakeCompletedListener listener) {        if (listener == null) {            throw new IllegalArgumentException("listener is null");        }        if (handshakeListeners == null) {            handshakeListeners = new                HashMap<HandshakeCompletedListener, AccessControlContext>(4);        }        handshakeListeners.put(listener, AccessController.getContext());    }      /**     * Removes a previously registered handshake completion listener.     */    public synchronized void removeHandshakeCompletedListener(            HandshakeCompletedListener listener) {        if (handshakeListeners == null) {            throw new IllegalArgumentException("no listeners");        }        if (handshakeListeners.remove(listener) == null) {            throw new IllegalArgumentException("listener not registered");        }        if (handshakeListeners.isEmpty()) {            handshakeListeners = null;        }    }     /**     * Returns the SSLParameters in effect for this SSLSocket.     */    synchronized public SSLParameters getSSLParameters() {        SSLParameters params = super.getSSLParameters();         // the super implementation does not handle the following parameters        params.setEndpointIdentificationAlgorithm(identificationProtocol);        params.setAlgorithmConstraints(algorithmConstraints);         return params;    }     /**     * Applies SSLParameters to this socket.     */    synchronized public void setSSLParameters(SSLParameters params) {        super.setSSLParameters(params);         // the super implementation does not handle the following parameters        identificationProtocol = params.getEndpointIdentificationAlgorithm();        algorithmConstraints = params.getAlgorithmConstraints();        if ((handshaker != null) && !handshaker.started()) {            handshaker.setIdentificationProtocol(identificationProtocol);            handshaker.setAlgorithmConstraints(algorithmConstraints);        }    }     //    // We allocate a separate thread to deliver handshake completion    // events.  This ensures that the notifications don't block the    // protocol state machine.    //    private static class NotifyHandshakeThread extends Thread {         private Set<Map.Entry<HandshakeCompletedListener,AccessControlContext>>                targets;        // who gets notified        private HandshakeCompletedEvent event;          // the notification         NotifyHandshakeThread(            Set<Map.Entry<HandshakeCompletedListener,AccessControlContext>>            entrySet, HandshakeCompletedEvent e) {             super("HandshakeCompletedNotify-Thread");            targets = entrySet;            event = e;        }         public void run() {            for (Map.Entry<HandshakeCompletedListener,AccessControlContext>                entry : targets) {                 final HandshakeCompletedListener l = entry.getKey();                AccessControlContext acc = entry.getValue();                AccessController.doPrivileged(new PrivilegedAction<Void>() {                    public Void run() {                        l.handshakeCompleted(event);                        return null;                    }                }, acc);            }        }    }     /**     * Return the name of the current thread. Utility method.     */    private static String threadName() {        return Thread.currentThread().getName();    }     /**     * Returns a printable representation of this end of the connection.     */    public String toString() {        StringBuffer retval = new StringBuffer(80);         retval.append(Integer.toHexString(hashCode()));        retval.append("[");        retval.append(sess.getCipherSuite());        retval.append(": ");         if (self == this) {            retval.append(super.toString());        } else {            retval.append(self.toString());        }        retval.append("]");         return retval.toString();    }}

Lines 2001–2493 of 2493. Previous lines