Home | History | Annotate | Download | only in ssl
      1 /*
      2  *  Licensed to the Apache Software Foundation (ASF) under one or more
      3  *  contributor license agreements.  See the NOTICE file distributed with
      4  *  this work for additional information regarding copyright ownership.
      5  *  The ASF licenses this file to You under the Apache License, Version 2.0
      6  *  (the "License"); you may not use this file except in compliance with
      7  *  the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  */
     17 
     18 package javax.net.ssl;
     19 
     20 import java.nio.ByteBuffer;
     21 
     22 /**
     23  * The abstract implementation of secure communications using SSL, TLS, or other
     24  * protocols. It includes the setup, handshake, and encrypt/decrypt
     25  * functionality needed to create a secure connection.
     26  *
     27  * @since 1.5
     28  */
     29 public abstract class SSLEngine {
     30     private final String peerHost;
     31     private final int peerPort;
     32 
     33     /**
     34      * Creates a new {@code SSLEngine} instance.
     35      */
     36     protected SSLEngine() {
     37         peerHost = null;
     38         peerPort = -1;
     39     }
     40 
     41     /**
     42      * Creates a new {@code SSLEngine} instance with the specified host and
     43      * port.
     44      *
     45      * @param host
     46      *            the name of the host.
     47      * @param port
     48      *            the port of the host.
     49      */
     50     protected SSLEngine(String host, int port) {
     51         this.peerHost = host;
     52         this.peerPort = port;
     53     }
     54 
     55     /**
     56      * Returns the name of the peer host.
     57      *
     58      * @return the name of the peer host, or {@code null} if none is available.
     59      */
     60     public String getPeerHost() {
     61         return peerHost;
     62     }
     63 
     64     /**
     65      * Returns the port number of the peer host.
     66      *
     67      * @return the port number of the peer host, or {@code -1} is none is
     68      *         available.
     69      */
     70     public int getPeerPort() {
     71         return peerPort;
     72     }
     73 
     74     /**
     75      * Initiates a handshake on this engine.
     76      * <p>
     77      * Calling this method is not needed for the initial handshake: it will be
     78      * called by {@code wrap} or {@code unwrap} if the initial handshake has not
     79      * been started yet.
     80      *
     81      * @throws SSLException
     82      *             if starting the handshake fails.
     83      * @throws IllegalStateException
     84      *             if the engine does not have all the needed settings (e.g.
     85      *             client/server mode not set).
     86      */
     87     public abstract void beginHandshake() throws SSLException;
     88 
     89     /**
     90      * Notifies this engine instance that no more inbound network data will be
     91      * sent to this engine.
     92      *
     93      * @throws SSLException
     94      *             if this engine did not receive a needed protocol specific
     95      *             close notification message from the peer.
     96      */
     97     public abstract void closeInbound() throws SSLException;
     98 
     99     /**
    100      * Notifies this engine instance that no more outbound application data will
    101      * be sent to this engine.
    102      */
    103     public abstract void closeOutbound();
    104 
    105     /**
    106      * Returns a delegate task for this engine instance. Some engine operations
    107      * may require the results of blocking or long running operations, and the
    108      * {@code SSLEngineResult} instances returned by this engine may indicate
    109      * that a delegated task result is needed. In this case the
    110      * {@link Runnable#run() run} method of the returned {@code Runnable}
    111      * delegated task must be called.
    112      *
    113      * @return a delegate task, or {@code null} if none are available.
    114      */
    115     public abstract Runnable getDelegatedTask();
    116 
    117     /**
    118      * Returns the SSL cipher suite names that are enabled in this engine
    119      * instance.
    120      *
    121      * @return the SSL cipher suite names that are enabled in this engine
    122      *         instance.
    123      */
    124     public abstract String[] getEnabledCipherSuites();
    125 
    126     /**
    127      * Returns the protocol version names that are enabled in this engine
    128      * instance.
    129      *
    130      * @return the protocol version names that are enabled in this engine
    131      *         instance.
    132      */
    133     public abstract String[] getEnabledProtocols();
    134 
    135     /**
    136      * Returns whether new SSL sessions may be established by this engine.
    137      *
    138      * @return {@code true} if new session may be established, {@code false} if
    139      *         existing sessions must be reused.
    140      */
    141     public abstract boolean getEnableSessionCreation();
    142 
    143     /**
    144      * Returns the status of the handshake of this engine instance.
    145      *
    146      * @return the status of the handshake of this engine instance.
    147      */
    148     public abstract SSLEngineResult.HandshakeStatus getHandshakeStatus();
    149 
    150     /**
    151      * Returns whether this engine instance will require client authentication.
    152      *
    153      * @return {@code true} if this engine will require client authentication,
    154      *         {@code false} if no client authentication is needed.
    155      */
    156     public abstract boolean getNeedClientAuth();
    157 
    158     /**
    159      * Returns the SSL session for this engine instance.
    160      *
    161      * @return the SSL session for this engine instance.
    162      */
    163     public abstract SSLSession getSession();
    164 
    165     /**
    166      * Returns the SSL cipher suite names that are supported by this engine.
    167      * These cipher suites can be enabled using
    168      * {@link #setEnabledCipherSuites(String[])}.
    169      *
    170      * @return the SSL cipher suite names that are supported by this engine.
    171      */
    172     public abstract String[] getSupportedCipherSuites();
    173 
    174     /**
    175      * Returns the protocol names that are supported by this engine. These
    176      * protocols can be enables using {@link #setEnabledProtocols(String[])}.
    177      *
    178      * @return the protocol names that are supported by this engine.
    179      */
    180     public abstract String[] getSupportedProtocols();
    181 
    182     /**
    183      * Returns whether this engine is set to act in client mode when
    184      * handshaking.
    185      *
    186      * @return {@code true} if the engine is set to do handshaking in client
    187      *         mode.
    188      */
    189     public abstract boolean getUseClientMode();
    190 
    191     /**
    192      * Returns whether this engine will request client authentication.
    193      *
    194      * @return {@code true} if client authentication will be requested,
    195      *         {@code false} otherwise.
    196      */
    197     public abstract boolean getWantClientAuth();
    198 
    199     /**
    200      * Returns whether no more inbound data will be accepted by this engine.
    201      *
    202      * @return {@code true} if no more inbound data will be accepted by this
    203      *         engine, {@code false} otherwise.
    204      */
    205     public abstract boolean isInboundDone();
    206 
    207     /**
    208      * Returns whether no more outbound data will be produced by this engine.
    209      *
    210      * @return {@code true} if no more outbound data will be producted by this
    211      *         engine, {@code otherwise} false.
    212      */
    213     public abstract boolean isOutboundDone();
    214 
    215     /**
    216      * Sets the SSL cipher suite names that should be enabled in this engine
    217      * instance. Only cipher suites listed by {@code getSupportedCipherSuites()}
    218      * are allowed.
    219      *
    220      * @param suites
    221      *            the SSL cipher suite names to be enabled.
    222      * @throws IllegalArgumentException
    223      *             if one of the specified cipher suites is not supported, or if
    224      *             {@code suites} is {@code null}.
    225      */
    226     public abstract void setEnabledCipherSuites(String[] suites);
    227 
    228     /**
    229      * Sets the protocol version names that should be enabled in this engine
    230      * instance. Only protocols listed by {@code getSupportedProtocols()} are
    231      * allowed.
    232      *
    233      * @param protocols
    234      *            the protocol version names to be enabled.
    235      * @throws IllegalArgumentException
    236      *             if one of the protocol version names is not supported, or if
    237      *             {@code protocols} is {@code null}.
    238      */
    239     public abstract void setEnabledProtocols(String[] protocols);
    240 
    241     /**
    242      * Sets whether new SSL sessions may be established by this engine instance.
    243      *
    244      * @param flag
    245      *            {@code true} if new SSL sessions may be established,
    246      *            {@code false} if existing SSL sessions must be reused.
    247      */
    248     public abstract void setEnableSessionCreation(boolean flag);
    249 
    250     /**
    251      * Sets whether this engine must require client authentication. The client
    252      * authentication is one of:
    253      * <ul>
    254      * <li>authentication required</li>
    255      * <li>authentication requested</li>
    256      * <li>no authentication needed</li>
    257      * </ul>
    258      * This method overrides the setting of {@link #setWantClientAuth(boolean)}.
    259      *
    260      * @param need
    261      *            {@code true} if client authentication is required,
    262      *            {@code false} if no authentication is needed.
    263      */
    264     public abstract void setNeedClientAuth(boolean need);
    265 
    266     /**
    267      * Sets whether this engine should act in client (or server) mode when
    268      * handshaking.
    269      *
    270      * @param mode
    271      *            {@code true} if this engine should act in client mode,
    272      *            {@code false} if not.
    273      * @throws IllegalArgumentException
    274      *             if this method is called after starting the initial
    275      *             handshake.
    276      */
    277     public abstract void setUseClientMode(boolean mode);
    278 
    279     /**
    280      * Sets whether this engine should request client authentication. The client
    281      * authentication is one of the following:
    282      * <ul>
    283      * <li>authentication required</li>
    284      * <li>authentication requested</li>
    285      * <li>no authentication needed</li>
    286      * </ul>
    287      * This method overrides the setting of {@link #setNeedClientAuth(boolean)}.
    288      *
    289      * @param want
    290      *            {@code true} if client authentication should be requested,
    291      *            {@code false} if no authentication is needed.
    292      */
    293     public abstract void setWantClientAuth(boolean want);
    294 
    295     /**
    296      * Decodes the incoming network data buffer into application data buffers.
    297      * If a handshake has not been started yet, it will automatically be
    298      * started.
    299      *
    300      * @param src
    301      *            the buffer with incoming network data
    302      * @param dsts
    303      *            the array of destination buffers for incoming application
    304      *            data.
    305      * @param offset
    306      *            the offset in the array of destination buffers to which data
    307      *            is to be transferred.
    308      * @param length
    309      *            the maximum number of destination buffers to be used.
    310      * @return the result object of this operation.
    311      * @throws SSLException
    312      *             if a problem occurred while processing the data.
    313      * @throws IndexOutOfBoundsException
    314      *             if {@code length} is greater than
    315      *             {@code dsts.length - offset}.
    316      * @throws java.nio.ReadOnlyBufferException
    317      *             if one of the destination buffers is read-only.
    318      * @throws IllegalArgumentException
    319      *             if {@code src}, {@code dsts}, or one of the entries in
    320      *             {@code dsts} is {@code null}.
    321      * @throws IllegalStateException
    322      *             if the engine does not have all the needed settings (e.g.
    323      *             client/server mode not set).
    324      */
    325     public abstract SSLEngineResult unwrap(ByteBuffer src,
    326                                            ByteBuffer[] dsts,
    327                                            int offset,
    328                                            int length) throws SSLException;
    329 
    330     /**
    331      * Encodes the outgoing application data buffers into the network data
    332      * buffer. If a handshake has not been started yet, it will automatically be
    333      * started.
    334      *
    335      * @param srcs
    336      *            the array of source buffers of outgoing application data.
    337      * @param offset
    338      *            the offset in the array of source buffers from which data is
    339      *            to be retrieved.
    340      * @param length
    341      *            the maximum number of source buffers to be used.
    342      * @param dst
    343      *            the destination buffer for network data.
    344      * @return the result object of this operation.
    345      * @throws SSLException
    346      *             if a problem occurred while processing the data.
    347      * @throws IndexOutOfBoundsException
    348      *             if {@code length} is greater than
    349      *             {@code srcs.length - offset}.
    350      * @throws java.nio.ReadOnlyBufferException
    351      *             if the destination buffer is readonly.
    352      * @throws IllegalArgumentException
    353      *             if {@code srcs}, {@code dst}, or one the entries in
    354      *             {@code srcs} is {@code null}.
    355      * @throws IllegalStateException
    356      *             if the engine does not have all the needed settings (e.g.
    357      *             client/server mode not set).
    358      */
    359     public abstract SSLEngineResult wrap(ByteBuffer[] srcs, int offset, int length, ByteBuffer dst)
    360             throws SSLException;
    361 
    362     /**
    363      * Decodes the incoming network data buffer into the application data
    364      * buffer. If a handshake has not been started yet, it will automatically be
    365      * started.
    366      *
    367      * @param src
    368      *            the buffer with incoming network data
    369      * @param dst
    370      *            the destination buffer for incoming application data.
    371      * @return the result object of this operation.
    372      * @throws SSLException
    373      *             if a problem occurred while processing the data.
    374      * @throws java.nio.ReadOnlyBufferException
    375      *             if one of the destination buffers is read-only.
    376      * @throws IllegalArgumentException
    377      *             if {@code src} or {@code dst} is {@code null}.
    378      * @throws IllegalStateException
    379      *             if the engine does not have all the needed settings (e.g.
    380      *             client/server mode not set).
    381      */
    382     public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer dst) throws SSLException {
    383         return unwrap(src, new ByteBuffer[] { dst }, 0, 1);
    384     }
    385 
    386     /**
    387      * Decodes the incoming network data buffer into the application data
    388      * buffers. If a handshake has not been started yet, it will automatically
    389      * be started.
    390      *
    391      * @param src
    392      *            the buffer with incoming network data
    393      * @param dsts
    394      *            the array of destination buffers for incoming application
    395      *            data.
    396      * @return the result object of this operation.
    397      * @throws SSLException
    398      *             if a problem occurred while processing the data.
    399      * @throws java.nio.ReadOnlyBufferException
    400      *             if one of the destination buffers is read-only.
    401      * @throws IllegalArgumentException
    402      *             if {@code src} or {@code dsts} is {@code null}.
    403      * @throws IllegalStateException
    404      *             if the engine does not have all the needed settings (e.g.
    405      *             client/server mode not set).
    406      */
    407     public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dsts) throws SSLException {
    408         if (dsts == null) {
    409             throw new IllegalArgumentException("Byte buffer array dsts is null");
    410         }
    411         return unwrap(src, dsts, 0, dsts.length);
    412     }
    413 
    414     /**
    415      * Encodes the outgoing application data buffers into the network data
    416      * buffer. If a handshake has not been started yet, it will automatically be
    417      * started.
    418      *
    419      * @param srcs
    420      *            the array of source buffers of outgoing application data.
    421      * @param dst
    422      *            the destination buffer for network data.
    423      * @return the result object of this operation.
    424      * @throws SSLException
    425      *             if a problem occurred while processing the data.
    426      * @throws java.nio.ReadOnlyBufferException
    427      *             if the destination buffer is readonly.
    428      * @throws IllegalArgumentException
    429      *             if {@code srcs} or {@code dst} is {@code null}.
    430      * @throws IllegalStateException
    431      *             if the engine does not have all the needed settings (e.g.
    432      *             client/server mode not set).
    433      */
    434     public SSLEngineResult wrap(ByteBuffer[] srcs, ByteBuffer dst) throws SSLException {
    435         if (srcs == null) {
    436             throw new IllegalArgumentException("Byte buffer array srcs is null");
    437         }
    438         return wrap(srcs, 0, srcs.length, dst);
    439     }
    440 
    441     /**
    442      * Encodes the outgoing application data buffer into the network data
    443      * buffer. If a handshake has not been started yet, it will automatically be
    444      * started.
    445      *
    446      * @param src
    447      *            the source buffers of outgoing application data.
    448      * @param dst
    449      *            the destination buffer for network data.
    450      * @return the result object of this operation.
    451      * @throws SSLException
    452      *             if a problem occurred while processing the data.
    453      * @throws java.nio.ReadOnlyBufferException
    454      *             if the destination buffer is readonly.
    455      * @throws IllegalArgumentException
    456      *             if {@code src} or {@code dst} is {@code null}.
    457      * @throws IllegalStateException
    458      *             if the engine does not have all the needed settings (e.g.
    459      *             client/server mode not set).
    460      */
    461     public SSLEngineResult wrap(ByteBuffer src, ByteBuffer dst) throws SSLException {
    462         return wrap(new ByteBuffer[] { src }, 0, 1, dst);
    463     }
    464 
    465     /**
    466      * Returns a new SSLParameters based on this SSLSocket's current
    467      * cipher suites, protocols, and client authentication settings.
    468      *
    469      * @since 1.6
    470      */
    471     public SSLParameters getSSLParameters() {
    472         SSLParameters p = new SSLParameters();
    473         p.setCipherSuites(getEnabledCipherSuites());
    474         p.setProtocols(getEnabledProtocols());
    475         p.setNeedClientAuth(getNeedClientAuth());
    476         p.setWantClientAuth(getWantClientAuth());
    477         return p;
    478     }
    479 
    480     /**
    481      * Sets various SSL handshake parameters based on the SSLParameter
    482      * argument. Specifically, sets the SSLEngine's enabled cipher
    483      * suites if the parameter's cipher suites are non-null. Similarly
    484      * sets the enabled protocols. If the parameters specify the want
    485      * or need for client authentication, those requirements are set
    486      * on the SSLEngine, otherwise both are set to false.
    487      * @since 1.6
    488      */
    489     public void setSSLParameters(SSLParameters p) {
    490         String[] cipherSuites = p.getCipherSuites();
    491         if (cipherSuites != null) {
    492             setEnabledCipherSuites(cipherSuites);
    493         }
    494         String[] protocols = p.getProtocols();
    495         if (protocols != null) {
    496             setEnabledProtocols(protocols);
    497         }
    498         if (p.getNeedClientAuth()) {
    499             setNeedClientAuth(true);
    500         } else if (p.getWantClientAuth()) {
    501             setWantClientAuth(true);
    502         } else {
    503             setWantClientAuth(false);
    504         }
    505     }
    506 }
    507