| |
@@ -1,590 +0,0 @@
|
| |
- diff --git openjdk.orig/src/java.base/share/classes/java/security/Security.java openjdk/src/java.base/share/classes/java/security/Security.java
|
| |
- index 53f32d12cc..28ab184617 100644
|
| |
- --- openjdk.orig/src/java.base/share/classes/java/security/Security.java
|
| |
- +++ openjdk/src/java.base/share/classes/java/security/Security.java
|
| |
- @@ -82,6 +82,10 @@ public final class Security {
|
| |
- public boolean isSystemFipsEnabled() {
|
| |
- return SystemConfigurator.isSystemFipsEnabled();
|
| |
- }
|
| |
- + @Override
|
| |
- + public boolean isPlainKeySupportEnabled() {
|
| |
- + return SystemConfigurator.isPlainKeySupportEnabled();
|
| |
- + }
|
| |
- });
|
| |
-
|
| |
- // doPrivileged here because there are multiple
|
| |
- diff --git openjdk.orig/src/java.base/share/classes/java/security/SystemConfigurator.java openjdk/src/java.base/share/classes/java/security/SystemConfigurator.java
|
| |
- index 5565acb7c6..874c6221eb 100644
|
| |
- --- openjdk.orig/src/java.base/share/classes/java/security/SystemConfigurator.java
|
| |
- +++ openjdk/src/java.base/share/classes/java/security/SystemConfigurator.java
|
| |
- @@ -55,6 +55,7 @@ final class SystemConfigurator {
|
| |
- CRYPTO_POLICIES_BASE_DIR + "/back-ends/java.config";
|
| |
-
|
| |
- private static boolean systemFipsEnabled = false;
|
| |
- + private static boolean plainKeySupportEnabled = false;
|
| |
-
|
| |
- private static final String SYSTEMCONF_NATIVE_LIB = "systemconf";
|
| |
-
|
| |
- @@ -149,6 +150,16 @@ final class SystemConfigurator {
|
| |
- }
|
| |
- loadedProps = true;
|
| |
- systemFipsEnabled = true;
|
| |
- + String plainKeySupport = System.getProperty("com.redhat.fips.plainKeySupport",
|
| |
- + "true");
|
| |
- + plainKeySupportEnabled = !"false".equals(plainKeySupport);
|
| |
- + if (sdebug != null) {
|
| |
- + if (plainKeySupportEnabled) {
|
| |
- + sdebug.println("FIPS support enabled with plain key support");
|
| |
- + } else {
|
| |
- + sdebug.println("FIPS support enabled without plain key support");
|
| |
- + }
|
| |
- + }
|
| |
- }
|
| |
- } catch (Exception e) {
|
| |
- if (sdebug != null) {
|
| |
- @@ -176,6 +187,19 @@ final class SystemConfigurator {
|
| |
- return systemFipsEnabled;
|
| |
- }
|
| |
-
|
| |
- + /**
|
| |
- + * Returns {@code true} if system FIPS alignment is enabled
|
| |
- + * and plain key support is allowed. Plain key support is
|
| |
- + * enabled by default but can be disabled with
|
| |
- + * {@code -Dcom.redhat.fips.plainKeySupport=false}.
|
| |
- + *
|
| |
- + * @return a boolean indicating whether plain key support
|
| |
- + * should be enabled.
|
| |
- + */
|
| |
- + static boolean isPlainKeySupportEnabled() {
|
| |
- + return plainKeySupportEnabled;
|
| |
- + }
|
| |
- +
|
| |
- /*
|
| |
- * OpenJDK FIPS mode will be enabled only if the com.redhat.fips
|
| |
- * system property is true (default) and the system is in FIPS mode.
|
| |
- diff --git openjdk.orig/src/java.base/share/classes/jdk/internal/misc/JavaSecuritySystemConfiguratorAccess.java openjdk/src/java.base/share/classes/jdk/internal/misc/JavaSecuritySystemConfiguratorAccess.java
|
| |
- index d8caa5640c..21bc6d0b59 100644
|
| |
- --- openjdk.orig/src/java.base/share/classes/jdk/internal/misc/JavaSecuritySystemConfiguratorAccess.java
|
| |
- +++ openjdk/src/java.base/share/classes/jdk/internal/misc/JavaSecuritySystemConfiguratorAccess.java
|
| |
- @@ -27,4 +27,5 @@ package jdk.internal.misc;
|
| |
-
|
| |
- public interface JavaSecuritySystemConfiguratorAccess {
|
| |
- boolean isSystemFipsEnabled();
|
| |
- + boolean isPlainKeySupportEnabled();
|
| |
- }
|
| |
- diff --git openjdk.orig/src/java.base/share/classes/sun/security/ssl/KeyManagerFactoryImpl.java openjdk/src/java.base/share/classes/sun/security/ssl/KeyManagerFactoryImpl.java
|
| |
- index ffee2c1603..ff3d5e0e4a 100644
|
| |
- --- openjdk.orig/src/java.base/share/classes/sun/security/ssl/KeyManagerFactoryImpl.java
|
| |
- +++ openjdk/src/java.base/share/classes/sun/security/ssl/KeyManagerFactoryImpl.java
|
| |
- @@ -33,8 +33,13 @@ import java.security.KeyStore.*;
|
| |
-
|
| |
- import javax.net.ssl.*;
|
| |
-
|
| |
- +import jdk.internal.misc.SharedSecrets;
|
| |
- +
|
| |
- abstract class KeyManagerFactoryImpl extends KeyManagerFactorySpi {
|
| |
-
|
| |
- + private static final boolean plainKeySupportEnabled = SharedSecrets
|
| |
- + .getJavaSecuritySystemConfiguratorAccess().isPlainKeySupportEnabled();
|
| |
- +
|
| |
- X509ExtendedKeyManager keyManager;
|
| |
- boolean isInitialized;
|
| |
-
|
| |
- @@ -62,7 +67,8 @@ abstract class KeyManagerFactoryImpl extends KeyManagerFactorySpi {
|
| |
- KeyStoreException, NoSuchAlgorithmException,
|
| |
- UnrecoverableKeyException {
|
| |
- if ((ks != null) && SunJSSE.isFIPS()) {
|
| |
- - if (ks.getProvider() != SunJSSE.cryptoProvider) {
|
| |
- + if (ks.getProvider() != SunJSSE.cryptoProvider &&
|
| |
- + !plainKeySupportEnabled) {
|
| |
- throw new KeyStoreException("FIPS mode: KeyStore must be "
|
| |
- + "from provider " + SunJSSE.cryptoProvider.getName());
|
| |
- }
|
| |
- @@ -91,8 +97,8 @@ abstract class KeyManagerFactoryImpl extends KeyManagerFactorySpi {
|
| |
- keyManager = new X509KeyManagerImpl(
|
| |
- Collections.<Builder>emptyList());
|
| |
- } else {
|
| |
- - if (SunJSSE.isFIPS() &&
|
| |
- - (ks.getProvider() != SunJSSE.cryptoProvider)) {
|
| |
- + if (SunJSSE.isFIPS() && (ks.getProvider() != SunJSSE.cryptoProvider)
|
| |
- + && !plainKeySupportEnabled) {
|
| |
- throw new KeyStoreException(
|
| |
- "FIPS mode: KeyStore must be " +
|
| |
- "from provider " + SunJSSE.cryptoProvider.getName());
|
| |
- diff --git openjdk.orig/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/FIPSKeyImporter.java openjdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/FIPSKeyImporter.java
|
| |
- new file mode 100644
|
| |
- index 0000000000..b848a1fd78
|
| |
- --- /dev/null
|
| |
- +++ openjdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/FIPSKeyImporter.java
|
| |
- @@ -0,0 +1,290 @@
|
| |
- +/*
|
| |
- + * Copyright (c) 2021, Red Hat, Inc.
|
| |
- + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
| |
- + *
|
| |
- + * This code is free software; you can redistribute it and/or modify it
|
| |
- + * under the terms of the GNU General Public License version 2 only, as
|
| |
- + * published by the Free Software Foundation. Oracle designates this
|
| |
- + * particular file as subject to the "Classpath" exception as provided
|
| |
- + * by Oracle in the LICENSE file that accompanied this code.
|
| |
- + *
|
| |
- + * This code is distributed in the hope that it will be useful, but WITHOUT
|
| |
- + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
| |
- + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
| |
- + * version 2 for more details (a copy is included in the LICENSE file that
|
| |
- + * accompanied this code).
|
| |
- + *
|
| |
- + * You should have received a copy of the GNU General Public License version
|
| |
- + * 2 along with this work; if not, write to the Free Software Foundation,
|
| |
- + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
| |
- + *
|
| |
- + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
| |
- + * or visit www.oracle.com if you need additional information or have any
|
| |
- + * questions.
|
| |
- + */
|
| |
- +
|
| |
- +package sun.security.pkcs11;
|
| |
- +
|
| |
- +import java.math.BigInteger;
|
| |
- +import java.security.KeyFactory;
|
| |
- +import java.security.Provider;
|
| |
- +import java.security.Security;
|
| |
- +import java.util.HashMap;
|
| |
- +import java.util.Map;
|
| |
- +import java.util.concurrent.locks.ReentrantLock;
|
| |
- +
|
| |
- +import javax.crypto.Cipher;
|
| |
- +import javax.crypto.spec.DHPrivateKeySpec;
|
| |
- +import javax.crypto.spec.IvParameterSpec;
|
| |
- +
|
| |
- +import sun.security.jca.JCAUtil;
|
| |
- +import sun.security.pkcs11.TemplateManager;
|
| |
- +import sun.security.pkcs11.wrapper.CK_ATTRIBUTE;
|
| |
- +import sun.security.pkcs11.wrapper.CK_MECHANISM;
|
| |
- +import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
|
| |
- +import sun.security.pkcs11.wrapper.PKCS11Exception;
|
| |
- +import sun.security.rsa.RSAUtil.KeyType;
|
| |
- +import sun.security.util.Debug;
|
| |
- +import sun.security.util.ECUtil;
|
| |
- +
|
| |
- +final class FIPSKeyImporter {
|
| |
- +
|
| |
- + private static final Debug debug =
|
| |
- + Debug.getInstance("sunpkcs11");
|
| |
- +
|
| |
- + private static P11Key importerKey = null;
|
| |
- + private static final ReentrantLock importerKeyLock = new ReentrantLock();
|
| |
- + private static CK_MECHANISM importerKeyMechanism = null;
|
| |
- + private static Cipher importerCipher = null;
|
| |
- +
|
| |
- + private static Provider sunECProvider = null;
|
| |
- + private static final ReentrantLock sunECProviderLock = new ReentrantLock();
|
| |
- +
|
| |
- + private static KeyFactory DHKF = null;
|
| |
- + private static final ReentrantLock DHKFLock = new ReentrantLock();
|
| |
- +
|
| |
- + static Long importKey(SunPKCS11 sunPKCS11, long hSession, CK_ATTRIBUTE[] attributes)
|
| |
- + throws PKCS11Exception {
|
| |
- + long keyID = -1;
|
| |
- + Token token = sunPKCS11.getToken();
|
| |
- + if (debug != null) {
|
| |
- + debug.println("Private or Secret key will be imported in" +
|
| |
- + " system FIPS mode.");
|
| |
- + }
|
| |
- + if (importerKey == null) {
|
| |
- + importerKeyLock.lock();
|
| |
- + try {
|
| |
- + if (importerKey == null) {
|
| |
- + if (importerKeyMechanism == null) {
|
| |
- + // Importer Key creation has not been tried yet. Try it.
|
| |
- + createImporterKey(token);
|
| |
- + }
|
| |
- + if (importerKey == null || importerCipher == null) {
|
| |
- + if (debug != null) {
|
| |
- + debug.println("Importer Key could not be" +
|
| |
- + " generated.");
|
| |
- + }
|
| |
- + throw new PKCS11Exception(CKR_GENERAL_ERROR);
|
| |
- + }
|
| |
- + if (debug != null) {
|
| |
- + debug.println("Importer Key successfully" +
|
| |
- + " generated.");
|
| |
- + }
|
| |
- + }
|
| |
- + } finally {
|
| |
- + importerKeyLock.unlock();
|
| |
- + }
|
| |
- + }
|
| |
- + long importerKeyID = importerKey.getKeyID();
|
| |
- + try {
|
| |
- + byte[] keyBytes = null;
|
| |
- + byte[] encKeyBytes = null;
|
| |
- + long keyClass = 0L;
|
| |
- + long keyType = 0L;
|
| |
- + Map<Long, CK_ATTRIBUTE> attrsMap = new HashMap<>();
|
| |
- + for (CK_ATTRIBUTE attr : attributes) {
|
| |
- + if (attr.type == CKA_CLASS) {
|
| |
- + keyClass = attr.getLong();
|
| |
- + } else if (attr.type == CKA_KEY_TYPE) {
|
| |
- + keyType = attr.getLong();
|
| |
- + }
|
| |
- + attrsMap.put(attr.type, attr);
|
| |
- + }
|
| |
- + BigInteger v = null;
|
| |
- + if (keyClass == CKO_PRIVATE_KEY) {
|
| |
- + if (keyType == CKK_RSA) {
|
| |
- + if (debug != null) {
|
| |
- + debug.println("Importing an RSA private key...");
|
| |
- + }
|
| |
- + keyBytes = sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(
|
| |
- + KeyType.RSA,
|
| |
- + null,
|
| |
- + ((v = attrsMap.get(CKA_MODULUS).getBigInteger()) != null)
|
| |
- + ? v : BigInteger.ZERO,
|
| |
- + ((v = attrsMap.get(CKA_PUBLIC_EXPONENT).getBigInteger()) != null)
|
| |
- + ? v : BigInteger.ZERO,
|
| |
- + ((v = attrsMap.get(CKA_PRIVATE_EXPONENT).getBigInteger()) != null)
|
| |
- + ? v : BigInteger.ZERO,
|
| |
- + ((v = attrsMap.get(CKA_PRIME_1).getBigInteger()) != null)
|
| |
- + ? v : BigInteger.ZERO,
|
| |
- + ((v = attrsMap.get(CKA_PRIME_2).getBigInteger()) != null)
|
| |
- + ? v : BigInteger.ZERO,
|
| |
- + ((v = attrsMap.get(CKA_EXPONENT_1).getBigInteger()) != null)
|
| |
- + ? v : BigInteger.ZERO,
|
| |
- + ((v = attrsMap.get(CKA_EXPONENT_2).getBigInteger()) != null)
|
| |
- + ? v : BigInteger.ZERO,
|
| |
- + ((v = attrsMap.get(CKA_COEFFICIENT).getBigInteger()) != null)
|
| |
- + ? v : BigInteger.ZERO
|
| |
- + ).getEncoded();
|
| |
- + } else if (keyType == CKK_DSA) {
|
| |
- + if (debug != null) {
|
| |
- + debug.println("Importing a DSA private key...");
|
| |
- + }
|
| |
- + keyBytes = new sun.security.provider.DSAPrivateKey(
|
| |
- + ((v = attrsMap.get(CKA_VALUE).getBigInteger()) != null)
|
| |
- + ? v : BigInteger.ZERO,
|
| |
- + ((v = attrsMap.get(CKA_PRIME).getBigInteger()) != null)
|
| |
- + ? v : BigInteger.ZERO,
|
| |
- + ((v = attrsMap.get(CKA_SUBPRIME).getBigInteger()) != null)
|
| |
- + ? v : BigInteger.ZERO,
|
| |
- + ((v = attrsMap.get(CKA_BASE).getBigInteger()) != null)
|
| |
- + ? v : BigInteger.ZERO
|
| |
- + ).getEncoded();
|
| |
- + if (token.config.getNssNetscapeDbWorkaround() &&
|
| |
- + attrsMap.get(CKA_NETSCAPE_DB) == null) {
|
| |
- + attrsMap.put(CKA_NETSCAPE_DB,
|
| |
- + new CK_ATTRIBUTE(CKA_NETSCAPE_DB, BigInteger.ZERO));
|
| |
- + }
|
| |
- + } else if (keyType == CKK_EC) {
|
| |
- + if (debug != null) {
|
| |
- + debug.println("Importing an EC private key...");
|
| |
- + }
|
| |
- + if (sunECProvider == null) {
|
| |
- + sunECProviderLock.lock();
|
| |
- + try {
|
| |
- + if (sunECProvider == null) {
|
| |
- + sunECProvider = Security.getProvider("SunEC");
|
| |
- + }
|
| |
- + } finally {
|
| |
- + sunECProviderLock.unlock();
|
| |
- + }
|
| |
- + }
|
| |
- + keyBytes = ECUtil.generateECPrivateKey(
|
| |
- + ((v = attrsMap.get(CKA_VALUE).getBigInteger()) != null)
|
| |
- + ? v : BigInteger.ZERO,
|
| |
- + ECUtil.getECParameterSpec(sunECProvider,
|
| |
- + attrsMap.get(CKA_EC_PARAMS).getByteArray()))
|
| |
- + .getEncoded();
|
| |
- + if (token.config.getNssNetscapeDbWorkaround() &&
|
| |
- + attrsMap.get(CKA_NETSCAPE_DB) == null) {
|
| |
- + attrsMap.put(CKA_NETSCAPE_DB,
|
| |
- + new CK_ATTRIBUTE(CKA_NETSCAPE_DB, BigInteger.ZERO));
|
| |
- + }
|
| |
- + } else if (keyType == CKK_DH) {
|
| |
- + if (debug != null) {
|
| |
- + debug.println("Importing a Diffie-Hellman private key...");
|
| |
- + }
|
| |
- + if (DHKF == null) {
|
| |
- + DHKFLock.lock();
|
| |
- + try {
|
| |
- + if (DHKF == null) {
|
| |
- + DHKF = KeyFactory.getInstance(
|
| |
- + "DH", P11Util.getSunJceProvider());
|
| |
- + }
|
| |
- + } finally {
|
| |
- + DHKFLock.unlock();
|
| |
- + }
|
| |
- + }
|
| |
- + DHPrivateKeySpec spec = new DHPrivateKeySpec
|
| |
- + (((v = attrsMap.get(CKA_VALUE).getBigInteger()) != null)
|
| |
- + ? v : BigInteger.ZERO,
|
| |
- + ((v = attrsMap.get(CKA_PRIME).getBigInteger()) != null)
|
| |
- + ? v : BigInteger.ZERO,
|
| |
- + ((v = attrsMap.get(CKA_BASE).getBigInteger()) != null)
|
| |
- + ? v : BigInteger.ZERO);
|
| |
- + keyBytes = DHKF.generatePrivate(spec).getEncoded();
|
| |
- + if (token.config.getNssNetscapeDbWorkaround() &&
|
| |
- + attrsMap.get(CKA_NETSCAPE_DB) == null) {
|
| |
- + attrsMap.put(CKA_NETSCAPE_DB,
|
| |
- + new CK_ATTRIBUTE(CKA_NETSCAPE_DB, BigInteger.ZERO));
|
| |
- + }
|
| |
- + } else {
|
| |
- + if (debug != null) {
|
| |
- + debug.println("Unrecognized private key type.");
|
| |
- + }
|
| |
- + throw new PKCS11Exception(CKR_GENERAL_ERROR);
|
| |
- + }
|
| |
- + } else if (keyClass == CKO_SECRET_KEY) {
|
| |
- + if (debug != null) {
|
| |
- + debug.println("Importing a secret key...");
|
| |
- + }
|
| |
- + keyBytes = attrsMap.get(CKA_VALUE).getByteArray();
|
| |
- + }
|
| |
- + if (keyBytes == null || keyBytes.length == 0) {
|
| |
- + if (debug != null) {
|
| |
- + debug.println("Private or secret key plain bytes could" +
|
| |
- + " not be obtained. Import failed.");
|
| |
- + }
|
| |
- + throw new PKCS11Exception(CKR_GENERAL_ERROR);
|
| |
- + }
|
| |
- + 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);
|
| |
- + attributes = token.getAttributes(TemplateManager.O_IMPORT,
|
| |
- + keyClass, keyType, attributes);
|
| |
- + keyID = token.p11.C_UnwrapKey(hSession,
|
| |
- + importerKeyMechanism, importerKeyID, encKeyBytes, attributes);
|
| |
- + if (debug != null) {
|
| |
- + debug.println("Imported key ID: " + keyID);
|
| |
- + }
|
| |
- + } catch (Throwable t) {
|
| |
- + throw new PKCS11Exception(CKR_GENERAL_ERROR);
|
| |
- + } finally {
|
| |
- + importerKey.releaseKeyID();
|
| |
- + }
|
| |
- + return Long.valueOf(keyID);
|
| |
- + }
|
| |
- +
|
| |
- + private static void createImporterKey(Token token) {
|
| |
- + if (debug != null) {
|
| |
- + debug.println("Generating Importer Key...");
|
| |
- + }
|
| |
- + byte[] iv = new byte[16];
|
| |
- + JCAUtil.getSecureRandom().nextBytes(iv);
|
| |
- + importerKeyMechanism = new CK_MECHANISM(CKM_AES_CBC_PAD, iv);
|
| |
- + try {
|
| |
- + CK_ATTRIBUTE[] attributes = token.getAttributes(TemplateManager.O_GENERATE,
|
| |
- + CKO_SECRET_KEY, CKK_AES, new CK_ATTRIBUTE[] {
|
| |
- + new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
|
| |
- + new CK_ATTRIBUTE(CKA_VALUE_LEN, 256 >> 3)});
|
| |
- + Session s = null;
|
| |
- + try {
|
| |
- + s = token.getObjSession();
|
| |
- + long keyID = token.p11.C_GenerateKey(
|
| |
- + s.id(), new CK_MECHANISM(CKM_AES_KEY_GEN),
|
| |
- + attributes);
|
| |
- + if (debug != null) {
|
| |
- + debug.println("Importer Key ID: " + keyID);
|
| |
- + }
|
| |
- + importerKey = (P11Key)P11Key.secretKey(s, keyID, "AES",
|
| |
- + 256 >> 3, null);
|
| |
- + } catch (PKCS11Exception e) {
|
| |
- + // best effort
|
| |
- + } finally {
|
| |
- + token.releaseSession(s);
|
| |
- + }
|
| |
- + if (importerKey != null) {
|
| |
- + importerCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
| |
- + }
|
| |
- + } 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.
|
| |
- + }
|
| |
- + }
|
| |
- +}
|
| |
- diff --git openjdk.orig/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java openjdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java
|
| |
- index 1eca1f8f0a..72674a7330 100644
|
| |
- --- openjdk.orig/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java
|
| |
- +++ openjdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java
|
| |
- @@ -26,6 +26,9 @@
|
| |
- package sun.security.pkcs11;
|
| |
-
|
| |
- import java.io.*;
|
| |
- +import java.lang.invoke.MethodHandle;
|
| |
- +import java.lang.invoke.MethodHandles;
|
| |
- +import java.lang.invoke.MethodType;
|
| |
- import java.util.*;
|
| |
-
|
| |
- import java.security.*;
|
| |
- @@ -64,6 +67,26 @@ public final class SunPKCS11 extends AuthProvider {
|
| |
- private static final boolean systemFipsEnabled = SharedSecrets
|
| |
- .getJavaSecuritySystemConfiguratorAccess().isSystemFipsEnabled();
|
| |
-
|
| |
- + private static final boolean plainKeySupportEnabled = SharedSecrets
|
| |
- + .getJavaSecuritySystemConfiguratorAccess().isPlainKeySupportEnabled();
|
| |
- +
|
| |
- + private static final MethodHandle fipsImportKey;
|
| |
- + static {
|
| |
- + MethodHandle fipsImportKeyTmp = null;
|
| |
- + if (plainKeySupportEnabled) {
|
| |
- + try {
|
| |
- + fipsImportKeyTmp = MethodHandles.lookup().findStatic(
|
| |
- + FIPSKeyImporter.class, "importKey",
|
| |
- + MethodType.methodType(Long.class, SunPKCS11.class,
|
| |
- + long.class, CK_ATTRIBUTE[].class));
|
| |
- + } catch (Throwable t) {
|
| |
- + throw new SecurityException("FIPS key importer initialization" +
|
| |
- + " failed", t);
|
| |
- + }
|
| |
- + }
|
| |
- + fipsImportKey = fipsImportKeyTmp;
|
| |
- + }
|
| |
- +
|
| |
- private static final long serialVersionUID = -1354835039035306505L;
|
| |
-
|
| |
- static final Debug debug = Debug.getInstance("sunpkcs11");
|
| |
- @@ -319,10 +342,15 @@ public final class SunPKCS11 extends AuthProvider {
|
| |
- // request multithreaded access first
|
| |
- initArgs.flags = CKF_OS_LOCKING_OK;
|
| |
- PKCS11 tmpPKCS11;
|
| |
- + MethodHandle fipsKeyImporter = null;
|
| |
- + if (plainKeySupportEnabled) {
|
| |
- + fipsKeyImporter = MethodHandles.insertArguments(
|
| |
- + fipsImportKey, 0, this);
|
| |
- + }
|
| |
- try {
|
| |
- tmpPKCS11 = PKCS11.getInstance(
|
| |
- library, functionList, initArgs,
|
| |
- - config.getOmitInitialize());
|
| |
- + config.getOmitInitialize(), fipsKeyImporter);
|
| |
- } catch (PKCS11Exception e) {
|
| |
- if (debug != null) {
|
| |
- debug.println("Multi-threaded initialization failed: " + e);
|
| |
- @@ -338,7 +366,7 @@ public final class SunPKCS11 extends AuthProvider {
|
| |
- initArgs.flags = 0;
|
| |
- }
|
| |
- tmpPKCS11 = PKCS11.getInstance(library,
|
| |
- - functionList, initArgs, config.getOmitInitialize());
|
| |
- + functionList, initArgs, config.getOmitInitialize(), fipsKeyImporter);
|
| |
- }
|
| |
- p11 = tmpPKCS11;
|
| |
-
|
| |
- diff --git openjdk.orig/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11.java openjdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11.java
|
| |
- index 04a369f453..8d2081abaa 100644
|
| |
- --- openjdk.orig/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11.java
|
| |
- +++ openjdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11.java
|
| |
- @@ -49,6 +49,7 @@ package sun.security.pkcs11.wrapper;
|
| |
-
|
| |
- import java.io.File;
|
| |
- import java.io.IOException;
|
| |
- +import java.lang.invoke.MethodHandle;
|
| |
- import java.util.*;
|
| |
-
|
| |
- import java.security.AccessController;
|
| |
- @@ -150,16 +151,28 @@ public class PKCS11 {
|
| |
-
|
| |
- public static synchronized PKCS11 getInstance(String pkcs11ModulePath,
|
| |
- String functionList, CK_C_INITIALIZE_ARGS pInitArgs,
|
| |
- - boolean omitInitialize) throws IOException, PKCS11Exception {
|
| |
- + boolean omitInitialize, MethodHandle fipsKeyImporter)
|
| |
- + throws IOException, PKCS11Exception {
|
| |
- // we may only call C_Initialize once per native .so/.dll
|
| |
- // so keep a cache using the (non-canonicalized!) path
|
| |
- PKCS11 pkcs11 = moduleMap.get(pkcs11ModulePath);
|
| |
- if (pkcs11 == null) {
|
| |
- + boolean nssFipsMode = fipsKeyImporter != null;
|
| |
- if ((pInitArgs != null)
|
| |
- && ((pInitArgs.flags & CKF_OS_LOCKING_OK) != 0)) {
|
| |
- - pkcs11 = new PKCS11(pkcs11ModulePath, functionList);
|
| |
- + if (nssFipsMode) {
|
| |
- + pkcs11 = new FIPSPKCS11(pkcs11ModulePath, functionList,
|
| |
- + fipsKeyImporter);
|
| |
- + } else {
|
| |
- + pkcs11 = new PKCS11(pkcs11ModulePath, functionList);
|
| |
- + }
|
| |
- } else {
|
| |
- - pkcs11 = new SynchronizedPKCS11(pkcs11ModulePath, functionList);
|
| |
- + if (nssFipsMode) {
|
| |
- + pkcs11 = new SynchronizedFIPSPKCS11(pkcs11ModulePath,
|
| |
- + functionList, fipsKeyImporter);
|
| |
- + } else {
|
| |
- + pkcs11 = new SynchronizedPKCS11(pkcs11ModulePath, functionList);
|
| |
- + }
|
| |
- }
|
| |
- if (omitInitialize == false) {
|
| |
- try {
|
| |
- @@ -1909,4 +1922,69 @@ static class SynchronizedPKCS11 extends PKCS11 {
|
| |
- super.C_GenerateRandom(hSession, randomData);
|
| |
- }
|
| |
- }
|
| |
- +
|
| |
- +// PKCS11 subclass that allows using plain private or secret keys in
|
| |
- +// FIPS-configured NSS Software Tokens. Only used when System FIPS
|
| |
- +// is enabled.
|
| |
- +static class FIPSPKCS11 extends PKCS11 {
|
| |
- + private MethodHandle fipsKeyImporter;
|
| |
- + FIPSPKCS11(String pkcs11ModulePath, String functionListName,
|
| |
- + MethodHandle fipsKeyImporter) throws IOException {
|
| |
- + super(pkcs11ModulePath, functionListName);
|
| |
- + this.fipsKeyImporter = fipsKeyImporter;
|
| |
- + }
|
| |
- +
|
| |
- + public synchronized long C_CreateObject(long hSession,
|
| |
- + CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
|
| |
- + // Creating sensitive key objects from plain key material in a
|
| |
- + // FIPS-configured NSS Software Token is not allowed. We apply
|
| |
- + // a key-unwrapping scheme to achieve so.
|
| |
- + if (FIPSPKCS11Helper.isSensitiveObject(pTemplate)) {
|
| |
- + try {
|
| |
- + return ((Long)fipsKeyImporter.invoke(hSession, pTemplate))
|
| |
- + .longValue();
|
| |
- + } catch (Throwable t) {
|
| |
- + throw new PKCS11Exception(CKR_GENERAL_ERROR);
|
| |
- + }
|
| |
- + }
|
| |
- + return super.C_CreateObject(hSession, pTemplate);
|
| |
- + }
|
| |
- +}
|
| |
- +
|
| |
- +// FIPSPKCS11 synchronized counterpart.
|
| |
- +static class SynchronizedFIPSPKCS11 extends SynchronizedPKCS11 {
|
| |
- + private MethodHandle fipsKeyImporter;
|
| |
- + SynchronizedFIPSPKCS11(String pkcs11ModulePath, String functionListName,
|
| |
- + MethodHandle fipsKeyImporter) throws IOException {
|
| |
- + super(pkcs11ModulePath, functionListName);
|
| |
- + this.fipsKeyImporter = fipsKeyImporter;
|
| |
- + }
|
| |
- +
|
| |
- + public synchronized long C_CreateObject(long hSession,
|
| |
- + CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
|
| |
- + // See FIPSPKCS11::C_CreateObject.
|
| |
- + if (FIPSPKCS11Helper.isSensitiveObject(pTemplate)) {
|
| |
- + try {
|
| |
- + return ((Long)fipsKeyImporter.invoke(hSession, pTemplate))
|
| |
- + .longValue();
|
| |
- + } catch (Throwable t) {
|
| |
- + throw new PKCS11Exception(CKR_GENERAL_ERROR);
|
| |
- + }
|
| |
- + }
|
| |
- + return super.C_CreateObject(hSession, pTemplate);
|
| |
- + }
|
| |
- +}
|
| |
- +
|
| |
- +private static class FIPSPKCS11Helper {
|
| |
- + static boolean isSensitiveObject(CK_ATTRIBUTE[] pTemplate) {
|
| |
- + for (CK_ATTRIBUTE attr : pTemplate) {
|
| |
- + if (attr.type == CKA_CLASS &&
|
| |
- + (attr.getLong() == CKO_PRIVATE_KEY ||
|
| |
- + attr.getLong() == CKO_SECRET_KEY)) {
|
| |
- + return true;
|
| |
- + }
|
| |
- + }
|
| |
- + return false;
|
| |
- + }
|
| |
- +}
|
| |
- }
|
| |
RH2090378: Revert to disabling system security properties and FIPS mode support together
Rebase RH1648249 nss.cfg patch so it applies after the FIPS patch
PR just for build testing, not review. This is the same change as previously applied to
java-17-openjdk
andjava-latest-openjdk
(though system security property enablement follows the placement of https://src.fedoraproject.org/rpms/java-17-openjdk/pull-request/19).