Search in sources :

Example 1 with BoundedInputStream

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);
    }
}
Also used : ByteArrayInputStream(java.io.ByteArrayInputStream) BoundedInputStream(org.apache.poi.util.BoundedInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) InflaterInputStream(java.util.zip.InflaterInputStream) InputStream(java.io.InputStream) BoundedInputStream(org.apache.poi.util.BoundedInputStream) InflaterInputStream(java.util.zip.InflaterInputStream)

Example 2 with BoundedInputStream

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);
}
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) AgileEncryptionHeader(org.apache.poi.poifs.crypt.agile.AgileEncryptionHeader) NPOIFSFileSystem(org.apache.poi.poifs.filesystem.NPOIFSFileSystem) ByteArrayInputStream(java.io.ByteArrayInputStream) BoundedInputStream(org.apache.poi.util.BoundedInputStream) 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 3 with BoundedInputStream

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;
}
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 4 with BoundedInputStream

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);
}
Also used : CipherInputStream(javax.crypto.CipherInputStream) CipherInputStream(javax.crypto.CipherInputStream) BoundedInputStream(org.apache.poi.util.BoundedInputStream) DocumentInputStream(org.apache.poi.poifs.filesystem.DocumentInputStream) InputStream(java.io.InputStream) BoundedInputStream(org.apache.poi.util.BoundedInputStream) Cipher(javax.crypto.Cipher) DocumentInputStream(org.apache.poi.poifs.filesystem.DocumentInputStream)

Aggregations

InputStream (java.io.InputStream)4 BoundedInputStream (org.apache.poi.util.BoundedInputStream)4 ByteArrayInputStream (java.io.ByteArrayInputStream)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 DocumentInputStream (org.apache.poi.poifs.filesystem.DocumentInputStream)2 POIFSFileSystem (org.apache.poi.poifs.filesystem.POIFSFileSystem)2 EOFException (java.io.EOFException)1 File (java.io.File)1 FileOutputStream (java.io.FileOutputStream)1 IOException (java.io.IOException)1 OutputStream (java.io.OutputStream)1 GeneralSecurityException (java.security.GeneralSecurityException)1 InflaterInputStream (java.util.zip.InflaterInputStream)1 Cipher (javax.crypto.Cipher)1 CipherInputStream (javax.crypto.CipherInputStream)1 EncryptedDocumentException (org.apache.poi.EncryptedDocumentException)1 ChunkedCipherInputStream (org.apache.poi.poifs.crypt.ChunkedCipherInputStream)1 AgileDecryptor (org.apache.poi.poifs.crypt.agile.AgileDecryptor)1 AgileEncryptionHeader (org.apache.poi.poifs.crypt.agile.AgileEncryptionHeader)1 DocumentNode (org.apache.poi.poifs.filesystem.DocumentNode)1