From 0872d2d8a64fd701776b272f49222428d8def07f Mon Sep 17 00:00:00 2001
From: Andreas Fitzek
+ * Only the following cases of XMLSignatureCreationModule
.
+ *
+ * This class performs the invocation of the
+ * iaik.server.modules.xmlsign.XMLSignatureCreationModule
from a
+ * CreateXMLSignatureRequest
given as an API object. The result of
+ * the invocation is integrated into a CreateXMLSignatureResponse
+ * and returned.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class XMLSignatureCreationInvoker {
+
+ /** The single instance of this class. */
+ private static XMLSignatureCreationInvoker instance = null;
+
+ /**
+ * Get the only instance of this class.
+ *
+ * @return The only instance of this class.
+ */
+ public static synchronized XMLSignatureCreationInvoker getInstance() {
+ if (instance == null) {
+ instance = new XMLSignatureCreationInvoker();
+ }
+ return instance;
+ }
+
+ /**
+ * Create a new XMLSignatureCreationInvoker
.
+ *
+ * Protected to disallow multiple instances.
+ */
+ protected XMLSignatureCreationInvoker() {
+ }
+
+ /**
+ * Process the CreateXMLSignatureRequest
message and invoke the
+ *
XMLSignatureCreationModule
for every
+ * SingleSignatureInfo
contained in the request.
+ *
+ * @param request A CreateXMLSignatureRequest
API object
+ * containing the information for creating the signature(s).
+ * @param reserved A
Set
of reserved object IDs.
+ *
+ * @return A CreateXMLSignatureResponse
API object containing
+ * the created signature(s). The response contains either a
+ * SignatureEnvironment
or a ErrorResponse
+ * for each SingleSignatureInfo
in the request.
+ * @throws MOAException An error occurred during signature creation.
+ */
+ public CreateXMLSignatureResponse createXMLSignature(
+ CreateXMLSignatureRequest request,
+ Set reserved)
+ throws MOAException {
+
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ LoggingContext loggingCtx =
+ LoggingContextManager.getInstance().getLoggingContext();
+ reserved = new HashSet(reserved);
+ XMLSignatureCreationProfileFactory profileFactory =
+ new XMLSignatureCreationProfileFactory(request, reserved);
+ CreateXMLSignatureResponseBuilder responseBuilder =
+ new CreateXMLSignatureResponseBuilder();
+ int createCount = 1;
+ IdGenerator refIdGen;
+ XMLSignatureCreationModule module;
+ Iterator singleSignatureInfoIter;
+
+ // create the XMLSignatureCreationModule and configure it
+ module = XMLSignatureCreationModuleFactory.getInstance();
+ module.setLog(new IaikLog(loggingCtx.getNodeID()));
+
+ // select the SingleSignatureInfo elements
+ singleSignatureInfoIter = request.getSingleSignatureInfos().iterator();
+
+ // iterate over all the SingleSignatureInfo elements in the request
+ while (singleSignatureInfoIter.hasNext()) {
+ SingleSignatureInfo singleSignatureInfo =
+ (SingleSignatureInfo) singleSignatureInfoIter.next();
+ CreateSignatureInfo createSignatureInfo;
+ List dataObjectList;
+ XMLSignatureCreationProfile profile;
+ XMLDataObject signatureEnvironment;
+ XMLDataObject signatureParent;
+ XMLSignature signature;
+ List additionalSignedProperties;
+ Node signatureEnvironmentParent = null;
+ Element requestElement = null;
+
+ try {
+
+ // build the signature environment
+ createSignatureInfo = singleSignatureInfo.getCreateSignatureInfo();
+ if (createSignatureInfo != null) {
+ DataObjectFactory dataObjFactory = DataObjectFactory.getInstance();
+
+ signatureEnvironment =
+ dataObjFactory.createSignatureEnvironment(
+ createSignatureInfo.getCreateSignatureEnvironment(),
+ getCreateSignatureEnvironmentProfileSupplements(singleSignatureInfo));
+ } else {
+ signatureEnvironment = null;
+ }
+
+ HashSet sigInfoReservedIDs = new HashSet();
+ if (signatureEnvironment != null)
+ {
+ // Find Id attributes of existing XML signatures in signature environment
+ HashMap nSMap = new HashMap();
+ String dsp = Constants.DSIG_PREFIX;
+ nSMap.put(dsp, Constants.DSIG_NS_URI);
+ String xPathExpr = "//" + dsp + ":Signature/@Id | //" + dsp + ":Reference/@Id | //"
+ + dsp + ":Object/@Id | //" + dsp + ":Manifest/@Id";
+ NodeList idAttrs = XPathUtils.selectNodeList(signatureEnvironment.getElement(), nSMap, xPathExpr);
+
+ // Add found Id attributes to set of reserved IDs
+ for (int i = 0; i < idAttrs.getLength(); i++) sigInfoReservedIDs.add(idAttrs.item(i).getNodeValue());
+ }
+
+ // create the reference id generator
+ HashSet allReservedIDs = new HashSet(reserved);
+ allReservedIDs.addAll(sigInfoReservedIDs);
+ refIdGen = new IdGenerator("reference-" + createCount++, allReservedIDs);
+
+ // build the list of DataObjects
+ List createTransformsProfiles = profileFactory.getCreateTransformsInfoProfiles(singleSignatureInfo);
+ dataObjectList =
+ buildDataObjectList(
+ singleSignatureInfo,
+ createTransformsProfiles,
+ signatureEnvironment,
+ refIdGen);
+
+ // build the XMLSignatureCreationProfile
+ profile = profileFactory.createProfile(singleSignatureInfo, sigInfoReservedIDs);
+
+ // build the additionalSignedProperties
+ additionalSignedProperties = buildAdditionalSignedProperties();
+
+ // build the signatureParentElement
+ if (signatureEnvironment != null) {
+ signatureParent =
+ buildSignatureParentElement(
+ signatureEnvironment.getElement(),
+ singleSignatureInfo);
+ } else {
+ signatureParent = null;
+ }
+
+ // make the signature environment the root of the document, if it is
+ // not a separate document anyway; this is done to assure that
+ // canonicalization of the signature environment contains the correct
+ // namespace declarations
+ if (signatureEnvironment != null) {
+ Document requestDoc =
+ signatureEnvironment.getElement().getOwnerDocument();
+ requestElement = requestDoc.getDocumentElement();
+ if (requestElement != signatureEnvironment.getElement()) {
+ signatureEnvironmentParent =
+ signatureEnvironment.getElement().getParentNode();
+ requestElement.getOwnerDocument().replaceChild(
+ signatureEnvironment.getElement(),
+ requestElement);
+ }
+ }
+
+ try {
+ ConfigurationProvider config = context.getConfiguration();
+ String xadesVersion = config.getXAdESVersion();
+
+ if (xadesVersion!= null && xadesVersion.compareTo(XMLSignatureCreationModule.XADES_VERSION_1_4_2) == 0) {
+ // create the signature (XAdES 1.4.2)
+ signature =
+ module.createSignature(
+ dataObjectList,
+ profile,
+ additionalSignedProperties,
+ signatureParent,
+ XMLSignatureCreationModule.XADES_VERSION_1_4_2,
+ new TransactionId(context.getTransactionID()));
+ }
+ else {
+ // create the signature (XAdES 1.1.1 = default)
+ signature =
+ module.createSignature(
+ dataObjectList,
+ profile,
+ additionalSignedProperties,
+ signatureParent,
+ XMLSignatureCreationModule.XADES_VERSION_1_1_1,
+ new TransactionId(context.getTransactionID()));
+ }
+
+ // insert the result into the response
+ if (signatureParent != null) {
+ responseBuilder.addSignatureEnvironment(
+ signatureEnvironment.getElement());
+ } else {
+ responseBuilder.addSignatureEnvironment(signature.getElement());
+ }
+
+ } catch (IAIKException e) {
+ MOAException moaException = IaikExceptionMapper.getInstance().map(e);
+
+ responseBuilder.addError(
+ moaException.getMessageId(),
+ moaException.getMessage());
+ Logger.warn(moaException.getMessage(), e);
+ } catch (IAIKRuntimeException e) {
+ MOAException moaException = IaikExceptionMapper.getInstance().map(e);
+
+ responseBuilder.addError(
+ moaException.getMessageId(),
+ moaException.getMessage());
+ Logger.warn(moaException.getMessage(), e);
+ }
+
+ // swap back in the request as root document
+ if (signatureEnvironment != null) {
+ if (requestElement != signatureEnvironment.getElement()) {
+ requestElement.getOwnerDocument().replaceChild(
+ requestElement,
+ signatureEnvironment.getElement());
+ signatureEnvironmentParent.appendChild(
+ signatureEnvironment.getElement());
+ }
+ }
+
+ } catch (MOAException e) {
+ responseBuilder.addError(e.getMessageId(), e.getMessage());
+ Logger.warn(e.getMessage(), e);
+ }
+
+ }
+
+ return responseBuilder.getResponse();
+ }
+
+ /**
+ * Build the list of DataObject
s from the given
+ * SingleSignatureInfo
object.
+ *
+ * DataObject
s are
+ * valid in case of an enveloping signature:
+ *
+ *
+ *
+ * Reference == null && Content != null
: The
+ * Content
will be used in the DataObject
.Reference != null && Content == null
: Resolve the
+ * Reference
and use it as DataObject
.
+ * Set the Reference
in the DataObject
as well.
+ * Only the following cases of DataObject
s are valid in case
+ * of a detached signature:
+ *
+ *
Reference != null && Content == null
: Resolve the
+ * Reference
and use it as DataObject
.
+ * Set the Reference
in the DataObject
as well.Reference != null && Content != null
: The
+ * Content
will be used in the DataObject
.
+ * Set the Reference
in the DataObject
as well.+ * All other cases will lead to an error. + *
+ * + * @param singleSignatureInfo TheSingleSignatureInfo
object
+ * containing the DataObjectInfo
objects.
+ * @param createTransformsProfiles A list of objects of type {@link CreateTransformsInfoProfileExplicit},
+ * each representing the transforms info profile information for the corresponding DataObject
.
+ * @param signatureEnvironment The
+ * @param idGen The ID generator for DataObject
references.
+ * @return The List
of DataObject
s contained in the
+ * given singleSignatureInfo
.
+ * @throws MOASystemException A system error occurred building the data
+ * objects.
+ * @throws MOAApplicationException An error occurred building the data
+ * objects.
+ */
+ private List buildDataObjectList(
+ SingleSignatureInfo singleSignatureInfo,
+ List createTransformsProfiles,
+ XMLDataObject signatureEnvironment,
+ IdGenerator idGen)
+ throws MOASystemException, MOAApplicationException {
+
+ List dataObjInfos = singleSignatureInfo.getDataObjectInfos();
+ List dataObjects = new ArrayList();
+ Iterator dtIter;
+ Iterator ctpIter = createTransformsProfiles.iterator();
+
+ for (dtIter = dataObjInfos.iterator(); dtIter.hasNext();)
+ {
+ DataObjectInfo dataObjInfo = (DataObjectInfo) dtIter.next();
+ String structure = dataObjInfo.getStructure();
+
+ CreateTransformsInfoProfileExplicit transformsProfile =
+ (CreateTransformsInfoProfileExplicit) ctpIter.next();
+ MetaInfo finalDataMetaInfo = transformsProfile.getCreateTransformsInfo().getFinalDataMetaInfo();
+
+ if (DataObjectInfo.STRUCTURE_ENVELOPING.equals(structure)) {
+ dataObjects.add(
+ buildEnvelopingDataObject(
+ dataObjInfo.getDataObject(),
+ finalDataMetaInfo,
+ idGen.uniqueId()));
+ } else if (DataObjectInfo.STRUCTURE_DETACHED.equals(structure)) {
+ dataObjects.add(
+ buildDetachedDataObject(
+ dataObjInfo.getDataObject(),
+ finalDataMetaInfo,
+ signatureEnvironment,
+ idGen.uniqueId()));
+ } else {
+ throw new MOAApplicationException("1103", new Object[] { structure });
+ }
+ }
+
+ return dataObjects;
+
+ }
+
+ /**
+ * Build a DataObject
to be used in an enveloping
+ * signature.
+ *
+ * @param content The Content
object containing the data object.
+ * ContentOptionalRefType
.
+ * @param finalDataMetaInfo The meta information corresponding with content
.
+ * @param referenceID The reference ID to use in the signature for the
+ * DataObject
created.
+ * @return The DataObject
representing the data contained in
+ * dataObjectElem
.
+ * @throws MOAApplicationException An error occurred during the creation of
+ * the DataObject
.
+ * @throws MOASystemException A system error occurred during the creation of
+ * the DataObject
.
+ */
+ private DataObject buildEnvelopingDataObject(
+ Content content,
+ MetaInfo finalDataMetaInfo,
+ String referenceID)
+ throws MOASystemException, MOAApplicationException {
+
+ DataObjectFactory factory = DataObjectFactory.getInstance();
+ DataObject dataObject;
+
+ dataObject =
+ factory.createFromContentOptionalRefType(
+ content,
+ finalDataMetaInfo,
+ referenceID,
+ false,
+ false,
+ true,
+ false);
+
+ return dataObject;
+ }
+
+ /**
+ * Build a DataObject
to be used in a detached signature.
+ *
+ * @param content The Content
object containing an the data.
+ * @param finalDataMetaInfo The meta information corresponding with content
.
+ * @param signatureEnvironment The signature environment where the signature
+ * will be inserted.
+ * @param referenceID The reference ID to use in the signature for the
+ * DataObject
created.
+ * @return The DataObject
representing the data contained in
+ * dataObjectElem
.
+ * @throws MOAApplicationException An error occurred during the creation of
+ * the DataObject
.
+ * @throws MOASystemException A system error occurred during the creation of
+ * the DataObject
.
+ */
+ private DataObject buildDetachedDataObject(
+ Content content,
+ MetaInfo finalDataMetaInfo,
+ XMLDataObject signatureEnvironment,
+ String referenceID)
+ throws MOASystemException, MOAApplicationException {
+
+ String reference = content.getReference();
+ DataObjectFactory factory = DataObjectFactory.getInstance();
+ DataObject dataObject;
+
+ if (reference == null) {
+ throw new MOAApplicationException("1102", null);
+ } else if ("".equals(reference) || reference.startsWith("#")) {
+ dataObject =
+ factory.createFromSignatureEnvironment(
+ signatureEnvironment.getElement(),
+ reference,
+ referenceID);
+ } else {
+ dataObject =
+ factory.createFromContentOptionalRefType(
+ content,
+ finalDataMetaInfo,
+ referenceID,
+ true,
+ false,
+ true,
+ false);
+ }
+ return dataObject;
+ }
+
+ /**
+ * Build the signature parent element.
+ *
+ * @param signatureEnvironment The signature environment containing the
+ * document in which to insert the signature.
+ * @param singleSignatureInfo The SingleSignatureInfo
+ * containing the signature parent element.
+ * @return An XMLDataObject
containing the signature parent
+ * element or null
, if the CreateSignatureInfo
is
+ * null
.
+ * @throws MOAApplicationException An error occurred during the creation of
+ * the signature parent.
+ */
+ private XMLDataObject buildSignatureParentElement(
+ Element signatureEnvironment,
+ SingleSignatureInfo singleSignatureInfo)
+ throws MOAApplicationException {
+
+ CreateSignatureInfo createInfo =
+ singleSignatureInfo.getCreateSignatureInfo();
+
+ // evaluate the CreateSignatureLocation
+ if (createInfo != null) {
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ ConfigurationProvider config = context.getConfiguration();
+ CreateSignatureEnvironmentProfileExplicit createProfile =
+ ProfileMapper.mapCreateSignatureEnvironmentProfile(
+ createInfo.getCreateSignatureEnvironmentProfile(),
+ config);
+ CreateSignatureLocation location =
+ createProfile.getCreateSignatureLocation();
+ Element signatureParent =
+ InvokerUtils.evaluateSignatureLocation(signatureEnvironment, location);
+
+ return new XMLDataObjectImpl(signatureParent);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Get the supplements contained in the
+ * CreateSignatureEnvironmentProfile
of the given
+ * SingleSignatureInfo
.
+ *
+ * @param singleSigInfo The SingleSignatureInfo
from which
+ * to extract the supplements.
+ * @return A List
of XMLDataObjectAssociation
s
+ * or null
, if the singleSigInfo
does not contain
+ * supplements.
+ * @throws MOAApplicationException An error occurred parsing the
+ * CreateSignatureEnvironmentProfile
.
+ */
+ private List getCreateSignatureEnvironmentProfileSupplements(SingleSignatureInfo singleSigInfo)
+ throws MOAApplicationException {
+ CreateSignatureInfo sigInfo = singleSigInfo.getCreateSignatureInfo();
+
+ if (sigInfo != null) {
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ ConfigurationProvider config = context.getConfiguration();
+ CreateSignatureEnvironmentProfileExplicit profile =
+ ProfileMapper.mapCreateSignatureEnvironmentProfile(
+ sigInfo.getCreateSignatureEnvironmentProfile(),
+ config);
+ List supplements = profile.getSupplements();
+
+ return supplements;
+ }
+ return null;
+ }
+
+ /**
+ * Build the list of additional signed properties.
+ *
+ * Based on the generic configuration setting
+ * ConfigurationProvider.TEST_SIGNING_TIME_PROPERTY
, a
+ * constant SigningTime
will be added to the properties.
+ *
+ * @return The List
of additional signed properties.
+ */
+ private List buildAdditionalSignedProperties() {
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ ConfigurationProvider config = context.getConfiguration();
+ List additionalSignedProperties = Collections.EMPTY_LIST;
+
+ return additionalSignedProperties;
+ }
+
+}
\ No newline at end of file
--
cgit v1.2.3