/* * XAdES4j - A Java library for generation and verification of XAdES signatures. * Copyright (C) 2010 Luis Goncalves. * * XAdES4j is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 3 of the License, or any later version. * * XAdES4j is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License along * with XAdES4j. If not, see <http://www.gnu.org/licenses/>. */ package xades4j.production; import org.apache.xml.security.utils.Constants; import org.w3c.dom.Element; import xades4j.properties.CounterSignatureProperty; import xades4j.properties.QualifyingProperty; import xades4j.XAdES4jException; import xades4j.properties.data.GenericDOMData; import xades4j.properties.data.PropertyDataObject; import xades4j.utils.DOMHelper; /** * * @author Luís */ class DataGenCounterSig implements PropertyDataObjectGenerator<CounterSignatureProperty> { /* * XAdES section 7.2.4.2: * "The content of this property is a XMLDSIG or XAdES signature whose ds:SignedInfo * MUST contain one ds:Reference element referencing the ds:SignatureValue element * of the embedding and countersigned XAdES signature. The content of the ds:DigestValue * in the aforementioned ds:Reference element of the countersignature MUST be the * base-64 encoded digest of the complete (and canonicalized) ds:SignatureValue * element (i.e. including the starting and closing tags) of the embedding and * countersigned XAdES signature." */ /* The ds:Reference element described above can be obtained with the default * XML-DSIG behaviour. We just need to reference the ds:SignatureValue element. */ @Override public PropertyDataObject generatePropertyData( CounterSignatureProperty prop, PropertiesDataGenerationContext ctx) throws PropertyDataGenerationException { // The element has to be in the document tree for the references to be // resolved. UGLY WORKAROUND. Element qPs = DOMHelper.getFirstDescendant(ctx.getTargetXmlSignature().getElement(), QualifyingProperty.XADES_XMLNS, QualifyingProperty.QUALIFYING_PROPS_TAG); // Create the CounterSignature property element. Element counterSigElem = ctx.createElementInSignatureDoc( "CounterSignature", qPs.getPrefix(), QualifyingProperty.XADES_XMLNS); qPs.appendChild(counterSigElem); try { // Rerence to the ds:SignatureValue element. This assumes that the // QualifyingProperties are in the signature's document and that the // SignatureValue element has an Id. Element sigValueElem = DOMHelper.getFirstDescendant( ctx.getTargetXmlSignature().getElement(), Constants.SignatureSpecNS, Constants._TAG_SIGNATUREVALUE); String sigValueId = sigValueElem.getAttribute(Constants._ATT_ID); DataObjectReference sigValueRef = new DataObjectReference('#' + sigValueId) .withType(CounterSignatureProperty.COUNTER_SIGNATURE_TYPE_URI); XadesSigner counterSigner = prop.getCounterSigSigner(); if (null == counterSigner) throw new PropertyDataGenerationException(prop, "signer not specified"); try { SignedDataObjects objs = prop.getSignedDataObjectsForCounterSig(); if(null == objs) objs = new SignedDataObjects(); objs.withSignedDataObject(sigValueRef); counterSigner.sign(objs, counterSigElem); } catch (XAdES4jException ex) { throw new PropertyDataGenerationException(prop, "cannot apply counter signature", ex); } } finally { qPs.removeChild(counterSigElem); } return new GenericDOMData(counterSigElem); } }