<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"/>
<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"/>
<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">
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
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
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
}\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
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
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
* Work-around for Office 2010.\r
*/\r
this.xadesSignatureFacet.setIssuerNameNoReverseOrder(true);\r
- setSignatureId("idPackageSignature");\r
addSignatureFacet(this.xadesSignatureFacet);\r
addSignatureFacet(new Office2010SignatureFacet());\r
}\r
\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
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
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
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
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
\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