1 /** 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 package org.apache.xml.security.test.interop; 20 21 import java.io.File; 22 import java.security.PublicKey; 23 import java.security.cert.X509Certificate; 24 import java.util.Iterator; 25 26 import javax.xml.xpath.XPath; 27 import javax.xml.xpath.XPathConstants; 28 import javax.xml.xpath.XPathFactory; 29 30 import org.apache.xml.security.keys.KeyInfo; 31 import org.apache.xml.security.signature.Reference; 32 import org.apache.xml.security.signature.SignedInfo; 33 import org.apache.xml.security.signature.XMLSignature; 34 import org.apache.xml.security.signature.reference.ReferenceData; 35 import org.apache.xml.security.signature.reference.ReferenceNodeSetData; 36 import org.apache.xml.security.signature.reference.ReferenceOctetStreamData; 37 import org.apache.xml.security.test.DSNamespaceContext; 38 import org.apache.xml.security.utils.resolver.ResourceResolverSpi; 39 import org.w3c.dom.Element; 40 import org.w3c.dom.Node; 41 42 public class InteropTestBase extends org.junit.Assert { 43 44 /** {@link org.apache.commons.logging} logging facility */ 45 static org.apache.commons.logging.Log log = 46 org.apache.commons.logging.LogFactory.getLog(InteropTestBase.class.getName()); 47 48 /** Field dbf */ 49 static javax.xml.parsers.DocumentBuilderFactory dbf = null; 50 51 /** 52 * Method setUp 53 * 54 */ InteropTestBase()55 public InteropTestBase() { 56 dbf = javax.xml.parsers.DocumentBuilderFactory.newInstance(); 57 dbf.setNamespaceAware(true); 58 } 59 60 61 /** 62 * Method verifyHMAC 63 * 64 * @param filename 65 * @param resolver 66 * @param hmacKey 67 * 68 * @throws Exception 69 */ verifyHMAC( String filename, ResourceResolverSpi resolver, boolean followManifests, byte[] hmacKey )70 public boolean verifyHMAC( 71 String filename, ResourceResolverSpi resolver, boolean followManifests, byte[] hmacKey 72 ) throws Exception { 73 File f = new File(filename); 74 javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder(); 75 org.w3c.dom.Document doc = db.parse(new java.io.FileInputStream(f)); 76 77 XPathFactory xpf = XPathFactory.newInstance(); 78 XPath xpath = xpf.newXPath(); 79 xpath.setNamespaceContext(new DSNamespaceContext()); 80 81 String expression = "//ds:Signature[1]"; 82 Element sigElement = 83 (Element) xpath.evaluate(expression, doc, XPathConstants.NODE); 84 XMLSignature signature = new XMLSignature(sigElement, f.toURI().toURL().toString()); 85 86 if (resolver != null) { 87 signature.addResourceResolver(resolver); 88 } 89 signature.setFollowNestedManifests(followManifests); 90 91 byte keybytes[] = hmacKey; 92 javax.crypto.SecretKey sk = signature.createSecretKey(keybytes); 93 94 return signature.checkSignatureValue(sk); 95 } 96 97 /** 98 * Method verify 99 * 100 * @param filename 101 * @param resolver 102 * 103 * @throws Exception 104 */ verify(String filename, ResourceResolverSpi resolver, boolean followManifests)105 public boolean verify(String filename, ResourceResolverSpi resolver, boolean followManifests) 106 throws Exception { 107 File f = new File(filename); 108 javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder(); 109 org.w3c.dom.Document doc = db.parse(f); 110 111 XPathFactory xpf = XPathFactory.newInstance(); 112 XPath xpath = xpf.newXPath(); 113 xpath.setNamespaceContext(new DSNamespaceContext()); 114 115 String expression = "//ds:Signature[1]"; 116 Element sigElement = 117 (Element) xpath.evaluate(expression, doc, XPathConstants.NODE); 118 XMLSignature signature = new XMLSignature(sigElement, f.toURI().toURL().toString()); 119 120 if (resolver != null) { 121 signature.addResourceResolver(resolver); 122 } 123 signature.setFollowNestedManifests(followManifests); 124 125 126 KeyInfo ki = signature.getKeyInfo(); 127 boolean result = false; 128 if (ki != null) { 129 X509Certificate cert = ki.getX509Certificate(); 130 131 if (cert != null) { 132 result = signature.checkSignatureValue(cert); 133 } else { 134 PublicKey pk = ki.getPublicKey(); 135 136 if (pk != null) { 137 result = signature.checkSignatureValue(pk); 138 } else { 139 throw new RuntimeException( 140 "Did not find a public key, so I can't check the signature"); 141 } 142 } 143 checkReferences(signature); 144 } else { 145 throw new RuntimeException("Did not find a KeyInfo"); 146 } 147 if (!result) { 148 for (int i = 0; i < signature.getSignedInfo().getLength(); i++) { 149 boolean refVerify = 150 signature.getSignedInfo().getVerificationResult(i); 151 152 if (refVerify) { 153 log.debug("Reference " + i + " was OK"); 154 } else { 155 // JavaUtils.writeBytesToFilename(filename + i + ".apache.txt", signature.getSignedInfo().item(i).getContentsAfterTransformation().getBytes()); 156 log.debug("Reference " + i + " was not OK"); 157 } 158 } 159 checkReferences(signature); 160 //throw new RuntimeException("Falle:"+sb.toString()); 161 } 162 163 return result; 164 } 165 checkReferences(XMLSignature xmlSignature)166 private void checkReferences(XMLSignature xmlSignature) throws Exception { 167 SignedInfo signedInfo = xmlSignature.getSignedInfo(); 168 assertTrue(signedInfo.getLength() > 0); 169 for (int i = 0; i < signedInfo.getLength(); i++) { 170 Reference reference = signedInfo.item(i); 171 assertNotNull(reference); 172 ReferenceData referenceData = reference.getReferenceData(); 173 assertNotNull(referenceData); 174 175 if (referenceData instanceof ReferenceNodeSetData) { 176 Iterator<Node> iter = ((ReferenceNodeSetData)referenceData).iterator(); 177 assertTrue(iter.hasNext()); 178 boolean found = false; 179 while (iter.hasNext()) { 180 Node n = (Node)iter.next(); 181 if (n instanceof Element) { 182 found = true; 183 break; 184 } 185 } 186 assertTrue(found); 187 } else if (referenceData instanceof ReferenceOctetStreamData) { 188 assertNotNull(((ReferenceOctetStreamData)referenceData).getOctetStream()); 189 } 190 } 191 } 192 193 } 194