poi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kiwiwi...@apache.org
Subject svn commit: r1553336 [4/4] - in /poi: site/src/documentation/content/xdocs/ trunk/ trunk/src/java/org/apache/poi/ trunk/src/java/org/apache/poi/poifs/crypt/ trunk/src/java/org/apache/poi/poifs/crypt/standard/ trunk/src/ooxml/java/org/apache/poi/ trunk/...
Date Tue, 24 Dec 2013 23:13:22 GMT
Added: poi/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestDecryptor.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestDecryptor.java?rev=1553336&view=auto
==============================================================================
--- poi/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestDecryptor.java (added)
+++ poi/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestDecryptor.java Tue Dec 24
23:13:21 2013
@@ -0,0 +1,118 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+package org.apache.poi.poifs.crypt;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.GeneralSecurityException;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import junit.framework.TestCase;
+
+import org.apache.poi.POIDataSamples;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+
+/**
+ *  @author Maxim Valyanskiy
+ *  @author Gary King
+ */
+public class TestDecryptor extends TestCase {
+    public void testPasswordVerification() throws IOException, GeneralSecurityException {
+        POIFSFileSystem fs = new POIFSFileSystem(POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx"));
+
+        EncryptionInfo info = new EncryptionInfo(fs);
+
+        Decryptor d = Decryptor.getInstance(info);
+
+        assertTrue(d.verifyPassword(Decryptor.DEFAULT_PASSWORD));
+    }
+
+    public void testDecrypt() throws IOException, GeneralSecurityException {
+        POIFSFileSystem fs = new POIFSFileSystem(POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx"));
+
+        EncryptionInfo info = new EncryptionInfo(fs);
+
+        Decryptor d = Decryptor.getInstance(info);
+
+        d.verifyPassword(Decryptor.DEFAULT_PASSWORD);
+
+        zipOk(fs, d);
+    }
+
+    public void testAgile() throws IOException, GeneralSecurityException {
+        POIFSFileSystem fs = new POIFSFileSystem(POIDataSamples.getPOIFSInstance().openResourceAsStream("protected_agile.docx"));
+
+        EncryptionInfo info = new EncryptionInfo(fs);
+
+        assertTrue(info.getVersionMajor() == 4 && info.getVersionMinor() == 4);
+
+        Decryptor d = Decryptor.getInstance(info);
+
+        assertTrue(d.verifyPassword(Decryptor.DEFAULT_PASSWORD));
+
+        zipOk(fs, d);
+    }
+
+    private void zipOk(POIFSFileSystem fs, Decryptor d) throws IOException, GeneralSecurityException
{
+        ZipInputStream zin = new ZipInputStream(d.getDataStream(fs));
+
+        while (true) {
+            ZipEntry entry = zin.getNextEntry();
+            if (entry==null) {
+                break;
+            }
+
+            while (zin.available()>0) {
+                zin.skip(zin.available());
+            }
+        }
+    }
+    public void testDataLength() throws Exception {
+        POIFSFileSystem fs = new POIFSFileSystem(POIDataSamples.getPOIFSInstance().openResourceAsStream("protected_agile.docx"));
+
+        EncryptionInfo info = new EncryptionInfo(fs);
+
+        Decryptor d = Decryptor.getInstance(info);
+
+        d.verifyPassword(Decryptor.DEFAULT_PASSWORD);
+
+        InputStream is = d.getDataStream(fs);
+
+        long len = d.getLength();
+        assertEquals(12810, len);
+
+        byte[] buf = new byte[(int)len];
+
+        is.read(buf);
+
+        ZipInputStream zin = new ZipInputStream(new ByteArrayInputStream(buf));
+
+        while (true) {
+            ZipEntry entry = zin.getNextEntry();
+            if (entry==null) {
+                break;
+            }
+
+            while (zin.available()>0) {
+                zin.skip(zin.available());
+            }
+        }
+    }
+
+}
\ No newline at end of file

Added: poi/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestEncryptionInfo.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestEncryptionInfo.java?rev=1553336&view=auto
==============================================================================
--- poi/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestEncryptionInfo.java (added)
+++ poi/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestEncryptionInfo.java Tue Dec
24 23:13:21 2013
@@ -0,0 +1,61 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+package org.apache.poi.poifs.crypt;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+
+import org.apache.poi.POIDataSamples;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.junit.Test;
+
+public class TestEncryptionInfo {
+    @Test
+    public void testEncryptionInfo() throws IOException {
+        POIFSFileSystem fs = new POIFSFileSystem(POIDataSamples.getPOIFSInstance().openResourceAsStream("protect.xlsx"));
+
+        EncryptionInfo info = new EncryptionInfo(fs);
+
+        assertEquals(3, info.getVersionMajor());
+        assertEquals(2, info.getVersionMinor());
+
+        assertEquals(CipherAlgorithm.aes128, info.getHeader().getCipherAlgorithm());
+        assertEquals(HashAlgorithm.sha1, info.getHeader().getHashAlgorithmEx());
+        assertEquals(128, info.getHeader().getKeySize());
+        assertEquals(32, info.getVerifier().getEncryptedVerifierHash().length);
+        assertEquals(CipherProvider.aes, info.getHeader().getCipherProvider());         
      
+        assertEquals("Microsoft Enhanced RSA and AES Cryptographic Provider", info.getHeader().getCspName());
+    }
+    
+    @Test
+    public void testEncryptionInfoSHA512() throws Exception {
+        POIFSFileSystem fs = new POIFSFileSystem(POIDataSamples.getPOIFSInstance().openResourceAsStream("protected_sha512.xlsx"));
+
+        EncryptionInfo info = new EncryptionInfo(fs);
+
+        assertEquals(4, info.getVersionMajor());
+        assertEquals(4, info.getVersionMinor());
+
+        assertEquals(CipherAlgorithm.aes256, info.getHeader().getCipherAlgorithm());
+        assertEquals(HashAlgorithm.sha512, info.getHeader().getHashAlgorithmEx());
+        assertEquals(256, info.getHeader().getKeySize());
+        assertEquals(64, info.getVerifier().getEncryptedVerifierHash().length);
+        assertEquals(CipherProvider.aes, info.getHeader().getCipherProvider());         
      
+//        assertEquals("Microsoft Enhanced RSA and AES Cryptographic Provider", info.getHeader().getCspName());
+    }
+}

Added: poi/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestEncryptor.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestEncryptor.java?rev=1553336&view=auto
==============================================================================
--- poi/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestEncryptor.java (added)
+++ poi/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestEncryptor.java Tue Dec 24
23:13:21 2013
@@ -0,0 +1,253 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+package org.apache.poi.poifs.crypt;
+
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Iterator;
+
+import org.apache.poi.POIDataSamples;
+import org.apache.poi.poifs.crypt.agile.AgileEncryptionHeader;
+import org.apache.poi.poifs.filesystem.DirectoryNode;
+import org.apache.poi.poifs.filesystem.DocumentNode;
+import org.apache.poi.poifs.filesystem.Entry;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.util.BoundedInputStream;
+import org.apache.poi.util.IOUtils;
+import org.junit.Test;
+
+public class TestEncryptor {
+    @Test
+    public void testAgileEncryption() throws Exception {
+        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("EncryptedPackage");
+        is = new BoundedInputStream(is, is.available()-16); // ignore padding block
+        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(
+              fs, 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);
+        
+        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("EncryptedPackage");
+        is = new BoundedInputStream(is, is.available()-16); // ignore padding block
+        byte encPackActual[] = IOUtils.toByteArray(is);
+        is.close();
+        
+        // listDir(nfs.getRoot(), "copy", "");
+        
+        nfs.close();
+        
+        AgileEncryptionHeader aehExpected = (AgileEncryptionHeader)infoExpected.getHeader();
+        AgileEncryptionHeader aehActual = (AgileEncryptionHeader)infoActual.getHeader();
+        assertThat(aehExpected.getEncryptedHmacKey(), equalTo(aehActual.getEncryptedHmacKey()));
+        assertEquals(decPackLenExpected, decPackLenActual);
+        assertThat(payloadExpected, equalTo(payloadActual));
+        assertThat(encPackExpected, equalTo(encPackActual));
+    }
+    
+    @Test
+    public void testStandardEncryption() 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();
+        
+        
+        POIFSFileSystem fs = new POIFSFileSystem();
+        EncryptionInfo infoActual = new EncryptionInfo(
+              fs, 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);
+        
+        assertThat(infoExpected.getVerifier().getEncryptedVerifier(), equalTo(infoActual.getVerifier().getEncryptedVerifier()));
+        assertThat(infoExpected.getVerifier().getEncryptedVerifierHash(), equalTo(infoActual.getVerifier().getEncryptedVerifierHash()));
+
+        // now we use a newly generated salt/verifier and check
+        // if the file content is still the same 
+
+        fs = new POIFSFileSystem();
+        infoActual = new EncryptionInfo(
+              fs, EncryptionMode.standard
+            , infoExpected.getVerifier().getCipherAlgorithm()
+            , infoExpected.getVerifier().getHashAlgorithm()
+            , infoExpected.getHeader().getKeySize()
+            , infoExpected.getHeader().getBlockSize()
+            , infoExpected.getVerifier().getChainingMode()
+        );
+        
+        e = Encryptor.getInstance(infoActual);
+        e.confirmPassword(pass);
+        
+        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();        
+        
+        assertThat(payloadExpected, equalTo(payloadActual));
+    }
+    
+    
+    private void listEntry(DocumentNode de, String ext, String path) throws IOException {
+        path += "\\" + de.getName().replace('\u0006', '_');
+        System.out.println(ext+": "+path+" ("+de.getSize()+" bytes)");
+        
+        String name = de.getName().replace('\u0006', '_');
+        
+        InputStream is = ((DirectoryNode)de.getParent()).createDocumentInputStream(de);
+        FileOutputStream fos = new FileOutputStream("solr."+name+"."+ext);
+        IOUtils.copy(is, fos);
+        fos.close();
+        is.close();
+    }
+    
+    @SuppressWarnings("unused")
+    private void listDir(DirectoryNode dn, String ext, String path) throws IOException {
+        path += "\\" + dn.getName().replace('\u0006', '_');
+        System.out.println(ext+": "+path+" ("+dn.getStorageClsid()+")");
+        
+        Iterator<Entry> iter = dn.getEntries();
+        while (iter.hasNext()) {
+            Entry ent = iter.next();
+            if (ent instanceof DirectoryNode) {
+                listDir((DirectoryNode)ent, ext, path);
+            } else {
+                listEntry((DocumentNode)ent, ext, path);
+            }
+        }
+    }
+}

Modified: poi/trunk/src/ooxml/testcases/org/apache/poi/xwpf/TestXWPFBugs.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/testcases/org/apache/poi/xwpf/TestXWPFBugs.java?rev=1553336&r1=1553335&r2=1553336&view=diff
==============================================================================
--- poi/trunk/src/ooxml/testcases/org/apache/poi/xwpf/TestXWPFBugs.java (original)
+++ poi/trunk/src/ooxml/testcases/org/apache/poi/xwpf/TestXWPFBugs.java Tue Dec 24 23:13:21
2013
@@ -11,9 +11,10 @@ import javax.crypto.Cipher;
 
 import org.apache.poi.POIDataSamples;
 import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.poifs.crypt.CipherAlgorithm;
 import org.apache.poi.poifs.crypt.Decryptor;
-import org.apache.poi.poifs.crypt.EncryptionHeader;
 import org.apache.poi.poifs.crypt.EncryptionInfo;
+import org.apache.poi.poifs.crypt.HashAlgorithm;
 import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
 import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
 import org.apache.poi.xwpf.usermodel.XWPFDocument;
@@ -33,8 +34,8 @@ public class TestXWPFBugs {
         // Check the encryption details
         EncryptionInfo info = new EncryptionInfo(filesystem);
         assertEquals(128, info.getHeader().getKeySize());
-        assertEquals(EncryptionHeader.ALGORITHM_AES_128, info.getHeader().getAlgorithm());
-        assertEquals(EncryptionHeader.HASH_SHA1, info.getHeader().getHashAlgorithm());
+        assertEquals(CipherAlgorithm.aes128, info.getHeader().getCipherAlgorithm());
+        assertEquals(HashAlgorithm.sha1, info.getHeader().getHashAlgorithmEx());
 
         // Check it can be decoded
         Decryptor d = Decryptor.getInstance(info);		
@@ -67,8 +68,8 @@ public class TestXWPFBugs {
         EncryptionInfo info = new EncryptionInfo(filesystem);
         assertEquals(16, info.getHeader().getBlockSize());
         assertEquals(256, info.getHeader().getKeySize());
-        assertEquals(EncryptionHeader.ALGORITHM_AES_256, info.getHeader().getAlgorithm());
-        assertEquals(EncryptionHeader.HASH_SHA1, info.getHeader().getHashAlgorithm());
+        assertEquals(CipherAlgorithm.aes256, info.getHeader().getCipherAlgorithm());
+        assertEquals(HashAlgorithm.sha1, info.getHeader().getHashAlgorithmEx());
 
         // Check it can be decoded
         Decryptor d = Decryptor.getInstance(info);		



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org


Mime
View raw message