/* * (C) Copyright 2010-2015 SAP SE. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * */ package eu.aniketos.pvm.checks.wsdl; import java.io.File; import java.io.IOException; import java.net.URL; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import eu.aniketos.pvm.commons.*; public class WsdlCheck { public static WSSecSpec readSpec(String atfile) { WSSecSpec spec = null; CryptoSpec input = null; CryptoSpec output =null; String algorithmSuite=""; String encryptionSchema=""; String algorithm=""; int keyLength=0; try { Document atDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File(atfile)); atDoc.normalize(); NodeList suites = atDoc.getElementsByTagName("wssAlgorithmSuite"); for (int i=0; i < suites.getLength(); i++) { NodeList reqs = suites.item(i).getChildNodes(); for (int j=0; j < reqs.getLength(); j++) { if(reqs.item(j).getNodeName().equals("encryptionScheme")) { encryptionSchema=reqs.item(j).getTextContent().trim(); } else if(reqs.item(j).getNodeName().equals("algorithm")) { algorithm=reqs.item(j).getTextContent().trim(); } else if(reqs.item(j).getNodeName().equals("key")) { keyLength=(new Integer(reqs.item(j).getTextContent())); } else if(reqs.item(j).getNodeName().equals("#text")) { String tmp = reqs.item(j).getNodeValue().trim(); if (!tmp.equals("")) { algorithmSuite=reqs.item(j).getNodeValue().trim(); } } } if((suites.item(i).getParentNode().getParentNode().getParentNode().getAttributes().getNamedItem("type")).getTextContent().equals("input")) { // input input=null; input=new CryptoSpec(algorithmSuite, encryptionSchema, algorithm, keyLength); } if(suites.item(i).getParentNode().getParentNode().getParentNode().getAttributes().getNamedItem("type").getTextContent().equals("output")) { // output output=null; output=new CryptoSpec(algorithmSuite, encryptionSchema, algorithm, keyLength); } } if (input != null || output != null) { spec = new WSSecSpec(input,output); } } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return spec; } private static PVMCoreResult checkWsdlSpec(WSSecSpec spec, WSSecSpec wsdl) { if ( spec == null || (spec.getInput()==null && spec.getOutput()==null)) { return new PVMCoreResult(0,"no requirements given, thus satisfied"); } else if (wsdl == null) { return new PVMCoreResult(-1,"no WSDL specification found"); } if(wsdl.isEqualOrStrongerAs(spec)) { if(spec.isEqualOrStrongerAs(wsdl)) { return new PVMCoreResult(0,"WSDL is equal to specification"); } else { return new PVMCoreResult(0,"WSDL is stronger as specification"); } } else { return new PVMCoreResult(-2,"WSDL specification to weak"); } } private static WSSecSpec readWSDL(String wsdlfile) { WSSecSpec spec = null; CryptoSpec input = null; CryptoSpec output =null; String InputURI=null; String OutputURI=null; try { Document wsdlDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File(wsdlfile)); wsdlDoc.normalize(); NodeList wsPoliciesRefs = wsdlDoc.getElementsByTagName("wsp:PolicyReference"); for (int i=0; i < wsPoliciesRefs.getLength(); i++) { if(wsPoliciesRefs.item(i).getParentNode().getNodeName().equals("wsdl:operation")) { // only one policy for both input and output InputURI = wsPoliciesRefs.item(i).getAttributes().getNamedItem("URI").getNodeValue(); OutputURI = wsPoliciesRefs.item(i).getAttributes().getNamedItem("URI").getNodeValue(); } else if (wsPoliciesRefs.item(i).getParentNode().getNodeName().equals("wsdl:input")) { InputURI = wsPoliciesRefs.item(i).getAttributes().getNamedItem("URI").getNodeValue(); } else if (wsPoliciesRefs.item(i).getParentNode().getNodeName().equals("wsdl:output")) { OutputURI = wsPoliciesRefs.item(i).getAttributes().getNamedItem("URI").getNodeValue(); } } NodeList wsPolicies = wsdlDoc.getElementsByTagName("wsp:Policy"); for (int i=0; i < wsPolicies.getLength(); i++) { if(wsPolicies.item(i).getAttributes().getNamedItem("wsu:Id")!=null) { if(InputURI != null && InputURI.equals("#"+wsPolicies.item(i).getAttributes().getNamedItem("wsu:Id").getNodeValue())) { input=policyNode2CryptoSpec(wsPolicies.item(i)); } if(OutputURI != null && OutputURI.equals("#"+wsPolicies.item(i).getAttributes().getNamedItem("wsu:Id").getNodeValue())) { output=policyNode2CryptoSpec(wsPolicies.item(i)); } } } } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } if (null != input || null != output) { spec = new WSSecSpec(input,output); } return spec ; } private static CryptoSpec policyNode2CryptoSpec(Node policyNode) { String algorithmSuite=""; String encryptionSchema=""; String algorithm=""; int keyLength=-128; Node binding = policyNode.getChildNodes().item(1) .getChildNodes().item(1) .getChildNodes().item(1) .getChildNodes().item(1); // Schema if(binding.getNodeName().toLowerCase().equals("sp:symmetricbinding")) { encryptionSchema="symmetric"; } else if(binding.getNodeName().toLowerCase().equals("sp:asymmetricbinding")) { encryptionSchema="symmetric"; } Node innerPolicy = binding.getChildNodes().item(1); // for (int i=0; i < innerPolicy.getChildNodes().getLength(); i++) { if(innerPolicy.getChildNodes().item(i).getNodeName().toLowerCase().equals("sp:algorithmsuite")) { algorithmSuite=innerPolicy.getChildNodes().item(i).getChildNodes().item(1).getChildNodes().item(1).getNodeName(); algorithmSuite=algorithmSuite.replaceFirst("sp:","").toLowerCase(); } } // The rest is hardcoded based on the Suite: // https://access.redhat.com/site/documentation/en-US/JBoss_Fuse/6.0/html/Web_Services_Security_Guide/files/MsgProtect-SOAP-SpecifyAlgorithmSuite.html# // Basic256Sha256Rsa15 Sha256 Aes256 KwAes256 KwRsa15 PSha1L256 PSha1L192 // Basic192Sha256Rsa15 Sha256 Aes192 KwAes192 KwRsa15 PSha1L192 PSha1L192 // Basic128Sha256Rsa15 Sha256 Aes128 KwAes128 KwRsa15 PSha1L128 PSha1L128 if(algorithmSuite.equals("basic256sha256rsa15")) { if(encryptionSchema.equals("symmetric")) { algorithm="aes"; keyLength=256; } else { algorithm="rsa"; keyLength=15; } } else if(algorithmSuite.equals("basic192sha256rsa15")) { if(encryptionSchema.equals("symmetric")) { algorithm="aes"; keyLength=192; } else { algorithm="rsa"; keyLength=15; } } if(algorithmSuite.equals("basic128sha256rsa15")) { if(encryptionSchema.equals("symmetric")) { algorithm="aes"; keyLength=128; } else { algorithm="rsa"; keyLength=15; } } return new CryptoSpec(algorithmSuite, encryptionSchema, algorithm, keyLength); } /////////////////////////////////////////////////////////////////////////////////////////// public PVMCoreResult verifyTechnicalTrustProperties(String AgreementTemplate, URL ServiceImplementation) { PVMCoreResult result = new PVMCoreResult(-255,"Fatal Error"); // Check for correct input if (AgreementTemplate == null) { return new PVMCoreResult(0, "No AgreementTemplate given"); } if (ServiceImplementation == null) { return new PVMCoreResult(0, "No ServiceImplementation (WSDL) given"); } File tempDirectory=null; try { tempDirectory = FileUtil.createTempDir(); } catch (IOException e) { e.printStackTrace(); } if(tempDirectory!=null) { String specfile= tempDirectory.toString() + File.separator + "agreementTemp.xml"; // Currently uses a link to an xml file String DecodedAgreementTemplate = FileUtil.decodeBase64(AgreementTemplate); FileUtil.writeStringToFile(DecodedAgreementTemplate, specfile); /////////////////////////// FileUtil.downloadFile(ServiceImplementation, tempDirectory, "service.wsdl"); String wsdlfile= tempDirectory.toString() + File.separator + "service.wsdl"; //////////////////////////////// WSSecSpec spec = readSpec(specfile); WSSecSpec wsdl = readWSDL(wsdlfile); result = WsdlCheck.checkWsdlSpec(spec,wsdl); } return result; } public PVMCoreResult verifyWSDL(WSSecSpec spec, URL ServiceImplementation) { PVMCoreResult result = new PVMCoreResult(-255,"Fatal Error"); if (spec == null) { return new PVMCoreResult(0, "No Requirements (Spec) given"); } if (ServiceImplementation == null) { return new PVMCoreResult(0, "No ServiceImplementation (WSDL) given"); } File tempDirectory=null; try { tempDirectory = FileUtil.createTempDir(); } catch (IOException e) { e.printStackTrace(); } if(tempDirectory!=null) { FileUtil.downloadFile(ServiceImplementation, tempDirectory, "service.wsdl"); String wsdlfile= tempDirectory.toString() + File.separator + "service.wsdl"; WSSecSpec wsdl = readWSDL(wsdlfile); result = WsdlCheck.checkWsdlSpec(spec,wsdl); } return result; } }