public static boolean copy(InputStream in, OutputStream out, Optional<XFileKey> keyCipher, Optional<byte[]> signature, Optional<IOFunction<InputStream, InputStream>> decompress) throws IOException { Digest digest = signature.flatMap(FileSignature::type) .orElse(FileSignature.ONE) .newDigest(); DigestInputStream dis = new DigestInputStream(in, digest); InputStream fis = decryptStream(dis, keyCipher); if (decompress.isPresent()) { logger.info("-- copy() - decompressing"); fis = decompress.get().apply(fis); } IOUtils.copyLarge(fis, out, new byte[BUFFER_SIZE]); out.flush(); return testSignature(dis.getDigest(), signature); }
public void engineLoad( InputStream stream, char[] password) throws IOException { table.clear(); if (stream == null) // just initialising { return; } DataInputStream dIn = new DataInputStream(stream); int version = dIn.readInt(); if (version != STORE_VERSION) { if (version != 0 && version != 1) { throw new IOException("Wrong version of key store."); } } byte[] salt = new byte[dIn.readInt()]; if (salt.length != STORE_SALT_SIZE) { throw new IOException("Key store corrupted."); } dIn.readFully(salt); int iterationCount = dIn.readInt(); if ((iterationCount < 0) || (iterationCount > 4 * MIN_ITERATIONS)) { throw new IOException("Key store corrupted."); } String cipherAlg; if (version == 0) { cipherAlg = "Old" + STORE_CIPHER; } else { cipherAlg = STORE_CIPHER; } Cipher cipher = this.makePBECipher(cipherAlg, Cipher.DECRYPT_MODE, password, salt, iterationCount); CipherInputStream cIn = new CipherInputStream(dIn, cipher); Digest dig = new SHA1Digest(); DigestInputStream dgIn = new DigestInputStream(cIn, dig); this.loadStore(dgIn); // Finalise our digest calculation byte[] hash = new byte[dig.getDigestSize()]; dig.doFinal(hash, 0); // TODO Should this actually be reading the remainder of the stream? // Read the original digest from the stream byte[] oldHash = new byte[dig.getDigestSize()]; Streams.readFully(cIn, oldHash); if (!Arrays.constantTimeAreEqual(hash, oldHash)) { table.clear(); throw new IOException("KeyStore integrity check failed."); } }