7131084: XMLDSig XPathFilter2Transform regression involving intersect filter
Reviewed-by: xuelei
--- 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<Node> convertNodeListToSet(List<NodeList> l){
- Set<Node> result=new HashSet<Node>();
-
- 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<Node> unionNodes, Set<Node> substractNodes,
- Set<Node> 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<NodeList> unionNodes, List<NodeList> substractNodes,
+ List<NodeList> intersectNodes) {
+ hasUnionFilter=!unionNodes.isEmpty();
+ this.unionNodes=convertNodeListToSet(unionNodes);
+ hasSubstractFilter=!substractNodes.isEmpty();
+ this.substractNodes=convertNodeListToSet(substractNodes);
+ hasIntersectFilter=!intersectNodes.isEmpty();
+ this.intersectNodes=convertNodeListToSet(intersectNodes);
}
Set<Node> unionNodes;
Set<Node> 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<Node> nodeList ) {
+ if (nodeList.isEmpty()) {
+ return false;
+ }
if (nodeList.contains(currentNode)) {
return true;
}
@@ -302,4 +293,17 @@
static boolean inList(Node currentNode, Set<Node> nodeList ) {
return nodeList.contains(currentNode);
}
+
+ private static Set<Node> convertNodeListToSet(List<NodeList> l){
+ Set<Node> result=new HashSet<Node>();
+
+ 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;
+ }
}
--- 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<X509Certificate> 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<X509Certificate>();
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<X509Certificate> match(int matchType, Object value,
+ Vector<X509Certificate> pool) {
+ Vector<X509Certificate> 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<X509Certificate> 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<X509Certificate> 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);
--- 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);
}
/**
--- 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<String> 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<X509Certificate> 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());
}
--- /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 @@
+<?xml version="1.0" encoding="UTF-8"?><Document><ToBeSigned><!-- comment --><Data/><NotToBeSigned><ReallyToBeSigned><!-- comment --><Data/></ReallyToBeSigned></NotToBeSigned></ToBeSigned><ToBeSigned><Data/><NotToBeSigned><Data/></NotToBeSigned></ToBeSigned><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2002/06/xmldsig-filter2"><XPath xmlns="http://www.w3.org/2002/06/xmldsig-filter2" Filter="intersect"> //FooBar </XPath><XPath xmlns="http://www.w3.org/2002/06/xmldsig-filter2" Filter="subtract"> //NotToBeSigned </XPath><XPath xmlns="http://www.w3.org/2002/06/xmldsig-filter2" Filter="union"> //ReallyToBeSigned </XPath></Transform></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><DigestValue>6S7pEM13ZCDvVUbP9XB8iRWFbAI=</DigestValue></Reference><Reference URI="#signature-value"><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><Transform Algorithm="http://www.w3.org/2002/06/xmldsig-filter2"><XPath xmlns="http://www.w3.org/2002/06/xmldsig-filter2" Filter="union"> / </XPath></Transform></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><DigestValue>2jmj7l5rSw0yVb/vlWAYkK/YBwk=</DigestValue></Reference></SignedInfo><SignatureValue Id="signature-value">cJBwfPGWSI9CiuFinTvWJLbF8bGVK5SRB/N/NjCM5IMxakBjra+KSg==</SignatureValue><KeyInfo><KeyValue><DSAKeyValue><P>/X9TgR11EilS30qcLuzk5/YRt1I870QAwx4/gLZRJmlFXUAiUftZPY1Y+r/F9bow9subVWzXgTuA
+HTRv8mZgt2uZUKWkn5/oBHsQIsJPu6nX/rfGG/g7V+fGqKYVDwT7g/bTxR7DAjVUE1oWkTL2dfOu
+K2HXKu/yIgMZndFIAcc=</P><Q>l2BQjxUjC8yykrmCouuEC/BYHPU=</Q><G>9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3
+zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKL
+Zl6Ae1UlZAFMO/7PSSo=</G><Y>5LRac3QkDCDOPaeNF5dJQ2r0hgIWZomZV7Z9pHrRqMoepJD5xnJpJY7aA4eUSS+AHS1qOm5I6VTZ
+68hsOdPZCDFF/DiR38BzTxi4ZD0PhtmOjBh32lSNG1nhEq6e9RsyzhUw5FVYHAPnCx2bX4/8Rz8i
+EMuG0IcCiAbbzsCfGBw=</Y></DSAKeyValue></KeyValue></KeyInfo></Signature></Document>
\ No newline at end of file