summaryrefslogtreecommitdiff
path: root/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl
diff options
context:
space:
mode:
Diffstat (limited to 'eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl')
-rw-r--r--eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/AbstractSignatureService.java97
-rw-r--r--eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/MoaSigInitializer.java113
-rw-r--r--eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/MoaSigSpringResourceProvider.java28
-rw-r--r--eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/SignatureCreationService.java32
-rw-r--r--eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/SignatureVerificationService.java517
-rw-r--r--eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/data/GenericSignatureVerificationResponse.java223
-rw-r--r--eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/data/VerifyCmsSignatureResponse.java14
-rw-r--r--eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/data/VerifyPdfSignatureResponse.java30
-rw-r--r--eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/data/VerifyXmlSignatureResponse.java35
-rw-r--r--eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/parser/VerifyXmlSignatureResponseParser.java194
10 files changed, 1283 insertions, 0 deletions
diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/AbstractSignatureService.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/AbstractSignatureService.java
new file mode 100644
index 00000000..942cd35c
--- /dev/null
+++ b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/AbstractSignatureService.java
@@ -0,0 +1,97 @@
+package at.gv.egiz.eaaf.modules.sigverify.moasig.impl;
+
+import java.security.Provider;
+import java.security.Security;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.w3c.dom.Document;
+
+import at.gv.egovernment.moa.spss.server.config.ConfigurationException;
+import at.gv.egovernment.moa.spss.server.iaik.config.IaikConfigurator;
+import at.gv.egovernment.moa.spss.server.transaction.TransactionContext;
+import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager;
+import at.gv.egovernment.moaspss.logging.LoggingContext;
+import at.gv.egovernment.moaspss.logging.LoggingContextManager;
+
+public abstract class AbstractSignatureService {
+ private static final Logger log = LoggerFactory.getLogger(AbstractSignatureService.class);
+
+ @Autowired(required = true)
+ MoaSigInitializer moaSigConfig;
+
+ /**
+ * Get a new {@link Document} from {@link DocumentBuilder} in synchronized form,
+ * because {@link DocumentBuilderFactory} and {@link DocumentBuilder} are not
+ * thread-safe.
+ *
+ * @return {@link Document}
+ * @throws ParserConfigurationException In case of an error
+ */
+ protected synchronized Document getNewDocumentBuilder() throws ParserConfigurationException {
+ final DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ return docBuilder.newDocument();
+
+ }
+
+ /**
+ * Set up the thread-local context information needed for calling the various
+ * <code>Invoker</code> classes.
+ *
+ * @throws ConfigurationException An error occurred setting up the configuration
+ * in the <code>TransactionContext</code>.
+ */
+ protected final void setUpContexts(final String transactionID) throws ConfigurationException {
+ final TransactionContextManager txMgr = TransactionContextManager.getInstance();
+ final LoggingContextManager logMgr = LoggingContextManager.getInstance();
+
+ if (txMgr.getTransactionContext() == null) {
+ log.debug("Set not MOA-Sig transaction context");
+ final TransactionContext ctx =
+ new TransactionContext(transactionID, null, moaSigConfig.getConfigHolder().getMoaSpssConfig());
+ txMgr.setTransactionContext(ctx);
+
+ }
+
+ //set Logging context into MOA-Sig
+ if (logMgr.getLoggingContext() == null) {
+ final LoggingContext ctx = new LoggingContext(transactionID);
+ logMgr.setLoggingContext(ctx);
+
+ }
+
+ //dump Java Security-Providers
+ if (log.isTraceEnabled()) {
+ log.trace("Set-Up verifier Bean: {}", this);
+ dumpSecProviders("MOA-Sig Context-Set-Up");
+
+ }
+
+ new IaikConfigurator().configure(moaSigConfig.getConfigHolder().getMoaSpssConfig());
+
+ }
+
+ private static void dumpSecProviders(String message) {
+ log.trace("Security Providers: {}", message);
+ for (final Provider provider : Security.getProviders()) {
+ log.trace(" - {} - {}", provider.getName(), provider.getVersion());
+
+ }
+ }
+
+ /**
+ * Tear down thread-local context information.
+ */
+ protected void tearDownContexts() {
+ TransactionContextManager.getInstance().setTransactionContext(null);
+ LoggingContextManager.getInstance().setLoggingContext(null);
+ log.debug("Closing MOA-Sig transaction context");
+
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/MoaSigInitializer.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/MoaSigInitializer.java
new file mode 100644
index 00000000..dc4aa4c0
--- /dev/null
+++ b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/MoaSigInitializer.java
@@ -0,0 +1,113 @@
+package at.gv.egiz.eaaf.modules.sigverify.moasig.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.Provider;
+import java.security.Security;
+import java.util.Iterator;
+import java.util.Map.Entry;
+
+import javax.annotation.PostConstruct;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import at.gv.egiz.eaaf.modules.sigverify.moasig.api.data.ISchemaRessourceProvider;
+import at.gv.egiz.eaaf.modules.sigverify.moasig.exceptions.MoaSigServiceConfigurationException;
+import at.gv.egovernment.moa.spss.server.init.StartupConfigurationHolder;
+import at.gv.egovernment.moa.spss.server.init.SystemInitializer;
+import at.gv.egovernment.moaspss.logging.LoggingContext;
+import at.gv.egovernment.moaspss.logging.LoggingContextManager;
+import at.gv.egovernment.moaspss.util.DOMUtils;
+import iaik.asn1.structures.AlgorithmID;
+import iaik.security.ec.provider.ECCelerate;
+import iaik.security.provider.IAIK;
+import lombok.Getter;
+
+public class MoaSigInitializer {
+ private static final Logger log = LoggerFactory.getLogger(MoaSigInitializer.class);
+
+ @Autowired(required = false)
+ ISchemaRessourceProvider[] schemas;
+
+ /**
+ * Get MOA-Sig configuration object.
+ */
+ @Getter
+ private StartupConfigurationHolder configHolder;
+
+
+ @PostConstruct
+ private synchronized void initialize() throws MoaSigServiceConfigurationException {
+ log.info("Initializing MOA-Sig signature-verification service ... ");
+
+ log.info("Loading Java security providers.");
+ IAIK.addAsProvider();
+ ECCelerate.addAsProvider();
+
+ try {
+ LoggingContextManager.getInstance().setLoggingContext(new LoggingContext("startup"));
+ log.debug("MOA-Sig library initialization process ... ");
+ configHolder = SystemInitializer.init();
+ log.info("MOA-Sig library initialization complete ");
+
+ fixJava8_141ProblemWithSslAlgorithms();
+
+ if (log.isDebugEnabled()) {
+ log.debug("Loaded Security Provider:");
+ final Provider[] providerList = Security.getProviders();
+ for (int i = 0; i < providerList.length; i++) {
+ log.debug("{}: {} Version {}", i, providerList[i].getName(), providerList[i].getVersion());
+
+ }
+ }
+
+ // Inject additional XML schemes
+ if (schemas != null && schemas.length > 0) {
+ log.debug("Infjecting additional XML schemes ... ");
+ for (final ISchemaRessourceProvider el : schemas) {
+ final Iterator<Entry<String, InputStream>> xmlSchemeIt =
+ el.getSchemas().entrySet().iterator();
+ while (xmlSchemeIt.hasNext()) {
+ final Entry<String, InputStream> xmlDef = xmlSchemeIt.next();
+ try {
+ DOMUtils.addSchemaToPool(xmlDef.getValue(), xmlDef.getKey());
+ log.info("Inject XML scheme: {}", xmlDef.getKey());
+
+ } catch (final IOException e) {
+ log.warn("Can NOT inject XML scheme: " + xmlDef.getKey(), e);
+
+ }
+
+ }
+ }
+ }
+
+ } catch (final RuntimeException e) {
+ log.error("MOA-SP initialization FAILED!", e);
+ throw new MoaSigServiceConfigurationException("service.moasig.04",
+ new Object[] { e.toString() }, e);
+ }
+
+ }
+
+ private static void fixJava8_141ProblemWithSslAlgorithms() {
+ log.info("Change AlgorithmIDs to fix problems with Java8 >= 141 ...");
+ // new AlgorithmID("1.2.840.113549.1.1.4", "md5WithRSAEncryption", new String[]
+ // { "MD5withRSA",
+ // "MD5/RSA", }, null, true);
+ new AlgorithmID("1.2.840.113549.1.1.5", "sha1WithRSAEncryption",
+ new String[] { "SHA1withRSA", "SHA1/RSA", "SHA-1/RSA", "SHA/RSA", }, null, true);
+ new AlgorithmID("1.2.840.113549.1.1.14", "sha224WithRSAEncryption",
+ new String[] { "SHA224withRSA", "SHA224/RSA", "SHA-224/RSA", }, null, true);
+ new AlgorithmID("1.2.840.113549.1.1.11", "sha256WithRSAEncryption",
+ new String[] { "SHA256withRSA", "SHA256/RSA", "SHA-256/RSA", }, null, true);
+ new AlgorithmID("1.2.840.113549.1.1.12", "sha384WithRSAEncryption",
+ new String[] { "SHA384withRSA", "SHA384/RSA", "SHA-384/RSA", }, null, true);
+ new AlgorithmID("1.2.840.113549.1.1.13", "sha512WithRSAEncryption",
+ new String[] { "SHA512withRSA", "SHA512/RSA", "SHA-512/RSA" }, null, true);
+
+ log.info("Change AlgorithmIDs finished");
+ }
+}
diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/MoaSigSpringResourceProvider.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/MoaSigSpringResourceProvider.java
new file mode 100644
index 00000000..b5e190d8
--- /dev/null
+++ b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/MoaSigSpringResourceProvider.java
@@ -0,0 +1,28 @@
+package at.gv.egiz.eaaf.modules.sigverify.moasig.impl;
+
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+
+import at.gv.egiz.components.spring.api.SpringResourceProvider;
+
+public class MoaSigSpringResourceProvider implements SpringResourceProvider {
+
+ @Override
+ public Resource[] getResourcesToLoad() {
+ final ClassPathResource moaSigConfig =
+ new ClassPathResource("/moa-sig-service.beans.xml", MoaSigSpringResourceProvider.class);
+ return new Resource[] { moaSigConfig };
+ }
+
+ @Override
+ public String[] getPackagesToScan() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String getName() {
+ return "Signature-verification service based on MOA-Sig (MOA-SPSS)";
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/SignatureCreationService.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/SignatureCreationService.java
new file mode 100644
index 00000000..0d8b7975
--- /dev/null
+++ b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/SignatureCreationService.java
@@ -0,0 +1,32 @@
+package at.gv.egiz.eaaf.modules.sigverify.moasig.impl;
+
+import javax.annotation.PostConstruct;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import at.gv.egiz.eaaf.modules.sigverify.moasig.api.ISignatureCreationService;
+import at.gv.egovernment.moa.spss.server.invoke.CMSSignatureCreationInvoker;
+import at.gv.egovernment.moa.spss.server.invoke.XMLSignatureCreationInvoker;
+
+@Service(value = "moaSigCreateService")
+public class SignatureCreationService extends AbstractSignatureService
+ implements ISignatureCreationService {
+ private static final Logger log = LoggerFactory.getLogger(SignatureCreationService.class);
+
+ private XMLSignatureCreationInvoker xadesInvoker;
+ private CMSSignatureCreationInvoker cadesInvoker;
+
+ @PostConstruct
+ protected void internalInitializer() {
+ log.debug("Instanzing SignatureCreationService implementation ... ");
+ xadesInvoker = XMLSignatureCreationInvoker.getInstance();
+ cadesInvoker = CMSSignatureCreationInvoker.getInstance();
+ log.trace("XML_impl: {} , CMS_imp: {}",
+ xadesInvoker.getClass().getName(), cadesInvoker.getClass().getName());
+ log.info("MOA-Sig signature-creation service initialized");
+
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/SignatureVerificationService.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/SignatureVerificationService.java
new file mode 100644
index 00000000..79f39e65
--- /dev/null
+++ b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/SignatureVerificationService.java
@@ -0,0 +1,517 @@
+package at.gv.egiz.eaaf.modules.sigverify.moasig.impl;
+
+import java.io.ByteArrayInputStream;
+import java.security.cert.CertificateEncodingException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.PostConstruct;
+
+import org.apache.commons.lang3.time.DateFormatUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.lang.Nullable;
+import org.springframework.stereotype.Service;
+import org.springframework.util.Base64Utils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import at.gv.egiz.eaaf.core.impl.data.Pair;
+import at.gv.egiz.eaaf.modules.sigverify.moasig.api.ISignatureVerificationService;
+import at.gv.egiz.eaaf.modules.sigverify.moasig.api.data.ICmsSignatureVerificationResponse;
+import at.gv.egiz.eaaf.modules.sigverify.moasig.api.data.IPdfSignatureVerificationResponse;
+import at.gv.egiz.eaaf.modules.sigverify.moasig.api.data.IXmlSignatureVerificationResponse;
+import at.gv.egiz.eaaf.modules.sigverify.moasig.exceptions.MoaSigServiceBuilderException;
+import at.gv.egiz.eaaf.modules.sigverify.moasig.exceptions.MoaSigServiceException;
+import at.gv.egiz.eaaf.modules.sigverify.moasig.impl.data.GenericSignatureVerificationResponse;
+import at.gv.egiz.eaaf.modules.sigverify.moasig.impl.data.VerifyPdfSignatureResponse;
+import at.gv.egiz.eaaf.modules.sigverify.moasig.impl.data.VerifyPdfSignatureResponse.CoversFullDocument;
+import at.gv.egiz.eaaf.modules.sigverify.moasig.impl.parser.VerifyXmlSignatureResponseParser;
+import at.gv.egovernment.moa.spss.MOAException;
+import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureRequest;
+import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponse;
+import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponseElement;
+import at.gv.egovernment.moa.spss.api.impl.VerifyCMSSignatureRequestImpl;
+import at.gv.egovernment.moa.spss.api.xmlbind.VerifyXMLSignatureRequestParser;
+import at.gv.egovernment.moa.spss.api.xmlbind.VerifyXMLSignatureResponseBuilder;
+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.invoke.CMSSignatureVerificationInvoker;
+import at.gv.egovernment.moa.spss.server.invoke.XMLSignatureVerificationInvoker;
+import at.gv.egovernment.moaspss.util.Constants;
+
+/**
+ * MOA-Sig based signature verification implementation.
+ *
+ * @author tlenz
+ *
+ */
+@Service(value = "moaSigVerifyService")
+public class SignatureVerificationService extends AbstractSignatureService
+ implements ISignatureVerificationService {
+ private static final Logger log = LoggerFactory.getLogger(SignatureVerificationService.class);
+
+ private static final String XMLNS_NS_URI = Constants.XMLNS_NS_URI;
+ private static final String MOA_NS_URI = Constants.MOA_NS_URI;
+ private static final String DSIG = Constants.DSIG_PREFIX + ":";
+ private static final String DEFAULT_XPATH_SIGNATURE_LOCATION = "//" + DSIG + "Signature";
+
+ public static final String PATTERN_ISSUE_INSTANT = "yyyy-MM-dd'T'HH:mm:ssXXX";
+
+ private CMSSignatureVerificationInvoker cadesInvoker;
+ private XMLSignatureVerificationInvoker xadesInvocer;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.
+ * ISignatureVerificationService# verifyCMSSignature(byte[], java.lang.String)
+ */
+ @Override
+ @Nullable
+ public ICmsSignatureVerificationResponse verifyCmsSignature(final byte[] signature,
+ final String trustProfileID) throws MoaSigServiceException {
+ return verifyCmsSignature(signature, trustProfileID, false);
+
+ }
+
+ @Override
+ public ICmsSignatureVerificationResponse verifyCmsSignature(byte[] signature, String trustProfileID,
+ boolean performExtendedValidation) throws MoaSigServiceException {
+ try {
+ // setup context
+ setUpContexts(Thread.currentThread().getName());
+
+ // verify signature
+ final VerifyCMSSignatureRequest cmsSigVerifyReq =
+ buildVerfifyCmsRequest(signature, trustProfileID, false, performExtendedValidation);
+ final VerifyCMSSignatureResponse cmsSigVerifyResp =
+ cadesInvoker.verifyCMSSignature(cmsSigVerifyReq);
+ return parseCmsVerificationResult(cmsSigVerifyResp);
+
+ } catch (final MOAException e) {
+ log.warn("CMS signature verification has an error.", e);
+ throw new MoaSigServiceException("service.03", new Object[] { e.toString() }, e);
+
+ } catch (final CertificateEncodingException e) {
+ log.warn("Can NOT serialize X509 certificate from CMS/CAdES signature-verification response",
+ e);
+ throw new MoaSigServiceException("service.03", new Object[] { e.toString() }, e);
+
+ } finally {
+ tearDownContexts();
+
+ }
+ }
+
+ @Override
+ public List<IPdfSignatureVerificationResponse> verifyPdfSignature(byte[] pdf, String trustProfileID)
+ throws MoaSigServiceException {
+ return verifyPdfSignature(pdf, trustProfileID, false);
+
+ }
+
+ @Override
+ public List<IPdfSignatureVerificationResponse> verifyPdfSignature(byte[] pdf, String trustProfileID,
+ boolean performExtendedValidation) throws MoaSigServiceException {
+ try {
+ // setup context
+ setUpContexts(Thread.currentThread().getName());
+
+ // verify signature
+ final VerifyCMSSignatureResponse cmsSigVerifyResp = cadesInvoker.verifyCMSSignature(
+ buildVerfifyCmsRequest(pdf, trustProfileID, true, performExtendedValidation));
+
+ return parsePdfVerificationResult(cmsSigVerifyResp);
+
+ } catch (final MOAException e) {
+ log.warn("PDF signature verification has an error.", e);
+ throw new MoaSigServiceException("service.03", new Object[] { e.toString() }, e);
+
+ } catch (final CertificateEncodingException e) {
+ log.warn("Can NOT serialize X509 certificate from PDF/PAdES signature-verification response",
+ e);
+ throw new MoaSigServiceException("service.03", new Object[] { e.toString() }, e);
+
+ } finally {
+ tearDownContexts();
+
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.
+ * ISignatureVerificationService# verifyXMLSignature(byte[], java.lang.String)
+ */
+ @Override
+ public IXmlSignatureVerificationResponse verifyXmlSignature(final byte[] signature,
+ final String trustProfileID) throws MoaSigServiceException {
+ return verifyXmlSignature(signature, trustProfileID, null, DEFAULT_XPATH_SIGNATURE_LOCATION, null,
+ Collections.emptyMap());
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.
+ * ISignatureVerificationService# verifyXMLSignature(byte[], java.lang.String,
+ * java.util.List)
+ */
+ @Override
+ public IXmlSignatureVerificationResponse verifyXmlSignature(final byte[] signature,
+ final String trustProfileID, final List<String> verifyTransformsInfoProfileID)
+ throws MoaSigServiceException {
+ return verifyXmlSignature(signature, trustProfileID, verifyTransformsInfoProfileID,
+ DEFAULT_XPATH_SIGNATURE_LOCATION, null, Collections.emptyMap());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see at.gv.egiz.eid.authhandler.modules.sigverify.moasig.impl.
+ * ISignatureVerificationService# verifyXMLSignature(byte[], java.lang.String,
+ * java.lang.String)
+ */
+ @Override
+ public IXmlSignatureVerificationResponse verifyXmlSignature(final byte[] signature,
+ final String trustProfileID, final String signatureLocationXpath)
+ throws MoaSigServiceException {
+ return verifyXmlSignature(signature, trustProfileID, null, signatureLocationXpath, null, Collections.emptyMap());
+ }
+
+ @Override
+ public IXmlSignatureVerificationResponse verifyXmlSignature(byte[] signature, String trustProfileID,
+ Date signingDate) throws MoaSigServiceException {
+ return verifyXmlSignature(signature, trustProfileID, null,
+ DEFAULT_XPATH_SIGNATURE_LOCATION, signingDate, Collections.emptyMap());
+ }
+
+
+ @Override
+ public IXmlSignatureVerificationResponse verifyXmlSignature(final byte[] signature,
+ final String trustProfileID, final List<String> verifyTransformsInfoProfileID,
+ final String xpathSignatureLocation, Date signingDate) throws MoaSigServiceException {
+ return verifyXmlSignature(signature, trustProfileID, verifyTransformsInfoProfileID, xpathSignatureLocation,
+ signingDate, Collections.emptyMap());
+ }
+
+ @Override
+ public IXmlSignatureVerificationResponse verifyXmlSignature(final byte[] signature,
+ final String trustProfileID, final List<String> verifyTransformsInfoProfileID,
+ final String xpathSignatureLocation, Date signingDate, final Map<String, byte[]> supplementContent)
+ throws MoaSigServiceException {
+ try {
+ // setup context
+ setUpContexts(Thread.currentThread().getName());
+
+ // build signature-verification request
+ final Element domVerifyXmlSignatureRequest = buildVerifyXmlRequest(signature, trustProfileID,
+ verifyTransformsInfoProfileID, xpathSignatureLocation, signingDate, supplementContent);
+
+ // send signature-verification to MOA-Sig
+ final VerifyXMLSignatureRequest vsrequest =
+ new VerifyXMLSignatureRequestParser().parse(domVerifyXmlSignatureRequest);
+ final VerifyXMLSignatureResponse vsresponse = xadesInvocer.verifyXMLSignature(vsrequest);
+ final Document result = new VerifyXMLSignatureResponseBuilder(true).build(vsresponse);
+
+ // parses the <IXMLSignatureVerificationResponse>
+ final IXmlSignatureVerificationResponse verifyXmlSignatureResponse =
+ new VerifyXmlSignatureResponseParser(result.getDocumentElement()).parseData();
+
+ return verifyXmlSignatureResponse;
+
+ } catch (final MoaSigServiceException e) {
+ throw e;
+
+ } catch (final MOAException e) {
+ log.warn("MOA-Sig signature-verification has an internal error." + " MsgCode: "
+ + e.getMessageId() + " Msg: " + e.getMessage(), e);
+ throw new MoaSigServiceException("service.moasig.03", new Object[] { e.getMessage() }, e);
+
+ } finally {
+ tearDownContexts();
+
+ }
+ }
+
+ private ICmsSignatureVerificationResponse parseCmsVerificationResult(
+ final VerifyCMSSignatureResponse cmsSigVerifyResp) throws CertificateEncodingException {
+
+ if (cmsSigVerifyResp.getResponseElements() == null
+ || cmsSigVerifyResp.getResponseElements().isEmpty()) {
+ log.info("No CMS signature FOUND. ");
+ return null;
+
+ }
+
+ if (cmsSigVerifyResp.getResponseElements().size() > 1) {
+ log.warn(
+ "CMS or CAdES signature contains more than one technical signatures. Only validate the first signature");
+ }
+
+ return (ICmsSignatureVerificationResponse) parseBasisSignatureInformation(
+ new at.gv.egiz.eaaf.modules.sigverify.moasig.impl.data.VerifyCmsSignatureResponse(),
+ (VerifyCMSSignatureResponseElement) cmsSigVerifyResp.getResponseElements().get(0));
+ }
+
+ private List<IPdfSignatureVerificationResponse> parsePdfVerificationResult(
+ VerifyCMSSignatureResponse cmsSigVerifyResp) throws CertificateEncodingException {
+
+ List<IPdfSignatureVerificationResponse> result = new ArrayList<>();
+ if (cmsSigVerifyResp.getResponseElements() == null
+ || cmsSigVerifyResp.getResponseElements().isEmpty()) {
+ log.info("No CMS signature FOUND. ");
+
+ } else {
+ Iterator<?> it = cmsSigVerifyResp.getResponseElements().iterator();
+ while (it.hasNext()) {
+ VerifyCMSSignatureResponseElement el = (VerifyCMSSignatureResponseElement) it.next();
+ VerifyPdfSignatureResponse pdfSigResult =
+ (VerifyPdfSignatureResponse) parseBasisSignatureInformation(new VerifyPdfSignatureResponse(), el);
+
+ pdfSigResult.setSignatureCoversFullDocument(
+ el.getCoversFullDocument() != null
+ ? el.getCoversFullDocument() ? CoversFullDocument.YES : CoversFullDocument.NO
+ : CoversFullDocument.UNKNOWN);
+ pdfSigResult.setByteRange(convertByteRanges(el.getByteRangeOfSignature()));
+ result.add(pdfSigResult);
+
+ }
+ }
+
+ return result;
+
+ }
+
+ private List<Pair<Integer, Integer>> convertByteRanges(int[] byteRangeOfSignature) {
+ List<Pair<Integer, Integer>> result = new ArrayList<>();
+
+ if (byteRangeOfSignature != null) {
+ for (int i = 0; i < byteRangeOfSignature.length / 2; i++) {
+ result.add(Pair.newInstance(
+ Integer.valueOf(byteRangeOfSignature[i]),
+ Integer.valueOf(byteRangeOfSignature[i + 1])));
+
+ }
+ } else {
+ log.debug("PDF signature-verification result contains no byte-range information");
+
+ }
+
+ return result;
+ }
+
+ private GenericSignatureVerificationResponse parseBasisSignatureInformation(
+ GenericSignatureVerificationResponse result, VerifyCMSSignatureResponseElement resp)
+ throws CertificateEncodingException {
+ // parse results into response container
+ result.setSignatureCheckCode(resp.getSignatureCheck().getCode());
+ result.setCertificateCheckCode(resp.getCertificateCheck().getCode());
+
+ if (resp.getSignerInfo() != null) {
+ result.setSigningDateTime(resp.getSignerInfo().getSigningTime());
+ result
+ .setX509CertificateEncoded(resp.getSignerInfo().getSignerCertificate().getEncoded());
+ result.setQualifiedCertificate(resp.getSignerInfo().isQualifiedCertificate());
+
+ result.setPublicAuthority(resp.getSignerInfo().isPublicAuthority());
+ result.setPublicAuthorityCode(resp.getSignerInfo().getPublicAuhtorityID());
+
+ } else {
+ log.info("CMS or CAdES verification result contains no SignerInfo");
+
+ }
+
+
+ //TODO: add extended validation infos
+ result.setSignatureAlgorithmIdentifier(resp.getSignatureAlgorithm());
+ result.setExtendedCertificateCheckResult(resp.getExtendedCertificateCheck());
+ result.setFormValidationResults(resp.getAdESFormResults());
+
+ return result;
+
+ }
+
+ /**
+ * Build a VerifyCMS-Siganture request for MOA-Sig. <br>
+ * <br>
+ * This builder only generates verification-request for enveloped CMS or CAdES
+ * signatures <br>
+ * This
+ *
+ * @param signature CMS or CAdES signature
+ * @param trustProfileID trustProfileID MOA-Sig Trust-Profile
+ * @param isPdfSignature Make CAdES signature as part of an PAdES
+ * document
+ * @param performExtendedValidation To extended validation. See MOA-Sig
+ * documentation for detailed information
+ * @return
+ */
+ private VerifyCMSSignatureRequest buildVerfifyCmsRequest(final byte[] signature,
+ final String trustProfileID, final boolean isPdfSignature,
+ final boolean performExtendedValidation) {
+ final VerifyCMSSignatureRequestImpl verifyCmsSignatureRequest =
+ new VerifyCMSSignatureRequestImpl();
+ verifyCmsSignatureRequest.setDateTime(null);
+ verifyCmsSignatureRequest.setCMSSignature(new ByteArrayInputStream(signature));
+ verifyCmsSignatureRequest.setDataObject(null);
+ verifyCmsSignatureRequest.setTrustProfileId(trustProfileID);
+ verifyCmsSignatureRequest.setSignatories(VerifyCMSSignatureRequest.ALL_SIGNATORIES);
+ verifyCmsSignatureRequest.setPDF(isPdfSignature);
+ verifyCmsSignatureRequest.setExtended(performExtendedValidation);
+ return verifyCmsSignatureRequest;
+
+ }
+
+ /**
+ * Build a VerifyXML-Signature request for MOA-Sig.
+ *
+ * @param signature Serialized XML signature
+ * @param trustProfileID MOA-Sig Trust-Profile
+ * @param verifyTransformsInfoProfileID {@link List} of Transformation-Profiles
+ * used for validation
+ * @param xpathSignatureLocation Xpath that points to location of
+ * Signature element
+ * @param sigValDate Signature timestamp
+ * @param supplementContent Map that contains supplement profile content; keyed by references. Each entry
+ * in this map becomes a Content/Base64Content child in the SupplementProfile
+ * node. Use this map to specify content of references that the verification
+ * service cannot resolve.
+ * @return MOA-Sig verification request element
+ * @throws MoaSigServiceBuilderException In case of an error
+ */
+ private Element buildVerifyXmlRequest(final byte[] signature, final String trustProfileID,
+ final List<String> verifyTransformsInfoProfileID, final String xpathSignatureLocation,
+ Date sigValDate, final Map<String, byte[]> supplementContent) throws MoaSigServiceBuilderException {
+ try {
+ // build empty document
+ final Document requestDoc_ = getNewDocumentBuilder();
+
+ final Element requestElem_ =
+ requestDoc_.createElementNS(MOA_NS_URI, "VerifyXMLSignatureRequest");
+ requestElem_.setAttributeNS(XMLNS_NS_URI, "xmlns", MOA_NS_URI);
+ requestElem_.setAttributeNS(XMLNS_NS_URI, "xmlns:" + Constants.DSIG_PREFIX,
+ Constants.DSIG_NS_URI);
+ requestDoc_.appendChild(requestElem_);
+
+ // build the request
+
+ // build set signing time
+ if (sigValDate != null) {
+ final Element dateTimeElem = requestDoc_.createElementNS(MOA_NS_URI, "DateTime");
+ requestElem_.appendChild(dateTimeElem);
+ final Node dateTime = requestDoc_.createTextNode(
+ DateFormatUtils.format(sigValDate, PATTERN_ISSUE_INSTANT));
+ dateTimeElem.appendChild(dateTime);
+
+ }
+
+ //set other parameters
+ final Element verifiySignatureInfoElem =
+ requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureInfo");
+ requestElem_.appendChild(verifiySignatureInfoElem);
+ final Element verifySignatureEnvironmentElem =
+ requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureEnvironment");
+ verifiySignatureInfoElem.appendChild(verifySignatureEnvironmentElem);
+ final Element base64ContentElem = requestDoc_.createElementNS(MOA_NS_URI, "Base64Content");
+ verifySignatureEnvironmentElem.appendChild(base64ContentElem);
+
+ // insert the base64 encoded signature
+ String base64EncodedAssertion = Base64Utils.encodeToString(signature);
+ // replace all '\r' characters by no char.
+ final StringBuffer replaced = new StringBuffer();
+ for (int i = 0; i < base64EncodedAssertion.length(); i++) {
+ final char c = base64EncodedAssertion.charAt(i);
+ if (c != '\r') {
+ replaced.append(c);
+ }
+ }
+ base64EncodedAssertion = replaced.toString();
+ final Node base64Content = requestDoc_.createTextNode(base64EncodedAssertion);
+ base64ContentElem.appendChild(base64Content);
+
+ // specify the signature location
+ final Element verifySignatureLocationElem =
+ requestDoc_.createElementNS(MOA_NS_URI, "VerifySignatureLocation");
+ verifiySignatureInfoElem.appendChild(verifySignatureLocationElem);
+ final Node signatureLocation = requestDoc_.createTextNode(xpathSignatureLocation);
+ verifySignatureLocationElem.appendChild(signatureLocation);
+
+ // signature manifest params
+ if (verifyTransformsInfoProfileID != null && !verifyTransformsInfoProfileID.isEmpty()) {
+ final Element signatureManifestCheckParamsElem =
+ requestDoc_.createElementNS(MOA_NS_URI, "SignatureManifestCheckParams");
+ requestElem_.appendChild(signatureManifestCheckParamsElem);
+ signatureManifestCheckParamsElem.setAttribute("ReturnReferenceInputData", "false");
+
+ // verify transformations
+ final Element referenceInfoElem = requestDoc_.createElementNS(MOA_NS_URI, "ReferenceInfo");
+ signatureManifestCheckParamsElem.appendChild(referenceInfoElem);
+ for (final String element : verifyTransformsInfoProfileID) {
+ final Element verifyTransformsInfoProfileIdElem =
+ requestDoc_.createElementNS(MOA_NS_URI, "VerifyTransformsInfoProfileID");
+ referenceInfoElem.appendChild(verifyTransformsInfoProfileIdElem);
+ verifyTransformsInfoProfileIdElem.appendChild(requestDoc_.createTextNode(element));
+
+ }
+ }
+
+ // hashinput data
+ final Element returnHashInputDataElem =
+ requestDoc_.createElementNS(MOA_NS_URI, "ReturnHashInputData");
+ requestElem_.appendChild(returnHashInputDataElem);
+
+ // add trustProfileID
+ final Element trustProfileIdElem = requestDoc_.createElementNS(MOA_NS_URI, "TrustProfileID");
+ trustProfileIdElem.appendChild(requestDoc_.createTextNode(trustProfileID));
+ requestElem_.appendChild(trustProfileIdElem);
+
+ // add supplement profile
+ if (!supplementContent.isEmpty()) {
+
+ final Element supplementProfile = requestDoc_.createElementNS(MOA_NS_URI, "SupplementProfile");
+
+ for (Map.Entry<String, byte[]> entry: supplementContent.entrySet()) {
+ String reference = entry.getKey();
+ byte[] contentBytes = entry.getValue();
+ final Element content = requestDoc_.createElementNS(MOA_NS_URI, "Content");
+ content.setAttribute("Reference", reference);
+ final Element b64content = requestDoc_.createElementNS(MOA_NS_URI, "Base64Content");
+ b64content.setTextContent(Base64Utils.encodeToString(contentBytes));
+ content.appendChild(b64content);
+ supplementProfile.appendChild(content);
+ }
+
+ requestElem_.appendChild(supplementProfile);
+ }
+
+ return requestElem_;
+
+ } catch (final Throwable t) {
+ log.warn("Can NOT build VerifyXML-Signature request for MOA-Sig", t);
+ throw new MoaSigServiceBuilderException("service.moasig.03", new Object[] { t.getMessage() },
+ t);
+
+ }
+ }
+
+ @PostConstruct
+ protected void internalInitializer() {
+ log.debug("Instanzing SignatureVerificationService implementation ... ");
+ // svs =
+ // at.gv.egovernment.moa.spss.api.SignatureVerificationService.getInstance();
+ cadesInvoker = CMSSignatureVerificationInvoker.getInstance();
+ xadesInvocer = XMLSignatureVerificationInvoker.getInstance();
+ log.info("MOA-Sig signature-verification service initialized");
+
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/data/GenericSignatureVerificationResponse.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/data/GenericSignatureVerificationResponse.java
new file mode 100644
index 00000000..6006b731
--- /dev/null
+++ b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/data/GenericSignatureVerificationResponse.java
@@ -0,0 +1,223 @@
+package at.gv.egiz.eaaf.modules.sigverify.moasig.impl.data;
+
+import java.io.Serializable;
+import java.security.cert.CertificateException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+
+import at.gv.egiz.eaaf.modules.sigverify.moasig.api.data.IGenericSignatureVerificationResponse;
+import at.gv.egiz.eaaf.modules.sigverify.moasig.exceptions.MoaSigServiceException;
+import at.gv.egiz.eaaf.modules.sigverify.moasig.exceptions.MoaSigServiceParserException;
+import at.gv.egovernment.moa.spss.api.common.ExtendedCertificateCheckResult;
+import at.gv.egovernment.moa.spss.api.xmlverify.AdESFormResults;
+import iaik.x509.X509Certificate;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Getter
+@Setter
+public class GenericSignatureVerificationResponse
+ implements IGenericSignatureVerificationResponse, Serializable {
+
+ private static final long serialVersionUID = -7751001050689401118L;
+
+ /** The signing time. */
+ private Date signingDateTime;
+
+ /** The signatureCheckCode to be stored. */
+ private int signatureCheckCode;
+
+ /** The certificateCheckCode to be stored. */
+ private int certificateCheckCode;
+
+ /** The publicAuthority to be stored. */
+ private boolean publicAuthority;
+
+ /** The publicAuthorityCode to be stored. */
+ private String publicAuthorityCode;
+
+ /** The qualifiedCertificate to be stored. */
+ private boolean qualifiedCertificate;
+
+ private byte[] x509CertificateEncoded;
+
+ /**
+ * Identifier of the signing algorithm.
+ */
+ private String signatureAlgorithmIdentifier;
+
+ private ExtendedCertificateValidation extendedCertificateValidation;
+
+ private List<ExtendedResult> formValidationResults = null;
+
+ @Override
+ public Date getSigningDateTime() {
+ if (this.signingDateTime != null) {
+ return new Date(this.signingDateTime.getTime());
+ }
+ return null;
+
+ }
+
+ @Override
+ public X509Certificate getX509Certificate() throws MoaSigServiceException {
+ if (x509CertificateEncoded != null) {
+ try {
+ return new X509Certificate(x509CertificateEncoded);
+
+ } catch (final CertificateException e) {
+ log.error("Can NOT parse X509 certifcate in "
+ + GenericSignatureVerificationResponse.class.getName(), e);
+ throw new MoaSigServiceParserException("service.moasig.01", null, e);
+ }
+
+ }
+
+ return null;
+
+ }
+
+ @Override
+ public byte[] getX509CertificateEncoded() {
+ if (this.x509CertificateEncoded != null) {
+ return this.x509CertificateEncoded.clone();
+
+ }
+ return null;
+
+ }
+
+ @Override
+ public String getPublicAuthorityCode() {
+ if (StringUtils.isNotEmpty(this.publicAuthorityCode)) {
+ return this.publicAuthorityCode;
+
+ } else {
+ return null;
+
+ }
+
+ }
+
+ @Override
+ public List<ExtendedResult> getFormValidationResults() {
+ if (formValidationResults == null) {
+ return Collections.emptyList();
+
+ } else {
+ return formValidationResults;
+
+ }
+ }
+
+ /**
+ * Set signature creation timestramp.
+ *
+ * @param signingDateTime timestamp
+ */
+ public void setSigningDateTime(final Date signingDateTime) {
+ if (signingDateTime != null) {
+ this.signingDateTime = new Date(signingDateTime.getTime());
+ }
+ }
+
+ /**
+ * Set encoded signer certificate.
+ *
+ * @param x509CertificateEncoded signer cerificate
+ */
+ public void setX509CertificateEncoded(final byte[] x509CertificateEncoded) {
+ if (x509CertificateEncoded != null) {
+ this.x509CertificateEncoded = x509CertificateEncoded.clone();
+
+ }
+ }
+
+ /**
+ * Set extended certificate-validation result.
+ *
+ * @param extendedCertificateCheck Extended result from MOA-Sig
+ */
+ public void setExtendedCertificateCheckResult(ExtendedCertificateCheckResult extendedCertificateCheck) {
+ if (extendedCertificateCheck != null) {
+ this.extendedCertificateValidation = ExtendedCertificateValidation.builder()
+ .majorResult(ExtendedResult.builder()
+ .code(extendedCertificateCheck.getMajorCode())
+ .info(extendedCertificateCheck.getMajorInfo())
+ .build())
+ .minorResult(ExtendedResult.builder()
+ .code(extendedCertificateCheck.getMinorCode())
+ .info(extendedCertificateCheck.getMinorInfo())
+ .build())
+ .build();
+
+ } else {
+ log.debug("No extended verification-result. Skipping certificate-result extraction ... ");
+
+ }
+ }
+
+ /**
+ * Set form-validation result.
+ *
+ * @param formCheckResult Extended form-validation result from MOA-Sig
+ */
+ public void setFormValidationResults(List<?> formCheckResult) {
+ if (formCheckResult != null) {
+ for (Object elObj : formCheckResult) {
+ if (elObj instanceof AdESFormResults) {
+ AdESFormResults el = (AdESFormResults)elObj;
+
+ if (formValidationResults == null) {
+ formValidationResults = new ArrayList<>();
+
+ }
+
+ formValidationResults.add(ExtendedResult.builder()
+ .code(el.getCode())
+ .info(el.getName())
+ .build());
+
+ } else {
+ log.warn("Skip unknown form-validation result of type: {}", elObj.getClass().getName());
+
+ }
+ }
+
+ } else {
+ log.debug("No extended verification-result. Skipping form-validation result extraction ... ");
+
+ }
+
+ }
+
+ @Getter
+ @Builder
+ public static class ExtendedCertificateValidation implements Serializable {
+
+ private static final long serialVersionUID = -7800026008655393276L;
+
+ private ExtendedResult majorResult;
+ private ExtendedResult minorResult;
+
+ }
+
+ @Getter
+ @Builder
+ public static class ExtendedResult implements Serializable {
+
+ private static final long serialVersionUID = 8523769744476971010L;
+
+ private int code;
+ private String info;
+
+ }
+
+}
diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/data/VerifyCmsSignatureResponse.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/data/VerifyCmsSignatureResponse.java
new file mode 100644
index 00000000..a812db56
--- /dev/null
+++ b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/data/VerifyCmsSignatureResponse.java
@@ -0,0 +1,14 @@
+package at.gv.egiz.eaaf.modules.sigverify.moasig.impl.data;
+
+import at.gv.egiz.eaaf.modules.sigverify.moasig.api.data.ICmsSignatureVerificationResponse;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class VerifyCmsSignatureResponse extends GenericSignatureVerificationResponse
+ implements ICmsSignatureVerificationResponse {
+
+ private static final long serialVersionUID = 708260904158070696L;
+
+}
diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/data/VerifyPdfSignatureResponse.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/data/VerifyPdfSignatureResponse.java
new file mode 100644
index 00000000..740ac55a
--- /dev/null
+++ b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/data/VerifyPdfSignatureResponse.java
@@ -0,0 +1,30 @@
+package at.gv.egiz.eaaf.modules.sigverify.moasig.impl.data;
+
+import java.util.List;
+
+import at.gv.egiz.eaaf.core.impl.data.Pair;
+import at.gv.egiz.eaaf.modules.sigverify.moasig.api.data.IPdfSignatureVerificationResponse;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class VerifyPdfSignatureResponse extends VerifyCmsSignatureResponse
+ implements IPdfSignatureVerificationResponse {
+
+ private static final long serialVersionUID = 1835687958341837826L;
+
+ /**
+ * Flag if signature covers the full pdf-document.
+ */
+ private CoversFullDocument signatureCoversFullDocument = CoversFullDocument.UNKNOWN;
+
+ /**
+ * PDF signing ranges as {@link List} of {@link Pair} of starting-byte and byte-length.
+ */
+ private List<Pair<Integer, Integer>> byteRange;
+
+
+ public enum CoversFullDocument { YES, NO, UNKNOWN }
+
+}
diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/data/VerifyXmlSignatureResponse.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/data/VerifyXmlSignatureResponse.java
new file mode 100644
index 00000000..4021a90b
--- /dev/null
+++ b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/data/VerifyXmlSignatureResponse.java
@@ -0,0 +1,35 @@
+package at.gv.egiz.eaaf.modules.sigverify.moasig.impl.data;
+
+import at.gv.egiz.eaaf.modules.sigverify.moasig.api.data.IXmlSignatureVerificationResponse;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * MOA-Sig signature verification response for XML based signatures.
+ *
+ * @author tlenz
+ *
+ */
+
+@Getter
+@Setter
+public class VerifyXmlSignatureResponse extends GenericSignatureVerificationResponse
+ implements IXmlSignatureVerificationResponse {
+
+ private static final long serialVersionUID = 8386070769565711601L;
+
+ /** The xmlDsigSubjectName to be stored. */
+ private String xmlDsigSubjectName;
+
+ /** The xmlDSIGManifestCheckCode to be stored. */
+ private int xmlDsigManifestCheckCode;
+ /** The xmlDSIGManigest to be stored. */
+ private boolean xmlDsigManigest;
+
+ /**
+ * The result of the signature manifest check. The default value <code>-1</code>
+ * indicates that the signature manifest has not been checked.
+ */
+ private int signatureManifestCheckCode = -1;
+
+}
diff --git a/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/parser/VerifyXmlSignatureResponseParser.java b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/parser/VerifyXmlSignatureResponseParser.java
new file mode 100644
index 00000000..746b5461
--- /dev/null
+++ b/eaaf_modules/eaaf_module_moa-sig/src/main/java/at/gv/egiz/eaaf/modules/sigverify/moasig/impl/parser/VerifyXmlSignatureResponseParser.java
@@ -0,0 +1,194 @@
+package at.gv.egiz.eaaf.modules.sigverify.moasig.impl.parser;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import org.joda.time.DateTime;
+import org.joda.time.format.ISODateTimeFormat;
+import org.springframework.lang.NonNull;
+import org.w3c.dom.Element;
+
+import at.gv.egiz.eaaf.modules.sigverify.moasig.api.data.IXmlSignatureVerificationResponse;
+import at.gv.egiz.eaaf.modules.sigverify.moasig.exceptions.MoaSigServiceException;
+import at.gv.egiz.eaaf.modules.sigverify.moasig.exceptions.MoaSigServiceParserException;
+import at.gv.egiz.eaaf.modules.sigverify.moasig.impl.data.VerifyXmlSignatureResponse;
+import at.gv.egovernment.moaspss.util.Constants;
+import at.gv.egovernment.moaspss.util.DOMUtils;
+import at.gv.egovernment.moaspss.util.XPathUtils;
+import iaik.utils.Base64InputStream;
+import iaik.x509.X509Certificate;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class VerifyXmlSignatureResponseParser {
+
+ //
+ // XPath namespace prefix shortcuts
+ //
+ /** Xpath prefix for reaching MOA Namespaces. */
+ private static final String MOA = Constants.MOA_PREFIX + ":";
+ /** Xpath prefix for reaching DSIG Namespaces. */
+ private static final String DSIG = Constants.DSIG_PREFIX + ":";
+ /** Xpath expression to the root element. */
+ private static final String ROOT = "/" + MOA + "VerifyXMLSignatureResponse/";
+
+ /** Xpath expression to the X509SubjectName element. */
+ private static final String DSIG_SUBJECT_NAME_XPATH =
+ ROOT + MOA + "SignerInfo/" + DSIG + "X509Data/" + DSIG + "X509SubjectName";
+ /** Xpath expression to the X509Certificate element. */
+ private static final String DSIG_X509_CERTIFICATE_XPATH =
+ ROOT + MOA + "SignerInfo/" + DSIG + "X509Data/" + DSIG + "X509Certificate";
+ /** Xpath expression to the PublicAuthority element. */
+ private static final String PUBLIC_AUTHORITY_XPATH =
+ ROOT + MOA + "SignerInfo/" + DSIG + "X509Data/" + MOA + "PublicAuthority";
+ /** Xpath expression to the PublicAuthorityCode element. */
+ private static final String PUBLIC_AUTHORITY_CODE_XPATH =
+ PUBLIC_AUTHORITY_XPATH + "/" + MOA + "Code";
+ /** Xpath expression to the QualifiedCertificate element. */
+ private static final String QUALIFIED_CERTIFICATE_XPATH =
+ ROOT + MOA + "SignerInfo/" + DSIG + "X509Data/" + MOA + "QualifiedCertificate";
+
+ /** Xpath expression to the SignatureCheckCode element. */
+ private static final String SIGNATURE_CHECK_CODE_XPATH =
+ ROOT + MOA + "SignatureCheck/" + MOA + "Code";
+ /** Xpath expression to the XMLDSIGManifestCheckCode element. */
+ private static final String XMLDSIG_MANIFEST_CHECK_CODE_XPATH =
+ ROOT + MOA + "XMLDSIGManifestCheck/" + MOA + "Code";
+ /** Xpath expression to the SignatureManifestCheckCode element. */
+ private static final String SIGNATURE_MANIFEST_CHECK_CODE_XPATH =
+ ROOT + MOA + "SignatureManifestCheck/" + MOA + "Code";
+ /** Xpath expression to the CertificateCheckCode element. */
+ private static final String CERTIFICATE_CHECK_CODE_XPATH =
+ ROOT + MOA + "CertificateCheck/" + MOA + "Code";
+
+ private static final String SIGNING_TIME_XPATH = ROOT + MOA + "SigningTime";
+
+ /**
+ * This is the root element of the XML-Document provided by the Security Layer
+ * Card.
+ */
+ private Element verifyXmlSignatureResponse;
+
+ /**
+ * Constructor for VerifyXMLSignatureResponseParser. A DOM-representation of the
+ * incoming String will be created
+ *
+ * @param xmlResponse <code>&lt;InfoboxReadResponse&gt;</code> as String
+ * @throws MoaSigServiceParserException on any parsing error
+ */
+ public VerifyXmlSignatureResponseParser(final String xmlResponse)
+ throws MoaSigServiceParserException {
+ try {
+ final InputStream s = new ByteArrayInputStream(xmlResponse.getBytes("UTF-8"));
+ verifyXmlSignatureResponse = DOMUtils.parseXmlValidating(s);
+
+ } catch (final Throwable t) {
+ log.warn("Can not parse MOA-Sig response.", t);
+ throw new MoaSigServiceParserException("service.moasig.02", new Object[] { t.toString() }, t);
+
+ }
+ }
+
+ /**
+ * Constructor for VerifyXMLSignatureResponseParser. A DOM-representation of the
+ * incoming Inputstream will be created
+ *
+ * @param xmlResponse <code>&lt;InfoboxReadResponse&gt;</code> as InputStream
+ * @throws MoaSigServiceParserException on any parsing error
+ */
+ public VerifyXmlSignatureResponseParser(final InputStream xmlResponse)
+ throws MoaSigServiceParserException {
+ try {
+ verifyXmlSignatureResponse = DOMUtils.parseXmlValidating(xmlResponse);
+
+ } catch (final Throwable t) {
+ log.warn("Can not parse MOA-Sig response.", t);
+ throw new MoaSigServiceParserException("service.moasig.02", new Object[] { t.toString() }, t);
+
+ }
+ }
+
+ /**
+ * Constructor for VerifyXMLSignatureResponseParser. The incoming Element will
+ * be used for further operations
+ *
+ * @param xmlResponse <code>&lt;InfoboxReadResponse&gt;</code> as Element
+ */
+ public VerifyXmlSignatureResponseParser(final Element xmlResponse) {
+ verifyXmlSignatureResponse = xmlResponse;
+
+ }
+
+ /**
+ * Parse MOA-Sig signatur-verification result into
+ * {@link IXmlSignatureVerificationResponse}.
+ *
+ * @return {@link IXmlSignatureVerificationResponse}
+ * @throws MoaSigServiceException on any parsing error
+ */
+ @NonNull
+ public IXmlSignatureVerificationResponse parseData() throws MoaSigServiceException {
+ try {
+ final VerifyXmlSignatureResponse respData = new VerifyXmlSignatureResponse();
+ respData.setXmlDsigSubjectName(
+ XPathUtils.getElementValue(verifyXmlSignatureResponse, DSIG_SUBJECT_NAME_XPATH, ""));
+ final Element e = (Element) XPathUtils.selectSingleNode(verifyXmlSignatureResponse,
+ QUALIFIED_CERTIFICATE_XPATH);
+ respData.setQualifiedCertificate(e != null);
+
+ final Base64InputStream in = new Base64InputStream(new ByteArrayInputStream(
+ XPathUtils.getElementValue(verifyXmlSignatureResponse, DSIG_X509_CERTIFICATE_XPATH, "")
+ .getBytes("UTF-8")),
+ true);
+
+ respData.setX509CertificateEncoded(new X509Certificate(in).getEncoded());
+
+ final Element publicAuthority =
+ (Element) XPathUtils.selectSingleNode(verifyXmlSignatureResponse, PUBLIC_AUTHORITY_XPATH);
+ respData.setPublicAuthority(publicAuthority != null);
+ respData.setPublicAuthorityCode(
+ XPathUtils.getElementValue(verifyXmlSignatureResponse, PUBLIC_AUTHORITY_CODE_XPATH, ""));
+ respData.setSignatureCheckCode(Integer.parseInt(
+ XPathUtils.getElementValue(verifyXmlSignatureResponse, SIGNATURE_CHECK_CODE_XPATH, "")));
+
+ final String xmlDsigCheckCode = XPathUtils.getElementValue(verifyXmlSignatureResponse,
+ XMLDSIG_MANIFEST_CHECK_CODE_XPATH, null);
+ if (xmlDsigCheckCode != null) {
+ respData.setXmlDsigManigest(true);
+ respData.setXmlDsigManifestCheckCode(Integer.parseInt(xmlDsigCheckCode));
+
+ } else {
+ respData.setXmlDsigManigest(false);
+
+ }
+
+ final String signatureManifestCheckCode = XPathUtils
+ .getElementValue(verifyXmlSignatureResponse, SIGNATURE_MANIFEST_CHECK_CODE_XPATH, null);
+ if (signatureManifestCheckCode != null) {
+ respData.setSignatureManifestCheckCode(Integer.parseInt(signatureManifestCheckCode));
+
+ }
+ respData.setCertificateCheckCode(Integer.parseInt(
+ XPathUtils.getElementValue(verifyXmlSignatureResponse, CERTIFICATE_CHECK_CODE_XPATH, "")));
+
+ final String signingTimeElement =
+ XPathUtils.getElementValue(verifyXmlSignatureResponse, SIGNING_TIME_XPATH, "");
+ if (signingTimeElement != null && !signingTimeElement.isEmpty()) {
+ final DateTime datetime =
+ ISODateTimeFormat.dateOptionalTimeParser().parseDateTime(signingTimeElement);
+ respData.setSigningDateTime(datetime.toDate());
+
+ }
+
+ //TODO: parse extended validation results
+
+ return respData;
+
+ } catch (final Throwable t) {
+ log.warn("Can not parse MOA-Sig response.", t);
+ throw new MoaSigServiceParserException("service.moasig.02", new Object[] { t.toString() }, t);
+ }
+
+ }
+
+}