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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -28,6 +28,7 @@ package sun.security.ssl;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.security.PublicKey; import java.security.PublicKey;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.security.interfaces.ECKey;
import java.security.interfaces.ECPublicKey; import java.security.interfaces.ECPublicKey;
import java.security.spec.ECParameterSpec; import java.security.spec.ECParameterSpec;
import java.util.AbstractMap.SimpleImmutableEntry; import java.util.AbstractMap.SimpleImmutableEntry;
@ -127,6 +128,26 @@ enum X509Authentication implements SSLAuthentication {
this.popCerts = popCerts; this.popCerts = popCerts;
this.popPrivateKey = popPrivateKey; 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 { static final class X509Credentials implements SSLCredentials {