8217610: TLSv1.3 fail with ClassException when EC keys are stored in PKCS11

Reviewed-by: valeriep
This commit is contained in:
Xue-Lei Andrew Fan 2019-04-03 16:23:22 -07:00
parent 2f20909d10
commit 661b5f1534
7 changed files with 36 additions and 16 deletions

@ -565,7 +565,7 @@ final class CertificateVerify {
ClientHandshakeContext chc = (ClientHandshakeContext)context;
this.signatureScheme = SignatureScheme.getPreferableAlgorithm(
chc.peerRequestedSignatureSchemes,
x509Possession.popPrivateKey,
x509Possession,
chc.negotiatedProtocol);
if (signatureScheme == null) {
// Unlikely, the credentials generator should have
@ -866,7 +866,7 @@ final class CertificateVerify {
this.signatureScheme = SignatureScheme.getPreferableAlgorithm(
context.peerRequestedSignatureSchemes,
x509Possession.popPrivateKey,
x509Possession,
context.negotiatedProtocol);
if (signatureScheme == null) {
// Unlikely, the credentials generator should have

@ -127,7 +127,7 @@ final class DHServerKeyExchange {
if (useExplicitSigAlgorithm) {
signatureScheme = SignatureScheme.getPreferableAlgorithm(
shc.peerRequestedSignatureSchemes,
x509Possession.popPrivateKey,
x509Possession,
shc.negotiatedProtocol);
if (signatureScheme == null) {
// Unlikely, the credentials generator should have

@ -31,9 +31,7 @@ import java.security.AlgorithmConstraints;
import java.security.CryptoPrimitive;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECParameterSpec;
import java.security.spec.ECPoint;
@ -285,14 +283,13 @@ final class ECDHClientKeyExchange {
"No expected EC server cert for ECDH client key exchange");
}
PrivateKey privateKey = x509Possession.popPrivateKey;
if (!privateKey.getAlgorithm().equals("EC")) {
ECParameterSpec params = x509Possession.getECParameterSpec();
if (params == null) {
// unlikely, have been checked during cipher suite negotiation.
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
"Not EC server cert for ECDH client key exchange");
}
ECParameterSpec params = ((ECPrivateKey)privateKey).getParams();
NamedGroup namedGroup = NamedGroup.valueOf(params);
if (namedGroup == null) {
// unlikely, have been checked during cipher suite negotiation.

@ -35,7 +35,6 @@ import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.ECGenParameterSpec;
@ -265,12 +264,12 @@ final class ECDHKeyExchange {
continue;
}
PrivateKey privateKey = ((X509Possession)poss).popPrivateKey;
if (!privateKey.getAlgorithm().equals("EC")) {
ECParameterSpec params =
((X509Possession)poss).getECParameterSpec();
if (params == null) {
continue;
}
ECParameterSpec params = ((ECPrivateKey)privateKey).getParams();
NamedGroup ng = NamedGroup.valueOf(params);
if (ng == null) {
// unlikely, have been checked during cipher suite negotiation.

@ -142,7 +142,7 @@ final class ECDHServerKeyExchange {
if (useExplicitSigAlgorithm) {
signatureScheme = SignatureScheme.getPreferableAlgorithm(
shc.peerRequestedSignatureSchemes,
x509Possession.popPrivateKey,
x509Possession,
shc.negotiatedProtocol);
if (signatureScheme == null) {
// Unlikely, the credentials generator should have

@ -41,6 +41,7 @@ import java.util.List;
import java.util.Set;
import sun.security.ssl.SupportedGroupsExtension.NamedGroup;
import sun.security.ssl.SupportedGroupsExtension.NamedGroupType;
import sun.security.ssl.X509Authentication.X509Possession;
import sun.security.util.KeyUtil;
enum SignatureScheme {
@ -415,9 +416,10 @@ enum SignatureScheme {
static SignatureScheme getPreferableAlgorithm(
List<SignatureScheme> schemes,
PrivateKey signingKey,
X509Possession x509Possession,
ProtocolVersion version) {
PrivateKey signingKey = x509Possession.popPrivateKey;
String keyAlgorithm = signingKey.getAlgorithm();
int keySize;
// Only need to check RSA algorithm at present.
@ -434,8 +436,9 @@ enum SignatureScheme {
if (ss.namedGroup != null &&
ss.namedGroup.type == NamedGroupType.NAMED_GROUP_ECDHE) {
ECParameterSpec params =
((ECPrivateKey)signingKey).getParams();
if (ss.namedGroup == NamedGroup.valueOf(params)) {
x509Possession.getECParameterSpec();
if (params != null &&
ss.namedGroup == NamedGroup.valueOf(params)) {
return ss;
}
} else {

@ -28,6 +28,7 @@ package sun.security.ssl;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.security.interfaces.ECKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECParameterSpec;
import java.util.AbstractMap.SimpleImmutableEntry;
@ -127,6 +128,26 @@ enum X509Authentication implements SSLAuthentication {
this.popCerts = popCerts;
this.popPrivateKey = popPrivateKey;
}
ECParameterSpec getECParameterSpec() {
if (popPrivateKey == null ||
!"EC".equals(popPrivateKey.getAlgorithm())) {
return null;
}
if (popPrivateKey instanceof ECKey) {
return ((ECKey)popPrivateKey).getParams();
} else if (popCerts != null && popCerts.length != 0) {
// The private key not extractable, get the parameters from
// the X.509 certificate.
PublicKey publicKey = popCerts[0].getPublicKey();
if (publicKey instanceof ECKey) {
return ((ECKey)publicKey).getParams();
}
}
return null;
}
}
static final class X509Credentials implements SSLCredentials {