8078661: [SunPKCS11] Fails to cast into RSAPrivateCrtKey after RSA KeyPair Generation
authorvaleriep
Fri, 19 Aug 2016 23:24:23 +0000
changeset 40453 0d68f70ab984
parent 40452 423fab158db3
child 40454 84a6dc93eef8
8078661: [SunPKCS11] Fails to cast into RSAPrivateCrtKey after RSA KeyPair Generation Summary: Changed to check all components instead of only the public exponent for RSA CRT key determination Reviewed-by: vinnie
jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11Key.java
--- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11Key.java	Fri Aug 19 22:15:32 2016 +0100
+++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11Key.java	Fri Aug 19 23:24:23 2016 +0000
@@ -340,25 +340,33 @@
         } else {
             switch (algorithm) {
                 case "RSA":
-                    // XXX better test for RSA CRT keys (single getAttributes() call)
-                    // we need to determine whether this is a CRT key
-                    // see if we can obtain the public exponent
-                    // this should also be readable for sensitive/extractable keys
+                    // In order to decide if this is RSA CRT key, we first query
+                    // and see if all extra CRT attributes are available.
                     CK_ATTRIBUTE[] attrs2 = new CK_ATTRIBUTE[] {
                         new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT),
+                        new CK_ATTRIBUTE(CKA_PRIME_1),
+                        new CK_ATTRIBUTE(CKA_PRIME_2),
+                        new CK_ATTRIBUTE(CKA_EXPONENT_1),
+                        new CK_ATTRIBUTE(CKA_EXPONENT_2),
+                        new CK_ATTRIBUTE(CKA_COEFFICIENT),
                     };
                     boolean crtKey;
                     try {
                         session.token.p11.C_GetAttributeValue
                             (session.id(), keyID, attrs2);
-                        crtKey = (attrs2[0].pValue instanceof byte[]);
+                        crtKey = ((attrs2[0].pValue instanceof byte[]) &&
+                                  (attrs2[1].pValue instanceof byte[]) &&
+                                  (attrs2[2].pValue instanceof byte[]) &&
+                                  (attrs2[3].pValue instanceof byte[]) &&
+                                  (attrs2[4].pValue instanceof byte[]) &&
+                                  (attrs2[5].pValue instanceof byte[])) ;
                     } catch (PKCS11Exception e) {
                         // ignore, assume not available
                         crtKey = false;
                     }
                     if (crtKey) {
                         return new P11RSAPrivateKey
-                                (session, keyID, algorithm, keyLength, attributes);
+                                (session, keyID, algorithm, keyLength, attributes, attrs2);
                     } else {
                         return new P11RSAPrivateNonCRTKey
                                 (session, keyID, algorithm, keyLength, attributes);
@@ -475,8 +483,24 @@
         private BigInteger n, e, d, p, q, pe, qe, coeff;
         private byte[] encoded;
         P11RSAPrivateKey(Session session, long keyID, String algorithm,
-                int keyLength, CK_ATTRIBUTE[] attributes) {
-            super(PRIVATE, session, keyID, algorithm, keyLength, attributes);
+                int keyLength, CK_ATTRIBUTE[] attrs, CK_ATTRIBUTE[] crtAttrs) {
+            super(PRIVATE, session, keyID, algorithm, keyLength, attrs);
+
+            for (CK_ATTRIBUTE a : crtAttrs) {
+                if (a.type == CKA_PUBLIC_EXPONENT) {
+                    e = a.getBigInteger();
+                } else if (a.type == CKA_PRIME_1) {
+                    p = a.getBigInteger();
+                } else if (a.type == CKA_PRIME_2) {
+                    q = a.getBigInteger();
+                } else if (a.type == CKA_EXPONENT_1) {
+                    pe = a.getBigInteger();
+                } else if (a.type == CKA_EXPONENT_2) {
+                    qe = a.getBigInteger();
+                } else if (a.type == CKA_COEFFICIENT) {
+                    coeff = a.getBigInteger();
+                }
+            }
         }
         private synchronized void fetchValues() {
             token.ensureValid();
@@ -485,24 +509,13 @@
             }
             CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
                 new CK_ATTRIBUTE(CKA_MODULUS),
-                new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT),
                 new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT),
-                new CK_ATTRIBUTE(CKA_PRIME_1),
-                new CK_ATTRIBUTE(CKA_PRIME_2),
-                new CK_ATTRIBUTE(CKA_EXPONENT_1),
-                new CK_ATTRIBUTE(CKA_EXPONENT_2),
-                new CK_ATTRIBUTE(CKA_COEFFICIENT),
             };
             fetchAttributes(attributes);
             n = attributes[0].getBigInteger();
-            e = attributes[1].getBigInteger();
-            d = attributes[2].getBigInteger();
-            p = attributes[3].getBigInteger();
-            q = attributes[4].getBigInteger();
-            pe = attributes[5].getBigInteger();
-            qe = attributes[6].getBigInteger();
-            coeff = attributes[7].getBigInteger();
+            d = attributes[1].getBigInteger();
         }
+
         public String getFormat() {
             token.ensureValid();
             return "PKCS#8";
@@ -529,7 +542,6 @@
             return n;
         }
         public BigInteger getPublicExponent() {
-            fetchValues();
             return e;
         }
         public BigInteger getPrivateExponent() {
@@ -537,23 +549,18 @@
             return d;
         }
         public BigInteger getPrimeP() {
-            fetchValues();
             return p;
         }
         public BigInteger getPrimeQ() {
-            fetchValues();
             return q;
         }
         public BigInteger getPrimeExponentP() {
-            fetchValues();
             return pe;
         }
         public BigInteger getPrimeExponentQ() {
-            fetchValues();
             return qe;
         }
         public BigInteger getCrtCoefficient() {
-            fetchValues();
             return coeff;
         }
     }