Search in sources :

Example 86 with POIFSFileSystem

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);
}
Also used : POIFSFileSystem(org.apache.poi.poifs.filesystem.POIFSFileSystem)

Example 87 with POIFSFileSystem

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;
}
Also used : DocumentNode(org.apache.poi.poifs.filesystem.DocumentNode) LittleEndianInputStream(org.apache.poi.util.LittleEndianInputStream) ChunkedCipherInputStream(org.apache.poi.poifs.crypt.ChunkedCipherInputStream) BoundedInputStream(org.apache.poi.util.BoundedInputStream) DocumentInputStream(org.apache.poi.poifs.filesystem.DocumentInputStream) InputStream(java.io.InputStream) GeneralSecurityException(java.security.GeneralSecurityException) LittleEndianInputStream(org.apache.poi.util.LittleEndianInputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) DocumentInputStream(org.apache.poi.poifs.filesystem.DocumentInputStream) GeneralSecurityException(java.security.GeneralSecurityException) IOException(java.io.IOException) EOFException(java.io.EOFException) EncryptedDocumentException(org.apache.poi.EncryptedDocumentException) POIFSFileSystem(org.apache.poi.poifs.filesystem.POIFSFileSystem) BoundedInputStream(org.apache.poi.util.BoundedInputStream) EOFException(java.io.EOFException)

Example 88 with POIFSFileSystem

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);
}
Also used : AgileDecryptor(org.apache.poi.poifs.crypt.agile.AgileDecryptor) ByteArrayInputStream(java.io.ByteArrayInputStream) BoundedInputStream(org.apache.poi.util.BoundedInputStream) InputStream(java.io.InputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) OutputStream(java.io.OutputStream) FileOutputStream(java.io.FileOutputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) NPOIFSFileSystem(org.apache.poi.poifs.filesystem.NPOIFSFileSystem) ByteArrayInputStream(java.io.ByteArrayInputStream) POIFSFileSystem(org.apache.poi.poifs.filesystem.POIFSFileSystem) NPOIFSFileSystem(org.apache.poi.poifs.filesystem.NPOIFSFileSystem) TempFile(org.apache.poi.util.TempFile) File(java.io.File) Test(org.junit.Test)

Example 89 with POIFSFileSystem

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();
}
Also used : AgileEncryptionVerifier(org.apache.poi.poifs.crypt.agile.AgileEncryptionVerifier) AgileDecryptor(org.apache.poi.poifs.crypt.agile.AgileDecryptor) ByteArrayInputStream(java.io.ByteArrayInputStream) BoundedInputStream(org.apache.poi.util.BoundedInputStream) InputStream(java.io.InputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) OutputStream(java.io.OutputStream) FileOutputStream(java.io.FileOutputStream) AgileEncryptionVerifier(org.apache.poi.poifs.crypt.agile.AgileEncryptionVerifier) ByteArrayOutputStream(java.io.ByteArrayOutputStream) AgileEncryptionHeader(org.apache.poi.poifs.crypt.agile.AgileEncryptionHeader) NPOIFSFileSystem(org.apache.poi.poifs.filesystem.NPOIFSFileSystem) ByteArrayInputStream(java.io.ByteArrayInputStream) POIFSFileSystem(org.apache.poi.poifs.filesystem.POIFSFileSystem) NPOIFSFileSystem(org.apache.poi.poifs.filesystem.NPOIFSFileSystem) AgileDecryptor(org.apache.poi.poifs.crypt.agile.AgileDecryptor) Test(org.junit.Test)

Example 90 with POIFSFileSystem

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();
}
Also used : XSSFEventBasedExcelExtractor(org.apache.poi.xssf.extractor.XSSFEventBasedExcelExtractor) POIFSFileSystem(org.apache.poi.poifs.filesystem.POIFSFileSystem) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) XSSFWorkbook(org.apache.poi.xssf.usermodel.XSSFWorkbook) File(java.io.File) ZipEntrySource(org.apache.poi.openxml4j.util.ZipEntrySource) AesZipFileZipEntrySource(org.apache.poi.poifs.crypt.temp.AesZipFileZipEntrySource) OPCPackage(org.apache.poi.openxml4j.opc.OPCPackage) FileInputStream(java.io.FileInputStream) Test(org.junit.Test)

Aggregations

POIFSFileSystem (org.apache.poi.poifs.filesystem.POIFSFileSystem)121 Test (org.junit.Test)58 NPOIFSFileSystem (org.apache.poi.poifs.filesystem.NPOIFSFileSystem)38 InputStream (java.io.InputStream)36 ByteArrayInputStream (java.io.ByteArrayInputStream)33 ByteArrayOutputStream (java.io.ByteArrayOutputStream)33 FileInputStream (java.io.FileInputStream)31 File (java.io.File)25 OPOIFSFileSystem (org.apache.poi.poifs.filesystem.OPOIFSFileSystem)15 FileOutputStream (java.io.FileOutputStream)14 OutputStream (java.io.OutputStream)14 HSSFWorkbook (org.apache.poi.hssf.usermodel.HSSFWorkbook)13 DirectoryNode (org.apache.poi.poifs.filesystem.DirectoryNode)13 TempFile (org.apache.poi.util.TempFile)13 IOException (java.io.IOException)12 MutablePropertySet (org.apache.poi.hpsf.MutablePropertySet)7 MutableSection (org.apache.poi.hpsf.MutableSection)7 HashMap (java.util.HashMap)6 DocumentEntry (org.apache.poi.poifs.filesystem.DocumentEntry)6 NDocumentOutputStream (org.apache.poi.poifs.filesystem.NDocumentOutputStream)6