ValidationTests.java revision 12057:5d60882157c9
1/* 2 * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24/** 25 * @test 26 * @bug 4635230 6365103 6366054 6824440 7131084 8046724 8079693 27 * @summary Basic unit tests for validating XML Signatures with JSR 105 28 * @modules java.base/sun.security.util 29 * java.base/sun.security.x509 30 * java.xml.crypto/org.jcp.xml.dsig.internal.dom 31 * @compile -XDignore.symbol.file KeySelectors.java SignatureValidator.java 32 * X509KeySelector.java ValidationTests.java 33 * @run main/othervm ValidationTests 34 * @author Sean Mullan 35 */ 36import java.io.File; 37import java.io.FileInputStream; 38import java.security.*; 39import javax.xml.crypto.Data; 40import javax.xml.crypto.KeySelector; 41import javax.xml.crypto.MarshalException; 42import javax.xml.crypto.OctetStreamData; 43import javax.xml.crypto.URIDereferencer; 44import javax.xml.crypto.URIReference; 45import javax.xml.crypto.URIReferenceException; 46import javax.xml.crypto.XMLCryptoContext; 47import javax.xml.crypto.dsig.XMLSignatureException; 48import javax.xml.crypto.dsig.XMLSignatureFactory; 49 50public class ValidationTests { 51 52 private static SignatureValidator validator; 53 private final static String DIR = System.getProperty("test.src", "."); 54 private final static String DATA_DIR = 55 DIR + System.getProperty("file.separator") + "data"; 56 private final static String KEYSTORE = 57 DATA_DIR + System.getProperty("file.separator") + "certs" + 58 System.getProperty("file.separator") + "xmldsig.jks"; 59 private final static String STYLESHEET = 60 "http://www.w3.org/TR/xml-stylesheet"; 61 private final static String STYLESHEET_B64 = 62 "http://www.w3.org/Signature/2002/04/xml-stylesheet.b64"; 63 64 static class Test { 65 String file; 66 KeySelector ks; 67 Class exception; 68 69 Test(String file, KeySelector ks, Class exception) { 70 this.file = file; 71 this.ks = ks; 72 this.exception = exception; 73 } 74 75 // XMLSignatureException is expected by default 76 Test(String file, KeySelector ks) { 77 this(file, ks, XMLSignatureException.class); 78 } 79 } 80 81 static KeySelector skks; 82 static { 83 try { 84 skks = 85 new KeySelectors.SecretKeySelector("secret".getBytes("ASCII")); 86 } catch (Exception e) { 87 //should not occur 88 } 89 } 90 private final static KeySelector SKKS = skks; 91 private final static KeySelector KVKS = 92 new KeySelectors.KeyValueKeySelector(); 93 private final static KeySelector CKS = 94 new KeySelectors.CollectionKeySelector(new File(DATA_DIR)); 95 private final static KeySelector RXKS = 96 new KeySelectors.RawX509KeySelector(); 97 private final static KeySelector XKS = null; 98 private static URIDereferencer httpUd = null; 99 100 private final static Test[] VALID_TESTS = { 101 new Test("signature-enveloped-dsa.xml", KVKS), 102 new Test("signature-enveloping-b64-dsa.xml", KVKS), 103 new Test("signature-enveloping-dsa.xml", KVKS), 104 new Test("signature-enveloping-rsa.xml", KVKS), 105 new Test("signature-enveloping-p256-sha1.xml", KVKS), 106 new Test("signature-enveloping-p384-sha1.xml", KVKS), 107 new Test("signature-enveloping-p521-sha1.xml", KVKS), 108 new Test("signature-enveloping-hmac-sha1.xml", SKKS), 109 new Test("signature-external-dsa.xml", KVKS), 110 new Test("signature-external-b64-dsa.xml", KVKS), 111 new Test("signature-retrievalmethod-rawx509crt.xml", CKS), 112 new Test("signature-keyname.xml", CKS), 113 new Test("signature-x509-crt-crl.xml", RXKS), 114 new Test("signature-x509-crt.xml", RXKS), 115 new Test("signature-x509-is.xml", CKS), 116 new Test("signature-x509-ski.xml", CKS), 117 new Test("signature-x509-sn.xml", CKS), 118 new Test("signature.xml", XKS), 119 new Test("exc-signature.xml", KVKS), 120 new Test("sign-spec.xml", RXKS), 121 new Test("xmldsig-xfilter2.xml", KVKS) 122 }; 123 124 private final static Test[] INVALID_TESTS = { 125 new Test("signature-enveloping-hmac-sha1-40.xml", SKKS), 126 new Test("signature-enveloping-hmac-sha1-trunclen-0-attack.xml", SKKS), 127 new Test("signature-enveloping-hmac-sha1-trunclen-8-attack.xml", SKKS), 128 new Test("signature-extra-text-in-signed-info.xml", SKKS, 129 MarshalException.class), 130 new Test("signature-wrong-canonicalization-method-algorithm.xml", SKKS, 131 MarshalException.class), 132 new Test("signature-wrong-transform-algorithm.xml", SKKS, 133 MarshalException.class), 134 new Test("signature-no-reference-uri.xml", SKKS), 135 new Test("signature-wrong-signature-method-algorithm.xml", SKKS, 136 MarshalException.class), 137 new Test("signature-wrong-tag-names.xml", SKKS, MarshalException.class) 138 }; 139 140 public static void main(String args[]) throws Exception { 141 httpUd = new HttpURIDereferencer(); 142 143 validator = new SignatureValidator(new File(DATA_DIR)); 144 145 boolean atLeastOneFailed = false; 146 for (Test test : VALID_TESTS) { 147 System.out.println("Validating " + test.file); 148 if (test_signature(test)) { 149 System.out.println("PASSED"); 150 } else { 151 System.out.println("FAILED"); 152 atLeastOneFailed = true; 153 } 154 } 155 // test with reference caching enabled 156 System.out.println("Validating sign-spec.xml with caching enabled"); 157 if (test_signature(new Test("sign-spec.xml", RXKS), true)) { 158 System.out.println("PASSED"); 159 } else { 160 System.out.println("FAILED"); 161 atLeastOneFailed = true; 162 } 163 164 for (Test test : INVALID_TESTS) { 165 System.out.println("Validating " + test.file); 166 try { 167 test_signature(test); 168 System.out.println("FAILED"); 169 atLeastOneFailed = true; 170 } catch (Exception e) { 171 System.out.println("Exception: " + e); 172 if (e.getClass() != test.exception) { 173 System.out.println("FAILED: unexpected exception"); 174 atLeastOneFailed = true; 175 } else { 176 System.out.println("PASSED"); 177 } 178 } 179 } 180 181 if (atLeastOneFailed) { 182 throw new Exception 183 ("At least one signature did not validate as expected"); 184 } 185 } 186 187 public static boolean test_signature(Test test) throws Exception { 188 return test_signature(test, false); 189 } 190 191 public static boolean test_signature(Test test, boolean cache) 192 throws Exception 193 { 194 if (test.ks == null) { 195 KeyStore keystore = KeyStore.getInstance("JKS"); 196 try (FileInputStream fis = new FileInputStream(KEYSTORE)) { 197 keystore.load(fis, "changeit".toCharArray()); 198 test.ks = new X509KeySelector(keystore, false); 199 } 200 } 201 return validator.validate(test.file, test.ks, httpUd, cache); 202 } 203 204 /** 205 * This URIDereferencer returns locally cached copies of http content to 206 * avoid test failures due to network glitches, etc. 207 */ 208 private static class HttpURIDereferencer implements URIDereferencer { 209 private URIDereferencer defaultUd; 210 211 HttpURIDereferencer() { 212 defaultUd = XMLSignatureFactory.getInstance().getURIDereferencer(); 213 } 214 215 public Data dereference(final URIReference ref, XMLCryptoContext ctx) 216 throws URIReferenceException { 217 String uri = ref.getURI(); 218 if (uri.equals(STYLESHEET) || uri.equals(STYLESHEET_B64)) { 219 try { 220 FileInputStream fis = new FileInputStream(new File 221 (DATA_DIR, uri.substring(uri.lastIndexOf('/')))); 222 return new OctetStreamData(fis,ref.getURI(),ref.getType()); 223 } catch (Exception e) { throw new URIReferenceException(e); } 224 } 225 226 // fallback on builtin deref 227 return defaultUd.dereference(ref, ctx); 228 } 229 } 230} 231