poi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kiwiwi...@apache.org
Subject svn commit: r1637001 - in /poi/trunk/src/ooxml: java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java
Date Wed, 05 Nov 2014 22:56:32 GMT
Author: kiwiwings
Date: Wed Nov  5 22:56:31 2014
New Revision: 1637001

URL: http://svn.apache.org/r1637001
Log:
Added a catch and another workaround for the OpenJDK SHA2 AIOOBE bug

Modified:
    poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java
    poi/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java

Modified: poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java?rev=1637001&r1=1637000&r2=1637001&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java Wed Nov  5
22:56:31 2014
@@ -32,6 +32,8 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.security.GeneralSecurityException;
 import java.security.MessageDigest;
+import java.security.Provider;
+import java.security.Security;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -395,138 +397,149 @@ public class SignatureInfo implements Si
     @SuppressWarnings("unchecked")
     public DigestInfo preSign(Document document, List<DigestInfo> digestInfos)
     throws XMLSignatureException, MarshalException {
-        signatureConfig.init(false);
-        
-        // it's necessary to explicitly set the mdssi namespace, but the sign() method has
no
-        // normal way to interfere with, so we need to add the namespace under the hand ...
-        EventTarget target = (EventTarget)document;
-        EventListener creationListener = signatureConfig.getSignatureMarshalListener();
-        if (creationListener != null) {
-            if (creationListener instanceof SignatureMarshalListener) {
-                ((SignatureMarshalListener)creationListener).setEventTarget(target);
-            }
-            SignatureMarshalListener.setListener(target, creationListener, true);
-        }
-        
-        /*
-         * Signature context construction.
-         */
-        XMLSignContext xmlSignContext = new DOMSignContext(signatureConfig.getKey(), document);
-        URIDereferencer uriDereferencer = signatureConfig.getUriDereferencer();
-        if (null != uriDereferencer) {
-            xmlSignContext.setURIDereferencer(uriDereferencer);
-        }
-
-        for (Map.Entry<String,String> me : signatureConfig.getNamespacePrefixes().entrySet())
{
-            xmlSignContext.putNamespacePrefix(me.getKey(), me.getValue());
-        }
-        xmlSignContext.setDefaultNamespacePrefix(""); // signatureConfig.getNamespacePrefixes().get(XML_DIGSIG_NS));
-        
-        XMLSignatureFactory signatureFactory = signatureConfig.getSignatureFactory();
-
-        /*
-         * Add ds:References that come from signing client local files.
-         */
-        List<Reference> references = new ArrayList<Reference>();
-        for (DigestInfo digestInfo : safe(digestInfos)) {
-            byte[] documentDigestValue = digestInfo.digestValue;
-
-            String uri = new File(digestInfo.description).getName();
-            Reference reference = SignatureFacet.newReference
-                (uri, null, null, null, documentDigestValue, signatureConfig);
-            references.add(reference);
-        }
-
-        /*
-         * Invoke the signature facets.
-         */
-        List<XMLObject> objects = new ArrayList<XMLObject>();
-        for (SignatureFacet signatureFacet : signatureConfig.getSignatureFacets()) {
-            LOG.log(POILogger.DEBUG, "invoking signature facet: " + signatureFacet.getClass().getSimpleName());
-            signatureFacet.preSign(document, references, objects);
-        }
-
-        /*
-         * ds:SignedInfo
-         */
-        SignedInfo signedInfo;
         try {
-            SignatureMethod signatureMethod = signatureFactory.newSignatureMethod
-                (signatureConfig.getSignatureMethodUri(), null);
-            CanonicalizationMethod canonicalizationMethod = signatureFactory
-                .newCanonicalizationMethod(signatureConfig.getCanonicalizationMethod(),
-                (C14NMethodParameterSpec) null);
-            signedInfo = signatureFactory.newSignedInfo(
-                canonicalizationMethod, signatureMethod, references);
-        } catch (GeneralSecurityException e) {
-            throw new XMLSignatureException(e);
-        }
-
-        /*
-         * JSR105 ds:Signature creation
-         */
-        String signatureValueId = signatureConfig.getPackageSignatureId() + "-signature-value";
-        javax.xml.crypto.dsig.XMLSignature xmlSignature = signatureFactory
-            .newXMLSignature(signedInfo, null, objects, signatureConfig.getPackageSignatureId(),
-            signatureValueId);
-
-        /*
-         * ds:Signature Marshalling.
-         */
-        xmlSignature.sign(xmlSignContext);
-
-        /*
-         * Completion of undigested ds:References in the ds:Manifests.
-         */
-        for (XMLObject object : objects) {
-            LOG.log(POILogger.DEBUG, "object java type: " + object.getClass().getName());
-            List<XMLStructure> objectContentList = object.getContent();
-            for (XMLStructure objectContent : objectContentList) {
-                LOG.log(POILogger.DEBUG, "object content java type: " + objectContent.getClass().getName());
-                if (!(objectContent instanceof Manifest)) continue;
-                Manifest manifest = (Manifest) objectContent;
-                List<Reference> manifestReferences = manifest.getReferences();
-                for (Reference manifestReference : manifestReferences) {
-                    if (manifestReference.getDigestValue() != null) continue;
-
-                    DOMReference manifestDOMReference = (DOMReference)manifestReference;
-                    manifestDOMReference.digest(xmlSignContext);
+            signatureConfig.init(false);
+            
+            // it's necessary to explicitly set the mdssi namespace, but the sign() method
has no
+            // normal way to interfere with, so we need to add the namespace under the hand
...
+            EventTarget target = (EventTarget)document;
+            EventListener creationListener = signatureConfig.getSignatureMarshalListener();
+            if (creationListener != null) {
+                if (creationListener instanceof SignatureMarshalListener) {
+                    ((SignatureMarshalListener)creationListener).setEventTarget(target);
                 }
+                SignatureMarshalListener.setListener(target, creationListener, true);
             }
-        }
-
-        /*
-         * Completion of undigested ds:References.
-         */
-        List<Reference> signedInfoReferences = signedInfo.getReferences();
-        for (Reference signedInfoReference : signedInfoReferences) {
-            DOMReference domReference = (DOMReference)signedInfoReference;
-
-            // ds:Reference with external digest value
-            if (domReference.getDigestValue() != null) continue;
             
-            domReference.digest(xmlSignContext);
+            /*
+             * Signature context construction.
+             */
+            XMLSignContext xmlSignContext = new DOMSignContext(signatureConfig.getKey(),
document);
+            URIDereferencer uriDereferencer = signatureConfig.getUriDereferencer();
+            if (null != uriDereferencer) {
+                xmlSignContext.setURIDereferencer(uriDereferencer);
+            }
+    
+            for (Map.Entry<String,String> me : signatureConfig.getNamespacePrefixes().entrySet())
{
+                xmlSignContext.putNamespacePrefix(me.getKey(), me.getValue());
+            }
+            xmlSignContext.setDefaultNamespacePrefix("");
+            // signatureConfig.getNamespacePrefixes().get(XML_DIGSIG_NS));
+            
+            // workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1155012
+            Provider bcProv = Security.getProvider("BC");
+            if (bcProv != null) {
+                xmlSignContext.setProperty("org.jcp.xml.dsig.internal.dom.SignatureProvider",
bcProv);
+            }            
+            
+            XMLSignatureFactory signatureFactory = signatureConfig.getSignatureFactory();
+    
+            /*
+             * Add ds:References that come from signing client local files.
+             */
+            List<Reference> references = new ArrayList<Reference>();
+            for (DigestInfo digestInfo : safe(digestInfos)) {
+                byte[] documentDigestValue = digestInfo.digestValue;
+    
+                String uri = new File(digestInfo.description).getName();
+                Reference reference = SignatureFacet.newReference
+                    (uri, null, null, null, documentDigestValue, signatureConfig);
+                references.add(reference);
+            }
+    
+            /*
+             * Invoke the signature facets.
+             */
+            List<XMLObject> objects = new ArrayList<XMLObject>();
+            for (SignatureFacet signatureFacet : signatureConfig.getSignatureFacets()) {
+                LOG.log(POILogger.DEBUG, "invoking signature facet: " + signatureFacet.getClass().getSimpleName());
+                signatureFacet.preSign(document, references, objects);
+            }
+    
+            /*
+             * ds:SignedInfo
+             */
+            SignedInfo signedInfo;
+            try {
+                SignatureMethod signatureMethod = signatureFactory.newSignatureMethod
+                    (signatureConfig.getSignatureMethodUri(), null);
+                CanonicalizationMethod canonicalizationMethod = signatureFactory
+                    .newCanonicalizationMethod(signatureConfig.getCanonicalizationMethod(),
+                    (C14NMethodParameterSpec) null);
+                signedInfo = signatureFactory.newSignedInfo(
+                    canonicalizationMethod, signatureMethod, references);
+            } catch (GeneralSecurityException e) {
+                throw new XMLSignatureException(e);
+            }
+    
+            /*
+             * JSR105 ds:Signature creation
+             */
+            String signatureValueId = signatureConfig.getPackageSignatureId() + "-signature-value";
+            javax.xml.crypto.dsig.XMLSignature xmlSignature = signatureFactory
+                .newXMLSignature(signedInfo, null, objects, signatureConfig.getPackageSignatureId(),
+                signatureValueId);
+    
+            /*
+             * ds:Signature Marshalling.
+             */
+            xmlSignature.sign(xmlSignContext);
+    
+            /*
+             * Completion of undigested ds:References in the ds:Manifests.
+             */
+            for (XMLObject object : objects) {
+                LOG.log(POILogger.DEBUG, "object java type: " + object.getClass().getName());
+                List<XMLStructure> objectContentList = object.getContent();
+                for (XMLStructure objectContent : objectContentList) {
+                    LOG.log(POILogger.DEBUG, "object content java type: " + objectContent.getClass().getName());
+                    if (!(objectContent instanceof Manifest)) continue;
+                    Manifest manifest = (Manifest) objectContent;
+                    List<Reference> manifestReferences = manifest.getReferences();
+                    for (Reference manifestReference : manifestReferences) {
+                        if (manifestReference.getDigestValue() != null) continue;
+    
+                        DOMReference manifestDOMReference = (DOMReference)manifestReference;
+                        manifestDOMReference.digest(xmlSignContext);
+                    }
+                }
+            }
+    
+            /*
+             * Completion of undigested ds:References.
+             */
+            List<Reference> signedInfoReferences = signedInfo.getReferences();
+            for (Reference signedInfoReference : signedInfoReferences) {
+                DOMReference domReference = (DOMReference)signedInfoReference;
+    
+                // ds:Reference with external digest value
+                if (domReference.getDigestValue() != null) continue;
+                
+                domReference.digest(xmlSignContext);
+            }
+    
+            /*
+             * Calculation of XML signature digest value.
+             */
+            DOMSignedInfo domSignedInfo = (DOMSignedInfo)signedInfo;
+            ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
+            domSignedInfo.canonicalize(xmlSignContext, dataStream);
+            byte[] octets = dataStream.toByteArray();
+    
+            /*
+             * TODO: we could be using DigestOutputStream here to optimize memory
+             * usage.
+             */
+    
+            MessageDigest md = CryptoFunctions.getMessageDigest(signatureConfig.getDigestAlgo());
+            byte[] digestValue = md.digest(octets);
+            
+            
+            String description = signatureConfig.getSignatureDescription();
+            return new DigestInfo(digestValue, signatureConfig.getDigestAlgo(), description);
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw new EncryptedDocumentException("\"your JVM is just too broken\" - check
https://bugzilla.redhat.com/show_bug.cgi?id=1155012 if this applies to the stacktrace ...",
e);
         }
-
-        /*
-         * Calculation of XML signature digest value.
-         */
-        DOMSignedInfo domSignedInfo = (DOMSignedInfo)signedInfo;
-        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
-        domSignedInfo.canonicalize(xmlSignContext, dataStream);
-        byte[] octets = dataStream.toByteArray();
-
-        /*
-         * TODO: we could be using DigestOutputStream here to optimize memory
-         * usage.
-         */
-
-        MessageDigest md = CryptoFunctions.getMessageDigest(signatureConfig.getDigestAlgo());
-        byte[] digestValue = md.digest(octets);
-        
-        
-        String description = signatureConfig.getSignatureDescription();
-        return new DigestInfo(digestValue, signatureConfig.getDigestAlgo(), description);
     }
 
     /**

Modified: poi/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java?rev=1637001&r1=1637000&r2=1637001&view=diff
==============================================================================
--- poi/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java (original)
+++ poi/trunk/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java Wed Nov
 5 22:56:31 2014
@@ -23,7 +23,10 @@
    ================================================================= */ 
 package org.apache.poi.poifs.crypt;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -47,6 +50,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.TimeZone;
 
+import org.apache.poi.EncryptedDocumentException;
 import org.apache.poi.POIDataSamples;
 import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.openxml4j.opc.PackageAccess;
@@ -455,18 +459,29 @@ public class TestSignatureInfo {
             , HashAlgorithm.sha384, HashAlgorithm.sha512, HashAlgorithm.ripemd160 }; 
         
         for (HashAlgorithm ha : testAlgo) {
-            signatureConfig.setDigestAlgo(ha);
-            OPCPackage pkg = OPCPackage.open(copy(testdata.getFile(testFile)), PackageAccess.READ_WRITE);
-            signatureConfig.setOpcPackage(pkg);
-            
-            SignatureInfo si = new SignatureInfo();
-            si.setSignatureConfig(signatureConfig);
-    
-            si.confirmSignature();
-            boolean b = si.verifySignature();
-            pkg.close();
-    
-            assertTrue(b);
+            OPCPackage pkg = null;
+            try {
+                signatureConfig.setDigestAlgo(ha);
+                pkg = OPCPackage.open(copy(testdata.getFile(testFile)), PackageAccess.READ_WRITE);
+                signatureConfig.setOpcPackage(pkg);
+                
+                SignatureInfo si = new SignatureInfo();
+                si.setSignatureConfig(signatureConfig);
+        
+                si.confirmSignature();
+                boolean b = si.verifySignature();
+                assertTrue(b);
+            } catch (EncryptedDocumentException e) {
+                // see http://apache-poi.1045710.n5.nabble.com/org-apache-poi-poifs-crypt-TestSignatureInfo-failing-on-trunk-on-Java-6-tp5717032.html
+                Throwable cause = e.getCause();
+                if (cause instanceof ArrayIndexOutOfBoundsException) {
+                    LOG.log(POILogger.ERROR, "ignoring AIOOBE - hopefully a SHA2 bug ...",
e);
+                } else {
+                    throw e;
+                }
+            } finally {
+                if (pkg != null) pkg.close();
+            }
         }
     }
     



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


Mime
View raw message