From 31458eb486649e2f8b6bff6803043dffd903613c Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Wed, 25 Dec 2013 01:04:29 +0000 Subject: [PATCH] JCE policy fix git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1553342 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/poi/poifs/crypt/CryptoFunctions.java | 11 +++++++++-- .../apache/poi/poifs/crypt/agile/AgileDecryptor.java | 11 ++++++++++- .../apache/poi/poifs/crypt/agile/AgileEncryptor.java | 12 +++++++++++- .../poifs/crypt/TestAgileEncryptionParameters.java | 6 ++++++ .../poi/poifs/crypt/TestCertificateEncryption.java | 2 +- .../org/apache/poi/poifs/crypt/TestEncryptor.java | 6 ++++++ 6 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java b/src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java index 33876fc975..42ca434198 100644 --- a/src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java +++ b/src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java @@ -22,12 +22,14 @@ import java.security.GeneralSecurityException; import java.security.MessageDigest; import java.security.Provider; import java.security.Security; +import java.security.spec.AlgorithmParameterSpec; import java.util.Arrays; import javax.crypto.Cipher; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.RC2ParameterSpec; import org.apache.poi.EncryptedDocumentException; import org.apache.poi.util.LittleEndian; @@ -188,8 +190,13 @@ public class CryptoFunctions { if (vec == null) { cipher.init(cipherMode, key); } else { - IvParameterSpec iv = new IvParameterSpec(vec); - cipher.init(cipherMode, key, iv); + AlgorithmParameterSpec aps; + if (cipherAlgorithm == CipherAlgorithm.rc2) { + aps = new RC2ParameterSpec(key.getEncoded().length*8, vec); + } else { + aps = new IvParameterSpec(vec); + } + cipher.init(cipherMode, key, aps); } return cipher; } catch (GeneralSecurityException e) { diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileDecryptor.java b/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileDecryptor.java index 7e45786db9..193e7a766b 100644 --- a/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileDecryptor.java +++ b/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileDecryptor.java @@ -29,12 +29,14 @@ import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.MessageDigest; import java.security.cert.X509Certificate; +import java.security.spec.AlgorithmParameterSpec; import java.util.Arrays; import javax.crypto.Cipher; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.RC2ParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.apache.poi.EncryptedDocumentException; @@ -383,7 +385,14 @@ public class AgileDecryptor extends Decryptor { LittleEndian.putInt(blockKey, 0, index); EncryptionHeader header = info.getHeader(); byte[] iv = generateIv(header.getHashAlgorithmEx(), header.getKeySalt(), blockKey, getBlockSizeInBytes()); - _cipher.init(Cipher.DECRYPT_MODE, getSecretKey(), new IvParameterSpec(iv)); + AlgorithmParameterSpec aps; + if (header.getCipherAlgorithm() == CipherAlgorithm.rc2) { + aps = new RC2ParameterSpec(getSecretKey().getEncoded().length*8, iv); + } else { + aps = new IvParameterSpec(iv); + } + + _cipher.init(Cipher.DECRYPT_MODE, getSecretKey(), aps); if (_lastIndex != index) _stream.skip((index - _lastIndex) << 12); diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptor.java b/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptor.java index 455c8cd4d7..aa538a9908 100644 --- a/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptor.java +++ b/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptor.java @@ -41,6 +41,7 @@ import java.security.GeneralSecurityException; import java.security.MessageDigest; import java.security.SecureRandom; import java.security.cert.CertificateEncodingException; +import java.security.spec.AlgorithmParameterSpec; import java.util.HashMap; import java.util.Map; import java.util.Random; @@ -49,9 +50,11 @@ import javax.crypto.Cipher; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.RC2ParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.apache.poi.EncryptedDocumentException; +import org.apache.poi.poifs.crypt.CipherAlgorithm; import org.apache.poi.poifs.crypt.CryptoFunctions; import org.apache.poi.poifs.crypt.DataSpaceMapUtils; import org.apache.poi.poifs.crypt.EncryptionHeader; @@ -315,7 +318,14 @@ public class AgileEncryptor extends Encryptor { LittleEndian.putInt(blockKey, 0, index); byte[] iv = generateIv(header.getHashAlgorithmEx(), header.getKeySalt(), blockKey, blockSize); try { - _cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(), new IvParameterSpec(iv)); + AlgorithmParameterSpec aps; + if (header.getCipherAlgorithm() == CipherAlgorithm.rc2) { + aps = new RC2ParameterSpec(getSecretKey().getEncoded().length*8, iv); + } else { + aps = new IvParameterSpec(iv); + } + + _cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(), aps); int ciLen = _cipher.doFinal(_chunk, 0, posInChunk, _chunk); out.write(_chunk, 0, ciLen); } catch (GeneralSecurityException e) { diff --git a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestAgileEncryptionParameters.java b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestAgileEncryptionParameters.java index 469286606f..131a5c2e49 100644 --- a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestAgileEncryptionParameters.java +++ b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestAgileEncryptionParameters.java @@ -28,9 +28,12 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import javax.crypto.Cipher; + import org.apache.poi.POIDataSamples; import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.util.IOUtils; +import org.junit.Assume; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; @@ -77,6 +80,9 @@ public class TestAgileEncryptionParameters { @Test public void testAgileEncryptionModes() throws Exception { + int maxKeyLen = Cipher.getMaxAllowedKeyLength(ca.jceId); + Assume.assumeTrue("Please install JCE Unlimited Strength Jurisdiction Policy files", maxKeyLen >= ca.defaultKeySize); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); POIFSFileSystem fsEnc = new POIFSFileSystem(); diff --git a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestCertificateEncryption.java b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestCertificateEncryption.java index d74719cc00..4b2ffb2b4e 100644 --- a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestCertificateEncryption.java +++ b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestCertificateEncryption.java @@ -157,7 +157,7 @@ public class TestCertificateEncryption { @Test public void testCertificateEncryption() throws Exception { POIFSFileSystem fs = new POIFSFileSystem(); - EncryptionInfo info = new EncryptionInfo(fs, EncryptionMode.agile, CipherAlgorithm.aes192, HashAlgorithm.sha1, -1, -1, ChainingMode.cbc); + EncryptionInfo info = new EncryptionInfo(fs, EncryptionMode.agile, CipherAlgorithm.aes128, HashAlgorithm.sha1, -1, -1, ChainingMode.cbc); AgileEncryptionVerifier aev = (AgileEncryptionVerifier)info.getVerifier(); CertData certData = loadKeystore(); aev.addCertificate(certData.x509); diff --git a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestEncryptor.java b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestEncryptor.java index 957ec10973..b04da659dc 100644 --- a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestEncryptor.java +++ b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestEncryptor.java @@ -30,6 +30,8 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.Iterator; +import javax.crypto.Cipher; + import org.apache.poi.POIDataSamples; import org.apache.poi.poifs.crypt.agile.AgileEncryptionHeader; import org.apache.poi.poifs.filesystem.DirectoryNode; @@ -39,11 +41,15 @@ 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.Assume; import org.junit.Test; public class TestEncryptor { @Test public void testAgileEncryption() 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); -- 2.39.5