aboutsummaryrefslogtreecommitdiff
path: root/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationInvoker.java
diff options
context:
space:
mode:
authorAndreas Fitzek <andreas.fitzek@iaik.tugraz.at>2015-11-03 14:38:34 +0100
committerAndreas Fitzek <andreas.fitzek@iaik.tugraz.at>2015-11-03 14:38:34 +0100
commit0872d2d8a64fd701776b272f49222428d8def07f (patch)
tree0954a523ad2cc7ad615dbbae5282dd56497e4c6e /moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationInvoker.java
parente635718b8d6a12e4e80207c8bdf30b02eed3f2ab (diff)
downloadmoa-sig-0872d2d8a64fd701776b272f49222428d8def07f.tar.gz
moa-sig-0872d2d8a64fd701776b272f49222428d8def07f.tar.bz2
moa-sig-0872d2d8a64fd701776b272f49222428d8def07f.zip
initial commit
Diffstat (limited to 'moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationInvoker.java')
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationInvoker.java727
1 files changed, 727 insertions, 0 deletions
diff --git a/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationInvoker.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationInvoker.java
new file mode 100644
index 0000000..2b158dd
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationInvoker.java
@@ -0,0 +1,727 @@
+/*
+ * 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.xml.crypto.utils.URI;
+import iaik.xml.crypto.utils.URIException;
+import iaik.server.modules.IAIKException;
+import iaik.server.modules.IAIKRuntimeException;
+import iaik.server.modules.xml.DataObject;
+import iaik.server.modules.xml.XMLDataObject;
+import iaik.server.modules.xml.XMLSignature;
+import iaik.server.modules.xmlsign.XMLConstants;
+import iaik.server.modules.xmlverify.DsigManifest;
+import iaik.server.modules.xmlverify.ReferenceData;
+import iaik.server.modules.xmlverify.SecurityLayerManifest;
+import iaik.server.modules.xmlverify.XMLSignatureVerificationModule;
+import iaik.server.modules.xmlverify.XMLSignatureVerificationModuleFactory;
+import iaik.server.modules.xmlverify.XMLSignatureVerificationProfile;
+import iaik.server.modules.xmlverify.XMLSignatureVerificationResult;
+import iaik.x509.X509Certificate;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+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 org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import at.gv.egovernment.moa.logging.LogMsg;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.logging.LoggingContext;
+import at.gv.egovernment.moa.logging.LoggingContextManager;
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.MOAException;
+import at.gv.egovernment.moa.spss.MOASystemException;
+import at.gv.egovernment.moa.spss.api.SPSSFactory;
+import at.gv.egovernment.moa.spss.api.common.CheckResult;
+import at.gv.egovernment.moa.spss.api.common.XMLDataObjectAssociation;
+import at.gv.egovernment.moa.spss.api.xmlverify.ReferenceInfo;
+import at.gv.egovernment.moa.spss.api.xmlverify.ReferencesCheckResult;
+import at.gv.egovernment.moa.spss.api.xmlverify.ReferencesCheckResultInfo;
+import at.gv.egovernment.moa.spss.api.xmlverify.SupplementProfileExplicit;
+import at.gv.egovernment.moa.spss.api.xmlverify.TransformParameter;
+import at.gv.egovernment.moa.spss.api.xmlverify.TransformParameterHash;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifySignatureLocation;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifyTransformsInfoProfileExplicit;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse;
+import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider;
+import at.gv.egovernment.moa.spss.server.config.TrustProfile;
+import at.gv.egovernment.moa.spss.server.iaik.xml.XMLSignatureImpl;
+import at.gv.egovernment.moa.spss.server.logging.IaikLog;
+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.util.CertificateUtils;
+import at.gv.egovernment.moa.spss.util.MessageProvider;
+import at.gv.egovernment.moa.spss.util.QCSSCDResult;
+import at.gv.egovernment.moa.util.CollectionUtils;
+import at.gv.egovernment.moa.util.Constants;
+
+/**
+ * A class providing a DOM based interface to the
+ * <code>XMLSignatureVerificationModule</code>.
+ *
+ * This class performs the invocation of the
+ * <code>iaik.server.modules.xmlverify.XMLSignatureVerificationModule</code>
+ * from a <code>VerifyXMLSignatureRequest</code> given as a DOM element. The
+ * result of the invocation is integrated into a
+ * <code>VerifyXMLSignatureResponse</code> and returned.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class XMLSignatureVerificationInvoker {
+
+ /** The single instance of this class. */
+ private static XMLSignatureVerificationInvoker instance = null;
+
+ private static Set FILTERED_REF_TYPES;
+
+ static {
+ FILTERED_REF_TYPES = new HashSet();
+ FILTERED_REF_TYPES.add(DsigManifest.XML_DSIG_MANIFEST_TYPE);
+ FILTERED_REF_TYPES.add(SecurityLayerManifest.SECURITY_LAYER_MANIFEST_TYPE);
+ FILTERED_REF_TYPES.add(SecurityLayerManifest.SECURITY_LAYER_MANIFEST_TYPE_OLD);
+ FILTERED_REF_TYPES.add(XMLConstants.NAMESPACE_ETSI_STRING + "SignedProperties");
+ FILTERED_REF_TYPES.add("http://uri.etsi.org/01903#SignedProperties");
+ }
+
+ /**
+ * Get the single instance of this class.
+ *
+ * @return The single instance of this class.
+ */
+ public static synchronized XMLSignatureVerificationInvoker getInstance() {
+ if (instance == null) {
+ instance = new XMLSignatureVerificationInvoker();
+ }
+ return instance;
+ }
+
+ /**
+ * Create a new <code>XMLSignatureCreationInvoker</code>.
+ *
+ * Protected to disallow multiple instances.
+ */
+ protected XMLSignatureVerificationInvoker() {
+ }
+
+ /**
+ * Process the <code>VerifyXMLSignatureRequest<code> message and invoke the
+ * <code>XMLSignatureVerificationModule</code>.
+ *
+ * @param request A <code>VerifyXMLSignatureRequest<code> API object
+ * containing the data for verifying an XML signature.
+ * @return A <code>VerifyXMLSignatureResponse</code> containing the
+ * answert to the <code>VerifyXMLSignatureRequest</code>.
+ * MOA schema definition.
+ * @throws MOAException An error occurred during signature verification.
+ */
+ public VerifyXMLSignatureResponse verifyXMLSignature(VerifyXMLSignatureRequest request)
+ throws MOAException {
+
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ LoggingContext loggingCtx =
+ LoggingContextManager.getInstance().getLoggingContext();
+ XMLSignatureVerificationProfileFactory profileFactory =
+ new XMLSignatureVerificationProfileFactory(request);
+ VerifyXMLSignatureResponseBuilder responseBuilder =
+ new VerifyXMLSignatureResponseBuilder();
+ XMLSignatureVerificationResult result;
+ XMLSignatureVerificationProfile profile;
+ ReferencesCheckResult signatureManifestCheck;
+ DataObjectFactory dataObjFactory;
+ XMLDataObject signatureEnvironment;
+ Node signatureEnvironmentParent = null;
+ Element requestElement = null;
+ XMLSignature xmlSignature;
+ Date signingTime;
+ List supplements;
+ List dataObjectList;
+
+ // get the supplements
+ supplements = getSupplements(request);
+
+ // build XMLSignature
+ dataObjFactory = DataObjectFactory.getInstance();
+ signatureEnvironment =
+ dataObjFactory.createSignatureEnvironment(
+ request.getSignatureInfo().getVerifySignatureEnvironment(),
+ supplements);
+ xmlSignature = buildXMLSignature(signatureEnvironment, request);
+
+ // build the list of DataObjects
+ dataObjectList = buildDataObjectList(supplements);
+
+ // build profile
+ profile = profileFactory.createProfile();
+
+ // get the signingTime
+ signingTime = request.getDateTime();
+
+ // 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
+ requestElement =
+ signatureEnvironment.getElement().getOwnerDocument().getDocumentElement();
+ if (requestElement != signatureEnvironment.getElement()) {
+ signatureEnvironmentParent =
+ signatureEnvironment.getElement().getParentNode();
+ requestElement.getOwnerDocument().replaceChild(
+ signatureEnvironment.getElement(),
+ requestElement);
+ }
+
+ QCSSCDResult qcsscdresult = new QCSSCDResult();
+ String tpID = profile.getCertificateValidationProfile().getTrustStoreProfile().getId();
+ ConfigurationProvider config = ConfigurationProvider.getInstance();
+ TrustProfile tp = config.getTrustProfile(tpID);
+
+ // verify the signature
+ try {
+ XMLSignatureVerificationModule module =
+ XMLSignatureVerificationModuleFactory.getInstance();
+
+ module.setLog(new IaikLog(loggingCtx.getNodeID()));
+
+ result =
+ module.verifySignature(
+ xmlSignature,
+ dataObjectList,
+ profile,
+ signingTime,
+ new TransactionId(context.getTransactionID()));
+ } catch (IAIKException e) {
+ MOAException moaException = IaikExceptionMapper.getInstance().map(e);
+ throw moaException;
+ } catch (IAIKRuntimeException e) {
+ MOAException moaException = IaikExceptionMapper.getInstance().map(e);
+ throw moaException;
+ }
+
+
+ // QC/SSCD check
+ List list = result.getCertificateValidationResult().getCertificateChain();
+ if (list != null) {
+ X509Certificate[] chain = new X509Certificate[list.size()];
+
+ Iterator it = list.iterator();
+ int i = 0;
+ while(it.hasNext()) {
+ chain[i] = (X509Certificate)it.next();
+ i++;
+ }
+
+ qcsscdresult = CertificateUtils.checkQCSSCD(chain, tp.isTSLEnabled());
+ }
+
+
+ // get signer certificate issuer country code
+ String issuerCountryCode = CertificateUtils.getIssuerCountry((X509Certificate)list.get(0));
+
+ // swap back in the request as root document
+ if (requestElement != signatureEnvironment.getElement()) {
+ requestElement.getOwnerDocument().replaceChild(
+ requestElement,
+ signatureEnvironment.getElement());
+ signatureEnvironmentParent.appendChild(signatureEnvironment.getElement());
+ }
+
+ // check the result
+ signatureManifestCheck =
+ validateSignatureManifest(request, result, profile);
+
+ // Check if signer certificate is in trust profile's allowed signer certificates pool
+ TrustProfile trustProfile = context.getConfiguration().getTrustProfile(request.getTrustProfileId());
+ CheckResult certificateCheck = validateSignerCertificate(result, trustProfile);
+
+
+ // build the response
+ responseBuilder.setResult(result, profile, signatureManifestCheck, certificateCheck, qcsscdresult.isQC(), qcsscdresult.isQCSourceTSL(), qcsscdresult.isSSCD(), qcsscdresult.isSSCDSourceTSL(), tp.isTSLEnabled(), issuerCountryCode);
+ return responseBuilder.getResponse();
+ }
+
+ /**
+ * Checks if the signer certificate matches one of the allowed signer certificates specified
+ * in the provided <code>trustProfile</code>.
+ *
+ * @param result The result produced by the <code>XMLSignatureVerificationModule</code>.
+ *
+ * @param trustProfile The trust profile the signer certificate is validated against.
+ *
+ * @return The overal result of the certificate validation for the signer certificate.
+ *
+ * @throws MOAException if one of the signer certificates specified in the <code>trustProfile</code>
+ * cannot be read from the file system.
+ */
+ private CheckResult validateSignerCertificate(XMLSignatureVerificationResult result, TrustProfile trustProfile)
+ throws MOAException
+ {
+ MessageProvider msg = MessageProvider.getInstance();
+
+ int resultCode = result.getCertificateValidationResult().getValidationResultCode().intValue();
+ if (resultCode == 0 && trustProfile.getSignerCertsUri() != null)
+ {
+ X509Certificate signerCertificate = (X509Certificate) result.getCertificateValidationResult().getCertificateChain().get(0);
+
+ File signerCertsDir = null;
+ try
+ {
+ signerCertsDir = new File(new URI(trustProfile.getSignerCertsUri()).getPath());
+ }
+ catch (URIException e)
+ {
+ throw new MOASystemException("2900", null, e); // Should not happen, already checked at loading the MOA configuration
+ }
+
+ File[] files = signerCertsDir.listFiles();
+ if (files == null) resultCode = 1;
+ int i;
+ for (i = 0; i < files.length; i++)
+ {
+ if (!files[i].isDirectory())
+ {
+ FileInputStream currentFIS = null;
+ try
+ {
+ currentFIS = new FileInputStream(files[i]);
+ }
+ catch (FileNotFoundException e) {
+ throw new MOASystemException("2900", null, e);
+ }
+
+ try
+ {
+ X509Certificate currentCert = new X509Certificate(currentFIS);
+ currentFIS.close();
+ if (currentCert.equals(signerCertificate)) break;
+ }
+ catch (Exception e)
+ {
+ // Simply ignore file if it cannot be interpreted as certificate
+ String logMsg = msg.getMessage("invoker.03", new Object[]{trustProfile.getId(), files[i].getName()});
+ Logger.warn(logMsg);
+ try
+ {
+ currentFIS.close();
+ }
+ catch (IOException e1) {
+ // If clean-up fails, do nothing
+ }
+ }
+ }
+ }
+ if (i >= files.length)
+ {
+ resultCode = 1; // No signer certificate from the trustprofile pool matches the actual signer certificate
+ }
+ }
+
+ SPSSFactory factory = SPSSFactory.getInstance();
+ return factory.createCheckResult(resultCode, null);
+ }
+
+
+
+ /**
+ * Select the <code>dsig:Signature</code> DOM element within the signature
+ * environment.
+ *
+ * @param signatureEnvironment The signature environment containing the
+ * <code>dsig:Signature</code>.
+ * @param request The <code>VerifyXMLSignatureRequest</code> containing the
+ * signature environment.
+ * @return The <code>dsig:Signature</code> element wrapped in a
+ * <code>XMLSignature</code> object.
+ * @throws MOAApplicationException An error occurred locating the
+ * <code>dsig:Signature</code>.
+ */
+ private XMLSignature buildXMLSignature(
+ XMLDataObject signatureEnvironment,
+ VerifyXMLSignatureRequest request)
+ throws MOAApplicationException {
+
+ VerifySignatureLocation signatureLocation =
+ request.getSignatureInfo().getVerifySignatureLocation();
+ Element signatureParent;
+
+ // evaluate the VerifySignatureLocation to get the signature parent
+ signatureParent =
+ InvokerUtils.evaluateSignatureLocation(
+ signatureEnvironment.getElement(),
+ signatureLocation);
+
+ // check for signatureParent to be a dsig:Signature element
+ if (!"Signature".equals(signatureParent.getLocalName())
+ || !Constants.DSIG_NS_URI.equals(signatureParent.getNamespaceURI())) {
+ throw new MOAApplicationException("2266", null);
+ }
+
+ return new XMLSignatureImpl(signatureParent);
+ }
+
+ /**
+ * Build the supplemental data objects contained in the
+ * <code>VerifyXMLSignatureRequest</code>.
+ *
+ * @param supplements A <code>List</code> of
+ * <code>XMLDataObjectAssociation</code>s containing the supplement data.
+ * @return A <code>List</code> of <code>DataObject</code>s representing the
+ * supplemental data objects.
+ * @throws MOASystemException A system error occurred building one of the data
+ * objects.
+ * @throws MOAApplicationException An error occurred building one of the data
+ * objects.
+ */
+ private List buildDataObjectList(List supplements)
+ throws MOASystemException, MOAApplicationException {
+ List dataObjectList = new ArrayList();
+
+ DataObjectFactory factory = DataObjectFactory.getInstance();
+ DataObject dataObject;
+ Iterator iter;
+
+ if (supplements != null) {
+ for (iter = supplements.iterator(); iter.hasNext();) {
+ XMLDataObjectAssociation supplement =
+ (XMLDataObjectAssociation) iter.next();
+ dataObject =
+ factory.createFromXmlDataObjectAssociation(supplement, true, false);
+ dataObjectList.add(dataObject);
+ }
+ }
+
+ return dataObjectList;
+
+ }
+
+ /**
+ * Get the supplemental data contained in the
+ * <code>VerifyXMLSignatureRequest</code>.
+ *
+ * @param request The <code>VerifyXMLSignatureRequest</code> containing the
+ * supplemental data.
+ * @return A <code>List</code> of <code>XMLDataObjectAssociation</code>
+ * objects containing the supplemental data.
+ * @throws MOAApplicationException An error occurred resolving one of the
+ * supplement profiles.
+ */
+ private List getSupplements(VerifyXMLSignatureRequest request)
+ throws MOAApplicationException {
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ ConfigurationProvider config = context.getConfiguration();
+ List supplementProfiles = request.getSupplementProfiles();
+
+ List supplements = new ArrayList();
+
+ if (supplementProfiles != null) {
+
+ List mappedProfiles =
+ ProfileMapper.mapSupplementProfiles(supplementProfiles, config);
+ Iterator iter;
+
+ for (iter = mappedProfiles.iterator(); iter.hasNext();) {
+ SupplementProfileExplicit profile =
+ (SupplementProfileExplicit) iter.next();
+ supplements.add(profile.getSupplementProfile());
+ }
+
+ }
+ return supplements;
+ }
+
+ /**
+ * Perform additional validations of the
+ * <code>XMLSignatureVerificationResult</code>.
+ *
+ * <p> In particular, it is verified that:
+ * <ul>
+ * <li>Each <code>ReferenceData</code> object contains transformation
+ * chain that matches one of the <code>Transforms</code> given in the
+ * corresponding <code>SignatureManifestCheckParams/ReferenceInfo</code></li>
+ * <li>The hash values of the <code>TransformParameter</code>s are valid.
+ * </li>
+ * </ul>
+ * </p>
+ *
+ * @param request The <code>VerifyXMLSignatureRequest</code> containing the
+ * signature to verify.
+ * @param result The result produced by
+ * <code>XMLSignatureVerificationModule</code>.
+ * @param profile The profile used for validating the <code>request</code>.
+ * @return The result of additional validations of the signature manifest.
+ * @throws MOAApplicationException Post-validation of the
+ * <code>XMLSignatureVerificaitonResult</code> failed.
+ */
+ private ReferencesCheckResult validateSignatureManifest(
+ VerifyXMLSignatureRequest request,
+ XMLSignatureVerificationResult result,
+ XMLSignatureVerificationProfile profile)
+ throws MOAApplicationException {
+
+ SPSSFactory factory = SPSSFactory.getInstance();
+ MessageProvider msg = MessageProvider.getInstance();
+
+ // validate that each ReferenceData object contains transforms specified
+ // in the corresponding SignatureManifestCheckParams/ReferenceInfo
+ if (request.getSignatureManifestCheckParams() != null) {
+ List refInfos =
+ request.getSignatureManifestCheckParams().getReferenceInfos();
+ List refDatas = filterReferenceInfos(result.getReferenceDataList());
+ List failedReferencesList = new ArrayList();
+ Iterator refInfoIter;
+ Iterator refDataIter;
+
+ if (refInfos.size() != refDatas.size()) {
+ return factory.createReferencesCheckResult(1, null);
+ }
+
+ refInfoIter = refInfos.iterator();
+ refDataIter =
+ filterReferenceInfos(result.getReferenceDataList()).iterator();
+
+ while (refInfoIter.hasNext()) {
+ ReferenceInfo refInfo = (ReferenceInfo) refInfoIter.next();
+ ReferenceData refData = (ReferenceData) refDataIter.next();
+ List transforms = buildTransformsList(refInfo);
+ boolean found = false;
+ Iterator trIter;
+
+ for (trIter = transforms.iterator(); trIter.hasNext() && !found;) {
+ found = trIter.next().equals(refData.getTransformationList());
+ }
+
+ if (!found) {
+ Integer refIndex = new Integer(refData.getReferenceIndex());
+ String logMsg =
+ msg.getMessage("invoker.01", new Object[] { refIndex });
+
+ failedReferencesList.add(refIndex);
+ Logger.debug(new LogMsg(logMsg));
+ }
+ }
+
+ if (!failedReferencesList.isEmpty()) {
+ // at least one reference failed - return their indexes and check code 1
+ int[] failedReferences =
+ CollectionUtils.toIntArray(failedReferencesList);
+ ReferencesCheckResultInfo checkInfo =
+ factory.createReferencesCheckResultInfo(null, failedReferences);
+
+ return factory.createReferencesCheckResult(1, checkInfo);
+ }
+ }
+
+ // validate the hashes contained in all the ReferenceInfo objects of the
+ // security layer manifest
+ if (request.getSignatureManifestCheckParams() != null
+ && result.containsSecurityLayerManifest()) {
+ Map hashValues = buildTransformParameterHashValues(request);
+ Set transformParameterURIs =
+ buildTransformParameterURIs(profile.getTransformationSupplements());
+ List referenceInfoList =
+ result.getSecurityLayerManifest().getReferenceDataList();
+ Iterator refIter;
+
+ for (refIter = referenceInfoList.iterator(); refIter.hasNext();) {
+ iaik.server.modules.xmlverify.ReferenceInfo ref =
+ (iaik.server.modules.xmlverify.ReferenceInfo) refIter.next();
+ byte[] hash = (byte[]) hashValues.get(ref.getURI());
+
+ if (!transformParameterURIs.contains(ref.getURI())
+ || (hash != null && !Arrays.equals(hash, ref.getHashValue()))) {
+
+ // the transform parameter doesn't exist or the hashs do not match
+ // return the index of the failed reference and check code 1
+ int[] failedReferences = new int[] { ref.getReferenceIndex()};
+ ReferencesCheckResultInfo checkInfo =
+ factory.createReferencesCheckResultInfo(null, failedReferences);
+ String logMsg =
+ msg.getMessage(
+ "invoker.02",
+ new Object[] { new Integer(ref.getReferenceIndex())});
+
+ Logger.debug(new LogMsg(logMsg));
+
+ return factory.createReferencesCheckResult(1, checkInfo);
+ }
+ }
+ }
+
+ return factory.createReferencesCheckResult(0, null);
+ }
+
+ /**
+ * Get all <code>Transform</code>s contained in all the
+ * <code>VerifyTransformsInfoProfile</code>s of the given
+ * <code>ReferenceInfo</code>.
+ *
+ * @param refInfo The <code>ReferenceInfo</code> object containing
+ * the transformations.
+ * @return A <code>List</code> of <code>List</code>s. Each of the
+ * <code>List</code>s contains <code>Transformation</code> objects.
+ * @throws MOAApplicationException An error occurred building one of the
+ * <code>Transformation</code>s.
+ */
+ private List buildTransformsList(ReferenceInfo refInfo)
+ throws MOAApplicationException {
+
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ ConfigurationProvider config = context.getConfiguration();
+ List profiles = refInfo.getVerifyTransformsInfoProfiles();
+ List mappedProfiles =
+ ProfileMapper.mapVerifyTransformsInfoProfiles(profiles, config);
+ List transformsList = new ArrayList();
+ TransformationFactory factory = TransformationFactory.getInstance();
+ Iterator iter;
+
+ for (iter = mappedProfiles.iterator(); iter.hasNext();) {
+ VerifyTransformsInfoProfileExplicit profile =
+ (VerifyTransformsInfoProfileExplicit) iter.next();
+ List transforms = profile.getTransforms();
+
+ if (transforms != null) {
+ transformsList.add(factory.createTransformationList(transforms));
+ }
+ }
+
+ return transformsList;
+ }
+
+ /**
+ * Build the <code>Set</code> of all <code>TransformParameter</code> URIs.
+ *
+ * @param transformParameters The <code>List</code> of
+ * <code>TransformParameter</code>s, as provided to the verification.
+ * @return The <code>Set</code> of all <code>TransformParameter</code> URIs.
+ */
+ private Set buildTransformParameterURIs(List transformParameters) {
+ Set uris = new HashSet();
+ Iterator iter;
+
+ for (iter = transformParameters.iterator(); iter.hasNext();) {
+ DataObject transformParameter = (DataObject) iter.next();
+ uris.add(transformParameter.getURI());
+ }
+
+ return uris;
+ }
+
+ /**
+ * Build a mapping between <code>TransformParameter</code> URIs (a
+ * <code>String</code> and <code>dsig:HashValue</code> (a
+ * <code>byte[]</code>).
+ *
+ * @param request The <code>VerifyXMLSignatureRequest</code>.
+ * @return Map The resulting mapping.
+ * @throws MOAApplicationException An error occurred accessing one of
+ * the profiles.
+ */
+ private Map buildTransformParameterHashValues(VerifyXMLSignatureRequest request)
+ throws MOAApplicationException {
+
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ ConfigurationProvider config = context.getConfiguration();
+ Map hashValues = new HashMap();
+ List refInfos =
+ request.getSignatureManifestCheckParams().getReferenceInfos();
+ Iterator refIter;
+
+ for (refIter = refInfos.iterator(); refIter.hasNext();) {
+ ReferenceInfo refInfo = (ReferenceInfo) refIter.next();
+ List profiles = refInfo.getVerifyTransformsInfoProfiles();
+ List mappedProfiles =
+ ProfileMapper.mapVerifyTransformsInfoProfiles(profiles, config);
+ Iterator prIter;
+
+ for (prIter = mappedProfiles.iterator(); prIter.hasNext();) {
+ VerifyTransformsInfoProfileExplicit profile =
+ (VerifyTransformsInfoProfileExplicit) prIter.next();
+ List trParameters = profile.getTransformParameters();
+ Iterator trIter;
+
+ for (trIter = trParameters.iterator(); trIter.hasNext();) {
+ TransformParameter transformParameter =
+ (TransformParameter) trIter.next();
+ String uri = transformParameter.getURI();
+
+ if (transformParameter.getTransformParameterType()
+ == TransformParameter.HASH_TRANSFORMPARAMETER) {
+ hashValues.put(
+ uri,
+ ((TransformParameterHash) transformParameter).getDigestValue());
+ }
+
+ }
+ }
+ }
+ return hashValues;
+ }
+
+ /**
+ * Filter the <code>ReferenceInfo</code>s returned by the
+ * <code>VerifyXMLSignatureResult</code> for comparison with the
+ * <code>ReferenceInfo</code> elements in the request.
+ *
+ * @param referenceInfos The <code>ReferenceInfo</code>s from the
+ * <code>VerifyXMLSignatureResult</code>.
+ * @return A <code>List</code> of all <code>ReferenceInfo</code>s whose type
+ * is not a XMLDsig manifest, Security Layer manifest, or ETSI signed
+ * property.
+ */
+ private List filterReferenceInfos(List referenceInfos) {
+ List filtered = new ArrayList();
+ Iterator iter;
+
+ for (iter = referenceInfos.iterator(); iter.hasNext();) {
+ iaik.server.modules.xmlverify.ReferenceInfo refInfo =
+ (iaik.server.modules.xmlverify.ReferenceInfo) iter.next();
+ String refType = refInfo.getReferenceType();
+
+ if (refType == null || !FILTERED_REF_TYPES.contains(refType)) {
+ filtered.add(refInfo);
+ }
+ }
+
+ return filtered;
+ }
+
+}