From d99cfe38205a8bae9a4bc9d59a2e8be25d0007ea Mon Sep 17 00:00:00 2001 From: tkellner Date: Wed, 25 Jan 2012 14:37:01 +0000 Subject: Add configurable option to create XAdES 1.4 signatures git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@1011 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../impl/CreateXMLSignatureCommandImpl.java | 9 +- .../egiz/bku/slcommands/impl/xsect/Signature.java | 153 ++++++++++++++++++++- 2 files changed, 154 insertions(+), 8 deletions(-) diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandImpl.java index 5d604abf..4827ab16 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandImpl.java @@ -98,6 +98,7 @@ public class CreateXMLSignatureCommandImpl extends private Configuration configuration; public static final String USE_STRONG_HASH = "useStrongHash"; + public static final String USE_XADES_1_4 = "useXAdES14"; public void setConfiguration(Configuration configuration) { this.configuration = configuration; @@ -106,7 +107,11 @@ public class CreateXMLSignatureCommandImpl extends public boolean getUseStrongHash() { return configuration.getBoolean(USE_STRONG_HASH, false); } - } + + public boolean getUseXAdES14() { + return configuration.getBoolean(USE_XADES_1_4, false); + } +} public void setConfiguration(Configuration configuration) { configurationFacade.setConfiguration(configuration); @@ -132,7 +137,7 @@ public class CreateXMLSignatureCommandImpl extends } signature = new Signature(commandContext.getURLDereferencer(), - idValueFactory, algorithmMethodFactory); + idValueFactory, algorithmMethodFactory, configurationFacade.getUseXAdES14()); // SigningTime signature.setSigningTime(new Date()); diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java index 2e489ac3..bbf44513 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java @@ -61,8 +61,8 @@ import javax.xml.stream.XMLStreamException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.etsi.uri._01903.v1_1.DataObjectFormatType; -import org.etsi.uri._01903.v1_1.QualifyingPropertiesType; +//import org.etsi.uri._01903.v1_1.DataObjectFormatType; +//import org.etsi.uri._01903.v1_1.QualifyingPropertiesType; import org.w3c.dom.DOMConfiguration; import org.w3c.dom.DOMException; import org.w3c.dom.Document; @@ -93,6 +93,7 @@ import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer; import at.gv.egiz.dom.DOMUtils; import at.gv.egiz.slbinding.impl.XMLContentType; import at.gv.egiz.stal.STAL; +import at.gv.egiz.xades.QualifyingProperties1_4Factory; import at.gv.egiz.xades.QualifyingPropertiesException; import at.gv.egiz.xades.QualifyingPropertiesFactory; @@ -156,13 +157,21 @@ public class Signature { */ private Date signingTime; + /** + * Whether to use XAdES v1.4 (v1.1 else) + */ + private boolean useXAdES14; + /** * Creates a new SLXMLSignature instance. * @param urlDereferencer TODO */ public Signature(URLDereferencer urlDereferencer, IdValueFactory idValueFactory, - AlgorithmMethodFactory algorithmMethodFactory) { + AlgorithmMethodFactory algorithmMethodFactory, + boolean useXAdES14) { + + this.useXAdES14 = useXAdES14; domImplLS = DOMUtils.getDOMImplementationLS(); @@ -345,7 +354,10 @@ public class Signature { } } - addXAdESObjectAndReference(objects, references, signatureId); + if (useXAdES14) + addXAdES1_4ObjectAndReference(objects, references, signatureId); + else + addXAdESObjectAndReference(objects, references, signatureId); XMLSignatureFactory signatureFactory = ctx.getSignatureFactory(); AlgorithmMethodFactory algorithmMethodFactory = ctx.getAlgorithmMethodFactory(); @@ -621,7 +633,7 @@ public class Signature { // XAdES QualifyingProperties. However MOA-SP supports only version 1.1.1. Therefore, // the version 1.1.1 is used in order to be compatible with current MOA-SP versions. - List dataObjectFormats = new ArrayList(); + List dataObjectFormats = new ArrayList(); for (DataObject dataObject : dataObjects) { if (dataObject.getMimeType() != null && dataObject.getReference() != null) { Reference reference = dataObject.getReference(); @@ -647,7 +659,7 @@ public class Signature { throw new SLCommandException(4006); } - JAXBElement qualifyingProperties; + JAXBElement qualifyingProperties; try { qualifyingProperties = factory.createQualifyingProperties111(target, date, signingCertificates, idValue, dataObjectFormats, dm); } catch (QualifyingPropertiesException e) { @@ -716,6 +728,135 @@ public class Signature { } + /** + * Adds the XAdES 1.4 QualifyingProperties as an + * ds:Object and a corresponding ds:Reference to + * it's SignedProperties element to this Signature. + * + * @param objects + * the list of ds:Objects to add the created + * ds:Object to + * @param references + * the list of ds:References to add the created + * ds:Reference to + * @param signatureId TODO + * @throws SLCommandException + * if creating and adding the XAdES + * QualifyingProperties fails + * @throws NullPointerException + * if objects or references is + * null + */ + private void addXAdES1_4ObjectAndReference(List objects, List references, String signatureId) throws SLCommandException { + + QualifyingProperties1_4Factory factory = QualifyingProperties1_4Factory.getInstance(); + + String idValue = ctx.getIdValueFactory().createIdValue("SignedProperties"); + + Date date = (signingTime != null) ? signingTime : new Date(); + + List signingCertificates; + if (signerCertificate != null) { + signingCertificates = Collections.singletonList(signerCertificate); + } else { + signingCertificates = Collections.emptyList(); + } + + List dataObjectFormats = new ArrayList(); + for (DataObject dataObject : dataObjects) { + if (dataObject.getMimeType() != null && dataObject.getReference() != null) { + Reference reference = dataObject.getReference(); + if (reference.getId() != null) { + String objectReference = "#" + reference.getId(); + dataObjectFormats.add(factory.createDataObjectFormatType( + objectReference, dataObject.getMimeType(), dataObject + .getDescription())); + } + } + } + + String target = "#" + signatureId; + + DigestMethod dm; + try { + dm = ctx.getAlgorithmMethodFactory().createDigestMethod(ctx); + } catch (NoSuchAlgorithmException e) { + log.error("Failed to get DigestMethod algorithm.", e); + throw new SLCommandException(4006); + } catch (InvalidAlgorithmParameterException e) { + log.error("Failed to get DigestMethod algorithm.", e); + throw new SLCommandException(4006); + } + + JAXBElement qualifyingProperties; + try { + qualifyingProperties = factory.createQualifyingProperties141(target, date, signingCertificates, idValue, dataObjectFormats, dm); + } catch (QualifyingPropertiesException e) { + log.error("Failed to create QualifyingProperties.", e); + throw new SLCommandException(4000); + } + + DocumentFragment fragment = ctx.getDocument().createDocumentFragment(); + + try { + factory.marshallQualifyingProperties(qualifyingProperties, fragment); + } catch (JAXBException e) { + log.error("Failed to marshal QualifyingProperties.", e); + throw new SLCommandException(4000); + } + + List content = Collections.singletonList(new DOMStructure(fragment.getFirstChild())); + + String objectIdValue = ctx.getIdValueFactory().createIdValue("Object"); + + XMLObject object = ctx.getSignatureFactory().newXMLObject(content, objectIdValue, null, null); + + objects.add(object); + + // TODO: Report MOA-SP Bug + // + // Direct referencing of the SignedPorperties Id-attribute is not supported by MOA-SP + // because the QualifyingProperties are parsed without the XAdES schema. Therefore, + // the shorthand XPointer could not be resolved. + // + // The following workaround uses an XPointer to select the SignedProperties in order + // to allow the signature to be verified with MOA-SP. + + String referenceURI = "#xmlns(xades=http://uri.etsi.org/01903/v1.4.1%23)%20xpointer(id('" + + objectIdValue + + "')/child::xades:QualifyingProperties/child::xades:SignedProperties)"; + + String referenceIdValue = ctx.getIdValueFactory().createIdValue("Reference"); + String referenceType = QualifyingProperties1_4Factory.SIGNED_PROPERTIES_REFERENCE_TYPE_V1_4_1; + + try { + dm = ctx.getAlgorithmMethodFactory().createDigestMethod(ctx); + } catch (NoSuchAlgorithmException e) { + log.error("Failed to get DigestMethod algorithm.", e); + throw new SLCommandException(4006); + } catch (InvalidAlgorithmParameterException e) { + log.error("Failed to get DigestMethod algorithm.", e); + throw new SLCommandException(4006); + } + + Reference reference = ctx.getSignatureFactory().newReference(referenceURI, dm, null, referenceType, referenceIdValue); + + references.add(reference); + + Node child = fragment.getFirstChild(); + if (child instanceof Element) { + NodeList nodes = ((Element) child).getElementsByTagNameNS(QualifyingProperties1_4Factory.NS_URI_V1_4_1, "SignedProperties"); + if (nodes.getLength() > 0) { + IdAttribute idAttribute = new IdAttribute(); + idAttribute.element = (Element) nodes.item(0); + idAttribute.namespaceURI = null; + idAttribute.localName = "Id"; + idAttributes.add(idAttribute); + } + } + + } + /** * Parse the SignatureEnvironment. * -- cgit v1.2.3