Autopsy  4.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
E01VerifyIngestModule.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2013-2014 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.modules.e01verify;
20 
21 import java.security.MessageDigest;
22 import java.security.NoSuchAlgorithmException;
23 import java.util.logging.Level;
24 import javax.xml.bind.DatatypeConverter;
25 import org.openide.util.NbBundle;
26 import org.python.bouncycastle.util.Arrays;
38 import org.openide.util.NbBundle;
39 
45 @NbBundle.Messages({
46  "UnableToCalculateHashes=Unable to calculate MD5 hashes."
47 })
49 
50  private static final Logger logger = Logger.getLogger(E01VerifyIngestModule.class.getName());
51  private static final long DEFAULT_CHUNK_SIZE = 32 * 1024;
52  private static final IngestServices services = IngestServices.getInstance();
53 
54  private MessageDigest messageDigest;
55  private boolean verified = false;
56  private String calculatedHash = "";
57  private String storedHash = "";
59 
61  }
62 
63  @Override
64  public void startUp(IngestJobContext context) throws IngestModuleException {
65  this.context = context;
66  verified = false;
67  storedHash = "";
68  calculatedHash = "";
69 
70  try {
71  messageDigest = MessageDigest.getInstance("MD5"); //NON-NLS
72  } catch (NoSuchAlgorithmException ex) {
73  throw new IngestModuleException(Bundle.UnableToCalculateHashes(), ex);
74  }
75  }
76 
77  @Override
78  public ProcessResult process(Content dataSource, DataSourceIngestModuleProgress statusHelper) {
79  String imgName = dataSource.getName();
80 
81  // Skip non-images
82  if (!(dataSource instanceof Image)) {
83  logger.log(Level.INFO, "Skipping non-image {0}", imgName); //NON-NLS
85  NbBundle.getMessage(this.getClass(),
86  "EwfVerifyIngestModule.process.skipNonEwf",
87  imgName)));
88  return ProcessResult.OK;
89  }
90  Image img = (Image) dataSource;
91 
92  // Skip images that are not E01
94  logger.log(Level.INFO, "Skipping non-ewf image {0}", imgName); //NON-NLS
96  NbBundle.getMessage(this.getClass(),
97  "EwfVerifyIngestModule.process.skipNonEwf",
98  imgName)));
99  return ProcessResult.OK;
100  }
101 
102  // Report an error for null or empty MD5
103  if ((img.getMd5() == null) || img.getMd5().isEmpty()) {
105  NbBundle.getMessage(this.getClass(),
106  "EwfVerifyIngestModule.process.noStoredHash",
107  imgName)));
108  return ProcessResult.ERROR;
109  }
110 
111  storedHash = img.getMd5().toLowerCase();
112  logger.log(Level.INFO, "Hash value stored in {0}: {1}", new Object[]{imgName, storedHash}); //NON-NLS
113 
114  logger.log(Level.INFO, "Starting hash verification of {0}", img.getName()); //NON-NLS
116  NbBundle.getMessage(this.getClass(),
117  "EwfVerifyIngestModule.process.startingImg",
118  imgName)));
119 
120  long size = img.getSize();
121  if (size == 0) {
122  logger.log(Level.WARNING, "Size of image {0} was 0 when queried.", imgName); //NON-NLS
124  NbBundle.getMessage(this.getClass(),
125  "EwfVerifyIngestModule.process.errGetSizeOfImg",
126  imgName)));
127  }
128 
129  // Libewf uses a sector size of 64 times the sector size, which is the
130  // motivation for using it here.
131  long chunkSize = 64 * img.getSsize();
132  chunkSize = (chunkSize == 0) ? DEFAULT_CHUNK_SIZE : chunkSize;
133 
134  // Casting to double to capture decimals
135  int totalChunks = (int) Math.ceil((double) size / (double) chunkSize);
136  logger.log(Level.INFO, "Total chunks = {0}", totalChunks); //NON-NLS
137  int read;
138 
139  byte[] data = new byte[(int) chunkSize];
140  statusHelper.switchToDeterminate(totalChunks);
141 
142  // Read in byte size chunks and update the hash value with the data.
143  for (int i = 0; i < totalChunks; i++) {
144  if (context.dataSourceIngestIsCancelled()) {
145  return ProcessResult.OK;
146  }
147  try {
148  read = img.read(data, i * chunkSize, chunkSize);
149  } catch (TskCoreException ex) {
150  String msg = NbBundle.getMessage(this.getClass(),
151  "EwfVerifyIngestModule.process.errReadImgAtChunk", imgName, i);
153  logger.log(Level.SEVERE, msg, ex);
154  return ProcessResult.ERROR;
155  }
156 
157  // Only update with the read bytes.
158  if (read == chunkSize) {
159  messageDigest.update(data);
160  } else {
161  byte[] subData = Arrays.copyOfRange(data, 0, read);
162  messageDigest.update(subData);
163  }
164  statusHelper.progress(i);
165  }
166 
167  // Finish generating the hash and get it as a string value
168  calculatedHash = DatatypeConverter.printHexBinary(messageDigest.digest()).toLowerCase();
169  verified = calculatedHash.equals(storedHash);
170  logger.log(Level.INFO, "Hash calculated from {0}: {1}", new Object[]{imgName, calculatedHash}); //NON-NLS
171 
172  logger.log(Level.INFO, "complete() {0}", E01VerifierModuleFactory.getModuleName()); //NON-NLS
173  String msg;
174  if (verified) {
175  msg = NbBundle.getMessage(this.getClass(), "EwfVerifyIngestModule.shutDown.verified");
176  } else {
177  msg = NbBundle.getMessage(this.getClass(), "EwfVerifyIngestModule.shutDown.notVerified");
178  }
179  String extra = NbBundle
180  .getMessage(this.getClass(), "EwfVerifyIngestModule.shutDown.verifyResultsHeader", imgName);
181  extra += NbBundle.getMessage(this.getClass(), "EwfVerifyIngestModule.shutDown.resultLi", msg);
182  extra += NbBundle.getMessage(this.getClass(), "EwfVerifyIngestModule.shutDown.calcHashLi", calculatedHash);
183  extra += NbBundle.getMessage(this.getClass(), "EwfVerifyIngestModule.shutDown.storedHashLi", storedHash);
184  services.postMessage(IngestMessage.createMessage(MessageType.INFO, E01VerifierModuleFactory.getModuleName(), imgName + msg, extra));
185  logger.log(Level.INFO, "{0}{1}", new Object[]{imgName, msg});
186 
187  return ProcessResult.OK;
188  }
189 }
TskData.TSK_IMG_TYPE_ENUM getType()
static IngestMessage createMessage(MessageType messageType, String source, String subject, String detailsHtml)
int read(byte[] buf, long offset, long len)
void postMessage(final IngestMessage message)
ProcessResult process(Content dataSource, DataSourceIngestModuleProgress statusHelper)
synchronized static Logger getLogger(String name)
Definition: Logger.java:161
static synchronized IngestServices getInstance()

Copyright © 2012-2016 Basis Technology. Generated on: Mon Apr 24 2017
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.