Home | History | Annotate | Download | only in security
      1 /*
      2  * Copyright (c) 1996, 2013, 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 java.security;
     27 
     28 import java.io.IOException;
     29 import java.io.EOFException;
     30 import java.io.InputStream;
     31 import java.io.FilterInputStream;
     32 import java.io.PrintStream;
     33 import java.io.ByteArrayInputStream;
     34 
     35 /**
     36  * A transparent stream that updates the associated message digest using
     37  * the bits going through the stream.
     38  *
     39  * <p>To complete the message digest computation, call one of the
     40  * {@code digest} methods on the associated message
     41  * digest after your calls to one of this digest input stream's
     42  * {@link #read() read} methods.
     43  *
     44  * <p>It is possible to turn this stream on or off (see
     45  * {@link #on(boolean) on}). When it is on, a call to one of the
     46  * {@code read} methods
     47  * results in an update on the message digest.  But when it is off,
     48  * the message digest is not updated. The default is for the stream
     49  * to be on.
     50  *
     51  * <p>Note that digest objects can compute only one digest (see
     52  * {@link MessageDigest}),
     53  * so that in order to compute intermediate digests, a caller should
     54  * retain a handle onto the digest object, and clone it for each
     55  * digest to be computed, leaving the orginal digest untouched.
     56  *
     57  * @see MessageDigest
     58  *
     59  * @see DigestOutputStream
     60  *
     61  * @author Benjamin Renaud
     62  */
     63 
     64 public class DigestInputStream extends FilterInputStream {
     65 
     66     /* NOTE: This should be made a generic UpdaterInputStream */
     67 
     68     /* Are we on or off? */
     69     private boolean on = true;
     70 
     71     /**
     72      * The message digest associated with this stream.
     73      */
     74     protected MessageDigest digest;
     75 
     76     /**
     77      * Creates a digest input stream, using the specified input stream
     78      * and message digest.
     79      *
     80      * @param stream the input stream.
     81      *
     82      * @param digest the message digest to associate with this stream.
     83      */
     84     public DigestInputStream(InputStream stream, MessageDigest digest) {
     85         super(stream);
     86         setMessageDigest(digest);
     87     }
     88 
     89     /**
     90      * Returns the message digest associated with this stream.
     91      *
     92      * @return the message digest associated with this stream.
     93      * @see #setMessageDigest(java.security.MessageDigest)
     94      */
     95     public MessageDigest getMessageDigest() {
     96         return digest;
     97     }
     98 
     99     /**
    100      * Associates the specified message digest with this stream.
    101      *
    102      * @param digest the message digest to be associated with this stream.
    103      * @see #getMessageDigest()
    104      */
    105     public void setMessageDigest(MessageDigest digest) {
    106         this.digest = digest;
    107     }
    108 
    109     /**
    110      * Reads a byte, and updates the message digest (if the digest
    111      * function is on).  That is, this method reads a byte from the
    112      * input stream, blocking until the byte is actually read. If the
    113      * digest function is on (see {@link #on(boolean) on}), this method
    114      * will then call {@code update} on the message digest associated
    115      * with this stream, passing it the byte read.
    116      *
    117      * @return the byte read.
    118      *
    119      * @exception IOException if an I/O error occurs.
    120      *
    121      * @see MessageDigest#update(byte)
    122      */
    123     public int read() throws IOException {
    124         int ch = in.read();
    125         if (on && ch != -1) {
    126             digest.update((byte)ch);
    127         }
    128         return ch;
    129     }
    130 
    131     /**
    132      * Reads into a byte array, and updates the message digest (if the
    133      * digest function is on).  That is, this method reads up to
    134      * {@code len} bytes from the input stream into the array
    135      * {@code b}, starting at offset {@code off}. This method
    136      * blocks until the data is actually
    137      * read. If the digest function is on (see
    138      * {@link #on(boolean) on}), this method will then call {@code update}
    139      * on the message digest associated with this stream, passing it
    140      * the data.
    141      *
    142      * @param b the array into which the data is read.
    143      *
    144      * @param off the starting offset into {@code b} of where the
    145      * data should be placed.
    146      *
    147      * @param len the maximum number of bytes to be read from the input
    148      * stream into b, starting at offset {@code off}.
    149      *
    150      * @return  the actual number of bytes read. This is less than
    151      * {@code len} if the end of the stream is reached prior to
    152      * reading {@code len} bytes. -1 is returned if no bytes were
    153      * read because the end of the stream had already been reached when
    154      * the call was made.
    155      *
    156      * @exception IOException if an I/O error occurs.
    157      *
    158      * @see MessageDigest#update(byte[], int, int)
    159      */
    160     public int read(byte[] b, int off, int len) throws IOException {
    161         int result = in.read(b, off, len);
    162         if (on && result != -1) {
    163             digest.update(b, off, result);
    164         }
    165         return result;
    166     }
    167 
    168     /**
    169      * Turns the digest function on or off. The default is on.  When
    170      * it is on, a call to one of the {@code read} methods results in an
    171      * update on the message digest.  But when it is off, the message
    172      * digest is not updated.
    173      *
    174      * @param on true to turn the digest function on, false to turn
    175      * it off.
    176      */
    177     public void on(boolean on) {
    178         this.on = on;
    179     }
    180 
    181     /**
    182      * Prints a string representation of this digest input stream and
    183      * its associated message digest object.
    184      */
    185      public String toString() {
    186          return "[Digest Input Stream] " + digest.toString();
    187      }
    188 }
    189