Skip to content

Commit f3d97d5

Browse files
franferraxmartinuy
andcommitted
RH2023467: Enable FIPS keys export v6
Co-Authored-By: Martin Balao <[email protected]>
1 parent 62ffef3 commit f3d97d5

File tree

5 files changed

+124
-148
lines changed

5 files changed

+124
-148
lines changed

src/java.base/share/classes/sun/security/rsa/SunRsaSignEntries.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,13 @@ public SunRsaSignEntries(Provider p) {
6565
attrs.put("SupportedKeyClasses",
6666
"java.security.interfaces.RSAPublicKey" +
6767
"|java.security.interfaces.RSAPrivateKey");
68+
}
6869

69-
add(p, "KeyFactory", "RSA",
70-
"sun.security.rsa.RSAKeyFactory$Legacy",
71-
getAliases("PKCS1"), null);
70+
add(p, "KeyFactory", "RSA",
71+
"sun.security.rsa.RSAKeyFactory$Legacy",
72+
getAliases("PKCS1"), null);
73+
74+
if (!systemFipsEnabled) {
7275
add(p, "KeyPairGenerator", "RSA",
7376
"sun.security.rsa.RSAKeyPairGenerator$Legacy",
7477
getAliases("PKCS1"), null);
@@ -98,9 +101,12 @@ public SunRsaSignEntries(Provider p) {
98101
"sun.security.rsa.RSASignature$SHA3_384withRSA", attrs);
99102
addA(p, "Signature", "SHA3-512withRSA",
100103
"sun.security.rsa.RSASignature$SHA3_512withRSA", attrs);
104+
}
105+
106+
addA(p, "KeyFactory", "RSASSA-PSS",
107+
"sun.security.rsa.RSAKeyFactory$PSS", attrs);
101108

