Using javax.xml.crypto.dsig, how do I unmarshal and validate an XMLSignature without specifying the public key? The public key appears to be in the signed xml, but I can't figure out a way to get it.
DOMValidateContext valContext = new DOMValidateContext(key,signatureNode);
XMLSignature signature = fac.unmarshalXMLSignature(valContext);
boolean coreValidity = signature.validate(valContext);
As far as I can tell it's necessary to pass a KeySelector instead of a Key to the DOMValidateContext. However, I can't figure out how to implement a KeySelector.
Here is the only example I've found about how to implement a KeySelector: http://download.oracle.com/javase/6/docs/technotes/guides/security/xmldsig/XMLDigitalSignature.html
Unfortunately it doesn't work. In that implementation it does the following but always fails because there are no KeyValue elements (it appears that instead of KeyValue elements they are org.jcp.xml.dsig.internal.dom.DOMX509Data elements which don't have a way to ge the key from them).
List list = keyInfo.getContent();
for (int i = 0; i < list.size(); i++) {
XMLStructure xs = (XMLStructure) list.get(i);
if(xs instanceof KeyValue) {
PublicKey pk = null;
try {
pk = ((KeyValue) xs).getPublicKey();
} catch (KeyException ke) {
throw new KeySelectorException(ke);
}
// make sure algorithm is compatible with method
if (algEquals(sm.getAlgorithm(), pk.getAlgorithm())) {
return new SimpleKeySelectorResult(pk);
}
}
}
throw new KeySelectorException("No KeyValue element found!");
So, is there a way to do this? I want to be able to validate the signature of an xml file without having to have the public key. I just want to get the public key from the xml.