Search in sources :

Example 1 with XMLSignContext

use of javax.xml.crypto.dsig.XMLSignContext in project poi by apache.

the class SignatureInfo method preSign.

/**
     * Helper method for adding informations before the signing.
     * Normally {@link #confirmSignature()} is sufficient to be used.
     */
@SuppressWarnings("unchecked")
public DigestInfo preSign(Document document, List<DigestInfo> digestInfos) throws XMLSignatureException, MarshalException {
    signatureConfig.init(false);
    // it's necessary to explicitly set the mdssi namespace, but the sign() method has no
    // normal way to interfere with, so we need to add the namespace under the hand ...
    EventTarget target = (EventTarget) document;
    EventListener creationListener = signatureConfig.getSignatureMarshalListener();
    if (creationListener != null) {
        if (creationListener instanceof SignatureMarshalListener) {
            ((SignatureMarshalListener) creationListener).setEventTarget(target);
        }
        SignatureMarshalListener.setListener(target, creationListener, true);
    }
    /*
         * Signature context construction.
         */
    XMLSignContext xmlSignContext = new DOMSignContext(signatureConfig.getKey(), document);
    URIDereferencer uriDereferencer = signatureConfig.getUriDereferencer();
    if (null != uriDereferencer) {
        xmlSignContext.setURIDereferencer(uriDereferencer);
    }
    for (Map.Entry<String, String> me : signatureConfig.getNamespacePrefixes().entrySet()) {
        xmlSignContext.putNamespacePrefix(me.getKey(), me.getValue());
    }
    xmlSignContext.setDefaultNamespacePrefix("");
    // signatureConfig.getNamespacePrefixes().get(XML_DIGSIG_NS));
    brokenJvmWorkaround(xmlSignContext);
    XMLSignatureFactory signatureFactory = signatureConfig.getSignatureFactory();
    /*
         * Add ds:References that come from signing client local files.
         */
    List<Reference> references = new ArrayList<Reference>();
    for (DigestInfo digestInfo : safe(digestInfos)) {
        byte[] documentDigestValue = digestInfo.digestValue;
        String uri = new File(digestInfo.description).getName();
        Reference reference = SignatureFacet.newReference(uri, null, null, null, documentDigestValue, signatureConfig);
        references.add(reference);
    }
    /*
         * Invoke the signature facets.
         */
    List<XMLObject> objects = new ArrayList<XMLObject>();
    for (SignatureFacet signatureFacet : signatureConfig.getSignatureFacets()) {
        LOG.log(POILogger.DEBUG, "invoking signature facet: " + signatureFacet.getClass().getSimpleName());
        signatureFacet.preSign(document, references, objects);
    }
    /*
         * ds:SignedInfo
         */
    SignedInfo signedInfo;
    try {
        SignatureMethod signatureMethod = signatureFactory.newSignatureMethod(signatureConfig.getSignatureMethodUri(), null);
        CanonicalizationMethod canonicalizationMethod = signatureFactory.newCanonicalizationMethod(signatureConfig.getCanonicalizationMethod(), (C14NMethodParameterSpec) null);
        signedInfo = signatureFactory.newSignedInfo(canonicalizationMethod, signatureMethod, references);
    } catch (GeneralSecurityException e) {
        throw new XMLSignatureException(e);
    }
    /*
         * JSR105 ds:Signature creation
         */
    String signatureValueId = signatureConfig.getPackageSignatureId() + "-signature-value";
    javax.xml.crypto.dsig.XMLSignature xmlSignature = signatureFactory.newXMLSignature(signedInfo, null, objects, signatureConfig.getPackageSignatureId(), signatureValueId);
    /*
         * ds:Signature Marshalling.
         */
    xmlSignature.sign(xmlSignContext);
    /*
         * Completion of undigested ds:References in the ds:Manifests.
         */
    for (XMLObject object : objects) {
        LOG.log(POILogger.DEBUG, "object java type: " + object.getClass().getName());
        List<XMLStructure> objectContentList = object.getContent();
        for (XMLStructure objectContent : objectContentList) {
            LOG.log(POILogger.DEBUG, "object content java type: " + objectContent.getClass().getName());
            if (!(objectContent instanceof Manifest))
                continue;
            Manifest manifest = (Manifest) objectContent;
            List<Reference> manifestReferences = manifest.getReferences();
            for (Reference manifestReference : manifestReferences) {
                if (manifestReference.getDigestValue() != null)
                    continue;
                DOMReference manifestDOMReference = (DOMReference) manifestReference;
                manifestDOMReference.digest(xmlSignContext);
            }
        }
    }
    /*
         * Completion of undigested ds:References.
         */
    List<Reference> signedInfoReferences = signedInfo.getReferences();
    for (Reference signedInfoReference : signedInfoReferences) {
        DOMReference domReference = (DOMReference) signedInfoReference;
        // ds:Reference with external digest value
        if (domReference.getDigestValue() != null)
            continue;
        domReference.digest(xmlSignContext);
    }
    /*
         * Calculation of XML signature digest value.
         */
    DOMSignedInfo domSignedInfo = (DOMSignedInfo) signedInfo;
    ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
    domSignedInfo.canonicalize(xmlSignContext, dataStream);
    byte[] octets = dataStream.toByteArray();
    /*
         * TODO: we could be using DigestOutputStream here to optimize memory
         * usage.
         */
    MessageDigest md = CryptoFunctions.getMessageDigest(signatureConfig.getDigestAlgo());
    byte[] digestValue = md.digest(octets);
    String description = signatureConfig.getSignatureDescription();
    return new DigestInfo(digestValue, signatureConfig.getDigestAlgo(), description);
}
Also used : ArrayList(java.util.ArrayList) XMLStructure(javax.xml.crypto.XMLStructure) URIDereferencer(javax.xml.crypto.URIDereferencer) XMLSignContext(javax.xml.crypto.dsig.XMLSignContext) EventListener(org.w3c.dom.events.EventListener) MessageDigest(java.security.MessageDigest) EventTarget(org.w3c.dom.events.EventTarget) XMLSignatureFactory(javax.xml.crypto.dsig.XMLSignatureFactory) DOMSignedInfo(org.apache.jcp.xml.dsig.internal.dom.DOMSignedInfo) DOMReference(org.apache.jcp.xml.dsig.internal.dom.DOMReference) Reference(javax.xml.crypto.dsig.Reference) GeneralSecurityException(java.security.GeneralSecurityException) CanonicalizationMethod(javax.xml.crypto.dsig.CanonicalizationMethod) XMLObject(javax.xml.crypto.dsig.XMLObject) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Manifest(javax.xml.crypto.dsig.Manifest) DOMReference(org.apache.jcp.xml.dsig.internal.dom.DOMReference) DOMSignedInfo(org.apache.jcp.xml.dsig.internal.dom.DOMSignedInfo) SignedInfo(javax.xml.crypto.dsig.SignedInfo) SignatureFacet(org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet) DOMSignContext(javax.xml.crypto.dsig.dom.DOMSignContext) SignatureMethod(javax.xml.crypto.dsig.SignatureMethod) Map(java.util.Map) HashMap(java.util.HashMap) File(java.io.File) XMLSignatureException(javax.xml.crypto.dsig.XMLSignatureException) XMLSignature(javax.xml.crypto.dsig.XMLSignature)

