19 package org.sleuthkit.autopsy.modules.hashdatabase;
 
   21 import java.io.InputStream;
 
   22 import java.io.BufferedInputStream;
 
   23 import java.io.FileInputStream;
 
   24 import java.io.IOException;
 
   25 import java.util.Arrays;
 
   26 import java.util.logging.Level;
 
   33 class EncaseHashSetParser 
implements HashSetParser {
 
   35     private final byte[] encaseHeader = {(byte) 0x48, (byte) 0x41, (byte) 0x53, (byte) 0x48, (byte) 0x0d, (byte) 0x0a, (byte) 0xff, (byte) 0x00,
 
   36         (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00};
 
   37     private final String filename;         
 
   38     private InputStream inputStream;       
 
   39     private final long expectedHashCount;  
 
   40     private int totalHashesRead = 0;       
 
   50     EncaseHashSetParser(String filename) 
throws TskCoreException {
 
   52             this.filename = filename;
 
   53             inputStream = 
new BufferedInputStream(
new FileInputStream(filename));
 
   56             byte[] header = 
new byte[16];
 
   57             readBuffer(header, 16);
 
   58             if (!Arrays.equals(header, encaseHeader)) {
 
   60                 throw new TskCoreException(
"File " + filename + 
" does not have an Encase header");
 
   64             byte[] sizeBuffer = 
new byte[4];
 
   65             readBuffer(sizeBuffer, 4);
 
   66             expectedHashCount = ((sizeBuffer[3] & 0xff) << 24) | ((sizeBuffer[2] & 0xff) << 16)
 
   67                     | ((sizeBuffer[1] & 0xff) << 8) | (sizeBuffer[0] & 0xff);
 
   70             byte[] filler = 
new byte[0x3f4];
 
   71             readBuffer(filler, 0x3f4);
 
   74             byte[] nameBuffer = 
new byte[0x50];
 
   75             readBuffer(nameBuffer, 0x50);
 
   78             byte[] typeBuffer = 
new byte[0x28];
 
   79             readBuffer(typeBuffer, 0x28);
 
   82         } 
catch (IOException ex) {
 
   84             throw new TskCoreException(
"Error reading " + filename, ex);
 
   85         } 
catch (TskCoreException ex) {
 
   98     public long getExpectedHashCount() {
 
   99         return expectedHashCount;
 
  108     public boolean doneReading() {
 
  109         return (totalHashesRead >= expectedHashCount);
 
  120     public String getNextHash() throws TskCoreException {
 
  121         if (inputStream == null) {
 
  122             throw new TskCoreException(
"Attempting to read from null inputStream");
 
  125         byte[] hashBytes = 
new byte[16];
 
  126         byte[] divider = 
new byte[2];
 
  129             readBuffer(hashBytes, 16);
 
  130             readBuffer(divider, 2);
 
  132             StringBuilder sb = 
new StringBuilder();
 
  133             for (byte b : hashBytes) {
 
  134                 sb.append(String.format(
"%02x", b));
 
  138             return sb.toString();
 
  139         } 
catch (IOException ex) {
 
  140             throw new TskCoreException(
"Ran out of data while reading Encase hash set " + filename, ex);
 
  148     public final void close() {
 
  149         if (inputStream != null) {
 
  152             } 
catch (IOException ex) {
 
  153                 Logger.getLogger(EncaseHashSetParser.class.getName()).log(Level.SEVERE, 
"Error closing Encase hash set " + filename, ex);
 
  160     private void readBuffer(byte[] buffer, 
int length) 
throws TskCoreException, IOException {
 
  161         if (inputStream == null) {
 
  162             throw new TskCoreException(
"readBuffer called on null inputStream");
 
  164         if (length != inputStream.read(buffer)) {
 
  165             throw new TskCoreException(
"Ran out of data unexpectedly while parsing Encase file " + filename);