summaryrefslogtreecommitdiff
path: root/src/main/java/at/gv/util/client/moaspss/MOASPSSClient.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/at/gv/util/client/moaspss/MOASPSSClient.java')
-rw-r--r--src/main/java/at/gv/util/client/moaspss/MOASPSSClient.java326
1 files changed, 326 insertions, 0 deletions
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 <a href="mailto:Arne.Tauber@egiz.gv.at">Arne Tauber</a>
+ *
+ */
+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<Source> dispatch = service.createDispatch(qname, Source.class,
+ Service.Mode.PAYLOAD);
+
+ BindingProvider bindingProvider = (BindingProvider) dispatch;
+ log.trace("Adding JAX-WS request/response trace handler.");
+ List<Handler> handlerList = bindingProvider.getBinding()
+ .getHandlerChain();
+ if (handlerList == null) {
+ handlerList = new ArrayList();
+ }
+ LoggingHandler loggingHandler = new LoggingHandler();
+ handlerList.add(loggingHandler);
+ bindingProvider.getBinding().setHandlerChain(handlerList);
+
+ // initialize ssl
+ Map<String, Object> 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<CreateXMLSignatureResponseType> jaxbElement = (JAXBElement<CreateXMLSignatureResponseType>) 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<Source> dispatch = service.createDispatch(qname, Source.class,
+ Service.Mode.PAYLOAD);
+
+ BindingProvider bindingProvider = (BindingProvider) dispatch;
+ log.trace("Adding JAX-WS request/response trace handler.");
+ List<Handler> handlerList = bindingProvider.getBinding()
+ .getHandlerChain();
+ if (handlerList == null) {
+ handlerList = new ArrayList();
+ }
+ LoggingHandler loggingHandler = new LoggingHandler();
+ handlerList.add(loggingHandler);
+ bindingProvider.getBinding().setHandlerChain(handlerList);
+
+ // initialize ssl
+ Map<String, Object> 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<VerifyXMLSignatureResponseType> jaxbElement = (JAXBElement<VerifyXMLSignatureResponseType>) 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;
+ }
+
+}