package at.gv.egovernment.moa.spss.server.webservice.binding; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.security.cert.CertificateEncodingException; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import javax.xml.bind.JAXBElement; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; import org.apache.commons.io.IOUtils; import org.w3c.dom.Element; import org.w3c.dom.Node; import at.gv.egiz.moasig.MoaTransformsType; import at.gv.egiz.moasig.PublicAuthorityType; import at.gv.egiz.moasig.QualifiedCertificate; import at.gv.egiz.moasig.SecureSignatureCreationDevice; import at.gv.egiz.moasig.TransformParameterType; import at.gv.egiz.moasig.TransformParameterType.Hash; import at.gv.egiz.moasig.VerifyXMLSignatureResponseType; import at.gv.egiz.moasig.XMLDataObjectAssociationType; import at.gv.egovernment.moa.spss.MOAApplicationException; 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.ContentBinary; import at.gv.egovernment.moa.spss.api.common.ContentXML; import at.gv.egovernment.moa.spss.api.common.InputData; import at.gv.egovernment.moa.spss.api.common.XMLDataObjectAssociation; import at.gv.egovernment.moa.spss.api.xmlverify.AdESFormResults; import at.gv.egovernment.moa.spss.api.xmlverify.ReferenceInfo; import at.gv.egovernment.moa.spss.api.xmlverify.SignatureManifestCheckParams; import at.gv.egovernment.moa.spss.api.xmlverify.SupplementProfile; import at.gv.egovernment.moa.spss.api.xmlverify.TransformParameter; 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.VerifyTransformsInfoProfile; import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest; import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse; import at.gv.egovernment.moa.spss.server.webservice.XMLVerifySignatureBinding; import at.gv.egovernment.moa.util.DOMUtils; import iaik.utils.RFC2253NameParser; import iaik.utils.RFC2253NameParserException; public class XMLVerifySignatureBindingImpl implements XMLVerifySignatureBinding { /** The SPSSFactory for creating new API objects. */ private SPSSFactory factory = SPSSFactory.getInstance(); private TransformerUtils transformerUtils = new TransformerUtils(); private TransformParser transformParser = new TransformParser(); @Override public VerifyXMLSignatureRequest buildXMLRequest( at.gv.egiz.moasig.VerifyXMLSignatureRequest verifyXMLSignatureRequest) throws MOAApplicationException { Date dateTime = null; if (verifyXMLSignatureRequest.getDateTime() != null) { dateTime = verifyXMLSignatureRequest.getDateTime().toGregorianCalendar().getTime(); } boolean returnHashInputData = false; returnHashInputData = (verifyXMLSignatureRequest.getReturnHashInputData() != null); String trustProfileID = verifyXMLSignatureRequest.getTrustProfileID(); VerifySignatureInfo verifySignatureInfo = parseVerifySignatureInfo( verifyXMLSignatureRequest.getVerifySignatureInfo()); List supplementProfiles = parseSupplementProfiles(verifyXMLSignatureRequest); SignatureManifestCheckParams signatureManifestCheckParams = this .parseSignatureManifestCheckParams(verifyXMLSignatureRequest.getSignatureManifestCheckParams()); return factory.createVerifyXMLSignatureRequest(dateTime, verifySignatureInfo, supplementProfiles, signatureManifestCheckParams, returnHashInputData, trustProfileID); } @Override public VerifyXMLSignatureResponseType buildXMLResponse(VerifyXMLSignatureResponse response) throws MOAApplicationException { VerifyXMLSignatureResponseType verifyXMLSignatureResponseType = new VerifyXMLSignatureResponseType(); verifyXMLSignatureResponseType.setSignerInfo(this.transformerUtils.buildSignerInfo(response.getSignerInfo())); if (response.getHashInputDatas() != null && !response.getHashInputDatas().isEmpty()) { for (Iterator iter = response.getHashInputDatas().iterator(); iter.hasNext();) { InputData inputData = (InputData) iter.next(); verifyXMLSignatureResponseType.getHashInputData().add(buildInputData(inputData)); } } if (response.getReferenceInputDatas() != null && !response.getReferenceInputDatas().isEmpty()) { for (Iterator iter = response.getReferenceInputDatas().iterator(); iter.hasNext();) { InputData inputData = (InputData) iter.next(); verifyXMLSignatureResponseType.getReferenceInputData().add(buildInputData(inputData)); } } // add the SignatureCheck verifyXMLSignatureResponseType.setSignatureCheck(buildReferencesCheckResult(response.getSignatureCheck())); // add the SignatureManifestCheck if (response.getSignatureManifestCheck() != null) { verifyXMLSignatureResponseType.setSignatureManifestCheck(buildReferencesCheckResult(response.getSignatureManifestCheck())); } // add the XMLDsigManifestChecks if(response.getXMLDsigManifestChecks() != null) { List xmlDsigManifestChecks = response.getXMLDsigManifestChecks(); Iterator iter = xmlDsigManifestChecks.iterator(); while(iter.hasNext()) { Object xmlDsigManifestCheck = iter.next(); verifyXMLSignatureResponseType.getXMLDSIGManifestCheck().add( buildManifestCheckResult((at.gv.egovernment.moa.spss.api.xmlverify.ManifestRefsCheckResult) xmlDsigManifestCheck)); } } // add the CertificateCheck verifyXMLSignatureResponseType.setCertificateCheck(this.transformerUtils.buildCheckResult(response.getCertificateCheck())); if(response.getAdESFormResults() != null) { Iterator formIterator = response.getAdESFormResults().iterator(); while(formIterator.hasNext()) { AdESFormResults adESFormResult = (AdESFormResults)formIterator.next(); verifyXMLSignatureResponseType.getFormCheckResult().add( buildFormResult(adESFormResult)); } } return verifyXMLSignatureResponseType; } private at.gv.egiz.moasig.InputDataType buildInputData(InputData inputData) throws MOAApplicationException { at.gv.egiz.moasig.InputDataType inputDataType = new at.gv.egiz.moasig.InputDataType(); inputDataType.setPartOf(inputData.getPartOf()); if(inputData.getReferringReferenceNumber() != InputData.REFERER_NONE_) { inputDataType.setReferringSigReference(BigInteger.valueOf(inputData.getReferringReferenceNumber())); } switch(inputData.getContentType()) { case Content.XML_CONTENT: ContentXML contentXml = (ContentXML) inputData; ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { iaik.xml.crypto.utils.DOMUtils.serialize(DOMUtils.nodeList2DocumentFragment( contentXml.getXMLContent()).getOwnerDocument(), baos); inputDataType.setBase64Content(baos.toByteArray()); } catch (TransformerException e) { throw new MOAApplicationException("2200", null, e); } catch (ParserConfigurationException e) { throw new MOAApplicationException("2200", null, e); } break; case Content.BINARY_CONTENT: ContentBinary contentBinary = (ContentBinary) inputData; try { inputDataType.setBase64Content(IOUtils.toByteArray(contentBinary.getBinaryContent())); } catch (IOException e) { throw new MOAApplicationException("2200", null, e); } break; } return inputDataType; } private at.gv.egiz.moasig.FormResultType buildFormResult(AdESFormResults adESFormResults) { at.gv.egiz.moasig.FormResultType formResult = new at.gv.egiz.moasig.FormResultType(); formResult.setCode(BigInteger.valueOf(adESFormResults.getCode())); formResult.setName(adESFormResults.getName()); return formResult; } private at.gv.egiz.moasig.ManifestRefsCheckResultType buildManifestCheckResult( at.gv.egovernment.moa.spss.api.xmlverify.ManifestRefsCheckResult referencesCheckResult) { at.gv.egiz.moasig.ManifestRefsCheckResultType referencesCheckResultType = new at.gv.egiz.moasig.ManifestRefsCheckResultType(); if (referencesCheckResult.getInfo() != null) { at.gv.egiz.moasig.ObjectFactory of = new at.gv.egiz.moasig.ObjectFactory(); at.gv.egiz.moasig.AnyChildrenType anyInfos = new at.gv.egiz.moasig.AnyChildrenType(); if (referencesCheckResult.getInfo().getFailedReferences() != null) { for (int idx = 0; idx < referencesCheckResult.getInfo().getFailedReferences().length; idx++) { anyInfos.getContent().add(of.createFailedReference( BigInteger.valueOf(referencesCheckResult.getInfo().getFailedReferences()[idx]))); } } if (referencesCheckResult.getInfo().getAnyOtherInfo() != null) { for (int idx = 0; idx < referencesCheckResult.getInfo().getAnyOtherInfo().getLength(); idx++) { Node node = referencesCheckResult.getInfo().getAnyOtherInfo().item(idx); if (node instanceof Element) { anyInfos.getContent().add((Element) node); } } } anyInfos.getContent().add(of.createReferringSigReference( BigInteger.valueOf(referencesCheckResult.getInfo().getReferringSignatureReference()))); referencesCheckResultType.setInfo(anyInfos); } referencesCheckResultType.setCode(BigInteger.valueOf(referencesCheckResult.getCode())); return referencesCheckResultType; } private at.gv.egiz.moasig.ReferencesCheckResultType buildReferencesCheckResult( at.gv.egovernment.moa.spss.api.xmlverify.ReferencesCheckResult referencesCheckResult) { at.gv.egiz.moasig.ReferencesCheckResultType referencesCheckResultType = new at.gv.egiz.moasig.ReferencesCheckResultType(); if (referencesCheckResult.getInfo() != null) { at.gv.egiz.moasig.ObjectFactory of = new at.gv.egiz.moasig.ObjectFactory(); at.gv.egiz.moasig.AnyChildrenType anyInfos = new at.gv.egiz.moasig.AnyChildrenType(); if (referencesCheckResult.getInfo().getFailedReferences() != null) { for (int idx = 0; idx < referencesCheckResult.getInfo().getFailedReferences().length; idx++) { anyInfos.getContent().add(of.createFailedReference( BigInteger.valueOf(referencesCheckResult.getInfo().getFailedReferences()[idx]))); } } if (referencesCheckResult.getInfo().getAnyOtherInfo() != null) { for (int idx = 0; idx < referencesCheckResult.getInfo().getAnyOtherInfo().getLength(); idx++) { Node node = referencesCheckResult.getInfo().getAnyOtherInfo().item(idx); if (node instanceof Element) { anyInfos.getContent().add((Element) node); } } } referencesCheckResultType.setInfo(anyInfos); } referencesCheckResultType.setCode(BigInteger.valueOf(referencesCheckResult.getCode())); return referencesCheckResultType; } /** * Parse the VerifySignatureInfo DOM element contained in the * VerifyXMLSignatureRequest DOM element. * * @param requestElem * The VerifyXMLSignatureRequest DOM element * containing the VerifySignatureInfo DOM element. * @return The VerifySignatureInfo API object containing the * data from the DOM element. * @throws MOAApplicationException */ private VerifySignatureInfo parseVerifySignatureInfo( at.gv.egiz.moasig.VerifyXMLSignatureRequestType.VerifySignatureInfo verifySignatureInfo) throws MOAApplicationException { Content verifySignatureEnvironment = transformerUtils .buildContent(verifySignatureInfo.getVerifySignatureEnvironment()); String xPathExpression = verifySignatureInfo.getVerifySignatureLocation(); VerifySignatureLocation verifySignatureLocation = factory.createVerifySignatureLocation(xPathExpression, new HashMap()); return factory.createVerifySignatureInfo(verifySignatureEnvironment, verifySignatureLocation); } /** * Parse the supplement profiles contained in the given * VerifyXMLSignatureRequest DOM element. * * @param requestElem * The VerifyXMLSignatureRequest DOM element. * @return A List of SupplementProfile API objects * containing the data from the SupplementProfile DOM * elements. * @throws MOAApplicationException */ private List parseSupplementProfiles(at.gv.egiz.moasig.VerifyXMLSignatureRequest verifyXMLSignatureRequest) throws MOAApplicationException { List supplementProfiles = new ArrayList(); List supplementElements = verifyXMLSignatureRequest.getSupplementProfileOrSupplementProfileID(); if (supplementElements != null) { Iterator supplementElementsIterator = supplementElements.iterator(); while (supplementElementsIterator.hasNext()) { Object object = supplementElementsIterator.next(); SupplementProfile profile; if (object instanceof XMLDataObjectAssociationType) { XMLDataObjectAssociationType xmlDataObjectAssociationType = (XMLDataObjectAssociationType) object; profile = parseSupplementProfile(xmlDataObjectAssociationType); } else if (object instanceof String) { String profileID = (String) object; profile = factory.createSupplementProfile(profileID); } else { throw new MOAApplicationException( "Invalid object in moa:SupplementProfile | moa:SupplementProfileID", null); } supplementProfiles.add(profile); } } return supplementProfiles; } public SupplementProfile parseSupplementProfile(XMLDataObjectAssociationType xmlDataObjectAssociationType) throws MOAApplicationException { XMLDataObjectAssociation supplementProfile = this.transformerUtils .parseXMLDataObjectAssociation(xmlDataObjectAssociationType); return factory.createSupplementProfile(supplementProfile); } /** * Parse the SignatureManifestCheckParams DOM element contained * in the given VerifyXMLSignatureRequest DOM element. * * @param requestElem * The VerifyXMLSignatureRequest DOM element. * @return The SignatureManifestCheckParams API object * containing the data from the * SignatureManifestCheckParams DOM element. * @throws MOAApplicationException * An error occurred parsing the * SignatureManifestCheckParams DOM element. */ private SignatureManifestCheckParams parseSignatureManifestCheckParams( at.gv.egiz.moasig.VerifyXMLSignatureRequestType.SignatureManifestCheckParams signatureManifestCheckParams) throws MOAApplicationException { if (signatureManifestCheckParams == null) { return null; } boolean returnReferencInputData = signatureManifestCheckParams.isReturnReferenceInputData(); List referenceInfos = signatureManifestCheckParams .getReferenceInfo(); List referenceInfosBuild = parseReferenceInfos(referenceInfos); return factory.createSignatureManifestCheckParams(referenceInfosBuild, returnReferencInputData); } /** * Parse the ReferenceInfo DOM elements contained in a * SignatureManifestCheckParams DOM element. * * @param paramsElem * The SignatureManifestCheckParams DOM element * containing the ReferenceInfo DOM elements. * @return A List of RefernceInfo API objects * containing the data from the ReferenceInfo DOM * elements. * @throws MOAApplicationException * An error occurred parsing the ReferenceInfo DOM * elements. */ private List parseReferenceInfos(List referenceInfosWeb) throws MOAApplicationException { List referenceInfos = new ArrayList(); if (referenceInfosWeb != null) { Iterator referenceInfosIterator = referenceInfosWeb.iterator(); while (referenceInfosIterator.hasNext()) { at.gv.egiz.moasig.VerifyTransformsDataType verifyTransformsDataType = referenceInfosIterator.next(); ReferenceInfo referenceInfo = parseReferenceInfo(verifyTransformsDataType); referenceInfos.add(referenceInfo); } } return referenceInfos; } /** * Parse a ReferenceInfo DOM element. * * @param refInfoElem * The ReferenceInfo DOM element to parse. * @return The ReferenceInfo API object containing the data * from the given ReferenceInfo DOM element. * @throws MOAApplicationException * An error occurred parsing the ReferenceInfo DOM * element. */ private ReferenceInfo parseReferenceInfo(at.gv.egiz.moasig.VerifyTransformsDataType verifyTransformsDataType) throws MOAApplicationException { List profiles = parseVerifyTransformsInfoProfiles(verifyTransformsDataType); return factory.createReferenceInfo(profiles); } /** * Parse the VerifyTransformsInfoProfile DOM elements contained * in a ReferenceInfo DOM element. * * @param refInfoElem * ReferenceInfo DOM element containing the * VerifyTransformsInfoProfile DOM elements. * @return A List of VerifyTransformsInfoProfile * API objects containing the profile data. * @throws MOAApplicationException * An error occurred building the * VerifyTransformsInfoProfiles. */ private List parseVerifyTransformsInfoProfiles(at.gv.egiz.moasig.VerifyTransformsDataType verifyTransformsDataType) throws MOAApplicationException { List profiles = new ArrayList(); List transformsList = verifyTransformsDataType .getVerifyTransformsInfoProfileOrVerifyTransformsInfoProfileID(); Iterator transformsListIterator = transformsList.iterator(); while (transformsListIterator.hasNext()) { Object object = transformsListIterator.next(); if (object instanceof at.gv.egiz.moasig.VerifyTransformsInfoProfile) { at.gv.egiz.moasig.VerifyTransformsInfoProfile verifyTransformsInfoProfile = (at.gv.egiz.moasig.VerifyTransformsInfoProfile) object; } else if (object instanceof String) { String profileID = (String) object; profiles.add(factory.createVerifyTransformsInfoProfile(profileID)); } else { throw new MOAApplicationException("Invalid object in VerifyTransformsData", null); } } return profiles; } /** * Parse a VerifyTransformsInfoProfile DOM element. * * @param profileElem * The VerifyTransformsInfoProfile DOM element to * parse. * @return A VerifyTransformsInfoProfile API object containing * the information from the VerifyTransformsInfoProfile * DOM element. * @throws MOAApplicationException * An error occurred parsing the * VerifyTransformsInfoProfile. */ public VerifyTransformsInfoProfile parseVerifyTransformsInfoProfile( at.gv.egiz.moasig.VerifyTransformsInfoProfile verifyTransformsInfoProfile) throws MOAApplicationException { List transforms = null; List transformParameters = new ArrayList(); List transformParams = verifyTransformsInfoProfile.getTransformParameter(); Iterator transformParamIterator = transformParams.iterator(); MoaTransformsType moaTransforms = verifyTransformsInfoProfile.getMoaTransforms(); if (moaTransforms != null) { transforms = transformParser.parseTransforms(moaTransforms); } while (transformParamIterator.hasNext()) { TransformParameterType transformParameter = transformParamIterator.next(); transformParameters.add(parseTransformParameter(transformParameter)); } return factory.createVerifyTransformsInfoProfile(transforms, transformParameters); } /** * Parse a TransformParameter DOM element. * * @param paramElem * The TransformParameter DOM element to parse. * @return The TransformParameter API object containing the * information from the TransformParameter DOM element. * @throws MOAApplicationException * An error occurred parsing the TransformParameter * DOM element. */ private TransformParameter parseTransformParameter(TransformParameterType transformParameter) throws MOAApplicationException { String uri = transformParameter.getURI(); if (transformParameter.getBase64Content() != null) { InputStream binaryContent = new ByteArrayInputStream(transformParameter.getBase64Content()); return factory.createTransformParameter(uri, binaryContent); } else if (transformParameter.getHash() != null) { Hash hash = transformParameter.getHash(); String digestMethodStr = ""; if (hash.getDigestMethod() != null) { digestMethodStr = hash.getDigestMethod().getAlgorithm(); } byte[] digestValue = hash.getDigestValue(); return factory.createTransformParameter(uri, digestMethodStr, digestValue); } else { return factory.createTransformParameter(uri); } } }