8217610: TLSv1.3 fail with ClassException when EC keys are stored in PKCS11
authorxuelei
Wed, 03 Apr 2019 16:23:22 -0700
changeset 54417 f87041131515
parent 54416 b788c494aa46
child 54418 e998c9effb37
8217610: TLSv1.3 fail with ClassException when EC keys are stored in PKCS11 Reviewed-by: valeriep
src/java.base/share/classes/sun/security/ssl/CertificateVerify.java
src/java.base/share/classes/sun/security/ssl/DHServerKeyExchange.java
src/java.base/share/classes/sun/security/ssl/ECDHClientKeyExchange.java
src/java.base/share/classes/sun/security/ssl/ECDHKeyExchange.java
src/java.base/share/classes/sun/security/ssl/ECDHServerKeyExchange.java
src/java.base/share/classes/sun/security/ssl/SignatureScheme.java
src/java.base/share/classes/sun/security/ssl/X509Authentication.java
--- a/src/java.base/share/classes/sun/security/ssl/CertificateVerify.java	Wed Apr 03 22:03:39 2019 +0000
+++ b/src/java.base/share/classes/sun/security/ssl/CertificateVerify.java	Wed Apr 03 16:23:22 2019 -0700
@@ -565,7 +565,7 @@
             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 @@
 
             this.signatureScheme = SignatureScheme.getPreferableAlgorithm(
                     context.peerRequestedSignatureSchemes,
-                    x509Possession.popPrivateKey,
+                    x509Possession,
                     context.negotiatedProtocol);
             if (signatureScheme == null) {
                 // Unlikely, the credentials generator should have
--- a/src/java.base/share/classes/sun/security/ssl/DHServerKeyExchange.java	Wed Apr 03 22:03:39 2019 +0000
+++ b/src/java.base/share/classes/sun/security/ssl/DHServerKeyExchange.java	Wed Apr 03 16:23:22 2019 -0700
@@ -127,7 +127,7 @@
                 if (useExplicitSigAlgorithm) {
                     signatureScheme = SignatureScheme.getPreferableAlgorithm(
                             shc.peerRequestedSignatureSchemes,
-                            x509Possession.popPrivateKey,
+                            x509Possession,
                             shc.negotiatedProtocol);
                     if (signatureScheme == null) {
                         // Unlikely, the credentials generator should have
--- a/src/java.base/share/classes/sun/security/ssl/ECDHClientKeyExchange.java	Wed Apr 03 22:03:39 2019 +0000
+++ b/src/java.base/share/classes/sun/security/ssl/ECDHClientKeyExchange.java	Wed Apr 03 16:23:22 2019 -0700
@@ -31,9 +31,7 @@
 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 @@
                     "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.
--- a/src/java.base/share/classes/sun/security/ssl/ECDHKeyExchange.java	Wed Apr 03 22:03:39 2019 +0000
+++ b/src/java.base/share/classes/sun/security/ssl/ECDHKeyExchange.java	Wed Apr 03 16:23:22 2019 -0700
@@ -35,7 +35,6 @@
 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 @@
                     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.
--- a/src/java.base/share/classes/sun/security/ssl/ECDHServerKeyExchange.java	Wed Apr 03 22:03:39 2019 +0000
+++ b/src/java.base/share/classes/sun/security/ssl/ECDHServerKeyExchange.java	Wed Apr 03 16:23:22 2019 -0700
@@ -142,7 +142,7 @@
                 if (useExplicitSigAlgorithm) {
                     signatureScheme = SignatureScheme.getPreferableAlgorithm(
                             shc.peerRequestedSignatureSchemes,
-                            x509Possession.popPrivateKey,
+                            x509Possession,
                             shc.negotiatedProtocol);
                     if (signatureScheme == null) {
                         // Unlikely, the credentials generator should have
--- a/src/java.base/share/classes/sun/security/ssl/SignatureScheme.java	Wed Apr 03 22:03:39 2019 +0000
+++ b/src/java.base/share/classes/sun/security/ssl/SignatureScheme.java	Wed Apr 03 16:23:22 2019 -0700
@@ -41,6 +41,7 @@
 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 @@
 
     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 @@
                 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 {
--- a/src/java.base/share/classes/sun/security/ssl/X509Authentication.java	Wed Apr 03 22:03:39 2019 +0000
+++ b/src/java.base/share/classes/sun/security/ssl/X509Authentication.java	Wed Apr 03 16:23:22 2019 -0700
@@ -28,6 +28,7 @@
 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 @@
             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 {