mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-14 18:03:44 +00:00
8359395: XML signature generation does not support user provided SecureRandom
Reviewed-by: mullan
This commit is contained in:
parent
53d152e7db
commit
b2b56cfc00
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2025, 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
|
||||
@ -32,6 +32,10 @@ import javax.xml.crypto.dom.DOMCryptoContext;
|
||||
import javax.xml.crypto.dsig.XMLSignContext;
|
||||
import javax.xml.crypto.dsig.XMLSignature;
|
||||
import java.security.Key;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Signature;
|
||||
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
@ -46,6 +50,17 @@ import org.w3c.dom.Node;
|
||||
* (for example, you should not use the same <code>DOMSignContext</code>
|
||||
* instance to sign two different {@link XMLSignature} objects).
|
||||
*
|
||||
* @implNote
|
||||
* The JDK implementation supports the following property that can be set
|
||||
* using the {@link #setProperty setProperty} method.
|
||||
* <ul>
|
||||
* <li><code>jdk.xmldsig.SecureRandom</code>: value must be a
|
||||
* {@link SecureRandom}. If specified, this object will be
|
||||
* used to initialize the underlying {@code Signature} during signing
|
||||
* using the {@link Signature#initSign(PrivateKey, SecureRandom)}
|
||||
* method.
|
||||
* </ul>
|
||||
*
|
||||
* @author Sean Mullan
|
||||
* @author JSR 105 Expert Group
|
||||
* @since 1.6
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
@ -33,6 +33,7 @@ import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.Provider;
|
||||
import java.security.PublicKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Signature;
|
||||
import java.security.SignatureException;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
@ -59,6 +60,7 @@ import org.w3c.dom.Text;
|
||||
public abstract class DOMRSAPSSSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
|
||||
private static final String DOM_SIGNATURE_PROVIDER = "org.jcp.xml.dsig.internal.dom.SignatureProvider";
|
||||
private static final String DOM_SIGNATURE_RANDOM = "jdk.xmldsig.SecureRandom";
|
||||
|
||||
private static final com.sun.org.slf4j.internal.Logger LOG =
|
||||
com.sun.org.slf4j.internal.LoggerFactory.getLogger(DOMRSAPSSSignatureMethod.class);
|
||||
@ -324,7 +326,12 @@ public abstract class DOMRSAPSSSignatureMethod extends AbstractDOMSignatureMetho
|
||||
throw new XMLSignatureException(nsae);
|
||||
}
|
||||
}
|
||||
signature.initSign((PrivateKey)key);
|
||||
SecureRandom sr = (SecureRandom)context.getProperty(DOM_SIGNATURE_RANDOM);
|
||||
if (sr != null) {
|
||||
signature.initSign((PrivateKey) key, sr);
|
||||
} else {
|
||||
signature.initSign((PrivateKey) key);
|
||||
}
|
||||
try {
|
||||
signature.setParameter(spec);
|
||||
} catch (InvalidAlgorithmParameterException e) {
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
package org.jcp.xml.dsig.internal.dom;
|
||||
|
||||
@ -33,6 +33,7 @@ import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.Provider;
|
||||
import java.security.PublicKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Signature;
|
||||
import java.security.SignatureException;
|
||||
import java.security.interfaces.DSAKey;
|
||||
@ -64,6 +65,7 @@ import sun.security.util.KeyUtil;
|
||||
public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
|
||||
private static final String DOM_SIGNATURE_PROVIDER = "org.jcp.xml.dsig.internal.dom.SignatureProvider";
|
||||
private static final String DOM_SIGNATURE_RANDOM = "jdk.xmldsig.SecureRandom";
|
||||
|
||||
private static final com.sun.org.slf4j.internal.Logger LOG =
|
||||
com.sun.org.slf4j.internal.LoggerFactory.getLogger(DOMSignatureMethod.class);
|
||||
@ -390,7 +392,12 @@ public abstract class DOMSignatureMethod extends AbstractDOMSignatureMethod {
|
||||
throw new XMLSignatureException(nsae);
|
||||
}
|
||||
}
|
||||
signature.initSign((PrivateKey)key);
|
||||
SecureRandom sr = (SecureRandom)context.getProperty(DOM_SIGNATURE_RANDOM);
|
||||
if (sr != null) {
|
||||
signature.initSign((PrivateKey) key, sr);
|
||||
} else {
|
||||
signature.initSign((PrivateKey) key);
|
||||
}
|
||||
LOG.debug("Signature provider: {}", signature.getProvider());
|
||||
LOG.debug("JCA Algorithm: {}", getJCAAlgorithm());
|
||||
|
||||
|
||||
100
test/jdk/javax/xml/crypto/dsig/Properties.java
Normal file
100
test/jdk/javax/xml/crypto/dsig/Properties.java
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import jdk.test.lib.Asserts;
|
||||
import jdk.test.lib.security.SeededSecureRandom;
|
||||
import jdk.test.lib.security.XMLUtils;
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
import javax.xml.crypto.dsig.XMLSignatureException;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Security;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8359395
|
||||
* @summary ensure properties are used
|
||||
* @library /test/lib
|
||||
*/
|
||||
public class Properties {
|
||||
|
||||
private static final String DOM_SIGNATURE_PROVIDER
|
||||
= "org.jcp.xml.dsig.internal.dom.SignatureProvider";
|
||||
private static final String DOM_SIGNATURE_RANDOM
|
||||
= "jdk.xmldsig.SecureRandom";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// Do not test on RSA. It's always deterministic.
|
||||
test("EC");
|
||||
test("RSASSA-PSS");
|
||||
}
|
||||
|
||||
static void test(String alg) throws Exception {
|
||||
var kp = KeyPairGenerator.getInstance(alg).generateKeyPair();
|
||||
var signer = XMLUtils.signer(kp.getPrivate(), kp.getPublic());
|
||||
|
||||
var n1 = getSignature(signer.sign("hello")); // random one
|
||||
var n2 = getSignature(signer.sign("hello")); // another random one
|
||||
|
||||
signer.prop(DOM_SIGNATURE_RANDOM, new SeededSecureRandom(1L));
|
||||
var s1 = getSignature(signer.sign("hello")); // deterministic one
|
||||
|
||||
signer.prop(DOM_SIGNATURE_RANDOM, new SeededSecureRandom(1L));
|
||||
var s1again = getSignature(signer.sign("hello")); // deterministic one repeated
|
||||
|
||||
signer.prop(DOM_SIGNATURE_RANDOM, new SeededSecureRandom(2L));
|
||||
var s2 = getSignature(signer.sign("hello")); // deterministic two
|
||||
|
||||
Asserts.assertEqualsByteArray(s1, s1again);
|
||||
assertsAllDifferent(n1, n2, s1, s2);
|
||||
|
||||
signer.prop(DOM_SIGNATURE_PROVIDER, Security.getProvider("SunJCE"));
|
||||
// Asserts throwing XMLSignatureException with cause NoSuchAlgorithmException
|
||||
Asserts.assertEquals(
|
||||
Asserts.assertThrows(XMLSignatureException.class,
|
||||
() -> signer.sign("hello")).getCause().getClass(),
|
||||
NoSuchAlgorithmException.class);
|
||||
}
|
||||
|
||||
private static void assertsAllDifferent(byte[]... inputs) {
|
||||
for (var a : inputs) {
|
||||
for (var b : inputs) {
|
||||
if (a != b) {
|
||||
Asserts.assertNotEqualsByteArray(a, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static byte[] getSignature(Document doc) {
|
||||
for (var n = doc.getDocumentElement().getFirstChild();
|
||||
n != null; n = n.getNextSibling()) {
|
||||
if ("SignatureValue".equals(n.getLocalName())) {
|
||||
return Base64.getMimeDecoder().decode(n.getTextContent());
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Not found");
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user