]> source.dussan.org Git - poi.git/commitdiff
migrated enveloped document test (1 of 2)
authorAndreas Beeker <kiwiwings@apache.org>
Fri, 15 Aug 2014 22:20:30 +0000 (22:20 +0000)
committerAndreas Beeker <kiwiwings@apache.org>
Fri, 15 Aug 2014 22:20:30 +0000 (22:20 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/xml_signature@1618288 13f79535-47bb-0310-9956-ffa450edef68

build.xml
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/XAdESXLSignatureFacet.java
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/XmlSignatureService.java
src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java

index 4423a7833d894b4f8a60b03c0ebe496b3cbe32a4..18e817232d0116510b70c555ffef2a59407dafa3 100644 (file)
--- a/build.xml
+++ b/build.xml
@@ -145,8 +145,12 @@ under the License.
     <property name="main.ant.url" value="${repository.m2}/maven2/org/apache/ant/ant/1.9.4/ant-1.9.4.jar"/>
     <property name="main.antlauncher.jar" location="${main.lib}/ant-launcher-1.9.4.jar"/>
     <property name="main.antlauncher.url" value="${repository.m2}/maven2/org/apache/ant/ant-launcher/1.9.4/ant-launcher-1.9.4.jar"/>
+       <property name="main.mockito.jar" location="${main.lib}/mockito-core-1.9.5.jar"/>
+       <property name="main.mockito.url" value="${repository.m2}/maven2/org/mockito/mockito-core/1.9.5/mockito-core-1.9.5.jar"/>
+       <property name="main.objenesis.jar" location="${main.lib}/com.springsource.org.objenesis-1.0.0.jar"/>
+       <property name="main.objenesis.url" value="http://repository.springsource.com/ivy/bundles/external/org.objenesis/com.springsource.org.objenesis/1.0.0/com.springsource.org.objenesis-1.0.0.jar"/>
 
-    <!-- jars in the lib-ooxml directory, see the fetch-ooxml-jars target-->
+       <!-- jars in the lib-ooxml directory, see the fetch-ooxml-jars target-->
     <property name="ooxml.xmlbeans23.jar" location="${ooxml.lib}/xmlbeans-2.3.0.jar"/>
     <property name="ooxml.xmlbeans23.url"
               value="${repository.m2}/maven2/org/apache/xmlbeans/xmlbeans/2.3.0/xmlbeans-2.3.0.jar"/>
@@ -159,7 +163,7 @@ under the License.
     <property name="jacoco.url" value="${repository.m2}/maven2/org/jacoco/jacoco/0.7.1.201405082137/jacoco-0.7.1.201405082137.zip"/>
     <property name="asm.jar" location="${main.lib}/asm-all-5.0.3.jar"/>
     <property name="asm.url" value="${repository.m2}/maven2/org/ow2/asm/asm-all/5.0.3/asm-all-5.0.3.jar"/>
-
+       
     <!-- license checks -->
     <property name="rat.jar" location="${main.lib}/apache-rat-0.10.jar"/>
     <property name="rat.url" value="${repository.m2}/maven2/org/apache/rat/apache-rat/0.10/apache-rat-0.10.jar"/>
@@ -431,6 +435,14 @@ under the License.
             <param name="sourcefile" value="${rat.url}"/>
             <param name="destfile" value="${rat.jar}"/>
         </antcall>
+        <antcall target="downloadfile">
+            <param name="sourcefile" value="${main.mockito.url}"/>
+            <param name="destfile" value="${main.mockito.jar}"/>
+        </antcall>
+        <antcall target="downloadfile">
+            <param name="sourcefile" value="${main.objenesis.url}"/>
+            <param name="destfile" value="${main.objenesis.jar}"/>
+        </antcall>
     </target>
 
     <target name="check-ooxml-jars">
index 142d56bc0acff454f153acb59f6fee69b2ad76c5..96ac896a63c681df761cbf38815c2fd6612c9cbf 100644 (file)
@@ -126,26 +126,28 @@ public class SignatureInfo {
         DigestInfo digestInfo = signatureService.preSign(null, x509Chain, null, null, null);\r
 \r
         // setup: key material, signature value\r
+        byte[] signatureValue = signDigest(key, hashAlgo, digestInfo.digestValue);\r
+        \r
+        // operate: postSign\r
+        signatureService.postSign(signatureValue, Collections.singletonList(x509));\r
+    }\r
 \r
+    public static byte[] signDigest(Key key, HashAlgorithm hashAlgo, byte digest[]) {\r
         Cipher cipher = CryptoFunctions.getCipher(key, CipherAlgorithm.rsa\r
             , ChainingMode.ecb, null, Cipher.ENCRYPT_MODE, "PKCS1Padding");\r
-        \r
-        byte[] signatureValue;\r
+            \r
         try {\r
             ByteArrayOutputStream digestInfoValueBuf = new ByteArrayOutputStream();\r
             digestInfoValueBuf.write(getHashMagic(hashAlgo));\r
-            digestInfoValueBuf.write(digestInfo.digestValue);\r
+            digestInfoValueBuf.write(digest);\r
             byte[] digestInfoValue = digestInfoValueBuf.toByteArray();\r
-            signatureValue = cipher.doFinal(digestInfoValue);\r
+            byte[] signatureValue = cipher.doFinal(digestInfoValue);\r
+            return signatureValue;\r
         } catch (Exception e) {\r
             throw new EncryptedDocumentException(e);\r
         }\r
-\r
-        \r
-        // operate: postSign\r
-        signatureService.postSign(signatureValue, Collections.singletonList(x509));\r
     }\r
-\r
+    \r
     public XmlSignatureService createSignatureService(HashAlgorithm hashAlgo, OPCPackage pkg) {\r
         XmlSignatureService signatureService = new XmlSignatureService(hashAlgo, pkg);\r
         signatureService.initFacets(new Date());\r
index ade2494f06d6d11be8532dcb53fba76b0c3096af..2b590fdd23701293cb965287b5998d4fc4adfad9 100644 (file)
@@ -49,8 +49,6 @@ import javax.xml.crypto.dsig.XMLSignatureFactory;
 import javax.xml.namespace.QName;\r
 \r
 import org.apache.poi.poifs.crypt.HashAlgorithm;\r
-import org.apache.poi.poifs.crypt.dsig.HorribleProxy;\r
-import org.apache.poi.poifs.crypt.dsig.SignatureInfo;\r
 import org.apache.poi.poifs.crypt.dsig.HorribleProxies.ASN1InputStreamIf;\r
 import org.apache.poi.poifs.crypt.dsig.HorribleProxies.ASN1OctetStringIf;\r
 import org.apache.poi.poifs.crypt.dsig.HorribleProxies.BasicOCSPRespIf;\r
@@ -62,6 +60,8 @@ import org.apache.poi.poifs.crypt.dsig.HorribleProxies.OCSPRespIf;
 import org.apache.poi.poifs.crypt.dsig.HorribleProxies.RespIDIf;\r
 import org.apache.poi.poifs.crypt.dsig.HorribleProxies.ResponderIDIf;\r
 import org.apache.poi.poifs.crypt.dsig.HorribleProxies.X509NameIf;\r
+import org.apache.poi.poifs.crypt.dsig.HorribleProxy;\r
+import org.apache.poi.poifs.crypt.dsig.SignatureInfo;\r
 import org.apache.poi.poifs.crypt.dsig.services.RevocationData;\r
 import org.apache.poi.poifs.crypt.dsig.services.RevocationDataService;\r
 import org.apache.poi.poifs.crypt.dsig.services.TimeStampService;\r
@@ -373,25 +373,22 @@ public class XAdESXLSignatureFacet implements SignatureFacet {
     }\r
 \r
     public static byte[] getC14nValue(List<Node> nodeList, String c14nAlgoId) {\r
-        byte[] c14nValue = null;\r
+        ByteArrayOutputStream c14nValue = new ByteArrayOutputStream();\r
         try {\r
             for (Node node : nodeList) {\r
                 /*\r
                  * Re-initialize the c14n else the namespaces will get cached\r
                  * and will be missing from the c14n resulting nodes.\r
                  */\r
-                CanonicalizerIf c14n = HorribleProxy.createProxy(CanonicalizerIf.class, "newInstance", c14nAlgoId);\r
-                ByteArrayOutputStream bos = new ByteArrayOutputStream();\r
-                bos.write(c14nValue);\r
-                bos.write(c14n.canonicalizeSubtree(node));\r
-                c14nValue = bos.toByteArray();\r
+                CanonicalizerIf c14n = HorribleProxy.createProxy(CanonicalizerIf.class, "getInstance", c14nAlgoId);\r
+                c14nValue.write(c14n.canonicalizeSubtree(node));\r
             }\r
         } catch (RuntimeException e) {\r
             throw e;\r
         } catch (Exception e) {\r
             throw new RuntimeException("c14n error: " + e.getMessage(), e);\r
         }\r
-        return c14nValue;\r
+        return c14nValue.toByteArray();\r
     }\r
 \r
     public void preSign(XMLSignatureFactory signatureFactory,\r
index bea7653430af81d0cbc84f394f3767cd37b1a4b0..91ed1646b5c7f684c1862f6b460bfe8ed678e26f 100644 (file)
@@ -112,7 +112,7 @@ public class XmlSignatureService implements SignatureService {
     protected final List<SignatureFacet> signatureFacets;\r
 \r
     private String signatureNamespacePrefix;\r
-    private String signatureId;\r
+    private String signatureId = "idPackageSignature";\r
     private final HashAlgorithm hashAlgo;\r
     private final OPCPackage opcPackage;\r
     private SignatureDocument sigDoc;\r
@@ -124,7 +124,6 @@ public class XmlSignatureService implements SignatureService {
     public XmlSignatureService(HashAlgorithm digestAlgo, OPCPackage opcPackage) {\r
         this.signatureFacets = new LinkedList<SignatureFacet>();\r
         this.signatureNamespacePrefix = null;\r
-        this.signatureId = null;\r
         this.hashAlgo = digestAlgo;\r
         this.opcPackage = opcPackage;\r
         this.sigDoc = null;\r
@@ -142,7 +141,6 @@ public class XmlSignatureService implements SignatureService {
          * Work-around for Office 2010.\r
          */\r
         this.xadesSignatureFacet.setIssuerNameNoReverseOrder(true);\r
-        setSignatureId("idPackageSignature");\r
         addSignatureFacet(this.xadesSignatureFacet);\r
         addSignatureFacet(new Office2010SignatureFacet());\r
     }\r
@@ -398,8 +396,9 @@ public class XmlSignatureService implements SignatureService {
 \r
         registerIds(doc);\r
         Element el = doc.getElementById("idPackageObject");\r
-        assert (el != null);\r
-        el.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:mdssi", PackageNamespaces.DIGITAL_SIGNATURE);\r
+        if (el != null) {\r
+            el.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:mdssi", PackageNamespaces.DIGITAL_SIGNATURE);\r
+        }\r
 \r
         \r
         /*\r
@@ -549,6 +548,10 @@ public class XmlSignatureService implements SignatureService {
     public String getFilesDigestAlgorithm() {\r
         return null;\r
     }\r
+    \r
+    public SignatureDocument getSignatureDocument() {\r
+        return sigDoc;\r
+    }\r
 \r
     protected String getCanonicalizationMethod() {\r
         return CanonicalizationMethod.INCLUSIVE;\r
index 191066014fa538e6898736ed867f1b1f6b3883ce..73f6b2381996d644446b579ba90351f0fb9bea36 100644 (file)
@@ -29,6 +29,8 @@ import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;\r
 import static org.mockito.Matchers.eq;\r
 import static org.mockito.Mockito.mock;\r
+import static org.mockito.Mockito.times;\r
+import static org.mockito.Mockito.verify;\r
 import static org.mockito.Mockito.when;\r
 \r
 import java.io.ByteArrayOutputStream;\r
@@ -54,6 +56,10 @@ import java.util.List;
 import java.util.TimeZone;\r
 \r
 import javax.crypto.Cipher;\r
+import javax.xml.crypto.KeySelector;\r
+import javax.xml.crypto.dsig.XMLSignature;\r
+import javax.xml.crypto.dsig.XMLSignatureFactory;\r
+import javax.xml.crypto.dsig.dom.DOMValidateContext;\r
 \r
 import org.apache.poi.POIDataSamples;\r
 import org.apache.poi.openxml4j.opc.OPCPackage;\r
@@ -75,10 +81,14 @@ import org.apache.poi.poifs.crypt.dsig.spi.DigestInfo;
 import org.apache.poi.util.IOUtils;\r
 import org.apache.poi.util.POILogFactory;\r
 import org.apache.poi.util.POILogger;\r
+import org.apache.xmlbeans.XmlObject;\r
+import org.etsi.uri.x01903.v13.DigestAlgAndValueType;\r
+import org.etsi.uri.x01903.v13.QualifyingPropertiesType;\r
 import org.junit.BeforeClass;\r
 import org.junit.Test;\r
 import org.mockito.invocation.InvocationOnMock;\r
 import org.mockito.stubbing.Answer;\r
+import org.w3.x2000.x09.xmldsig.SignatureDocument;\r
 \r
 public class TestSignatureInfo {\r
     private static final POILogger LOG = POILogFactory.getLogger(TestSignatureInfo.class);\r
@@ -244,8 +254,52 @@ public class TestSignatureInfo {
 \r
         // verify\r
         assertNotNull(digestInfo);\r
-        assertEquals("SHA-1", digestInfo.hashAlgo);\r
+        assertEquals(HashAlgorithm.sha1, digestInfo.hashAlgo);\r
         assertNotNull(digestInfo.digestValue);\r
+        \r
+        SignatureDocument sigDoc = testedInstance.getSignatureDocument();\r
+        String certDigestXQuery =\r
+                "declare namespace xades='http://uri.etsi.org/01903/v1.3.2#'; "\r
+              + "declare namespace ds='http://www.w3.org/2000/09/xmldsig#'; "\r
+              + "$this/ds:Signature/ds:Object/xades:QualifyingProperties/xades:SignedProperties/xades:SignedSignatureProperties/xades:SigningCertificate/xades:Cert/xades:CertDigest";\r
+        XmlObject xoList[] = sigDoc.selectPath(certDigestXQuery);\r
+        assertEquals(xoList.length, 1);\r
+        DigestAlgAndValueType certDigest = (DigestAlgAndValueType)xoList[0];\r
+        assertNotNull(certDigest.getDigestValue());\r
+\r
+        // Sign the received XML signature digest value.\r
+        byte[] signatureValue = SignatureInfo.signDigest(keyPair.getPrivate(), HashAlgorithm.sha1, digestInfo.digestValue);\r
+\r
+        // Operate: postSign\r
+        testedInstance.postSign(signatureValue, certificateChain);\r
+        \r
+        // verify\r
+        verify(mockTimeStampService, times(2)).timeStamp(any(byte[].class), any(RevocationData.class));\r
+        verify(mockRevocationDataService).getRevocationData(certificateChain);\r
+        \r
+        DOMValidateContext domValidateContext = new DOMValidateContext(\r
+                KeySelector.singletonKeySelector(keyPair.getPublic()),\r
+                testedInstance.getSignatureDocument().getDomNode());\r
+        XMLSignatureFactory xmlSignatureFactory = SignatureInfo.getSignatureFactory();\r
+        XMLSignature xmlSignature = xmlSignatureFactory\r
+                .unmarshalXMLSignature(domValidateContext);\r
+        boolean validity = xmlSignature.validate(domValidateContext);\r
+        assertTrue(validity);\r
+\r
+        xoList = sigDoc.selectPath(certDigestXQuery);\r
+        assertEquals(xoList.length, 1);\r
+        certDigest = (DigestAlgAndValueType)xoList[0];\r
+        assertNotNull(certDigest.getDigestValue());\r
+        \r
+        String qualPropXQuery =\r
+                "declare namespace xades='http://uri.etsi.org/01903/v1.3.2#'; "\r
+              + "declare namespace ds='http://www.w3.org/2000/09/xmldsig#'; "\r
+              + "$this/ds:Signature/ds:Object/xades:QualifyingProperties";\r
+        xoList = sigDoc.selectPath(qualPropXQuery);\r
+        assertEquals(xoList.length, 1);\r
+        QualifyingPropertiesType qualProp = (QualifyingPropertiesType)xoList[0];\r
+        boolean qualPropXsdOk = qualProp.validate();\r
+        assertTrue(qualPropXsdOk);\r
     }\r
     \r
     private OPCPackage sign(OPCPackage pkgCopy, String alias, String signerDn, int signerCount) throws Exception {\r