19 package org.sleuthkit.autopsy.modules.dataSourceIntegrity;
 
   21 import java.security.MessageDigest;
 
   22 import java.security.NoSuchAlgorithmException;
 
   23 import java.util.ArrayList;
 
   24 import java.util.List;
 
   25 import java.util.logging.Level;
 
   26 import java.util.Arrays;
 
   27 import org.apache.commons.codec.binary.Hex;
 
   38 import org.openide.util.NbBundle;
 
   66         computeHashes = settings.shouldComputeHashes();
 
   67         verifyHashes = settings.shouldVerifyHashes();
 
   71         "DataSourceIntegrityIngestModule.startup.noCheckboxesSelected=At least one of the checkboxes must be selected" 
   78         if (!(computeHashes || verifyHashes)) {
 
   79             throw new IngestModuleException(Bundle.DataSourceIntegrityIngestModule_startup_noCheckboxesSelected());
 
   85         "DataSourceIntegrityIngestModule.process.skipCompute=Not computing new hashes for {0} since the option was disabled",
 
   87         "DataSourceIntegrityIngestModule.process.skipVerify=Not verifying existing hashes for {0} since the option was disabled",
 
   89         "DataSourceIntegrityIngestModule.process.hashAlgorithmError=Error creating message digest for {0} algorithm",
 
   91         "DataSourceIntegrityIngestModule.process.hashMatch=<li>{0} hash verified </li>",
 
   93         "DataSourceIntegrityIngestModule.process.hashNonMatch=<li>{0} hash not verified </li>",
 
   94         "# {0} - calculatedHashValue",
 
   95         "# {1} - storedHashValue",
 
   96         "DataSourceIntegrityIngestModule.process.hashList=<ul><li>Calculated hash: {0} </li><li>Stored hash: {1} </li></ul>",
 
   98         "# {1} - calculatedHashValue",
 
   99         "DataSourceIntegrityIngestModule.process.calcHashWithType=<li>Calculated {0} hash: {1} </li>",
 
  101         "DataSourceIntegrityIngestModule.process.calculateHashDone=<p>Data Source Hash Calculation Results for {0} </p>",
 
  102         "DataSourceIntegrityIngestModule.process.hashesCalculated= hashes calculated",
 
  104         "DataSourceIntegrityIngestModule.process.errorSavingHashes= Error saving hashes for image {0} to the database",
 
  106         "DataSourceIntegrityIngestModule.process.errorLoadingHashes= Error loading hashes for image {0} from the database",
 
  107         "# {0} - hashAlgorithm",
 
  108         "# {1} - calculatedHashValue",
 
  109         "# {2} - storedHashValue",
 
  110         "DataSourceIntegrityIngestModule.process.hashFailedForArtifact={0} hash verification failed:\n  Calculated hash: {1}\n  Stored hash: {2}\n",
 
  112         "DataSourceIntegrityIngestModule.process.verificationSuccess=Integrity of {0} verified",
 
  114         "DataSourceIntegrityIngestModule.process.verificationFailure={0} failed integrity verification",})
 
  117         String imgName = dataSource.
getName();
 
  120         if (!(dataSource instanceof 
Image)) {
 
  121             logger.log(Level.INFO, 
"Skipping non-image {0}", imgName); 
 
  123                     NbBundle.getMessage(this.getClass(),
 
  124                             "DataSourceIntegrityIngestModule.process.skipNonEwf",
 
  128         Image img = (Image) dataSource;
 
  133             logger.log(Level.WARNING, 
"Size of image {0} was 0 when queried.", imgName); 
 
  151             String msg = Bundle.DataSourceIntegrityIngestModule_process_errorLoadingHashes(imgName);
 
  153             logger.log(Level.SEVERE, msg, ex);
 
  159         if (hashDataList.isEmpty()) {
 
  167             logger.log(Level.INFO, 
"Not computing hashes for {0} since the option was disabled", imgName); 
 
  169                     Bundle.DataSourceIntegrityIngestModule_process_skipCompute(imgName)));
 
  172             logger.log(Level.INFO, 
"Not verifying hashes for {0} since the option was disabled", imgName); 
 
  174                     Bundle.DataSourceIntegrityIngestModule_process_skipVerify(imgName)));
 
  182                 hashDataList.add(
new HashData(type, 
""));
 
  187         for (
HashData hashData : hashDataList) {
 
  189                 hashData.digest = MessageDigest.getInstance(hashData.type.getName());
 
  190             } 
