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 }