1 /*
   2  * Copyright (c) 2003, 2004, 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 javax.net.ssl;
  27 
  28 /**
  29  * An encapsulation of the result state produced by
  30  * <code>SSLEngine</code> I/O calls.
  31  *
  32  * <p> A <code>SSLEngine</code> provides a means for establishing
  33  * secure communication sessions between two peers.  <code>SSLEngine</code>
  34  * operations typically consume bytes from an input buffer and produce
  35  * bytes in an output buffer.  This class provides operational result
  36  * values describing the state of the <code>SSLEngine</code>, including
  37  * indications of what operations are needed to finish an
  38  * ongoing handshake.  Lastly, it reports the number of bytes consumed
  39  * and produced as a result of this operation.
  40  *
  41  * @see SSLEngine
  42  * @see SSLEngine#wrap(ByteBuffer, ByteBuffer)
  43  * @see SSLEngine#unwrap(ByteBuffer, ByteBuffer)
  44  *
  45  * @author Brad R. Wetmore
  46  * @since 1.5
  47  */
  48 
  49 public class SSLEngineResult {
  50 
  51     /**
  52      * An <code>SSLEngineResult</code> enum describing the overall result
  53      * of the <code>SSLEngine</code> operation.
  54      *
  55      * The <code>Status</code> value does not reflect the
  56      * state of a <code>SSLEngine</code> handshake currently
  57      * in progress.  The <code>SSLEngineResult's HandshakeStatus</code>
  58      * should be consulted for that information.
  59      *
  60      * @author Brad R. Wetmore
  61      * @since 1.5
  62      */
  63     public static enum Status {
  64 
  65         /**
  66          * The <code>SSLEngine</code> was not able to unwrap the
  67          * incoming data because there were not enough source bytes
  68          * available to make a complete packet.
  69          *
  70          * <P>
  71          * Repeat the call once more bytes are available.
  72          */
  73         BUFFER_UNDERFLOW,
  74 
  75         /**
  76          * The <code>SSLEngine</code> was not able to process the
  77          * operation because there are not enough bytes available in the
  78          * destination buffer to hold the result.
  79          * <P>
  80          * Repeat the call once more bytes are available.
  81          *
  82          * @see SSLSession#getPacketBufferSize()
  83          * @see SSLSession#getApplicationBufferSize()
  84          */
  85         BUFFER_OVERFLOW,
  86 
  87         /**
  88          * The <code>SSLEngine</code> completed the operation, and
  89          * is available to process similar calls.
  90          */
  91         OK,
  92 
  93         /**
  94          * The operation just closed this side of the
  95          * <code>SSLEngine</code>, or the operation
  96          * could not be completed because it was already closed.
  97          */
  98         CLOSED;
  99     }
 100 
 101     /**
 102      * An <code>SSLEngineResult</code> enum describing the current
 103      * handshaking state of this <code>SSLEngine</code>.
 104      *
 105      * @author Brad R. Wetmore
 106      * @since 1.5
 107      */
 108     public static enum HandshakeStatus {
 109 
 110         /**
 111          * The <code>SSLEngine</code> is not currently handshaking.
 112          */
 113         NOT_HANDSHAKING,
 114 
 115         /**
 116          * The <code>SSLEngine</code> has just finished handshaking.
 117          * <P>
 118          * This value is only generated by a call to
 119          * <code>SSLEngine.wrap()/unwrap()</code> when that call
 120          * finishes a handshake.  It is never generated by
 121          * <code>SSLEngine.getHandshakeStatus()</code>.
 122          *
 123          * @see SSLEngine#wrap(ByteBuffer, ByteBuffer)
 124          * @see SSLEngine#unwrap(ByteBuffer, ByteBuffer)
 125          * @see SSLEngine#getHandshakeStatus()
 126          */
 127         FINISHED,
 128 
 129         /**
 130          * The <code>SSLEngine</code> needs the results of one (or more)
 131          * delegated tasks before handshaking can continue.
 132          *
 133          * @see SSLEngine#getDelegatedTask()
 134          */
 135         NEED_TASK,
 136 
 137         /**
 138          * The <code>SSLEngine</code> must send data to the remote side
 139          * before handshaking can continue, so <code>SSLEngine.wrap()</code>
 140          * should be called.
 141          *
 142          * @see SSLEngine#wrap(ByteBuffer, ByteBuffer)
 143          */
 144         NEED_WRAP,
 145 
 146         /**
 147          * The <code>SSLEngine</code> needs to receive data from the
 148          * remote side before handshaking can continue.
 149          */
 150         NEED_UNWRAP;
 151     }
 152 
 153 
 154     private final Status status;
 155     private final HandshakeStatus handshakeStatus;
 156     private final int bytesConsumed;
 157     private final int bytesProduced;
 158 
 159     /**
 160      * Initializes a new instance of this class.
 161      *
 162      * @param   status
 163      *          the return value of the operation.
 164      *
 165      * @param   handshakeStatus
 166      *          the current handshaking status.
 167      *
 168      * @param   bytesConsumed
 169      *          the number of bytes consumed from the source ByteBuffer
 170      *
 171      * @param   bytesProduced
 172      *          the number of bytes placed into the destination ByteBuffer
 173      *
 174      * @throws  IllegalArgumentException
 175      *          if the <code>status</code> or <code>handshakeStatus</code>
 176      *          arguments are null, or if <<code>bytesConsumed</code> or
 177      *          <code>bytesProduced</code> is negative.
 178      */
 179     public SSLEngineResult(Status status, HandshakeStatus handshakeStatus,
 180             int bytesConsumed, int bytesProduced) {
 181 
 182         if ((status == null) || (handshakeStatus == null) ||
 183                 (bytesConsumed < 0) || (bytesProduced < 0)) {
 184             throw new IllegalArgumentException("Invalid Parameter(s)");
 185         }
 186 
 187         this.status = status;
 188         this.handshakeStatus = handshakeStatus;
 189         this.bytesConsumed = bytesConsumed;
 190         this.bytesProduced = bytesProduced;
 191     }
 192 
 193     /**
 194      * Gets the return value of this <code>SSLEngine</code> operation.
 195      *
 196      * @return  the return value
 197      */
 198     final public Status getStatus() {
 199         return status;
 200     }
 201 
 202     /**
 203      * Gets the handshake status of this <code>SSLEngine</code>
 204      * operation.
 205      *
 206      * @return  the handshake status
 207      */
 208     final public HandshakeStatus getHandshakeStatus() {
 209         return handshakeStatus;
 210     }
 211 
 212     /**
 213      * Returns the number of bytes consumed from the input buffer.
 214      *
 215      * @return  the number of bytes consumed.
 216      */
 217     final public int bytesConsumed() {
 218         return bytesConsumed;
 219     }
 220 
 221     /**
 222      * Returns the number of bytes written to the output buffer.
 223      *
 224      * @return  the number of bytes produced
 225      */
 226     final public int bytesProduced() {
 227         return bytesProduced;
 228     }
 229 
 230     /**
 231      * Returns a String representation of this object.
 232      */
 233     @Override
 234     public String toString() {
 235         return ("Status = " + status +
 236             " HandshakeStatus = " + handshakeStatus +
 237             "\nbytesConsumed = " + bytesConsumed +
 238             " bytesProduced = " + bytesProduced);
 239     }
 240 }