1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.security; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.FilterInputStream; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.InputStream; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code DigestInputStream} is a {@code FilterInputStream} which maintains an 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * associated message digest. 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class DigestInputStream extends FilterInputStream { 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The message digest for this stream. 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected MessageDigest digest; 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Indicates whether digest functionality is on or off 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean isOn = true; 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs a new instance of this {@code DigestInputStream}, using the 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * given {@code stream} and the {@code digest}. 412f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 42858dd42310622fd1b77bfa0fbd85ec851b3925c1Jesse Wilson * <p><strong>Warning:</strong> passing a null source creates an invalid 43858dd42310622fd1b77bfa0fbd85ec851b3925c1Jesse Wilson * {@code DigestInputStream}. All operations on such a stream will fail. 44858dd42310622fd1b77bfa0fbd85ec851b3925c1Jesse Wilson * 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param stream 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the input stream. 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param digest 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the message digest. 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public DigestInputStream(InputStream stream, MessageDigest digest) { 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(stream); 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.digest = digest; 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the message digest for this stream. 572f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the message digest for this stream. 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public MessageDigest getMessageDigest() { 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return digest; 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Sets the message digest which this stream will use. 662f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param digest 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the message digest which this stream will use. 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setMessageDigest(MessageDigest digest) { 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.digest = digest; 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads the next byte and returns it as an {@code int}. Updates the digest 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for the byte if this function is {@link #on(boolean)}. 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This operation is blocking. 792f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the byte which was read or -1 at end of stream. 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if reading the source stream causes an {@code IOException}. 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 842f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes @Override 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int read() throws IOException { 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // read the next byte 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int byteRead = in.read(); 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // update digest only if 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // - digest functionality is on 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // - eos has not been reached 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isOn && (byteRead != -1)) { 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project digest.update((byte)byteRead); 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // return byte read 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return byteRead; 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads {@code len} bytes into the specified {@code byte[]}, starting from 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the specified offset. Updates the digest if this function is 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link #on(boolean)}. 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This operation is blocking. 1042f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param b 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the byte array in which to store the bytes 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param off 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the initial position in {@code b} to store the bytes read from 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this stream 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param len 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the maximum number of bytes to store in {@code b} 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of bytes actually read or -1 if the end of the 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * filtered stream has been reached while reading 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if reading the source stream causes an {@code IOException} 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1172f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes @Override 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int read(byte[] b, int off, int len) throws IOException { 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // read next up to len bytes 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int bytesRead = in.read(b, off, len); 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // update digest only if 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // - digest functionality is on 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // - eos has not been reached 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isOn && (bytesRead != -1)) { 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project digest.update(b, off, bytesRead); 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // return number of bytes read 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return bytesRead; 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Enables or disables the digest function (default is on). 1332f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param on 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code true} if the digest should be computed, {@code false} 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherwise. 137d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes * @see MessageDigest 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void on(boolean on) { 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isOn = on; 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a string containing a concise, human-readable description of this 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code DigestInputStream} including the digest. 1462f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a printable representation for this {@code DigestInputStream}. 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1492f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes @Override 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toString() { 151f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes return super.toString() + ", " + digest.toString() + 152f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes (isOn ? ", is on" : ", is off"); 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 155