From defceef8afef538555c13d33e344a89a828a3d97 Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Fri, 20 Dec 2013 12:35:28 +0100 Subject: inital --- .../at/gv/util/client/moaspss/MOASPSSClient.java | 326 +++++++++++++++++++++ .../client/moaspss/MOASPSSClientException.java | 44 +++ 2 files changed, 370 insertions(+) create mode 100644 src/main/java/at/gv/util/client/moaspss/MOASPSSClient.java create mode 100644 src/main/java/at/gv/util/client/moaspss/MOASPSSClientException.java (limited to 'src/main/java/at/gv/util/client/moaspss') diff --git a/src/main/java/at/gv/util/client/moaspss/MOASPSSClient.java b/src/main/java/at/gv/util/client/moaspss/MOASPSSClient.java new file mode 100644 index 0000000..ab8acd8 --- /dev/null +++ b/src/main/java/at/gv/util/client/moaspss/MOASPSSClient.java @@ -0,0 +1,326 @@ +/* + * Copyright 2011 Federal Chancellery Austria and + * Graz University of Technology + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package at.gv.util.client.moaspss; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.net.ssl.SSLContext; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import javax.xml.namespace.QName; +import javax.xml.transform.Source; +import javax.xml.transform.TransformerException; +import javax.xml.transform.stream.StreamSource; +import javax.xml.ws.BindingProvider; +import javax.xml.ws.Dispatch; +import javax.xml.ws.Service; +import javax.xml.ws.handler.Handler; +import javax.xml.ws.soap.SOAPBinding; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import at.gv.util.DOMUtils; +import at.gv.util.LaxHostNameVerifier; +import at.gv.util.LoggingHandler; +import at.gv.util.MiscUtil; +import at.gv.util.config.EgovUtilConfiguration; +import at.gv.util.ex.EgovUtilException; +import at.gv.util.wsdl.SignatureCreationService; +import at.gv.util.wsdl.SignatureVerificationService; +import at.gv.util.xsd.moaspss.CreateXMLSignatureRequest; +import at.gv.util.xsd.moaspss.CreateXMLSignatureResponseType; +import at.gv.util.xsd.moaspss.ErrorResponseType; +import at.gv.util.xsd.moaspss.VerifyXMLSignatureRequestType; +import at.gv.util.xsd.moaspss.VerifyXMLSignatureResponseType; + +import com.sun.org.apache.xpath.internal.XPathAPI; +import com.sun.xml.ws.developer.JAXWSProperties; + +/** + * MOA-SS client. + * + * @author Arne Tauber + * + */ +public class MOASPSSClient { + + private static Logger log = LoggerFactory.getLogger(MOASPSSClient.class); + + private EgovUtilConfiguration config = null; + + public MOASPSSClient(EgovUtilConfiguration config) { + if (config == null) { + throw new NullPointerException("Argument 'config' must not be null."); + } + this.config = config; + } + + public MOASPSSClient() { + } + + @SuppressWarnings("unchecked") + public Element sendSignatureCreationRequest(String serviceURL, + InputStream signatureCreationRequest) throws MOASPSSClientException { + + log.debug("Creating XML signature using raw CreateXMLSignatureRequest."); + // check for arguments + if (serviceURL == null) { + throw new NullPointerException("Argument 'serviceURL' must not be null."); + } + if (signatureCreationRequest == null) { + throw new NullPointerException( + "Argument 'signatureRequest' must not be null."); + } + + try { + + log.trace("MOA-SS signature service URL: " + serviceURL); + URL url = MOASPSSClient.class.getResource("/wsdl/MOA-SPSS-1.3.wsdl"); + SignatureCreationService service = new SignatureCreationService( + url, + new QName( + "http://reference.e-government.gv.at/namespace/moa/20020822#moa.wsdl", + "SignatureCreationService")); + QName qname = new QName( + "http://localhost:8080/moa-spss/services/SignatureCreation", + "CreateXMLSignatureRequest"); + service.addPort(qname, SOAPBinding.SOAP11HTTP_BINDING, serviceURL); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + MiscUtil.copyStream(signatureCreationRequest, bos); + + Source source = new StreamSource(new ByteArrayInputStream( + bos.toByteArray())); + Dispatch dispatch = service.createDispatch(qname, Source.class, + Service.Mode.PAYLOAD); + + BindingProvider bindingProvider = (BindingProvider) dispatch; + log.trace("Adding JAX-WS request/response trace handler."); + List handlerList = bindingProvider.getBinding() + .getHandlerChain(); + if (handlerList == null) { + handlerList = new ArrayList(); + } + LoggingHandler loggingHandler = new LoggingHandler(); + handlerList.add(loggingHandler); + bindingProvider.getBinding().setHandlerChain(handlerList); + + // initialize ssl + Map requestContext = bindingProvider.getRequestContext(); + + if (serviceURL.toLowerCase().startsWith("https")) { + log.trace("Using ssl for MOA-SP request."); + if (this.config == null) { + throw new MOASPSSClientException( + "SSL requires client to be configured."); + } + SSLContext sslContext = this.config.getMOASPSSsslConfiguration() + .getSSLContext(false); + if (sslContext == null) { + throw new MOASPSSClientException( + "SSL context from configuration is empty. Please configure an SSL context in the configuration first."); + } + requestContext.put(JAXWSProperties.SSL_SOCKET_FACTORY, + sslContext.getSocketFactory()); + + // check for lax hostname + if (this.config.getMOASPSSsslConfiguration().useLaxHostNameVerifier()) { + log.trace("LaxHostnameVerifier enabled. This setting is not recommended to use."); + requestContext.put(JAXWSProperties.HOSTNAME_VERIFIER, + new LaxHostNameVerifier()); + } + } + + log.trace("Invoking MOA-SS signature creation service."); + Source response = dispatch.invoke(source); + + log.trace("Parsing MOA-SS response."); + byte[] moaResponse = MiscUtil.sourceToByteArray(response); + JAXBContext ctx = JAXBContext.newInstance(CreateXMLSignatureRequest.class + .getPackage().getName()); + JAXBElement jaxbElement = (JAXBElement) ctx + .createUnmarshaller() + .unmarshal(new ByteArrayInputStream(moaResponse)); + CreateXMLSignatureResponseType createXMLResponse = jaxbElement.getValue(); + for (Object obj : createXMLResponse + .getSignatureEnvironmentOrErrorResponse()) { + if (obj instanceof ErrorResponseType) { + ErrorResponseType errorResponse = (ErrorResponseType) obj; + log.trace("Could not create signature: " + + errorResponse.getErrorCode() + "/" + errorResponse.getInfo()); + throw new MOASPSSClientException("MOA-SS signature error: " + + errorResponse.getErrorCode() + "/" + errorResponse.getInfo()); + } + } + log.trace(new String(moaResponse)); + log.trace("Signature successfully created. Extracting from MOA-SS container."); + // ok, we have success + Document doc = MiscUtil.parseDocument(new ByteArrayInputStream( + moaResponse)); + String xpathExpression = "/moa:CreateXMLSignatureResponse/moa:SignatureEnvironment/child::*"; + Element nsNode = doc.createElement("NsNode"); + nsNode.setAttribute("xmlns:moa", doc.getDocumentElement() + .getNamespaceURI()); + log.trace("Selecting signed doc " + xpathExpression); + Element documentNode = (Element) XPathAPI.selectSingleNode(doc, + xpathExpression, nsNode); + log.trace("Signed document: " + DOMUtils.serializeNode(documentNode)); + + return documentNode; + } catch (TransformerException e) { + throw new MOASPSSClientException(e); + } catch (IOException e) { + throw new MOASPSSClientException(e); + } catch (JAXBException e) { + throw new MOASPSSClientException(e); + } catch (EgovUtilException e) { + throw new MOASPSSClientException(e); + } + } + + @SuppressWarnings("unchecked") + public VerifyXMLSignatureResponseType sendSignatureVerificationRequest( + String serviceURL, InputStream signatureVerificationRequest) + throws MOASPSSClientException { + log.debug("Verifying XML signature using raw VerifyXMLSignatureRequest."); + + // check for arguments + if (serviceURL == null) { + throw new NullPointerException("Argument 'serviceURL' must not be null."); + } + if (signatureVerificationRequest == null) { + throw new NullPointerException( + "Argument 'signatureRequest' must not be null."); + } + + try { + log.trace("MOA-SP verification service URL: " + serviceURL); + URL url = MOASPSSClient.class.getResource("/wsdl/MOA-SPSS-1.3.wsdl"); + SignatureVerificationService service = new SignatureVerificationService( + url, + new QName( + "http://reference.e-government.gv.at/namespace/moa/20020822#moa.wsdl", + "SignatureCreationService")); + QName qname = new QName( + "http://localhost:8080/moa-spss/services/SignatureVerification", + "VerifyXMLSignatureRequest"); + service.addPort(qname, SOAPBinding.SOAP11HTTP_BINDING, serviceURL); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + MiscUtil.copyStream(signatureVerificationRequest, bos); + + Source source = new StreamSource(new ByteArrayInputStream( + bos.toByteArray())); + Dispatch dispatch = service.createDispatch(qname, Source.class, + Service.Mode.PAYLOAD); + + BindingProvider bindingProvider = (BindingProvider) dispatch; + log.trace("Adding JAX-WS request/response trace handler."); + List handlerList = bindingProvider.getBinding() + .getHandlerChain(); + if (handlerList == null) { + handlerList = new ArrayList(); + } + LoggingHandler loggingHandler = new LoggingHandler(); + handlerList.add(loggingHandler); + bindingProvider.getBinding().setHandlerChain(handlerList); + + // initialize ssl + Map requestContext = bindingProvider.getRequestContext(); + + if (serviceURL.toLowerCase().startsWith("https")) { + log.trace("Using ssl for MOA-SP request."); + if (this.config == null) { + throw new MOASPSSClientException( + "SSL requires client to be configured."); + } + SSLContext sslContext = this.config.getMOASPSSsslConfiguration() + .getSSLContext(false); + if (sslContext == null) { + throw new MOASPSSClientException( + "SSL context from configuration is empty. Please configure an SSL context in the configuration first."); + } + requestContext.put(JAXWSProperties.SSL_SOCKET_FACTORY, + sslContext.getSocketFactory()); + + // check for lax hostname + if (this.config.getMOASPSSsslConfiguration().useLaxHostNameVerifier()) { + log.trace("LaxHostnameVerifier enabled. This setting is not recommended to use."); + requestContext.put(JAXWSProperties.HOSTNAME_VERIFIER, + new LaxHostNameVerifier()); + } + } + + log.trace("Invoking MOA-SP signature verification service."); + Source response = dispatch.invoke(source); + + log.trace("Parsing MOA-SP response."); + byte[] moaResponse = MiscUtil.sourceToByteArray(response); + JAXBContext ctx = JAXBContext + .newInstance(VerifyXMLSignatureRequestType.class.getPackage() + .getName()); + JAXBElement jaxbElement = (JAXBElement) ctx + .createUnmarshaller() + .unmarshal(new ByteArrayInputStream(moaResponse)); + VerifyXMLSignatureResponseType verifyXMLResponse = jaxbElement.getValue(); + log.trace(new String(moaResponse)); + return verifyXMLResponse; + } catch (TransformerException e) { + throw new MOASPSSClientException(e); + } catch (IOException e) { + throw new MOASPSSClientException(e); + } catch (JAXBException e) { + throw new MOASPSSClientException(e); + } catch (EgovUtilException e) { + throw new MOASPSSClientException(e); + } + } + + public static boolean isSuccess(VerifyXMLSignatureResponseType verifyResult) { + if (verifyResult == null) { + throw new NullPointerException( + "Argument 'verifyResult' must not be null."); + } + log.trace("Checking for signature verification result."); + + int signatureCheckCode = verifyResult.getSignatureCheck().getCode() + .intValue(); + int signtaureManifestCheckCode = verifyResult.getSignatureManifestCheck() + .getCode().intValue(); + int certificateCheckCode = verifyResult.getCertificateCheck().getCode() + .intValue(); + + log.trace("Signature check code: " + signatureCheckCode); + log.trace("Signature manifest check code: " + signtaureManifestCheckCode); + log.trace("Certificate check code: " + certificateCheckCode); + + return signatureCheckCode == 0 && signtaureManifestCheckCode == 0 + && certificateCheckCode == 0; + } + +} diff --git a/src/main/java/at/gv/util/client/moaspss/MOASPSSClientException.java b/src/main/java/at/gv/util/client/moaspss/MOASPSSClientException.java new file mode 100644 index 0000000..73f3acc --- /dev/null +++ b/src/main/java/at/gv/util/client/moaspss/MOASPSSClientException.java @@ -0,0 +1,44 @@ +/* + * Copyright 2011 Federal Chancellery Austria and + * Graz University of Technology + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package at.gv.util.client.moaspss; + +/** + * MOA-SS client exception class. + * + * @author Arne Tauber + * + */ +public class MOASPSSClientException extends Exception { + + private static final long serialVersionUID = 1L; + + public MOASPSSClientException() { + } + + public MOASPSSClientException(String message) { + super(message); + } + + public MOASPSSClientException(Throwable cause) { + super(cause); + } + + public MOASPSSClientException(String message, Throwable cause) { + super(message, cause); + } + +} -- cgit v1.2.3