aboutsummaryrefslogtreecommitdiff
path: root/spss/server/serverlib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationProfileFactory.java
diff options
context:
space:
mode:
Diffstat (limited to 'spss/server/serverlib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationProfileFactory.java')
-rw-r--r--spss/server/serverlib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationProfileFactory.java479
1 files changed, 479 insertions, 0 deletions
diff --git a/spss/server/serverlib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationProfileFactory.java b/spss/server/serverlib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationProfileFactory.java
new file mode 100644
index 000000000..5c4a2c76a
--- /dev/null
+++ b/spss/server/serverlib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationProfileFactory.java
@@ -0,0 +1,479 @@
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-SPSS has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import iaik.server.modules.algorithms.HashAlgorithms;
+import iaik.server.modules.keys.KeyEntryID;
+import iaik.server.modules.keys.KeyModule;
+import iaik.server.modules.keys.KeyModuleFactory;
+import iaik.server.modules.xmlsign.SignatureStructureTypes;
+import iaik.server.modules.xmlsign.XMLSignatureCreationProfile;
+import iaik.server.modules.xmlsign.XMLSignatureInsertionLocation;
+
+import java.math.BigInteger;
+import java.security.Principal;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import at.gv.egovernment.moa.logging.LogMsg;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.MOASystemException;
+import at.gv.egovernment.moa.spss.api.common.XMLDataObjectAssociation;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureEnvironmentProfileExplicit;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureInfo;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfoProfileExplicit;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureRequest;
+import at.gv.egovernment.moa.spss.api.xmlsign.DataObjectInfo;
+import at.gv.egovernment.moa.spss.api.xmlsign.SingleSignatureInfo;
+import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider;
+import at.gv.egovernment.moa.spss.server.config.KeyGroupEntry;
+import at.gv.egovernment.moa.spss.server.iaik.xml.CanonicalizationImpl;
+import at.gv.egovernment.moa.spss.server.iaik.xmlsign.DataObjectTreatmentImpl;
+import at.gv.egovernment.moa.spss.server.iaik.xmlsign.XMLSignatureCreationProfileImpl;
+import at.gv.egovernment.moa.spss.server.iaik.xmlsign.XMLSignatureInsertionLocationImpl;
+import at.gv.egovernment.moa.spss.server.logging.TransactionId;
+import at.gv.egovernment.moa.spss.server.transaction.TransactionContext;
+import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager;
+import at.gv.egovernment.moa.spss.server.util.IdGenerator;
+import at.gv.egovernment.moa.spss.util.MessageProvider;
+import at.gv.egovernment.moa.util.Constants;
+
+/**
+ * A factory to create <code>XMLSignatureCreationProfile</code>s from a
+ * <code>CreateXMLSignatureRequest</code>, based on the current MOA
+ * configuration.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class XMLSignatureCreationProfileFactory {
+
+ private static Map HASH_ALGORITHM_MAPPING;
+
+ static {
+ HASH_ALGORITHM_MAPPING = new HashMap();
+ HASH_ALGORITHM_MAPPING.put(Constants.SHA1_URI, HashAlgorithms.SHA1);
+ }
+
+ /** The <code>CreateXMLSignatureRequest</code> for which to create the
+ * profile.*/
+ private CreateXMLSignatureRequest request;
+ /** How many profiles have been created based on the same request. */
+ private int createProfileCount;
+ /** The <code>Set</code> of reserved object IDs.*/
+ private Set reserved;
+
+ /**
+ * Create a new <code>XMLSignatureCreationProfileFactory</code>.
+ *
+ * @param request The request for which to create profiles.
+ * @param reserved The <code>Set</code> of reserved object IDs. IDs will
+ * be added during signature creation.
+ */
+ public XMLSignatureCreationProfileFactory(
+ CreateXMLSignatureRequest request,
+ Set reserved) {
+ this.request = request;
+ this.reserved = reserved;
+ createProfileCount = 1;
+ }
+
+ /**
+ * Create a <code>XMLSignatureCreationProfile</code> for the given
+ * <code>SingleSignatureInfo</code> object..
+ *
+ * @param singleSignatureInfo The <code>SingleSignatureInfo</code> object
+ * containing information about the creation of a signature.
+ * @param sigInfoReservedIDs The <code>Set</code> of reserved ID attribue values
+ * for the particular <code>singleSignatureInfo</code>.
+ * @return The <code>XMLSignatureCreationProfile</code> containing additional
+ * information for creating an XML signature.
+ * @throws MOASystemException A system error occurred during creation of the
+ * profile. See message for details
+ * @throws MOAApplicationException An application error occurred during
+ * creation of the profile. See message for details.
+ */
+ public XMLSignatureCreationProfile createProfile(SingleSignatureInfo singleSignatureInfo,
+ Set sigInfoReservedIDs) throws MOASystemException, MOAApplicationException {
+
+ HashSet allReservedIDs = new HashSet(reserved);
+ allReservedIDs.addAll(sigInfoReservedIDs);
+
+ XMLSignatureCreationProfileImpl profile =
+ new XMLSignatureCreationProfileImpl(createProfileCount, allReservedIDs);
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ ConfigurationProvider config = context.getConfiguration();
+ CanonicalizationImpl canonicalization;
+ List dataObjectTreatmentList;
+ String keyGroupID;
+ Set keySet;
+ List transformationSupplements;
+ List createTransformsProfiles;
+
+ // build the transformation supplements
+ createTransformsProfiles =
+ getCreateTransformsInfoProfiles(singleSignatureInfo);
+ transformationSupplements =
+ buildTransformationSupplements(createTransformsProfiles);
+
+ // build and set the data object treatment list
+ dataObjectTreatmentList =
+ buildDataObjectTreatmentList(
+ singleSignatureInfo,
+ createTransformsProfiles,
+ transformationSupplements,
+ allReservedIDs);
+ profile.setDataObjectTreatmentList(dataObjectTreatmentList);
+
+ // set the key set
+ keyGroupID = request.getKeyIdentifier();
+ keySet = buildKeySet(keyGroupID);
+ if (keySet == null) {
+ throw new MOAApplicationException("2231", null);
+ } else if (keySet.size() == 0) {
+ throw new MOAApplicationException("2232", null);
+ }
+ profile.setKeySet(keySet);
+
+ // set the Security Layer manifest algorithm name
+ profile.setSecurityLayerManifestTypeURI(Constants.SL_MANIFEST_TYPE_URI);
+
+ // set the structure type
+ if (singleSignatureInfo.getCreateSignatureInfo() != null) {
+ profile.setSignatureStructureType(SignatureStructureTypes.ENVELOPED);
+ } else {
+ profile.setSignatureStructureType(SignatureStructureTypes.DETACHED);
+ }
+
+ // set insertion location
+ profile.setSignatureInsertionLocation(
+ getSignatureInsertionLocationIndex(singleSignatureInfo));
+
+ // set the canonicalization algorithm
+ canonicalization =
+ new CanonicalizationImpl(config.getCanonicalizationAlgorithmName());
+ profile.setSignedInfoCanonicalization(canonicalization);
+
+ // set the signed properties
+ profile.setSignedProperties(Collections.EMPTY_LIST);
+
+ // set security layer conformity
+ profile.setSecurityLayerConform(
+ singleSignatureInfo.isSecurityLayerConform());
+
+ // update the createProfileCount
+ createProfileCount++;
+
+ return profile;
+ }
+
+ /**
+ * Get the <code>List</code> of all <code>CreateTransformsInfoProfile</code>s
+ * contained in all the <code>DataObjectInfo</code>s of the given
+ * <code>SingleSignatureInfo</code>.
+ *
+ * @param singleSignatureInfo The <code>SingleSignatureInfo</code> object from
+ * which to extract the <code>CreateTransformsInfoProfile</code>s.
+ * @return All <code>CreateTransformsInfoProfile</code>s of all
+ * <code>DataObjectInfo</code>s of <code>singleSignatureInfo</code>.
+ * @throws MOAApplicationException An error occurred creating one of the
+ * profiles.
+ */
+ List getCreateTransformsInfoProfiles(SingleSignatureInfo singleSignatureInfo)
+ throws MOAApplicationException {
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ ConfigurationProvider config = context.getConfiguration();
+ List dataObjInfos = singleSignatureInfo.getDataObjectInfos();
+ List profiles = new ArrayList();
+ Iterator dtIter;
+
+ for (dtIter = dataObjInfos.iterator(); dtIter.hasNext();) {
+ DataObjectInfo dataObjInfo = (DataObjectInfo) dtIter.next();
+ CreateTransformsInfoProfileExplicit profile =
+ ProfileMapper.mapCreateTransformsInfoProfile(
+ dataObjInfo.getCreateTransformsInfoProfile(),
+ config);
+ profiles.add(profile);
+ }
+
+ return profiles;
+ }
+
+ /**
+ * Build the <code>List</code> of transformation supplements contained in a
+ * <code>SingleSignatureInfo</code> object.
+ *
+ * @param createTransformsInfoProfiles The
+ * <code>CreateTransformsInfoProfile</code> object from which to extract the
+ * transformation supplements.
+ * @return A <code>List</code> of <code>DataObject</code>s containing the
+ * transformation supplements.
+ * @throws MOASystemException A system error occurred creating one of the
+ * transformation supplements.
+ * @throws MOAApplicationException An error occurred creating one of the
+ * transformation supplements.
+ */
+ private List buildTransformationSupplements(List createTransformsInfoProfiles)
+ throws MOASystemException, MOAApplicationException {
+
+ List transformationSupplements = new ArrayList();
+ DataObjectFactory factory = DataObjectFactory.getInstance();
+ Iterator iter;
+
+ for (iter = createTransformsInfoProfiles.iterator(); iter.hasNext();) {
+ CreateTransformsInfoProfileExplicit profile =
+ (CreateTransformsInfoProfileExplicit) iter.next();
+ List supplements = profile.getSupplements();
+
+ if (supplements != null) {
+ Iterator supplIter;
+
+ for (supplIter = supplements.iterator(); supplIter.hasNext();) {
+ XMLDataObjectAssociation supplement =
+ (XMLDataObjectAssociation) supplIter.next();
+
+ transformationSupplements.add(
+ factory.createFromXmlDataObjectAssociation(
+ supplement,
+ false,
+ true));
+ }
+ }
+ }
+
+ return transformationSupplements;
+ }
+
+ /**
+ * Build the <code>List</code> of <code>DataObjectTreatment</code>s for the
+ * given <code>SingleSignatureInfo</code> object..
+ *
+ * @param singleSignatureInfo The <code>SingleSignatureInfo</code> object
+ * from which to exctract the <code>CreateTransformsInfoProfile</code>s
+ * containing the data for the <code>DataObjectTreatment</code>s.
+ * @param createTransformsInfoProfiles The
+ * <code>CreateTransformsInfoProfile</code>s contained in the
+ * <code>singleSignatureInfo</code>.
+ * @param transformationSupplements Additional parameters for
+ * transformations contained in <code>DataObjectTreatment</code>s.
+ * @param reservedIDs The <code>Set</code> of reserved object IDs.
+ * @return A <code>List</code> of <code>DataObjectTreatment</code> objects.
+ * @throws MOAApplicationException An error occurred building one of the
+ * <code>DataObjectTreatment</code>s.
+ * @throws MOASystemException A system error occurred building one of the
+ * <code>DataObjectTreatment</code>s.
+ */
+ private List buildDataObjectTreatmentList(
+ SingleSignatureInfo singleSignatureInfo,
+ List createTransformsInfoProfiles,
+ List transformationSupplements,
+ Set reservedIDs)
+ throws MOASystemException, MOAApplicationException {
+
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ ConfigurationProvider config = context.getConfiguration();
+ List treatments = new ArrayList();
+ List dataObjInfos = singleSignatureInfo.getDataObjectInfos();
+ int dataObjectTreatmentCount = 1;
+ String hashAlgorithmName;
+ Iterator dtIter;
+ Iterator prIter;
+
+ prIter = createTransformsInfoProfiles.iterator();
+ for (dtIter = dataObjInfos.iterator(); dtIter.hasNext();) {
+ CreateTransformsInfoProfileExplicit profile =
+ (CreateTransformsInfoProfileExplicit) prIter.next();
+ DataObjectInfo dataObjInfo = (DataObjectInfo) dtIter.next();
+ IdGenerator objIdGen =
+ new IdGenerator(
+ ("signed-data-" + createProfileCount)
+ + ("-" + dataObjectTreatmentCount++),
+ reservedIDs);
+ DataObjectTreatmentImpl treatment = new DataObjectTreatmentImpl(objIdGen);
+
+ treatment.setFinalContentType(
+ profile.getCreateTransformsInfo().getFinalDataMetaInfo().getMimeType());
+ treatment.setTransformationList(buildTransformationList(profile));
+ treatment.setReferenceInManifest(dataObjInfo.isChildOfManifest());
+
+ hashAlgorithmName =
+ (String) HASH_ALGORITHM_MAPPING.get(
+ config.getDigestMethodAlgorithmName());
+ if (hashAlgorithmName == null) {
+ error(
+ "config.17",
+ new Object[] { config.getDigestMethodAlgorithmName()});
+ throw new MOASystemException("2900", null);
+ }
+
+ treatment.setHashAlgorithmName(hashAlgorithmName);
+ treatment.setIncludedInSignature(
+ DataObjectInfo.STRUCTURE_ENVELOPING.equals(dataObjInfo.getStructure()));
+ treatment.setTransformationSupplements(transformationSupplements);
+
+ treatments.add(treatment);
+
+ }
+
+ return treatments;
+ }
+
+ /**
+ * Build the <code>List</code> of transformations contained in a
+ * <code>CreateTransformsInfoProfile</code> object.
+ *
+ * @param profile The <code>CreateTransformsInfoProfile</code> object
+ * from which to extract the <code>Transform</code>s.
+ * @return A <code>List</code> of <code>Transformation</code>s contained in
+ * the given <code>CreateTransformsInfoProfile</code>.
+ * @throws MOAApplicationException An error occurred building one of the
+ * <code>Transformation</code>s.
+ */
+ private List buildTransformationList(CreateTransformsInfoProfileExplicit profile)
+ throws MOAApplicationException {
+
+ TransformationFactory factory = TransformationFactory.getInstance();
+ List transforms = profile.getCreateTransformsInfo().getTransforms();
+
+ return transforms != null
+ ? factory.createTransformationList(transforms)
+ : Collections.EMPTY_LIST;
+ }
+
+ /**
+ * Build the set of <code>KeyEntryID</code>s available to the given
+ * <code>keyGroupID</code>.
+ *
+ * @param keyGroupID The keygroup ID for which the available keys should be
+ * returned.
+ * @return The <code>Set</code> of <code>KeyEntryID</code>s
+ * identifying the available keys.
+ */
+ private Set buildKeySet(String keyGroupID) {
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ ConfigurationProvider config = context.getConfiguration();
+ Set keyGroupEntries;
+
+ // get the KeyGroup entries from the configuration
+ if (context.getClientCertificate() != null) {
+ X509Certificate cert = context.getClientCertificate()[0];
+ Principal issuer = cert.getIssuerDN();
+ BigInteger serialNumber = cert.getSerialNumber();
+
+ keyGroupEntries =
+ config.getKeyGroupEntries(issuer, serialNumber, keyGroupID);
+ } else {
+ keyGroupEntries = config.getKeyGroupEntries(null, null, keyGroupID);
+ }
+
+ // map the KeyGroup entries to a set of KeyEntryIDs
+ if (keyGroupEntries == null) {
+ return null;
+ } else if (keyGroupEntries.size() == 0) {
+ return Collections.EMPTY_SET;
+ } else {
+ KeyModule module =
+ KeyModuleFactory.getInstance(
+ new TransactionId(context.getTransactionID()));
+ Set keyEntryIDs = module.getPrivateKeyEntryIDs();
+ Set keySet = new HashSet();
+ Iterator iter;
+
+ // filter out the keys that do not exist in the IAIK configuration
+ // by walking through the key entries and checking if the exist in the
+ // keyGroupEntries
+ for (iter = keyEntryIDs.iterator(); iter.hasNext();) {
+ KeyEntryID entryID = (KeyEntryID) iter.next();
+ KeyGroupEntry entry =
+ new KeyGroupEntry(
+ entryID.getModuleID(),
+ entryID.getCertificateIssuer(),
+ entryID.getCertificateSerialNumber());
+ if (keyGroupEntries.contains(entry)) {
+ keySet.add(entryID);
+ }
+ }
+ return keySet;
+ }
+ }
+
+ /**
+ * Get the signature location index where the signature will be inserted into
+ * the signature parent element.
+ *
+ * @param singleSignatureInfo The <code>SingleSignatureInfo</code> object
+ * containing the <code>CreateSignatureLocation</code>.
+ * @return The index at which to insert the signature into the signature
+ * environment.
+ * @throws MOAApplicationException An error occurred parsing the
+ * <code>CreateSignatureEnvironmentProfile</code>.
+ */
+ private XMLSignatureInsertionLocation getSignatureInsertionLocationIndex(SingleSignatureInfo singleSignatureInfo)
+ throws MOAApplicationException {
+
+ CreateSignatureInfo createInfo =
+ singleSignatureInfo.getCreateSignatureInfo();
+
+ if (createInfo != null) {
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ ConfigurationProvider config = context.getConfiguration();
+ CreateSignatureEnvironmentProfileExplicit profile =
+ ProfileMapper.mapCreateSignatureEnvironmentProfile(
+ createInfo.getCreateSignatureEnvironmentProfile(),
+ config);
+ int index = profile.getCreateSignatureLocation().getIndex();
+
+ return new XMLSignatureInsertionLocationImpl(index);
+ } else {
+ return new XMLSignatureInsertionLocationImpl(0);
+ }
+ }
+
+ /**
+ * Utility function to issue an error message to the log.
+ *
+ * @param messageId The ID of the message to log.
+ * @param parameters Additional message parameters.
+ */
+ private static void error(String messageId, Object[] parameters) {
+ MessageProvider msg = MessageProvider.getInstance();
+
+ Logger.error(new LogMsg(msg.getMessage(messageId, parameters)));
+ }
+
+}