aboutsummaryrefslogtreecommitdiff
path: root/moaSig/moa-asic/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'moaSig/moa-asic/src/main')
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiC.java13
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiCConstants.java9
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiCEntry.java38
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiCFactory.java159
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiCFormat.java9
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiCVerificationResult.java40
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiCVerifier.java16
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/exceptions/ASiCException.java7
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ASiCBaseFormatFactory.java134
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ASiCContainer.java22
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ASiCExtendedFormatFactory.java51
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ASiCImpl.java73
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ASiCMOAVerifier.java87
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ASiCSimpleFormatFactory.java54
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/EntryHandler.java14
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/Verifier.java18
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ZipCommentReaderStream.java180
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/AllDataHandler.java28
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/BaseHandler.java27
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/CAdESHandler.java20
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/EvidenceERSRecordHandler.java18
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/EvidenceXMLRecordHandler.java15
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/ExtendedASiCCAdESHandler.java13
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/ExtendedASiCXAdESHandler.java11
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/ExtendedEvidenceERSRecordHandler.java11
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/ExtendedEvidenceXMLRecordHandler.java11
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/HandlerSorter.java16
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/MetaInfHandler.java33
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/MimefileHandler.java36
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/SignatureHandler.java36
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/SimpleASiCCAdESHandler.java13
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/SimpleASiCXAdESHandler.java13
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/SimpleEvidenceERSRecordHandler.java13
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/SimpleEvidenceXMLRecordHandler.java13
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/XAdESHandler.java17
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/BaseVerifier.java61
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/CAdESVerifier.java43
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/ExtendedCAdESVerifier.java168
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/ExtendedXAdESVerifier.java184
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/SimpleCAdESVerifier.java45
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/SimpleXAdESVerifier.java128
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/XAdESVerifier.java54
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/xmlbind/VerifyASICSignatureRequestParser.java112
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/xmlbind/VerifyASICSignatureResponseBuilder.java177
-rw-r--r--moaSig/moa-asic/src/main/java/at/gv/egiz/asic/xmlbind/VerifyASiCRequest.java46
-rw-r--r--moaSig/moa-asic/src/main/resources/schemas/asic.xsd71
46 files changed, 2356 insertions, 1 deletions
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiC.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiC.java
new file mode 100644
index 0000000..e79d2ca
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiC.java
@@ -0,0 +1,13 @@
+package at.gv.egiz.asic.api;
+
+import java.util.List;
+
+public interface ASiC {
+ public ASiCFormat getFormat();
+ public boolean isXAdES();
+ public boolean isCAdES();
+
+ public List<ASiCEntry> getSignaturesEntries();
+ public List<ASiCEntry> getDataEntries();
+ public List<ASiCEntry> getInformationEntries();
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiCConstants.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiCConstants.java
new file mode 100644
index 0000000..02baf40
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiCConstants.java
@@ -0,0 +1,9 @@
+package at.gv.egiz.asic.api;
+
+/**
+ * Created by afitzek on 6/15/16.
+ */
+public interface ASiCConstants {
+ public static final String FILE_MIME_TYPE = "mimetype";
+ public static final String FILE_META_INF = "META-INF/";
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiCEntry.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiCEntry.java
new file mode 100644
index 0000000..7c026cf
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiCEntry.java
@@ -0,0 +1,38 @@
+package at.gv.egiz.asic.api;
+
+import java.io.InputStream;
+
+/**
+ * Created by afitzek on 6/15/16.
+ */
+public class ASiCEntry {
+
+ private String entryName;
+ private InputStream contents;
+
+ public ASiCEntry() {
+ }
+
+ public String getEntryName() {
+ return entryName;
+ }
+
+ public void setEntryName(String entryName) {
+ this.entryName = entryName;
+ }
+
+ public InputStream getContents() {
+ return contents;
+ }
+
+ public void setContents(InputStream contents) {
+ this.contents = contents;
+ }
+
+ @Override
+ public String toString() {
+ return "ASiCEntry{" +
+ "entryName='" + entryName + '\'' +
+ '}';
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiCFactory.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiCFactory.java
index e9ad9dc..6b067f7 100644
--- a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiCFactory.java
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiCFactory.java
@@ -1,7 +1,164 @@
package at.gv.egiz.asic.api;
+import at.gv.egiz.asic.exceptions.ASiCException;
+import at.gv.egiz.asic.impl.ASiCBaseFormatFactory;
+import at.gv.egiz.asic.impl.ASiCExtendedFormatFactory;
+import at.gv.egiz.asic.impl.ASiCSimpleFormatFactory;
+import at.gv.egiz.asic.impl.ZipCommentReaderStream;
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.MOAException;
+import org.apache.commons.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
/**
* Created by afitzek on 6/15/16.
*/
-public interface ASiCFactory {
+public class ASiCFactory {
+
+ private static final Logger logger = LoggerFactory.getLogger(ASiCFactory.class);
+
+ private static final String MIMETYPE_FORMAT_E = "application/vnd.etsi.asic-e+zip";
+ private static final String MIMETYPE_FORMAT_S = "application/vnd.etsi.asic-s+zip";
+
+ public static ASiC parseASiC(InputStream is, ASiCFormat format) throws MOAException {
+
+ InputStream newInputStream = is;
+
+
+ // Try to determine the asic format!
+ if (!newInputStream.markSupported()) {
+ ByteArrayOutputStream asicContainer = new ByteArrayOutputStream();
+
+ try {
+ IOUtils.copy(newInputStream, asicContainer);
+ } catch (IOException e) {
+ throw new MOAApplicationException("asic.0003", null);
+ }
+ newInputStream = new ByteArrayInputStream(asicContainer.toByteArray());
+ }
+
+ String mimeTypeFile = null;
+ ZipCommentReaderStream commentReaderStream = new ZipCommentReaderStream(newInputStream);
+ byte[] buffer = new byte[8096];
+ try {
+ while (commentReaderStream.read(buffer) >= 0) {
+ }
+ newInputStream.reset();
+ } catch (IOException e) {
+ throw new MOAApplicationException("asic.0003", null);
+ }
+
+ ZipInputStream zipInputStream = new ZipInputStream(newInputStream);
+
+ try {
+ for (ZipEntry entry = zipInputStream.getNextEntry(); entry != null; entry = zipInputStream.getNextEntry()) {
+ String entryName = entry.getName();
+
+ if("mimetype".equalsIgnoreCase(entryName)) {
+ if(mimeTypeFile == null) {
+ mimeTypeFile = IOUtils.toString(zipInputStream, "UTF-8");
+ } else {
+ logger.warn("multiple mimetype files found in archiv");
+ }
+ }
+ }
+ newInputStream.reset();
+ } catch (IOException e) {
+ throw new MOAApplicationException("asic.0007", null);
+ }
+
+ String fileComment = commentReaderStream.getFileComment();
+ ASiCFormat fileCommentFormat = null;
+ if (fileComment != null) {
+ logger.info("Found file comment in ASiC {}", fileComment);
+ if(fileComment.startsWith("mimetype=")) {
+ String fileCommentMimeType = fileComment.substring("mimetype=".length());
+ if(fileCommentMimeType.startsWith(MIMETYPE_FORMAT_E)) {
+ fileCommentFormat = ASiCFormat.ASiCE;
+ } else if(fileCommentMimeType.startsWith(MIMETYPE_FORMAT_S)) {
+ fileCommentFormat = ASiCFormat.ASiCS;
+ }
+ }
+ } else {
+ logger.info("No file comment in ASiC");
+ }
+
+
+ ASiCFormat mimeTypeFileFormat = null;
+ if (mimeTypeFile != null) {
+ logger.info("Found mimetype file in ASiC {}", mimeTypeFile);
+ if(MIMETYPE_FORMAT_E.equalsIgnoreCase(mimeTypeFile)) {
+ mimeTypeFileFormat = ASiCFormat.ASiCE;
+ } else if(MIMETYPE_FORMAT_S.equalsIgnoreCase(mimeTypeFile)) {
+ mimeTypeFileFormat = ASiCFormat.ASiCS;
+ }
+ } else {
+ logger.info("No mimetype file in ASiC");
+ }
+
+ if (format == null) {
+ if (fileCommentFormat != null && mimeTypeFileFormat != null) {
+ // both are set
+ if (fileCommentFormat == mimeTypeFileFormat) {
+ format = fileCommentFormat;
+ } else {
+ throw new MOAApplicationException("asic.0009", null);
+ }
+ } else if (fileCommentFormat != null) {
+ format = fileCommentFormat;
+ } else if (mimeTypeFileFormat != null) {
+ format = mimeTypeFileFormat;
+ } else {
+ throw new MOAApplicationException("asic.0008", null);
+ }
+ } else {
+ // format is provided, only check for missmatches
+ if (fileCommentFormat != null && fileCommentFormat != format) {
+ logger.warn("ASiC format missmatch file comment {} vs provided {}", fileCommentFormat, format);
+ throw new MOAApplicationException("asic.0009", null);
+ }
+ if (mimeTypeFileFormat != null && mimeTypeFileFormat != format) {
+ logger.warn("ASiC format missmatch mimetype file {} vs provided {}", mimeTypeFileFormat, format);
+ throw new MOAApplicationException("asic.0009", null);
+ }
+
+ if (fileCommentFormat != null && mimeTypeFileFormat != null) {
+ // both are set
+ if (fileCommentFormat != mimeTypeFileFormat) {
+ logger.warn("ASiC format missmatch file comment {} vs mimetype file {}", fileCommentFormat, mimeTypeFileFormat);
+ throw new MOAApplicationException("asic.0009", null);
+ }
+ }
+ }
+
+ ASiCBaseFormatFactory formatFactory = null;
+
+ if (format == null) {
+ throw new MOAApplicationException("asic.0008", null);
+ }
+
+ switch (format) {
+ case ASiCE:
+ formatFactory = new ASiCExtendedFormatFactory();
+ break;
+ case ASiCS:
+ formatFactory = new ASiCSimpleFormatFactory();
+ break;
+ }
+
+ if (formatFactory == null) {
+ throw new MOAApplicationException("asic.0008", null);
+ }
+
+ return formatFactory.createASiC(newInputStream);
+ }
+
}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiCFormat.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiCFormat.java
new file mode 100644
index 0000000..8106944
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiCFormat.java
@@ -0,0 +1,9 @@
+package at.gv.egiz.asic.api;
+
+/**
+ * Created by Andreas Fitzek on 6/15/16.
+ */
+public enum ASiCFormat {
+ ASiCS,
+ ASiCE
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiCVerificationResult.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiCVerificationResult.java
new file mode 100644
index 0000000..a350f18
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiCVerificationResult.java
@@ -0,0 +1,40 @@
+package at.gv.egiz.asic.api;
+
+import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponse;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by Andreas Fitzek on 6/16/16.
+ */
+public class ASiCVerificationResult {
+
+ private List<String> signedFiles = new ArrayList<String>();
+
+ private VerifyCMSSignatureResponse cmsResult = null;
+ private VerifyXMLSignatureResponse xmlResult = null;
+
+ public ASiCVerificationResult(List<String> references, VerifyCMSSignatureResponse cmsResult) {
+ this.signedFiles = references;
+ this.cmsResult = cmsResult;
+ }
+
+ public ASiCVerificationResult(List<String> references, VerifyXMLSignatureResponse xmlResult) {
+ this.signedFiles = references;
+ this.xmlResult = xmlResult;
+ }
+
+ public List<String> getSignedFiles() {
+ return signedFiles;
+ }
+
+ public VerifyXMLSignatureResponse getXmlResult() {
+ return xmlResult;
+ }
+
+ public VerifyCMSSignatureResponse getCmsResult() {
+ return cmsResult;
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiCVerifier.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiCVerifier.java
new file mode 100644
index 0000000..77bc61d
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/api/ASiCVerifier.java
@@ -0,0 +1,16 @@
+package at.gv.egiz.asic.api;
+
+import at.gv.egovernment.moa.spss.MOAException;
+import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponse;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Created by Andreas Fitzek on 6/15/16.
+ */
+public interface ASiCVerifier {
+
+ public List<ASiCVerificationResult> verify(ASiC asic, String trustProfileID, Date date) throws MOAException;
+
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/exceptions/ASiCException.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/exceptions/ASiCException.java
new file mode 100644
index 0000000..f29199a
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/exceptions/ASiCException.java
@@ -0,0 +1,7 @@
+package at.gv.egiz.asic.exceptions;
+
+/**
+ * Created by afitzek on 6/15/16.
+ */
+public class ASiCException {
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ASiCBaseFormatFactory.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ASiCBaseFormatFactory.java
new file mode 100644
index 0000000..bce179d
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ASiCBaseFormatFactory.java
@@ -0,0 +1,134 @@
+package at.gv.egiz.asic.impl;
+
+import at.gv.egiz.asic.api.ASiC;
+import at.gv.egiz.asic.api.ASiCEntry;
+import at.gv.egiz.asic.api.ASiCFormat;
+import at.gv.egiz.asic.impl.handler.*;
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.MOAException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+/**
+ * Created by Andreas Fitzek on 6/15/16.
+ */
+public abstract class ASiCBaseFormatFactory implements ASiCContainer {
+
+ private static final Logger logger = LoggerFactory.getLogger(ASiCBaseFormatFactory.class);
+
+ protected boolean cadesSigned = false;
+ protected boolean xadesSigned = false;
+ protected boolean timestamped = false;
+
+ protected String mimeType = null;
+
+ protected List<ASiCEntry> signatureEntries = new ArrayList<ASiCEntry>();
+ protected List<ASiCEntry> dataEntries = new ArrayList<ASiCEntry>();
+ protected List<ASiCEntry> informationEntries = new ArrayList<ASiCEntry>();
+
+ protected List<EntryHandler> handlers = new ArrayList<EntryHandler>();
+
+ @Override
+ public void addDataEntry(ASiCEntry entry) {
+ this.dataEntries.add(entry);
+ }
+
+ @Override
+ public void addSignatureEntry(ASiCEntry entry) {
+ this.signatureEntries.add(entry);
+ }
+
+ @Override
+ public void addInformationEntry(ASiCEntry entry) {
+ this.informationEntries.add(entry);
+ }
+
+ public ASiCBaseFormatFactory() {
+ handlers.add(new MimefileHandler());
+ handlers.add(new MetaInfHandler());
+ handlers.add(new AllDataHandler());
+ }
+
+ public abstract ASiCFormat factoryFormat();
+
+ protected abstract void validate() throws MOAException;
+
+ public ASiC createASiC(InputStream is) throws MOAException {
+
+ ZipCommentReaderStream commentReaderStream = new ZipCommentReaderStream(is);
+
+ ZipInputStream zipInputStream = new ZipInputStream(commentReaderStream);
+
+ try {
+ for (ZipEntry entry = zipInputStream.getNextEntry(); entry != null; entry = zipInputStream.getNextEntry()) {
+ String entryName = entry.getName();
+
+ Iterator<EntryHandler> handlerIterator = this.handlers.iterator();
+ while (handlerIterator.hasNext()) {
+ EntryHandler entryHandler = handlerIterator.next();
+
+ if (entryHandler.handle(entryName, zipInputStream, this)) {
+ break;
+ }
+ }
+ }
+ } catch(IOException e) {
+ logger.info("Failed to read from ASiC Container", e);
+ throw new MOAApplicationException("asic.0007", null);
+ }
+
+
+ if(this.mimeType == null) {
+ String mimeTypeComment = commentReaderStream.getFileComment();
+ if(mimeTypeComment != null) {
+ this.mimeType = mimeTypeComment;
+ }
+ }
+
+ this.validate();
+
+ // unpack and retrieve all available information on ASiC signature
+ return new ASiCImpl(this.factoryFormat(), this.xadesSigned, this.cadesSigned, this.signatureEntries, dataEntries, this.informationEntries);
+ }
+
+ @Override
+ public void setMimeType(String mimeType) {
+ this.mimeType = mimeType;
+ }
+
+ public void setIsXAdES() throws MOAException {
+ if(this.cadesSigned) {
+ throw new MOAApplicationException("asic.0010", null);
+ }
+ this.xadesSigned = true;
+ }
+
+ public void setIsCAdES() throws MOAException {
+ if(this.xadesSigned) {
+ throw new MOAApplicationException("asic.0010", null);
+ }
+ this.cadesSigned = true;
+ }
+
+ public void setIsTimestamped() throws MOAException {
+ throw new MOAApplicationException("asic.0013", null);
+ }
+
+ @Override
+ public void setIsEvidenceERS() throws MOAException {
+ throw new MOAApplicationException("asic.0011", null);
+ }
+
+ @Override
+ public void setIsEvidenceXML() throws MOAException {
+ throw new MOAApplicationException("asic.0012", null);
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ASiCContainer.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ASiCContainer.java
new file mode 100644
index 0000000..73d1566
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ASiCContainer.java
@@ -0,0 +1,22 @@
+package at.gv.egiz.asic.impl;
+
+import at.gv.egiz.asic.api.ASiCEntry;
+import at.gv.egovernment.moa.spss.MOAException;
+
+/**
+ * Created by afitzek on 6/15/16.
+ */
+public interface ASiCContainer {
+
+ public void setMimeType(String mimeType);
+ public void addDataEntry(ASiCEntry entry);
+ public void addSignatureEntry(ASiCEntry entry);
+ public void addInformationEntry(ASiCEntry entry);
+
+ public void setIsXAdES() throws MOAException;
+ public void setIsCAdES() throws MOAException;
+ public void setIsEvidenceERS() throws MOAException;
+ public void setIsEvidenceXML() throws MOAException;
+ public void setIsTimestamped() throws MOAException;
+
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ASiCExtendedFormatFactory.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ASiCExtendedFormatFactory.java
new file mode 100644
index 0000000..f71552b
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ASiCExtendedFormatFactory.java
@@ -0,0 +1,51 @@
+package at.gv.egiz.asic.impl;
+
+import at.gv.egiz.asic.api.ASiC;
+import at.gv.egiz.asic.api.ASiCFormat;
+import at.gv.egiz.asic.impl.handler.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+/**
+ * Created by Andreas Fitzek on 6/15/16.
+ */
+public class ASiCExtendedFormatFactory extends ASiCBaseFormatFactory {
+
+ private static final Logger logger = LoggerFactory.getLogger(ASiCExtendedFormatFactory.class);
+
+ public ASiCExtendedFormatFactory() {
+ super();
+ handlers.add(new ExtendedASiCCAdESHandler());
+ handlers.add(new ExtendedASiCXAdESHandler());
+ handlers.add(new ExtendedEvidenceERSRecordHandler());
+ handlers.add(new ExtendedEvidenceXMLRecordHandler());
+
+ Collections.sort(handlers, new HandlerSorter());
+
+ logger.debug("Handler ordering for ASiCExtendedFormatFactory");
+ Iterator<EntryHandler> handlerIterator = this.handlers.iterator();
+ while(handlerIterator.hasNext()) {
+ EntryHandler entryHandler = handlerIterator.next();
+ logger.debug(" " + entryHandler.getPriority() + " " + entryHandler.getClass().getSimpleName());
+ }
+ }
+
+ @Override
+ protected void validate() {
+
+ }
+
+ @Override
+ public ASiCFormat factoryFormat() {
+ return ASiCFormat.ASiCE;
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ASiCImpl.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ASiCImpl.java
new file mode 100644
index 0000000..c78385a
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ASiCImpl.java
@@ -0,0 +1,73 @@
+package at.gv.egiz.asic.impl;
+
+import at.gv.egiz.asic.api.ASiC;
+import at.gv.egiz.asic.api.ASiCEntry;
+import at.gv.egiz.asic.api.ASiCFormat;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by Andreas Fitzek on 6/15/16.
+ */
+public class ASiCImpl implements ASiC {
+
+ private ASiCFormat format;
+ private boolean xades;
+ private boolean cades;
+
+ protected List<ASiCEntry> signatureEntries = new ArrayList<ASiCEntry>();
+ protected List<ASiCEntry> dataEntries = new ArrayList<ASiCEntry>();
+ protected List<ASiCEntry> informationEntries = new ArrayList<ASiCEntry>();
+
+ public ASiCImpl(ASiCFormat format, boolean xades, boolean cades, List<ASiCEntry> signatureEntries, List<ASiCEntry> dataEntries, List<ASiCEntry> informationEntries) {
+ this.format = format;
+ this.xades = xades;
+ this.cades = cades;
+ this.signatureEntries = signatureEntries;
+ this.dataEntries = dataEntries;
+ this.informationEntries = informationEntries;
+ }
+
+ @Override
+ public ASiCFormat getFormat() {
+ return format;
+ }
+
+ @Override
+ public boolean isXAdES() {
+ return xades;
+ }
+
+ @Override
+ public boolean isCAdES() {
+ return cades;
+ }
+
+ @Override
+ public List<ASiCEntry> getSignaturesEntries() {
+ return signatureEntries;
+ }
+
+ @Override
+ public List<ASiCEntry> getDataEntries() {
+ return dataEntries;
+ }
+
+ @Override
+ public List<ASiCEntry> getInformationEntries() {
+ return informationEntries;
+ }
+
+ @Override
+ public String toString() {
+ return "ASiCImpl{" +
+ "format=" + format +
+ ", xades=" + xades +
+ ", cades=" + cades +
+ ", signatureEntries=" + signatureEntries +
+ ", dataEntries=" + dataEntries +
+ ", informationEntries=" + informationEntries +
+ '}';
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ASiCMOAVerifier.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ASiCMOAVerifier.java
new file mode 100644
index 0000000..51392da
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ASiCMOAVerifier.java
@@ -0,0 +1,87 @@
+package at.gv.egiz.asic.impl;
+
+import at.gv.egiz.asic.ASiCManifestType;
+import at.gv.egiz.asic.DataObjectReferenceType;
+import at.gv.egiz.asic.ReferenceType;
+import at.gv.egiz.asic.XAdESSignaturesType;
+import at.gv.egiz.asic.api.*;
+import at.gv.egiz.asic.impl.verifier.ExtendedCAdESVerifier;
+import at.gv.egiz.asic.impl.verifier.ExtendedXAdESVerifier;
+import at.gv.egiz.asic.impl.verifier.SimpleCAdESVerifier;
+import at.gv.egiz.asic.impl.verifier.SimpleXAdESVerifier;
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.MOAException;
+import at.gv.egovernment.moa.spss.MOARuntimeException;
+import at.gv.egovernment.moa.spss.MOASystemException;
+import at.gv.egovernment.moa.spss.api.SPSSFactory;
+import at.gv.egovernment.moa.spss.api.cmsverify.*;
+import at.gv.egovernment.moa.spss.api.common.*;
+import at.gv.egovernment.moa.spss.api.impl.SPSSFactoryImpl;
+import at.gv.egovernment.moa.spss.api.xmlverify.SupplementProfile;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifySignatureInfo;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifySignatureLocation;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest;
+import at.gv.egovernment.moa.spss.server.invoke.CMSSignatureVerificationInvoker;
+import at.gv.egovernment.moa.spss.server.invoke.VerifyCMSSignatureResponseBuilder;
+import at.gv.egovernment.moa.spss.server.invoke.XMLSignatureVerificationInvoker;
+import iaik.server.cmspdfverify.CertificateValidationResult;
+import org.apache.commons.codec.binary.Hex;
+import org.apache.commons.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.xml.bind.DataBindingException;
+import javax.xml.bind.JAXB;
+import javax.xml.crypto.dsig.Reference;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.DigestInputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.X509Certificate;
+import java.util.*;
+
+/**
+ * Created by Andreas Fitzek on 6/15/16.
+ */
+public class ASiCMOAVerifier implements ASiCVerifier {
+
+ private static final Logger logger = LoggerFactory.getLogger(ASiCMOAVerifier.class);
+
+ private List<Verifier> verifierMap = new ArrayList<Verifier>();
+
+ public ASiCMOAVerifier() {
+ verifierMap.add(new SimpleCAdESVerifier());
+ verifierMap.add(new SimpleXAdESVerifier());
+ verifierMap.add(new ExtendedCAdESVerifier());
+ verifierMap.add(new ExtendedXAdESVerifier());
+ }
+
+ @Override
+ public List<ASiCVerificationResult> verify(ASiC asic, String trustProfileID, Date date) throws MOAException {
+ List<ASiCVerificationResult> response = new ArrayList<ASiCVerificationResult>();
+ boolean handled = false;
+
+ Iterator<Verifier> verifierIterator = verifierMap.iterator();
+
+ while (verifierIterator.hasNext()) {
+ Verifier verifier = verifierIterator.next();
+ if (verifier.handles(asic)) {
+ verifier.verify(asic, trustProfileID, date, response);
+ handled = true;
+ break;
+ }
+ }
+
+ if (!handled) {
+ logger.warn("Cannot handle ASiC: {}", asic);
+ throw new MOASystemException("asic.0016", null);
+ }
+
+ return response;
+ }
+
+
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ASiCSimpleFormatFactory.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ASiCSimpleFormatFactory.java
new file mode 100644
index 0000000..90b3081
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ASiCSimpleFormatFactory.java
@@ -0,0 +1,54 @@
+package at.gv.egiz.asic.impl;
+
+import at.gv.egiz.asic.api.ASiCFormat;
+import at.gv.egiz.asic.impl.handler.*;
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collections;
+import java.util.Iterator;
+
+/**
+ * Created by Andreas Fitzek on 6/15/16.
+ */
+public class ASiCSimpleFormatFactory extends ASiCBaseFormatFactory {
+
+ private static final Logger logger = LoggerFactory.getLogger(ASiCSimpleFormatFactory.class);
+
+ public ASiCSimpleFormatFactory() {
+ super();
+
+ handlers.add(new SimpleASiCCAdESHandler());
+ handlers.add(new SimpleASiCXAdESHandler());
+ handlers.add(new SimpleEvidenceXMLRecordHandler());
+ handlers.add(new SimpleEvidenceERSRecordHandler());
+
+ Collections.sort(handlers, new HandlerSorter());
+
+ logger.debug("Handler ordering for ASiCSimpleFormatFactory");
+ Iterator<EntryHandler> handlerIterator = this.handlers.iterator();
+ while(handlerIterator.hasNext()) {
+ EntryHandler entryHandler = handlerIterator.next();
+ logger.debug(" " + entryHandler.getPriority() + " " + entryHandler.getClass().getSimpleName());
+ }
+ }
+
+ @Override
+ protected void validate() throws MOAApplicationException {
+ if(this.dataEntries.size() != 1) {
+ logger.warn("There can only be one data entry for ASiC signatures in simple format");
+ throw new MOAApplicationException("asic.0014", null);
+ }
+
+ if(this.signatureEntries.size() != 1) {
+ logger.warn("There can only be one signature entry for ASiC signatures in simple format");
+ throw new MOAApplicationException("asic.0015", null);
+ }
+ }
+
+ @Override
+ public ASiCFormat factoryFormat() {
+ return ASiCFormat.ASiCS;
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/EntryHandler.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/EntryHandler.java
new file mode 100644
index 0000000..7767b33
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/EntryHandler.java
@@ -0,0 +1,14 @@
+package at.gv.egiz.asic.impl;
+
+import at.gv.egovernment.moa.spss.MOAException;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Created by afitzek on 6/15/16.
+ */
+public interface EntryHandler {
+ public int getPriority();
+ public boolean handle(String entryName, InputStream is, ASiCContainer container) throws IOException, MOAException;
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/Verifier.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/Verifier.java
new file mode 100644
index 0000000..95a2450
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/Verifier.java
@@ -0,0 +1,18 @@
+package at.gv.egiz.asic.impl;
+
+import at.gv.egiz.asic.api.ASiC;
+import at.gv.egiz.asic.api.ASiCVerificationResult;
+import at.gv.egovernment.moa.spss.MOAException;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Created by Andreas Fitzek on 6/17/16.
+ */
+public interface Verifier {
+ public boolean handles(ASiC asic);
+
+ public void verify(ASiC asic, String trustProfileID, Date date, List<ASiCVerificationResult> response)
+ throws MOAException;
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ZipCommentReaderStream.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ZipCommentReaderStream.java
new file mode 100644
index 0000000..93b7651
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/ZipCommentReaderStream.java
@@ -0,0 +1,180 @@
+package at.gv.egiz.asic.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Created by afitzek on 6/15/16.
+ */
+public class ZipCommentReaderStream extends InputStream {
+
+ private InputStream inputStream;
+
+ private int[] tempBuffer = new int[22];
+
+ private int[] commentBuffer = null;
+
+ private int commentBufferContentLen = 0;
+ private int commentBufferContentOff = 0;
+
+ private int tempBufferContentLen = 0;
+ private int tempBufferContentOff = 0;
+
+ private String fileComment = null;
+
+ private static final byte[] directoryRecord = new byte[] { (byte)0x50, (byte)0x4b, 0x05, 0x06 };
+
+ public ZipCommentReaderStream(InputStream inputStream) {
+ this.inputStream = inputStream;
+ }
+
+ private int readIntIntoBuffer() throws IOException {
+ int tValue = this.inputStream.read();
+
+ if(this.tempBuffer.length <= tempBufferContentOff) {
+ throw new IOException("Temp Buffer is out of space! @ " + tempBufferContentOff);
+ }
+
+ this.tempBuffer[tempBufferContentOff] = tValue;
+ tempBufferContentOff++;
+ tempBufferContentLen++;
+
+ return tValue;
+ }
+
+ private int readIntIntoCommentBuffer() throws IOException {
+ int tValue = this.inputStream.read();
+
+ if(this.commentBuffer.length <= commentBufferContentOff) {
+ throw new IOException("Comment Buffer is out of space! @ " + commentBufferContentOff);
+ }
+
+ this.commentBuffer[commentBufferContentOff] = tValue;
+ commentBufferContentOff++;
+ commentBufferContentLen++;
+
+ return tValue;
+ }
+
+ private void checkMagicBytes() throws IOException {
+ boolean foundMagic = true;
+ tempBufferContentOff = 0;
+ tempBufferContentLen = 0;
+ for(int i = 1; i < directoryRecord.length; i++) {
+ int tValue = readIntIntoBuffer();
+ if(tValue != directoryRecord[i]) {
+ foundMagic = false;
+ break;
+ }
+ if(tValue < 0) {
+ // Found EOF
+ return;
+ }
+ }
+
+ if(foundMagic) {
+ // read input stream until comment length
+ for(int i = 0; i < 16; i++) {
+ int tValue = readIntIntoBuffer();
+
+ if(tValue < 0) {
+ // Found EOF
+ return;
+ }
+ }
+
+ int commentlengthHigh = readIntIntoBuffer();
+
+ if(commentlengthHigh < 0) {
+ // Found EOF
+ return;
+ }
+
+ int commentlengthLow = readIntIntoBuffer();
+
+ if(commentlengthLow < 0) {
+ // Found EOF
+ return;
+ }
+
+ int commentLength = commentlengthLow * 255 + commentlengthHigh;
+
+ if(commentLength == 0) {
+ return;
+ }
+
+ this.commentBuffer = new int[commentLength];
+
+ commentBufferContentOff = 0;
+ commentBufferContentLen = 0;
+
+ // read comment buffer string
+ for(int i = 0; i < commentLength; i++) {
+ int tValue = readIntIntoCommentBuffer();
+
+ if(tValue < 0) {
+ // Found EOF
+ return;
+ }
+ }
+
+ byte[] stringBuffer = new byte[this.commentBuffer.length];
+
+ for(int i = 0; i < stringBuffer.length; i++) {
+ stringBuffer[i] = (byte)this.commentBuffer[i];
+ }
+
+ this.fileComment = new String(stringBuffer);
+ }
+ }
+
+ @Override
+ public int read() throws IOException {
+ int value = -1;
+ if(tempBufferContentLen > 0) {
+ value = this.tempBuffer[tempBufferContentOff];
+ tempBufferContentOff++;
+
+ // reset temp buffer
+ if(tempBufferContentOff >= tempBufferContentLen) {
+ tempBufferContentOff = 0;
+ tempBufferContentLen = 0;
+ }
+
+ return value;
+ }
+
+ if(this.commentBuffer != null) {
+ value = this.commentBuffer[commentBufferContentOff];
+
+ commentBufferContentOff++;
+
+ // reset comment buffer
+ if(commentBufferContentOff >= commentBufferContentLen) {
+ commentBufferContentOff = 0;
+ commentBufferContentLen = 0;
+ this.commentBuffer = null;
+ }
+
+ return value;
+ }
+
+ value = this.inputStream.read();
+
+ if(value == directoryRecord[0] && this.fileComment == null) {
+ // might have found start of magic bytes
+ checkMagicBytes();
+ // reset buffer offsets
+ tempBufferContentOff = 0;
+ commentBufferContentOff = 0;
+ }
+
+ return value;
+ }
+
+ public String getFileComment() {
+ return this.fileComment;
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/AllDataHandler.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/AllDataHandler.java
new file mode 100644
index 0000000..fa31bfc
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/AllDataHandler.java
@@ -0,0 +1,28 @@
+package at.gv.egiz.asic.impl.handler;
+
+import at.gv.egiz.asic.api.ASiCConstants;
+import at.gv.egiz.asic.impl.ASiCContainer;
+import at.gv.egiz.asic.api.ASiCEntry;
+import at.gv.egiz.asic.impl.EntryHandler;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Created by afitzek on 6/15/16.
+ */
+public class AllDataHandler extends BaseHandler implements EntryHandler, ASiCConstants {
+ @Override
+ public int getPriority() {
+ return 100;
+ }
+
+ @Override
+ public boolean handle(String entryName, InputStream is, ASiCContainer container) throws IOException {
+
+ ASiCEntry entry = buildASiCEntry(entryName, is);
+ container.addDataEntry(entry);
+
+ return true;
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/BaseHandler.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/BaseHandler.java
new file mode 100644
index 0000000..2b5ca9a
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/BaseHandler.java
@@ -0,0 +1,27 @@
+package at.gv.egiz.asic.impl.handler;
+
+import at.gv.egiz.asic.api.ASiCConstants;
+import at.gv.egiz.asic.api.ASiCEntry;
+import at.gv.egiz.asic.impl.EntryHandler;
+import org.apache.commons.io.IOUtils;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Created by Andreas Fitzek on 6/15/16.
+ */
+public abstract class BaseHandler implements EntryHandler, ASiCConstants {
+
+ protected ASiCEntry buildASiCEntry(String entryName, InputStream is) throws IOException {
+ ASiCEntry entry = new ASiCEntry();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ IOUtils.copy(is, baos);
+ entry.setContents(new ByteArrayInputStream(baos.toByteArray()));
+ entry.setEntryName(entryName);
+ return entry;
+ }
+
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/CAdESHandler.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/CAdESHandler.java
new file mode 100644
index 0000000..3ee97fc
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/CAdESHandler.java
@@ -0,0 +1,20 @@
+package at.gv.egiz.asic.impl.handler;
+
+import at.gv.egiz.asic.api.ASiCConstants;
+import at.gv.egiz.asic.impl.ASiCContainer;
+import at.gv.egiz.asic.impl.EntryHandler;
+import at.gv.egovernment.moa.spss.MOAException;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Created by Andreas Fitzek on 6/15/16.
+ */
+public abstract class CAdESHandler extends SignatureHandler implements EntryHandler, ASiCConstants {
+
+ @Override
+ protected void setType(ASiCContainer container) throws MOAException {
+ container.setIsCAdES();
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/EvidenceERSRecordHandler.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/EvidenceERSRecordHandler.java
new file mode 100644
index 0000000..f89c6d0
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/EvidenceERSRecordHandler.java
@@ -0,0 +1,18 @@
+package at.gv.egiz.asic.impl.handler;
+
+import at.gv.egiz.asic.impl.ASiCContainer;
+import at.gv.egovernment.moa.spss.MOAException;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Created by Andreas Fitzek on 6/17/16.
+ */
+public abstract class EvidenceERSRecordHandler extends SignatureHandler {
+
+ @Override
+ protected void setType(ASiCContainer container) throws MOAException {
+ container.setIsEvidenceERS();
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/EvidenceXMLRecordHandler.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/EvidenceXMLRecordHandler.java
new file mode 100644
index 0000000..4516bb0
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/EvidenceXMLRecordHandler.java
@@ -0,0 +1,15 @@
+package at.gv.egiz.asic.impl.handler;
+
+import at.gv.egiz.asic.impl.ASiCContainer;
+import at.gv.egovernment.moa.spss.MOAException;
+
+/**
+ * Created by Andreas Fitzek on 6/17/16.
+ */
+public abstract class EvidenceXMLRecordHandler extends SignatureHandler {
+
+ @Override
+ protected void setType(ASiCContainer container) throws MOAException {
+ container.setIsEvidenceXML();
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/ExtendedASiCCAdESHandler.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/ExtendedASiCCAdESHandler.java
new file mode 100644
index 0000000..464bcf6
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/ExtendedASiCCAdESHandler.java
@@ -0,0 +1,13 @@
+package at.gv.egiz.asic.impl.handler;
+
+import at.gv.egiz.asic.api.ASiCConstants;
+
+/**
+ * Created by Andreas Fitzek on 6/15/16.
+ */
+public class ExtendedASiCCAdESHandler extends CAdESHandler {
+ @Override
+ protected boolean matches(String entryName) {
+ return entryName.endsWith(".p7s") && entryName.startsWith(FILE_META_INF) && entryName.contains("signature");
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/ExtendedASiCXAdESHandler.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/ExtendedASiCXAdESHandler.java
new file mode 100644
index 0000000..28b21a3
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/ExtendedASiCXAdESHandler.java
@@ -0,0 +1,11 @@
+package at.gv.egiz.asic.impl.handler;
+
+/**
+ * Created by Andreas Fitzek on 6/15/16.
+ */
+public class ExtendedASiCXAdESHandler extends XAdESHandler {
+ @Override
+ protected boolean matches(String entryName) {
+ return entryName.endsWith(".xml") && entryName.startsWith(FILE_META_INF) && entryName.contains("signature");
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/ExtendedEvidenceERSRecordHandler.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/ExtendedEvidenceERSRecordHandler.java
new file mode 100644
index 0000000..ccf9224
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/ExtendedEvidenceERSRecordHandler.java
@@ -0,0 +1,11 @@
+package at.gv.egiz.asic.impl.handler;
+
+/**
+ * Created by Andreas Fitzek on 6/17/16.
+ */
+public class ExtendedEvidenceERSRecordHandler extends EvidenceERSRecordHandler {
+ @Override
+ protected boolean matches(String entryName) {
+ return entryName.endsWith(".ers") && entryName.startsWith(FILE_META_INF) && entryName.contains("evidencerecord");
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/ExtendedEvidenceXMLRecordHandler.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/ExtendedEvidenceXMLRecordHandler.java
new file mode 100644
index 0000000..d24d61b
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/ExtendedEvidenceXMLRecordHandler.java
@@ -0,0 +1,11 @@
+package at.gv.egiz.asic.impl.handler;
+
+/**
+ * Created by Andreas Fitzek on 6/17/16.
+ */
+public class ExtendedEvidenceXMLRecordHandler extends EvidenceERSRecordHandler {
+ @Override
+ protected boolean matches(String entryName) {
+ return entryName.endsWith(".xml") && entryName.startsWith(FILE_META_INF) && entryName.contains("evidencerecord");
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/HandlerSorter.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/HandlerSorter.java
new file mode 100644
index 0000000..36a215d
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/HandlerSorter.java
@@ -0,0 +1,16 @@
+package at.gv.egiz.asic.impl.handler;
+
+import at.gv.egiz.asic.impl.EntryHandler;
+
+import java.util.Comparator;
+
+/**
+ * Created by afitzek on 6/15/16.
+ */
+public class HandlerSorter implements Comparator<EntryHandler> {
+
+ @Override
+ public int compare(EntryHandler o1, EntryHandler o2) {
+ return Integer.compare(o1.getPriority(), o2.getPriority());
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/MetaInfHandler.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/MetaInfHandler.java
new file mode 100644
index 0000000..ec4f101
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/MetaInfHandler.java
@@ -0,0 +1,33 @@
+package at.gv.egiz.asic.impl.handler;
+
+import at.gv.egiz.asic.api.ASiCConstants;
+import at.gv.egiz.asic.impl.ASiCContainer;
+import at.gv.egiz.asic.api.ASiCEntry;
+import at.gv.egiz.asic.impl.EntryHandler;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Created by Andreas Fitzek on 6/15/16.
+ */
+public class MetaInfHandler extends BaseHandler implements EntryHandler, ASiCConstants {
+ @Override
+ public int getPriority() {
+ return 20;
+ }
+
+ @Override
+ public boolean handle(String entryName, InputStream is, ASiCContainer container) throws IOException {
+
+ boolean metainf = entryName.startsWith(FILE_META_INF);
+
+ if(metainf) {
+ ASiCEntry entry = buildASiCEntry(entryName, is);
+ container.addInformationEntry(entry);
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/MimefileHandler.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/MimefileHandler.java
new file mode 100644
index 0000000..68fc87e
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/MimefileHandler.java
@@ -0,0 +1,36 @@
+package at.gv.egiz.asic.impl.handler;
+
+import at.gv.egiz.asic.api.ASiCConstants;
+import at.gv.egiz.asic.impl.ASiCContainer;
+import at.gv.egiz.asic.impl.EntryHandler;
+import org.apache.commons.io.IOUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Created by afitzek on 6/15/16.
+ */
+public class MimefileHandler implements EntryHandler, ASiCConstants {
+
+ private boolean isMimeType(String entryName) {
+ return FILE_MIME_TYPE.equalsIgnoreCase(entryName);
+ }
+
+ @Override
+ public int getPriority() {
+ return 1;
+ }
+
+ @Override
+ public boolean handle(String entryName, InputStream is, ASiCContainer container) throws IOException {
+
+ if(isMimeType(entryName)) {
+ String mimeType = IOUtils.toString(is, "UTF-8");
+ container.setMimeType(mimeType);
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/SignatureHandler.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/SignatureHandler.java
new file mode 100644
index 0000000..621c9d4
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/SignatureHandler.java
@@ -0,0 +1,36 @@
+package at.gv.egiz.asic.impl.handler;
+
+import at.gv.egiz.asic.impl.ASiCContainer;
+import at.gv.egovernment.moa.spss.MOAException;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Created by Andreas Fitzek on 6/15/16.
+ */
+public abstract class SignatureHandler extends BaseHandler {
+
+ @Override
+ public int getPriority() {
+ return 0;
+ }
+
+ protected abstract boolean matches(String entryName);
+
+ protected abstract void setType(ASiCContainer container) throws MOAException;
+
+ @Override
+ public boolean handle(String entryName, InputStream is, ASiCContainer container) throws IOException, MOAException {
+ boolean signature = this.matches(entryName);
+
+ if(signature) {
+ this.setType(container);
+ container.addSignatureEntry(buildASiCEntry(entryName, is));
+ return true;
+ }
+
+ return false;
+ }
+
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/SimpleASiCCAdESHandler.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/SimpleASiCCAdESHandler.java
new file mode 100644
index 0000000..fdeda41
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/SimpleASiCCAdESHandler.java
@@ -0,0 +1,13 @@
+package at.gv.egiz.asic.impl.handler;
+
+import at.gv.egiz.asic.api.ASiCConstants;
+
+/**
+ * Created by Andreas Fitzek on 6/15/16.
+ */
+public class SimpleASiCCAdESHandler extends CAdESHandler {
+ @Override
+ protected boolean matches(String entryName) {
+ return (ASiCConstants.FILE_META_INF + "signature.p7s").equalsIgnoreCase(entryName);
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/SimpleASiCXAdESHandler.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/SimpleASiCXAdESHandler.java
new file mode 100644
index 0000000..66a7546
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/SimpleASiCXAdESHandler.java
@@ -0,0 +1,13 @@
+package at.gv.egiz.asic.impl.handler;
+
+import at.gv.egiz.asic.api.ASiCConstants;
+
+/**
+ * Created by Andreas Fitzek on 6/15/16.
+ */
+public class SimpleASiCXAdESHandler extends XAdESHandler {
+ @Override
+ protected boolean matches(String entryName) {
+ return (ASiCConstants.FILE_META_INF + "signatures.xml").equalsIgnoreCase(entryName);
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/SimpleEvidenceERSRecordHandler.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/SimpleEvidenceERSRecordHandler.java
new file mode 100644
index 0000000..58221f5
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/SimpleEvidenceERSRecordHandler.java
@@ -0,0 +1,13 @@
+package at.gv.egiz.asic.impl.handler;
+
+import at.gv.egiz.asic.api.ASiCConstants;
+
+/**
+ * Created by Andreas Fitzek on 6/17/16.
+ */
+public class SimpleEvidenceERSRecordHandler extends EvidenceERSRecordHandler {
+ @Override
+ protected boolean matches(String entryName) {
+ return (ASiCConstants.FILE_META_INF + "evidencerecord.ers").equalsIgnoreCase(entryName);
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/SimpleEvidenceXMLRecordHandler.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/SimpleEvidenceXMLRecordHandler.java
new file mode 100644
index 0000000..dacc218
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/SimpleEvidenceXMLRecordHandler.java
@@ -0,0 +1,13 @@
+package at.gv.egiz.asic.impl.handler;
+
+import at.gv.egiz.asic.api.ASiCConstants;
+
+/**
+ * Created by Andreas Fitzek on 6/17/16.
+ */
+public class SimpleEvidenceXMLRecordHandler extends EvidenceERSRecordHandler {
+ @Override
+ protected boolean matches(String entryName) {
+ return (ASiCConstants.FILE_META_INF + "evidencerecord.xml").equalsIgnoreCase(entryName);
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/XAdESHandler.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/XAdESHandler.java
new file mode 100644
index 0000000..ff19759
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/handler/XAdESHandler.java
@@ -0,0 +1,17 @@
+package at.gv.egiz.asic.impl.handler;
+
+import at.gv.egiz.asic.api.ASiCConstants;
+import at.gv.egiz.asic.impl.ASiCContainer;
+import at.gv.egiz.asic.impl.EntryHandler;
+import at.gv.egovernment.moa.spss.MOAException;
+
+/**
+ * Created by afitzek on 6/15/16.
+ */
+public abstract class XAdESHandler extends SignatureHandler implements EntryHandler, ASiCConstants {
+
+ @Override
+ protected void setType(ASiCContainer container) throws MOAException {
+ container.setIsXAdES();
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/BaseVerifier.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/BaseVerifier.java
new file mode 100644
index 0000000..a0bc516
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/BaseVerifier.java
@@ -0,0 +1,61 @@
+package at.gv.egiz.asic.impl.verifier;
+
+import at.gv.egiz.asic.impl.Verifier;
+import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponse;
+import org.apache.commons.codec.binary.Hex;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by Andreas Fitzek on 6/17/16.
+ */
+public abstract class BaseVerifier implements Verifier {
+
+ protected static Map<String, String> hashTranslator = new HashMap<String, String>();
+
+ static {
+ hashTranslator.put("http://www.w3.org/2000/09/xmldsig#sha1", "SHA-1");
+ hashTranslator.put("http://www.w3.org/2001/04/xmldsig-more#sha224", "SHA-224");
+ hashTranslator.put("http://www.w3.org/2001/04/xmlenc#sha256", "SHA-256");
+ hashTranslator.put("http://www.w3.org/2001/04/xmldsig-more#sha384", "SHA-384");
+ hashTranslator.put("http://www.w3.org/2001/04/xmlenc#sha512", "SHA-512");
+ hashTranslator.put("http://www.w3.org/2001/04/xmlenc#ripemd160", "RIPEMD-160");
+ }
+
+ private static final Logger logger = LoggerFactory.getLogger(BaseVerifier.class);
+
+ protected boolean compareHash(byte[] reference, byte[] calculated, String refName) {
+ String referenceHex = Hex.encodeHexString(reference);
+ String calculatedHex = Hex.encodeHexString(calculated);
+ if(Arrays.equals(reference, calculated)) {
+ logger.info("Digest from manifest do match for {}", refName);
+ return true;
+ } else {
+ logger.info("Digest from manifest do not match for {}", refName);
+ logger.info("Digest from manifest for {} : {}", refName, referenceHex);
+ logger.info("Digest from calculated for {} : {}", refName, calculatedHex);
+ return false;
+ }
+ }
+
+ protected MessageDigest getMessageDigestFromURI(String uri) {
+ try {
+
+ String algo = hashTranslator.get(uri);
+
+ if(algo == null) {
+ algo = uri;
+ }
+
+ return MessageDigest.getInstance(algo);
+ } catch (NoSuchAlgorithmException e) {
+ return null;
+ }
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/CAdESVerifier.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/CAdESVerifier.java
new file mode 100644
index 0000000..5ab677c
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/CAdESVerifier.java
@@ -0,0 +1,43 @@
+package at.gv.egiz.asic.impl.verifier;
+
+import at.gv.egiz.asic.api.ASiC;
+import at.gv.egovernment.moa.spss.MOAException;
+import at.gv.egovernment.moa.spss.api.SPSSFactory;
+import at.gv.egovernment.moa.spss.api.cmsverify.CMSContent;
+import at.gv.egovernment.moa.spss.api.cmsverify.CMSDataObject;
+import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureRequest;
+import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponse;
+import at.gv.egovernment.moa.spss.server.invoke.CMSSignatureVerificationInvoker;
+
+import java.io.InputStream;
+import java.util.Date;
+
+/**
+ * Created by Andreas Fitzek on 6/17/16.
+ */
+public abstract class CAdESVerifier extends BaseVerifier {
+ @Override
+ public boolean handles(ASiC asic) {
+ return asic.isCAdES();
+ }
+
+ protected VerifyCMSSignatureResponse runCMSVerification(InputStream signedData, InputStream cmsSignature,
+ String trustProfileID, Date date) throws MOAException {
+ CMSContent cmsContent = SPSSFactory.getInstance().createCMSContent(signedData);
+ CMSDataObject cmsDataObject = SPSSFactory.getInstance().createCMSDataObject(null, cmsContent, null, null);
+
+ VerifyCMSSignatureRequest verifyCMSSignatureRequest =
+ SPSSFactory.getInstance().createVerifyCMSSignatureRequest(
+ VerifyCMSSignatureRequest.ALL_SIGNATORIES,
+ date,
+ cmsSignature,
+ cmsDataObject,
+ trustProfileID,
+ false,
+ true);
+
+ VerifyCMSSignatureResponse verifyResponse = CMSSignatureVerificationInvoker.getInstance().verifyCMSSignature(
+ verifyCMSSignatureRequest);
+ return verifyResponse;
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/ExtendedCAdESVerifier.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/ExtendedCAdESVerifier.java
new file mode 100644
index 0000000..e71f263
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/ExtendedCAdESVerifier.java
@@ -0,0 +1,168 @@
+package at.gv.egiz.asic.impl.verifier;
+
+import at.gv.egiz.asic.ASiCManifestType;
+import at.gv.egiz.asic.DataObjectReferenceType;
+import at.gv.egiz.asic.api.ASiC;
+import at.gv.egiz.asic.api.ASiCEntry;
+import at.gv.egiz.asic.api.ASiCFormat;
+import at.gv.egiz.asic.api.ASiCVerificationResult;
+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.cmsverify.*;
+import at.gv.egovernment.moa.spss.api.common.CheckResult;
+import at.gv.egovernment.moa.spss.api.common.SignerInfo;
+import at.gv.egovernment.moa.spss.server.invoke.CMSSignatureVerificationInvoker;
+import org.apache.commons.codec.binary.Hex;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.xml.bind.JAXB;
+import java.io.IOException;
+import java.security.DigestInputStream;
+import java.security.MessageDigest;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Created by Andreas Fitzek on 6/17/16.
+ */
+public class ExtendedCAdESVerifier extends CAdESVerifier {
+
+ private static final Logger logger = LoggerFactory.getLogger(ExtendedCAdESVerifier.class);
+
+ @Override
+ public boolean handles(ASiC asic) {
+ return super.handles(asic) && ASiCFormat.ASiCE.equals(asic.getFormat());
+ }
+
+ @Override
+ public void verify(ASiC asic, String trustProfileID, Date date, List<ASiCVerificationResult> response) throws MOAException {
+ try {
+ Iterator<ASiCEntry> informationsIterator = asic.getInformationEntries().iterator();
+
+ while (informationsIterator.hasNext()) {
+ ASiCEntry informationEntry = informationsIterator.next();
+
+ if (informationEntry.getEntryName().startsWith("META-INF/") && informationEntry.getEntryName().endsWith(".xml")
+ && informationEntry.getEntryName().contains("ASiCManifest")) {
+ // Got ASiC Manifest
+ ASiCManifestType asiCManifestType = JAXB.unmarshal(informationEntry.getContents(), ASiCManifestType.class);
+ String signatureName = asiCManifestType.getSigReference().getURI();
+
+ ASiCEntry cadesSignature = null;
+
+ // find referenced signature
+ Iterator<ASiCEntry> cadesSignatureIterator = asic.getSignaturesEntries().iterator();
+
+ while (cadesSignatureIterator.hasNext()) {
+ ASiCEntry tmpCadesSignature = cadesSignatureIterator.next();
+ if (signatureName.equalsIgnoreCase(tmpCadesSignature.getEntryName())) {
+ cadesSignature = tmpCadesSignature;
+ break;
+ }
+ }
+
+ if (cadesSignature == null) {
+ throw new MOAApplicationException("asic.0004", new Object[]{signatureName});
+ }
+
+ // verify all references
+
+ boolean allReferencesValid = true;
+ List<String> signedFiles = new ArrayList<String>();
+ Iterator<DataObjectReferenceType> dataObjectReferenceTypeIterator = asiCManifestType.getDataObjectReference().iterator();
+ while (dataObjectReferenceTypeIterator.hasNext()) {
+ DataObjectReferenceType dataObjectReferenceType = dataObjectReferenceTypeIterator.next();
+
+ String mdURI = dataObjectReferenceType.getDigestMethod().getAlgorithm();
+ String uri = dataObjectReferenceType.getURI();
+ signedFiles.add(uri);
+
+ Iterator<ASiCEntry> dataEntryIterator = asic.getDataEntries().iterator();
+
+ while (dataEntryIterator.hasNext()) {
+ ASiCEntry dataEntry = dataEntryIterator.next();
+ if (uri.equalsIgnoreCase(dataEntry.getEntryName())) {
+ MessageDigest md = this.getMessageDigestFromURI(mdURI);
+ if (md == null) {
+ throw new MOAApplicationException("asic.0005", new Object[]{mdURI});
+ }
+ DigestInputStream dis = new DigestInputStream(dataEntry.getContents(), md);
+ byte[] buffer = new byte[8096];
+ while (dis.read(buffer) > 0) ;
+
+ if (!this.compareHash(dataObjectReferenceType.getDigestValue(), md.digest(), uri)) {
+ allReferencesValid = false;
+ }
+
+ dataEntry.getContents().reset();
+ break;
+ }
+ }
+ }
+
+ if (allReferencesValid) {
+ logger.info("ASiCManifest {} references do match data files!",
+ informationEntry.getEntryName());
+ }
+
+ informationEntry.getContents().reset();
+ MessageDigest md = this.getMessageDigestFromURI("SHA-256");
+ DigestInputStream dis = new DigestInputStream(informationEntry.getContents(), md);
+
+ VerifyCMSSignatureResponse verifyResponse =
+ this.runCMSVerification(dis, cadesSignature.getContents(), trustProfileID, date);
+
+ dis.close();
+
+ String fullDigest = Hex.encodeHexString(md.digest());
+ logger.info("CMS Input data {}", fullDigest);
+
+ if (!allReferencesValid) {
+ logger.warn("ASiCManifest {} References do not match data files!",
+ informationEntry.getEntryName());
+ List responseElements = new ArrayList();
+
+ SignerInfo signerInfo;
+
+
+ // add SignerInfo element
+ Iterator responseElementIterator = verifyResponse.getResponseElements().iterator();
+ while (responseElementIterator.hasNext()) {
+ VerifyCMSSignatureResponseElement orig = (VerifyCMSSignatureResponseElement)
+ responseElementIterator.next();
+
+ CheckResult signatureCheck;
+ CheckResult certificateCheck;
+
+ // add SignatureCheck element
+ signatureCheck = SPSSFactory.getInstance().createCheckResult(1, null);
+
+ // build the response element
+ VerifyCMSSignatureResponseElement responseElement =
+ SPSSFactory.getInstance().createVerifyCMSSignatureResponseElement(
+ orig.getSignerInfo(),
+ signatureCheck,
+ orig.getCertificateCheck(),
+ orig.getAdESFormResults(),
+ orig.getExtendedCertificateCheck());
+ responseElements.add(responseElement);
+ }
+ VerifyCMSSignatureResponse verifyCMSSignatureResponse = SPSSFactory.getInstance().
+ createVerifyCMSSignatureResponse(responseElements);
+ response.add(new ASiCVerificationResult(signedFiles, verifyCMSSignatureResponse));
+ continue;
+ } else {
+ response.add(new ASiCVerificationResult(signedFiles, verifyResponse));
+ }
+ }
+ }
+ } catch (IOException ex) {
+ throw new MOASystemException("asic.0003", null, ex);
+ }
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/ExtendedXAdESVerifier.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/ExtendedXAdESVerifier.java
new file mode 100644
index 0000000..58f0185
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/ExtendedXAdESVerifier.java
@@ -0,0 +1,184 @@
+package at.gv.egiz.asic.impl.verifier;
+
+import at.gv.egiz.asic.ReferenceType;
+import at.gv.egiz.asic.SignatureType;
+import at.gv.egiz.asic.XAdESSignaturesType;
+import at.gv.egiz.asic.api.ASiC;
+import at.gv.egiz.asic.api.ASiCEntry;
+import at.gv.egiz.asic.api.ASiCFormat;
+import at.gv.egiz.asic.api.ASiCVerificationResult;
+import at.gv.egovernment.moa.spss.MOAException;
+import at.gv.egovernment.moa.spss.MOARuntimeException;
+import at.gv.egovernment.moa.spss.MOASystemException;
+import at.gv.egovernment.moa.spss.api.SPSSFactory;
+import at.gv.egovernment.moa.spss.api.common.Content;
+import at.gv.egovernment.moa.spss.api.common.XMLDataObjectAssociation;
+import at.gv.egovernment.moa.spss.api.impl.SPSSFactoryImpl;
+import at.gv.egovernment.moa.spss.api.xmlverify.SupplementProfile;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifySignatureInfo;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifySignatureLocation;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest;
+import at.gv.egovernment.moa.spss.server.invoke.XMLSignatureVerificationInvoker;
+import at.gv.egovernment.moaspss.util.URLEncoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.*;
+import org.xml.sax.SAXException;
+
+import javax.xml.bind.*;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.*;
+import java.util.*;
+
+/**
+ * Created by Andreas Fitzek on 6/17/16.
+ */
+public class ExtendedXAdESVerifier extends XAdESVerifier {
+
+ private static final Logger logger = LoggerFactory.getLogger(ExtendedXAdESVerifier.class);
+
+ private void resetStream(InputStream is) {
+ try {
+ is.reset();
+ } catch (IOException e) {
+ throw new MOARuntimeException("Failed to reset inputStream", null, e);
+ }
+ }
+
+ @Override
+ public void verify(ASiC asic, String trustProfileID, Date date, List<ASiCVerificationResult> response) throws MOAException {
+ try {
+ Iterator<ASiCEntry> xadesSignatureIterator = asic.getSignaturesEntries().iterator();
+
+ while (xadesSignatureIterator.hasNext()) {
+ ASiCEntry xadesSignature = xadesSignatureIterator.next();
+
+ List<SignatureType> xmlSignatures = null;
+ //int signatureSize = 0;
+
+
+ // TODO: support not only XAdESSignaturesType object 4.4.3.2
+// XAdESSignaturesType xAdESSignaturesType = JAXB.unmarshal(xadesSignature.getContents(), XAdESSignaturesType.class);
+ // signatureSize = xAdESSignaturesType.getSignature().size();
+
+ // this.resetStream(xadesSignature.getContents());
+ DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+ dbFactory.setNamespaceAware(true);
+ //dbFactory.setValidating(true);
+ DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
+ Document doc = dBuilder.parse(xadesSignature.getContents());
+
+ this.resetStream(xadesSignature.getContents());
+
+ org.w3c.dom.Element rootElement = doc.getDocumentElement();
+
+ if ("http://www.w3.org/2000/09/xmldsig#".equals(rootElement.getNamespaceURI()) &&
+ "Signature".equals(rootElement.getTagName())) {
+ JAXBContext jc = JAXBContext.newInstance("at.gv.egiz.asic");
+ JAXBElement<SignatureType> xmlSignatureJaxb = jc.createUnmarshaller().unmarshal(rootElement, SignatureType.class);
+ SignatureType xmlSignature = xmlSignatureJaxb.getValue();
+ xmlSignatures = new ArrayList<SignatureType>();
+ xmlSignatures.add(xmlSignature);
+ } else if ("http://uri.etsi.org/02918/v1.2.1#".equals(rootElement.getNamespaceURI()) &&
+ "XAdESSignatures".equals(rootElement.getLocalName())) {
+ XAdESSignaturesType xAdESSignaturesType = JAXB.unmarshal(xadesSignature.getContents(), XAdESSignaturesType.class);
+ xmlSignatures = xAdESSignaturesType.getSignature();
+ } else {
+ NodeList childrenNodes = rootElement.getChildNodes();
+ for(int i = 0; i < childrenNodes.getLength(); i++) {
+ Node node = childrenNodes.item(i);
+ JAXBContext jc = JAXBContext.newInstance("at.gv.egiz.asic");
+ xmlSignatures = new ArrayList<SignatureType>();
+ if ("http://www.w3.org/2000/09/xmldsig#".equals(node.getNamespaceURI()) &&
+ "Signature".equals(rootElement.getTagName())) {
+ JAXBElement<SignatureType> xmlSignatureJaxb = jc.createUnmarshaller().unmarshal(rootElement, SignatureType.class);
+ SignatureType xmlSignature = xmlSignatureJaxb.getValue();
+ xmlSignatures.add(xmlSignature);
+ }
+ }
+ }
+
+
+ this.resetStream(xadesSignature.getContents());
+
+ Map namespaces = new HashMap();
+
+ //namespaces.put("asic", "http://uri.etsi.org/02918/v1.2.1#");
+ namespaces.put("ds", "http://www.w3.org/2000/09/xmldsig#");
+
+ for (int i = 0; i < xmlSignatures.size(); i++) {
+ //NodeList nodes = (NodeList) result;
+
+ //for(int i = 0; i < nodes.getLength(); i++) {
+ //Node node = nodes.item(i);
+ //JAXBContext jc = JAXBContext.newInstance( "at.gv.egiz.asic" );
+ //JAXBElement<SignatureType> xmlSignatureJaxb = jc.createUnmarshaller().unmarshal(node, SignatureType.class);
+ //SignatureType xmlSignature = xmlSignatureJaxb.getValue();
+ List<String> signedFiles = new ArrayList<String>();
+
+ //Iterator<ReferenceType> it = xmlSignature.getSignedInfo().getReference().iterator();
+ Iterator<ReferenceType> it = xmlSignatures.get(i).getSignedInfo().getReference().iterator();
+ while (it.hasNext()) {
+ ReferenceType refType = it.next();
+ if (!refType.getURI().startsWith("#")) {
+ signedFiles.add(refType.getURI());
+ }
+ }
+
+ Iterator<ASiCEntry> dataEntryIterator = asic.getDataEntries().iterator();
+
+ Content content = SPSSFactory.getInstance().createContent(xadesSignature.getContents(), null);
+
+ List supplementsList = new ArrayList();
+ while (dataEntryIterator.hasNext()) {
+ ASiCEntry dataEntry = dataEntryIterator.next();
+ dataEntry.getContents().reset();
+ String entryName = URLEncoder.encode(dataEntry.getEntryName(), "UTF-8")
+ .replaceAll("\\+", "%20")
+ .replaceAll("\\%21", "!")
+ .replaceAll("\\%2F", "/")
+ //.replaceAll("\\%27", "'")
+ //.replaceAll("\\%28", "(")
+ //.replaceAll("\\%29", ")")
+ .replaceAll("\\%7E", "~");
+ logger.info("Adding Entry : {}", entryName);
+ Content dataContent = SPSSFactory.getInstance().createContent(dataEntry.getContents(), entryName);
+ XMLDataObjectAssociation association = SPSSFactoryImpl.getInstance().createXMLDataObjectAssociation(null, dataContent);
+ SupplementProfile profile = SPSSFactoryImpl.getInstance().createSupplementProfile(association);
+ supplementsList.add(profile);
+ }
+ String location = "(//ds:Signature)[" + (i + 1) + "]";
+
+ VerifySignatureLocation verifySignatureLocation = SPSSFactory.getInstance().createVerifySignatureLocation(
+ location, namespaces);
+
+ VerifySignatureInfo verifySignatureInfo = SPSSFactory.getInstance().createVerifySignatureInfo(content, verifySignatureLocation);
+
+ VerifyXMLSignatureRequest verifyXMLSignatureRequest = SPSSFactory.getInstance().createVerifyXMLSignatureRequest(
+ date, verifySignatureInfo, supplementsList, null, false, trustProfileID, true);
+
+ response.add(new ASiCVerificationResult(signedFiles,
+ XMLSignatureVerificationInvoker.getInstance().verifyXMLSignature(verifyXMLSignatureRequest)));
+ }
+ }
+ } catch( UnsupportedEncodingException e) {
+ logger.error("UTF8 encoding not supported by system. MOA will not work on this system!", e);
+ throw new MOARuntimeException("asic.0003", null, e);
+ } catch (IOException ex) {
+ throw new MOASystemException("asic.0003", null, ex);
+ } catch (ParserConfigurationException e) {
+ throw new MOASystemException("asic.0003", null, e);
+ } catch (SAXException e) {
+ throw new MOASystemException("asic.0003", null, e);
+ } catch (JAXBException e) {
+ throw new MOASystemException("asic.0003", null, e);
+ }
+ }
+
+ @Override
+ public boolean handles(ASiC asic) {
+ return super.handles(asic) && ASiCFormat.ASiCE.equals(asic.getFormat());
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/SimpleCAdESVerifier.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/SimpleCAdESVerifier.java
new file mode 100644
index 0000000..b86e290
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/SimpleCAdESVerifier.java
@@ -0,0 +1,45 @@
+package at.gv.egiz.asic.impl.verifier;
+
+import at.gv.egiz.asic.api.ASiC;
+import at.gv.egiz.asic.api.ASiCEntry;
+import at.gv.egiz.asic.api.ASiCFormat;
+import at.gv.egiz.asic.api.ASiCVerificationResult;
+import at.gv.egovernment.moa.spss.MOAException;
+import at.gv.egovernment.moa.spss.api.SPSSFactory;
+import at.gv.egovernment.moa.spss.api.cmsverify.CMSContent;
+import at.gv.egovernment.moa.spss.api.cmsverify.CMSDataObject;
+import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureRequest;
+import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponse;
+import at.gv.egovernment.moa.spss.server.invoke.CMSSignatureVerificationInvoker;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Created by Andreas Fitzek on 6/17/16.
+ */
+public class SimpleCAdESVerifier extends CAdESVerifier {
+ @Override
+ public boolean handles(ASiC asic) {
+ return super.handles(asic) && ASiCFormat.ASiCS.equals(asic.getFormat());
+ }
+
+ @Override
+ public void verify(ASiC asic, String trustProfileID, Date date, List<ASiCVerificationResult> response) throws MOAException {
+ ASiCEntry cadesSignature = asic.getSignaturesEntries().get(0);
+
+ ASiCEntry dataEntry = asic.getDataEntries().get(0);
+
+ List<String> signedFiles = new ArrayList<String>();
+ signedFiles.add(dataEntry.getEntryName());
+
+ VerifyCMSSignatureResponse verifyResponse =
+ this.runCMSVerification(dataEntry.getContents(), cadesSignature.getContents(), trustProfileID, date);
+
+ response.add(new ASiCVerificationResult(signedFiles,
+ verifyResponse));
+ }
+
+
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/SimpleXAdESVerifier.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/SimpleXAdESVerifier.java
new file mode 100644
index 0000000..a71462c
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/SimpleXAdESVerifier.java
@@ -0,0 +1,128 @@
+package at.gv.egiz.asic.impl.verifier;
+
+import at.gv.egiz.asic.ReferenceType;
+import at.gv.egiz.asic.XAdESSignaturesType;
+import at.gv.egiz.asic.api.ASiC;
+import at.gv.egiz.asic.api.ASiCEntry;
+import at.gv.egiz.asic.api.ASiCFormat;
+import at.gv.egiz.asic.api.ASiCVerificationResult;
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.MOAException;
+import at.gv.egovernment.moa.spss.MOARuntimeException;
+import at.gv.egovernment.moa.spss.api.SPSSFactory;
+import at.gv.egovernment.moa.spss.api.common.Content;
+import at.gv.egovernment.moa.spss.api.common.XMLDataObjectAssociation;
+import at.gv.egovernment.moa.spss.api.impl.SPSSFactoryImpl;
+import at.gv.egovernment.moa.spss.api.xmlverify.SupplementProfile;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifySignatureInfo;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifySignatureLocation;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest;
+import at.gv.egovernment.moa.spss.server.invoke.XMLSignatureVerificationInvoker;
+import at.gv.egovernment.moaspss.util.URLEncoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.xml.bind.JAXB;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.*;
+
+/**
+ * Created by Andreas Fitzek on 6/17/16.
+ */
+public class SimpleXAdESVerifier extends XAdESVerifier {
+
+ private static final Logger logger = LoggerFactory.getLogger(SimpleXAdESVerifier.class);
+
+
+ @Override
+ public void verify(ASiC asic, String trustProfileID, Date date, List<ASiCVerificationResult> response) throws MOAException {
+ // XAdES
+ try {
+ ASiCEntry xadesSignature = asic.getSignaturesEntries().get(0);
+
+ XAdESSignaturesType xAdESSignaturesType = null;
+ try {
+ xAdESSignaturesType = JAXB.unmarshal(xadesSignature.getContents(), XAdESSignaturesType.class);
+ } catch (Throwable ex) {
+ logger.warn("Failed to process xml signature: ex");
+ throw new MOAApplicationException("asic.0003", null, ex);
+ }
+
+ if (xAdESSignaturesType == null) {
+ throw new MOAApplicationException("asic.0003", null);
+ }
+
+ int signatureSize = xAdESSignaturesType.getSignature().size();
+
+ try {
+ xadesSignature.getContents().reset();
+ } catch (IOException e) {
+ throw new MOARuntimeException("asic.0003", null, e);
+ }
+ Map namespaces = new HashMap();
+
+ namespaces.put("asic", "http://uri.etsi.org/02918/v1.2.1#");
+ namespaces.put("ds", "http://www.w3.org/2000/09/xmldsig#");
+
+ for (int i = 0; i < signatureSize; i++) {
+
+ List<String> signedFiles = new ArrayList<String>();
+
+ Iterator<ReferenceType> it = xAdESSignaturesType.getSignature().get(i).getSignedInfo().getReference().iterator();
+ while (it.hasNext()) {
+ ReferenceType refType = it.next();
+ if (!refType.getURI().startsWith("#")) {
+ signedFiles.add(refType.getURI());
+ }
+ }
+
+ boolean addAll = signedFiles.isEmpty() && asic.getDataEntries().size() == 1;
+
+ Iterator<ASiCEntry> dataEntryIterator = asic.getDataEntries().iterator();
+
+ Content content = SPSSFactory.getInstance().createContent(xadesSignature.getContents(), null);
+ List supplementsList = new ArrayList();
+ while (dataEntryIterator.hasNext()) {
+ ASiCEntry dataEntry = dataEntryIterator.next();
+ String uriName = URLEncoder.encode(dataEntry.getEntryName(), "UTF-8")
+ .replaceAll("\\+", "%20")
+ .replaceAll("\\%21", "!")
+ .replaceAll("\\%27", "'")
+ //.replaceAll("\\%28", "(")
+ //.replaceAll("\\%29", ")")
+ .replaceAll("\\%7E", "~");
+
+ Content dataContent = SPSSFactory.getInstance().createContent(dataEntry.getContents(), uriName);
+ XMLDataObjectAssociation association = SPSSFactoryImpl.getInstance().createXMLDataObjectAssociation(null, dataContent);
+ SupplementProfile profile = SPSSFactoryImpl.getInstance().createSupplementProfile(association);
+ supplementsList.add(profile);
+
+ if (addAll) {
+ signedFiles.add(dataEntry.getEntryName());
+ }
+ }
+ String location = "(//ds:Signature)[" + (i + 1) + "]";
+
+ VerifySignatureLocation verifySignatureLocation = SPSSFactory.getInstance().createVerifySignatureLocation(
+ location, namespaces);
+
+ VerifySignatureInfo verifySignatureInfo = SPSSFactory.getInstance().createVerifySignatureInfo(content, verifySignatureLocation);
+
+ VerifyXMLSignatureRequest verifyXMLSignatureRequest = SPSSFactory.getInstance().createVerifyXMLSignatureRequest(
+ date, verifySignatureInfo, supplementsList, null, false, trustProfileID, true);
+
+ response.add(new ASiCVerificationResult(signedFiles,
+ XMLSignatureVerificationInvoker.getInstance().verifyXMLSignature(verifyXMLSignatureRequest)));
+ }
+ } catch(UnsupportedEncodingException e) {
+ logger.error("UTF8 encoding not supported by system. MOA will not work on this system!", e);
+ throw new MOARuntimeException("asic.0003", null, e);
+ }
+ }
+
+ @Override
+ public boolean handles(ASiC asic) {
+ return super.handles(asic) && ASiCFormat.ASiCS.equals(asic.getFormat());
+ }
+} \ No newline at end of file
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/XAdESVerifier.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/XAdESVerifier.java
new file mode 100644
index 0000000..904ad4e
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier/XAdESVerifier.java
@@ -0,0 +1,54 @@
+package at.gv.egiz.asic.impl.verifier;
+
+import at.gv.egiz.asic.api.ASiC;
+import at.gv.egiz.asic.api.ASiCEntry;
+import at.gv.egiz.asic.api.ASiCVerificationResult;
+import at.gv.egovernment.moa.spss.MOAException;
+import at.gv.egovernment.moa.spss.api.SPSSFactory;
+import at.gv.egovernment.moa.spss.api.cmsverify.CMSContent;
+import at.gv.egovernment.moa.spss.api.cmsverify.CMSDataObject;
+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.common.Content;
+import at.gv.egovernment.moa.spss.api.common.XMLDataObjectAssociation;
+import at.gv.egovernment.moa.spss.api.impl.SPSSFactoryImpl;
+import at.gv.egovernment.moa.spss.api.xmlverify.*;
+import at.gv.egovernment.moa.spss.server.invoke.CMSSignatureVerificationInvoker;
+import at.gv.egovernment.moa.spss.server.invoke.XMLSignatureVerificationInvoker;
+
+import java.io.InputStream;
+import java.util.*;
+
+/**
+ * Created by Andreas Fitzek on 6/17/16.
+ */
+public abstract class XAdESVerifier extends BaseVerifier {
+ @Override
+ public boolean handles(ASiC asic) {
+ return asic.isXAdES();
+ }
+
+ protected VerifyXMLSignatureResponse runXMLVerification(InputStream signedData, InputStream xmlSignature,
+ String trustProfileID, Date date, List supplementsList,
+ String location, Map namespaces) throws MOAException {
+
+ if(namespaces == null) {
+ namespaces = new HashMap();
+
+ namespaces.put("asic", "http://uri.etsi.org/02918/v1.2.1#");
+ namespaces.put("ds", "http://www.w3.org/2000/09/xmldsig#");
+ }
+
+ Content content = SPSSFactory.getInstance().createContent(xmlSignature, null);
+
+ VerifySignatureLocation verifySignatureLocation = SPSSFactory.getInstance().createVerifySignatureLocation(
+ location, namespaces);
+
+ VerifySignatureInfo verifySignatureInfo = SPSSFactory.getInstance().createVerifySignatureInfo(content, verifySignatureLocation);
+
+ VerifyXMLSignatureRequest verifyXMLSignatureRequest = SPSSFactory.getInstance().createVerifyXMLSignatureRequest(
+ date, verifySignatureInfo, supplementsList, null, false, trustProfileID, true);
+
+ return XMLSignatureVerificationInvoker.getInstance().verifyXMLSignature(verifyXMLSignatureRequest);
+ }
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/xmlbind/VerifyASICSignatureRequestParser.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/xmlbind/VerifyASICSignatureRequestParser.java
new file mode 100644
index 0000000..c06e30e
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/xmlbind/VerifyASICSignatureRequestParser.java
@@ -0,0 +1,112 @@
+/*
+ * 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.egiz.asic.xmlbind;
+
+import at.gv.egiz.asic.api.ASiCFormat;
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.api.SPSSFactory;
+import at.gv.egovernment.moa.spss.api.cmsverify.CMSContent;
+import at.gv.egovernment.moa.spss.api.cmsverify.CMSDataObject;
+import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureRequest;
+import at.gv.egovernment.moa.spss.api.common.MetaInfo;
+import at.gv.egovernment.moa.spss.api.xmlbind.RequestParserUtils;
+import at.gv.egovernment.moaspss.util.*;
+import org.w3c.dom.Element;
+
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.StringTokenizer;
+
+/**
+ * A parser to parse <code>VerifyCMSSignatureRequest</code> DOM trees into
+ * <code>VerifyCMSSignatureRequest</code> API objects.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class VerifyASICSignatureRequestParser {
+
+ //
+ // XPath expressions for selecting parts of the DOM message
+ //
+ private static final String MOA = Constants.MOA_PREFIX + ":";
+ private static final String DATE_TIME_XPATH = MOA + "DateTime";
+ private static final String EXTENDED_VALIDATION_XPATH = MOA + "ExtendedValidation";
+ private static final String ASIC_SIGNATURE_XPATH = MOA + "ASICSignature";
+ private static final String ASIC_EXTENSION_XPATH = MOA + "ASICExtension";
+ private static final String TRUST_PROFILE_ID_XPATH = MOA + "TrustProfileID";
+
+
+ /** The <code>SPSSFactory</code> for creating new API objects. */
+ private SPSSFactory factory = SPSSFactory.getInstance();
+
+ /**
+ * Parse a <code>VerifyCMSSignatureRequest</code> DOM element, as defined
+ * by the MOA schema.
+ *
+ * @param requestElem The <code>VerifyCMSSignatureRequest</code> to parse. The
+ * request must have been successfully parsed against the schema for this
+ * method to succeed.
+ * @return A <code>VerifyCMSSignatureRequest</code> API objects containing
+ * the data from the DOM element.
+ * @throws MOAApplicationException An error occurred parsing the request.
+ */
+ public VerifyASiCRequest parseASIC(Element requestElem)
+ throws MOAApplicationException {
+ Date dateTime =
+ RequestParserUtils.parseDateTime(requestElem, DATE_TIME_XPATH);
+
+ boolean extendedValidation =
+ RequestParserUtils.parseExtendedValidation(requestElem, EXTENDED_VALIDATION_XPATH, false);
+
+ String asicSignatureStr =
+ XPathUtils.getElementValue(requestElem, ASIC_SIGNATURE_XPATH, "");
+
+ String asicExtensionStr =
+ XPathUtils.getElementValue(requestElem, ASIC_EXTENSION_XPATH, "");
+
+ String trustProfileID =
+ XPathUtils.getElementValue(requestElem, TRUST_PROFILE_ID_XPATH, null);
+ //Logger.info("CMSSignature: " + cmsSignatureStr);
+ InputStream asicSignature =
+ Base64Utils.decodeToStream(asicSignatureStr, true);
+
+ ASiCFormat format = null;
+
+ if("asics".equalsIgnoreCase(asicExtensionStr) || "scs".equalsIgnoreCase(asicExtensionStr)
+ || "application/vnd.etsi.asic-s+zip".equalsIgnoreCase(asicExtensionStr)) {
+ format = ASiCFormat.ASiCS;
+ } else if("asice".equalsIgnoreCase(asicExtensionStr) || "sce".equalsIgnoreCase(asicExtensionStr)
+ || "application/vnd.etsi.asic-e+zip".equalsIgnoreCase(asicExtensionStr)) {
+ format = ASiCFormat.ASiCE;
+ }
+
+ return new VerifyASiCRequest(format, dateTime, asicSignature, trustProfileID, extendedValidation);
+ }
+
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/xmlbind/VerifyASICSignatureResponseBuilder.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/xmlbind/VerifyASICSignatureResponseBuilder.java
new file mode 100644
index 0000000..781a081
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/xmlbind/VerifyASICSignatureResponseBuilder.java
@@ -0,0 +1,177 @@
+/*
+ * 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.egiz.asic.xmlbind;
+
+import at.gv.egiz.asic.api.ASiCVerificationResult;
+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.cmsverify.VerifyCMSSignatureResponse;
+import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponseElement;
+import at.gv.egovernment.moa.spss.api.common.CheckResult;
+import at.gv.egovernment.moa.spss.api.common.SignerInfo;
+import at.gv.egovernment.moa.spss.api.xmlbind.ResponseBuilderUtils;
+import at.gv.egovernment.moa.spss.api.xmlbind.VerifyXMLSignatureResponseBuilder;
+import at.gv.egovernment.moa.spss.api.xmlverify.AdESFormResults;
+import at.gv.egovernment.moa.spss.api.xmlbind.VerifyCMSSignatureResponseBuilder;
+import at.gv.egovernment.moaspss.util.Constants;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Convert a <code>VerifyCMSSignatureResponse</code> API object into its
+ * XML representation, according to the MOA XML schema.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class VerifyASICSignatureResponseBuilder {
+ /** The XML document containing the response element. */
+ private Document responseDoc;
+ /** The response <code>VerifyCMSSignatureResponse</code> DOM element. */
+ private Element responseElem;
+
+ /**
+ * Create a new <code>VerifyCMSSignatureResponseBuilder</code>:
+ *
+ * @throws MOASystemException An error occurred setting up the resulting
+ * XML document.
+ */
+ public VerifyASICSignatureResponseBuilder() throws MOASystemException {
+ responseDoc =
+ ResponseBuilderUtils.createResponse("VerifyASICSignatureResponse");
+ responseElem = responseDoc.getDocumentElement();
+ }
+
+ /**
+ * Build a document containing a <code>VerifyCMSSignatureResponse</code>
+ * DOM element being the XML representation of the given
+ * <code>VerifyCMSSignatureResponse</code> API object.
+ *
+ * @param response The <code>VerifyCMSSignatureResponse</code> to convert
+ * to XML.
+ * @return A document containing the <code>VerifyCMSSignatureResponse</code>
+ * DOM element.
+ * @throws MOAApplicationException An error occurred building the response.
+ */
+ public Document build(List<ASiCVerificationResult> results)
+ throws MOAException {
+
+ Iterator<ASiCVerificationResult> iter = results.iterator();
+
+ while(iter.hasNext()) {
+ ASiCVerificationResult aSiCVerificationResult = iter.next();
+ addASiCResultElement(aSiCVerificationResult);
+ }
+
+ return responseDoc;
+ }
+
+ private void addASiCResultElement(ASiCVerificationResult aSiCVerificationResult)
+ throws MOAException {
+ Element asiCSignatureResultElem = responseDoc.createElementNS(Constants.MOA_NS_URI, "ASiCSignatureResult");
+
+ Iterator<String> signedFiles = aSiCVerificationResult.getSignedFiles().iterator();
+ while (signedFiles.hasNext()) {
+ String signedFile = signedFiles.next();
+ Element signedFilesElem = responseDoc.createElementNS(Constants.MOA_NS_URI, "signedFiles");
+ signedFilesElem.setTextContent(signedFile);
+ asiCSignatureResultElem.appendChild(signedFilesElem);
+ }
+
+ if(aSiCVerificationResult.getXmlResult() != null) {
+ VerifyXMLSignatureResponseBuilder verifyXMLSignatureResponseBuilder = new VerifyXMLSignatureResponseBuilder(this.responseDoc, "XMLSignatureResult");
+ asiCSignatureResultElem.appendChild(verifyXMLSignatureResponseBuilder.buildElement(aSiCVerificationResult.getXmlResult()));
+ } else if(aSiCVerificationResult.getCmsResult() != null) {
+ VerifyCMSSignatureResponseBuilder verifyCMSSignatureResponseBuilder = new VerifyCMSSignatureResponseBuilder(this.responseDoc, "CMSSignatureResult");
+ asiCSignatureResultElem.appendChild(verifyCMSSignatureResponseBuilder.buildElement(aSiCVerificationResult.getCmsResult()));
+ }
+
+ responseElem.appendChild(asiCSignatureResultElem);
+ }
+
+ /**
+ * Add an element to the response.
+ *
+ * @param responseElement The element to add to the response.
+ * @throws MOAApplicationException An error occurred adding the element.
+ */
+ private void addResponseElement(VerifyCMSSignatureResponseElement responseElement)
+ throws MOAApplicationException {
+
+ SignerInfo signerInfo = responseElement.getSignerInfo();
+ CheckResult signatureCheck = responseElement.getSignatureCheck();
+ CheckResult certCheck = responseElement.getCertificateCheck();
+
+ ResponseBuilderUtils.addSignerInfo(
+ responseDoc,
+ responseElem,
+ signerInfo.getSignerCertificate(),
+ signerInfo.isQualifiedCertificate(),
+ signerInfo.getQCSource(),
+ signerInfo.isPublicAuthority(),
+ signerInfo.getPublicAuhtorityID(),
+ signerInfo.isSSCD(),
+ signerInfo.getSSCDSource(),
+ signerInfo.getIssuerCountryCode());
+
+ ResponseBuilderUtils.addCodeInfoElement(
+ responseDoc,
+ responseElem,
+ "SignatureCheck",
+ signatureCheck.getCode(),
+ signatureCheck.getInfo());
+
+ ResponseBuilderUtils.addCodeInfoElement(
+ responseDoc,
+ responseElem,
+ "CertificateCheck",
+ certCheck.getCode(),
+ certCheck.getInfo());
+
+
+ if (responseElement.getAdESFormResults() != null) {
+
+ Iterator formIterator = responseElement.getAdESFormResults().iterator();
+
+ while (formIterator.hasNext()) {
+ AdESFormResults adESFormResult = (AdESFormResults) formIterator.next();
+ // add the CertificateCheck
+ ResponseBuilderUtils.addFormCheckElement(responseDoc, responseElem, "FormCheckResult",
+ adESFormResult.getCode().intValue(), adESFormResult.getName());
+
+ }
+ }
+
+ if(responseElement.getExtendedCertificateCheck() != null) {
+ ResponseBuilderUtils.addExtendendResult(responseDoc, responseElem, responseElement.getExtendedCertificateCheck());
+ }
+
+ }
+
+}
diff --git a/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/xmlbind/VerifyASiCRequest.java b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/xmlbind/VerifyASiCRequest.java
new file mode 100644
index 0000000..37584a6
--- /dev/null
+++ b/moaSig/moa-asic/src/main/java/at/gv/egiz/asic/xmlbind/VerifyASiCRequest.java
@@ -0,0 +1,46 @@
+package at.gv.egiz.asic.xmlbind;
+
+import at.gv.egiz.asic.api.ASiCFormat;
+
+import java.io.InputStream;
+import java.util.Date;
+
+/**
+ * Created by Andreas Fitzek on 6/16/16.
+ */
+public class VerifyASiCRequest {
+ private Date date;
+ private InputStream asicInput;
+ private String trustProfile;
+ private ASiCFormat format;
+ private boolean extendedValidation;
+
+
+ public VerifyASiCRequest(ASiCFormat format, Date date, InputStream asicInput, String trustProfile, boolean extendedValidation) {
+ this.format = format;
+ this.date = date;
+ this.asicInput = asicInput;
+ this.trustProfile = trustProfile;
+ this.extendedValidation = extendedValidation;
+ }
+
+ public Date getDate() {
+ return date;
+ }
+
+ public InputStream getAsicInput() {
+ return asicInput;
+ }
+
+ public String getTrustProfile() {
+ return trustProfile;
+ }
+
+ public ASiCFormat getFormat() {
+ return format;
+ }
+
+ public boolean isExtendedValidation() {
+ return extendedValidation;
+ }
+}
diff --git a/moaSig/moa-asic/src/main/resources/schemas/asic.xsd b/moaSig/moa-asic/src/main/resources/schemas/asic.xsd
new file mode 100644
index 0000000..d6d3534
--- /dev/null
+++ b/moaSig/moa-asic/src/main/resources/schemas/asic.xsd
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema
+ targetNamespace="http://uri.etsi.org/02918/v1.2.1#"
+ xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
+ xmlns="http://uri.etsi.org/02918/v1.2.1#"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified">
+ <xsd:import
+ namespace="http://www.w3.org/2000/09/xmldsig#"
+ schemaLocation="http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd"/>
+
+ <xsd:element name="ASiCManifest" type="ASiCManifestType">
+ <xsd:annotation>
+ <xsd:documentation>Schema for ASiCManifest – See ETSI EN 319 162</xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:complexType name="ASiCManifestType">
+ <xsd:sequence>
+ <xsd:element ref="SigReference"/>
+ <xsd:element ref="DataObjectReference" maxOccurs="unbounded"/>
+ <xsd:element name="ASiCManifestExtensions" type="ExtensionsListType" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="SigReference" type="SigReferenceType"/>
+ <xsd:complexType name="SigReferenceType">
+ <xsd:attribute name="URI" type="xsd:anyURI" use="required"/>
+ <xsd:attribute name="MimeType" type="xsd:string" use="optional"/>
+ </xsd:complexType>
+ <xsd:element name="DataObjectReference" type="DataObjectReferenceType"/>
+ <xsd:complexType name="DataObjectReferenceType">
+ <xsd:sequence>
+ <xsd:element ref="ds:DigestMethod"/>
+ <xsd:element ref="ds:DigestValue"/>
+ <xsd:element name="DataObjectReferenceExtensions" type="ExtensionsListType"
+ minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="URI" type="xsd:anyURI" use="required" />
+ <xsd:attribute name="MimeType" type="xsd:string" use="optional" />
+ <xsd:attribute name="Rootfile" type="xsd:boolean" use="optional" />
+ </xsd:complexType>
+ <xsd:complexType name="AnyType" mixed="true">
+ <xsd:sequence minOccurs="0" maxOccurs="unbounded">
+ <xsd:any processContents="lax"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:element name="Extension" type="ExtensionType"/>
+ <xsd:complexType name="ExtensionType">
+ <xsd:complexContent>
+ <xsd:extension base="AnyType">
+ <xsd:attribute name="Critical" type="xsd:boolean" use="required"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ <xsd:complexType name="ExtensionsListType">
+ <xsd:sequence>
+ <xsd:element ref="Extension" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="XAdESSignatures" type="XAdESSignaturesType">
+ <xsd:annotation>
+ <xsd:documentation>Schema for parallel detached XAdES Signatures </xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:complexType name="XAdESSignaturesType">
+ <xsd:sequence>
+ <xsd:element ref="ds:Signature" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+</xsd:schema> \ No newline at end of file