URIReferenceException
Modified jwsdp-2.0 sample GenDetached to accept command line argument for URI to be signed, rather than a hardwired URI, see below.
Sad to say, the signature.sign(signContext) is triggering an XMLSignatureException / URIReferenceException / NullPointerException. The exception is apparently occurring in org.jcp.xml.dsig.internal.dom.DOMReference.dereference.
Can anyone suggest why this is happening? Thanks.
=========================
[echo] java GenDetached foo.txt detachedSignature.xml
[java] file:/C:/Sun/jwsdp-2.0/xmldsig/samples/gendetached/foo.txt
[java] Exception in thread "main" javax.xml.crypto.dsig.XMLSignatureException: javax.xml.crypto.URIReferenceException: java.lang.NullPointerException
[java] at org.jcp.xml.dsig.internal.dom.DOMReference.dereference(DOMReference.java:352)
[java] at org.jcp.xml.dsig.internal.dom.DOMReference.digest(DOMReference.java:278)
[java] at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.digestReference(DOMXMLSignature.java:441)
[java] at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.sign(DOMXMLSignature.java:337)
[java] at GenDetached.main(GenDetached.java:130)
[java] Caused by: javax.xml.crypto.URIReferenceException: java.lang.NullPointerException
[java] at org.jcp.xml.dsig.internal.dom.DOMURIDereferencer.dereference(DOMURIDereferencer.java:84)
[java] at org.jcp.xml.dsig.internal.dom.DOMReference.dereference(DOMReference.java:344)
[java] ... 4 more
[java] Caused by: java.lang.NullPointerException
[java] at com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverDirectHTTP.engineCanResolve(ResolverDirectHTTP.java:265)
[java] at com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver.canResolve(ResourceResolver.java:295)
[java] at com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver.getInstance(ResourceResolver.java:111)
[java] at org.jcp.xml.dsig.internal.dom.DOMURIDereferencer.dereference(DOMURIDereferencer.java:75)
[java] ... 5 more
[java] javax.xml.crypto.URIReferenceException: java.lang.NullPointerException
[java] at org.jcp.xml.dsig.internal.dom.DOMURIDereferencer.dereference(DOMURIDereferencer.java:84)
[java] at org.jcp.xml.dsig.internal.dom.DOMReference.dereference(DOMReference.java:344)
[java] at org.jcp.xml.dsig.internal.dom.DOMReference.digest(DOMReference.java:278)
[java] at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.digestReference(DOMXMLSignature.java:441)
[java] at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.sign(DOMXMLSignature.java:337)
[java] at GenDetached.main(GenDetached.java:130)
[java] Caused by: java.lang.NullPointerException
[java] at com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverDirectHTTP.engineCanResolve(ResolverDirectHTTP.java:265)
[java] at com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver.canResolve(ResourceResolver.java:295)
[java] at com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver.getInstance(ResourceResolver.java:111)
[java] at org.jcp.xml.dsig.internal.dom.DOMURIDereferencer.dereference(DOMURIDereferencer.java:75)
[java] ... 5 more
=========================
public class GenDetached {
//
// Synopsis: java GenDetached [output]
//
// where output is the name of the file that will contain the detached
// signature. If not specified, standard output is used.
//
public static void main(String[] args) throws Exception {
if (args.length < 1 || args.length > 2)
{
System.err.println("Usage GenDetached <input document> [output XML]");
System.exit(1);
}
// First, create a DOM XMLSignatureFactory that will be used to
// generate the XMLSignature and marshal it to DOM.
String providerName = System.getProperty
("jsr105Provider", "org.jcp.xml.dsig.internal.dom.XMLDSigRI");
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM",
(Provider) Class.forName(providerName).newInstance());
// Create a Reference to an external URI that will be digested
// using the SHA1 digest algorithm
Reference ref = fac.newReference(
//"http://www.w3.org/TR/xml-stylesheet",
new File(args[0]).toURI().toString(),
fac.newDigestMethod(DigestMethod.SHA1, null));
System.out.println(new File(args[0]).toURI().toString());
// Create the SignedInfo
SignedInfo si = fac.newSignedInfo(
fac.newCanonicalizationMethod
(CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
(C14NMethodParameterSpec) null),
fac.newSignatureMethod(SignatureMethod.DSA_SHA1, null),
Collections.singletonList(ref));
// Create a DSA KeyPair
KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
kpg.initialize(512);
KeyPair kp = kpg.generateKeyPair();
// Create a KeyValue containing the DSA PublicKey that was generated
KeyInfoFactory kif = fac.getKeyInfoFactory();
KeyValue kv = kif.newKeyValue(kp.getPublic());
// Create a KeyInfo and add the KeyValue to it
KeyInfo ki = kif.newKeyInfo(Collections.singletonList(kv));
// Create the XMLSignature (but don't sign it yet)
XMLSignature signature = fac.newXMLSignature(si, ki);
// Create the Document that will hold the resulting XMLSignature
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true); // must be set
Document doc = dbf.newDocumentBuilder().newDocument();
// Create a DOMSignContext and set the signing Key to the DSA
// PrivateKey and specify where the XMLSignature should be inserted
// in the target document (in this case, the document root)
DOMSignContext signContext = new DOMSignContext(kp.getPrivate(), doc);
// Marshal, generate (and sign) the detached XMLSignature. The DOM
// Document will contain the XML Signature if this method returns
// successfully.
signature.sign(signContext);
// output the resulting document
OutputStream os;
if (args.length > 1) {
os = new FileOutputStream(args[1]);
} else {
os = System.out;
}
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
trans.transform(new DOMSource(doc), new StreamResult(os));
}
}

