You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ki...@apache.org on 2014/04/21 14:16:54 UTC

svn commit: r1588874 - in /poi/trunk/src: java/org/apache/poi/poifs/crypt/ ooxml/java/org/apache/poi/poifs/crypt/agile/ scratchpad/src/org/apache/poi/hslf/usermodel/ testcases/org/apache/poi/ss/formula/function/

Author: kiwiwings
Date: Mon Apr 21 12:16:54 2014
New Revision: 1588874

URL: http://svn.apache.org/r1588874
Log:
Some encryption fixes:
- don't rely on SecretKey object having the right algorithm set
- leave encryption-description parsing of string/stream to xmlbeans and refactor it to one location
- use namespaces of schema instead of hard-coded strings
- use CryptoFunctions.getMessageDigest() instead of code duplication

Modified:
    poi/trunk/src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java
    poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionHeader.java
    poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionInfoBuilder.java
    poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionVerifier.java
    poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptor.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java
    poi/trunk/src/testcases/org/apache/poi/ss/formula/function/ExcelFileFormatDocFunctionExtractor.java

Modified: poi/trunk/src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java?rev=1588874&r1=1588873&r2=1588874&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java Mon Apr 21 12:16:54 2014
@@ -195,16 +195,18 @@ public class CryptoFunctions {
         
         try {
             // Ensure the JCE policies files allow for this sized key
-            if (Cipher.getMaxAllowedKeyLength(key.getAlgorithm()) < keySizeInBytes*8) {
+            if (Cipher.getMaxAllowedKeyLength(cipherAlgorithm.jceId) < keySizeInBytes*8) {
                 throw new EncryptedDocumentException("Export Restrictions in place - please install JCE Unlimited Strength Jurisdiction Policy files");
             }
 
             Cipher cipher;
-            if (cipherAlgorithm.needsBouncyCastle) {
+            if (cipherAlgorithm == CipherAlgorithm.rc4) {
+                cipher = Cipher.getInstance(cipherAlgorithm.jceId);
+            } else if (cipherAlgorithm.needsBouncyCastle) {
                 registerBouncyCastle();
-                cipher = Cipher.getInstance(key.getAlgorithm() + "/" + chain.jceId + "/" + padding, "BC");
+                cipher = Cipher.getInstance(cipherAlgorithm.jceId + "/" + chain.jceId + "/" + padding, "BC");
             } else {
-                cipher = Cipher.getInstance(key.getAlgorithm() + "/" + chain.jceId + "/" + padding);
+                cipher = Cipher.getInstance(cipherAlgorithm.jceId + "/" + chain.jceId + "/" + padding);
             }
             
             if (vec == null) {
@@ -282,7 +284,6 @@ public class CryptoFunctions {
         }
     }
 
-
     private static final int InitialCodeArray[] = { 
         0xE1F0, 0x1D0F, 0xCC9C, 0x84C0, 0x110C, 0x0E10, 0xF1CE, 
         0x313E, 0x1872, 0xE139, 0xD40F, 0x84F9, 0x280C, 0xA96A, 

Modified: poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionHeader.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionHeader.java?rev=1588874&r1=1588873&r2=1588874&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionHeader.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionHeader.java Mon Apr 21 12:16:54 2014
@@ -16,14 +16,11 @@
 ==================================================================== */
 package org.apache.poi.poifs.crypt.agile;
 
-import java.io.IOException;
-
 import org.apache.poi.EncryptedDocumentException;
 import org.apache.poi.poifs.crypt.ChainingMode;
 import org.apache.poi.poifs.crypt.CipherAlgorithm;
 import org.apache.poi.poifs.crypt.EncryptionHeader;
 import org.apache.poi.poifs.crypt.HashAlgorithm;
-import org.apache.xmlbeans.XmlException;
 
 import com.microsoft.schemas.office.x2006.encryption.CTDataIntegrity;
 import com.microsoft.schemas.office.x2006.encryption.CTKeyData;
@@ -33,14 +30,11 @@ import com.microsoft.schemas.office.x200
 public class AgileEncryptionHeader extends EncryptionHeader {
     private byte encryptedHmacKey[], encryptedHmacValue[];
     
-    public AgileEncryptionHeader(String descriptor) throws IOException {
-        EncryptionDocument ed;
-        try {
-            ed = EncryptionDocument.Factory.parse(descriptor);
-        } catch (XmlException e) {
-            throw new EncryptedDocumentException("Unable to parse encryption descriptor", e);
-        }
-        
+    public AgileEncryptionHeader(String descriptor) {
+        this(AgileEncryptionInfoBuilder.parseDescriptor(descriptor));
+    }
+    
+    protected AgileEncryptionHeader(EncryptionDocument ed) {
         CTKeyData keyData;
         try {
             keyData = ed.getEncryption().getKeyData();

Modified: poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionInfoBuilder.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionInfoBuilder.java?rev=1588874&r1=1588873&r2=1588874&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionInfoBuilder.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionInfoBuilder.java Mon Apr 21 12:16:54 2014
@@ -17,14 +17,19 @@
 package org.apache.poi.poifs.crypt.agile;
 
 import java.io.IOException;
+import java.io.InputStream;
 
 import org.apache.poi.EncryptedDocumentException;
 import org.apache.poi.poifs.crypt.ChainingMode;
 import org.apache.poi.poifs.crypt.CipherAlgorithm;
 import org.apache.poi.poifs.crypt.EncryptionInfo;
 import org.apache.poi.poifs.crypt.EncryptionInfoBuilder;
+import org.apache.poi.poifs.crypt.EncryptionMode;
 import org.apache.poi.poifs.crypt.HashAlgorithm;
 import org.apache.poi.poifs.filesystem.DocumentInputStream;
+import org.apache.xmlbeans.XmlException;
+
+import com.microsoft.schemas.office.x2006.encryption.EncryptionDocument;
 
 public class AgileEncryptionInfoBuilder implements EncryptionInfoBuilder {
     
@@ -37,15 +42,11 @@ public class AgileEncryptionInfoBuilder 
     public void initialize(EncryptionInfo info, DocumentInputStream dis) throws IOException {
         this.info = info;
         
-        StringBuilder builder = new StringBuilder();
-        byte[] xmlDescriptor = new byte[dis.available()];
-        dis.read(xmlDescriptor);
-        for (byte b : xmlDescriptor)
-            builder.append((char)b);
-        String descriptor = builder.toString();
-        header = new AgileEncryptionHeader(descriptor);
-        verifier = new AgileEncryptionVerifier(descriptor);
-        if (info.getVersionMajor() == 4 && info.getVersionMinor() == 4) {
+        EncryptionDocument ed = parseDescriptor(dis);
+        header = new AgileEncryptionHeader(ed);
+        verifier = new AgileEncryptionVerifier(ed);
+        if (info.getVersionMajor() == EncryptionMode.agile.versionMajor
+            && info.getVersionMinor() == EncryptionMode.agile.versionMinor) {
             decryptor = new AgileDecryptor(this);
         }
     }
@@ -107,5 +108,19 @@ public class AgileEncryptionInfoBuilder 
         return info;
     }
     
-    
+    protected static EncryptionDocument parseDescriptor(String descriptor) {
+        try {
+            return EncryptionDocument.Factory.parse(descriptor);
+        } catch (XmlException e) {
+            throw new EncryptedDocumentException("Unable to parse encryption descriptor", e);
+        }
+    }
+
+    protected static EncryptionDocument parseDescriptor(InputStream descriptor) {
+        try {
+            return EncryptionDocument.Factory.parse(descriptor);
+        } catch (Exception e) {
+            throw new EncryptedDocumentException("Unable to parse encryption descriptor", e);
+        }
+    }
 }

Modified: poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionVerifier.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionVerifier.java?rev=1588874&r1=1588873&r2=1588874&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionVerifier.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptionVerifier.java Mon Apr 21 12:16:54 2014
@@ -29,7 +29,6 @@ import org.apache.poi.poifs.crypt.Chaini
 import org.apache.poi.poifs.crypt.CipherAlgorithm;
 import org.apache.poi.poifs.crypt.EncryptionVerifier;
 import org.apache.poi.poifs.crypt.HashAlgorithm;
-import org.apache.xmlbeans.XmlException;
 
 import com.microsoft.schemas.office.x2006.encryption.CTKeyEncryptor;
 import com.microsoft.schemas.office.x2006.encryption.EncryptionDocument;
@@ -50,15 +49,11 @@ public class AgileEncryptionVerifier ext
     
     private List<AgileCertificateEntry> certList = new ArrayList<AgileCertificateEntry>();
 
-    
     public AgileEncryptionVerifier(String descriptor) {
-        EncryptionDocument ed;
-        try {
-            ed = EncryptionDocument.Factory.parse(descriptor);
-        } catch (XmlException e) {
-            throw new EncryptedDocumentException("Unable to parse encryption descriptor", e);
-        }
-
+        this(AgileEncryptionInfoBuilder.parseDescriptor(descriptor));
+    }
+    
+    protected AgileEncryptionVerifier(EncryptionDocument ed) {
         Iterator<CTKeyEncryptor> encList = ed.getEncryption().getKeyEncryptors().getKeyEncryptorList().iterator();
         CTPasswordKeyEncryptor keyData;
         try {

Modified: poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptor.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptor.java?rev=1588874&r1=1588873&r2=1588874&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptor.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/agile/AgileEncryptor.java Mon Apr 21 12:16:54 2014
@@ -403,6 +403,11 @@ public class AgileEncryptor extends Encr
     }
 
     protected void createEncryptionInfoEntry(DirectoryNode dir) throws IOException {
+        final CTKeyEncryptor.Uri.Enum passwordUri = 
+            CTKeyEncryptor.Uri.HTTP_SCHEMAS_MICROSOFT_COM_OFFICE_2006_KEY_ENCRYPTOR_PASSWORD;
+        final CTKeyEncryptor.Uri.Enum certificateUri = 
+                CTKeyEncryptor.Uri.HTTP_SCHEMAS_MICROSOFT_COM_OFFICE_2006_KEY_ENCRYPTOR_CERTIFICATE;
+        
         AgileEncryptionVerifier ver = builder.getVerifier();
         AgileEncryptionHeader header = builder.getHeader();
         
@@ -412,7 +417,7 @@ public class AgileEncryptor extends Encr
         CTKeyData keyData = edRoot.addNewKeyData();
         CTKeyEncryptors keyEncList = edRoot.addNewKeyEncryptors();
         CTKeyEncryptor keyEnc = keyEncList.addNewKeyEncryptor();
-        keyEnc.setUri(CTKeyEncryptor.Uri.HTTP_SCHEMAS_MICROSOFT_COM_OFFICE_2006_KEY_ENCRYPTOR_PASSWORD);
+        keyEnc.setUri(passwordUri);
         CTPasswordKeyEncryptor keyPass = keyEnc.addNewEncryptedPasswordKey();
 
         keyPass.setSpinCount(ver.getSpinCount());
@@ -469,7 +474,7 @@ public class AgileEncryptor extends Encr
         
         for (AgileCertificateEntry ace : ver.getCertificates()) {
             keyEnc = keyEncList.addNewKeyEncryptor();
-            keyEnc.setUri(CTKeyEncryptor.Uri.HTTP_SCHEMAS_MICROSOFT_COM_OFFICE_2006_KEY_ENCRYPTOR_CERTIFICATE);
+            keyEnc.setUri(certificateUri);
             CTCertificateKeyEncryptor certData = keyEnc.addNewEncryptedCertificateKey();
             try {
                 certData.setX509Certificate(ace.x509.getEncoded());
@@ -479,13 +484,13 @@ public class AgileEncryptor extends Encr
             certData.setEncryptedKeyValue(ace.encryptedKey);
             certData.setCertVerifier(ace.certVerifier);
         }
-
+        
         XmlOptions xo = new XmlOptions();
         xo.setCharacterEncoding("UTF-8");
         Map<String,String> nsMap = new HashMap<String,String>();
-        nsMap.put("http://schemas.microsoft.com/office/2006/keyEncryptor/password","p");
-        nsMap.put("http://schemas.microsoft.com/office/2006/keyEncryptor/certificate", "c");
-        nsMap.put("http://schemas.microsoft.com/office/2006/encryption","");
+        nsMap.put(passwordUri.toString(),"p");
+        nsMap.put(certificateUri.toString(), "c");
+        xo.setUseDefaultNamespace();
         xo.setSaveSuggestedPrefixes(nsMap);
         xo.setSaveNamespacesFirst();
         xo.setSaveAggressiveNamespaces();
@@ -505,7 +510,7 @@ public class AgileEncryptor extends Encr
         leos.writeShort(info.getVersionMajor());
         leos.writeShort(info.getVersionMinor());
         // Reserved (4 bytes): A value that MUST be 0x00000040
-        leos.writeInt(0x40);
+        leos.writeInt(info.getEncryptionFlags());
         leos.write(bos.toByteArray());
         
         dir.createDocument("EncryptionInfo", leos.getWriteIndex(), new POIFSWriterListener() {

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java?rev=1588874&r1=1588873&r2=1588874&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/PictureData.java Mon Apr 21 12:16:54 2014
@@ -21,7 +21,6 @@ import java.awt.Graphics2D;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
 
 import org.apache.poi.hslf.blip.BitmapPainter;
 import org.apache.poi.hslf.blip.DIB;
@@ -31,8 +30,9 @@ import org.apache.poi.hslf.blip.JPEG;
 import org.apache.poi.hslf.blip.PICT;
 import org.apache.poi.hslf.blip.PNG;
 import org.apache.poi.hslf.blip.WMF;
-import org.apache.poi.hslf.exceptions.HSLFException;
 import org.apache.poi.hslf.model.Picture;
+import org.apache.poi.poifs.crypt.CryptoFunctions;
+import org.apache.poi.poifs.crypt.HashAlgorithm;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
@@ -138,14 +138,9 @@ public abstract class PictureData {
      * Compute 16-byte checksum of this picture using MD5 algorithm.
      */
     public static byte[] getChecksum(byte[] data) {
-        MessageDigest sha;
-        try {
-            sha = MessageDigest.getInstance("MD5");
-        } catch (NoSuchAlgorithmException e){
-            throw new HSLFException(e.getMessage());
-        }
-        sha.update(data);
-        return sha.digest();
+        MessageDigest md5 = CryptoFunctions.getMessageDigest(HashAlgorithm.md5);
+        md5.update(data);
+        return md5.digest();
     }
 
     /**

Modified: poi/trunk/src/testcases/org/apache/poi/ss/formula/function/ExcelFileFormatDocFunctionExtractor.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/ss/formula/function/ExcelFileFormatDocFunctionExtractor.java?rev=1588874&r1=1588873&r2=1588874&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/ss/formula/function/ExcelFileFormatDocFunctionExtractor.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/ss/formula/function/ExcelFileFormatDocFunctionExtractor.java Mon Apr 21 12:16:54 2014
@@ -31,7 +31,6 @@ import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLConnection;
 import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -43,6 +42,8 @@ import java.util.Stack;
 import java.util.zip.ZipException;
 import java.util.zip.ZipFile;
 
+import org.apache.poi.poifs.crypt.CryptoFunctions;
+import org.apache.poi.poifs.crypt.HashAlgorithm;
 import org.xml.sax.Attributes;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.InputSource;
@@ -542,12 +543,7 @@ public final class ExcelFileFormatDocFun
 	 * Helps identify the source file
 	 */
 	private static String getFileMD5(File f) {
-		MessageDigest m;
-		try {
-			m = MessageDigest.getInstance("MD5");
-		} catch (NoSuchAlgorithmException e) {
-			throw new RuntimeException(e);
-		}
+	    MessageDigest m = CryptoFunctions.getMessageDigest(HashAlgorithm.md5);
 
 		byte[]buf = new byte[2048];
 		try {



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