diff -r 423fab158db3 -r 0d68f70ab984 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; } }