# HG changeset patch # User mullan # Date 1327339024 18000 # Node ID a657f8ba55fc6a684fd7625596e1a28a7bb7c018 # Parent b1f9f8d4806b9f5c02f87b43ae0784a88781858c 7131084: XMLDSig XPathFilter2Transform regression involving intersect filter Reviewed-by: xuelei diff -r b1f9f8d4806b -r a657f8ba55fc jdk/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath2Filter.java --- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath2Filter.java Wed Jan 18 11:00:20 2012 -0800 +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath2Filter.java Mon Jan 23 12:17:04 2012 -0500 @@ -148,8 +148,8 @@ } - input.addNodeFilter(new XPath2NodeFilter(convertNodeListToSet(unionNodes), - convertNodeListToSet(substractNodes),convertNodeListToSet(intersectNodes))); + input.addNodeFilter(new XPath2NodeFilter(unionNodes, substractNodes, + intersectNodes)); input.setNodeSet(true); return input; } catch (TransformerException ex) { @@ -170,32 +170,20 @@ throw new TransformationException("empty", ex); } } - static Set convertNodeListToSet(List l){ - Set result=new HashSet(); - - for (NodeList rootNodes : l) { - int length = rootNodes.getLength(); - for (int i = 0; i < length; i++) { - Node rootNode = rootNodes.item(i); - result.add(rootNode); - } - } - return result; - } } class XPath2NodeFilter implements NodeFilter { - boolean hasUnionNodes; - boolean hasSubstractNodes; - boolean hasIntersectNodes; - XPath2NodeFilter(Set unionNodes, Set substractNodes, - Set intersectNodes) { - this.unionNodes=unionNodes; - hasUnionNodes=!unionNodes.isEmpty(); - this.substractNodes=substractNodes; - hasSubstractNodes=!substractNodes.isEmpty(); - this.intersectNodes=intersectNodes; - hasIntersectNodes=!intersectNodes.isEmpty(); + boolean hasUnionFilter; + boolean hasSubstractFilter; + boolean hasIntersectFilter; + XPath2NodeFilter(List unionNodes, List substractNodes, + List intersectNodes) { + hasUnionFilter=!unionNodes.isEmpty(); + this.unionNodes=convertNodeListToSet(unionNodes); + hasSubstractFilter=!substractNodes.isEmpty(); + this.substractNodes=convertNodeListToSet(substractNodes); + hasIntersectFilter=!intersectNodes.isEmpty(); + this.intersectNodes=convertNodeListToSet(intersectNodes); } Set unionNodes; Set substractNodes; @@ -208,16 +196,16 @@ public int isNodeInclude(Node currentNode) { int result=1; - if (hasSubstractNodes && rooted(currentNode, substractNodes)) { + if (hasSubstractFilter && rooted(currentNode, substractNodes)) { result = -1; - } else if (hasIntersectNodes && !rooted(currentNode, intersectNodes)) { + } else if (hasIntersectFilter && !rooted(currentNode, intersectNodes)) { result = 0; } //TODO OPTIMIZE if (result==1) return 1; - if (hasUnionNodes) { + if (hasUnionFilter) { if (rooted(currentNode, unionNodes)) { return 1; } @@ -231,7 +219,7 @@ int inUnion=-1; public int isNodeIncludeDO(Node n, int level) { int result=1; - if (hasSubstractNodes) { + if (hasSubstractFilter) { if ((inSubstract==-1) || (level<=inSubstract)) { if (inList(n, substractNodes)) { inSubstract=level; @@ -244,7 +232,7 @@ } } if (result!=-1){ - if (hasIntersectNodes) { + if (hasIntersectFilter) { if ((inIntersect==-1) || (level<=inIntersect)) { if (!inList(n, intersectNodes)) { inIntersect=-1; @@ -260,7 +248,7 @@ inUnion=-1; if (result==1) return 1; - if (hasUnionNodes) { + if (hasUnionFilter) { if ((inUnion==-1) && inList(n, unionNodes)) { inUnion=level; } @@ -280,6 +268,9 @@ * @return if rooted bye the rootnodes */ static boolean rooted(Node currentNode, Set nodeList ) { + if (nodeList.isEmpty()) { + return false; + } if (nodeList.contains(currentNode)) { return true; } @@ -302,4 +293,17 @@ static boolean inList(Node currentNode, Set nodeList ) { return nodeList.contains(currentNode); } + + private static Set convertNodeListToSet(List l){ + Set result=new HashSet(); + + for (NodeList rootNodes : l) { + int length = rootNodes.getLength(); + for (int i = 0; i < length; i++) { + Node rootNode = rootNodes.item(i); + result.add(rootNode); + } + } + return result; + } } diff -r b1f9f8d4806b -r a657f8ba55fc jdk/test/javax/xml/crypto/dsig/KeySelectors.java --- a/jdk/test/javax/xml/crypto/dsig/KeySelectors.java Wed Jan 18 11:00:20 2012 -0800 +++ b/jdk/test/javax/xml/crypto/dsig/KeySelectors.java Mon Jan 23 12:17:04 2012 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,9 @@ */ import java.io.*; -import java.security.*; +import java.security.Key; +import java.security.KeyException; +import java.security.PublicKey; import java.security.cert.*; import java.util.*; import javax.crypto.SecretKey; @@ -76,7 +78,7 @@ } public byte[] getEncoded() { - return (byte[]) bytes.clone(); + return bytes.clone(); } }; } @@ -196,9 +198,9 @@ * matching public key. */ static class CollectionKeySelector extends KeySelector { - private CertificateFactory certFac; + private CertificateFactory cf; private File certDir; - private Vector certs; + private Vector certs; private static final int MATCH_SUBJECT = 0; private static final int MATCH_ISSUER = 1; private static final int MATCH_SERIAL = 2; @@ -208,24 +210,24 @@ CollectionKeySelector(File dir) { certDir = dir; try { - certFac = CertificateFactory.getInstance("X509"); + cf = CertificateFactory.getInstance("X509"); } catch (CertificateException ex) { // not going to happen } - certs = new Vector(); + certs = new Vector(); File[] files = new File(certDir, "certs").listFiles(); for (int i = 0; i < files.length; i++) { - try { - certs.add(certFac.generateCertificate - (new FileInputStream(files[i]))); + try (FileInputStream fis = new FileInputStream(files[i])) { + certs.add((X509Certificate)cf.generateCertificate(fis)); } catch (Exception ex) { } } } - Vector match(int matchType, Object value, Vector pool) { - Vector matchResult = new Vector(); + Vector match(int matchType, Object value, + Vector pool) { + Vector matchResult = new Vector<>(); for (int j=0; j < pool.size(); j++) { - X509Certificate c = (X509Certificate) pool.get(j); + X509Certificate c = pool.get(j); switch (matchType) { case MATCH_SUBJECT: try { @@ -286,19 +288,18 @@ if (xmlStructure instanceof KeyName) { String name = ((KeyName)xmlStructure).getName(); PublicKey pk = null; - try { + File certFile = new File(new File(certDir, "certs"), + name.toLowerCase() + ".crt"); + try (FileInputStream fis = new FileInputStream(certFile)) { // Lookup the public key using the key name 'Xxx', // i.e. the public key is in "certs/xxx.crt". - File certFile = new File(new File(certDir, "certs"), - name.toLowerCase()+".crt"); X509Certificate cert = (X509Certificate) - certFac.generateCertificate - (new FileInputStream(certFile)); + cf.generateCertificate(fis); pk = cert.getPublicKey(); } catch (FileNotFoundException e) { // assume KeyName contains subject DN and search // collection of certs for match - Vector result = + Vector result = match(MATCH_SUBJECT, name, certs); int numOfMatches = (result==null? 0:result.size()); if (numOfMatches != 1) { @@ -306,7 +307,7 @@ ((numOfMatches==0?"No":"More than one") + " match found"); } - pk =((X509Certificate)result.get(0)).getPublicKey(); + pk = result.get(0).getPublicKey(); } return new SimpleKSResult(pk); } else if (xmlStructure instanceof RetrievalMethod) { @@ -316,10 +317,12 @@ String type = rm.getType(); if (type.equals(X509Data.RAW_X509_CERTIFICATE_TYPE)) { String uri = rm.getURI(); - X509Certificate cert = (X509Certificate) - certFac.generateCertificate - (new FileInputStream(new File(certDir, uri))); - return new SimpleKSResult(cert.getPublicKey()); + try (FileInputStream fis = + new FileInputStream(new File(certDir, uri))) { + X509Certificate cert = (X509Certificate) + cf.generateCertificate(fis); + return new SimpleKSResult(cert.getPublicKey()); + } } else { throw new KeySelectorException ("Unsupported RetrievalMethod type"); @@ -327,7 +330,7 @@ } else if (xmlStructure instanceof X509Data) { List content = ((X509Data)xmlStructure).getContent(); int size = content.size(); - Vector result = null; + Vector result = null; // Lookup the public key using the information // specified in X509Data element, i.e. searching // over the collection of certificate files under @@ -357,8 +360,7 @@ ((numOfMatches==0?"No":"More than one") + " match found"); } - return new SimpleKSResult(((X509Certificate) - result.get(0)).getPublicKey()); + return new SimpleKSResult(result.get(0).getPublicKey()); } } catch (Exception ex) { throw new KeySelectorException(ex); diff -r b1f9f8d4806b -r a657f8ba55fc jdk/test/javax/xml/crypto/dsig/ValidationTests.java --- a/jdk/test/javax/xml/crypto/dsig/ValidationTests.java Wed Jan 18 11:00:20 2012 -0800 +++ b/jdk/test/javax/xml/crypto/dsig/ValidationTests.java Mon Jan 23 12:17:04 2012 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /** * @test - * @bug 4635230 6365103 6366054 6824440 + * @bug 4635230 6365103 6366054 6824440 7131084 * @summary Basic unit tests for validating XML Signatures with JSR 105 * @compile -XDignore.symbol.file KeySelectors.java SignatureValidator.java * X509KeySelector.java ValidationTests.java @@ -43,10 +43,6 @@ import javax.xml.crypto.dsig.XMLSignatureException; import javax.xml.crypto.dsig.XMLSignatureFactory; -/** - * This is a testcase to validate all "merlin-xmldsig-twenty-three" - * testcases from Baltimore - */ public class ValidationTests { private static SignatureValidator validator; @@ -61,25 +57,14 @@ private final static String STYLESHEET_B64 = "http://www.w3.org/Signature/2002/04/xml-stylesheet.b64"; - private final static String[] FILES = { - "signature-enveloped-dsa.xml", - "signature-enveloping-b64-dsa.xml", - "signature-enveloping-dsa.xml", - "signature-enveloping-rsa.xml", - "signature-enveloping-hmac-sha1.xml", - "signature-external-dsa.xml", - "signature-external-b64-dsa.xml", - "signature-retrievalmethod-rawx509crt.xml", - "signature-keyname.xml", - "signature-x509-crt-crl.xml", - "signature-x509-crt.xml", - "signature-x509-is.xml", - "signature-x509-ski.xml", - "signature-x509-sn.xml", -// "signature.xml", - "exc-signature.xml", - "sign-spec.xml" - }; + static class Test { + String file; + KeySelector ks; + Test(String file, KeySelector ks) { + this.file = file; + this.ks = ks; + } + } static KeySelector skks; static { @@ -98,26 +83,34 @@ private final static KeySelector RXKS = new KeySelectors.RawX509KeySelector(); private final static KeySelector XKS = null; - private final static KeySelector[] KEY_SELECTORS = { - KVKS, - KVKS, - KVKS, - KVKS, - SKKS, - KVKS, - KVKS, - CKS, - CKS, - RXKS, - RXKS, - CKS, - CKS, - CKS, -// XKS, - KVKS, - RXKS + private static URIDereferencer httpUd = null; + + private final static Test[] VALID_TESTS = { + new Test("signature-enveloped-dsa.xml", KVKS), + new Test("signature-enveloping-b64-dsa.xml", KVKS), + new Test("signature-enveloping-dsa.xml", KVKS), + new Test("signature-enveloping-rsa.xml", KVKS), + new Test("signature-enveloping-hmac-sha1.xml", SKKS), + new Test("signature-external-dsa.xml", KVKS), + new Test("signature-external-b64-dsa.xml", KVKS), + new Test("signature-retrievalmethod-rawx509crt.xml", CKS), + new Test("signature-keyname.xml", CKS), + new Test("signature-x509-crt-crl.xml", RXKS), + new Test("signature-x509-crt.xml", RXKS), + new Test("signature-x509-is.xml", CKS), + new Test("signature-x509-ski.xml", CKS), + new Test("signature-x509-sn.xml", CKS), + new Test("signature.xml", XKS), + new Test("exc-signature.xml", KVKS), + new Test("sign-spec.xml", RXKS), + new Test("xmldsig-xfilter2.xml", KVKS) }; - private static URIDereferencer httpUd = null; + + private final static Test[] INVALID_TESTS = { + new Test("signature-enveloping-hmac-sha1-40.xml", SKKS), + new Test("signature-enveloping-hmac-sha1-trunclen-0-attack.xml", SKKS), + new Test("signature-enveloping-hmac-sha1-trunclen-8-attack.xml", SKKS) + }; public static void main(String args[]) throws Exception { httpUd = new HttpURIDereferencer(); @@ -125,9 +118,9 @@ validator = new SignatureValidator(new File(DATA_DIR)); boolean atLeastOneFailed = false; - for (int i=0; i < FILES.length; i++) { - System.out.println("Validating " + FILES[i]); - if (test_signature(FILES[i], KEY_SELECTORS[i])) { + for (Test test : VALID_TESTS) { + System.out.println("Validating " + test.file); + if (test_signature(test)) { System.out.println("PASSED"); } else { System.out.println("FAILED"); @@ -136,41 +129,23 @@ } // test with reference caching enabled System.out.println("Validating sign-spec.xml with caching enabled"); - if (test_signature("sign-spec.xml", RXKS, true)) { + if (test_signature(new Test("sign-spec.xml", RXKS), true)) { System.out.println("PASSED"); } else { System.out.println("FAILED"); atLeastOneFailed = true; } - System.out.println("Validating signature-enveloping-hmac-sha1-40.xml"); - try { - test_signature("signature-enveloping-hmac-sha1-40.xml", SKKS, false); - System.out.println("FAILED"); - atLeastOneFailed = true; - } catch (XMLSignatureException xse) { - System.out.println(xse.getMessage()); - System.out.println("PASSED"); - } - - System.out.println("Validating signature-enveloping-hmac-sha1-trunclen-0-attack.xml"); - try { - test_signature("signature-enveloping-hmac-sha1-trunclen-0-attack.xml", SKKS, false); - System.out.println("FAILED"); - atLeastOneFailed = true; - } catch (XMLSignatureException xse) { - System.out.println(xse.getMessage()); - System.out.println("PASSED"); - } - - System.out.println("Validating signature-enveloping-hmac-sha1-trunclen-8-attack.xml"); - try { - test_signature("signature-enveloping-hmac-sha1-trunclen-8-attack.xml", SKKS, false); - System.out.println("FAILED"); - atLeastOneFailed = true; - } catch (XMLSignatureException xse) { - System.out.println(xse.getMessage()); - System.out.println("PASSED"); + for (Test test : INVALID_TESTS) { + System.out.println("Validating " + test.file); + try { + test_signature(test); + System.out.println("FAILED"); + atLeastOneFailed = true; + } catch (XMLSignatureException xse) { + System.out.println(xse.getMessage()); + System.out.println("PASSED"); + } } if (atLeastOneFailed) { @@ -179,20 +154,21 @@ } } - public static boolean test_signature(String file, KeySelector ks) - throws Exception { - return test_signature(file, ks, false); + public static boolean test_signature(Test test) throws Exception { + return test_signature(test, false); } - public static boolean test_signature(String file, KeySelector ks, - boolean cache) throws Exception { - if (ks == null) { + public static boolean test_signature(Test test, boolean cache) + throws Exception + { + if (test.ks == null) { KeyStore keystore = KeyStore.getInstance("JKS"); - keystore.load - (new FileInputStream(KEYSTORE), "changeit".toCharArray()); - ks = new X509KeySelector(keystore, false); + try (FileInputStream fis = new FileInputStream(KEYSTORE)) { + keystore.load(fis, "changeit".toCharArray()); + test.ks = new X509KeySelector(keystore, false); + } } - return validator.validate(file, ks, httpUd, cache); + return validator.validate(test.file, test.ks, httpUd, cache); } /** diff -r b1f9f8d4806b -r a657f8ba55fc jdk/test/javax/xml/crypto/dsig/X509KeySelector.java --- a/jdk/test/javax/xml/crypto/dsig/X509KeySelector.java Wed Jan 18 11:00:20 2012 -0800 +++ b/jdk/test/javax/xml/crypto/dsig/X509KeySelector.java Mon Jan 23 12:17:04 2012 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -205,9 +205,9 @@ */ private KeySelectorResult keyStoreSelect(CertSelector cs) throws KeyStoreException { - Enumeration aliases = ks.aliases(); + Enumeration aliases = ks.aliases(); while (aliases.hasMoreElements()) { - String alias = (String) aliases.nextElement(); + String alias = aliases.nextElement(); Certificate cert = ks.getCertificate(alias); if (cert != null && cs.match(cert)) { return new SimpleKeySelectorResult(cert.getPublicKey()); @@ -301,7 +301,7 @@ } catch (IOException ioe) { throw new KeySelectorException(ioe); } - Collection certs = new ArrayList(); + Collection certs = new ArrayList<>(); Iterator xi = xd.getContent().iterator(); while (xi.hasNext()) { @@ -345,7 +345,7 @@ System.arraycopy(ski, 0, encodedSki, 2, ski.length); subjectcs.setSubjectKeyIdentifier(encodedSki); } else if (o instanceof X509Certificate) { - certs.add((X509Certificate) o); + certs.add((X509Certificate)o); // check X509CRL // not supported: should use CertPath API } else { @@ -359,9 +359,7 @@ } if (!certs.isEmpty() && !trusted) { // try to find public key in certs in X509Data - Iterator i = certs.iterator(); - while (i.hasNext()) { - X509Certificate cert = (X509Certificate) i.next(); + for (X509Certificate cert : certs) { if (subjectcs.match(cert)) { return new SimpleKeySelectorResult(cert.getPublicKey()); } diff -r b1f9f8d4806b -r a657f8ba55fc jdk/test/javax/xml/crypto/dsig/data/xmldsig-xfilter2.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/crypto/dsig/data/xmldsig-xfilter2.xml Mon Jan 23 12:17:04 2012 -0500 @@ -0,0 +1,7 @@ + //FooBar //NotToBeSigned //ReallyToBeSigned 6S7pEM13ZCDvVUbP9XB8iRWFbAI= / 2jmj7l5rSw0yVb/vlWAYkK/YBwk=cJBwfPGWSI9CiuFinTvWJLbF8bGVK5SRB/N/NjCM5IMxakBjra+KSg==

/X9TgR11EilS30qcLuzk5/YRt1I870QAwx4/gLZRJmlFXUAiUftZPY1Y+r/F9bow9subVWzXgTuA +HTRv8mZgt2uZUKWkn5/oBHsQIsJPu6nX/rfGG/g7V+fGqKYVDwT7g/bTxR7DAjVUE1oWkTL2dfOu +K2HXKu/yIgMZndFIAcc=

l2BQjxUjC8yykrmCouuEC/BYHPU=9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3 +zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKL +Zl6Ae1UlZAFMO/7PSSo=5LRac3QkDCDOPaeNF5dJQ2r0hgIWZomZV7Z9pHrRqMoepJD5xnJpJY7aA4eUSS+AHS1qOm5I6VTZ +68hsOdPZCDFF/DiR38BzTxi4ZD0PhtmOjBh32lSNG1nhEq6e9RsyzhUw5FVYHAPnCx2bX4/8Rz8i +EMuG0IcCiAbbzsCfGBw=
\ No newline at end of file