Example 2 with XMLSignContext

use of javax.xml.crypto.dsig.XMLSignContext in project testcases by coheigea.

the class SignatureJSR105EnvelopedTest method testSignatureUsingJSR105.

// Sign + Verify an XML Document using the JSR-105 API
@org.junit.Test
public void testSignatureUsingJSR105() throws Exception {
    // Read in plaintext document
    InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("plaintext.xml");
    DocumentBuilder builder = XMLUtils.createDocumentBuilder(false);
    Document document = builder.parse(sourceDocument);
    // Set up the Key
    KeyStore keyStore = KeyStore.getInstance("jks");
    keyStore.load(this.getClass().getClassLoader().getResource("clientstore.jks").openStream(), "cspass".toCharArray());
    Key key = keyStore.getKey("myclientkey", "ckpass".toCharArray());
    X509Certificate cert = (X509Certificate) keyStore.getCertificate("myclientkey");
    String signatureId = "_" + UUID.randomUUID().toString();
    String signaturePropertyId = "_" + UUID.randomUUID().toString();
    // Sign using DOM
    XMLSignatureFactory signatureFactory = XMLSignatureFactory.getInstance("DOM");
    CanonicalizationMethod c14nMethod = signatureFactory.newCanonicalizationMethod("http://www.w3.org/2001/10/xml-exc-c14n#", (C14NMethodParameterSpec) null);
    KeyInfoFactory keyInfoFactory = signatureFactory.getKeyInfoFactory();
    X509Data x509Data = keyInfoFactory.newX509Data(Collections.singletonList(cert));
    javax.xml.crypto.dsig.keyinfo.KeyInfo keyInfo = keyInfoFactory.newKeyInfo(Collections.singletonList(x509Data));
    SignatureMethod signatureMethod = signatureFactory.newSignatureMethod("http://www.w3.org/2000/09/xmldsig#rsa-sha1", null);
    Transform transform = signatureFactory.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null);
    DigestMethod digestMethod = signatureFactory.newDigestMethod("http://www.w3.org/2000/09/xmldsig#sha1", null);
    Reference reference = signatureFactory.newReference("", digestMethod, Collections.singletonList(transform), null, null);
    Transform objectTransform = signatureFactory.newTransform("http://www.w3.org/2001/10/xml-exc-c14n#", (TransformParameterSpec) null);
    Reference objectReference = signatureFactory.newReference("#" + signaturePropertyId, digestMethod, Collections.singletonList(objectTransform), "http://www.w3.org/2000/09/xmldsig#SignatureProperties", null);
    List<Reference> references = new ArrayList<>();
    references.add(reference);
    references.add(objectReference);
    SignedInfo signedInfo = signatureFactory.newSignedInfo(c14nMethod, signatureMethod, references);
    // Add a SignatureProperty containing a Timestamp
    Element timestamp = document.createElementNS(null, "Timestamp");
    timestamp.setTextContent(new Date().toString());
    XMLStructure content = new DOMStructure(timestamp);
    SignatureProperty signatureProperty = signatureFactory.newSignatureProperty(Collections.singletonList(content), "#" + signatureId, signaturePropertyId);
    SignatureProperties signatureProperties = signatureFactory.newSignatureProperties(Collections.singletonList(signatureProperty), null);
    XMLObject object = signatureFactory.newXMLObject(Collections.singletonList(signatureProperties), null, null, null);
    XMLSignature sig = signatureFactory.newXMLSignature(signedInfo, keyInfo, Collections.singletonList(object), signatureId, null);
    XMLSignContext signContext = new DOMSignContext(key, document.getDocumentElement());
    sig.sign(signContext);
    // XMLUtils.outputDOM(document, System.out);
    // Verify using JSR-105
    // Find the Signature Element
    Element sigElement = SignatureUtils.getSignatureElement(document);
    Assert.assertNotNull(sigElement);
    XMLValidateContext context = new DOMValidateContext(cert.getPublicKey(), sigElement);
    context.setProperty("javax.xml.crypto.dsig.cacheReference", Boolean.TRUE);
    context.setProperty("org.apache.jcp.xml.dsig.secureValidation", Boolean.TRUE);
    context.setProperty("org.jcp.xml.dsig.secureValidation", Boolean.TRUE);
    signatureFactory = XMLSignatureFactory.getInstance("DOM");
    XMLSignature xmlSignature = signatureFactory.unmarshalXMLSignature(context);
    // Check the Signature value
    Assert.assertTrue(xmlSignature.validate(context));
    // First find the Timestamp
    SignatureProperty timestampSignatureProperty = getTimestampSignatureProperty(xmlSignature);
    assertNotNull(timestampSignatureProperty);
    // Check that what was signed is what we expected to be signed.
    boolean foundEnvelopedSig = false;
    boolean foundSignedTimestamp = false;
    for (Object refObject : signedInfo.getReferences()) {
        Reference ref = (Reference) refObject;
        if ("".equals(ref.getURI())) {
            List<Transform> transforms = (List<Transform>) ref.getTransforms();
            if (transforms != null && transforms.stream().anyMatch(t -> t.getAlgorithm().equals(Transform.ENVELOPED))) {
                foundEnvelopedSig = true;
            }
        } else if ("http://www.w3.org/2000/09/xmldsig#SignatureProperties".equals(ref.getType()) && ref.getURI().equals("#" + timestampSignatureProperty.getId())) {
            // Found matching SignatureProperties Object
            // Now validate Timestamp
            validateTimestamp(signatureProperty, cert);
            foundSignedTimestamp = true;
        }
    }
    assertEquals(sigElement.getParentNode(), document.getDocumentElement());
    assertTrue(foundEnvelopedSig);
    assertTrue(foundSignedTimestamp);
}
Also used : X509Certificate(java.security.cert.X509Certificate) DOMSignContext(javax.xml.crypto.dsig.dom.DOMSignContext) CanonicalizationMethod(javax.xml.crypto.dsig.CanonicalizationMethod) SignatureMethod(javax.xml.crypto.dsig.SignatureMethod) Date(java.util.Date) SignatureProperty(javax.xml.crypto.dsig.SignatureProperty) CertificateNotYetValidException(java.security.cert.CertificateNotYetValidException) Transform(javax.xml.crypto.dsig.Transform) XMLValidateContext(javax.xml.crypto.dsig.XMLValidateContext) CertificateExpiredException(java.security.cert.CertificateExpiredException) ArrayList(java.util.ArrayList) Document(org.w3c.dom.Document) X509Data(javax.xml.crypto.dsig.keyinfo.X509Data) XMLObject(javax.xml.crypto.dsig.XMLObject) XMLStructure(javax.xml.crypto.XMLStructure) DOMStructure(javax.xml.crypto.dom.DOMStructure) Iterator(java.util.Iterator) C14NMethodParameterSpec(javax.xml.crypto.dsig.spec.C14NMethodParameterSpec) XMLSignContext(javax.xml.crypto.dsig.XMLSignContext) KeyStore(java.security.KeyStore) UUID(java.util.UUID) XMLSignatureFactory(javax.xml.crypto.dsig.XMLSignatureFactory) Key(java.security.Key) List(java.util.List) Element(org.w3c.dom.Element) SignedInfo(javax.xml.crypto.dsig.SignedInfo) Reference(javax.xml.crypto.dsig.Reference) DOMValidateContext(javax.xml.crypto.dsig.dom.DOMValidateContext) DocumentBuilder(javax.xml.parsers.DocumentBuilder) DigestMethod(javax.xml.crypto.dsig.DigestMethod) KeyInfoFactory(javax.xml.crypto.dsig.keyinfo.KeyInfoFactory) TransformParameterSpec(javax.xml.crypto.dsig.spec.TransformParameterSpec) XMLUtils(org.apache.xml.security.utils.XMLUtils) SignatureProperties(javax.xml.crypto.dsig.SignatureProperties) Assert(org.junit.Assert) Collections(java.util.Collections) Init(org.apache.xml.security.Init) InputStream(java.io.InputStream) XMLSignature(javax.xml.crypto.dsig.XMLSignature) Element(org.w3c.dom.Element) ArrayList(java.util.ArrayList) DigestMethod(javax.xml.crypto.dsig.DigestMethod) XMLStructure(javax.xml.crypto.XMLStructure) Document(org.w3c.dom.Document) SignatureProperty(javax.xml.crypto.dsig.SignatureProperty) X509Data(javax.xml.crypto.dsig.keyinfo.X509Data) KeyInfoFactory(javax.xml.crypto.dsig.keyinfo.KeyInfoFactory) XMLSignature(javax.xml.crypto.dsig.XMLSignature) DOMValidateContext(javax.xml.crypto.dsig.dom.DOMValidateContext) DOMStructure(javax.xml.crypto.dom.DOMStructure) XMLSignContext(javax.xml.crypto.dsig.XMLSignContext) ArrayList(java.util.ArrayList) List(java.util.List) XMLSignatureFactory(javax.xml.crypto.dsig.XMLSignatureFactory) XMLValidateContext(javax.xml.crypto.dsig.XMLValidateContext) InputStream(java.io.InputStream) Reference(javax.xml.crypto.dsig.Reference) CanonicalizationMethod(javax.xml.crypto.dsig.CanonicalizationMethod) XMLObject(javax.xml.crypto.dsig.XMLObject) KeyStore(java.security.KeyStore) X509Certificate(java.security.cert.X509Certificate) Date(java.util.Date) SignedInfo(javax.xml.crypto.dsig.SignedInfo) DocumentBuilder(javax.xml.parsers.DocumentBuilder) DOMSignContext(javax.xml.crypto.dsig.dom.DOMSignContext) SignatureProperties(javax.xml.crypto.dsig.SignatureProperties) SignatureMethod(javax.xml.crypto.dsig.SignatureMethod) XMLObject(javax.xml.crypto.dsig.XMLObject) Transform(javax.xml.crypto.dsig.Transform) Key(java.security.Key)

