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 /** 99325ff8c68ed5e530e9e1d487b9e2e6d8f8e2bd37Elliott Hughes * Reads up to {@code byteCount} bytes into {@code buffer}, starting at 100325ff8c68ed5e530e9e1d487b9e2e6d8f8e2bd37Elliott Hughes * {@code byteOffset}. Updates the digest if this function is 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link #on(boolean)}. 1022f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 103325ff8c68ed5e530e9e1d487b9e2e6d8f8e2bd37Elliott Hughes * <p>This operation is blocking. 104325ff8c68ed5e530e9e1d487b9e2e6d8f8e2bd37Elliott Hughes * 105325ff8c68ed5e530e9e1d487b9e2e6d8f8e2bd37Elliott Hughes * <p>Returns the number of bytes actually read or -1 if the end of the 106325ff8c68ed5e530e9e1d487b9e2e6d8f8e2bd37Elliott Hughes * filtered stream has been reached while reading. 107325ff8c68ed5e530e9e1d487b9e2e6d8f8e2bd37Elliott Hughes * 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if reading the source stream causes an {@code IOException} 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1112f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes @Override 112325ff8c68ed5e530e9e1d487b9e2e6d8f8e2bd37Elliott Hughes public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException { 113325ff8c68ed5e530e9e1d487b9e2e6d8f8e2bd37Elliott Hughes int bytesRead = in.read(buffer, byteOffset, byteCount); 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // update digest only if 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // - digest functionality is on 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // - eos has not been reached 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isOn && (bytesRead != -1)) { 118325ff8c68ed5e530e9e1d487b9e2e6d8f8e2bd37Elliott Hughes digest.update(buffer, byteOffset, bytesRead); 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // return number of bytes read 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return bytesRead; 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Enables or disables the digest function (default is on). 1262f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param on 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code true} if the digest should be computed, {@code false} 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherwise. 130d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes * @see MessageDigest 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void on(boolean on) { 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isOn = on; 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a string containing a concise, human-readable description of this 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code DigestInputStream} including the digest. 1392f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes * 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a printable representation for this {@code DigestInputStream}. 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1422f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes @Override 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toString() { 144f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes return super.toString() + ", " + digest.toString() + 145f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes (isOn ? ", is on" : ", is off"); 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 148