use of org.apache.poi.util.BoundedInputStream in project poi by apache.
the class ExOleObjStg method getData.
/**
* Opens an input stream which will decompress the data on the fly.
*
* @return the data input stream.
*/
public InputStream getData() {
if (isCompressed()) {
int size = LittleEndian.getInt(_data);
InputStream compressedStream = new ByteArrayInputStream(_data, 4, _data.length);
return new BoundedInputStream(new InflaterInputStream(compressedStream), size);
} else {
return new ByteArrayInputStream(_data, 0, _data.length);
}
}
use of org.apache.poi.util.BoundedInputStream in project poi by apache.
the class TestEncryptor method agileEncryption.
@Test
public void agileEncryption() throws Exception {
int maxKeyLen = Cipher.getMaxAllowedKeyLength("AES");
Assume.assumeTrue("Please install JCE Unlimited Strength Jurisdiction Policy files for AES 256", maxKeyLen == 2147483647);
File file = POIDataSamples.getDocumentInstance().getFile("bug53475-password-is-pass.docx");
String pass = "pass";
NPOIFSFileSystem nfs = new NPOIFSFileSystem(file);
// Check the encryption details
EncryptionInfo infoExpected = new EncryptionInfo(nfs);
Decryptor decExpected = Decryptor.getInstance(infoExpected);
boolean passed = decExpected.verifyPassword(pass);
assertTrue("Unable to process: document is encrypted", passed);
// extract the payload
InputStream is = decExpected.getDataStream(nfs);
byte[] payloadExpected = IOUtils.toByteArray(is);
is.close();
long decPackLenExpected = decExpected.getLength();
assertEquals(decPackLenExpected, payloadExpected.length);
is = nfs.getRoot().createDocumentInputStream(Decryptor.DEFAULT_POIFS_ENTRY);
// ignore padding block
is = new BoundedInputStream(is, is.available() - 16);
byte[] encPackExpected = IOUtils.toByteArray(is);
is.close();
// listDir(nfs.getRoot(), "orig", "");
nfs.close();
// check that same verifier/salt lead to same hashes
byte[] verifierSaltExpected = infoExpected.getVerifier().getSalt();
byte[] verifierExpected = decExpected.getVerifier();
byte[] keySalt = infoExpected.getHeader().getKeySalt();
byte[] keySpec = decExpected.getSecretKey().getEncoded();
byte[] integritySalt = decExpected.getIntegrityHmacKey();
// the hmacs of the file always differ, as we use PKCS5-padding to pad the bytes
// whereas office just uses random bytes
// byte integrityHash[] = d.getIntegrityHmacValue();
POIFSFileSystem fs = new POIFSFileSystem();
EncryptionInfo infoActual = new EncryptionInfo(EncryptionMode.agile, infoExpected.getVerifier().getCipherAlgorithm(), infoExpected.getVerifier().getHashAlgorithm(), infoExpected.getHeader().getKeySize(), infoExpected.getHeader().getBlockSize(), infoExpected.getVerifier().getChainingMode());
Encryptor e = Encryptor.getInstance(infoActual);
e.confirmPassword(pass, keySpec, keySalt, verifierExpected, verifierSaltExpected, integritySalt);
OutputStream os = e.getDataStream(fs);
IOUtils.copy(new ByteArrayInputStream(payloadExpected), os);
os.close();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
fs.writeFilesystem(bos);
fs.close();
nfs = new NPOIFSFileSystem(new ByteArrayInputStream(bos.toByteArray()));
infoActual = new EncryptionInfo(nfs.getRoot());
Decryptor decActual = Decryptor.getInstance(infoActual);
passed = decActual.verifyPassword(pass);
assertTrue("Unable to process: document is encrypted", passed);
// extract the payload
is = decActual.getDataStream(nfs);
byte[] payloadActual = IOUtils.toByteArray(is);
is.close();
long decPackLenActual = decActual.getLength();
is = nfs.getRoot().createDocumentInputStream(Decryptor.DEFAULT_POIFS_ENTRY);
// ignore padding block
is = new BoundedInputStream(is, is.available() - 16);
byte[] encPackActual = IOUtils.toByteArray(is);
is.close();
// listDir(nfs.getRoot(), "copy", "");
nfs.close();
AgileEncryptionHeader aehExpected = (AgileEncryptionHeader) infoExpected.getHeader();
AgileEncryptionHeader aehActual = (AgileEncryptionHeader) infoActual.getHeader();
assertArrayEquals(aehExpected.getEncryptedHmacKey(), aehActual.getEncryptedHmacKey());
assertEquals(decPackLenExpected, decPackLenActual);
assertArrayEquals(payloadExpected, payloadActual);
assertArrayEquals(encPackExpected, encPackActual);
}
use of org.apache.poi.util.BoundedInputStream in project poi by apache.
the class CryptoAPIDecryptor method getSummaryEntries.
/**
* Decrypt the Document-/SummaryInformation and other optionally streams.
* Opposed to other crypto modes, cryptoapi is record based and can't be used
* to stream-decrypt a whole file
*
* @see <a href="http://msdn.microsoft.com/en-us/library/dd943321(v=office.12).aspx">2.3.5.4 RC4 CryptoAPI Encrypted Summary Stream</a>
*/
public POIFSFileSystem getSummaryEntries(DirectoryNode root, String encryptedStream) throws IOException, GeneralSecurityException {
// HSLF: encryptedStream
// HSSF: encryption
DocumentNode es = (DocumentNode) root.getEntry(encryptedStream);
DocumentInputStream dis = root.createDocumentInputStream(es);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
IOUtils.copy(dis, bos);
dis.close();
CryptoAPIDocumentInputStream sbis = new CryptoAPIDocumentInputStream(this, bos.toByteArray());
LittleEndianInputStream leis = new LittleEndianInputStream(sbis);
POIFSFileSystem fsOut = null;
try {
int streamDescriptorArrayOffset = (int) leis.readUInt();
/* int streamDescriptorArraySize = (int) */
leis.readUInt();
long skipN = streamDescriptorArrayOffset - 8L;
if (sbis.skip(skipN) < skipN) {
throw new EOFException("buffer underrun");
}
sbis.setBlock(0);
int encryptedStreamDescriptorCount = (int) leis.readUInt();
StreamDescriptorEntry[] entries = new StreamDescriptorEntry[encryptedStreamDescriptorCount];
for (int i = 0; i < encryptedStreamDescriptorCount; i++) {
StreamDescriptorEntry entry = new StreamDescriptorEntry();
entries[i] = entry;
entry.streamOffset = (int) leis.readUInt();
entry.streamSize = (int) leis.readUInt();
entry.block = leis.readUShort();
int nameSize = leis.readUByte();
entry.flags = leis.readUByte();
// boolean isStream = StreamDescriptorEntry.flagStream.isSet(entry.flags);
entry.reserved2 = leis.readInt();
entry.streamName = StringUtil.readUnicodeLE(leis, nameSize);
leis.readShort();
assert (entry.streamName.length() == nameSize);
}
// NOSONAR
fsOut = new POIFSFileSystem();
for (StreamDescriptorEntry entry : entries) {
sbis.seek(entry.streamOffset);
sbis.setBlock(entry.block);
InputStream is = new BoundedInputStream(sbis, entry.streamSize);
fsOut.createDocument(is, entry.streamName);
is.close();
}
} catch (Exception e) {
IOUtils.closeQuietly(fsOut);
if (e instanceof GeneralSecurityException) {
throw (GeneralSecurityException) e;
} else if (e instanceof IOException) {
throw (IOException) e;
} else {
throw new IOException("summary entries can't be read", e);
}
} finally {
IOUtils.closeQuietly(leis);
IOUtils.closeQuietly(sbis);
}
return fsOut;
}
use of org.apache.poi.util.BoundedInputStream in project poi by apache.
the class StandardDecryptor method getDataStream.
@Override
@SuppressWarnings("resource")
public InputStream getDataStream(DirectoryNode dir) throws IOException {
DocumentInputStream dis = dir.createDocumentInputStream(DEFAULT_POIFS_ENTRY);
_length = dis.readLong();
if (getSecretKey() == null) {
verifyPassword(null);
}
// limit wrong calculated ole entries - (bug #57080)
// standard encryption always uses aes encoding, so blockSize is always 16
// http://stackoverflow.com/questions/3283787/size-of-data-after-aes-encryption
int blockSize = getEncryptionInfo().getHeader().getCipherAlgorithm().blockSize;
long cipherLen = (_length / blockSize + 1) * blockSize;
Cipher cipher = getCipher(getSecretKey());
InputStream boundedDis = new BoundedInputStream(dis, cipherLen);
return new BoundedInputStream(new CipherInputStream(boundedDis, cipher), _length);
}
Aggregations