/* * Copyright 2008 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 moaspss; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.URL; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.SchemaOutputResolver; import javax.xml.bind.Unmarshaller; import javax.xml.bind.Validator; import javax.xml.namespace.QName; import javax.xml.transform.Result; import moaspss.generated.ContentOptionalRefType; import moaspss.generated.InputDataType; import moaspss.generated.MOAFault; import moaspss.generated.ObjectFactory; import moaspss.generated.SignatureVerificationPortType; import moaspss.generated.SignatureVerificationService; import moaspss.generated.VerifyXMLSignatureRequestType; import moaspss.generated.VerifyXMLSignatureResponseType; import moaspss.generated.VerifyXMLSignatureRequestType.VerifySignatureInfo; import org.w3c.dom.Node; import org.w3c.dom.bootstrap.DOMImplementationRegistry; import org.w3c.dom.ls.DOMImplementationLS; import org.w3c.dom.ls.LSOutput; import org.w3c.dom.ls.LSSerializer; import com.sun.xml.bind.api.Bridge; import com.sun.xml.bind.api.BridgeContext; import com.sun.xml.bind.api.JAXBRIContext; import com.sun.xml.bind.api.RawAccessor; import com.sun.xml.bind.api.TypeReference; import com.sun.xml.bind.marshaller.NamespacePrefixMapper; import com.sun.xml.ws.api.model.SEIModel; import com.sun.xml.ws.developer.JAXBContextFactory; import com.sun.xml.ws.developer.UsesJAXBContextFeature; @SuppressWarnings("deprecation") public class MOASPClient { private static class JAXBContextHolder { private static final JAXBContext context; static { try { context = JAXBRIContext.newInstance(VerifyXMLSignatureRequestType.class.getPackage().getName()); } catch (JAXBException e) { throw new RuntimeException("Failed to setup JAXBContext.", e); } } } public static JAXBContext getJAXBContext() { return JAXBContextHolder.context; } public static class ClientJAXBContextFactory implements JAXBContextFactory { public JAXBRIContext createJAXBContext(final SEIModel sei, final List classesToBind, final List typeReferences) throws JAXBException { System.out.println("Create Context"); return new JAXBRIContext() { JAXBRIContext context = JAXBRIContext.newInstance(classesToBind.toArray (new Class[classesToBind.size()]), typeReferences, null, sei.getTargetNamespace(), false, null); @Override public Validator createValidator() throws JAXBException { return context.createValidator(); } @Override public Unmarshaller createUnmarshaller() throws JAXBException { return context.createUnmarshaller(); } @Override public Marshaller createMarshaller() throws JAXBException { Marshaller marshaller = context.createMarshaller(); ClientNamespacePrefixMapper pm = new ClientNamespacePrefixMapper(); System.out.println(pm.toString()); marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", pm); return marshaller; } @Override public boolean hasSwaRef() { return context.hasSwaRef(); } @Override public QName getTypeName(TypeReference arg0) { return context.getTypeName(arg0); } @Override public List getKnownNamespaceURIs() { return context.getKnownNamespaceURIs(); } @Override public RawAccessor getElementPropertyAccessor(Class arg0, String arg1, String arg2) throws JAXBException { return context.getElementPropertyAccessor(arg0, arg1, arg2); } @Override public QName getElementName(Object arg0) throws JAXBException { return context.getElementName(arg0); } @Override public String getBuildId() { return context.getBuildId(); } @Override public void generateSchema(SchemaOutputResolver arg0) throws IOException { context.generateSchema(arg0); } @Override public void generateEpisode(Result arg0) { context.generateEpisode(arg0); } @Override public BridgeContext createBridgeContext() { return context.createBridgeContext(); } @Override public Bridge createBridge(TypeReference arg0) { return context.createBridge(arg0); } }; } } public static class ClientNamespacePrefixMapper extends NamespacePrefixMapper { protected static final Map prefixMap = new HashMap(); static { prefixMap.put("http://www.w3.org/2001/XMLSchema-instance", "xsi"); prefixMap.put("http://reference.e-government.gv.at/namespace/moa/20020822#", "moa"); prefixMap.put("http://www.w3.org/2000/09/xmldsig#", "dsig"); prefixMap.put("http://uri.etsi.org/01903/v1.1.1#", "xades"); } @Override public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) { String prefix = prefixMap.get(namespaceUri); return (prefix != null) ? prefix : suggestion; } /** * Returns a list of namespace URIs that should be declared * at the root element. *

* By default, the JAXB RI produces namespace declarations only when * they are necessary, only at where they are used. Because of this * lack of look-ahead, sometimes the marshaller produces a lot of * namespace declarations that look redundant to human eyes. For example, */ @Override public String[] getPreDeclaredNamespaceUris() { return new String[]{ "http://www.w3.org/2000/09/xmldsig#" }; } } private SignatureVerificationPortType port; public MOASPClient() { QName serviceName = new QName("http://reference.e-government.gv.at/namespace/moa/wsdl/20020822#", "SignatureVerificationService"); URL wsdlURL = MOASPClient.class.getClassLoader().getResource("MOA-SPSS-1.3.wsdl"); SignatureVerificationService service = new SignatureVerificationService(wsdlURL, serviceName); UsesJAXBContextFeature feature = new UsesJAXBContextFeature(ClientJAXBContextFactory.class); port = service.getSignatureVerificationPort(feature); } public JAXBElement verifySignature(Node node, String signatureLocation, String trustProfileId) throws JAXBException, IOException, ClassCastException, ClassNotFoundException, InstantiationException, IllegalAccessException { DOMImplementationLS domImpl = (DOMImplementationLS) DOMImplementationRegistry .newInstance().getDOMImplementation("LS"); LSSerializer serializer = domImpl.createLSSerializer(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); LSOutput output = domImpl.createLSOutput(); output.setByteStream(bos); serializer.write(node, output); ObjectFactory factory = new ObjectFactory(); ContentOptionalRefType contentOptionalRefType = factory.createContentOptionalRefType(); contentOptionalRefType.setBase64Content(bos.toByteArray()); VerifySignatureInfo verifySignatureInfo = factory.createVerifyXMLSignatureRequestTypeVerifySignatureInfo(); verifySignatureInfo.setVerifySignatureEnvironment(contentOptionalRefType); verifySignatureInfo.setVerifySignatureLocation(signatureLocation); VerifyXMLSignatureRequestType verifyXMLSignatureRequestType = factory.createVerifyXMLSignatureRequestType(); verifyXMLSignatureRequestType.setVerifySignatureInfo(verifySignatureInfo); verifyXMLSignatureRequestType.setTrustProfileID(trustProfileId); verifyXMLSignatureRequestType.setReturnHashInputData(Boolean.TRUE); VerifyXMLSignatureResponseType resp = null; try { resp = port.verifyXMLSignature(verifyXMLSignatureRequestType); } catch (MOAFault e) { e.printStackTrace(); } JAXBElement verifyXMLSignatureResponse = factory.createVerifyXMLSignatureResponse(resp); Marshaller marshaller = getJAXBContext().createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); marshaller.marshal(verifyXMLSignatureResponse, System.out); List hashInputData = resp.getHashInputData(); for (InputDataType inputDataType : hashInputData) { System.out.println("------------------------------------------"); System.out.println("HashInputData: " + inputDataType.getPartOf() + " " + inputDataType.getReferringSigReference()); System.out.println("------------------------------------------"); System.out.write(inputDataType.getBase64Content()); System.out.println(); } return verifyXMLSignatureResponse; } }