Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-7094155

JSR105 code throws javax.xml.crypto.URIReferenceException when running into Java 7 VM

XMLWordPrintable

    • 7
    • b14
    • x86
    • windows_7
    • Verified

        FULL PRODUCT VERSION :
        java version "1.7.0"
        Java(TM) SE Runtime Environment (build 1.7.0-b147)

        ADDITIONAL OS VERSION INFORMATION :
        Microsoft Windows [version 6.1.7601]

        A DESCRIPTION OF THE PROBLEM :
        JSR105 code throws javax.xml.crypto.URIReference when running into Java 7 VM. A referenced node is not found.

        REGRESSION. Last worked in version 6u26

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        See attached source code.

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        XML signature should be produced.
        ACTUAL -
        a javax.xml.crypto.dsig.XMLSignatureException is thrown with Java 7.

        XML signature is produced with Java 1.6.

        ERROR MESSAGES/STACK TRACES THAT OCCUR :

        javax.xml.crypto.dsig.XMLSignatureException: javax.xml.crypto.URIReferenceException: java.lang.NullPointerException
        at org.jcp.xml.dsig.internal.dom.DOMReference.dereference(Unknown Source)
        at org.jcp.xml.dsig.internal.dom.DOMReference.digest(Unknown Source)
        at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.digestReference(Unknown Source)
        at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.sign(Unknown Source)
        at Main.main(Main.java:332)
        Caused by: javax.xml.crypto.URIReferenceException: java.lang.NullPointerException
        at org.jcp.xml.dsig.internal.dom.DOMURIDereferencer.dereference(Unknown Source)
        ... 5 more
        Caused by: java.lang.NullPointerException
        at com.sun.org.apache.xml.internal.security.utils.IdResolver.isElement(Unknown Source)
        at com.sun.org.apache.xml.internal.security.utils.IdResolver.getEl(Unknown Source)
        at com.sun.org.apache.xml.internal.security.utils.IdResolver.getElementBySearching(Unknown Source)
        at com.sun.org.apache.xml.internal.security.utils.IdResolver.getElementById(Unknown Source)
        at com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverFragment.engineResolve(Unknown Source)
        at com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver.resolve(Unknown Source)
        ... 6 more
        javax.xml.crypto.URIReferenceException: java.lang.NullPointerException
        at org.jcp.xml.dsig.internal.dom.DOMURIDereferencer.dereference(Unknown Source)
        at org.jcp.xml.dsig.internal.dom.DOMReference.dereference(Unknown Source)
        at org.jcp.xml.dsig.internal.dom.DOMReference.digest(Unknown Source)
        at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.digestReference(Unknown Source)
        at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.sign(Unknown Source)
        at Main.main(Main.java:332)
        Caused by: java.lang.NullPointerException
        at com.sun.org.apache.xml.internal.security.utils.IdResolver.isElement(Unknown Source)
        at com.sun.org.apache.xml.internal.security.utils.IdResolver.getEl(Unknown Source)
        at com.sun.org.apache.xml.internal.security.utils.IdResolver.getElementBySearching(Unknown Source)
        at com.sun.org.apache.xml.internal.security.utils.IdResolver.getElementById(Unknown Source)
        at com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverFragment.engineResolve(Unknown Source)
        at com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver.resolve(Unknown Source)
        ... 6 more

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        import java.io.ByteArrayInputStream;
        import java.io.File;
        import java.io.FileOutputStream;
        import java.io.InputStream;
        import java.io.OutputStream;
        import java.security.KeyStore;
        import java.security.PrivateKey;
        import java.security.Security;
        import java.security.cert.X509Certificate;
        import java.text.SimpleDateFormat;
        import java.util.ArrayList;
        import java.util.Collections;
        import java.util.Date;
        import java.util.Enumeration;
        import java.util.Iterator;
        import java.util.List;

        import javax.xml.crypto.Data;
        import javax.xml.crypto.NodeSetData;
        import javax.xml.crypto.URIDereferencer;
        import javax.xml.crypto.URIReference;
        import javax.xml.crypto.URIReferenceException;
        import javax.xml.crypto.XMLCryptoContext;
        import javax.xml.crypto.XMLStructure;
        import javax.xml.crypto.dom.DOMStructure;
        import javax.xml.crypto.dsig.CanonicalizationMethod;
        import javax.xml.crypto.dsig.Reference;
        import javax.xml.crypto.dsig.SignatureMethod;
        import javax.xml.crypto.dsig.SignedInfo;
        import javax.xml.crypto.dsig.XMLObject;
        import javax.xml.crypto.dsig.XMLSignature;
        import javax.xml.crypto.dsig.XMLSignatureFactory;
        import javax.xml.crypto.dsig.dom.DOMSignContext;
        import javax.xml.crypto.dsig.keyinfo.KeyInfo;
        import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
        import javax.xml.crypto.dsig.keyinfo.X509Data;
        import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
        import javax.xml.parsers.DocumentBuilderFactory;
        import javax.xml.transform.OutputKeys;
        import javax.xml.transform.Transformer;
        import javax.xml.transform.TransformerFactory;
        import javax.xml.transform.dom.DOMSource;
        import javax.xml.transform.stream.StreamResult;

        import org.jcp.xml.dsig.internal.dom.ApacheNodeSetData;
        import org.w3c.dom.Document;
        import org.w3c.dom.Element;
        import org.w3c.dom.Node;
        import org.w3c.dom.Text;

        import com.sun.org.apache.xml.internal.security.utils.Base64;


        public class JSR105Test {

        private static PrivateKey privateKey;
        private static java.security.cert.Certificate certificate = null;
        private static Element data;
        private static Element signedProperties;

        /**
        * @param args
        */
        public static void main(String[] args) {

        try {

        XMLSignatureFactory xmlSignatureFactory = XMLSignatureFactory.getInstance("DOM");
        String signatureId = "MySignatureId";

        // Retrieve a certificate object
        retrieveCertificateAndPrivateKey();
        if (null == certificate || null == privateKey) {
        throw new Exception("no certificate");
        }

        Document document = createDocument(null);
        data = createElement(document, "DummyData", null, null);
        CanonicalizationMethod canonicalizationMethod = null;

        List referencesList = new ArrayList();
        List objectsList = new ArrayList();

        String signedPropertiesId = signatureId + "_SignedProperties";

        // xad:QualifyingProperties
        Element qualifyingProperties = createElement(document, "QualifyingProperties", "xad", "http://uri.etsi.org/01903/v1.3.2#");
        qualifyingProperties.setAttributeNS(null, "Target", "#"+signatureId);
        qualifyingProperties.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:"+"xad", "http://uri.etsi.org/01903/v1.3.2#");

        // xad:SignedProperties
        signedProperties = createElement(document, "SignedProperties", "xad", "http://uri.etsi.org/01903/v1.3.2#");
        signedProperties.setAttributeNS(null, "Id", signedPropertiesId);
        qualifyingProperties.appendChild(signedProperties);



        // xad:UnsignedProperties
        Element unsignedProperties = createElement(document, "UnsignedProperties", "xad", "http://uri.etsi.org/01903/v1.3.2#");
        qualifyingProperties.appendChild(unsignedProperties);
        DOMStructure qualifyingPropertiesStructure = new DOMStructure(qualifyingProperties);
        XMLObject xadesObject = xmlSignatureFactory.newXMLObject(Collections.singletonList(qualifyingPropertiesStructure), null, null, null);
        objectsList.add(xadesObject);

        // xad:SignedSignatureProperties
        Element signedSignatureProperties = createElement(document, "SignedSignatureProperties", "xad", "http://uri.etsi.org/01903/v1.3.2#");
        signedProperties.appendChild(signedSignatureProperties);

        // xad:SigningTime, yyyy-MM-dd'T'HH:mm:ssZ
        Element signingTime = createElement(document, "SigningTime", "xad", "http://uri.etsi.org/01903/v1.3.2#");
        Text signingTimeText = document.createTextNode(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").format(new Date()));
        signingTime.appendChild(signingTimeText);
        signedSignatureProperties.appendChild(signingTime);

        // xad:SigningCertificate
        Element signingCertificateElement = createElement(document, "SigningCertificate", "xad", "http://uri.etsi.org/01903/v1.3.2#");
        signedSignatureProperties.appendChild(signingCertificateElement);
        Element cert = createElement(document, "Cert", "xad", "http://uri.etsi.org/01903/v1.3.2#");
        signingCertificateElement.appendChild(cert);
        Element certDigest = createElement(document, "CertDigest", "xad", "http://uri.etsi.org/01903/v1.3.2#");
        cert.appendChild(certDigest);
        Element issuerSerial = createElement(document, "IssuerSerial", "xad", "http://uri.etsi.org/01903/v1.3.2#");
        cert.appendChild(issuerSerial);
        Element digestMethodElement = createElement(document, "DigestMethod", "ds", "http://www.w3.org/2000/09/xmldsig#");
        digestMethodElement.setAttribute("Algorithm", "http://www.w3.org/2000/09/xmldsig#sha1");
        Element digestValueElement = createElement(document, "DigestValue", "ds", "http://www.w3.org/2000/09/xmldsig#");
        try {
        byte[] hashBytes = Util.digestStream(new ByteArrayInputStream(certificate.getEncoded()));
        } catch (Exception e) {
        e.printStackTrace();
        throw new Exception("unable to compute certificate digest");
        }
        Text digestValueText = document.createTextNode(new String(Base64.encode(hashBytes));
        digestValueElement.appendChild(digestValueText);
        certDigest.appendChild(digestMethodElement);
        certDigest.appendChild(digestValueElement);
        Element x509IssuerName = createElement(document, "X509IssuerName", "ds", "http://www.w3.org/2000/09/xmldsig#");
        issuerSerial.appendChild(x509IssuerName);
        Text x509IssuerNameText = document.createTextNode(certificate.getSubjectDistinguishedName());
        x509IssuerName.appendChild(x509IssuerNameText);
        Element x509IssuerSerialNumber = createElement(document, "X509SerialNumber", "ds", "http://www.w3.org/2000/09/xmldsig#");
        issuerSerial.appendChild(x509IssuerSerialNumber);
        Text x509IssuerSerialNumberText = document.createTextNode(certificate.getSerialNumber().toString());
        x509IssuerSerialNumber.appendChild(x509IssuerSerialNumberText);

        // xad:SignaturePolicyIdentifier
        Element signaturePolicyIdentifier = createElement(document, "SignaturePolicyIdentifier", "xad", "http://uri.etsi.org/01903/v1.3.2#");
        signedSignatureProperties.appendChild(signaturePolicyIdentifier);

        try {
        C14NMethodParameterSpec c14nSpec = null;
        canonicalizationMethod = xmlSignatureFactory.newCanonicalizationMethod("http://www.w3.org/2001/10/xml-exc-c14n#", c14nSpec);
        } catch (Exception e) {
        e.printStackTrace();
        throw new Exception("a cryptographic algorithm seems unsupported");
        }

        String xadesReferenceNodeId = signedPropertiesId + "_Reference";
        Reference xadesReference = xmlSignatureFactory.newReference("#"+signedPropertiesId, xmlSignatureFactory.newDigestMethod("http://www.w3.org/2000/09/xmldsig#sha1", null), Collections.singletonList(canonicalizationMethod), "http://uri.etsi.org/01903/#SignedProperties", xadesReferenceNodeId);
        referencesList.add(xadesReference);

        //
        // Prepare the data
        //
        XMLStructure dataContent = new DOMStructure(data);

        //
        // Prepare the transforms
        //
        SignatureMethod signatureMethod;
        C14NMethodParameterSpec c14nSpec = null;
        ArrayList standardTransformList = new ArrayList();

        try {
        signatureMethod = xmlSignatureFactory.newSignatureMethod("http://www.w3.org/2000/09/xmldsig#rsa-sha1", null);
        canonicalizationMethod = xmlSignatureFactory.newCanonicalizationMethod("http://www.w3.org/TR/2001/REC-xml-c14n-20010315", c14nSpec);
        } catch (Exception e) {
        e.printStackTrace();
        throw new Exception("a cryptographic algorithm seems unsupported");
        }

        standardTransformList.add(canonicalizationMethod); // always c14n

        //
        // Build the data reference & object
        //
        int currentObjectCount = 0;
        String dataObjectNodeId = "";
        String dataReferenceUri = dataObjectNodeId;
        String dataReferenceType = null;
        String dataObjectMimeType = "text/xml";

        // use the signature Id for <ds:object>
        dataObjectNodeId = signatureId + "_D" + currentObjectCount++;
        dataReferenceUri = "#"+dataObjectNodeId;
        String dataReferenceNodeId = dataObjectNodeId + "_Reference";

        //
        // Add the data reference & object
        //
        Reference dataReference = xmlSignatureFactory.newReference(dataReferenceUri, xmlSignatureFactory.newDigestMethod("http://www.w3.org/2000/09/xmldsig#sha1", null), standardTransformList, dataReferenceType, dataReferenceNodeId);
        referencesList.add(0, dataReference);

        XMLObject dataObject = xmlSignatureFactory.newXMLObject(Collections.singletonList(dataContent), dataObjectNodeId, dataObjectMimeType, null);
        objectsList.add(0, dataObject);

        // SignedInfo creation from references
        try {
        canonicalizationMethod = xmlSignatureFactory.newCanonicalizationMethod("http://www.w3.org/2001/10/xml-exc-c14n#", c14nSpec);
        } catch (Exception e) {
        e.printStackTrace();
        throw new Exception("a cryptographic algorithm seems unsupported");
        }
        SignedInfo signedInfo = xmlSignatureFactory.newSignedInfo(canonicalizationMethod, signatureMethod, referencesList);

        // KeyInfo creation
        KeyInfoFactory keyInfoFactory = xmlSignatureFactory.getKeyInfoFactory();
        List x509Content = new ArrayList();
        x509Content.add((X509Certificate)certificate);
        X509Data x509Data = keyInfoFactory.newX509Data(x509Content);

        KeyInfo keyInfo = keyInfoFactory.newKeyInfo(Collections.singletonList(x509Data));

        // Compute signature
        XMLSignature signature = xmlSignatureFactory.newXMLSignature(signedInfo, keyInfo, objectsList, signatureId, signatureId+"_SV");
        DOMSignContext domSignContext = new DOMSignContext(privateKey, document);
        domSignContext.setDefaultNamespacePrefix("ds");

        try {
        signature.sign(domSignContext);
        }
        catch (Exception e) {
        e.printStackTrace();
        throw new Exception("signature failed !");
        }

        } catch (Exception e) {
        e.printStackTrace();
        }
        }

        /**
        * Retrieve a certificate
        */
        private static void retrieveCertificateAndPrivateKey() {
        // TODO Auto-generated method stub
        }

        /**
        * Element creation helper
        */
        protected static Element createElement(Document document, String elementName, String namespacePrefix, String namespaceURI) {
        String finalName = (null==namespacePrefix)?elementName:namespacePrefix+":"+elementName;
        return document.createElementNS(namespaceURI, finalName);
        }

        /**
        * Document creation helper
        * @throws Exception
        */
        protected static Document createDocument(InputStream data) throws Exception {
        Document document = null;
        try {
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        documentBuilderFactory.setNamespaceAware(true);
        if (null!=data) {
        document = documentBuilderFactory.newDocumentBuilder().parse(data);
        } else {
        document = documentBuilderFactory.newDocumentBuilder().newDocument();
        }
        } catch (Exception e) {
        throw new Exception("unable to create or parse the XML document");
        }
        return document;
        }
        }

        ---------- END SOURCE ----------

              mullan Sean Mullan
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: