protected byte[] digest(final String algorithm, final InputStream in) throws ChecksumException { final MessageDigest md; try { md = MessageDigest.getInstance(algorithm); } catch(NoSuchAlgorithmException e) { throw new ChecksumException(LocaleFactory.localizedString("Checksum failure", "Error"), e.getMessage(), e); } try { byte[] buffer = new byte[16384]; int bytesRead; while((bytesRead = in.read(buffer, 0, buffer.length)) != -1) { md.update(buffer, 0, bytesRead); } } catch(IOException e) { throw new ChecksumException(LocaleFactory.localizedString("Checksum failure", "Error"), e.getMessage(), e); } finally { IOUtils.closeQuietly(in); } return md.digest(); }
@Override public Checksum compute(final String data, final TransferStatus status) throws ChecksumException { try { return this.compute(new ByteArrayInputStream(Hex.decodeHex(data.toCharArray())), status); } catch(DecoderException e) { throw new ChecksumException(LocaleFactory.localizedString("Checksum failure", "Error"), e.getMessage(), e); } }
@Override public Checksum compute(final InputStream in, final TransferStatus status) throws ChecksumException { final InputStream normalized = this.normalize(in, status); final CRC32 crc32 = new CRC32(); try { byte[] buffer = new byte[16384]; int bytesRead; while((bytesRead = normalized.read(buffer, 0, buffer.length)) != -1) { crc32.update(buffer, 0, bytesRead); } } catch(IOException e) { throw new ChecksumException(LocaleFactory.localizedString("Checksum failure", "Error"), e.getMessage(), e); } finally { IOUtils.closeQuietly(normalized); } return new Checksum(HashAlgorithm.crc32, Long.toHexString(crc32.getValue())); } }
@Override protected void verify(final Path file, final MessageDigest digest, final Checksum checksum) throws ChecksumException { if(null == digest) { log.debug(String.format("Digest verification disabled for file %s", file)); return; } if(file.getType().contains(Path.Type.encrypted)) { log.warn(String.format("Skip checksum verification for %s with client side encryption enabled", file)); return; } final String expected = Hex.encodeHexString(digest.digest()); if(!checksum.equals(Checksum.parse(expected))) { throw new ChecksumException(MessageFormat.format(LocaleFactory.localizedString("Upload {0} failed", "Error"), file.getName()), MessageFormat.format("Mismatch between {0} hash {1} of uploaded data and ETag {2} returned by the server", checksum.algorithm.toString(), expected, checksum.hash)); } }
protected void verify(final Path file, final MessageDigest digest, final Checksum checksum) throws ChecksumException { if(file.getType().contains(Path.Type.encrypted)) { log.warn(String.format("Skip checksum verification for %s with client side encryption enabled", file)); return; } if(null == digest) { log.debug(String.format("Digest disabled for file %s", file)); return; } if(null == checksum) { log.warn("ETag returned by server is unknown checksum algorithm"); return; } if(!checksum.algorithm.equals(HashAlgorithm.md5)) { log.warn(String.format("ETag %s returned by server is %s but expected MD5", checksum.hash, checksum.algorithm)); return; } // Obtain locally-calculated MD5 hash. final String expected = Hex.encodeHexString(digest.digest()); // Compare our locally-calculated hash with the ETag returned by S3. if(!checksum.equals(Checksum.parse(expected))) { throw new ChecksumException(MessageFormat.format(LocaleFactory.localizedString("Upload {0} failed", "Error"), file.getName()), MessageFormat.format("Mismatch between MD5 hash {0} of uploaded data and ETag {1} returned by the server", expected, checksum.hash)); } }
protected byte[] digest(final String algorithm, final InputStream in) throws ChecksumException { final MD5 md = new MD5(); try { byte[] buffer = new byte[16384]; int bytesRead; while((bytesRead = in.read(buffer, 0, buffer.length)) != -1) { md.Update(buffer, 0, bytesRead); } } catch(IOException e) { throw new ChecksumException(LocaleFactory.localizedString("Checksum failure", "Error"), e.getMessage(), e); } finally { IOUtils.closeQuietly(in); } return md.Final(); }
return new ChecksumException(buffer.toString(), e);
throw new ChecksumException(MessageFormat.format(LocaleFactory.localizedString("Upload {0} failed", "Error"), file.getName()), MessageFormat.format("Mismatch between MD5 hash {0} of uploaded data and ETag {1} returned by the server", expected, reference));
throw new ChecksumException(LocaleFactory.localizedString("Checksum failure", "Error"), e.getMessage(), e); throw new ChecksumException(LocaleFactory.localizedString("Checksum failure", "Error"), e.getMessage(), e);
throw new ChecksumException(MessageFormat.format(LocaleFactory.localizedString("Upload {0} failed", "Error"), file.getName()), MessageFormat.format("Mismatch between MD5 hash {0} of uploaded data and ETag {1} returned by the server", expected, reference));
protected InputStream normalize(final InputStream in, final TransferStatus status) throws ChecksumException { try { final InputStream bounded = status.getLength() > 0 ? new BoundedInputStream(in, status.getOffset() + status.getLength()) : in; return status.getOffset() > 0 ? StreamCopier.skip(bounded, status.getOffset()) : bounded; } catch(BackgroundException e) { throw new ChecksumException(LocaleFactory.localizedString("Checksum failure", "Error"), e.getMessage(), e); } } }
final Checksum download = compute.compute(local.getInputStream(), new TransferStatus()); if(!checksum.equals(download)) { throw new ChecksumException( MessageFormat.format(LocaleFactory.localizedString("Download {0} failed", "Error"), file.getName()), MessageFormat.format(LocaleFactory.localizedString("Mismatch between {0} hash {1} of downloaded data and checksum {2} returned by the server", "Error"),
final Checksum expected = ChecksumComputeFactory.get(fingerprint.algorithm).compute(local.getInputStream(), copy); if(!expected.equals(fingerprint)) { throw new ChecksumException(MessageFormat.format(LocaleFactory.localizedString("Upload {0} failed", "Error"), file.getName()), MessageFormat.format("Mismatch between {0} hash {1} of uploaded data and ETag {2} returned by the server", fingerprint.algorithm.toString(), expected, fingerprint.hash));