8216039: TLS with BC and RSASSA-PSS breaks ECDHServerKeyExchange
Add internal Signature init methods to select provider based on both key and parameter Reviewed-by: xuelei
This commit is contained in:
parent
eebe346715
commit
3b6b6b3cb3
@ -40,6 +40,8 @@ import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import jdk.internal.access.JavaSecuritySignatureAccess;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
|
||||
import sun.security.util.Debug;
|
||||
import sun.security.jca.*;
|
||||
@ -118,6 +120,34 @@ import sun.security.jca.GetInstance.Instance;
|
||||
|
||||
public abstract class Signature extends SignatureSpi {
|
||||
|
||||
static {
|
||||
SharedSecrets.setJavaSecuritySignatureAccess(
|
||||
new JavaSecuritySignatureAccess() {
|
||||
@Override
|
||||
public void initVerify(Signature s, PublicKey publicKey,
|
||||
AlgorithmParameterSpec params)
|
||||
throws InvalidKeyException,
|
||||
InvalidAlgorithmParameterException {
|
||||
s.initVerify(publicKey, params);
|
||||
}
|
||||
@Override
|
||||
public void initVerify(Signature s,
|
||||
java.security.cert.Certificate certificate,
|
||||
AlgorithmParameterSpec params)
|
||||
throws InvalidKeyException,
|
||||
InvalidAlgorithmParameterException {
|
||||
s.initVerify(certificate, params);
|
||||
}
|
||||
@Override
|
||||
public void initSign(Signature s, PrivateKey privateKey,
|
||||
AlgorithmParameterSpec params, SecureRandom random)
|
||||
throws InvalidKeyException,
|
||||
InvalidAlgorithmParameterException {
|
||||
s.initSign(privateKey, params, random);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static final Debug debug =
|
||||
Debug.getInstance("jca", "Signature");
|
||||
|
||||
@ -481,6 +511,53 @@ public abstract class Signature extends SignatureSpi {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this object for verification. If this method is called
|
||||
* again with different arguments, it negates the effect
|
||||
* of this call.
|
||||
*
|
||||
* @param publicKey the public key of the identity whose signature is
|
||||
* going to be verified.
|
||||
* @param params the parameters used for verifying this signature.
|
||||
*
|
||||
* @exception InvalidKeyException if the key is invalid.
|
||||
* @exception InvalidAlgorithmParameterException if the params is invalid.
|
||||
*/
|
||||
final void initVerify(PublicKey publicKey, AlgorithmParameterSpec params)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException {
|
||||
engineInitVerify(publicKey, params);
|
||||
state = VERIFY;
|
||||
|
||||
if (!skipDebug && pdebug != null) {
|
||||
pdebug.println("Signature." + algorithm +
|
||||
" verification algorithm from: " + getProviderName());
|
||||
}
|
||||
}
|
||||
|
||||
private static PublicKey getPublicKeyFromCert(Certificate cert)
|
||||
throws InvalidKeyException {
|
||||
// If the certificate is of type X509Certificate,
|
||||
// we should check whether it has a Key Usage
|
||||
// extension marked as critical.
|
||||
//if (cert instanceof java.security.cert.X509Certificate) {
|
||||
if (cert instanceof X509Certificate) {
|
||||
// Check whether the cert has a key usage extension
|
||||
// marked as a critical extension.
|
||||
// The OID for KeyUsage extension is 2.5.29.15.
|
||||
X509Certificate c = (X509Certificate)cert;
|
||||
Set<String> critSet = c.getCriticalExtensionOIDs();
|
||||
|
||||
if (critSet != null && !critSet.isEmpty()
|
||||
&& critSet.contains("2.5.29.15")) {
|
||||
boolean[] keyUsageInfo = c.getKeyUsage();
|
||||
// keyUsageInfo[0] is for digitalSignature.
|
||||
if ((keyUsageInfo != null) && (keyUsageInfo[0] == false))
|
||||
throw new InvalidKeyException("Wrong key usage");
|
||||
}
|
||||
}
|
||||
return cert.getPublicKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes this object for verification, using the public key from
|
||||
* the given certificate.
|
||||
@ -501,27 +578,40 @@ public abstract class Signature extends SignatureSpi {
|
||||
*/
|
||||
public final void initVerify(Certificate certificate)
|
||||
throws InvalidKeyException {
|
||||
// If the certificate is of type X509Certificate,
|
||||
// we should check whether it has a Key Usage
|
||||
// extension marked as critical.
|
||||
if (certificate instanceof java.security.cert.X509Certificate) {
|
||||
// Check whether the cert has a key usage extension
|
||||
// marked as a critical extension.
|
||||
// The OID for KeyUsage extension is 2.5.29.15.
|
||||
X509Certificate cert = (X509Certificate)certificate;
|
||||
Set<String> critSet = cert.getCriticalExtensionOIDs();
|
||||
engineInitVerify(getPublicKeyFromCert(certificate));
|
||||
state = VERIFY;
|
||||
|
||||
if (critSet != null && !critSet.isEmpty()
|
||||
&& critSet.contains("2.5.29.15")) {
|
||||
boolean[] keyUsageInfo = cert.getKeyUsage();
|
||||
// keyUsageInfo[0] is for digitalSignature.
|
||||
if ((keyUsageInfo != null) && (keyUsageInfo[0] == false))
|
||||
throw new InvalidKeyException("Wrong key usage");
|
||||
}
|
||||
if (!skipDebug && pdebug != null) {
|
||||
pdebug.println("Signature." + algorithm +
|
||||
" verification algorithm from: " + getProviderName());
|
||||
}
|
||||
}
|
||||
|
||||
PublicKey publicKey = certificate.getPublicKey();
|
||||
engineInitVerify(publicKey);
|
||||
/**
|
||||
* Initializes this object for verification, using the public key from
|
||||
* the given certificate.
|
||||
* <p>If the certificate is of type X.509 and has a <i>key usage</i>
|
||||
* extension field marked as critical, and the value of the <i>key usage</i>
|
||||
* extension field implies that the public key in
|
||||
* the certificate and its corresponding private key are not
|
||||
* supposed to be used for digital signatures, an
|
||||
* {@code InvalidKeyException} is thrown.
|
||||
*
|
||||
* @param certificate the certificate of the identity whose signature is
|
||||
* going to be verified.
|
||||
* @param params the parameters used for verifying this signature.
|
||||
*
|
||||
* @exception InvalidKeyException if the public key in the certificate
|
||||
* is not encoded properly or does not include required parameter
|
||||
* information or cannot be used for digital signature purposes.
|
||||
* @exception InvalidAlgorithmParameterException if the params is invalid.
|
||||
*
|
||||
* @since 13
|
||||
*/
|
||||
final void initVerify(Certificate certificate,
|
||||
AlgorithmParameterSpec params)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException {
|
||||
engineInitVerify(getPublicKeyFromCert(certificate), params);
|
||||
state = VERIFY;
|
||||
|
||||
if (!skipDebug && pdebug != null) {
|
||||
@ -574,6 +664,31 @@ public abstract class Signature extends SignatureSpi {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this object for signing. If this method is called
|
||||
* again with different arguments, it negates the effect
|
||||
* of this call.
|
||||
*
|
||||
* @param privateKey the private key of the identity whose signature
|
||||
* is going to be generated.
|
||||
* @param params the parameters used for generating signature.
|
||||
* @param random the source of randomness for this signature.
|
||||
*
|
||||
* @exception InvalidKeyException if the key is invalid.
|
||||
* @exception InvalidAlgorithmParameterException if the params is invalid
|
||||
*/
|
||||
final void initSign(PrivateKey privateKey,
|
||||
AlgorithmParameterSpec params, SecureRandom random)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException {
|
||||
engineInitSign(privateKey, params, random);
|
||||
state = SIGN;
|
||||
|
||||
if (!skipDebug && pdebug != null) {
|
||||
pdebug.println("Signature." + algorithm +
|
||||
" signing algorithm from: " + getProviderName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the signature bytes of all the data updated.
|
||||
* The format of the signature depends on the underlying
|
||||
@ -1110,11 +1225,13 @@ public abstract class Signature extends SignatureSpi {
|
||||
}
|
||||
}
|
||||
|
||||
private void chooseProvider(int type, Key key, SecureRandom random)
|
||||
throws InvalidKeyException {
|
||||
// Used by engineSetParameter/engineInitSign/engineInitVerify() to
|
||||
// find the right provider with the supplied key, parameters, random source
|
||||
private void chooseProvider(int type, Key key,
|
||||
AlgorithmParameterSpec params, SecureRandom random)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException {
|
||||
synchronized (lock) {
|
||||
if (sigSpi != null) {
|
||||
init(sigSpi, type, key, random);
|
||||
return;
|
||||
}
|
||||
Exception lastException = null;
|
||||
@ -1127,7 +1244,7 @@ public abstract class Signature extends SignatureSpi {
|
||||
s = serviceIterator.next();
|
||||
}
|
||||
// if provider says it does not support this key, ignore it
|
||||
if (s.supportsParameter(key) == false) {
|
||||
if (key != null && s.supportsParameter(key) == false) {
|
||||
continue;
|
||||
}
|
||||
// if instance is not a SignatureSpi, ignore it
|
||||
@ -1136,7 +1253,7 @@ public abstract class Signature extends SignatureSpi {
|
||||
}
|
||||
try {
|
||||
SignatureSpi spi = newInstance(s);
|
||||
init(spi, type, key, random);
|
||||
tryOperation(spi, type, key, params, random);
|
||||
provider = s.getProvider();
|
||||
sigSpi = spi;
|
||||
firstService = null;
|
||||
@ -1158,6 +1275,10 @@ public abstract class Signature extends SignatureSpi {
|
||||
if (lastException instanceof RuntimeException) {
|
||||
throw (RuntimeException)lastException;
|
||||
}
|
||||
if (lastException instanceof InvalidAlgorithmParameterException) {
|
||||
throw (InvalidAlgorithmParameterException)lastException;
|
||||
}
|
||||
|
||||
String k = (key != null) ? key.getClass().getName() : "(null)";
|
||||
throw new InvalidKeyException
|
||||
("No installed provider supports this key: "
|
||||
@ -1165,22 +1286,35 @@ public abstract class Signature extends SignatureSpi {
|
||||
}
|
||||
}
|
||||
|
||||
private static final int I_PUB = 1;
|
||||
private static final int I_PRIV = 2;
|
||||
private static final int I_PRIV_SR = 3;
|
||||
private static final int I_PUB = 1;
|
||||
private static final int I_PRIV = 2;
|
||||
private static final int I_PRIV_SR = 3;
|
||||
private static final int I_PUB_PARAM = 4;
|
||||
private static final int I_PRIV_PARAM_SR = 5;
|
||||
private static final int S_PARAM = 6;
|
||||
|
||||
private void init(SignatureSpi spi, int type, Key key,
|
||||
SecureRandom random) throws InvalidKeyException {
|
||||
private void tryOperation(SignatureSpi spi, int type, Key key,
|
||||
AlgorithmParameterSpec params, SecureRandom random)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException {
|
||||
switch (type) {
|
||||
case I_PUB:
|
||||
spi.engineInitVerify((PublicKey)key);
|
||||
break;
|
||||
case I_PUB_PARAM:
|
||||
spi.engineInitVerify((PublicKey)key, params);
|
||||
break;
|
||||
case I_PRIV:
|
||||
spi.engineInitSign((PrivateKey)key);
|
||||
break;
|
||||
case I_PRIV_SR:
|
||||
spi.engineInitSign((PrivateKey)key, random);
|
||||
break;
|
||||
case I_PRIV_PARAM_SR:
|
||||
spi.engineInitSign((PrivateKey)key, params, random);
|
||||
break;
|
||||
case S_PARAM:
|
||||
spi.engineSetParameter(params);
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError("Internal error: " + type);
|
||||
}
|
||||
@ -1191,7 +1325,22 @@ public abstract class Signature extends SignatureSpi {
|
||||
if (sigSpi != null) {
|
||||
sigSpi.engineInitVerify(publicKey);
|
||||
} else {
|
||||
chooseProvider(I_PUB, publicKey, null);
|
||||
try {
|
||||
chooseProvider(I_PUB, publicKey, null, null);
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
// should not happen, re-throw as IKE just in case
|
||||
throw new InvalidKeyException(iape);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void engineInitVerify(PublicKey publicKey,
|
||||
AlgorithmParameterSpec params)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException {
|
||||
if (sigSpi != null) {
|
||||
sigSpi.engineInitVerify(publicKey, params);
|
||||
} else {
|
||||
chooseProvider(I_PUB_PARAM, publicKey, params, null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1200,7 +1349,12 @@ public abstract class Signature extends SignatureSpi {
|
||||
if (sigSpi != null) {
|
||||
sigSpi.engineInitSign(privateKey);
|
||||
} else {
|
||||
chooseProvider(I_PRIV, privateKey, null);
|
||||
try {
|
||||
chooseProvider(I_PRIV, privateKey, null, null);
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
// should not happen, re-throw as IKE just in case
|
||||
throw new InvalidKeyException(iape);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1209,7 +1363,22 @@ public abstract class Signature extends SignatureSpi {
|
||||
if (sigSpi != null) {
|
||||
sigSpi.engineInitSign(privateKey, sr);
|
||||
} else {
|
||||
chooseProvider(I_PRIV_SR, privateKey, sr);
|
||||
try {
|
||||
chooseProvider(I_PRIV_SR, privateKey, null, sr);
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
// should not happen, re-throw as IKE just in case
|
||||
throw new InvalidKeyException(iape);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void engineInitSign(PrivateKey privateKey,
|
||||
AlgorithmParameterSpec params, SecureRandom sr)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException {
|
||||
if (sigSpi != null) {
|
||||
sigSpi.engineInitSign(privateKey, params, sr);
|
||||
} else {
|
||||
chooseProvider(I_PRIV_PARAM_SR, privateKey, params, sr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1260,8 +1429,16 @@ public abstract class Signature extends SignatureSpi {
|
||||
|
||||
protected void engineSetParameter(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
chooseFirstProvider();
|
||||
sigSpi.engineSetParameter(params);
|
||||
if (sigSpi != null) {
|
||||
sigSpi.engineSetParameter(params);
|
||||
} else {
|
||||
try {
|
||||
chooseProvider(S_PARAM, null, params, null);
|
||||
} catch (InvalidKeyException ike) {
|
||||
// should never happen, rethrow just in case
|
||||
throw new InvalidAlgorithmParameterException(ike);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Object engineGetParameter(String param)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2019, 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
|
||||
@ -70,6 +70,33 @@ public abstract class SignatureSpi {
|
||||
protected abstract void engineInitVerify(PublicKey publicKey)
|
||||
throws InvalidKeyException;
|
||||
|
||||
/**
|
||||
* Initializes this signature object with the specified
|
||||
* public key for verification operations.
|
||||
*
|
||||
* @param publicKey the public key of the identity whose signature is
|
||||
* going to be verified.
|
||||
* @param params the parameters for generating this signature
|
||||
*
|
||||
* @exception InvalidKeyException if the key is improperly
|
||||
* encoded, does not work with the given parameters, and so on.
|
||||
* @exception InvalidAlgorithmParameterException if the given parameters
|
||||
* is invalid.
|
||||
*/
|
||||
void engineInitVerify(PublicKey publicKey,
|
||||
AlgorithmParameterSpec params)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException {
|
||||
if (params != null) {
|
||||
try {
|
||||
engineSetParameter(params);
|
||||
} catch (UnsupportedOperationException usoe) {
|
||||
// error out if not overrridden
|
||||
throw new InvalidAlgorithmParameterException(usoe);
|
||||
}
|
||||
}
|
||||
engineInitVerify(publicKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes this signature object with the specified
|
||||
* private key for signing operations.
|
||||
@ -98,10 +125,41 @@ public abstract class SignatureSpi {
|
||||
* encoded, parameters are missing, and so on.
|
||||
*/
|
||||
protected void engineInitSign(PrivateKey privateKey,
|
||||
SecureRandom random)
|
||||
throws InvalidKeyException {
|
||||
this.appRandom = random;
|
||||
engineInitSign(privateKey);
|
||||
SecureRandom random)
|
||||
throws InvalidKeyException {
|
||||
this.appRandom = random;
|
||||
engineInitSign(privateKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes this signature object with the specified
|
||||
* private key and source of randomness for signing operations.
|
||||
*
|
||||
* <p>This concrete method has been added to this previously-defined
|
||||
* abstract class. (For backwards compatibility, it cannot be abstract.)
|
||||
*
|
||||
* @param privateKey the private key of the identity whose signature
|
||||
* will be generated.
|
||||
* @param params the parameters for generating this signature
|
||||
* @param random the source of randomness
|
||||
*
|
||||
* @exception InvalidKeyException if the key is improperly
|
||||
* encoded, parameters are missing, and so on.
|
||||
* @exception InvalidAlgorithmParameterException if the parameters is
|
||||
* invalid.
|
||||
*/
|
||||
void engineInitSign(PrivateKey privateKey,
|
||||
AlgorithmParameterSpec params, SecureRandom random)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException {
|
||||
if (params != null) {
|
||||
try {
|
||||
engineSetParameter(params);
|
||||
} catch (UnsupportedOperationException usoe) {
|
||||
// error out if not overrridden
|
||||
throw new InvalidAlgorithmParameterException(usoe);
|
||||
}
|
||||
}
|
||||
engineInitSign(privateKey, random);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -127,7 +185,7 @@ public abstract class SignatureSpi {
|
||||
* properly
|
||||
*/
|
||||
protected abstract void engineUpdate(byte[] b, int off, int len)
|
||||
throws SignatureException;
|
||||
throws SignatureException;
|
||||
|
||||
/**
|
||||
* Updates the data to be signed or verified using the specified
|
||||
@ -223,7 +281,7 @@ public abstract class SignatureSpi {
|
||||
* @since 1.2
|
||||
*/
|
||||
protected int engineSign(byte[] outbuf, int offset, int len)
|
||||
throws SignatureException {
|
||||
throws SignatureException {
|
||||
byte[] sig = engineSign();
|
||||
if (len < sig.length) {
|
||||
throw new SignatureException
|
||||
@ -251,7 +309,7 @@ public abstract class SignatureSpi {
|
||||
* process the input data provided, etc.
|
||||
*/
|
||||
protected abstract boolean engineVerify(byte[] sigBytes)
|
||||
throws SignatureException;
|
||||
throws SignatureException;
|
||||
|
||||
/**
|
||||
* Verifies the passed-in signature in the specified array
|
||||
@ -273,7 +331,7 @@ public abstract class SignatureSpi {
|
||||
* @since 1.4
|
||||
*/
|
||||
protected boolean engineVerify(byte[] sigBytes, int offset, int length)
|
||||
throws SignatureException {
|
||||
throws SignatureException {
|
||||
byte[] sigBytesCopy = new byte[length];
|
||||
System.arraycopy(sigBytes, offset, sigBytesCopy, 0, length);
|
||||
return engineVerify(sigBytesCopy);
|
||||
@ -305,7 +363,7 @@ public abstract class SignatureSpi {
|
||||
*/
|
||||
@Deprecated
|
||||
protected abstract void engineSetParameter(String param, Object value)
|
||||
throws InvalidParameterException;
|
||||
throws InvalidParameterException;
|
||||
|
||||
/**
|
||||
* <p>This method is overridden by providers to initialize
|
||||
@ -321,8 +379,8 @@ public abstract class SignatureSpi {
|
||||
* are inappropriate for this signature engine
|
||||
*/
|
||||
protected void engineSetParameter(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
throw new UnsupportedOperationException();
|
||||
throws InvalidAlgorithmParameterException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2019, 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
|
||||
@ -239,16 +239,15 @@ public abstract class X509CRL extends CRL implements X509Extension {
|
||||
public void verify(PublicKey key, Provider sigProvider)
|
||||
throws CRLException, NoSuchAlgorithmException,
|
||||
InvalidKeyException, SignatureException {
|
||||
String sigAlgName = getSigAlgName();
|
||||
Signature sig = (sigProvider == null)
|
||||
? Signature.getInstance(getSigAlgName())
|
||||
: Signature.getInstance(getSigAlgName(), sigProvider);
|
||||
? Signature.getInstance(sigAlgName)
|
||||
: Signature.getInstance(sigAlgName, sigProvider);
|
||||
|
||||
sig.initVerify(key);
|
||||
|
||||
// set parameters after Signature.initSign/initVerify call,
|
||||
// so the deferred provider selections occur when key is set
|
||||
try {
|
||||
SignatureUtil.specialSetParameter(sig, getSigAlgParams());
|
||||
byte[] paramBytes = getSigAlgParams();
|
||||
SignatureUtil.initVerifyWithParam(sig, key,
|
||||
SignatureUtil.getParamSpec(sigAlgName, paramBytes));
|
||||
} catch (ProviderException e) {
|
||||
throw new CRLException(e.getMessage(), e.getCause());
|
||||
} catch (InvalidAlgorithmParameterException e) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2019, 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
|
||||
@ -676,16 +676,14 @@ implements X509Extension {
|
||||
public void verify(PublicKey key, Provider sigProvider)
|
||||
throws CertificateException, NoSuchAlgorithmException,
|
||||
InvalidKeyException, SignatureException {
|
||||
String sigName = getSigAlgName();
|
||||
Signature sig = (sigProvider == null)
|
||||
? Signature.getInstance(getSigAlgName())
|
||||
: Signature.getInstance(getSigAlgName(), sigProvider);
|
||||
? Signature.getInstance(sigName)
|
||||
: Signature.getInstance(sigName, sigProvider);
|
||||
|
||||
sig.initVerify(key);
|
||||
|
||||
// set parameters after Signature.initSign/initVerify call,
|
||||
// so the deferred provider selections occur when key is set
|
||||
try {
|
||||
SignatureUtil.specialSetParameter(sig, getSigAlgParams());
|
||||
SignatureUtil.initVerifyWithParam(sig, key,
|
||||
SignatureUtil.getParamSpec(sigName, getSigAlgParams()));
|
||||
} catch (ProviderException e) {
|
||||
throw new CertificateException(e.getMessage(), e.getCause());
|
||||
} catch (InvalidAlgorithmParameterException e) {
|
||||
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package jdk.internal.access;
|
||||
|
||||
import java.security.*;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
|
||||
public interface JavaSecuritySignatureAccess {
|
||||
|
||||
void initVerify(Signature s, PublicKey publicKey, AlgorithmParameterSpec params)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException;
|
||||
|
||||
void initVerify(Signature s, java.security.cert.Certificate certificate,
|
||||
AlgorithmParameterSpec params)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException;
|
||||
|
||||
void initSign(Signature s, PrivateKey privateKey,
|
||||
AlgorithmParameterSpec params, SecureRandom random)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException;
|
||||
}
|
@ -36,6 +36,7 @@ import java.io.FilePermission;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.security.Signature;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
|
||||
/** A repository of "shared secrets", which are a mechanism for
|
||||
@ -73,6 +74,7 @@ public class SharedSecrets {
|
||||
private static JavaObjectInputStreamAccess javaObjectInputStreamAccess;
|
||||
private static JavaObjectInputFilterAccess javaObjectInputFilterAccess;
|
||||
private static JavaIORandomAccessFileAccess javaIORandomAccessFileAccess;
|
||||
private static JavaSecuritySignatureAccess javaSecuritySignatureAccess;
|
||||
private static JavaxCryptoSealedObjectAccess javaxCryptoSealedObjectAccess;
|
||||
|
||||
public static JavaUtilJarAccess javaUtilJarAccess() {
|
||||
@ -327,6 +329,17 @@ public class SharedSecrets {
|
||||
return javaIORandomAccessFileAccess;
|
||||
}
|
||||
|
||||
public static void setJavaSecuritySignatureAccess(JavaSecuritySignatureAccess jssa) {
|
||||
javaSecuritySignatureAccess = jssa;
|
||||
}
|
||||
|
||||
public static JavaSecuritySignatureAccess getJavaSecuritySignatureAccess() {
|
||||
if (javaSecuritySignatureAccess == null) {
|
||||
unsafe.ensureClassInitialized(Signature.class);
|
||||
}
|
||||
return javaSecuritySignatureAccess;
|
||||
}
|
||||
|
||||
public static void setJavaxCryptoSealedObjectAccess(JavaxCryptoSealedObjectAccess jcsoa) {
|
||||
javaxCryptoSealedObjectAccess = jcsoa;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2019, 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
|
||||
@ -447,15 +447,13 @@ public class SignerInfo implements DerEncoder {
|
||||
|
||||
Signature sig = Signature.getInstance(algname);
|
||||
|
||||
sig.initVerify(key);
|
||||
|
||||
// set parameters after Signature.initSign/initVerify call,
|
||||
// so the deferred provider selections occur when key is set
|
||||
AlgorithmParameters ap =
|
||||
digestEncryptionAlgorithmId.getParameters();
|
||||
try {
|
||||
SignatureUtil.specialSetParameter(sig, ap);
|
||||
} catch (ProviderException | InvalidAlgorithmParameterException e) {
|
||||
SignatureUtil.initVerifyWithParam(sig, key,
|
||||
SignatureUtil.getParamSpec(algname, ap));
|
||||
} catch (ProviderException | InvalidAlgorithmParameterException |
|
||||
InvalidKeyException e) {
|
||||
throw new SignatureException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
@ -466,8 +464,6 @@ public class SignerInfo implements DerEncoder {
|
||||
} catch (IOException e) {
|
||||
throw new SignatureException("IO error verifying signature:\n" +
|
||||
e.getMessage());
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new SignatureException("InvalidKey: " + e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -167,12 +167,8 @@ public class PKCS10 {
|
||||
try {
|
||||
sigAlg = id.getName();
|
||||
sig = Signature.getInstance(sigAlg);
|
||||
|
||||
sig.initVerify(subjectPublicKeyInfo);
|
||||
|
||||
// set parameters after Signature.initSign/initVerify call,
|
||||
// so the deferred provider selections occur when key is set
|
||||
SignatureUtil.specialSetParameter(sig, id.getParameters());
|
||||
SignatureUtil.initVerifyWithParam(sig, subjectPublicKeyInfo,
|
||||
SignatureUtil.getParamSpec(sigAlg, id.getParameters()));
|
||||
|
||||
sig.update(data);
|
||||
if (!sig.verify(sigData)) {
|
||||
|
@ -43,6 +43,7 @@ import sun.security.ssl.SupportedGroupsExtension.NamedGroup;
|
||||
import sun.security.ssl.SupportedGroupsExtension.NamedGroupType;
|
||||
import sun.security.ssl.X509Authentication.X509Possession;
|
||||
import sun.security.util.KeyUtil;
|
||||
import sun.security.util.SignatureUtil;
|
||||
|
||||
enum SignatureScheme {
|
||||
// EdDSA algorithms
|
||||
@ -471,16 +472,11 @@ enum SignatureScheme {
|
||||
|
||||
Signature signer = Signature.getInstance(algorithm);
|
||||
if (key instanceof PublicKey) {
|
||||
signer.initVerify((PublicKey)(key));
|
||||
SignatureUtil.initVerifyWithParam(signer, (PublicKey)key,
|
||||
signAlgParameter);
|
||||
} else {
|
||||
signer.initSign((PrivateKey)key);
|
||||
}
|
||||
|
||||
// Important note: Please don't set the parameters before signature
|
||||
// or verification initialization, so that the crypto provider can
|
||||
// be selected properly.
|
||||
if (signAlgParameter != null) {
|
||||
signer.setParameter(signAlgParameter);
|
||||
SignatureUtil.initSignWithParam(signer, (PrivateKey)key,
|
||||
signAlgParameter, null);
|
||||
}
|
||||
|
||||
return signer;
|
||||
|
@ -84,6 +84,7 @@ import sun.security.provider.certpath.ssl.SSLServerCertStore;
|
||||
import sun.security.util.Password;
|
||||
import sun.security.util.SecurityProperties;
|
||||
import sun.security.util.SecurityProviderConstants;
|
||||
import sun.security.util.SignatureUtil;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
@ -1441,11 +1442,12 @@ public final class Main {
|
||||
sigAlgName = getCompatibleSigAlgName(privateKey);
|
||||
}
|
||||
Signature signature = Signature.getInstance(sigAlgName);
|
||||
signature.initSign(privateKey);
|
||||
|
||||
X509CertInfo info = new X509CertInfo();
|
||||
AlgorithmParameterSpec params = AlgorithmId
|
||||
.getDefaultAlgorithmParameterSpec(sigAlgName, privateKey);
|
||||
|
||||
SignatureUtil.initSignWithParam(signature, privateKey, params, null);
|
||||
|
||||
X509CertInfo info = new X509CertInfo();
|
||||
AlgorithmId algID = AlgorithmId.getWithParameterSpec(sigAlgName, params);
|
||||
info.set(X509CertInfo.VALIDITY, interval);
|
||||
info.set(X509CertInfo.SERIAL_NUMBER,
|
||||
@ -1599,12 +1601,9 @@ public final class Main {
|
||||
}
|
||||
|
||||
Signature signature = Signature.getInstance(sigAlgName);
|
||||
signature.initSign(privKey);
|
||||
AlgorithmParameterSpec params = AlgorithmId
|
||||
.getDefaultAlgorithmParameterSpec(sigAlgName, privKey);
|
||||
if (params != null) {
|
||||
signature.setParameter(params);
|
||||
}
|
||||
SignatureUtil.initSignWithParam(signature, privKey, params, null);
|
||||
|
||||
X500Name subject = dname == null?
|
||||
new X500Name(((X509Certificate)cert).getSubjectDN().toString()):
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, 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
|
||||
@ -29,6 +29,7 @@ import java.io.IOException;
|
||||
import java.security.*;
|
||||
import java.security.spec.*;
|
||||
import sun.security.rsa.RSAUtil;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
|
||||
/**
|
||||
* Utility class for Signature related operations. Currently used by various
|
||||
@ -39,12 +40,25 @@ import sun.security.rsa.RSAUtil;
|
||||
*/
|
||||
public class SignatureUtil {
|
||||
|
||||
private static String checkName(String algName) throws ProviderException {
|
||||
if (algName.indexOf(".") == -1) {
|
||||
return algName;
|
||||
}
|
||||
// convert oid to String
|
||||
try {
|
||||
return Signature.getInstance(algName).getAlgorithm();
|
||||
} catch (Exception e) {
|
||||
throw new ProviderException("Error mapping algorithm name", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Utility method of creating an AlgorithmParameters object with
|
||||
// the specified algorithm name and encoding
|
||||
private static AlgorithmParameters createAlgorithmParameters(String algName,
|
||||
byte[] paramBytes) throws ProviderException {
|
||||
|
||||
try {
|
||||
algName = checkName(algName);
|
||||
AlgorithmParameters result =
|
||||
AlgorithmParameters.getInstance(algName);
|
||||
result.init(paramBytes);
|
||||
@ -54,52 +68,81 @@ public class SignatureUtil {
|
||||
}
|
||||
}
|
||||
|
||||
private static AlgorithmParameterSpec getParamSpec(String sigName,
|
||||
// Utility method for converting the specified AlgorithmParameters object
|
||||
// into an AlgorithmParameterSpec object.
|
||||
public static AlgorithmParameterSpec getParamSpec(String sigName,
|
||||
AlgorithmParameters params)
|
||||
throws InvalidAlgorithmParameterException, ProviderException {
|
||||
throws ProviderException {
|
||||
|
||||
if (params == null) return null;
|
||||
|
||||
if (sigName.toUpperCase().indexOf("RSA") == -1) {
|
||||
throw new ProviderException
|
||||
("Unrecognized algorithm for signature parameters " +
|
||||
sigName);
|
||||
}
|
||||
// AlgorithmParameters.getAlgorithm() may returns oid if it's
|
||||
// created during DER decoding. Convert to use the standard name
|
||||
// before passing it to RSAUtil
|
||||
String alg = params.getAlgorithm();
|
||||
if (alg.equalsIgnoreCase(sigName) || alg.indexOf(".") != -1) {
|
||||
try {
|
||||
params = createAlgorithmParameters(sigName,
|
||||
params.getEncoded());
|
||||
} catch (IOException e) {
|
||||
throw new ProviderException(e);
|
||||
sigName = checkName(sigName);
|
||||
AlgorithmParameterSpec paramSpec = null;
|
||||
if (params != null) {
|
||||
if (sigName.toUpperCase().indexOf("RSA") == -1) {
|
||||
throw new ProviderException
|
||||
("Unrecognized algorithm for signature parameters " +
|
||||
sigName);
|
||||
}
|
||||
// AlgorithmParameters.getAlgorithm() may returns oid if it's
|
||||
// created during DER decoding. Convert to use the standard name
|
||||
// before passing it to RSAUtil
|
||||
if (params.getAlgorithm().indexOf(".") != -1) {
|
||||
try {
|
||||
params = createAlgorithmParameters(sigName,
|
||||
params.getEncoded());
|
||||
} catch (IOException e) {
|
||||
throw new ProviderException(e);
|
||||
}
|
||||
}
|
||||
paramSpec = RSAUtil.getParamSpec(params);
|
||||
}
|
||||
return RSAUtil.getParamSpec(params);
|
||||
return paramSpec;
|
||||
}
|
||||
|
||||
// Special method for setting the specified parameter bytes into the
|
||||
// specified Signature object as signature parameters.
|
||||
public static void specialSetParameter(Signature sig, byte[] paramBytes)
|
||||
throws InvalidAlgorithmParameterException, ProviderException {
|
||||
// Utility method for converting the specified parameter bytes into an
|
||||
// AlgorithmParameterSpec object.
|
||||
public static AlgorithmParameterSpec getParamSpec(String sigName,
|
||||
byte[] paramBytes)
|
||||
throws ProviderException {
|
||||
sigName = checkName(sigName);
|
||||
AlgorithmParameterSpec paramSpec = null;
|
||||
if (paramBytes != null) {
|
||||
String sigName = sig.getAlgorithm();
|
||||
if (sigName.toUpperCase().indexOf("RSA") == -1) {
|
||||
throw new ProviderException
|
||||
("Unrecognized algorithm for signature parameters " +
|
||||
sigName);
|
||||
}
|
||||
AlgorithmParameters params =
|
||||
createAlgorithmParameters(sigName, paramBytes);
|
||||
specialSetParameter(sig, params);
|
||||
paramSpec = RSAUtil.getParamSpec(params);
|
||||
}
|
||||
return paramSpec;
|
||||
}
|
||||
|
||||
// Special method for setting the specified AlgorithmParameter object
|
||||
// into the specified Signature object as signature parameters.
|
||||
public static void specialSetParameter(Signature sig,
|
||||
AlgorithmParameters params)
|
||||
throws InvalidAlgorithmParameterException, ProviderException {
|
||||
if (params != null) {
|
||||
String sigName = sig.getAlgorithm();
|
||||
sig.setParameter(getParamSpec(sigName, params));
|
||||
}
|
||||
// Utility method for initializing the specified Signature object
|
||||
// for verification with the specified key and params (may be null)
|
||||
public static void initVerifyWithParam(Signature s, PublicKey key,
|
||||
AlgorithmParameterSpec params)
|
||||
throws ProviderException, InvalidAlgorithmParameterException,
|
||||
InvalidKeyException {
|
||||
SharedSecrets.getJavaSecuritySignatureAccess().initVerify(s, key, params);
|
||||
}
|
||||
|
||||
// Utility method for initializing the specified Signature object
|
||||
// for verification with the specified Certificate and params (may be null)
|
||||
public static void initVerifyWithParam(Signature s,
|
||||
java.security.cert.Certificate cert,
|
||||
AlgorithmParameterSpec params)
|
||||
throws ProviderException, InvalidAlgorithmParameterException,
|
||||
InvalidKeyException {
|
||||
SharedSecrets.getJavaSecuritySignatureAccess().initVerify(s, cert, params);
|
||||
}
|
||||
|
||||
// Utility method for initializing the specified Signature object
|
||||
// for signing with the specified key and params (may be null)
|
||||
public static void initSignWithParam(Signature s, PrivateKey key,
|
||||
AlgorithmParameterSpec params, SecureRandom sr)
|
||||
throws ProviderException, InvalidAlgorithmParameterException,
|
||||
InvalidKeyException {
|
||||
SharedSecrets.getJavaSecuritySignatureAccess().initSign(s, key, params, sr);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2019, 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
|
||||
@ -370,18 +370,16 @@ public class X509CRLImpl extends X509CRL implements DerEncoder {
|
||||
throw new CRLException("Uninitialized CRL");
|
||||
}
|
||||
Signature sigVerf = null;
|
||||
String sigName = sigAlgId.getName();
|
||||
if (sigProvider.isEmpty()) {
|
||||
sigVerf = Signature.getInstance(sigAlgId.getName());
|
||||
sigVerf = Signature.getInstance(sigName);
|
||||
} else {
|
||||
sigVerf = Signature.getInstance(sigAlgId.getName(), sigProvider);
|
||||
sigVerf = Signature.getInstance(sigName, sigProvider);
|
||||
}
|
||||
|
||||
sigVerf.initVerify(key);
|
||||
|
||||
// set parameters after Signature.initSign/initVerify call,
|
||||
// so the deferred provider selection happens when key is set
|
||||
try {
|
||||
SignatureUtil.specialSetParameter(sigVerf, getSigAlgParams());
|
||||
SignatureUtil.initVerifyWithParam(sigVerf, key,
|
||||
SignatureUtil.getParamSpec(sigName, getSigAlgParams()));
|
||||
} catch (ProviderException e) {
|
||||
throw new CRLException(e.getMessage(), e.getCause());
|
||||
} catch (InvalidAlgorithmParameterException e) {
|
||||
@ -425,18 +423,16 @@ public class X509CRLImpl extends X509CRL implements DerEncoder {
|
||||
throw new CRLException("Uninitialized CRL");
|
||||
}
|
||||
Signature sigVerf = null;
|
||||
String sigName = sigAlgId.getName();
|
||||
if (sigProvider == null) {
|
||||
sigVerf = Signature.getInstance(sigAlgId.getName());
|
||||
sigVerf = Signature.getInstance(sigName);
|
||||
} else {
|
||||
sigVerf = Signature.getInstance(sigAlgId.getName(), sigProvider);
|
||||
sigVerf = Signature.getInstance(sigName, sigProvider);
|
||||
}
|
||||
|
||||
sigVerf.initVerify(key);
|
||||
|
||||
// set parameters after Signature.initSign/initVerify call,
|
||||
// so the deferred provider selection happens when key is set
|
||||
try {
|
||||
SignatureUtil.specialSetParameter(sigVerf, getSigAlgParams());
|
||||
SignatureUtil.initVerifyWithParam(sigVerf, key,
|
||||
SignatureUtil.getParamSpec(sigName, getSigAlgParams()));
|
||||
} catch (ProviderException e) {
|
||||
throw new CRLException(e.getMessage(), e.getCause());
|
||||
} catch (InvalidAlgorithmParameterException e) {
|
||||
@ -502,7 +498,7 @@ public class X509CRLImpl extends X509CRL implements DerEncoder {
|
||||
|
||||
sigEngine.initSign(key);
|
||||
|
||||
// in case the name is reset
|
||||
// in case the name is reset
|
||||
sigAlgId = AlgorithmId.get(sigEngine.getAlgorithm());
|
||||
infoSigAlgId = sigAlgId;
|
||||
|
||||
|
@ -422,18 +422,16 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
||||
}
|
||||
// Verify the signature ...
|
||||
Signature sigVerf = null;
|
||||
String sigName = algId.getName();
|
||||
if (sigProvider.isEmpty()) {
|
||||
sigVerf = Signature.getInstance(algId.getName());
|
||||
sigVerf = Signature.getInstance(sigName);
|
||||
} else {
|
||||
sigVerf = Signature.getInstance(algId.getName(), sigProvider);
|
||||
sigVerf = Signature.getInstance(sigName, sigProvider);
|
||||
}
|
||||
|
||||
sigVerf.initVerify(key);
|
||||
|
||||
// set parameters after Signature.initSign/initVerify call,
|
||||
// so the deferred provider selection happens when key is set
|
||||
try {
|
||||
SignatureUtil.specialSetParameter(sigVerf, getSigAlgParams());
|
||||
SignatureUtil.initVerifyWithParam(sigVerf, key,
|
||||
SignatureUtil.getParamSpec(sigName, getSigAlgParams()));
|
||||
} catch (ProviderException e) {
|
||||
throw new CertificateException(e.getMessage(), e.getCause());
|
||||
} catch (InvalidAlgorithmParameterException e) {
|
||||
@ -478,18 +476,16 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
||||
}
|
||||
// Verify the signature ...
|
||||
Signature sigVerf = null;
|
||||
String sigName = algId.getName();
|
||||
if (sigProvider == null) {
|
||||
sigVerf = Signature.getInstance(algId.getName());
|
||||
sigVerf = Signature.getInstance(sigName);
|
||||
} else {
|
||||
sigVerf = Signature.getInstance(algId.getName(), sigProvider);
|
||||
sigVerf = Signature.getInstance(sigName, sigProvider);
|
||||
}
|
||||
|
||||
sigVerf.initVerify(key);
|
||||
|
||||
// set parameters after Signature.initSign/initVerify call,
|
||||
// so the deferred provider selection happens when key is set
|
||||
try {
|
||||
SignatureUtil.specialSetParameter(sigVerf, getSigAlgParams());
|
||||
SignatureUtil.initVerifyWithParam(sigVerf, key,
|
||||
SignatureUtil.getParamSpec(sigName, getSigAlgParams()));
|
||||
} catch (ProviderException e) {
|
||||
throw new CertificateException(e.getMessage(), e.getCause());
|
||||
} catch (InvalidAlgorithmParameterException e) {
|
||||
@ -587,22 +583,19 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
|
||||
InvalidKeyException, InvalidAlgorithmParameterException,
|
||||
NoSuchProviderException, SignatureException {
|
||||
try {
|
||||
if (readOnly)
|
||||
if (readOnly) {
|
||||
throw new CertificateEncodingException(
|
||||
"cannot over-write existing certificate");
|
||||
Signature sigEngine = null;
|
||||
if (provider == null || provider.isEmpty())
|
||||
sigEngine = Signature.getInstance(algorithm);
|
||||
else
|
||||
sigEngine = Signature.getInstance(algorithm, provider);
|
||||
|
||||
sigEngine.initSign(key);
|
||||
|
||||
if (signingParams != null) {
|
||||
// set parameters after Signature.initSign/initVerify call, so
|
||||
// the deferred provider selection happens when the key is set
|
||||
sigEngine.setParameter(signingParams);
|
||||
"cannot over-write existing certificate");
|
||||
}
|
||||
Signature sigEngine = null;
|
||||
if (provider == null || provider.isEmpty()) {
|
||||
sigEngine = Signature.getInstance(algorithm);
|
||||
} else {
|
||||
sigEngine = Signature.getInstance(algorithm, provider);
|
||||
}
|
||||
|
||||
SignatureUtil.initSignWithParam(sigEngine, key, signingParams,
|
||||
null);
|
||||
|
||||
// in case the name is reset
|
||||
if (signingParams != null) {
|
||||
|
239
test/jdk/java/security/Signature/SignatureGetInstance.java
Normal file
239
test/jdk/java/security/Signature/SignatureGetInstance.java
Normal file
@ -0,0 +1,239 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8216039
|
||||
* @summary Ensure the BC provider-reselection workaround in Signature class
|
||||
* functions correctly
|
||||
* @modules java.base/sun.security.util
|
||||
* @run main/othervm SignatureGetInstance
|
||||
*/
|
||||
import java.security.*;
|
||||
import java.security.interfaces.*;
|
||||
import java.security.spec.*;
|
||||
import sun.security.util.SignatureUtil;
|
||||
|
||||
public class SignatureGetInstance {
|
||||
|
||||
private static final String SIGALG = "RSASSA-PSS";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Provider testProvider = new TestProvider();
|
||||
// put test provider before SunRsaSign provider
|
||||
Security.insertProviderAt(testProvider, 1);
|
||||
//Security.addProvider(testProvider);
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
|
||||
KeyPair kp = kpg.generateKeyPair();
|
||||
|
||||
MyPrivKey testPriv = new MyPrivKey();
|
||||
MyPubKey testPub = new MyPubKey();
|
||||
|
||||
testDblInit(testPriv, testPub, true, "TestProvider");
|
||||
testDblInit(kp.getPrivate(), kp.getPublic(), true, "SunRsaSign");
|
||||
testDblInit(testPriv, kp.getPublic(), false, null);
|
||||
testDblInit(kp.getPrivate(), testPub, false, null);
|
||||
|
||||
testSetAndInit(null, testPriv, true);
|
||||
testSetAndInit(null, testPub, true);
|
||||
testSetAndInit(null, kp.getPrivate(), true);
|
||||
testSetAndInit(null, kp.getPublic(), true);
|
||||
|
||||
String provName = "SunRsaSign";
|
||||
testSetAndInit(provName, testPriv, false);
|
||||
testSetAndInit(provName, testPub, false);
|
||||
testSetAndInit(provName, kp.getPrivate(), true);
|
||||
testSetAndInit(provName, kp.getPublic(), true);
|
||||
|
||||
provName = "TestProvider";
|
||||
testSetAndInit(provName, testPriv, true);
|
||||
testSetAndInit(provName, testPub, true);
|
||||
testSetAndInit(provName, kp.getPrivate(), false);
|
||||
testSetAndInit(provName, kp.getPublic(), false);
|
||||
|
||||
System.out.println("Test Passed");
|
||||
}
|
||||
|
||||
private static void checkName(Signature s, String name) {
|
||||
if (name != null &&
|
||||
!(name.equals(s.getProvider().getName()))) {
|
||||
throw new RuntimeException("Fail: provider name mismatch");
|
||||
}
|
||||
}
|
||||
|
||||
private static void testDblInit(PrivateKey key1, PublicKey key2,
|
||||
boolean shouldPass, String expectedProvName) throws Exception {
|
||||
Signature sig = Signature.getInstance(SIGALG);
|
||||
SignatureUtil.initSignWithParam(sig, key1, PSSParameterSpec.DEFAULT, null);
|
||||
try {
|
||||
sig.initVerify(key2);
|
||||
if (!shouldPass) {
|
||||
throw new RuntimeException("Fail: should throw InvalidKeyException");
|
||||
}
|
||||
checkName(sig, expectedProvName);
|
||||
} catch (InvalidKeyException ike) {
|
||||
if (shouldPass) {
|
||||
System.out.println("Fail: Unexpected InvalidKeyException");
|
||||
throw ike;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void testSetAndInit(String provName, Key key,
|
||||
boolean shouldPass) throws Exception {
|
||||
Signature sig;
|
||||
if (provName == null) {
|
||||
sig = Signature.getInstance(SIGALG);
|
||||
} else {
|
||||
sig = Signature.getInstance(SIGALG, provName);
|
||||
}
|
||||
AlgorithmParameterSpec params = PSSParameterSpec.DEFAULT;
|
||||
boolean doSign = (key instanceof PrivateKey);
|
||||
try {
|
||||
if (doSign) {
|
||||
SignatureUtil.initSignWithParam(sig, (PrivateKey)key, params, null);
|
||||
} else {
|
||||
SignatureUtil.initVerifyWithParam(sig, (PublicKey)key, params);
|
||||
}
|
||||
if (!shouldPass) {
|
||||
throw new RuntimeException("Fail: should throw InvalidKeyException");
|
||||
}
|
||||
checkName(sig, provName);
|
||||
// check that the earlier parameter is still there
|
||||
if (sig.getParameters() == null) {
|
||||
throw new RuntimeException("Fail: parameters not preserved");
|
||||
}
|
||||
} catch (InvalidKeyException ike) {
|
||||
if (shouldPass) {
|
||||
System.out.println("Fail: Unexpected InvalidKeyException");
|
||||
throw ike;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test provider which only accepts its own Key objects
|
||||
// Registered to be more preferred than SunRsaSign provider
|
||||
// for testing deferred provider selection
|
||||
public static class TestProvider extends Provider {
|
||||
TestProvider() {
|
||||
super("TestProvider", "1.0", "provider for SignatureGetInstance");
|
||||
put("Signature.RSASSA-PSS",
|
||||
"SignatureGetInstance$MySigImpl");
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyPrivKey implements PrivateKey {
|
||||
public String getAlgorithm() { return "RSASSA-PSS"; }
|
||||
public String getFormat() { return "MyOwn"; }
|
||||
public byte[] getEncoded() { return null; }
|
||||
}
|
||||
|
||||
public static class MyPubKey implements PublicKey {
|
||||
public String getAlgorithm() { return "RSASSA-PSS"; }
|
||||
public String getFormat() { return "MyOwn"; }
|
||||
public byte[] getEncoded() { return null; }
|
||||
}
|
||||
|
||||
public static class MySigImpl extends SignatureSpi {
|
||||
// simulate BC behavior of only using params set before init calls
|
||||
AlgorithmParameterSpec initParamSpec = null;
|
||||
AlgorithmParameterSpec paramSpec = null;
|
||||
|
||||
public MySigImpl() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void engineInitVerify(PublicKey publicKey)
|
||||
throws InvalidKeyException {
|
||||
if (!(publicKey instanceof MyPubKey)) {
|
||||
throw new InvalidKeyException("Must be MyPubKey");
|
||||
}
|
||||
initParamSpec = paramSpec;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void engineInitSign(PrivateKey privateKey)
|
||||
throws InvalidKeyException {
|
||||
if (!(privateKey instanceof MyPrivKey)) {
|
||||
throw new InvalidKeyException("Must be MyPrivKey");
|
||||
}
|
||||
initParamSpec = paramSpec;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void engineUpdate(byte b) throws SignatureException {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void engineUpdate(byte[] b, int off, int len)
|
||||
throws SignatureException {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected byte[] engineSign()
|
||||
throws SignatureException {
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean engineVerify(byte[] sigBytes)
|
||||
throws SignatureException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
protected void engineSetParameter(String param, Object value)
|
||||
throws InvalidParameterException {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void engineSetParameter(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
paramSpec = params;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
protected AlgorithmParameters engineGetParameter(String param)
|
||||
throws InvalidParameterException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AlgorithmParameters engineGetParameters() {
|
||||
if (initParamSpec != null) {
|
||||
try {
|
||||
AlgorithmParameters ap =
|
||||
AlgorithmParameters.getInstance("RSASSA-PSS");
|
||||
ap.init(initParamSpec);
|
||||
return ap;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, 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
|
||||
@ -23,8 +23,8 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8214096
|
||||
* @summary Make sure SignatureUtil can accept null algorithm parameters
|
||||
* @bug 8214096 8216039
|
||||
* @summary Make sure SignatureUtil works with null algorithm parameters
|
||||
* @modules java.base/sun.security.util
|
||||
*/
|
||||
import java.security.*;
|
||||
@ -35,8 +35,8 @@ public class SetNullSigParams {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Signature sig = new SpecialSigImpl();
|
||||
SignatureUtil.specialSetParameter(sig, (byte[]) null);
|
||||
SignatureUtil.specialSetParameter(sig, (AlgorithmParameters) null);
|
||||
SignatureUtil.initVerifyWithParam(sig, (PublicKey) null, null);
|
||||
SignatureUtil.initSignWithParam(sig, null, null, null);
|
||||
}
|
||||
|
||||
// Sample Signature impl class which simulates 3rd party provider behavior
|
||||
|
Loading…
Reference in New Issue
Block a user