diff options
Diffstat (limited to 'moaSig/moa-asic/src/main/java/at/gv/egiz/asic/impl/verifier')
7 files changed, 683 insertions, 0 deletions
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); + } +} |