001 package com.croftsoft.core.util.cache.secure;
002
003 import java.io.*;
004 import java.security.*;
005
006 /*********************************************************************
007 * A FilterInputStream which will throw a SecurityException if the
008 * stream content does not have the digest expected.
009 *
010 * @see
011 * java.security.DigestInputStream
012 * @see
013 * java.security.MessageDigest
014 *
015 * @version
016 * 1999-04-13
017 * @author
018 * <a href="https://www.croftsoft.com/">David Wallace Croft</a>
019 *********************************************************************/
020
021 public class SecureInputStream extends FilterInputStream
022 //////////////////////////////////////////////////////////////////////
023 //////////////////////////////////////////////////////////////////////
024 {
025
026 /** The expected digest. */
027 private byte [ ] digest;
028
029 //////////////////////////////////////////////////////////////////////
030 // Constructor method
031 //////////////////////////////////////////////////////////////////////
032
033 /*********************************************************************
034 * @param algorithm
035 * The MessageDigest algorithm to use.
036 * @param digest
037 * The expected digest.
038 *********************************************************************/
039 public SecureInputStream (
040 InputStream inputStream,
041 String algorithm,
042 byte [ ] digest )
043 throws NoSuchAlgorithmException
044 //////////////////////////////////////////////////////////////////////
045 {
046 super ( new DigestInputStream ( inputStream,
047 MessageDigest.getInstance ( algorithm ) ) );
048
049 this.digest = digest;
050 }
051
052 //////////////////////////////////////////////////////////////////////
053 //////////////////////////////////////////////////////////////////////
054
055 /*********************************************************************
056 * @throws SecurityException
057 * If the end of the stream is reached and the digest is not what
058 * is expected.
059 *********************************************************************/
060 public int read ( ) throws IOException
061 //////////////////////////////////////////////////////////////////////
062 {
063 int i = super.read ( );
064
065 if ( i < 0 ) checkDigest ( );
066
067 return i;
068 }
069
070 /*********************************************************************
071 * @throws SecurityException
072 * If the end of the stream is reached and the digest is not what
073 * is expected.
074 *********************************************************************/
075 public int read ( byte [ ] byteArray, int offset, int length )
076 throws IOException
077 //////////////////////////////////////////////////////////////////////
078 {
079 int i = super.read ( byteArray, offset, length );
080
081 if ( i < length ) checkDigest ( );
082
083 return i;
084 }
085
086 private void checkDigest ( ) throws IOException
087 //////////////////////////////////////////////////////////////////////
088 {
089 if ( !MessageDigest.isEqual ( digest,
090 ( ( DigestInputStream ) in ).getMessageDigest ( ).digest ( ) ) )
091 {
092 throw new IOException ( "bad message digest" );
093 }
094 }
095
096 //////////////////////////////////////////////////////////////////////
097 //////////////////////////////////////////////////////////////////////
098 }