]> source.dussan.org Git - poi.git/blob
c1e474f6e227709a4b81f10b3b482760c7b923fe
[poi.git] /
1
2 /* ====================================================================
3    Licensed to the Apache Software Foundation (ASF) under one or more
4    contributor license agreements.  See the NOTICE file distributed with
5    this work for additional information regarding copyright ownership.
6    The ASF licenses this file to You under the Apache License, Version 2.0
7    (the "License"); you may not use this file except in compliance with
8    the License.  You may obtain a copy of the License at
9
10        http://www.apache.org/licenses/LICENSE-2.0
11
12    Unless required by applicable law or agreed to in writing, software
13    distributed under the License is distributed on an "AS IS" BASIS,
14    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15    See the License for the specific language governing permissions and
16    limitations under the License.
17 ==================================================================== */
18
19 /*
20  * Based on the eID Applet Project code.
21  * Original Copyright (C) 2008-2009 FedICT.
22  */
23
24 package org.apache.poi.ooxml.signature.service.signer;
25
26 import java.io.ByteArrayInputStream;
27 import java.io.ByteArrayOutputStream;
28 import java.io.InputStream;
29 import java.io.OutputStream;
30 import java.security.KeyPair;
31 import java.security.MessageDigest;
32 import java.security.cert.X509Certificate;
33 import java.util.Collections;
34 import java.util.HashMap;
35 import java.util.LinkedList;
36 import java.util.List;
37 import java.util.Map;
38
39 import javax.crypto.Cipher;
40 import javax.xml.crypto.Data;
41 import javax.xml.crypto.KeySelector;
42 import javax.xml.crypto.OctetStreamData;
43 import javax.xml.crypto.URIDereferencer;
44 import javax.xml.crypto.URIReference;
45 import javax.xml.crypto.URIReferenceException;
46 import javax.xml.crypto.XMLCryptoContext;
47 import javax.xml.crypto.dom.DOMCryptoContext;
48 import javax.xml.crypto.dsig.CanonicalizationMethod;
49 import javax.xml.crypto.dsig.DigestMethod;
50 import javax.xml.crypto.dsig.Reference;
51 import javax.xml.crypto.dsig.SignatureMethod;
52 import javax.xml.crypto.dsig.SignedInfo;
53 import javax.xml.crypto.dsig.XMLSignContext;
54 import javax.xml.crypto.dsig.XMLSignature;
55 import javax.xml.crypto.dsig.XMLSignatureFactory;
56 import javax.xml.crypto.dsig.dom.DOMSignContext;
57 import javax.xml.crypto.dsig.dom.DOMValidateContext;
58 import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
59 import javax.xml.parsers.DocumentBuilder;
60 import javax.xml.parsers.DocumentBuilderFactory;
61
62 import junit.framework.TestCase;
63
64 import org.apache.commons.lang.ArrayUtils;
65 import org.apache.commons.logging.Log;
66 import org.apache.commons.logging.LogFactory;
67 import org.apache.poi.ooxml.signature.service.spi.DigestInfo;
68 import org.apache.xml.security.utils.Constants;
69 import org.apache.xpath.XPathAPI;
70 import org.bouncycastle.asn1.x509.KeyUsage;
71 import org.jcp.xml.dsig.internal.dom.DOMReference;
72 import org.jcp.xml.dsig.internal.dom.DOMXMLSignature;
73 import org.joda.time.DateTime;
74 import org.w3c.dom.Document;
75 import org.w3c.dom.Element;
76 import org.w3c.dom.Node;
77 import org.w3c.dom.NodeList;
78
79
80
81 public class TestAbstractXmlSignatureService extends TestCase {
82
83     private static final Log LOG = LogFactory.getLog(TestAbstractXmlSignatureService.class);
84
85     private static class XmlSignatureTestService extends AbstractXmlSignatureService {
86
87         private Document envelopingDocument;
88
89         private List<String> referenceUris;
90
91         private TemporaryTestDataStorage temporaryDataStorage;
92
93         private String signatureDescription;
94
95         private ByteArrayOutputStream signedDocumentOutputStream;
96
97         private URIDereferencer uriDereferencer;
98
99         public XmlSignatureTestService() {
100             super();
101             this.referenceUris = new LinkedList<String>();
102             this.temporaryDataStorage = new TemporaryTestDataStorage();
103             this.signedDocumentOutputStream = new ByteArrayOutputStream();
104         }
105
106         public byte[] getSignedDocumentData() {
107             return this.signedDocumentOutputStream.toByteArray();
108         }
109
110         public void setEnvelopingDocument(Document envelopingDocument) {
111             this.envelopingDocument = envelopingDocument;
112         }
113
114         @Override
115         protected Document getEnvelopingDocument() {
116             return this.envelopingDocument;
117         }
118
119         @Override
120         protected String getSignatureDescription() {
121             return this.signatureDescription;
122         }
123
124         public void setSignatureDescription(String signatureDescription) {
125             this.signatureDescription = signatureDescription;
126         }
127
128         @Override
129         protected List<String> getReferenceUris() {
130             return this.referenceUris;
131         }
132
133         public void addReferenceUri(String referenceUri) {
134             this.referenceUris.add(referenceUri);
135         }
136
137         @Override
138         protected OutputStream getSignedDocumentOutputStream() {
139             return this.signedDocumentOutputStream;
140         }
141
142         @Override
143         protected TemporaryDataStorage getTemporaryDataStorage() {
144             return this.temporaryDataStorage;
145         }
146
147         public String getFilesDigestAlgorithm() {
148             return null;
149         }
150
151         @Override
152         protected URIDereferencer getURIDereferencer() {
153             return this.uriDereferencer;
154         }
155
156         public void setUriDereferencer(URIDereferencer uriDereferencer) {
157             this.uriDereferencer = uriDereferencer;
158         }
159     }
160
161     public void testSignEnvelopingDocument() throws Exception {
162         // setup
163         DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
164         documentBuilderFactory.setNamespaceAware(true);
165         DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
166         Document document = documentBuilder.newDocument();
167         Element rootElement = document.createElementNS("urn:test", "tns:root");
168         rootElement.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:tns", "urn:test");
169         document.appendChild(rootElement);
170         Element dataElement = document.createElementNS("urn:test", "tns:data");
171         dataElement.setAttributeNS(null, "Id", "id-1234");
172         dataElement.setTextContent("data to be signed");
173         rootElement.appendChild(dataElement);
174
175         XmlSignatureTestService testedInstance = new XmlSignatureTestService();
176         testedInstance.setEnvelopingDocument(document);
177         testedInstance.addReferenceUri("#id-1234");
178         testedInstance.setSignatureDescription("test-signature-description");
179
180         // operate
181         DigestInfo digestInfo = testedInstance.preSign(null, null);
182
183         // verify
184         assertNotNull(digestInfo);
185         LOG.debug("digest info description: " + digestInfo.description);
186         assertEquals("test-signature-description", digestInfo.description);
187         assertNotNull(digestInfo.digestValue);
188         LOG.debug("digest algo: " + digestInfo.digestAlgo);
189         assertEquals("SHA-1", digestInfo.digestAlgo);
190
191         TemporaryTestDataStorage temporaryDataStorage = (TemporaryTestDataStorage) testedInstance.getTemporaryDataStorage();
192         assertNotNull(temporaryDataStorage);
193         InputStream tempInputStream = temporaryDataStorage.getTempInputStream();
194         assertNotNull(tempInputStream);
195         Document tmpDocument = PkiTestUtils.loadDocument(tempInputStream);
196
197         LOG.debug("tmp document: " + PkiTestUtils.toString(tmpDocument));
198         Element nsElement = tmpDocument.createElement("ns");
199         nsElement.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:ds", Constants.SignatureSpecNS);
200         Node digestValueNode = XPathAPI.selectSingleNode(tmpDocument, "//ds:DigestValue", nsElement);
201         assertNotNull(digestValueNode);
202         String digestValueTextContent = digestValueNode.getTextContent();
203         LOG.debug("digest value text content: " + digestValueTextContent);
204         assertFalse(digestValueTextContent.isEmpty());
205
206         /*
207          * Sign the received XML signature digest value.
208          */
209         KeyPair keyPair = PkiTestUtils.generateKeyPair();
210         Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
211         cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPrivate());
212         byte[] digestInfoValue = ArrayUtils.addAll(PkiTestUtils.SHA1_DIGEST_INFO_PREFIX, digestInfo.digestValue);
213         byte[] signatureValue = cipher.doFinal(digestInfoValue);
214
215         DateTime notBefore = new DateTime();
216         DateTime notAfter = notBefore.plusYears(1);
217         X509Certificate certificate = PkiTestUtils.generateCertificate(keyPair.getPublic(), "CN=Test", notBefore, notAfter, null, keyPair.getPrivate(), true,
218                                         0, null, null, new KeyUsage(KeyUsage.nonRepudiation));
219
220         /*
221          * Operate: postSign
222          */
223         testedInstance.postSign(signatureValue, Collections.singletonList(certificate));
224
225         byte[] signedDocumentData = testedInstance.getSignedDocumentData();
226         assertNotNull(signedDocumentData);
227         Document signedDocument = PkiTestUtils.loadDocument(new ByteArrayInputStream(signedDocumentData));
228         LOG.debug("signed document: " + PkiTestUtils.toString(signedDocument));
229
230         NodeList signatureNodeList = signedDocument.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
231         assertEquals(1, signatureNodeList.getLength());
232         Node signatureNode = signatureNodeList.item(0);
233
234         DOMValidateContext domValidateContext = new DOMValidateContext(KeySelector.singletonKeySelector(keyPair.getPublic()), signatureNode);
235         XMLSignatureFactory xmlSignatureFactory = XMLSignatureFactory.getInstance();
236         XMLSignature xmlSignature = xmlSignatureFactory.unmarshalXMLSignature(domValidateContext);
237         boolean validity = xmlSignature.validate(domValidateContext);
238         assertTrue(validity);
239     }
240
241     public static class UriTestDereferencer implements URIDereferencer {
242
243         private final Map<String, byte[]> resources;
244
245         public UriTestDereferencer() {
246             this.resources = new HashMap<String, byte[]>();
247         }
248
249         public void addResource(String uri, byte[] data) {
250             this.resources.put(uri, data);
251         }
252
253         public Data dereference(URIReference uriReference, XMLCryptoContext xmlCryptoContext) throws URIReferenceException {
254             String uri = uriReference.getURI();
255             byte[] data = this.resources.get(uri);
256             if (null == data) {
257                 return null;
258             }
259             return new OctetStreamData(new ByteArrayInputStream(data));
260         }
261     }
262
263     public void testSignExternalUri() throws Exception {
264         // setup
265         DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
266         documentBuilderFactory.setNamespaceAware(true);
267         DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
268         Document document = documentBuilder.newDocument();
269
270         XmlSignatureTestService testedInstance = new XmlSignatureTestService();
271         testedInstance.setEnvelopingDocument(document);
272         testedInstance.addReferenceUri("external-uri");
273         testedInstance.setSignatureDescription("test-signature-description");
274         UriTestDereferencer uriDereferencer = new UriTestDereferencer();
275         uriDereferencer.addResource("external-uri", "hello world".getBytes());
276         testedInstance.setUriDereferencer(uriDereferencer);
277
278         // operate
279         DigestInfo digestInfo = testedInstance.preSign(null, null);
280
281         // verify
282         assertNotNull(digestInfo);
283         LOG.debug("digest info description: " + digestInfo.description);
284         assertEquals("test-signature-description", digestInfo.description);
285         assertNotNull(digestInfo.digestValue);
286         LOG.debug("digest algo: " + digestInfo.digestAlgo);
287         assertEquals("SHA-1", digestInfo.digestAlgo);
288
289         TemporaryTestDataStorage temporaryDataStorage = (TemporaryTestDataStorage) testedInstance.getTemporaryDataStorage();
290         assertNotNull(temporaryDataStorage);
291         InputStream tempInputStream = temporaryDataStorage.getTempInputStream();
292         assertNotNull(tempInputStream);
293         Document tmpDocument = PkiTestUtils.loadDocument(tempInputStream);
294
295         LOG.debug("tmp document: " + PkiTestUtils.toString(tmpDocument));
296         Element nsElement = tmpDocument.createElement("ns");
297         nsElement.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:ds", Constants.SignatureSpecNS);
298         Node digestValueNode = XPathAPI.selectSingleNode(tmpDocument, "//ds:DigestValue", nsElement);
299         assertNotNull(digestValueNode);
300         String digestValueTextContent = digestValueNode.getTextContent();
301         LOG.debug("digest value text content: " + digestValueTextContent);
302         assertFalse(digestValueTextContent.isEmpty());
303
304         /*
305          * Sign the received XML signature digest value.
306          */
307         KeyPair keyPair = PkiTestUtils.generateKeyPair();
308         Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
309         cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPrivate());
310         byte[] digestInfoValue = ArrayUtils.addAll(PkiTestUtils.SHA1_DIGEST_INFO_PREFIX, digestInfo.digestValue);
311         byte[] signatureValue = cipher.doFinal(digestInfoValue);
312
313         DateTime notBefore = new DateTime();
314         DateTime notAfter = notBefore.plusYears(1);
315         X509Certificate certificate = PkiTestUtils.generateCertificate(keyPair.getPublic(), "CN=Test", notBefore, notAfter, null, keyPair.getPrivate(), true,
316                                         0, null, null, new KeyUsage(KeyUsage.nonRepudiation));
317
318         /*
319          * Operate: postSign
320          */
321         testedInstance.postSign(signatureValue, Collections.singletonList(certificate));
322
323         byte[] signedDocumentData = testedInstance.getSignedDocumentData();
324         assertNotNull(signedDocumentData);
325         Document signedDocument = PkiTestUtils.loadDocument(new ByteArrayInputStream(signedDocumentData));
326         LOG.debug("signed document: " + PkiTestUtils.toString(signedDocument));
327
328         NodeList signatureNodeList = signedDocument.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
329         assertEquals(1, signatureNodeList.getLength());
330         Node signatureNode = signatureNodeList.item(0);
331
332         DOMValidateContext domValidateContext = new DOMValidateContext(KeySelector.singletonKeySelector(keyPair.getPublic()), signatureNode);
333         domValidateContext.setURIDereferencer(uriDereferencer);
334         XMLSignatureFactory xmlSignatureFactory = XMLSignatureFactory.getInstance();
335         XMLSignature xmlSignature = xmlSignatureFactory.unmarshalXMLSignature(domValidateContext);
336         boolean validity = xmlSignature.validate(domValidateContext);
337         assertTrue(validity);
338     }
339
340     public void testSignEnvelopingDocumentWithExternalDigestInfo() throws Exception {
341         // setup
342         DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
343         documentBuilderFactory.setNamespaceAware(true);
344         DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
345         Document document = documentBuilder.newDocument();
346         Element rootElement = document.createElementNS("urn:test", "tns:root");
347         rootElement.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:tns", "urn:test");
348         document.appendChild(rootElement);
349
350         XmlSignatureTestService testedInstance = new XmlSignatureTestService();
351         testedInstance.setEnvelopingDocument(document);
352         testedInstance.setSignatureDescription("test-signature-description");
353
354         byte[] refData = "hello world".getBytes();
355         MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
356         messageDigest.update(refData);
357         byte[] digestValue = messageDigest.digest();
358         DigestInfo refDigestInfo = new DigestInfo(digestValue, "SHA-1", "urn:test:ref");
359
360         // operate
361         DigestInfo digestInfo = testedInstance.preSign(Collections.singletonList(refDigestInfo), null);
362
363         // verify
364         assertNotNull(digestInfo);
365         LOG.debug("digest info description: " + digestInfo.description);
366         assertEquals("test-signature-description", digestInfo.description);
367         assertNotNull(digestInfo.digestValue);
368         LOG.debug("digest algo: " + digestInfo.digestAlgo);
369         assertEquals("SHA-1", digestInfo.digestAlgo);
370
371         TemporaryTestDataStorage temporaryDataStorage = (TemporaryTestDataStorage) testedInstance.getTemporaryDataStorage();
372         assertNotNull(temporaryDataStorage);
373         InputStream tempInputStream = temporaryDataStorage.getTempInputStream();
374         assertNotNull(tempInputStream);
375         Document tmpDocument = PkiTestUtils.loadDocument(tempInputStream);
376
377         LOG.debug("tmp document: " + PkiTestUtils.toString(tmpDocument));
378         Element nsElement = tmpDocument.createElement("ns");
379         nsElement.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:ds", Constants.SignatureSpecNS);
380         Node digestValueNode = XPathAPI.selectSingleNode(tmpDocument, "//ds:DigestValue", nsElement);
381         assertNotNull(digestValueNode);
382         String digestValueTextContent = digestValueNode.getTextContent();
383         LOG.debug("digest value text content: " + digestValueTextContent);
384         assertFalse(digestValueTextContent.isEmpty());
385
386         /*
387          * Sign the received XML signature digest value.
388          */
389         KeyPair keyPair = PkiTestUtils.generateKeyPair();
390         Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
391         cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPrivate());
392         byte[] digestInfoValue = ArrayUtils.addAll(PkiTestUtils.SHA1_DIGEST_INFO_PREFIX, digestInfo.digestValue);
393         byte[] signatureValue = cipher.doFinal(digestInfoValue);
394
395         DateTime notBefore = new DateTime();
396         DateTime notAfter = notBefore.plusYears(1);
397         X509Certificate certificate = PkiTestUtils.generateCertificate(keyPair.getPublic(), "CN=Test", notBefore, notAfter, null, keyPair.getPrivate(), true,
398                                         0, null, null, new KeyUsage(KeyUsage.nonRepudiation));
399
400         /*
401          * Operate: postSign
402          */
403         testedInstance.postSign(signatureValue, Collections.singletonList(certificate));
404
405         byte[] signedDocumentData = testedInstance.getSignedDocumentData();
406         assertNotNull(signedDocumentData);
407         Document signedDocument = PkiTestUtils.loadDocument(new ByteArrayInputStream(signedDocumentData));
408         LOG.debug("signed document: " + PkiTestUtils.toString(signedDocument));
409
410         NodeList signatureNodeList = signedDocument.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
411         assertEquals(1, signatureNodeList.getLength());
412         Node signatureNode = signatureNodeList.item(0);
413
414         DOMValidateContext domValidateContext = new DOMValidateContext(KeySelector.singletonKeySelector(keyPair.getPublic()), signatureNode);
415         URIDereferencer dereferencer = new URITest2Dereferencer();
416         domValidateContext.setURIDereferencer(dereferencer);
417         XMLSignatureFactory xmlSignatureFactory = XMLSignatureFactory.getInstance();
418         XMLSignature xmlSignature = xmlSignatureFactory.unmarshalXMLSignature(domValidateContext);
419         boolean validity = xmlSignature.validate(domValidateContext);
420         assertTrue(validity);
421     }
422
423     public void testSignExternalDigestInfo() throws Exception {
424         // setup
425         DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
426         documentBuilderFactory.setNamespaceAware(true);
427         DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
428         Document document = documentBuilder.newDocument();
429
430         XmlSignatureTestService testedInstance = new XmlSignatureTestService();
431         testedInstance.setEnvelopingDocument(document);
432         testedInstance.setSignatureDescription("test-signature-description");
433
434         byte[] refData = "hello world".getBytes();
435         MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
436         messageDigest.update(refData);
437         byte[] digestValue = messageDigest.digest();
438         DigestInfo refDigestInfo = new DigestInfo(digestValue, "SHA-1", "urn:test:ref");
439
440         // operate
441         DigestInfo digestInfo = testedInstance.preSign(Collections.singletonList(refDigestInfo), null);
442
443         // verify
444         assertNotNull(digestInfo);
445         LOG.debug("digest info description: " + digestInfo.description);
446         assertEquals("test-signature-description", digestInfo.description);
447         assertNotNull(digestInfo.digestValue);
448         LOG.debug("digest algo: " + digestInfo.digestAlgo);
449         assertEquals("SHA-1", digestInfo.digestAlgo);
450
451         TemporaryTestDataStorage temporaryDataStorage = (TemporaryTestDataStorage) testedInstance.getTemporaryDataStorage();
452         assertNotNull(temporaryDataStorage);
453         InputStream tempInputStream = temporaryDataStorage.getTempInputStream();
454         assertNotNull(tempInputStream);
455         Document tmpDocument = PkiTestUtils.loadDocument(tempInputStream);
456
457         LOG.debug("tmp document: " + PkiTestUtils.toString(tmpDocument));
458         Element nsElement = tmpDocument.createElement("ns");
459         nsElement.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:ds", Constants.SignatureSpecNS);
460         Node digestValueNode = XPathAPI.selectSingleNode(tmpDocument, "//ds:DigestValue", nsElement);
461         assertNotNull(digestValueNode);
462         String digestValueTextContent = digestValueNode.getTextContent();
463         LOG.debug("digest value text content: " + digestValueTextContent);
464         assertFalse(digestValueTextContent.isEmpty());
465
466         /*
467          * Sign the received XML signature digest value.
468          */
469         KeyPair keyPair = PkiTestUtils.generateKeyPair();
470         Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
471         cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPrivate());
472         byte[] digestInfoValue = ArrayUtils.addAll(PkiTestUtils.SHA1_DIGEST_INFO_PREFIX, digestInfo.digestValue);
473         byte[] signatureValue = cipher.doFinal(digestInfoValue);
474
475         DateTime notBefore = new DateTime();
476         DateTime notAfter = notBefore.plusYears(1);
477         X509Certificate certificate = PkiTestUtils.generateCertificate(keyPair.getPublic(), "CN=Test", notBefore, notAfter, null, keyPair.getPrivate(), true,
478                                         0, null, null, new KeyUsage(KeyUsage.nonRepudiation));
479
480         /*
481          * Operate: postSign
482          */
483         testedInstance.postSign(signatureValue, Collections.singletonList(certificate));
484
485         byte[] signedDocumentData = testedInstance.getSignedDocumentData();
486         assertNotNull(signedDocumentData);
487         Document signedDocument = PkiTestUtils.loadDocument(new ByteArrayInputStream(signedDocumentData));
488         LOG.debug("signed document: " + PkiTestUtils.toString(signedDocument));
489
490         NodeList signatureNodeList = signedDocument.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
491         assertEquals(1, signatureNodeList.getLength());
492         Node signatureNode = signatureNodeList.item(0);
493
494         DOMValidateContext domValidateContext = new DOMValidateContext(KeySelector.singletonKeySelector(keyPair.getPublic()), signatureNode);
495         URIDereferencer dereferencer = new URITest2Dereferencer();
496         domValidateContext.setURIDereferencer(dereferencer);
497         XMLSignatureFactory xmlSignatureFactory = XMLSignatureFactory.getInstance();
498         XMLSignature xmlSignature = xmlSignatureFactory.unmarshalXMLSignature(domValidateContext);
499         boolean validity = xmlSignature.validate(domValidateContext);
500         assertTrue(validity);
501     }
502
503     private static class URITest2Dereferencer implements URIDereferencer {
504
505         private static final Log LOG = LogFactory.getLog(URITest2Dereferencer.class);
506
507         public Data dereference(URIReference uriReference, XMLCryptoContext context) throws URIReferenceException {
508             LOG.debug("dereference: " + uriReference.getURI());
509             return new OctetStreamData(new ByteArrayInputStream("hello world".getBytes()));
510         }
511     }
512
513     public void testJsr105Signature() throws Exception {
514         KeyPair keyPair = PkiTestUtils.generateKeyPair();
515
516         DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
517         documentBuilderFactory.setNamespaceAware(true);
518         DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
519         Document document = documentBuilder.newDocument();
520         Element rootElement = document.createElementNS("urn:test", "tns:root");
521         rootElement.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:tns", "urn:test");
522         document.appendChild(rootElement);
523         Element dataElement = document.createElementNS("urn:test", "tns:data");
524         dataElement.setAttributeNS(null, "Id", "id-1234");
525         dataElement.setTextContent("data to be signed");
526         rootElement.appendChild(dataElement);
527
528         XMLSignatureFactory signatureFactory = XMLSignatureFactory.getInstance("DOM", new org.jcp.xml.dsig.internal.dom.XMLDSigRI());
529
530         XMLSignContext signContext = new DOMSignContext(keyPair.getPrivate(), document.getDocumentElement());
531         signContext.putNamespacePrefix(javax.xml.crypto.dsig.XMLSignature.XMLNS, "ds");
532
533         DigestMethod digestMethod = signatureFactory.newDigestMethod(DigestMethod.SHA1, null);
534         Reference reference = signatureFactory.newReference("#id-1234", digestMethod);
535         DOMReference domReference = (DOMReference) reference;
536         assertNull(domReference.getCalculatedDigestValue());
537         assertNull(domReference.getDigestValue());
538
539         SignatureMethod signatureMethod = signatureFactory.newSignatureMethod(SignatureMethod.RSA_SHA1, null);
540         CanonicalizationMethod canonicalizationMethod = signatureFactory.newCanonicalizationMethod(CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS,
541                                         (C14NMethodParameterSpec) null);
542         SignedInfo signedInfo = signatureFactory.newSignedInfo(canonicalizationMethod, signatureMethod, Collections.singletonList(reference));
543
544         javax.xml.crypto.dsig.XMLSignature xmlSignature = signatureFactory.newXMLSignature(signedInfo, null);
545
546         DOMXMLSignature domXmlSignature = (DOMXMLSignature) xmlSignature;
547         domXmlSignature.marshal(document.getDocumentElement(), "ds", (DOMCryptoContext) signContext);
548         domReference.digest(signContext);
549         // xmlSignature.sign(signContext);
550         // LOG.debug("signed document: " + toString(document));
551
552         Element nsElement = document.createElement("ns");
553         nsElement.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:ds", Constants.SignatureSpecNS);
554         Node digestValueNode = XPathAPI.selectSingleNode(document, "//ds:DigestValue", nsElement);
555         assertNotNull(digestValueNode);
556         String digestValueTextContent = digestValueNode.getTextContent();
557         LOG.debug("digest value text content: " + digestValueTextContent);
558         assertFalse(digestValueTextContent.isEmpty());
559     }
560 }