102-
addA(p, "KeyFactory", "RSASSA-PSS",
103-
"sun.security.rsa.RSAKeyFactory$PSS", attrs);
109+
if (!systemFipsEnabled) {
104110
addA(p, "KeyPairGenerator", "RSASSA-PSS",
105111
"sun.security.rsa.RSAKeyPairGenerator$PSS", attrs);
106112
addA(p, "Signature", "RSASSA-PSS",

src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/FIPSKeyImporter.java

Lines changed: 80 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
import java.security.KeyFactory;
3030
import java.security.Provider;
3131
import java.security.Security;
32-
import java.security.interfaces.ECPrivateKey;
32+
import java.security.interfaces.RSAPrivateCrtKey;
3333
import java.security.interfaces.RSAPrivateKey;
3434
import java.util.HashMap;
3535
import java.util.Map;
@@ -48,6 +48,8 @@
4848
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
4949
import static sun.security.pkcs11.wrapper.PKCS11Exception.*;
5050
import sun.security.pkcs11.wrapper.PKCS11Exception;
51+
import sun.security.rsa.RSAPrivateCrtKeyImpl;
52+
import sun.security.rsa.RSAUtil;
5153
import sun.security.rsa.RSAUtil.KeyType;
5254
import sun.security.util.Debug;
5355
import sun.security.util.ECUtil;
@@ -271,7 +273,8 @@ static Long importKey(SunPKCS11 sunPKCS11, long hSession, CK_ATTRIBUTE[] attribu
271273
}
272274

273275
static void exportKey(SunPKCS11 sunPKCS11, long hSession, long hObject,
274-
long keyClass, CK_ATTRIBUTE[] attributes) throws PKCS11Exception {
276+
long keyClass, long keyType, Map<Long, CK_ATTRIBUTE> sensitiveAttrs)
277+
throws PKCS11Exception {
275278
Token token = sunPKCS11.getToken();
276279
if (debug != null) {
277280
debug.println("Private or Secret key will be exported in" +
@@ -316,60 +319,12 @@ static void exportKey(SunPKCS11 sunPKCS11, long hSession, long hObject,
316319
exporterKeyLock.unlock();
317320
}
318321
if (keyClass == CKO_PRIVATE_KEY) {
319-
long keyType = 0L;
320-
for (CK_ATTRIBUTE attr : attributes) {
321-
if (attr.type == CKA_KEY_TYPE) {
322-
keyType = attr.getLong();
323-
}
324-
}
325-
if (keyType == CKK_RSA) {
326-
RSAPrivateKey rsaKey = sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(
327-
sun.security.rsa.RSAUtil.KeyType.RSA,
328-
"PKCS#8",
329-
plainExportedKey);
330-
for (CK_ATTRIBUTE attr : attributes) {
331-
if (attr.type == CKA_MODULUS) {
332-
attr.pValue = rsaKey.getModulus().toByteArray();
333-
} else if (attr.type == CKA_PRIVATE_EXPONENT) {
334-
attr.pValue = rsaKey.getPrivateExponent().toByteArray();
335-
}
336-
}
337-
} else if (keyType == CKK_DSA) {
338-
sun.security.provider.DSAPrivateKey dsaKey =
339-
new sun.security.provider.DSAPrivateKey(plainExportedKey);
340-
for (CK_ATTRIBUTE attr : attributes) {
341-
if (attr.type == CKA_VALUE) {
342-
attr.pValue = dsaKey.getX().toByteArray();
343-
} else if (attr.type == CKA_PRIME) {
344-
attr.pValue = dsaKey.getParams().getP().toByteArray();
345-
} else if (attr.type == CKA_SUBPRIME) {
346-
attr.pValue = dsaKey.getParams().getQ().toByteArray();
347-
} else if (attr.type == CKA_BASE) {
348-
attr.pValue = dsaKey.getParams().getG().toByteArray();
349-
}
350-
}
351-
} else if (keyType == CKK_EC) {
352-
ECPrivateKey ecKey =
353-
ECUtil.decodePKCS8ECPrivateKey(plainExportedKey);
354-
for (CK_ATTRIBUTE attr : attributes) {
355-
if (attr.type == CKA_VALUE) {
356-
attr.pValue = ecKey.getS().toByteArray();
357-
} else if (attr.type == CKA_EC_PARAMS) {
358-
attr.pValue = sun.security.util.CurveDB.lookup(
359-
ecKey.getParams()).getEncoded();
360-
}
361-
}
362-
} else {
363-
throw new PKCS11Exception(CKR_GENERAL_ERROR,
364-
" fips key exporter");
365-
}
322+
exportPrivateKey(sensitiveAttrs, keyType, plainExportedKey);
366323
} else if (keyClass == CKO_SECRET_KEY) {
367-
for (CK_ATTRIBUTE attr : attributes) {
368-
if (attr.type == CKA_VALUE) {
369-
attr.pValue = plainExportedKey;
370-
break;
371-
}
372-
}
324+
checkAttrs(sensitiveAttrs, "CKO_SECRET_KEY", CKA_VALUE);
325+
// CKA_VALUE is guaranteed to be present, since sensitiveAttrs'
326+
// size is greater than 0 and no invalid attributes exist
327+
sensitiveAttrs.get(CKA_VALUE).pValue = plainExportedKey;
373328
} else {
374329
throw new PKCS11Exception(CKR_GENERAL_ERROR,
375330
" fips key exporter");
@@ -385,6 +340,76 @@ static void exportKey(SunPKCS11 sunPKCS11, long hSession, long hObject,
385340
}
386341
}
387342

343+
private static void exportPrivateKey(
344+
Map<Long, CK_ATTRIBUTE> sensitiveAttrs, long keyType,
345+
byte[] plainExportedKey) throws Throwable {
346+
if (keyType == CKK_RSA) {
347+
checkAttrs(sensitiveAttrs, "CKO_PRIVATE_KEY CKK_RSA",
348+
CKA_PRIVATE_EXPONENT, CKA_PRIME_1, CKA_PRIME_2,
349+
CKA_EXPONENT_1, CKA_EXPONENT_2, CKA_COEFFICIENT);
350+
RSAPrivateKey rsaPKey = RSAPrivateCrtKeyImpl.newKey(
351+
RSAUtil.KeyType.RSA, "PKCS#8", plainExportedKey
352+
);
353+
CK_ATTRIBUTE attr;
354+
if ((attr = sensitiveAttrs.get(CKA_PRIVATE_EXPONENT)) != null) {
355+
attr.pValue = rsaPKey.getPrivateExponent().toByteArray();
356+
}
357+
if (rsaPKey instanceof RSAPrivateCrtKey) {
358+
RSAPrivateCrtKey rsaPCrtKey = (RSAPrivateCrtKey) rsaPKey;
359+
if ((attr = sensitiveAttrs.get(CKA_PRIME_1)) != null) {
360+
attr.pValue = rsaPCrtKey.getPrimeP().toByteArray();
361+
}
362+
if ((attr = sensitiveAttrs.get(CKA_PRIME_2)) != null) {
363+
attr.pValue = rsaPCrtKey.getPrimeQ().toByteArray();
364+
}
365+
if ((attr = sensitiveAttrs.get(CKA_EXPONENT_1)) != null) {
366+
attr.pValue = rsaPCrtKey.getPrimeExponentP().toByteArray();
367+
}
368+
if ((attr = sensitiveAttrs.get(CKA_EXPONENT_2)) != null) {
369+
attr.pValue = rsaPCrtKey.getPrimeExponentQ().toByteArray();
370+
}
371+
if ((attr = sensitiveAttrs.get(CKA_COEFFICIENT)) != null) {
372+
attr.pValue = rsaPCrtKey.getCrtCoefficient().toByteArray();
373+
}
374+
} else {
375+
checkAttrs(sensitiveAttrs, "CKO_PRIVATE_KEY CKK_RSA",
376+
CKA_PRIVATE_EXPONENT);
377+
}
378+
} else if (keyType == CKK_DSA) {
379+
checkAttrs(sensitiveAttrs, "CKO_PRIVATE_KEY CKK_DSA", CKA_VALUE);
380+
// CKA_VALUE is guaranteed to be present, since sensitiveAttrs'
381+
// size is greater than 0 and no invalid attributes exist
382+
sensitiveAttrs.get(CKA_VALUE).pValue =
383+
new sun.security.provider.DSAPrivateKey(plainExportedKey)
384+
.getX().toByteArray();
385+
} else if (keyType == CKK_EC) {
386+
checkAttrs(sensitiveAttrs, "CKO_PRIVATE_KEY CKK_EC", CKA_VALUE);
387+
// CKA_VALUE is guaranteed to be present, since sensitiveAttrs'
388+
// size is greater than 0 and no invalid attributes exist
389+
sensitiveAttrs.get(CKA_VALUE).pValue =
390+
ECUtil.decodePKCS8ECPrivateKey(plainExportedKey)
391+
.getS().toByteArray();
392+
} else {
393+
throw new PKCS11Exception(CKR_GENERAL_ERROR,
394+
" unsupported CKO_PRIVATE_KEY key type: " + keyType);
395+
}
396+
}
397+
398+
private static void checkAttrs(Map<Long, CK_ATTRIBUTE> sensitiveAttrs,
399+
String keyName, long... validAttrs)
400+
throws PKCS11Exception {
401+
int sensitiveAttrsCount = sensitiveAttrs.size();
402+
if (sensitiveAttrsCount <= validAttrs.length) {
403+
int validAttrsCount = 0;
404+
for (long validAttr : validAttrs) {
405+
if (sensitiveAttrs.containsKey(validAttr)) validAttrsCount++;
406+
}
407+
if (validAttrsCount == sensitiveAttrsCount) return;
408+
}
409+
throw new PKCS11Exception(CKR_GENERAL_ERROR,
410+
" invalid attribute types for a " + keyName + " key object");
411+
}
412+
388413
private static void createImporterKey(Token token) {
389414
if (debug != null) {
390415
debug.println("Generating Importer Key...");

src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,8 @@ static PrivateKey privateKey(Session session, long keyID, String algorithm,
384384
new CK_ATTRIBUTE(CKA_SENSITIVE),
385385
new CK_ATTRIBUTE(CKA_EXTRACTABLE),
386386
});
387-
if (attributes[1].getBoolean() || (attributes[2].getBoolean() == false)) {
387+
if (!plainKeySupportEnabled && (attributes[1].getBoolean() ||
388+
(attributes[2].getBoolean() == false))) {
388389
return new P11PrivateKey
389390
(session, keyID, algorithm, keyLength, attributes);
390391
} else {

src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ public final class SunPKCS11 extends AuthProvider {
8686
fipsExportKeyTmp = MethodHandles.lookup().findStatic(
8787
FIPSKeyImporter.class, "exportKey",
8888
MethodType.methodType(void.class, SunPKCS11.class,
89-
long.class, long.class, long.class,
90-
CK_ATTRIBUTE[].class));
89+
long.class, long.class,
90+
long.class, long.class, Map.class));
9191
} catch (Throwable t) {
9292
throw new SecurityException("FIPS key importer-exporter" +
9393
" initialization failed", t);

src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11.java

Lines changed: 29 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -2053,96 +2053,41 @@ static void C_GetAttributeValue(MethodHandle hC_GetAttributeValue,
20532053
sensitiveAttrs, nonSensitiveAttrs);
20542054
try {
20552055
if (sensitiveAttrs.size() > 0) {
2056-
CK_ATTRIBUTE[] keyClsAttrs = new CK_ATTRIBUTE[] {
2057-
new CK_ATTRIBUTE(CKA_CLASS)
2058-
};
2059-
hC_GetAttributeValue.invoke(hSession, hObject, keyClsAttrs);
2060-
long keyClass = keyClsAttrs[0].getLong();
2056+
long keyClass = -1L;
2057+
long keyType = -1L;
2058+
try {
2059+
// Secret and private keys have both class and type
2060+
// attributes, so we can query them at once.
2061+
CK_ATTRIBUTE[] queryAttrs = new CK_ATTRIBUTE[]{
2062+
new CK_ATTRIBUTE(CKA_CLASS),
2063+
new CK_ATTRIBUTE(CKA_KEY_TYPE),
2064+
};
2065+
hC_GetAttributeValue.invoke(hSession, hObject, queryAttrs);
2066+
keyClass = queryAttrs[0].getLong();
2067+
keyType = queryAttrs[1].getLong();
2068+
} catch (PKCS11Exception e) {
2069+
// If the query fails, the object is neither a secret nor a
2070+
// private key. As this case won't be handled with the FIPS
2071+
// Key Exporter, we keep keyClass initialized to -1L.
2072+
}
20612073
if (keyClass == CKO_SECRET_KEY || keyClass == CKO_PRIVATE_KEY) {
2062-
if (keyClass == CKO_PRIVATE_KEY) {
2063-
CK_ATTRIBUTE[] keyTypeAttrs = new CK_ATTRIBUTE[] {
2064-
new CK_ATTRIBUTE(CKA_KEY_TYPE)
2065-
};
2066-
hC_GetAttributeValue.invoke(hSession, hObject, keyTypeAttrs);
2067-
long keyType = keyTypeAttrs[0].getLong();
2068-
if (keyType == CKK_RSA) {
2069-
if (!(sensitiveAttrs.size() == 2 &&
2070-
sensitiveAttrs.containsKey(CKA_MODULUS) &&
2071-
sensitiveAttrs.containsKey(CKA_PRIVATE_EXPONENT))) {
2072-
throw new PKCS11Exception(CKR_GENERAL_ERROR,
2073-
" cannot get attribute values from" +
2074-
" a CKO_PRIVATE_KEY key object");
2075-
}
2076-
CK_ATTRIBUTE[] rsaAttrs = new CK_ATTRIBUTE[]{
2077-
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
2078-
sensitiveAttrs.get(CKA_MODULUS),
2079-
sensitiveAttrs.get(CKA_PRIVATE_EXPONENT)
2080-
};
2081-
fipsKeyExporter.invoke(hSession, hObject, keyClass,
2082-
rsaAttrs);
2083-
} else if (keyType == CKK_DSA) {
2084-
if (!(sensitiveAttrs.size() == 4 &&
2085-
sensitiveAttrs.containsKey(CKA_VALUE) &&
2086-
sensitiveAttrs.containsKey(CKA_PRIME) &&
2087-
sensitiveAttrs.containsKey(CKA_SUBPRIME) &&
2088-
sensitiveAttrs.containsKey(CKA_BASE))) {
2089-
throw new PKCS11Exception(CKR_GENERAL_ERROR,
2090-
" cannot get attribute values from" +
2091-
" a CKO_PRIVATE_KEY key object");
2092-
}
2093-
CK_ATTRIBUTE[] dsaAttrs = new CK_ATTRIBUTE[]{
2094-
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_DSA),
2095-
sensitiveAttrs.get(CKA_VALUE),
2096-
sensitiveAttrs.get(CKA_PRIME),
2097-
sensitiveAttrs.get(CKA_SUBPRIME),
2098-
sensitiveAttrs.get(CKA_BASE)
2099-
};
2100-
fipsKeyExporter.invoke(hSession, hObject, keyClass,
2101-
dsaAttrs);
2102-
} else if (keyType == CKK_EC) {
2103-
if (!(sensitiveAttrs.size() == 2 &&
2104-
sensitiveAttrs.containsKey(CKA_VALUE) &&
2105-
sensitiveAttrs.containsKey(CKA_EC_PARAMS))) {
2106-
throw new PKCS11Exception(CKR_GENERAL_ERROR,
2107-
" cannot get attribute values from" +
2108-
" a CKO_PRIVATE_KEY key object");
2109-
}
2110-
CK_ATTRIBUTE[] ecAttrs = new CK_ATTRIBUTE[]{
2111-
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_EC),
2112-
sensitiveAttrs.get(CKA_VALUE),
2113-
sensitiveAttrs.get(CKA_EC_PARAMS)
2114-
};
2115-
fipsKeyExporter.invoke(hSession, hObject, keyClass,
2116-
ecAttrs);
2117-
} else {
2118-
throw new PKCS11Exception(CKR_GENERAL_ERROR,
2119-
" cannot get attribute values from" +
2120-
" a CKO_PRIVATE_KEY key object");
2121-
}
2122-
} else if (keyClass == CKO_SECRET_KEY) {
2123-
// If the key is a secret key, we can extract the
2124-
// CKA_VALUE attribute with the FIPS Key Exporter.
2125-
if (!sensitiveAttrs.containsKey(CKA_VALUE) ||
2126-
sensitiveAttrs.size() > 1) {
2127-
throw new PKCS11Exception(CKR_GENERAL_ERROR,
2128-
" cannot get attribute values from" +
2129-
" a CKO_SECRET_KEY key object");
2130-
}
2131-
CK_ATTRIBUTE[] keyValueAttrs = new CK_ATTRIBUTE[]{
2132-
sensitiveAttrs.get(CKA_VALUE)
2133-
};
2134-
fipsKeyExporter.invoke(hSession, hObject, keyClass,
2135-
keyValueAttrs);
2136-
}
2074+
fipsKeyExporter.invoke(hSession, hObject, keyClass, keyType,
2075+
sensitiveAttrs);
21372076
if (nonSensitiveAttrs.size() > 0) {
21382077
CK_ATTRIBUTE[] pNonSensitiveAttrs =
21392078
new CK_ATTRIBUTE[nonSensitiveAttrs.size()];
21402079
int i = 0;
2141-
for (CK_ATTRIBUTE nonSensitiveAttr : nonSensitiveAttrs) {
2142-
pNonSensitiveAttrs[i++] = nonSensitiveAttr;
2080+
for (CK_ATTRIBUTE nonSensAttr : nonSensitiveAttrs) {
2081+
pNonSensitiveAttrs[i++] = nonSensAttr;
21432082
}
21442083
hC_GetAttributeValue.invoke(hSession, hObject,
21452084
pNonSensitiveAttrs);
2085+
// libj2pkcs11 allocates new CK_ATTRIBUTE objects, so we
2086+
// update the reference on the previous CK_ATTRIBUTEs
2087+
i = 0;
2088+
for (CK_ATTRIBUTE nonSensAttr : nonSensitiveAttrs) {
2089+
nonSensAttr.pValue = pNonSensitiveAttrs[i++].pValue;
2090+
}
21462091
}
21472092
return;
21482093
}
@@ -2161,12 +2106,11 @@ private static void getAttributesBySensitivity(CK_ATTRIBUTE[] pTemplate,
21612106
List<CK_ATTRIBUTE> nonSensitiveAttrs) {
21622107
for (CK_ATTRIBUTE attr : pTemplate) {
21632108
long type = attr.type;
2109+
// Aligned with NSS' sftk_isSensitive in lib/softoken/pkcs11u.c
21642110
if (type == CKA_VALUE || type == CKA_PRIVATE_EXPONENT ||
21652111
type == CKA_PRIME_1 || type == CKA_PRIME_2 ||
21662112
type == CKA_EXPONENT_1 || type == CKA_EXPONENT_2 ||
2167-
type == CKA_COEFFICIENT || type == CKA_MODULUS ||
2168-
type == CKA_PRIME || type == CKA_SUBPRIME ||
2169-
type == CKA_BASE || type == CKA_EC_PARAMS) {
2113+
type == CKA_COEFFICIENT) {
21702114
sensitiveAttrs.put(type, attr);
21712115
} else {
21722116
nonSensitiveAttrs.add(attr);

0 commit comments

Comments
 (0)