Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,13 @@ public SunRsaSignEntries(Provider p) {
attrs.put("SupportedKeyClasses",
"java.security.interfaces.RSAPublicKey" +
"|java.security.interfaces.RSAPrivateKey");
}

add(p, "KeyFactory", "RSA",
"sun.security.rsa.RSAKeyFactory$Legacy",
getAliases("PKCS1"), null);
add(p, "KeyFactory", "RSA",
"sun.security.rsa.RSAKeyFactory$Legacy",
getAliases("PKCS1"), null);

if (!systemFipsEnabled) {
add(p, "KeyPairGenerator", "RSA",
"sun.security.rsa.RSAKeyPairGenerator$Legacy",
getAliases("PKCS1"), null);
Expand Down Expand Up @@ -98,9 +101,12 @@ public SunRsaSignEntries(Provider p) {
"sun.security.rsa.RSASignature$SHA3_384withRSA", attrs);
addA(p, "Signature", "SHA3-512withRSA",
"sun.security.rsa.RSASignature$SHA3_512withRSA", attrs);
}

addA(p, "KeyFactory", "RSASSA-PSS",
"sun.security.rsa.RSAKeyFactory$PSS", attrs);

addA(p, "KeyFactory", "RSASSA-PSS",
"sun.security.rsa.RSAKeyFactory$PSS", attrs);
if (!systemFipsEnabled) {
addA(p, "KeyPairGenerator", "RSASSA-PSS",
"sun.security.rsa.RSAKeyPairGenerator$PSS", attrs);
addA(p, "Signature", "RSASSA-PSS",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,15 @@
import java.security.KeyFactory;
import java.security.Provider;
import java.security.Security;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPrivateKey;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.DHPrivateKeySpec;
import javax.crypto.spec.IvParameterSpec;

Expand All @@ -44,6 +48,8 @@
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
import static sun.security.pkcs11.wrapper.PKCS11Exception.*;
import sun.security.pkcs11.wrapper.PKCS11Exception;
import sun.security.rsa.RSAPrivateCrtKeyImpl;
import sun.security.rsa.RSAUtil;
import sun.security.rsa.RSAUtil.KeyType;
import sun.security.util.Debug;
import sun.security.util.ECUtil;
Expand All @@ -53,15 +59,21 @@ final class FIPSKeyImporter {
private static final Debug debug =
Debug.getInstance("sunpkcs11");

private static P11Key importerKey = null;
private static volatile P11Key importerKey = null;
private static SecretKeySpec exporterKey = null;
private static volatile P11Key exporterKeyP11 = null;
private static final ReentrantLock importerKeyLock = new ReentrantLock();
private static CK_MECHANISM importerKeyMechanism = null;
// Do not take the exporterKeyLock with the importerKeyLock held.
private static final ReentrantLock exporterKeyLock = new ReentrantLock();
private static volatile CK_MECHANISM importerKeyMechanism = null;
private static volatile CK_MECHANISM exporterKeyMechanism = null;
private static Cipher importerCipher = null;
private static Cipher exporterCipher = null;

private static Provider sunECProvider = null;
private static volatile Provider sunECProvider = null;
private static final ReentrantLock sunECProviderLock = new ReentrantLock();

private static KeyFactory DHKF = null;
private static volatile KeyFactory DHKF = null;
private static final ReentrantLock DHKFLock = new ReentrantLock();

static Long importKey(SunPKCS11 sunPKCS11, long hSession, CK_ATTRIBUTE[] attributes)
Expand All @@ -85,7 +97,8 @@ static Long importKey(SunPKCS11 sunPKCS11, long hSession, CK_ATTRIBUTE[] attribu
debug.println("Importer Key could not be" +
" generated.");
}
throw new PKCS11Exception(CKR_GENERAL_ERROR);
throw new PKCS11Exception(CKR_GENERAL_ERROR,
" fips key importer");
}
if (debug != null) {
debug.println("Importer Key successfully" +
Expand Down Expand Up @@ -213,7 +226,8 @@ static Long importKey(SunPKCS11 sunPKCS11, long hSession, CK_ATTRIBUTE[] attribu
if (debug != null) {
debug.println("Unrecognized private key type.");
}
throw new PKCS11Exception(CKR_GENERAL_ERROR);
throw new PKCS11Exception(CKR_GENERAL_ERROR,
" fips key importer");
}
} else if (keyClass == CKO_SECRET_KEY) {
if (debug != null) {
Expand All @@ -226,14 +240,19 @@ static Long importKey(SunPKCS11 sunPKCS11, long hSession, CK_ATTRIBUTE[] attribu
debug.println("Private or secret key plain bytes could" +
" not be obtained. Import failed.");
}
throw new PKCS11Exception(CKR_GENERAL_ERROR);
throw new PKCS11Exception(CKR_GENERAL_ERROR,
" fips key importer");
}
importerCipher.init(Cipher.ENCRYPT_MODE, importerKey,
new IvParameterSpec((byte[])importerKeyMechanism.pParameter),
null);
attributes = new CK_ATTRIBUTE[attrsMap.size()];
attrsMap.values().toArray(attributes);
encKeyBytes = importerCipher.doFinal(keyBytes);
importerKeyLock.lock();
try {
// No need to reset the cipher object because no multi-part
// operations are performed.
encKeyBytes = importerCipher.doFinal(keyBytes);
} finally {
importerKeyLock.unlock();
}
attributes = token.getAttributes(TemplateManager.O_IMPORT,
keyClass, keyType, attributes);
keyID = token.p11.C_UnwrapKey(hSession,
Expand All @@ -242,13 +261,155 @@ static Long importKey(SunPKCS11 sunPKCS11, long hSession, CK_ATTRIBUTE[] attribu
debug.println("Imported key ID: " + keyID);
}
} catch (Throwable t) {
throw new PKCS11Exception(CKR_GENERAL_ERROR);
if (t instanceof PKCS11Exception) {
throw (PKCS11Exception)t;
}
throw new PKCS11Exception(CKR_GENERAL_ERROR,
t.getMessage());
} finally {
importerKey.releaseKeyID();
}
return Long.valueOf(keyID);
}

static void exportKey(SunPKCS11 sunPKCS11, long hSession, long hObject,
long keyClass, long keyType, Map<Long, CK_ATTRIBUTE> sensitiveAttrs)
throws PKCS11Exception {
Token token = sunPKCS11.getToken();
if (debug != null) {
debug.println("Private or Secret key will be exported in" +
" system FIPS mode.");
}
if (exporterKeyP11 == null) {
try {
exporterKeyLock.lock();
if (exporterKeyP11 == null) {
if (exporterKeyMechanism == null) {
// Exporter Key creation has not been tried yet. Try it.
createExporterKey(token);
}
if (exporterKeyP11 == null || exporterCipher == null) {
if (debug != null) {
debug.println("Exporter Key could not be" +
" generated.");
}
throw new PKCS11Exception(CKR_GENERAL_ERROR,
" fips key exporter");
}
if (debug != null) {
debug.println("Exporter Key successfully" +
" generated.");
}
}
} finally {
exporterKeyLock.unlock();
}
}
long exporterKeyID = exporterKeyP11.getKeyID();
try {
byte[] wrappedKeyBytes = token.p11.C_WrapKey(hSession,
exporterKeyMechanism, exporterKeyID, hObject);
byte[] plainExportedKey = null;
exporterKeyLock.lock();
try {
// No need to reset the cipher object because no multi-part
// operations are performed.
plainExportedKey = exporterCipher.doFinal(wrappedKeyBytes);
} finally {
exporterKeyLock.unlock();
}
if (keyClass == CKO_PRIVATE_KEY) {
exportPrivateKey(sensitiveAttrs, keyType, plainExportedKey);
} else if (keyClass == CKO_SECRET_KEY) {
checkAttrs(sensitiveAttrs, "CKO_SECRET_KEY", CKA_VALUE);
// CKA_VALUE is guaranteed to be present, since sensitiveAttrs'
// size is greater than 0 and no invalid attributes exist
sensitiveAttrs.get(CKA_VALUE).pValue = plainExportedKey;
} else {
throw new PKCS11Exception(CKR_GENERAL_ERROR,
" fips key exporter");
}
} catch (Throwable t) {
if (t instanceof PKCS11Exception) {
throw (PKCS11Exception)t;
}
throw new PKCS11Exception(CKR_GENERAL_ERROR,
t.getMessage());
} finally {
exporterKeyP11.releaseKeyID();
}
}

private static void exportPrivateKey(
Map<Long, CK_ATTRIBUTE> sensitiveAttrs, long keyType,
byte[] plainExportedKey) throws Throwable {
if (keyType == CKK_RSA) {
checkAttrs(sensitiveAttrs, "CKO_PRIVATE_KEY CKK_RSA",
CKA_PRIVATE_EXPONENT, CKA_PRIME_1, CKA_PRIME_2,
CKA_EXPONENT_1, CKA_EXPONENT_2, CKA_COEFFICIENT);
RSAPrivateKey rsaPKey = RSAPrivateCrtKeyImpl.newKey(
RSAUtil.KeyType.RSA, "PKCS#8", plainExportedKey
);
CK_ATTRIBUTE attr;
if ((attr = sensitiveAttrs.get(CKA_PRIVATE_EXPONENT)) != null) {
attr.pValue = rsaPKey.getPrivateExponent().toByteArray();
}
if (rsaPKey instanceof RSAPrivateCrtKey) {
RSAPrivateCrtKey rsaPCrtKey = (RSAPrivateCrtKey) rsaPKey;
if ((attr = sensitiveAttrs.get(CKA_PRIME_1)) != null) {
attr.pValue = rsaPCrtKey.getPrimeP().toByteArray();
}
if ((attr = sensitiveAttrs.get(CKA_PRIME_2)) != null) {
attr.pValue = rsaPCrtKey.getPrimeQ().toByteArray();
}
if ((attr = sensitiveAttrs.get(CKA_EXPONENT_1)) != null) {
attr.pValue = rsaPCrtKey.getPrimeExponentP().toByteArray();
}
if ((attr = sensitiveAttrs.get(CKA_EXPONENT_2)) != null) {
attr.pValue = rsaPCrtKey.getPrimeExponentQ().toByteArray();
}
if ((attr = sensitiveAttrs.get(CKA_COEFFICIENT)) != null) {
attr.pValue = rsaPCrtKey.getCrtCoefficient().toByteArray();
}
} else {
checkAttrs(sensitiveAttrs, "CKO_PRIVATE_KEY CKK_RSA",
CKA_PRIVATE_EXPONENT);
}
} else if (keyType == CKK_DSA) {
checkAttrs(sensitiveAttrs, "CKO_PRIVATE_KEY CKK_DSA", CKA_VALUE);
// CKA_VALUE is guaranteed to be present, since sensitiveAttrs'
// size is greater than 0 and no invalid attributes exist
sensitiveAttrs.get(CKA_VALUE).pValue =
new sun.security.provider.DSAPrivateKey(plainExportedKey)
.getX().toByteArray();
} else if (keyType == CKK_EC) {
checkAttrs(sensitiveAttrs, "CKO_PRIVATE_KEY CKK_EC", CKA_VALUE);
// CKA_VALUE is guaranteed to be present, since sensitiveAttrs'
// size is greater than 0 and no invalid attributes exist
sensitiveAttrs.get(CKA_VALUE).pValue =
ECUtil.decodePKCS8ECPrivateKey(plainExportedKey)
.getS().toByteArray();
} else {
throw new PKCS11Exception(CKR_GENERAL_ERROR,
" unsupported CKO_PRIVATE_KEY key type: " + keyType);
}
}

private static void checkAttrs(Map<Long, CK_ATTRIBUTE> sensitiveAttrs,
String keyName, long... validAttrs)
throws PKCS11Exception {
int sensitiveAttrsCount = sensitiveAttrs.size();
if (sensitiveAttrsCount <= validAttrs.length) {
int validAttrsCount = 0;
for (long validAttr : validAttrs) {
if (sensitiveAttrs.containsKey(validAttr)) validAttrsCount++;
}
if (validAttrsCount == sensitiveAttrsCount) return;
}
throw new PKCS11Exception(CKR_GENERAL_ERROR,
" invalid attribute types for a " + keyName + " key object");
}

private static void createImporterKey(Token token) {
if (debug != null) {
debug.println("Generating Importer Key...");
Expand Down Expand Up @@ -279,13 +440,51 @@ private static void createImporterKey(Token token) {
}
if (importerKey != null) {
importerCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
importerCipher.init(Cipher.ENCRYPT_MODE, importerKey,
new IvParameterSpec(
(byte[])importerKeyMechanism.pParameter), null);
}
} catch (Throwable t) {
// best effort
importerKey = null;
importerCipher = null;
// importerKeyMechanism value is kept initialized to indicate that
// Importer Key creation has been tried and failed.
if (debug != null) {
debug.println("Error generating the Importer Key");
}
}
}

private static void createExporterKey(Token token) {
if (debug != null) {
debug.println("Generating Exporter Key...");
}
byte[] iv = new byte[16];
JCAUtil.getSecureRandom().nextBytes(iv);
exporterKeyMechanism = new CK_MECHANISM(CKM_AES_CBC_PAD, iv);
byte[] exporterKeyRaw = new byte[32];
JCAUtil.getSecureRandom().nextBytes(exporterKeyRaw);
exporterKey = new SecretKeySpec(exporterKeyRaw, "AES");
try {
SecretKeyFactory skf = SecretKeyFactory.getInstance("AES");
exporterKeyP11 = (P11Key)(skf.translateKey(exporterKey));
if (exporterKeyP11 != null) {
exporterCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
exporterCipher.init(Cipher.DECRYPT_MODE, exporterKey,
new IvParameterSpec(
(byte[])exporterKeyMechanism.pParameter), null);
}
} catch (Throwable t) {
// best effort
exporterKey = null;
exporterKeyP11 = null;
exporterCipher = null;
// exporterKeyMechanism value is kept initialized to indicate that
// Exporter Key creation has been tried and failed.
if (debug != null) {
debug.println("Error generating the Exporter Key");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
import javax.crypto.interfaces.*;
import javax.crypto.spec.*;

import jdk.internal.access.SharedSecrets;

import sun.security.rsa.RSAUtil.KeyType;
import sun.security.rsa.RSAPublicKeyImpl;
import sun.security.rsa.RSAPrivateCrtKeyImpl;
Expand Down Expand Up @@ -69,6 +71,9 @@
*/
abstract class P11Key implements Key, Length {

private static final boolean plainKeySupportEnabled = SharedSecrets
.getJavaSecuritySystemConfiguratorAccess().isPlainKeySupportEnabled();

private static final long serialVersionUID = -2575874101938349339L;

private static final String PUBLIC = "public";
Expand Down Expand Up @@ -379,7 +384,8 @@ static PrivateKey privateKey(Session session, long keyID, String algorithm,
new CK_ATTRIBUTE(CKA_SENSITIVE),
new CK_ATTRIBUTE(CKA_EXTRACTABLE),
});
if (attributes[1].getBoolean() || (attributes[2].getBoolean() == false)) {
if (!plainKeySupportEnabled && (attributes[1].getBoolean() ||
(attributes[2].getBoolean() == false))) {
return new P11PrivateKey
(session, keyID, algorithm, keyLength, attributes);
} else {
Expand Down Expand Up @@ -461,7 +467,8 @@ private static class P11SecretKey extends P11Key implements SecretKey {
}
public String getFormat() {
token.ensureValid();
if (sensitive || (extractable == false)) {
if (!plainKeySupportEnabled &&
(sensitive || (extractable == false))) {
return null;
} else {
return "RAW";
Expand Down
Loading