diff options
Diffstat (limited to 'src/testcases')
7 files changed, 168 insertions, 159 deletions
diff --git a/src/testcases/org/apache/poi/hssf/record/TestRecordFactoryInputStream.java b/src/testcases/org/apache/poi/hssf/record/TestRecordFactoryInputStream.java index a97bb5fb30..8df989d158 100644 --- a/src/testcases/org/apache/poi/hssf/record/TestRecordFactoryInputStream.java +++ b/src/testcases/org/apache/poi/hssf/record/TestRecordFactoryInputStream.java @@ -17,22 +17,25 @@ package org.apache.poi.hssf.record; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import java.io.ByteArrayInputStream; import java.util.Arrays; -import junit.framework.AssertionFailedError; -import junit.framework.TestCase; - import org.apache.poi.EncryptedDocumentException; import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey; import org.apache.poi.util.HexRead; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; /** * Tests for {@link RecordFactoryInputStream} * * @author Josh Micich */ -public final class TestRecordFactoryInputStream extends TestCase { +public final class TestRecordFactoryInputStream { /** * Hex dump of a BOF record and most of a FILEPASS record. @@ -55,10 +58,15 @@ public final class TestRecordFactoryInputStream extends TestCase { private static final String SAMPLE_WINDOW1 = "3D 00 12 00" + "00 00 00 00 40 38 55 23 38 00 00 00 00 00 01 00 58 02"; + @Rule + public ExpectedException expectedEx = ExpectedException.none(); + + /** * Makes sure that a default password mismatch condition is represented with {@link EncryptedDocumentException} */ - public void testDefaultPassword() { + @Test + public void defaultPasswordWrong() { // This encodng depends on docId, password and stream position final String SAMPLE_WINDOW1_ENCR1 = "3D 00 12 00" + "C4, 9B, 02, 50, 86, E0, DF, 34, FB, 57, 0E, 8C, CE, 25, 45, E3, 80, 01"; @@ -69,33 +77,36 @@ public final class TestRecordFactoryInputStream extends TestCase { + SAMPLE_WINDOW1_ENCR1 ); - RecordFactoryInputStream rfis; - try { - rfis = createRFIS(dataWrongDefault); - throw new AssertionFailedError("Expected password mismatch error"); - } catch (EncryptedDocumentException e) { - // expected during successful test - if (!e.getMessage().equals("Default password is invalid for docId/saltData/saltHash")) { - throw e; - } - } - - byte[] dataCorrectDefault = HexRead.readFromString("" - + COMMON_HEX_DATA - + "137BEF04 969A200B 306329DE 52254005" // correct saltHash for default password (and docId/saltHash) - + SAMPLE_WINDOW1_ENCR1 - ); - - rfis = createRFIS(dataCorrectDefault); - - confirmReadInitialRecords(rfis); + Biff8EncryptionKey.setCurrentUserPassword(null); + expectedEx.expect(EncryptedDocumentException.class); + expectedEx.expectMessage("Default password is invalid for salt/verifier/verifierHash"); + createRFIS(dataWrongDefault); } + + @Test + public void defaultPasswordOK() { + // This encodng depends on docId, password and stream position + final String SAMPLE_WINDOW1_ENCR1 = "3D 00 12 00" + + "C4, 9B, 02, 50, 86, E0, DF, 34, FB, 57, 0E, 8C, CE, 25, 45, E3, 80, 01"; + + byte[] dataCorrectDefault = HexRead.readFromString("" + + COMMON_HEX_DATA + + "137BEF04 969A200B 306329DE 52254005" // correct saltHash for default password (and docId/saltHash) + + SAMPLE_WINDOW1_ENCR1 + ); + + Biff8EncryptionKey.setCurrentUserPassword(null); + RecordFactoryInputStream rfis = createRFIS(dataCorrectDefault); + confirmReadInitialRecords(rfis); + } + /** * Makes sure that an incorrect user supplied password condition is represented with {@link EncryptedDocumentException} */ - public void testSuppliedPassword() { - // This encodng depends on docId, password and stream position + @Test + public void suppliedPasswordWrong() { + // This encoding depends on docId, password and stream position final String SAMPLE_WINDOW1_ENCR2 = "3D 00 12 00" + "45, B9, 90, FE, B6, C6, EC, 73, EE, 3F, 52, 45, 97, DB, E3, C1, D6, FE"; @@ -108,29 +119,32 @@ public final class TestRecordFactoryInputStream extends TestCase { Biff8EncryptionKey.setCurrentUserPassword("passw0rd"); - RecordFactoryInputStream rfis; - try { - rfis = createRFIS(dataWrongDefault); - throw new AssertionFailedError("Expected password mismatch error"); - } catch (EncryptedDocumentException e) { - // expected during successful test - if (!e.getMessage().equals("Supplied password is invalid for docId/saltData/saltHash")) { - throw e; - } - } - - byte[] dataCorrectDefault = HexRead.readFromString("" - + COMMON_HEX_DATA - + "C728659A C38E35E0 568A338F C3FC9D70" // correct saltHash for supplied password (and docId/saltHash) - + SAMPLE_WINDOW1_ENCR2 - ); + expectedEx.expect(EncryptedDocumentException.class); + expectedEx.expectMessage("Supplied password is invalid for salt/verifier/verifierHash"); + createRFIS(dataWrongDefault); + } - rfis = createRFIS(dataCorrectDefault); - Biff8EncryptionKey.setCurrentUserPassword(null); + @Test + public void suppliedPasswordOK() { + // This encoding depends on docId, password and stream position + final String SAMPLE_WINDOW1_ENCR2 = "3D 00 12 00" + + "45, B9, 90, FE, B6, C6, EC, 73, EE, 3F, 52, 45, 97, DB, E3, C1, D6, FE"; - confirmReadInitialRecords(rfis); - } + Biff8EncryptionKey.setCurrentUserPassword("passw0rd"); + + byte[] dataCorrectDefault = HexRead.readFromString("" + + COMMON_HEX_DATA + + "C728659A C38E35E0 568A338F C3FC9D70" // correct saltHash for supplied password (and docId/saltHash) + + SAMPLE_WINDOW1_ENCR2 + ); + + RecordFactoryInputStream rfis = createRFIS(dataCorrectDefault); + Biff8EncryptionKey.setCurrentUserPassword(null); + confirmReadInitialRecords(rfis); + } + + /** * makes sure the record stream starts with {@link BOFRecord} and then {@link WindowOneRecord} * The second record is gets decrypted so this method also checks its content. diff --git a/src/testcases/org/apache/poi/hssf/record/crypto/AllHSSFEncryptionTests.java b/src/testcases/org/apache/poi/hssf/record/crypto/AllHSSFEncryptionTests.java index 4d56858c95..c727008788 100644 --- a/src/testcases/org/apache/poi/hssf/record/crypto/AllHSSFEncryptionTests.java +++ b/src/testcases/org/apache/poi/hssf/record/crypto/AllHSSFEncryptionTests.java @@ -17,22 +17,18 @@ package org.apache.poi.hssf.record.crypto; -import junit.framework.Test; -import junit.framework.TestSuite; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; /** * Collects all tests for package <tt>org.apache.poi.hssf.record.crypto</tt>. * * @author Josh Micich */ +@RunWith(Suite.class) +@Suite.SuiteClasses({ + TestBiff8DecryptingStream.class, + TestBiff8EncryptionKey.class +}) public final class AllHSSFEncryptionTests { - - public static Test suite() { - TestSuite result = new TestSuite(AllHSSFEncryptionTests.class.getName()); - - result.addTestSuite(TestBiff8DecryptingStream.class); - result.addTestSuite(TestRC4.class); - result.addTestSuite(TestBiff8EncryptionKey.class); - return result; - } } diff --git a/src/testcases/org/apache/poi/hssf/record/crypto/TestBiff8DecryptingStream.java b/src/testcases/org/apache/poi/hssf/record/crypto/TestBiff8DecryptingStream.java index 00c860ad0e..9d9c04417f 100644 --- a/src/testcases/org/apache/poi/hssf/record/crypto/TestBiff8DecryptingStream.java +++ b/src/testcases/org/apache/poi/hssf/record/crypto/TestBiff8DecryptingStream.java @@ -17,22 +17,25 @@ package org.apache.poi.hssf.record.crypto; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + import java.io.InputStream; import java.util.Arrays; import junit.framework.AssertionFailedError; import junit.framework.ComparisonFailure; -import junit.framework.TestCase; import org.apache.poi.util.HexDump; import org.apache.poi.util.HexRead; +import org.junit.Test; /** * Tests for {@link Biff8DecryptingStream} * * @author Josh Micich */ -public final class TestBiff8DecryptingStream extends TestCase { +public final class TestBiff8DecryptingStream { /** * A mock {@link InputStream} that keeps track of position and also produces @@ -40,15 +43,14 @@ public final class TestBiff8DecryptingStream extends TestCase { * than the previous. */ private static final class MockStream extends InputStream { - private int _val; + private final int _initialValue; private int _position; public MockStream(int initialValue) { - _val = initialValue & 0xFF; + _initialValue = initialValue; } public int read() { - _position++; - return _val++ & 0xFF; + return (_initialValue+_position++) & 0xFF; } public int getPosition() { return _position; @@ -68,7 +70,7 @@ public final class TestBiff8DecryptingStream extends TestCase { public StreamTester(MockStream ms, String keyDigestHex, int expectedFirstInt) { _ms = ms; byte[] keyDigest = HexRead.readFromString(keyDigestHex); - _bds = new Biff8DecryptingStream(_ms, 0, new Biff8EncryptionKey(keyDigest)); + _bds = new Biff8DecryptingStream(_ms, 0, new Biff8RC4Key(keyDigest)); assertEquals(expectedFirstInt, _bds.readInt()); _errorsOccurred = false; } @@ -148,7 +150,8 @@ public final class TestBiff8DecryptingStream extends TestCase { /** * Tests reading of 64,32,16 and 8 bit integers aligned with key changing boundaries */ - public void testReadsAlignedWithBoundary() { + @Test + public void readsAlignedWithBoundary() { StreamTester st = createStreamTester(0x50, "BA AD F0 0D 00", 0x96C66829); st.rollForward(0x0004, 0x03FF); @@ -169,7 +172,8 @@ public final class TestBiff8DecryptingStream extends TestCase { /** * Tests reading of 64,32 and 16 bit integers <i>across</i> key changing boundaries */ - public void testReadsSpanningBoundary() { + @Test + public void readsSpanningBoundary() { StreamTester st = createStreamTester(0x50, "BA AD F0 0D 00", 0x96C66829); st.rollForward(0x0004, 0x03FC); @@ -185,7 +189,8 @@ public final class TestBiff8DecryptingStream extends TestCase { * Checks that the BIFF header fields (sid, size) get read without applying decryption, * and that the RC4 stream stays aligned during these calls */ - public void testReadHeaderUShort() { + @Test + public void readHeaderUShort() { StreamTester st = createStreamTester(0x50, "BA AD F0 0D 00", 0x96C66829); st.rollForward(0x0004, 0x03FF); @@ -213,7 +218,8 @@ public final class TestBiff8DecryptingStream extends TestCase { /** * Tests reading of byte sequences <i>across</i> and <i>aligned with</i> key changing boundaries */ - public void testReadByteArrays() { + @Test + public void readByteArrays() { StreamTester st = createStreamTester(0x50, "BA AD F0 0D 00", 0x96C66829); st.rollForward(0x0004, 0x2FFC); @@ -223,7 +229,7 @@ public final class TestBiff8DecryptingStream extends TestCase { st.confirmData("01 C2 4E 55"); // first 4 bytes in next block st.assertNoErrors(); } - + private static StreamTester createStreamTester(int mockStreamStartVal, String keyDigestHex, int expectedFirstInt) { return new StreamTester(new MockStream(mockStreamStartVal), keyDigestHex, expectedFirstInt); } diff --git a/src/testcases/org/apache/poi/hssf/record/crypto/TestBiff8EncryptionKey.java b/src/testcases/org/apache/poi/hssf/record/crypto/TestBiff8EncryptionKey.java index 7c6ad42a74..294cb09e7c 100644 --- a/src/testcases/org/apache/poi/hssf/record/crypto/TestBiff8EncryptionKey.java +++ b/src/testcases/org/apache/poi/hssf/record/crypto/TestBiff8EncryptionKey.java @@ -19,12 +19,12 @@ package org.apache.poi.hssf.record.crypto; import java.util.Arrays; -import org.apache.poi.util.HexDump; -import org.apache.poi.util.HexRead; - import junit.framework.ComparisonFailure; import junit.framework.TestCase; +import org.apache.poi.util.HexDump; +import org.apache.poi.util.HexRead; + /** * Tests for {@link Biff8EncryptionKey} * @@ -37,7 +37,7 @@ public final class TestBiff8EncryptionKey extends TestCase { } public void testCreateKeyDigest() { byte[] docIdData = fromHex("17 F6 D1 6B 09 B1 5F 7B 4C 9D 03 B4 81 B5 B4 4A"); - byte[] keyDigest = Biff8EncryptionKey.createKeyDigest("MoneyForNothing", docIdData); + byte[] keyDigest = Biff8RC4Key.createKeyDigest("MoneyForNothing", docIdData); byte[] expResult = fromHex("C2 D9 56 B2 6B"); if (!Arrays.equals(expResult, keyDigest)) { throw new ComparisonFailure("keyDigest mismatch", HexDump.toHex(expResult), HexDump.toHex(keyDigest)); diff --git a/src/testcases/org/apache/poi/hssf/record/crypto/TestRC4.java b/src/testcases/org/apache/poi/hssf/record/crypto/TestRC4.java deleted file mode 100644 index 35b6da4fd7..0000000000 --- a/src/testcases/org/apache/poi/hssf/record/crypto/TestRC4.java +++ /dev/null @@ -1,76 +0,0 @@ -/* ==================================================================== - 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.hssf.record.crypto; - -import java.security.GeneralSecurityException; -import java.security.InvalidKeyException; -import java.util.Arrays; - -import javax.crypto.Cipher; -import javax.crypto.spec.SecretKeySpec; - -import junit.framework.ComparisonFailure; -import junit.framework.TestCase; - -import org.apache.poi.util.HexDump; -import org.apache.poi.util.HexRead; - -/** - * Tests for {@link RC4} - * - * @author Josh Micich - */ -public class TestRC4 extends TestCase { - public void testSimple() { - confirmRC4("Key", "Plaintext", "BBF316E8D940AF0AD3"); - confirmRC4("Wiki", "pedia", "1021BF0420"); - confirmRC4("Secret", "Attack at dawn", "45A01F645FC35B383552544B9BF5"); - - } - - private static void confirmRC4(String k, String origText, String expEncrHex) { - byte[] actEncr = origText.getBytes(); - new RC4(k.getBytes()).encrypt(actEncr); - byte[] expEncr = HexRead.readFromString(expEncrHex); - - if (!Arrays.equals(expEncr, actEncr)) { - throw new ComparisonFailure("Data mismatch", HexDump.toHex(expEncr), HexDump.toHex(actEncr)); - } - - - Cipher cipher; - try { - cipher = Cipher.getInstance("RC4"); - } catch (GeneralSecurityException e) { - throw new RuntimeException(e); - } - String k2 = k+k; // Sun has minimum of 5 bytes for key - SecretKeySpec skeySpec = new SecretKeySpec(k2.getBytes(), "RC4"); - - try { - cipher.init(Cipher.DECRYPT_MODE, skeySpec); - } catch (InvalidKeyException e) { - throw new RuntimeException(e); - } - byte[] origData = origText.getBytes(); - byte[] altEncr = cipher.update(origData); - if (!Arrays.equals(expEncr, altEncr)) { - throw new RuntimeException("Mismatch from jdk provider"); - } - } -} diff --git a/src/testcases/org/apache/poi/hssf/record/crypto/TestXorEncryption.java b/src/testcases/org/apache/poi/hssf/record/crypto/TestXorEncryption.java new file mode 100644 index 0000000000..e763a18300 --- /dev/null +++ b/src/testcases/org/apache/poi/hssf/record/crypto/TestXorEncryption.java @@ -0,0 +1,66 @@ +/* ====================================================================
+ 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.hssf.record.crypto;
+
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+import org.apache.poi.hssf.HSSFTestDataSamples;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.poifs.crypt.CryptoFunctions;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
+import org.apache.poi.util.HexRead;
+import org.junit.Test;
+
+public class TestXorEncryption {
+
+ private static HSSFTestDataSamples samples = new HSSFTestDataSamples();
+
+ @Test
+ public void testXorEncryption() throws Exception {
+ // Xor-Password: abc
+ // 2.5.343 XORObfuscation
+ // key = 20810
+ // verifier = 52250
+ int verifier = CryptoFunctions.createXorVerifier1("abc");
+ int key = CryptoFunctions.createXorKey1("abc");
+ assertEquals(20810, key);
+ assertEquals(52250, verifier);
+
+ byte xorArrAct[] = CryptoFunctions.createXorArray1("abc");
+ byte xorArrExp[] = HexRead.readFromString("AC-CC-A4-AB-D6-BA-C3-BA-D6-A3-2B-45-D3-79-29-BB");
+ assertThat(xorArrExp, equalTo(xorArrAct));
+ }
+
+ @SuppressWarnings("static-access")
+ @Test
+ public void testUserFile() throws Exception {
+ Biff8EncryptionKey.setCurrentUserPassword("abc");
+ NPOIFSFileSystem fs = new NPOIFSFileSystem(samples.getSampleFile("xor-encryption-abc.xls"), true);
+ HSSFWorkbook hwb = new HSSFWorkbook(fs.getRoot(), true);
+
+ HSSFSheet sh = hwb.getSheetAt(0);
+ assertEquals(1.0, sh.getRow(0).getCell(0).getNumericCellValue(), 0.0);
+ assertEquals(2.0, sh.getRow(1).getCell(0).getNumericCellValue(), 0.0);
+ assertEquals(3.0, sh.getRow(2).getCell(0).getNumericCellValue(), 0.0);
+
+ fs.close();
+ }
+}
diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java index 197531965d..3bd97827cc 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java @@ -54,6 +54,7 @@ import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate; import org.apache.poi.hssf.record.aggregates.PageSettingsBlock; import org.apache.poi.hssf.record.aggregates.RecordAggregate; import org.apache.poi.hssf.record.common.UnicodeString; +import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey; import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.ss.formula.ptg.Area3DPtg; @@ -2113,6 +2114,8 @@ public final class TestBugs extends BaseTestBugzillaIssues { */ @Test public void bug50833() throws Exception { + Biff8EncryptionKey.setCurrentUserPassword(null); + HSSFWorkbook wb = openSample("50833.xls"); HSSFSheet s = wb.getSheetAt(0); assertEquals("Sheet1", s.getSheetName()); @@ -2350,14 +2353,9 @@ public final class TestBugs extends BaseTestBugzillaIssues { * Normally encrypted files have BOF then FILEPASS, but * some may squeeze a WRITEPROTECT in the middle */ - @Test + @Test(expected=EncryptedDocumentException.class) public void bug51832() { - try { - openSample("51832.xls"); - fail("Encrypted file"); - } catch(EncryptedDocumentException e) { - // Good - } + openSample("51832.xls"); } @Test @@ -2480,10 +2478,15 @@ public final class TestBugs extends BaseTestBugzillaIssues { assertEquals(rstyle.getBorderBottom(), HSSFCellStyle.BORDER_DOUBLE); } - @Test(expected=EncryptedDocumentException.class) + @Test public void bug35897() throws Exception { // password is abc - openSample("xor-encryption-abc.xls"); + try { + Biff8EncryptionKey.setCurrentUserPassword("abc"); + openSample("xor-encryption-abc.xls"); + } finally { + Biff8EncryptionKey.setCurrentUserPassword(null); + } } @Test |