Example 3 with XMLSignContext

use of javax.xml.crypto.dsig.XMLSignContext in project testcases by coheigea.

the class SignatureUtils method signUsingJSR105.

/**
 * Sign the document using the JSR-105 API, which is included in the JDK
 * It signs a list of QNames that it finds in the Document via XPath.
 */
public static void signUsingJSR105(Document document, List<QName> namesToSign, String algorithm, Key signingKey, X509Certificate signingCert) throws Exception {
    XMLSignatureFactory signatureFactory = XMLSignatureFactory.getInstance("DOM");
    CanonicalizationMethod c14nMethod = signatureFactory.newCanonicalizationMethod("http://www.w3.org/2001/10/xml-exc-c14n#", (C14NMethodParameterSpec) null);
    KeyInfoFactory keyInfoFactory = signatureFactory.getKeyInfoFactory();
    X509Data x509Data = keyInfoFactory.newX509Data(Collections.singletonList(signingCert));
    javax.xml.crypto.dsig.keyinfo.KeyInfo keyInfo = keyInfoFactory.newKeyInfo(Collections.singletonList(x509Data));
    XPathFactory xpf = XPathFactory.newInstance();
    XPath xpath = xpf.newXPath();
    xpath.setNamespaceContext(new DSNamespaceContext());
    List<javax.xml.crypto.dsig.Reference> referenceList = new ArrayList<>();
    for (QName nameToSign : namesToSign) {
        String expression = "//*[local-name()='" + nameToSign.getLocalPart() + "']";
        NodeList elementsToSign = (NodeList) xpath.evaluate(expression, document, XPathConstants.NODESET);
        for (int i = 0; i < elementsToSign.getLength(); i++) {
            Element elementToSign = (Element) elementsToSign.item(i);
            Assert.assertNotNull(elementToSign);
            String id = UUID.randomUUID().toString();
            elementToSign.setAttributeNS(null, "Id", id);
            elementToSign.setIdAttributeNS(null, "Id", true);
            javax.xml.crypto.dsig.Transform transform = signatureFactory.newTransform("http://www.w3.org/2001/10/xml-exc-c14n#", (TransformParameterSpec) null);
            DigestMethod digestMethod = signatureFactory.newDigestMethod("http://www.w3.org/2000/09/xmldsig#sha1", null);
            javax.xml.crypto.dsig.Reference reference = signatureFactory.newReference("#" + id, digestMethod, Collections.singletonList(transform), null, null);
            referenceList.add(reference);
        }
    }
    SignatureMethod signatureMethod = signatureFactory.newSignatureMethod(algorithm, null);
    SignedInfo signedInfo = signatureFactory.newSignedInfo(c14nMethod, signatureMethod, referenceList);
    javax.xml.crypto.dsig.XMLSignature sig = signatureFactory.newXMLSignature(signedInfo, keyInfo, null, null, null);
    XMLSignContext signContext = new DOMSignContext(signingKey, document.getDocumentElement());
    sig.sign(signContext);
    // Find the Signature Element
    Element sigElement = getSignatureElement(document);
    Assert.assertNotNull(sigElement);
}
Also used : Element(org.w3c.dom.Element) ArrayList(java.util.ArrayList) DigestMethod(javax.xml.crypto.dsig.DigestMethod) X509Data(javax.xml.crypto.dsig.keyinfo.X509Data) KeyInfoFactory(javax.xml.crypto.dsig.keyinfo.KeyInfoFactory) XPathFactory(javax.xml.xpath.XPathFactory) XMLSignContext(javax.xml.crypto.dsig.XMLSignContext) XPath(javax.xml.xpath.XPath) XMLSignatureFactory(javax.xml.crypto.dsig.XMLSignatureFactory) QName(javax.xml.namespace.QName) NodeList(org.w3c.dom.NodeList) CanonicalizationMethod(javax.xml.crypto.dsig.CanonicalizationMethod) SignedInfo(javax.xml.crypto.dsig.SignedInfo) DOMSignContext(javax.xml.crypto.dsig.dom.DOMSignContext) SignatureMethod(javax.xml.crypto.dsig.SignatureMethod)

