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