catch (NoSuchAlgorithmException ex) {
 
  191                 String msg = Bundle.DataSourceIntegrityIngestModule_process_hashAlgorithmError(hashData.type.getName());
 
  193                 logger.log(Level.SEVERE, msg, ex);
 
  201         long chunkSize = 64 * img.
getSsize();
 
  202         chunkSize = (chunkSize == 0) ? DEFAULT_CHUNK_SIZE : chunkSize;
 
  205         int totalChunks = (int) Math.ceil((
double) size / (
double) chunkSize);
 
  206         logger.log(Level.INFO, 
"Total chunks = {0}", totalChunks); 
 
  209             logger.log(Level.INFO, 
"Starting hash verification of {0}", img.
getName()); 
 
  211             logger.log(Level.INFO, 
"Starting hash calculation for {0}", img.
getName()); 
 
  214                 NbBundle.getMessage(this.getClass(),
 
  215                         "DataSourceIntegrityIngestModule.process.startingImg",
 
  222         byte[] data = 
new byte[(int) chunkSize];
 
  224         for (
int i = 0; i < totalChunks; i++) {
 
  229                 read = img.
read(data, i * chunkSize, chunkSize);
 
  231                 String msg = NbBundle.getMessage(this.getClass(),
 
  232                         "DataSourceIntegrityIngestModule.process.errReadImgAtChunk", imgName, i);
 
  234                 logger.log(Level.SEVERE, msg, ex);
 
  239             if (read == chunkSize) {
 
  240                 for (
HashData struct : hashDataList) {
 
  241                     struct.digest.update(data);
 
  244                 byte[] subData = Arrays.copyOfRange(data, 0, read);
 
  245                 for (
HashData struct : hashDataList) {
 
  246                     struct.digest.update(subData);
 
  253         for(
HashData hashData: hashDataList) {
 
  254             hashData.calculatedHash = Hex.encodeHexString(hashData.digest.digest()).toLowerCase();
 
  255             logger.log(Level.INFO, 
"Hash calculated from {0}: {1}", 
new Object[]{imgName, hashData.calculatedHash}); 
 
  260             boolean verified = 
true;
 
  261             String detailedResults = NbBundle
 
  262                     .getMessage(this.getClass(), 
"DataSourceIntegrityIngestModule.shutDown.verifyResultsHeader", imgName);
 
  263             String hashResults = 
"";
 
  264             String artifactComment = 
"";
 
  266             for (
HashData hashData : hashDataList) {
 
  267                 if (hashData.storedHash.equals(hashData.calculatedHash)) {
 
  268                     hashResults += Bundle.DataSourceIntegrityIngestModule_process_hashMatch(hashData.type.name) + 
" ";
 
  271                     hashResults += Bundle.DataSourceIntegrityIngestModule_process_hashNonMatch(hashData.type.name) + 
" ";
 
  272                     artifactComment += Bundle.DataSourceIntegrityIngestModule_process_hashFailedForArtifact(hashData.type.name,
 
  273                             hashData.calculatedHash, hashData.storedHash) + 
" ";
 
  275                 hashResults += Bundle.DataSourceIntegrityIngestModule_process_hashList(hashData.calculatedHash, hashData.storedHash);
 
  278             String verificationResultStr;
 
  279             String messageResultStr;
 
  283                 verificationResultStr = NbBundle.getMessage(this.getClass(), 
"DataSourceIntegrityIngestModule.shutDown.verified");
 
  284                 messageResultStr = Bundle.DataSourceIntegrityIngestModule_process_verificationSuccess(imgName);
 
  287                 verificationResultStr = NbBundle.getMessage(this.getClass(), 
"DataSourceIntegrityIngestModule.shutDown.notVerified");
 
  288                 messageResultStr = Bundle.DataSourceIntegrityIngestModule_process_verificationFailure(imgName);
 
  291             detailedResults += NbBundle.getMessage(this.getClass(), 
"DataSourceIntegrityIngestModule.shutDown.resultLi", verificationResultStr);
 
  292             detailedResults += hashResults;
 
  300                             null, null, artifactComment,
 
  303                             .getAnalysisResult();
 
  308                     logger.log(Level.SEVERE, 
"Error creating verification failed artifact", ex);
 
  310                     logger.log(Level.SEVERE, 
"Error posting verification failed artifact", ex);
 
  315                     messageResultStr, detailedResults));
 
  320                 String results = Bundle.DataSourceIntegrityIngestModule_process_calculateHashDone(imgName);
 
  322                 for (
HashData hashData : hashDataList) {
 
  323                     switch (hashData.type) {
 
  326                             img.
setMD5(hashData.calculatedHash);
 
  328                             logger.log(Level.SEVERE, 
"Error setting calculated hash", ex);
 
  333                             img.
setSha1(hashData.calculatedHash);
 
  335                             logger.log(Level.SEVERE, 
"Error setting calculated hash", ex);
 
  342                             logger.log(Level.SEVERE, 
"Error setting calculated hash", ex);
 
  348                     results += Bundle.DataSourceIntegrityIngestModule_process_calcHashWithType(hashData.type.name, hashData.calculatedHash);
 
  353                         imgName + Bundle.DataSourceIntegrityIngestModule_process_hashesCalculated(), results));
 
  356                 String msg = Bundle.DataSourceIntegrityIngestModule_process_errorSavingHashes(imgName);
 
  358                 logger.log(Level.SEVERE, 
"Error saving hash for image " + imgName + 
" to database", ex);
 
static final IngestServices services
static final Score SCORE_NOTABLE
org.sleuthkit.datamodel.Blackboard getArtifactsBlackboard()
Blackboard getBlackboard()
static final Logger logger
void setSha1(String sha1)
static IngestMessage createMessage(MessageType messageType, String source, String subject, String detailsHtml)
int read(byte[] buf, long offset, long len)
final List< HashData > hashDataList
static final Type TSK_VERIFICATION_FAILED
void postMessage(final IngestMessage message)
final boolean verifyHashes
SleuthkitCase getSleuthkitCase()
static final long DEFAULT_CHUNK_SIZE
void setSha256(String sha256)
boolean dataSourceIngestIsCancelled()
AnalysisResultAdded newAnalysisResult(BlackboardArtifact.Type artifactType, long objId, Long dataSourceObjId, Score score, String conclusion, String configuration, String justification, Collection< BlackboardAttribute > attributesList)
void switchToDeterminate(int workUnits)
static Case getCurrentCase()
synchronized static Logger getLogger(String name)
final boolean computeHashes
ProcessResult process(Content dataSource, DataSourceIngestModuleProgress statusHelper)
void progress(int workUnits)
void startUp(IngestJobContext context)
static synchronized IngestServices getInstance()