use of org.apache.poi.poifs.filesystem.POIFSFileSystem in project poi by apache.
the class TestHSSFEventFactory method testUnknownContinueRecords.
/**
* Unknown records can be continued.
* Check that HSSFEventFactory doesn't break on them.
* (the test file was provided in a reopen of bug #42844)
*/
public void testUnknownContinueRecords() throws Exception {
HSSFRequest req = new HSSFRequest();
MockHSSFListener mockListen = new MockHSSFListener();
req.addListenerForAllRecords(mockListen);
POIFSFileSystem fs = new POIFSFileSystem(openSample("42844.xls"));
HSSFEventFactory factory = new HSSFEventFactory();
factory.processWorkbookEvents(req, fs);
}
use of org.apache.poi.poifs.filesystem.POIFSFileSystem 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.poifs.filesystem.POIFSFileSystem in project poi by apache.
the class TestEncryptor method standardEncryption.
@Test
public void standardEncryption() throws Exception {
File file = POIDataSamples.getDocumentInstance().getFile("bug53475-password-is-solrcell.docx");
String pass = "solrcell";
NPOIFSFileSystem nfs = new NPOIFSFileSystem(file);
// Check the encryption details
EncryptionInfo infoExpected = new EncryptionInfo(nfs);
Decryptor d = Decryptor.getInstance(infoExpected);
boolean passed = d.verifyPassword(pass);
assertTrue("Unable to process: document is encrypted", passed);
// extract the payload
ByteArrayOutputStream bos = new ByteArrayOutputStream();
InputStream is = d.getDataStream(nfs);
IOUtils.copy(is, bos);
is.close();
nfs.close();
byte[] payloadExpected = bos.toByteArray();
// check that same verifier/salt lead to same hashes
byte[] verifierSaltExpected = infoExpected.getVerifier().getSalt();
byte[] verifierExpected = d.getVerifier();
byte[] keySpec = d.getSecretKey().getEncoded();
byte[] keySalt = infoExpected.getHeader().getKeySalt();
EncryptionInfo infoActual = new EncryptionInfo(EncryptionMode.standard, 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, null);
assertArrayEquals(infoExpected.getVerifier().getEncryptedVerifier(), infoActual.getVerifier().getEncryptedVerifier());
assertArrayEquals(infoExpected.getVerifier().getEncryptedVerifierHash(), infoActual.getVerifier().getEncryptedVerifierHash());
// now we use a newly generated salt/verifier and check
// if the file content is still the same
infoActual = new EncryptionInfo(EncryptionMode.standard, infoExpected.getVerifier().getCipherAlgorithm(), infoExpected.getVerifier().getHashAlgorithm(), infoExpected.getHeader().getKeySize(), infoExpected.getHeader().getBlockSize(), infoExpected.getVerifier().getChainingMode());
e = Encryptor.getInstance(infoActual);
e.confirmPassword(pass);
POIFSFileSystem fs = new POIFSFileSystem();
OutputStream os = e.getDataStream(fs);
IOUtils.copy(new ByteArrayInputStream(payloadExpected), os);
os.close();
bos.reset();
fs.writeFilesystem(bos);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
// FileOutputStream fos = new FileOutputStream("encrypted.docx");
// IOUtils.copy(bis, fos);
// fos.close();
// bis.reset();
nfs = new NPOIFSFileSystem(bis);
infoExpected = new EncryptionInfo(nfs);
d = Decryptor.getInstance(infoExpected);
passed = d.verifyPassword(pass);
assertTrue("Unable to process: document is encrypted", passed);
bos.reset();
is = d.getDataStream(nfs);
IOUtils.copy(is, bos);
is.close();
nfs.close();
byte[] payloadActual = bos.toByteArray();
assertArrayEquals(payloadExpected, payloadActual);
}
use of org.apache.poi.poifs.filesystem.POIFSFileSystem in project poi by apache.
the class TestEncryptor method bug60320CustomEncrypt.
/*
* this test simulates the generation of bugs 60320 sample file
* as the padding bytes of the EncryptedPackage stream are random or in POIs case PKCS5-padded
* one would need to mock those bytes to get the same hmacValues - see diff below
*
* this use-case is experimental - for the time being the setters of the encryption classes
* are spreaded between two packages and are protected - so you would need to violate
* the packages rules and provide a helper class in the *poifs.crypt package-namespace.
* the default way of defining the encryption settings is via the EncryptionInfo class
*/
@Test
public void bug60320CustomEncrypt() throws Exception {
int maxKeyLen = Cipher.getMaxAllowedKeyLength("AES");
Assume.assumeTrue("Please install JCE Unlimited Strength Jurisdiction Policy files for AES 256", maxKeyLen == 2147483647);
// --- src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java (revision 1766745)
// +++ src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java (working copy)
// @@ -208,6 +208,13 @@
// protected int invokeCipher(int posInChunk, boolean doFinal) throws GeneralSecurityException {
// byte plain[] = (_plainByteFlags.isEmpty()) ? null : _chunk.clone();
//
// + if (posInChunk < 4096) {
// + _cipher.update(_chunk, 0, posInChunk, _chunk);
// + byte bla[] = { (byte)0x7A,(byte)0x0F,(byte)0x27,(byte)0xF0,(byte)0x17,(byte)0x6E,(byte)0x77,(byte)0x05,(byte)0xB9,(byte)0xDA,(byte)0x49,(byte)0xF9,(byte)0xD7,(byte)0x8E,(byte)0x03,(byte)0x1D };
// + System.arraycopy(bla, 0, _chunk, posInChunk-2, bla.length);
// + return posInChunk-2+bla.length;
// + }
// +
// int ciLen = (doFinal)
// ? _cipher.doFinal(_chunk, 0, posInChunk, _chunk)
// : _cipher.update(_chunk, 0, posInChunk, _chunk);
//
// --- src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileDecryptor.java (revision 1766745)
// +++ src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileDecryptor.java (working copy)
//
// @@ -300,7 +297,7 @@
// protected static Cipher initCipherForBlock(Cipher existing, int block, boolean lastChunk, EncryptionInfo encryptionInfo, SecretKey skey, int encryptionMode)
// throws GeneralSecurityException {
// EncryptionHeader header = encryptionInfo.getHeader();
// - String padding = (lastChunk ? "PKCS5Padding" : "NoPadding");
// + String padding = "NoPadding"; // (lastChunk ? "PKCS5Padding" : "NoPadding");
// if (existing == null || !existing.getAlgorithm().endsWith(padding)) {
// existing = getCipher(skey, header.getCipherAlgorithm(), header.getChainingMode(), header.getKeySalt(), encryptionMode, padding);
// }
InputStream is = POIDataSamples.getPOIFSInstance().openResourceAsStream("60320-protected.xlsx");
POIFSFileSystem fsOrig = new POIFSFileSystem(is);
is.close();
EncryptionInfo infoOrig = new EncryptionInfo(fsOrig);
Decryptor decOrig = infoOrig.getDecryptor();
boolean b = decOrig.verifyPassword("Test001!!");
assertTrue(b);
InputStream decIn = decOrig.getDataStream(fsOrig);
byte[] zipInput = IOUtils.toByteArray(decIn);
decIn.close();
InputStream epOrig = fsOrig.getRoot().createDocumentInputStream("EncryptedPackage");
// ignore the 16 padding bytes
byte[] epOrigBytes = IOUtils.toByteArray(epOrig, 9400);
epOrig.close();
EncryptionInfo eiNew = new EncryptionInfo(EncryptionMode.agile);
AgileEncryptionHeader aehHeader = (AgileEncryptionHeader) eiNew.getHeader();
aehHeader.setCipherAlgorithm(CipherAlgorithm.aes128);
aehHeader.setHashAlgorithm(HashAlgorithm.sha1);
AgileEncryptionVerifier aehVerifier = (AgileEncryptionVerifier) eiNew.getVerifier();
// this cast might look strange - if the setters would be public, it will become obsolete
// see http://stackoverflow.com/questions/5637650/overriding-protected-methods-in-java
((EncryptionVerifier) aehVerifier).setCipherAlgorithm(CipherAlgorithm.aes256);
aehVerifier.setHashAlgorithm(HashAlgorithm.sha512);
Encryptor enc = eiNew.getEncryptor();
enc.confirmPassword("Test001!!", infoOrig.getDecryptor().getSecretKey().getEncoded(), infoOrig.getHeader().getKeySalt(), infoOrig.getDecryptor().getVerifier(), infoOrig.getVerifier().getSalt(), infoOrig.getDecryptor().getIntegrityHmacKey());
NPOIFSFileSystem fsNew = new NPOIFSFileSystem();
OutputStream os = enc.getDataStream(fsNew);
os.write(zipInput);
os.close();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
fsNew.writeFilesystem(bos);
fsNew.close();
NPOIFSFileSystem fsReload = new NPOIFSFileSystem(new ByteArrayInputStream(bos.toByteArray()));
InputStream epReload = fsReload.getRoot().createDocumentInputStream("EncryptedPackage");
byte[] epNewBytes = IOUtils.toByteArray(epReload, 9400);
epReload.close();
assertArrayEquals(epOrigBytes, epNewBytes);
EncryptionInfo infoReload = new EncryptionInfo(fsOrig);
Decryptor decReload = infoReload.getDecryptor();
b = decReload.verifyPassword("Test001!!");
assertTrue(b);
AgileEncryptionHeader aehOrig = (AgileEncryptionHeader) infoOrig.getHeader();
AgileEncryptionHeader aehReload = (AgileEncryptionHeader) infoReload.getHeader();
assertEquals(aehOrig.getBlockSize(), aehReload.getBlockSize());
assertEquals(aehOrig.getChainingMode(), aehReload.getChainingMode());
assertEquals(aehOrig.getCipherAlgorithm(), aehReload.getCipherAlgorithm());
assertEquals(aehOrig.getCipherProvider(), aehReload.getCipherProvider());
assertEquals(aehOrig.getCspName(), aehReload.getCspName());
assertArrayEquals(aehOrig.getEncryptedHmacKey(), aehReload.getEncryptedHmacKey());
// this only works, when the paddings are mocked to be the same ...
// assertArrayEquals(aehOrig.getEncryptedHmacValue(), aehReload.getEncryptedHmacValue());
assertEquals(aehOrig.getFlags(), aehReload.getFlags());
assertEquals(aehOrig.getHashAlgorithm(), aehReload.getHashAlgorithm());
assertArrayEquals(aehOrig.getKeySalt(), aehReload.getKeySalt());
assertEquals(aehOrig.getKeySize(), aehReload.getKeySize());
AgileEncryptionVerifier aevOrig = (AgileEncryptionVerifier) infoOrig.getVerifier();
AgileEncryptionVerifier aevReload = (AgileEncryptionVerifier) infoReload.getVerifier();
assertEquals(aevOrig.getBlockSize(), aevReload.getBlockSize());
assertEquals(aevOrig.getChainingMode(), aevReload.getChainingMode());
assertEquals(aevOrig.getCipherAlgorithm(), aevReload.getCipherAlgorithm());
assertArrayEquals(aevOrig.getEncryptedKey(), aevReload.getEncryptedKey());
assertArrayEquals(aevOrig.getEncryptedVerifier(), aevReload.getEncryptedVerifier());
assertArrayEquals(aevOrig.getEncryptedVerifierHash(), aevReload.getEncryptedVerifierHash());
assertEquals(aevOrig.getHashAlgorithm(), aevReload.getHashAlgorithm());
assertEquals(aevOrig.getKeySize(), aevReload.getKeySize());
assertArrayEquals(aevOrig.getSalt(), aevReload.getSalt());
assertEquals(aevOrig.getSpinCount(), aevReload.getSpinCount());
AgileDecryptor adOrig = (AgileDecryptor) infoOrig.getDecryptor();
AgileDecryptor adReload = (AgileDecryptor) infoReload.getDecryptor();
assertArrayEquals(adOrig.getIntegrityHmacKey(), adReload.getIntegrityHmacKey());
// doesn't work without mocking ... see above
// assertArrayEquals(adOrig.getIntegrityHmacValue(), adReload.getIntegrityHmacValue());
assertArrayEquals(adOrig.getSecretKey().getEncoded(), adReload.getSecretKey().getEncoded());
assertArrayEquals(adOrig.getVerifier(), adReload.getVerifier());
fsReload.close();
}
use of org.apache.poi.poifs.filesystem.POIFSFileSystem in project poi by apache.
the class TestSecureTempZip method protectedTempZip.
/**
* Test case for #59841 - this is an example on how to use encrypted temp files,
* which are streamed into POI opposed to having everything in memory
*/
@Test
public void protectedTempZip() throws IOException, GeneralSecurityException, XmlException, OpenXML4JException {
File tikaProt = XSSFTestDataSamples.getSampleFile("protected_passtika.xlsx");
FileInputStream fis = new FileInputStream(tikaProt);
POIFSFileSystem poifs = new POIFSFileSystem(fis);
EncryptionInfo ei = new EncryptionInfo(poifs);
Decryptor dec = ei.getDecryptor();
boolean passOk = dec.verifyPassword("tika");
assertTrue(passOk);
// extract encrypted ooxml file and write to custom encrypted zip file
InputStream is = dec.getDataStream(poifs);
// provide ZipEntrySource to poi which decrypts on the fly
ZipEntrySource source = AesZipFileZipEntrySource.createZipEntrySource(is);
// test the source
OPCPackage opc = OPCPackage.open(source);
String expected = "This is an Encrypted Excel spreadsheet.";
XSSFEventBasedExcelExtractor extractor = new XSSFEventBasedExcelExtractor(opc);
extractor.setIncludeSheetNames(false);
String txt = extractor.getText();
assertEquals(expected, txt.trim());
XSSFWorkbook wb = new XSSFWorkbook(opc);
txt = wb.getSheetAt(0).getRow(0).getCell(0).getStringCellValue();
assertEquals(expected, txt);
extractor.close();
wb.close();
opc.close();
source.close();
poifs.close();
fis.close();
}
Aggregations