mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
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
15 changed files with 723 additions and 177 deletions
|
@ -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) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue