提交 ca962ac7 编写于 作者: M mullan

7131084: XMLDSig XPathFilter2Transform regression involving intersect filter

Reviewed-by: xuelei
上级 2790852e
......@@ -148,8 +148,8 @@ public class TransformXPath2Filter extends TransformSpi {
}
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 @@ public class TransformXPath2Filter extends TransformSpi {
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 @@ class XPath2NodeFilter implements NodeFilter {
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 @@ class XPath2NodeFilter implements NodeFilter {
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 @@ class XPath2NodeFilter implements NodeFilter {
}
}
if (result!=-1){
if (hasIntersectNodes) {
if (hasIntersectFilter) {
if ((inIntersect==-1) || (level<=inIntersect)) {
if (!inList(n, intersectNodes)) {
inIntersect=-1;
......@@ -260,7 +248,7 @@ class XPath2NodeFilter implements NodeFilter {
inUnion=-1;
if (result==1)
return 1;
if (hasUnionNodes) {
if (hasUnionFilter) {
if ((inUnion==-1) && inList(n, unionNodes)) {
inUnion=level;
}
......@@ -280,6 +268,9 @@ class XPath2NodeFilter implements NodeFilter {
* @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 @@ class XPath2NodeFilter implements NodeFilter {
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;
}
}
/*
* 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 @@ class KeySelectors {
}
public byte[] getEncoded() {
return (byte[]) bytes.clone();
return bytes.clone();
}
};
}
......@@ -196,9 +198,9 @@ class KeySelectors {
* 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 @@ class KeySelectors {
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 @@ class KeySelectors {
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 @@ class KeySelectors {
((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 @@ class KeySelectors {
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 @@ class KeySelectors {
} 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 @@ class KeySelectors {
((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);
......
/*
* 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.XMLCryptoContext;
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 @@ public class ValidationTests {
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,36 +83,44 @@ public class ValidationTests {
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 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();
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 @@ public class ValidationTests {
}
// 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 class ValidationTests {
}
}
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);
}
/**
......
/*
* 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 @@ class X509KeySelector extends KeySelector {
*/
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 @@ class X509KeySelector extends KeySelector {
} 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 @@ class X509KeySelector extends KeySelector {
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 @@ class X509KeySelector extends KeySelector {
}
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());
}
......
<?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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册