Aggregations

ArrayList (java.util.ArrayList)3 CanonicalizationMethod (javax.xml.crypto.dsig.CanonicalizationMethod)3 SignatureMethod (javax.xml.crypto.dsig.SignatureMethod)3 SignedInfo (javax.xml.crypto.dsig.SignedInfo)3 XMLSignContext (javax.xml.crypto.dsig.XMLSignContext)3 XMLSignatureFactory (javax.xml.crypto.dsig.XMLSignatureFactory)3 DOMSignContext (javax.xml.crypto.dsig.dom.DOMSignContext)3 XMLStructure (javax.xml.crypto.XMLStructure)2 DigestMethod (javax.xml.crypto.dsig.DigestMethod)2 Reference (javax.xml.crypto.dsig.Reference)2 XMLObject (javax.xml.crypto.dsig.XMLObject)2 XMLSignature (javax.xml.crypto.dsig.XMLSignature)2 KeyInfoFactory (javax.xml.crypto.dsig.keyinfo.KeyInfoFactory)2 X509Data (javax.xml.crypto.dsig.keyinfo.X509Data)2 Element (org.w3c.dom.Element)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 File (java.io.File)1 InputStream (java.io.InputStream)1 GeneralSecurityException (java.security.GeneralSecurityException)1 Key (java.security.Key)1