diff --git a/fips-17u-d63771ea660.patch b/fips-17u-d63771ea660.patch deleted file mode 100644 index 4830fb2..0000000 --- a/fips-17u-d63771ea660.patch +++ /dev/null @@ -1,7250 +0,0 @@ -diff --git a/make/autoconf/build-aux/pkg.m4 b/make/autoconf/build-aux/pkg.m4 -index 5f4b22bb27f..1ca9f5b8ffe 100644 ---- a/make/autoconf/build-aux/pkg.m4 -+++ b/make/autoconf/build-aux/pkg.m4 -@@ -179,3 +179,19 @@ else - ifelse([$3], , :, [$3]) - fi[]dnl - ])# PKG_CHECK_MODULES -+ -+dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, -+dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -+dnl ------------------------------------------- -+dnl Since: 0.28 -+dnl -+dnl Retrieves the value of the pkg-config variable for the given module. -+AC_DEFUN([PKG_CHECK_VAR], -+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -+AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl -+ -+_PKG_CONFIG([$1], [variable="][$3]["], [$2]) -+AS_VAR_COPY([$1], [pkg_cv_][$1]) -+ -+AS_VAR_IF([$1], [""], [$5], [$4])dnl -+])dnl PKG_CHECK_VAR -diff --git a/make/autoconf/lib-sysconf.m4 b/make/autoconf/lib-sysconf.m4 -new file mode 100644 -index 00000000000..f48fc7f7e80 ---- /dev/null -+++ b/make/autoconf/lib-sysconf.m4 -@@ -0,0 +1,87 @@ -+# -+# 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. -+# -+ -+################################################################################ -+# Setup system configuration libraries -+################################################################################ -+AC_DEFUN_ONCE([LIB_SETUP_SYSCONF_LIBS], -+[ -+ ############################################################################### -+ # -+ # Check for the NSS library -+ # -+ AC_MSG_CHECKING([for NSS library directory]) -+ PKG_CHECK_VAR(NSS_LIBDIR, nss, libdir, [AC_MSG_RESULT([$NSS_LIBDIR])], [AC_MSG_RESULT([not found])]) -+ -+ AC_MSG_CHECKING([whether to link the system NSS library with the System Configurator (libsysconf)]) -+ -+ # default is not available -+ DEFAULT_SYSCONF_NSS=no -+ -+ AC_ARG_ENABLE([sysconf-nss], [AS_HELP_STRING([--enable-sysconf-nss], -+ [build the System Configurator (libsysconf) using the system NSS library if available @<:@disabled@:>@])], -+ [ -+ case "${enableval}" in -+ yes) -+ sysconf_nss=yes -+ ;; -+ *) -+ sysconf_nss=no -+ ;; -+ esac -+ ], -+ [ -+ sysconf_nss=${DEFAULT_SYSCONF_NSS} -+ ]) -+ AC_MSG_RESULT([$sysconf_nss]) -+ -+ USE_SYSCONF_NSS=false -+ if test "x${sysconf_nss}" = "xyes"; then -+ PKG_CHECK_MODULES(NSS, nss >= 3.53, [NSS_FOUND=yes], [NSS_FOUND=no]) -+ if test "x${NSS_FOUND}" = "xyes"; then -+ AC_MSG_CHECKING([for system FIPS support in NSS]) -+ saved_libs="${LIBS}" -+ saved_cflags="${CFLAGS}" -+ CFLAGS="${CFLAGS} ${NSS_CFLAGS}" -+ LIBS="${LIBS} ${NSS_LIBS}" -+ AC_LANG_PUSH([C]) -+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], -+ [[SECMOD_GetSystemFIPSEnabled()]])], -+ [AC_MSG_RESULT([yes])], -+ [AC_MSG_RESULT([no]) -+ AC_MSG_ERROR([System NSS FIPS detection unavailable])]) -+ AC_LANG_POP([C]) -+ CFLAGS="${saved_cflags}" -+ LIBS="${saved_libs}" -+ USE_SYSCONF_NSS=true -+ else -+ dnl NSS 3.53 is the one that introduces the SECMOD_GetSystemFIPSEnabled API -+ dnl in nss3/pk11pub.h. -+ AC_MSG_ERROR([--enable-sysconf-nss specified, but NSS 3.53 or above not found.]) -+ fi -+ fi -+ AC_SUBST(USE_SYSCONF_NSS) -+ AC_SUBST(NSS_LIBDIR) -+]) -diff --git a/make/autoconf/libraries.m4 b/make/autoconf/libraries.m4 -index 62db5b16c31..f0bb4333fc9 100644 ---- a/make/autoconf/libraries.m4 -+++ b/make/autoconf/libraries.m4 -@@ -33,6 +33,7 @@ m4_include([lib-std.m4]) - m4_include([lib-x11.m4]) - m4_include([lib-fontconfig.m4]) - m4_include([lib-tests.m4]) -+m4_include([lib-sysconf.m4]) - - ################################################################################ - # Determine which libraries are needed for this configuration -@@ -104,6 +105,7 @@ AC_DEFUN_ONCE([LIB_SETUP_LIBRARIES], - LIB_SETUP_BUNDLED_LIBS - LIB_SETUP_MISC_LIBS - LIB_TESTS_SETUP_GTEST -+ LIB_SETUP_SYSCONF_LIBS - - BASIC_JDKLIB_LIBS="" - if test "x$TOOLCHAIN_TYPE" != xmicrosoft; then -diff --git a/make/autoconf/spec.gmk.in b/make/autoconf/spec.gmk.in -index 537c3e3043c..16ad3df6f09 100644 ---- a/make/autoconf/spec.gmk.in -+++ b/make/autoconf/spec.gmk.in -@@ -841,6 +841,11 @@ INSTALL_SYSCONFDIR=@sysconfdir@ - # Libraries - # - -+USE_SYSCONF_NSS:=@USE_SYSCONF_NSS@ -+NSS_LIBS:=@NSS_LIBS@ -+NSS_CFLAGS:=@NSS_CFLAGS@ -+NSS_LIBDIR:=@NSS_LIBDIR@ -+ - USE_EXTERNAL_LCMS:=@USE_EXTERNAL_LCMS@ - LCMS_CFLAGS:=@LCMS_CFLAGS@ - LCMS_LIBS:=@LCMS_LIBS@ -diff --git a/make/modules/java.base/Gendata.gmk b/make/modules/java.base/Gendata.gmk -index 4b894eeae4a..51567071aa8 100644 ---- a/make/modules/java.base/Gendata.gmk -+++ b/make/modules/java.base/Gendata.gmk -@@ -98,3 +98,17 @@ $(GENDATA_JAVA_SECURITY): $(BUILD_TOOLS_JDK) $(GENDATA_JAVA_SECURITY_SRC) $(REST - TARGETS += $(GENDATA_JAVA_SECURITY) - - ################################################################################ -+ -+GENDATA_NSS_FIPS_CFG_SRC := $(TOPDIR)/src/java.base/share/conf/security/nss.fips.cfg.in -+GENDATA_NSS_FIPS_CFG := $(SUPPORT_OUTPUTDIR)/modules_conf/java.base/security/nss.fips.cfg -+ -+$(GENDATA_NSS_FIPS_CFG): $(GENDATA_NSS_FIPS_CFG_SRC) -+ $(call LogInfo, Generating nss.fips.cfg) -+ $(call MakeTargetDir) -+ $(call ExecuteWithLog, $(SUPPORT_OUTPUTDIR)/gensrc/java.base/_$(@F), \ -+ ( $(SED) -e 's:@NSS_LIBDIR@:$(NSS_LIBDIR):g' $< ) > $@ \ -+ ) -+ -+TARGETS += $(GENDATA_NSS_FIPS_CFG) -+ -+################################################################################ -diff --git a/make/modules/java.base/Lib.gmk b/make/modules/java.base/Lib.gmk -index 5658ff342e5..c8bc5bde1e1 100644 ---- a/make/modules/java.base/Lib.gmk -+++ b/make/modules/java.base/Lib.gmk -@@ -167,6 +167,29 @@ ifeq ($(call isTargetOsType, unix), true) - endif - endif - -+################################################################################ -+# Create the systemconf library -+ -+LIBSYSTEMCONF_CFLAGS := -+LIBSYSTEMCONF_CXXFLAGS := -+ -+ifeq ($(USE_SYSCONF_NSS), true) -+ LIBSYSTEMCONF_CFLAGS += $(NSS_CFLAGS) -DSYSCONF_NSS -+ LIBSYSTEMCONF_CXXFLAGS += $(NSS_CFLAGS) -DSYSCONF_NSS -+endif -+ -+$(eval $(call SetupJdkLibrary, BUILD_LIBSYSTEMCONF, \ -+ NAME := systemconf, \ -+ OPTIMIZATION := LOW, \ -+ CFLAGS := $(CFLAGS_JDKLIB) $(LIBSYSTEMCONF_CFLAGS), \ -+ CXXFLAGS := $(CXXFLAGS_JDKLIB) $(LIBSYSTEMCONF_CXXFLAGS), \ -+ LDFLAGS := $(LDFLAGS_JDKLIB) \ -+ $(call SET_SHARED_LIBRARY_ORIGIN), \ -+ LIBS_unix := $(LIBDL) $(NSS_LIBS), \ -+)) -+ -+TARGETS += $(BUILD_LIBSYSTEMCONF) -+ - ################################################################################ - # Create the symbols file for static builds. - -diff --git a/src/java.base/share/classes/com/sun/crypto/provider/HmacPKCS12PBECore.java b/src/java.base/share/classes/com/sun/crypto/provider/HmacPKCS12PBECore.java -index 1fd6230d83b..683e3dd3a8d 100644 ---- a/src/java.base/share/classes/com/sun/crypto/provider/HmacPKCS12PBECore.java -+++ b/src/java.base/share/classes/com/sun/crypto/provider/HmacPKCS12PBECore.java -@@ -25,13 +25,12 @@ - - package com.sun.crypto.provider; - --import java.util.Arrays; -- - import javax.crypto.SecretKey; - import javax.crypto.spec.SecretKeySpec; --import javax.crypto.spec.PBEParameterSpec; -+import javax.crypto.spec.PBEKeySpec; - import java.security.*; - import java.security.spec.*; -+import sun.security.util.PBEUtil; - - /** - * This is an implementation of the HMAC algorithms as defined -@@ -108,79 +107,15 @@ abstract class HmacPKCS12PBECore extends HmacCore { - */ - protected void engineInit(Key key, AlgorithmParameterSpec params) - throws InvalidKeyException, InvalidAlgorithmParameterException { -- char[] passwdChars; -- byte[] salt = null; -- int iCount = 0; -- if (key instanceof javax.crypto.interfaces.PBEKey) { -- javax.crypto.interfaces.PBEKey pbeKey = -- (javax.crypto.interfaces.PBEKey) key; -- passwdChars = pbeKey.getPassword(); -- salt = pbeKey.getSalt(); // maybe null if unspecified -- iCount = pbeKey.getIterationCount(); // maybe 0 if unspecified -- } else if (key instanceof SecretKey) { -- byte[] passwdBytes; -- if (!(key.getAlgorithm().regionMatches(true, 0, "PBE", 0, 3)) || -- (passwdBytes = key.getEncoded()) == null) { -- throw new InvalidKeyException("Missing password"); -- } -- passwdChars = new char[passwdBytes.length]; -- for (int i=0; i attrs = new HashMap<>(3); -- attrs.put("SupportedModes", "ECB"); -- attrs.put("SupportedPaddings", "NOPADDING|PKCS1PADDING|OAEPPADDING" -- + "|OAEPWITHMD5ANDMGF1PADDING" -- + "|OAEPWITHSHA1ANDMGF1PADDING" -- + "|OAEPWITHSHA-1ANDMGF1PADDING" -- + "|OAEPWITHSHA-224ANDMGF1PADDING" -- + "|OAEPWITHSHA-256ANDMGF1PADDING" -- + "|OAEPWITHSHA-384ANDMGF1PADDING" -- + "|OAEPWITHSHA-512ANDMGF1PADDING" -- + "|OAEPWITHSHA-512/224ANDMGF1PADDING" -- + "|OAEPWITHSHA-512/256ANDMGF1PADDING"); -- attrs.put("SupportedKeyClasses", -- "java.security.interfaces.RSAPublicKey" + -- "|java.security.interfaces.RSAPrivateKey"); -- ps("Cipher", "RSA", -- "com.sun.crypto.provider.RSACipher", null, attrs); -- -- // common block cipher modes, pads -- final String BLOCK_MODES = "ECB|CBC|PCBC|CTR|CTS|CFB|OFB" + -- "|CFB8|CFB16|CFB24|CFB32|CFB40|CFB48|CFB56|CFB64" + -- "|OFB8|OFB16|OFB24|OFB32|OFB40|OFB48|OFB56|OFB64"; -- final String BLOCK_MODES128 = BLOCK_MODES + -- "|CFB72|CFB80|CFB88|CFB96|CFB104|CFB112|CFB120|CFB128" + -- "|OFB72|OFB80|OFB88|OFB96|OFB104|OFB112|OFB120|OFB128"; -- final String BLOCK_PADS = "NOPADDING|PKCS5PADDING|ISO10126PADDING"; -- -- attrs.clear(); -- attrs.put("SupportedModes", BLOCK_MODES); -- attrs.put("SupportedPaddings", BLOCK_PADS); -- attrs.put("SupportedKeyFormats", "RAW"); -- ps("Cipher", "DES", -- "com.sun.crypto.provider.DESCipher", null, attrs); -- psA("Cipher", "DESede", "com.sun.crypto.provider.DESedeCipher", -- attrs); -- ps("Cipher", "Blowfish", -- "com.sun.crypto.provider.BlowfishCipher", null, attrs); -- -- ps("Cipher", "RC2", -- "com.sun.crypto.provider.RC2Cipher", null, attrs); -- -- attrs.clear(); -- attrs.put("SupportedModes", BLOCK_MODES128); -- attrs.put("SupportedPaddings", BLOCK_PADS); -- attrs.put("SupportedKeyFormats", "RAW"); -- psA("Cipher", "AES", -- "com.sun.crypto.provider.AESCipher$General", attrs); -- -- attrs.clear(); -- attrs.put("SupportedKeyFormats", "RAW"); -- psA("Cipher", "AES/KW/NoPadding", -- "com.sun.crypto.provider.KeyWrapCipher$AES_KW_NoPadding", -- attrs); -- ps("Cipher", "AES/KW/PKCS5Padding", -- "com.sun.crypto.provider.KeyWrapCipher$AES_KW_PKCS5Padding", -- null, attrs); -- psA("Cipher", "AES/KWP/NoPadding", -- "com.sun.crypto.provider.KeyWrapCipher$AES_KWP_NoPadding", -- attrs); -- -- psA("Cipher", "AES_128/ECB/NoPadding", -- "com.sun.crypto.provider.AESCipher$AES128_ECB_NoPadding", -- attrs); -- psA("Cipher", "AES_128/CBC/NoPadding", -- "com.sun.crypto.provider.AESCipher$AES128_CBC_NoPadding", -- attrs); -- psA("Cipher", "AES_128/OFB/NoPadding", -- "com.sun.crypto.provider.AESCipher$AES128_OFB_NoPadding", -- attrs); -- psA("Cipher", "AES_128/CFB/NoPadding", -- "com.sun.crypto.provider.AESCipher$AES128_CFB_NoPadding", -- attrs); -- psA("Cipher", "AES_128/KW/NoPadding", -- "com.sun.crypto.provider.KeyWrapCipher$AES128_KW_NoPadding", -- attrs); -- ps("Cipher", "AES_128/KW/PKCS5Padding", -- "com.sun.crypto.provider.KeyWrapCipher$AES128_KW_PKCS5Padding", -- null, attrs); -- psA("Cipher", "AES_128/KWP/NoPadding", -- "com.sun.crypto.provider.KeyWrapCipher$AES128_KWP_NoPadding", -- attrs); -- -- psA("Cipher", "AES_192/ECB/NoPadding", -- "com.sun.crypto.provider.AESCipher$AES192_ECB_NoPadding", -- attrs); -- psA("Cipher", "AES_192/CBC/NoPadding", -- "com.sun.crypto.provider.AESCipher$AES192_CBC_NoPadding", -- attrs); -- psA("Cipher", "AES_192/OFB/NoPadding", -- "com.sun.crypto.provider.AESCipher$AES192_OFB_NoPadding", -- attrs); -- psA("Cipher", "AES_192/CFB/NoPadding", -- "com.sun.crypto.provider.AESCipher$AES192_CFB_NoPadding", -- attrs); -- psA("Cipher", "AES_192/KW/NoPadding", -- "com.sun.crypto.provider.KeyWrapCipher$AES192_KW_NoPadding", -- attrs); -- ps("Cipher", "AES_192/KW/PKCS5Padding", -- "com.sun.crypto.provider.KeyWrapCipher$AES192_KW_PKCS5Padding", -- null, attrs); -- psA("Cipher", "AES_192/KWP/NoPadding", -- "com.sun.crypto.provider.KeyWrapCipher$AES192_KWP_NoPadding", -- attrs); -- -- psA("Cipher", "AES_256/ECB/NoPadding", -- "com.sun.crypto.provider.AESCipher$AES256_ECB_NoPadding", -- attrs); -- psA("Cipher", "AES_256/CBC/NoPadding", -- "com.sun.crypto.provider.AESCipher$AES256_CBC_NoPadding", -- attrs); -- psA("Cipher", "AES_256/OFB/NoPadding", -- "com.sun.crypto.provider.AESCipher$AES256_OFB_NoPadding", -- attrs); -- psA("Cipher", "AES_256/CFB/NoPadding", -- "com.sun.crypto.provider.AESCipher$AES256_CFB_NoPadding", -- attrs); -- psA("Cipher", "AES_256/KW/NoPadding", -- "com.sun.crypto.provider.KeyWrapCipher$AES256_KW_NoPadding", -- attrs); -- ps("Cipher", "AES_256/KW/PKCS5Padding", -- "com.sun.crypto.provider.KeyWrapCipher$AES256_KW_PKCS5Padding", -- null, attrs); -- psA("Cipher", "AES_256/KWP/NoPadding", -- "com.sun.crypto.provider.KeyWrapCipher$AES256_KWP_NoPadding", -- attrs); -- -- attrs.clear(); -- attrs.put("SupportedModes", "GCM"); -- attrs.put("SupportedKeyFormats", "RAW"); -- -- ps("Cipher", "AES/GCM/NoPadding", -- "com.sun.crypto.provider.GaloisCounterMode$AESGCM", null, -- attrs); -- psA("Cipher", "AES_128/GCM/NoPadding", -- "com.sun.crypto.provider.GaloisCounterMode$AES128", -- attrs); -- psA("Cipher", "AES_192/GCM/NoPadding", -- "com.sun.crypto.provider.GaloisCounterMode$AES192", -- attrs); -- psA("Cipher", "AES_256/GCM/NoPadding", -- "com.sun.crypto.provider.GaloisCounterMode$AES256", -- attrs); -- -- attrs.clear(); -- attrs.put("SupportedModes", "CBC"); -- attrs.put("SupportedPaddings", "NOPADDING"); -- attrs.put("SupportedKeyFormats", "RAW"); -- ps("Cipher", "DESedeWrap", -- "com.sun.crypto.provider.DESedeWrapCipher", null, attrs); -- -- attrs.clear(); -- attrs.put("SupportedModes", "ECB"); -- attrs.put("SupportedPaddings", "NOPADDING"); -- attrs.put("SupportedKeyFormats", "RAW"); -- psA("Cipher", "ARCFOUR", -- "com.sun.crypto.provider.ARCFOURCipher", attrs); -- -- attrs.clear(); -- attrs.put("SupportedKeyFormats", "RAW"); -- ps("Cipher", "ChaCha20", -- "com.sun.crypto.provider.ChaCha20Cipher$ChaCha20Only", -- null, attrs); -- psA("Cipher", "ChaCha20-Poly1305", -- "com.sun.crypto.provider.ChaCha20Cipher$ChaCha20Poly1305", -- attrs); -- -- // PBES1 -- psA("Cipher", "PBEWithMD5AndDES", -- "com.sun.crypto.provider.PBEWithMD5AndDESCipher", -- null); -- ps("Cipher", "PBEWithMD5AndTripleDES", -- "com.sun.crypto.provider.PBEWithMD5AndTripleDESCipher"); -- psA("Cipher", "PBEWithSHA1AndDESede", -- "com.sun.crypto.provider.PKCS12PBECipherCore$PBEWithSHA1AndDESede", -- null); -- psA("Cipher", "PBEWithSHA1AndRC2_40", -- "com.sun.crypto.provider.PKCS12PBECipherCore$PBEWithSHA1AndRC2_40", -- null); -- psA("Cipher", "PBEWithSHA1AndRC2_128", -- "com.sun.crypto.provider.PKCS12PBECipherCore$PBEWithSHA1AndRC2_128", -- null); -- psA("Cipher", "PBEWithSHA1AndRC4_40", -- "com.sun.crypto.provider.PKCS12PBECipherCore$PBEWithSHA1AndRC4_40", -- null); -- -- psA("Cipher", "PBEWithSHA1AndRC4_128", -- "com.sun.crypto.provider.PKCS12PBECipherCore$PBEWithSHA1AndRC4_128", -- null); -- -- // PBES2 -- ps("Cipher", "PBEWithHmacSHA1AndAES_128", -- "com.sun.crypto.provider.PBES2Core$HmacSHA1AndAES_128"); -- -- ps("Cipher", "PBEWithHmacSHA224AndAES_128", -- "com.sun.crypto.provider.PBES2Core$HmacSHA224AndAES_128"); -- -- ps("Cipher", "PBEWithHmacSHA256AndAES_128", -- "com.sun.crypto.provider.PBES2Core$HmacSHA256AndAES_128"); -- -- ps("Cipher", "PBEWithHmacSHA384AndAES_128", -- "com.sun.crypto.provider.PBES2Core$HmacSHA384AndAES_128"); -- -- ps("Cipher", "PBEWithHmacSHA512AndAES_128", -- "com.sun.crypto.provider.PBES2Core$HmacSHA512AndAES_128"); -- -- ps("Cipher", "PBEWithHmacSHA1AndAES_256", -- "com.sun.crypto.provider.PBES2Core$HmacSHA1AndAES_256"); -- -- ps("Cipher", "PBEWithHmacSHA224AndAES_256", -- "com.sun.crypto.provider.PBES2Core$HmacSHA224AndAES_256"); -- -- ps("Cipher", "PBEWithHmacSHA256AndAES_256", -- "com.sun.crypto.provider.PBES2Core$HmacSHA256AndAES_256"); -- -- ps("Cipher", "PBEWithHmacSHA384AndAES_256", -- "com.sun.crypto.provider.PBES2Core$HmacSHA384AndAES_256"); -- -- ps("Cipher", "PBEWithHmacSHA512AndAES_256", -- "com.sun.crypto.provider.PBES2Core$HmacSHA512AndAES_256"); -- -- /* -- * Key(pair) Generator engines -- */ -- ps("KeyGenerator", "DES", -- "com.sun.crypto.provider.DESKeyGenerator"); -- psA("KeyGenerator", "DESede", -- "com.sun.crypto.provider.DESedeKeyGenerator", -- null); -- ps("KeyGenerator", "Blowfish", -- "com.sun.crypto.provider.BlowfishKeyGenerator"); -- psA("KeyGenerator", "AES", -- "com.sun.crypto.provider.AESKeyGenerator", -- null); -- ps("KeyGenerator", "RC2", -- "com.sun.crypto.provider.KeyGeneratorCore$RC2KeyGenerator"); -- psA("KeyGenerator", "ARCFOUR", -- "com.sun.crypto.provider.KeyGeneratorCore$ARCFOURKeyGenerator", -- null); -- ps("KeyGenerator", "ChaCha20", -- "com.sun.crypto.provider.KeyGeneratorCore$ChaCha20KeyGenerator"); -- ps("KeyGenerator", "HmacMD5", -- "com.sun.crypto.provider.HmacMD5KeyGenerator"); -- -- psA("KeyGenerator", "HmacSHA1", -- "com.sun.crypto.provider.HmacSHA1KeyGenerator", null); -- psA("KeyGenerator", "HmacSHA224", -- "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA224", -- null); -- psA("KeyGenerator", "HmacSHA256", -- "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA256", -- null); -- psA("KeyGenerator", "HmacSHA384", -- "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA384", -- null); -- psA("KeyGenerator", "HmacSHA512", -- "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA512", -- null); -- psA("KeyGenerator", "HmacSHA512/224", -- "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA512_224", -- null); -- psA("KeyGenerator", "HmacSHA512/256", -- "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA512_256", -- null); -- -- psA("KeyGenerator", "HmacSHA3-224", -- "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA3_224", -- null); -- psA("KeyGenerator", "HmacSHA3-256", -- "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA3_256", -- null); -- psA("KeyGenerator", "HmacSHA3-384", -- "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA3_384", -- null); -- psA("KeyGenerator", "HmacSHA3-512", -- "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA3_512", -- null); -- -- psA("KeyPairGenerator", "DiffieHellman", -- "com.sun.crypto.provider.DHKeyPairGenerator", -- null); -+ if (!systemFipsEnabled) { -+ attrs.put("SupportedModes", "ECB"); -+ attrs.put("SupportedPaddings", "NOPADDING|PKCS1PADDING|OAEPPADDING" -+ + "|OAEPWITHMD5ANDMGF1PADDING" -+ + "|OAEPWITHSHA1ANDMGF1PADDING" -+ + "|OAEPWITHSHA-1ANDMGF1PADDING" -+ + "|OAEPWITHSHA-224ANDMGF1PADDING" -+ + "|OAEPWITHSHA-256ANDMGF1PADDING" -+ + "|OAEPWITHSHA-384ANDMGF1PADDING" -+ + "|OAEPWITHSHA-512ANDMGF1PADDING" -+ + "|OAEPWITHSHA-512/224ANDMGF1PADDING" -+ + "|OAEPWITHSHA-512/256ANDMGF1PADDING"); -+ attrs.put("SupportedKeyClasses", -+ "java.security.interfaces.RSAPublicKey" + -+ "|java.security.interfaces.RSAPrivateKey"); -+ ps("Cipher", "RSA", -+ "com.sun.crypto.provider.RSACipher", null, attrs); -+ -+ // common block cipher modes, pads -+ final String BLOCK_MODES = "ECB|CBC|PCBC|CTR|CTS|CFB|OFB" + -+ "|CFB8|CFB16|CFB24|CFB32|CFB40|CFB48|CFB56|CFB64" + -+ "|OFB8|OFB16|OFB24|OFB32|OFB40|OFB48|OFB56|OFB64"; -+ final String BLOCK_MODES128 = BLOCK_MODES + -+ "|CFB72|CFB80|CFB88|CFB96|CFB104|CFB112|CFB120|CFB128" + -+ "|OFB72|OFB80|OFB88|OFB96|OFB104|OFB112|OFB120|OFB128"; -+ final String BLOCK_PADS = "NOPADDING|PKCS5PADDING|ISO10126PADDING"; -+ -+ attrs.clear(); -+ attrs.put("SupportedModes", BLOCK_MODES); -+ attrs.put("SupportedPaddings", BLOCK_PADS); -+ attrs.put("SupportedKeyFormats", "RAW"); -+ ps("Cipher", "DES", -+ "com.sun.crypto.provider.DESCipher", null, attrs); -+ psA("Cipher", "DESede", "com.sun.crypto.provider.DESedeCipher", -+ attrs); -+ ps("Cipher", "Blowfish", -+ "com.sun.crypto.provider.BlowfishCipher", null, attrs); -+ -+ ps("Cipher", "RC2", -+ "com.sun.crypto.provider.RC2Cipher", null, attrs); -+ -+ attrs.clear(); -+ attrs.put("SupportedModes", BLOCK_MODES128); -+ attrs.put("SupportedPaddings", BLOCK_PADS); -+ attrs.put("SupportedKeyFormats", "RAW"); -+ psA("Cipher", "AES", -+ "com.sun.crypto.provider.AESCipher$General", attrs); -+ -+ attrs.clear(); -+ attrs.put("SupportedKeyFormats", "RAW"); -+ psA("Cipher", "AES/KW/NoPadding", -+ "com.sun.crypto.provider.KeyWrapCipher$AES_KW_NoPadding", -+ attrs); -+ ps("Cipher", "AES/KW/PKCS5Padding", -+ "com.sun.crypto.provider.KeyWrapCipher$AES_KW_PKCS5Padding", -+ null, attrs); -+ psA("Cipher", "AES/KWP/NoPadding", -+ "com.sun.crypto.provider.KeyWrapCipher$AES_KWP_NoPadding", -+ attrs); -+ -+ psA("Cipher", "AES_128/ECB/NoPadding", -+ "com.sun.crypto.provider.AESCipher$AES128_ECB_NoPadding", -+ attrs); -+ psA("Cipher", "AES_128/CBC/NoPadding", -+ "com.sun.crypto.provider.AESCipher$AES128_CBC_NoPadding", -+ attrs); -+ psA("Cipher", "AES_128/OFB/NoPadding", -+ "com.sun.crypto.provider.AESCipher$AES128_OFB_NoPadding", -+ attrs); -+ psA("Cipher", "AES_128/CFB/NoPadding", -+ "com.sun.crypto.provider.AESCipher$AES128_CFB_NoPadding", -+ attrs); -+ psA("Cipher", "AES_128/KW/NoPadding", -+ "com.sun.crypto.provider.KeyWrapCipher$AES128_KW_NoPadding", -+ attrs); -+ ps("Cipher", "AES_128/KW/PKCS5Padding", -+ "com.sun.crypto.provider.KeyWrapCipher$AES128_KW_PKCS5Padding", -+ null, attrs); -+ psA("Cipher", "AES_128/KWP/NoPadding", -+ "com.sun.crypto.provider.KeyWrapCipher$AES128_KWP_NoPadding", -+ attrs); -+ -+ psA("Cipher", "AES_192/ECB/NoPadding", -+ "com.sun.crypto.provider.AESCipher$AES192_ECB_NoPadding", -+ attrs); -+ psA("Cipher", "AES_192/CBC/NoPadding", -+ "com.sun.crypto.provider.AESCipher$AES192_CBC_NoPadding", -+ attrs); -+ psA("Cipher", "AES_192/OFB/NoPadding", -+ "com.sun.crypto.provider.AESCipher$AES192_OFB_NoPadding", -+ attrs); -+ psA("Cipher", "AES_192/CFB/NoPadding", -+ "com.sun.crypto.provider.AESCipher$AES192_CFB_NoPadding", -+ attrs); -+ psA("Cipher", "AES_192/KW/NoPadding", -+ "com.sun.crypto.provider.KeyWrapCipher$AES192_KW_NoPadding", -+ attrs); -+ ps("Cipher", "AES_192/KW/PKCS5Padding", -+ "com.sun.crypto.provider.KeyWrapCipher$AES192_KW_PKCS5Padding", -+ null, attrs); -+ psA("Cipher", "AES_192/KWP/NoPadding", -+ "com.sun.crypto.provider.KeyWrapCipher$AES192_KWP_NoPadding", -+ attrs); -+ -+ psA("Cipher", "AES_256/ECB/NoPadding", -+ "com.sun.crypto.provider.AESCipher$AES256_ECB_NoPadding", -+ attrs); -+ psA("Cipher", "AES_256/CBC/NoPadding", -+ "com.sun.crypto.provider.AESCipher$AES256_CBC_NoPadding", -+ attrs); -+ psA("Cipher", "AES_256/OFB/NoPadding", -+ "com.sun.crypto.provider.AESCipher$AES256_OFB_NoPadding", -+ attrs); -+ psA("Cipher", "AES_256/CFB/NoPadding", -+ "com.sun.crypto.provider.AESCipher$AES256_CFB_NoPadding", -+ attrs); -+ psA("Cipher", "AES_256/KW/NoPadding", -+ "com.sun.crypto.provider.KeyWrapCipher$AES256_KW_NoPadding", -+ attrs); -+ ps("Cipher", "AES_256/KW/PKCS5Padding", -+ "com.sun.crypto.provider.KeyWrapCipher$AES256_KW_PKCS5Padding", -+ null, attrs); -+ psA("Cipher", "AES_256/KWP/NoPadding", -+ "com.sun.crypto.provider.KeyWrapCipher$AES256_KWP_NoPadding", -+ attrs); -+ -+ attrs.clear(); -+ attrs.put("SupportedModes", "GCM"); -+ attrs.put("SupportedKeyFormats", "RAW"); -+ -+ ps("Cipher", "AES/GCM/NoPadding", -+ "com.sun.crypto.provider.GaloisCounterMode$AESGCM", null, -+ attrs); -+ psA("Cipher", "AES_128/GCM/NoPadding", -+ "com.sun.crypto.provider.GaloisCounterMode$AES128", -+ attrs); -+ psA("Cipher", "AES_192/GCM/NoPadding", -+ "com.sun.crypto.provider.GaloisCounterMode$AES192", -+ attrs); -+ psA("Cipher", "AES_256/GCM/NoPadding", -+ "com.sun.crypto.provider.GaloisCounterMode$AES256", -+ attrs); -+ -+ attrs.clear(); -+ attrs.put("SupportedModes", "CBC"); -+ attrs.put("SupportedPaddings", "NOPADDING"); -+ attrs.put("SupportedKeyFormats", "RAW"); -+ ps("Cipher", "DESedeWrap", -+ "com.sun.crypto.provider.DESedeWrapCipher", null, attrs); -+ -+ attrs.clear(); -+ attrs.put("SupportedModes", "ECB"); -+ attrs.put("SupportedPaddings", "NOPADDING"); -+ attrs.put("SupportedKeyFormats", "RAW"); -+ psA("Cipher", "ARCFOUR", -+ "com.sun.crypto.provider.ARCFOURCipher", attrs); -+ -+ attrs.clear(); -+ attrs.put("SupportedKeyFormats", "RAW"); -+ ps("Cipher", "ChaCha20", -+ "com.sun.crypto.provider.ChaCha20Cipher$ChaCha20Only", -+ null, attrs); -+ psA("Cipher", "ChaCha20-Poly1305", -+ "com.sun.crypto.provider.ChaCha20Cipher$ChaCha20Poly1305", -+ attrs); -+ -+ // PBES1 -+ psA("Cipher", "PBEWithMD5AndDES", -+ "com.sun.crypto.provider.PBEWithMD5AndDESCipher", -+ null); -+ ps("Cipher", "PBEWithMD5AndTripleDES", -+ "com.sun.crypto.provider.PBEWithMD5AndTripleDESCipher"); -+ psA("Cipher", "PBEWithSHA1AndDESede", -+ "com.sun.crypto.provider.PKCS12PBECipherCore$PBEWithSHA1AndDESede", -+ null); -+ psA("Cipher", "PBEWithSHA1AndRC2_40", -+ "com.sun.crypto.provider.PKCS12PBECipherCore$PBEWithSHA1AndRC2_40", -+ null); -+ psA("Cipher", "PBEWithSHA1AndRC2_128", -+ "com.sun.crypto.provider.PKCS12PBECipherCore$PBEWithSHA1AndRC2_128", -+ null); -+ psA("Cipher", "PBEWithSHA1AndRC4_40", -+ "com.sun.crypto.provider.PKCS12PBECipherCore$PBEWithSHA1AndRC4_40", -+ null); -+ -+ psA("Cipher", "PBEWithSHA1AndRC4_128", -+ "com.sun.crypto.provider.PKCS12PBECipherCore$PBEWithSHA1AndRC4_128", -+ null); -+ -+ // PBES2 -+ ps("Cipher", "PBEWithHmacSHA1AndAES_128", -+ "com.sun.crypto.provider.PBES2Core$HmacSHA1AndAES_128"); -+ -+ ps("Cipher", "PBEWithHmacSHA224AndAES_128", -+ "com.sun.crypto.provider.PBES2Core$HmacSHA224AndAES_128"); -+ -+ ps("Cipher", "PBEWithHmacSHA256AndAES_128", -+ "com.sun.crypto.provider.PBES2Core$HmacSHA256AndAES_128"); -+ -+ ps("Cipher", "PBEWithHmacSHA384AndAES_128", -+ "com.sun.crypto.provider.PBES2Core$HmacSHA384AndAES_128"); -+ -+ ps("Cipher", "PBEWithHmacSHA512AndAES_128", -+ "com.sun.crypto.provider.PBES2Core$HmacSHA512AndAES_128"); -+ -+ ps("Cipher", "PBEWithHmacSHA1AndAES_256", -+ "com.sun.crypto.provider.PBES2Core$HmacSHA1AndAES_256"); -+ -+ ps("Cipher", "PBEWithHmacSHA224AndAES_256", -+ "com.sun.crypto.provider.PBES2Core$HmacSHA224AndAES_256"); -+ -+ ps("Cipher", "PBEWithHmacSHA256AndAES_256", -+ "com.sun.crypto.provider.PBES2Core$HmacSHA256AndAES_256"); -+ -+ ps("Cipher", "PBEWithHmacSHA384AndAES_256", -+ "com.sun.crypto.provider.PBES2Core$HmacSHA384AndAES_256"); -+ -+ ps("Cipher", "PBEWithHmacSHA512AndAES_256", -+ "com.sun.crypto.provider.PBES2Core$HmacSHA512AndAES_256"); -+ -+ /* -+ * Key(pair) Generator engines -+ */ -+ ps("KeyGenerator", "DES", -+ "com.sun.crypto.provider.DESKeyGenerator"); -+ psA("KeyGenerator", "DESede", -+ "com.sun.crypto.provider.DESedeKeyGenerator", -+ null); -+ ps("KeyGenerator", "Blowfish", -+ "com.sun.crypto.provider.BlowfishKeyGenerator"); -+ psA("KeyGenerator", "AES", -+ "com.sun.crypto.provider.AESKeyGenerator", -+ null); -+ ps("KeyGenerator", "RC2", -+ "com.sun.crypto.provider.KeyGeneratorCore$RC2KeyGenerator"); -+ psA("KeyGenerator", "ARCFOUR", -+ "com.sun.crypto.provider.KeyGeneratorCore$ARCFOURKeyGenerator", -+ null); -+ ps("KeyGenerator", "ChaCha20", -+ "com.sun.crypto.provider.KeyGeneratorCore$ChaCha20KeyGenerator"); -+ ps("KeyGenerator", "HmacMD5", -+ "com.sun.crypto.provider.HmacMD5KeyGenerator"); -+ -+ psA("KeyGenerator", "HmacSHA1", -+ "com.sun.crypto.provider.HmacSHA1KeyGenerator", null); -+ psA("KeyGenerator", "HmacSHA224", -+ "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA224", -+ null); -+ psA("KeyGenerator", "HmacSHA256", -+ "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA256", -+ null); -+ psA("KeyGenerator", "HmacSHA384", -+ "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA384", -+ null); -+ psA("KeyGenerator", "HmacSHA512", -+ "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA512", -+ null); -+ psA("KeyGenerator", "HmacSHA512/224", -+ "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA512_224", -+ null); -+ psA("KeyGenerator", "HmacSHA512/256", -+ "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA512_256", -+ null); -+ -+ psA("KeyGenerator", "HmacSHA3-224", -+ "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA3_224", -+ null); -+ psA("KeyGenerator", "HmacSHA3-256", -+ "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA3_256", -+ null); -+ psA("KeyGenerator", "HmacSHA3-384", -+ "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA3_384", -+ null); -+ psA("KeyGenerator", "HmacSHA3-512", -+ "com.sun.crypto.provider.KeyGeneratorCore$HmacKG$SHA3_512", -+ null); -+ -+ psA("KeyPairGenerator", "DiffieHellman", -+ "com.sun.crypto.provider.DHKeyPairGenerator", -+ null); -+ } - - /* - * Algorithm parameter generation engines -@@ -430,15 +437,17 @@ public final class SunJCE extends Provider { - "DiffieHellman", "com.sun.crypto.provider.DHParameterGenerator", - null); - -- /* -- * Key Agreement engines -- */ -- attrs.clear(); -- attrs.put("SupportedKeyClasses", "javax.crypto.interfaces.DHPublicKey" + -- "|javax.crypto.interfaces.DHPrivateKey"); -- psA("KeyAgreement", "DiffieHellman", -- "com.sun.crypto.provider.DHKeyAgreement", -- attrs); -+ if (!systemFipsEnabled) { -+ /* -+ * Key Agreement engines -+ */ -+ attrs.clear(); -+ attrs.put("SupportedKeyClasses", "javax.crypto.interfaces.DHPublicKey" + -+ "|javax.crypto.interfaces.DHPrivateKey"); -+ psA("KeyAgreement", "DiffieHellman", -+ "com.sun.crypto.provider.DHKeyAgreement", -+ attrs); -+ } - - /* - * Algorithm Parameter engines -@@ -610,118 +619,120 @@ public final class SunJCE extends Provider { - ps("SecretKeyFactory", "PBEWithHmacSHA512AndAES_256", - "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA512AndAES_256"); - -- // PBKDF2 -- psA("SecretKeyFactory", "PBKDF2WithHmacSHA1", -- "com.sun.crypto.provider.PBKDF2Core$HmacSHA1", -- null); -- ps("SecretKeyFactory", "PBKDF2WithHmacSHA224", -- "com.sun.crypto.provider.PBKDF2Core$HmacSHA224"); -- ps("SecretKeyFactory", "PBKDF2WithHmacSHA256", -- "com.sun.crypto.provider.PBKDF2Core$HmacSHA256"); -- ps("SecretKeyFactory", "PBKDF2WithHmacSHA384", -- "com.sun.crypto.provider.PBKDF2Core$HmacSHA384"); -- ps("SecretKeyFactory", "PBKDF2WithHmacSHA512", -- "com.sun.crypto.provider.PBKDF2Core$HmacSHA512"); -- -- /* -- * MAC -- */ -- attrs.clear(); -- attrs.put("SupportedKeyFormats", "RAW"); -- ps("Mac", "HmacMD5", "com.sun.crypto.provider.HmacMD5", null, attrs); -- psA("Mac", "HmacSHA1", "com.sun.crypto.provider.HmacSHA1", -- attrs); -- psA("Mac", "HmacSHA224", -- "com.sun.crypto.provider.HmacCore$HmacSHA224", attrs); -- psA("Mac", "HmacSHA256", -- "com.sun.crypto.provider.HmacCore$HmacSHA256", attrs); -- psA("Mac", "HmacSHA384", -- "com.sun.crypto.provider.HmacCore$HmacSHA384", attrs); -- psA("Mac", "HmacSHA512", -- "com.sun.crypto.provider.HmacCore$HmacSHA512", attrs); -- psA("Mac", "HmacSHA512/224", -- "com.sun.crypto.provider.HmacCore$HmacSHA512_224", attrs); -- psA("Mac", "HmacSHA512/256", -- "com.sun.crypto.provider.HmacCore$HmacSHA512_256", attrs); -- psA("Mac", "HmacSHA3-224", -- "com.sun.crypto.provider.HmacCore$HmacSHA3_224", attrs); -- psA("Mac", "HmacSHA3-256", -- "com.sun.crypto.provider.HmacCore$HmacSHA3_256", attrs); -- psA("Mac", "HmacSHA3-384", -- "com.sun.crypto.provider.HmacCore$HmacSHA3_384", attrs); -- psA("Mac", "HmacSHA3-512", -- "com.sun.crypto.provider.HmacCore$HmacSHA3_512", attrs); -- -- ps("Mac", "HmacPBESHA1", -- "com.sun.crypto.provider.HmacPKCS12PBECore$HmacPKCS12PBE_SHA1", -- null, attrs); -- ps("Mac", "HmacPBESHA224", -- "com.sun.crypto.provider.HmacPKCS12PBECore$HmacPKCS12PBE_SHA224", -- null, attrs); -- ps("Mac", "HmacPBESHA256", -- "com.sun.crypto.provider.HmacPKCS12PBECore$HmacPKCS12PBE_SHA256", -- null, attrs); -- ps("Mac", "HmacPBESHA384", -- "com.sun.crypto.provider.HmacPKCS12PBECore$HmacPKCS12PBE_SHA384", -- null, attrs); -- ps("Mac", "HmacPBESHA512", -- "com.sun.crypto.provider.HmacPKCS12PBECore$HmacPKCS12PBE_SHA512", -- null, attrs); -- ps("Mac", "HmacPBESHA512/224", -- "com.sun.crypto.provider.HmacPKCS12PBECore$HmacPKCS12PBE_SHA512_224", -- null, attrs); -- ps("Mac", "HmacPBESHA512/256", -- "com.sun.crypto.provider.HmacPKCS12PBECore$HmacPKCS12PBE_SHA512_256", -- null, attrs); -- -- -- // PBMAC1 -- ps("Mac", "PBEWithHmacSHA1", -- "com.sun.crypto.provider.PBMAC1Core$HmacSHA1", null, attrs); -- ps("Mac", "PBEWithHmacSHA224", -- "com.sun.crypto.provider.PBMAC1Core$HmacSHA224", null, attrs); -- ps("Mac", "PBEWithHmacSHA256", -- "com.sun.crypto.provider.PBMAC1Core$HmacSHA256", null, attrs); -- ps("Mac", "PBEWithHmacSHA384", -- "com.sun.crypto.provider.PBMAC1Core$HmacSHA384", null, attrs); -- ps("Mac", "PBEWithHmacSHA512", -- "com.sun.crypto.provider.PBMAC1Core$HmacSHA512", null, attrs); -- ps("Mac", "SslMacMD5", -- "com.sun.crypto.provider.SslMacCore$SslMacMD5", null, attrs); -- ps("Mac", "SslMacSHA1", -- "com.sun.crypto.provider.SslMacCore$SslMacSHA1", null, attrs); -- -- /* -- * KeyStore -- */ -- ps("KeyStore", "JCEKS", -- "com.sun.crypto.provider.JceKeyStore"); -- -- /* -- * SSL/TLS mechanisms -- * -- * These are strictly internal implementations and may -- * be changed at any time. These names were chosen -- * because PKCS11/SunPKCS11 does not yet have TLS1.2 -- * mechanisms, and it will cause calls to come here. -- */ -- ps("KeyGenerator", "SunTlsPrf", -- "com.sun.crypto.provider.TlsPrfGenerator$V10"); -- ps("KeyGenerator", "SunTls12Prf", -- "com.sun.crypto.provider.TlsPrfGenerator$V12"); -- -- ps("KeyGenerator", "SunTlsMasterSecret", -- "com.sun.crypto.provider.TlsMasterSecretGenerator", -- List.of("SunTls12MasterSecret", "SunTlsExtendedMasterSecret"), -- null); -- -- ps("KeyGenerator", "SunTlsKeyMaterial", -- "com.sun.crypto.provider.TlsKeyMaterialGenerator", -- List.of("SunTls12KeyMaterial"), null); -- -- ps("KeyGenerator", "SunTlsRsaPremasterSecret", -- "com.sun.crypto.provider.TlsRsaPremasterSecretGenerator", -- List.of("SunTls12RsaPremasterSecret"), null); -+ if (!systemFipsEnabled) { -+ // PBKDF2 -+ psA("SecretKeyFactory", "PBKDF2WithHmacSHA1", -+ "com.sun.crypto.provider.PBKDF2Core$HmacSHA1", -+ null); -+ ps("SecretKeyFactory", "PBKDF2WithHmacSHA224", -+ "com.sun.crypto.provider.PBKDF2Core$HmacSHA224"); -+ ps("SecretKeyFactory", "PBKDF2WithHmacSHA256", -+ "com.sun.crypto.provider.PBKDF2Core$HmacSHA256"); -+ ps("SecretKeyFactory", "PBKDF2WithHmacSHA384", -+ "com.sun.crypto.provider.PBKDF2Core$HmacSHA384"); -+ ps("SecretKeyFactory", "PBKDF2WithHmacSHA512", -+ "com.sun.crypto.provider.PBKDF2Core$HmacSHA512"); -+ -+ /* -+ * MAC -+ */ -+ attrs.clear(); -+ attrs.put("SupportedKeyFormats", "RAW"); -+ ps("Mac", "HmacMD5", "com.sun.crypto.provider.HmacMD5", null, attrs); -+ psA("Mac", "HmacSHA1", "com.sun.crypto.provider.HmacSHA1", -+ attrs); -+ psA("Mac", "HmacSHA224", -+ "com.sun.crypto.provider.HmacCore$HmacSHA224", attrs); -+ psA("Mac", "HmacSHA256", -+ "com.sun.crypto.provider.HmacCore$HmacSHA256", attrs); -+ psA("Mac", "HmacSHA384", -+ "com.sun.crypto.provider.HmacCore$HmacSHA384", attrs); -+ psA("Mac", "HmacSHA512", -+ "com.sun.crypto.provider.HmacCore$HmacSHA512", attrs); -+ psA("Mac", "HmacSHA512/224", -+ "com.sun.crypto.provider.HmacCore$HmacSHA512_224", attrs); -+ psA("Mac", "HmacSHA512/256", -+ "com.sun.crypto.provider.HmacCore$HmacSHA512_256", attrs); -+ psA("Mac", "HmacSHA3-224", -+ "com.sun.crypto.provider.HmacCore$HmacSHA3_224", attrs); -+ psA("Mac", "HmacSHA3-256", -+ "com.sun.crypto.provider.HmacCore$HmacSHA3_256", attrs); -+ psA("Mac", "HmacSHA3-384", -+ "com.sun.crypto.provider.HmacCore$HmacSHA3_384", attrs); -+ psA("Mac", "HmacSHA3-512", -+ "com.sun.crypto.provider.HmacCore$HmacSHA3_512", attrs); -+ -+ ps("Mac", "HmacPBESHA1", -+ "com.sun.crypto.provider.HmacPKCS12PBECore$HmacPKCS12PBE_SHA1", -+ null, attrs); -+ ps("Mac", "HmacPBESHA224", -+ "com.sun.crypto.provider.HmacPKCS12PBECore$HmacPKCS12PBE_SHA224", -+ null, attrs); -+ ps("Mac", "HmacPBESHA256", -+ "com.sun.crypto.provider.HmacPKCS12PBECore$HmacPKCS12PBE_SHA256", -+ null, attrs); -+ ps("Mac", "HmacPBESHA384", -+ "com.sun.crypto.provider.HmacPKCS12PBECore$HmacPKCS12PBE_SHA384", -+ null, attrs); -+ ps("Mac", "HmacPBESHA512", -+ "com.sun.crypto.provider.HmacPKCS12PBECore$HmacPKCS12PBE_SHA512", -+ null, attrs); -+ ps("Mac", "HmacPBESHA512/224", -+ "com.sun.crypto.provider.HmacPKCS12PBECore$HmacPKCS12PBE_SHA512_224", -+ null, attrs); -+ ps("Mac", "HmacPBESHA512/256", -+ "com.sun.crypto.provider.HmacPKCS12PBECore$HmacPKCS12PBE_SHA512_256", -+ null, attrs); -+ -+ -+ // PBMAC1 -+ ps("Mac", "PBEWithHmacSHA1", -+ "com.sun.crypto.provider.PBMAC1Core$HmacSHA1", null, attrs); -+ ps("Mac", "PBEWithHmacSHA224", -+ "com.sun.crypto.provider.PBMAC1Core$HmacSHA224", null, attrs); -+ ps("Mac", "PBEWithHmacSHA256", -+ "com.sun.crypto.provider.PBMAC1Core$HmacSHA256", null, attrs); -+ ps("Mac", "PBEWithHmacSHA384", -+ "com.sun.crypto.provider.PBMAC1Core$HmacSHA384", null, attrs); -+ ps("Mac", "PBEWithHmacSHA512", -+ "com.sun.crypto.provider.PBMAC1Core$HmacSHA512", null, attrs); -+ ps("Mac", "SslMacMD5", -+ "com.sun.crypto.provider.SslMacCore$SslMacMD5", null, attrs); -+ ps("Mac", "SslMacSHA1", -+ "com.sun.crypto.provider.SslMacCore$SslMacSHA1", null, attrs); -+ -+ /* -+ * KeyStore -+ */ -+ ps("KeyStore", "JCEKS", -+ "com.sun.crypto.provider.JceKeyStore"); -+ -+ /* -+ * SSL/TLS mechanisms -+ * -+ * These are strictly internal implementations and may -+ * be changed at any time. These names were chosen -+ * because PKCS11/SunPKCS11 does not yet have TLS1.2 -+ * mechanisms, and it will cause calls to come here. -+ */ -+ ps("KeyGenerator", "SunTlsPrf", -+ "com.sun.crypto.provider.TlsPrfGenerator$V10"); -+ ps("KeyGenerator", "SunTls12Prf", -+ "com.sun.crypto.provider.TlsPrfGenerator$V12"); -+ -+ ps("KeyGenerator", "SunTlsMasterSecret", -+ "com.sun.crypto.provider.TlsMasterSecretGenerator", -+ List.of("SunTls12MasterSecret", "SunTlsExtendedMasterSecret"), -+ null); -+ -+ ps("KeyGenerator", "SunTlsKeyMaterial", -+ "com.sun.crypto.provider.TlsKeyMaterialGenerator", -+ List.of("SunTls12KeyMaterial"), null); -+ -+ ps("KeyGenerator", "SunTlsRsaPremasterSecret", -+ "com.sun.crypto.provider.TlsRsaPremasterSecretGenerator", -+ List.of("SunTls12RsaPremasterSecret"), null); -+ } - } - - // Return the instance of this class or create one if needed. -diff --git a/src/java.base/share/classes/java/security/Security.java b/src/java.base/share/classes/java/security/Security.java -index 2477027969c..06b1b6c671c 100644 ---- a/src/java.base/share/classes/java/security/Security.java -+++ b/src/java.base/share/classes/java/security/Security.java -@@ -33,6 +33,7 @@ import java.net.URL; - import jdk.internal.access.JavaSecurityPropertiesAccess; - import jdk.internal.event.EventHelper; - import jdk.internal.event.SecurityPropertyModificationEvent; -+import jdk.internal.access.JavaSecuritySystemConfiguratorAccess; - import jdk.internal.access.SharedSecrets; - import jdk.internal.util.StaticProperty; - import sun.security.util.Debug; -@@ -57,6 +58,11 @@ import sun.security.jca.*; - - public final class Security { - -+ private static final String SYS_PROP_SWITCH = -+ "java.security.disableSystemPropertiesFile"; -+ private static final String SEC_PROP_SWITCH = -+ "security.useSystemPropertiesFile"; -+ - /* Are we debugging? -- for developers */ - private static final Debug sdebug = - Debug.getInstance("properties"); -@@ -74,6 +80,19 @@ public final class Security { - } - - static { -+ // Initialise here as used by code with system properties disabled -+ SharedSecrets.setJavaSecuritySystemConfiguratorAccess( -+ new JavaSecuritySystemConfiguratorAccess() { -+ @Override -+ public boolean isSystemFipsEnabled() { -+ return SystemConfigurator.isSystemFipsEnabled(); -+ } -+ @Override -+ public boolean isPlainKeySupportEnabled() { -+ return SystemConfigurator.isPlainKeySupportEnabled(); -+ } -+ }); -+ - // doPrivileged here because there are multiple - // things in initialize that might require privs. - // (the FileInputStream call and the File.exists call, -@@ -97,6 +116,7 @@ public final class Security { - private static void initialize() { - props = new Properties(); - boolean overrideAll = false; -+ boolean systemSecPropsEnabled = false; - - // first load the system properties file - // to determine the value of security.overridePropertiesFile -@@ -117,6 +137,60 @@ public final class Security { - } - loadProps(null, extraPropFile, overrideAll); - } -+ -+ boolean sysUseProps = Boolean.valueOf(System.getProperty(SYS_PROP_SWITCH, "false")); -+ boolean secUseProps = Boolean.valueOf(props.getProperty(SEC_PROP_SWITCH)); -+ if (sdebug != null) { -+ sdebug.println(SYS_PROP_SWITCH + "=" + sysUseProps); -+ sdebug.println(SEC_PROP_SWITCH + "=" + secUseProps); -+ } -+ if (!sysUseProps && secUseProps) { -+ systemSecPropsEnabled = SystemConfigurator.configureSysProps(props); -+ if (!systemSecPropsEnabled) { -+ if (sdebug != null) { -+ sdebug.println("WARNING: System security properties could not be loaded."); -+ } -+ } -+ } else { -+ if (sdebug != null) { -+ sdebug.println("System security property support disabled by user."); -+ } -+ } -+ -+ if (systemSecPropsEnabled) { -+ boolean shouldEnable; -+ String sysProp = System.getProperty("com.redhat.fips"); -+ if (sysProp == null) { -+ shouldEnable = true; -+ if (sdebug != null) { -+ sdebug.println("com.redhat.fips unset, using default value of true"); -+ } -+ } else { -+ shouldEnable = Boolean.valueOf(sysProp); -+ if (sdebug != null) { -+ sdebug.println("com.redhat.fips set, using its value " + shouldEnable); -+ } -+ } -+ if (shouldEnable) { -+ boolean fipsEnabled = SystemConfigurator.configureFIPS(props); -+ if (sdebug != null) { -+ if (fipsEnabled) { -+ sdebug.println("FIPS mode support configured and enabled."); -+ } else { -+ sdebug.println("FIPS mode support disabled."); -+ } -+ } -+ } else { -+ if (sdebug != null ) { -+ sdebug.println("FIPS mode support disabled by user."); -+ } -+ } -+ } else { -+ if (sdebug != null) { -+ sdebug.println("WARNING: FIPS mode support can not be enabled without " + -+ "system security properties being enabled."); -+ } -+ } - initialSecurityProperties = (Properties) props.clone(); - if (sdebug != null) { - for (String key : props.stringPropertyNames()) { -@@ -124,10 +198,9 @@ public final class Security { - props.getProperty(key)); - } - } -- - } - -- private static boolean loadProps(File masterFile, String extraPropFile, boolean overrideAll) { -+ static boolean loadProps(File masterFile, String extraPropFile, boolean overrideAll) { - InputStream is = null; - try { - if (masterFile != null && masterFile.exists()) { -diff --git a/src/java.base/share/classes/java/security/SystemConfigurator.java b/src/java.base/share/classes/java/security/SystemConfigurator.java -new file mode 100644 -index 00000000000..9d26a54f5d4 ---- /dev/null -+++ b/src/java.base/share/classes/java/security/SystemConfigurator.java -@@ -0,0 +1,232 @@ -+/* -+ * Copyright (c) 2019, 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 java.security; -+ -+import java.io.BufferedInputStream; -+import java.io.FileInputStream; -+import java.io.IOException; -+ -+import java.util.Iterator; -+import java.util.Map.Entry; -+import java.util.Properties; -+ -+import sun.security.util.Debug; -+ -+/** -+ * Internal class to align OpenJDK with global crypto-policies. -+ * Called from java.security.Security class initialization, -+ * during startup. -+ * -+ */ -+ -+final class SystemConfigurator { -+ -+ private static final Debug sdebug = -+ Debug.getInstance("properties"); -+ -+ private static final String CRYPTO_POLICIES_BASE_DIR = -+ "/etc/crypto-policies"; -+ -+ private static final String CRYPTO_POLICIES_JAVA_CONFIG = -+ 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"; -+ -+ private static native boolean getSystemFIPSEnabled() -+ throws IOException; -+ -+ static { -+ @SuppressWarnings("removal") -+ var dummy = AccessController.doPrivileged(new PrivilegedAction() { -+ public Void run() { -+ System.loadLibrary(SYSTEMCONF_NATIVE_LIB); -+ return null; -+ } -+ }); -+ } -+ -+ /* -+ * Invoked when java.security.Security class is initialized, if -+ * java.security.disableSystemPropertiesFile property is not set and -+ * security.useSystemPropertiesFile is true. -+ */ -+ static boolean configureSysProps(Properties props) { -+ // now load the system file, if it exists, so its values -+ // will win if they conflict with the earlier values -+ return Security.loadProps(null, CRYPTO_POLICIES_JAVA_CONFIG, false); -+ } -+ -+ /* -+ * Invoked at the end of java.security.Security initialisation -+ * if java.security properties have been loaded -+ */ -+ static boolean configureFIPS(Properties props) { -+ boolean loadedProps = false; -+ -+ try { -+ if (enableFips()) { -+ if (sdebug != null) { sdebug.println("FIPS mode detected"); } -+ // Remove all security providers -+ Iterator> i = props.entrySet().iterator(); -+ while (i.hasNext()) { -+ Entry e = i.next(); -+ if (((String) e.getKey()).startsWith("security.provider")) { -+ if (sdebug != null) { sdebug.println("Removing provider: " + e); } -+ i.remove(); -+ } -+ } -+ // Add FIPS security providers -+ String fipsProviderValue = null; -+ for (int n = 1; -+ (fipsProviderValue = (String) props.get("fips.provider." + n)) != null; n++) { -+ String fipsProviderKey = "security.provider." + n; -+ if (sdebug != null) { -+ sdebug.println("Adding provider " + n + ": " + -+ fipsProviderKey + "=" + fipsProviderValue); -+ } -+ props.put(fipsProviderKey, fipsProviderValue); -+ } -+ // Add other security properties -+ String keystoreTypeValue = (String) props.get("fips.keystore.type"); -+ if (keystoreTypeValue != null) { -+ String nonFipsKeystoreType = props.getProperty("keystore.type"); -+ props.put("keystore.type", keystoreTypeValue); -+ if (keystoreTypeValue.equals("PKCS11")) { -+ // If keystore.type is PKCS11, javax.net.ssl.keyStore -+ // must be "NONE". See JDK-8238264. -+ System.setProperty("javax.net.ssl.keyStore", "NONE"); -+ } -+ if (System.getProperty("javax.net.ssl.trustStoreType") == null) { -+ // If no trustStoreType has been set, use the -+ // previous keystore.type under FIPS mode. In -+ // a default configuration, the Trust Store will -+ // be 'cacerts' (JKS type). -+ System.setProperty("javax.net.ssl.trustStoreType", -+ nonFipsKeystoreType); -+ } -+ if (sdebug != null) { -+ sdebug.println("FIPS mode default keystore.type = " + -+ keystoreTypeValue); -+ sdebug.println("FIPS mode javax.net.ssl.keyStore = " + -+ System.getProperty("javax.net.ssl.keyStore", "")); -+ sdebug.println("FIPS mode javax.net.ssl.trustStoreType = " + -+ System.getProperty("javax.net.ssl.trustStoreType", "")); -+ } -+ } -+ 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"); -+ } -+ } -+ } else { -+ if (sdebug != null) { sdebug.println("FIPS mode not detected"); } -+ } -+ } catch (Exception e) { -+ if (sdebug != null) { -+ sdebug.println("unable to load FIPS configuration"); -+ e.printStackTrace(); -+ } -+ } -+ return loadedProps; -+ } -+ -+ /** -+ * Returns whether or not global system FIPS alignment is enabled. -+ * -+ * Value is always 'false' before java.security.Security class is -+ * initialized. -+ * -+ * Call from out of this package through SharedSecrets: -+ * SharedSecrets.getJavaSecuritySystemConfiguratorAccess() -+ * .isSystemFipsEnabled(); -+ * -+ * @return a boolean value indicating whether or not global -+ * system FIPS alignment is enabled. -+ */ -+ static boolean isSystemFipsEnabled() { -+ 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; -+ } -+ -+ /** -+ * Determines whether FIPS mode should be enabled. -+ * -+ * OpenJDK FIPS mode will be enabled only if the system is in -+ * FIPS mode. -+ * -+ * Calls to this method only occur if the system property -+ * com.redhat.fips is not set to false. -+ * -+ * There are 2 possible ways in which OpenJDK detects that the system -+ * is in FIPS mode: 1) if the NSS SECMOD_GetSystemFIPSEnabled API is -+ * available at OpenJDK's built-time, it is called; 2) otherwise, the -+ * /proc/sys/crypto/fips_enabled file is read. -+ * -+ * @return true if the system is in FIPS mode -+ */ -+ private static boolean enableFips() throws Exception { -+ if (sdebug != null) { -+ sdebug.println("Calling getSystemFIPSEnabled (libsystemconf)..."); -+ } -+ try { -+ boolean fipsEnabled = getSystemFIPSEnabled(); -+ if (sdebug != null) { -+ sdebug.println("Call to getSystemFIPSEnabled (libsystemconf) returned: " -+ + fipsEnabled); -+ } -+ return fipsEnabled; -+ } catch (IOException e) { -+ if (sdebug != null) { -+ sdebug.println("Call to getSystemFIPSEnabled (libsystemconf) failed:"); -+ sdebug.println(e.getMessage()); -+ } -+ throw e; -+ } -+ } -+} -diff --git a/src/java.base/share/classes/jdk/internal/access/JavaSecuritySystemConfiguratorAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaSecuritySystemConfiguratorAccess.java -new file mode 100644 -index 00000000000..3f3caac64dc ---- /dev/null -+++ b/src/java.base/share/classes/jdk/internal/access/JavaSecuritySystemConfiguratorAccess.java -@@ -0,0 +1,31 @@ -+/* -+ * Copyright (c) 2020, 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 jdk.internal.access; -+ -+public interface JavaSecuritySystemConfiguratorAccess { -+ boolean isSystemFipsEnabled(); -+ boolean isPlainKeySupportEnabled(); -+} -diff --git a/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java b/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java -index ea28bb8747e..77161eb3844 100644 ---- a/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java -+++ b/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java -@@ -40,6 +40,7 @@ import java.io.FilePermission; - import java.io.ObjectInputStream; - import java.io.RandomAccessFile; - import java.security.ProtectionDomain; -+import java.security.Security; - import java.security.Signature; - - /** A repository of "shared secrets", which are a mechanism for -@@ -83,6 +84,7 @@ public class SharedSecrets { - private static JavaSecuritySpecAccess javaSecuritySpecAccess; - private static JavaxCryptoSealedObjectAccess javaxCryptoSealedObjectAccess; - private static JavaxCryptoSpecAccess javaxCryptoSpecAccess; -+ private static JavaSecuritySystemConfiguratorAccess javaSecuritySystemConfiguratorAccess; - - public static void setJavaUtilCollectionAccess(JavaUtilCollectionAccess juca) { - javaUtilCollectionAccess = juca; -@@ -457,4 +459,15 @@ public class SharedSecrets { - MethodHandles.lookup().ensureInitialized(c); - } catch (IllegalAccessException e) {} - } -+ -+ public static void setJavaSecuritySystemConfiguratorAccess(JavaSecuritySystemConfiguratorAccess jssca) { -+ javaSecuritySystemConfiguratorAccess = jssca; -+ } -+ -+ public static JavaSecuritySystemConfiguratorAccess getJavaSecuritySystemConfiguratorAccess() { -+ if (javaSecuritySystemConfiguratorAccess == null) { -+ ensureClassInitialized(Security.class); -+ } -+ return javaSecuritySystemConfiguratorAccess; -+ } - } -diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java -index fad70bdc058..29a813a485f 100644 ---- a/src/java.base/share/classes/module-info.java -+++ b/src/java.base/share/classes/module-info.java -@@ -152,6 +152,8 @@ module java.base { - java.naming, - java.rmi, - jdk.charsets, -+ jdk.crypto.cryptoki, -+ jdk.crypto.ec, - jdk.jartool, - jdk.jlink, - jdk.jfr, -diff --git a/src/java.base/share/classes/sun/security/provider/SunEntries.java b/src/java.base/share/classes/sun/security/provider/SunEntries.java -index 912cad59714..7803e97f7ef 100644 ---- a/src/java.base/share/classes/sun/security/provider/SunEntries.java -+++ b/src/java.base/share/classes/sun/security/provider/SunEntries.java -@@ -30,6 +30,7 @@ import java.net.*; - import java.util.*; - import java.security.*; - -+import jdk.internal.access.SharedSecrets; - import jdk.internal.util.StaticProperty; - import sun.security.action.GetPropertyAction; - import sun.security.util.SecurityProviderConstants; -@@ -83,6 +84,10 @@ import static sun.security.util.SecurityProviderConstants.getAliases; - - public final class SunEntries { - -+ private static final boolean systemFipsEnabled = -+ SharedSecrets.getJavaSecuritySystemConfiguratorAccess() -+ .isSystemFipsEnabled(); -+ - // the default algo used by SecureRandom class for new SecureRandom() calls - public static final String DEF_SECURE_RANDOM_ALGO; - -@@ -94,89 +99,92 @@ public final class SunEntries { - // common attribute map - HashMap attrs = new HashMap<>(3); - -- /* -- * SecureRandom engines -- */ -- attrs.put("ThreadSafe", "true"); -- if (NativePRNG.isAvailable()) { -- add(p, "SecureRandom", "NativePRNG", -- "sun.security.provider.NativePRNG", attrs); -- } -- if (NativePRNG.Blocking.isAvailable()) { -- add(p, "SecureRandom", "NativePRNGBlocking", -- "sun.security.provider.NativePRNG$Blocking", attrs); -- } -- if (NativePRNG.NonBlocking.isAvailable()) { -- add(p, "SecureRandom", "NativePRNGNonBlocking", -- "sun.security.provider.NativePRNG$NonBlocking", attrs); -- } -- attrs.put("ImplementedIn", "Software"); -- add(p, "SecureRandom", "DRBG", "sun.security.provider.DRBG", attrs); -- add(p, "SecureRandom", "SHA1PRNG", -- "sun.security.provider.SecureRandom", attrs); -- -- /* -- * Signature engines -- */ -- attrs.clear(); -- String dsaKeyClasses = "java.security.interfaces.DSAPublicKey" + -- "|java.security.interfaces.DSAPrivateKey"; -- attrs.put("SupportedKeyClasses", dsaKeyClasses); -- attrs.put("ImplementedIn", "Software"); -- -- attrs.put("KeySize", "1024"); // for NONE and SHA1 DSA signatures -- -- addWithAlias(p, "Signature", "SHA1withDSA", -- "sun.security.provider.DSA$SHA1withDSA", attrs); -- addWithAlias(p, "Signature", "NONEwithDSA", -- "sun.security.provider.DSA$RawDSA", attrs); -- -- // for DSA signatures with 224/256-bit digests -- attrs.put("KeySize", "2048"); -- -- addWithAlias(p, "Signature", "SHA224withDSA", -- "sun.security.provider.DSA$SHA224withDSA", attrs); -- addWithAlias(p, "Signature", "SHA256withDSA", -- "sun.security.provider.DSA$SHA256withDSA", attrs); -- -- addWithAlias(p, "Signature", "SHA3-224withDSA", -- "sun.security.provider.DSA$SHA3_224withDSA", attrs); -- addWithAlias(p, "Signature", "SHA3-256withDSA", -- "sun.security.provider.DSA$SHA3_256withDSA", attrs); -- -- attrs.put("KeySize", "3072"); // for DSA sig using 384/512-bit digests -- -- addWithAlias(p, "Signature", "SHA384withDSA", -- "sun.security.provider.DSA$SHA384withDSA", attrs); -- addWithAlias(p, "Signature", "SHA512withDSA", -- "sun.security.provider.DSA$SHA512withDSA", attrs); -- addWithAlias(p, "Signature", "SHA3-384withDSA", -- "sun.security.provider.DSA$SHA3_384withDSA", attrs); -- addWithAlias(p, "Signature", "SHA3-512withDSA", -- "sun.security.provider.DSA$SHA3_512withDSA", attrs); -+ if (!systemFipsEnabled) { -+ /* -+ * SecureRandom engines -+ */ -+ attrs.put("ThreadSafe", "true"); -+ if (NativePRNG.isAvailable()) { -+ add(p, "SecureRandom", "NativePRNG", -+ "sun.security.provider.NativePRNG", attrs); -+ } -+ if (NativePRNG.Blocking.isAvailable()) { -+ add(p, "SecureRandom", "NativePRNGBlocking", -+ "sun.security.provider.NativePRNG$Blocking", attrs); -+ } -+ if (NativePRNG.NonBlocking.isAvailable()) { -+ add(p, "SecureRandom", "NativePRNGNonBlocking", -+ "sun.security.provider.NativePRNG$NonBlocking", attrs); -+ } -+ attrs.put("ImplementedIn", "Software"); -+ add(p, "SecureRandom", "DRBG", "sun.security.provider.DRBG", attrs); -+ add(p, "SecureRandom", "SHA1PRNG", -+ "sun.security.provider.SecureRandom", attrs); - -- attrs.remove("KeySize"); -+ /* -+ * Signature engines -+ */ -+ attrs.clear(); -+ String dsaKeyClasses = "java.security.interfaces.DSAPublicKey" + -+ "|java.security.interfaces.DSAPrivateKey"; -+ attrs.put("SupportedKeyClasses", dsaKeyClasses); -+ attrs.put("ImplementedIn", "Software"); -+ -+ attrs.put("KeySize", "1024"); // for NONE and SHA1 DSA signatures -+ -+ addWithAlias(p, "Signature", "SHA1withDSA", -+ "sun.security.provider.DSA$SHA1withDSA", attrs); -+ addWithAlias(p, "Signature", "NONEwithDSA", -+ "sun.security.provider.DSA$RawDSA", attrs); -+ -+ // for DSA signatures with 224/256-bit digests -+ attrs.put("KeySize", "2048"); -+ -+ addWithAlias(p, "Signature", "SHA224withDSA", -+ "sun.security.provider.DSA$SHA224withDSA", attrs); -+ addWithAlias(p, "Signature", "SHA256withDSA", -+ "sun.security.provider.DSA$SHA256withDSA", attrs); -+ -+ addWithAlias(p, "Signature", "SHA3-224withDSA", -+ "sun.security.provider.DSA$SHA3_224withDSA", attrs); -+ addWithAlias(p, "Signature", "SHA3-256withDSA", -+ "sun.security.provider.DSA$SHA3_256withDSA", attrs); -+ -+ attrs.put("KeySize", "3072"); // for DSA sig using 384/512-bit digests -+ -+ addWithAlias(p, "Signature", "SHA384withDSA", -+ "sun.security.provider.DSA$SHA384withDSA", attrs); -+ addWithAlias(p, "Signature", "SHA512withDSA", -+ "sun.security.provider.DSA$SHA512withDSA", attrs); -+ addWithAlias(p, "Signature", "SHA3-384withDSA", -+ "sun.security.provider.DSA$SHA3_384withDSA", attrs); -+ addWithAlias(p, "Signature", "SHA3-512withDSA", -+ "sun.security.provider.DSA$SHA3_512withDSA", attrs); -+ -+ attrs.remove("KeySize"); -+ -+ add(p, "Signature", "SHA1withDSAinP1363Format", -+ "sun.security.provider.DSA$SHA1withDSAinP1363Format"); -+ add(p, "Signature", "NONEwithDSAinP1363Format", -+ "sun.security.provider.DSA$RawDSAinP1363Format"); -+ add(p, "Signature", "SHA224withDSAinP1363Format", -+ "sun.security.provider.DSA$SHA224withDSAinP1363Format"); -+ add(p, "Signature", "SHA256withDSAinP1363Format", -+ "sun.security.provider.DSA$SHA256withDSAinP1363Format"); -+ add(p, "Signature", "SHA384withDSAinP1363Format", -+ "sun.security.provider.DSA$SHA384withDSAinP1363Format"); -+ add(p, "Signature", "SHA512withDSAinP1363Format", -+ "sun.security.provider.DSA$SHA512withDSAinP1363Format"); -+ add(p, "Signature", "SHA3-224withDSAinP1363Format", -+ "sun.security.provider.DSA$SHA3_224withDSAinP1363Format"); -+ add(p, "Signature", "SHA3-256withDSAinP1363Format", -+ "sun.security.provider.DSA$SHA3_256withDSAinP1363Format"); -+ add(p, "Signature", "SHA3-384withDSAinP1363Format", -+ "sun.security.provider.DSA$SHA3_384withDSAinP1363Format"); -+ add(p, "Signature", "SHA3-512withDSAinP1363Format", -+ "sun.security.provider.DSA$SHA3_512withDSAinP1363Format"); -+ } - -- add(p, "Signature", "SHA1withDSAinP1363Format", -- "sun.security.provider.DSA$SHA1withDSAinP1363Format"); -- add(p, "Signature", "NONEwithDSAinP1363Format", -- "sun.security.provider.DSA$RawDSAinP1363Format"); -- add(p, "Signature", "SHA224withDSAinP1363Format", -- "sun.security.provider.DSA$SHA224withDSAinP1363Format"); -- add(p, "Signature", "SHA256withDSAinP1363Format", -- "sun.security.provider.DSA$SHA256withDSAinP1363Format"); -- add(p, "Signature", "SHA384withDSAinP1363Format", -- "sun.security.provider.DSA$SHA384withDSAinP1363Format"); -- add(p, "Signature", "SHA512withDSAinP1363Format", -- "sun.security.provider.DSA$SHA512withDSAinP1363Format"); -- add(p, "Signature", "SHA3-224withDSAinP1363Format", -- "sun.security.provider.DSA$SHA3_224withDSAinP1363Format"); -- add(p, "Signature", "SHA3-256withDSAinP1363Format", -- "sun.security.provider.DSA$SHA3_256withDSAinP1363Format"); -- add(p, "Signature", "SHA3-384withDSAinP1363Format", -- "sun.security.provider.DSA$SHA3_384withDSAinP1363Format"); -- add(p, "Signature", "SHA3-512withDSAinP1363Format", -- "sun.security.provider.DSA$SHA3_512withDSAinP1363Format"); - /* - * Key Pair Generator engines - */ -@@ -184,9 +192,11 @@ public final class SunEntries { - attrs.put("ImplementedIn", "Software"); - attrs.put("KeySize", "2048"); // for DSA KPG and APG only - -- String dsaKPGImplClass = "sun.security.provider.DSAKeyPairGenerator$"; -- dsaKPGImplClass += (useLegacyDSA? "Legacy" : "Current"); -- addWithAlias(p, "KeyPairGenerator", "DSA", dsaKPGImplClass, attrs); -+ if (!systemFipsEnabled) { -+ String dsaKPGImplClass = "sun.security.provider.DSAKeyPairGenerator$"; -+ dsaKPGImplClass += (useLegacyDSA? "Legacy" : "Current"); -+ addWithAlias(p, "KeyPairGenerator", "DSA", dsaKPGImplClass, attrs); -+ } - - /* - * Algorithm Parameter Generator engines -@@ -201,40 +211,42 @@ public final class SunEntries { - addWithAlias(p, "AlgorithmParameters", "DSA", - "sun.security.provider.DSAParameters", attrs); - -- /* -- * Key factories -- */ -- addWithAlias(p, "KeyFactory", "DSA", -- "sun.security.provider.DSAKeyFactory", attrs); -- -- /* -- * Digest engines -- */ -- add(p, "MessageDigest", "MD2", "sun.security.provider.MD2", attrs); -- add(p, "MessageDigest", "MD5", "sun.security.provider.MD5", attrs); -- addWithAlias(p, "MessageDigest", "SHA-1", "sun.security.provider.SHA", -- attrs); -+ if (!systemFipsEnabled) { -+ /* -+ * Key factories -+ */ -+ addWithAlias(p, "KeyFactory", "DSA", -+ "sun.security.provider.DSAKeyFactory", attrs); - -- addWithAlias(p, "MessageDigest", "SHA-224", -- "sun.security.provider.SHA2$SHA224", attrs); -- addWithAlias(p, "MessageDigest", "SHA-256", -- "sun.security.provider.SHA2$SHA256", attrs); -- addWithAlias(p, "MessageDigest", "SHA-384", -- "sun.security.provider.SHA5$SHA384", attrs); -- addWithAlias(p, "MessageDigest", "SHA-512", -- "sun.security.provider.SHA5$SHA512", attrs); -- addWithAlias(p, "MessageDigest", "SHA-512/224", -- "sun.security.provider.SHA5$SHA512_224", attrs); -- addWithAlias(p, "MessageDigest", "SHA-512/256", -- "sun.security.provider.SHA5$SHA512_256", attrs); -- addWithAlias(p, "MessageDigest", "SHA3-224", -- "sun.security.provider.SHA3$SHA224", attrs); -- addWithAlias(p, "MessageDigest", "SHA3-256", -- "sun.security.provider.SHA3$SHA256", attrs); -- addWithAlias(p, "MessageDigest", "SHA3-384", -- "sun.security.provider.SHA3$SHA384", attrs); -- addWithAlias(p, "MessageDigest", "SHA3-512", -- "sun.security.provider.SHA3$SHA512", attrs); -+ /* -+ * Digest engines -+ */ -+ add(p, "MessageDigest", "MD2", "sun.security.provider.MD2", attrs); -+ add(p, "MessageDigest", "MD5", "sun.security.provider.MD5", attrs); -+ addWithAlias(p, "MessageDigest", "SHA-1", "sun.security.provider.SHA", -+ attrs); -+ -+ addWithAlias(p, "MessageDigest", "SHA-224", -+ "sun.security.provider.SHA2$SHA224", attrs); -+ addWithAlias(p, "MessageDigest", "SHA-256", -+ "sun.security.provider.SHA2$SHA256", attrs); -+ addWithAlias(p, "MessageDigest", "SHA-384", -+ "sun.security.provider.SHA5$SHA384", attrs); -+ addWithAlias(p, "MessageDigest", "SHA-512", -+ "sun.security.provider.SHA5$SHA512", attrs); -+ addWithAlias(p, "MessageDigest", "SHA-512/224", -+ "sun.security.provider.SHA5$SHA512_224", attrs); -+ addWithAlias(p, "MessageDigest", "SHA-512/256", -+ "sun.security.provider.SHA5$SHA512_256", attrs); -+ addWithAlias(p, "MessageDigest", "SHA3-224", -+ "sun.security.provider.SHA3$SHA224", attrs); -+ addWithAlias(p, "MessageDigest", "SHA3-256", -+ "sun.security.provider.SHA3$SHA256", attrs); -+ addWithAlias(p, "MessageDigest", "SHA3-384", -+ "sun.security.provider.SHA3$SHA384", attrs); -+ addWithAlias(p, "MessageDigest", "SHA3-512", -+ "sun.security.provider.SHA3$SHA512", attrs); -+ } - - /* - * Certificates -diff --git a/src/java.base/share/classes/sun/security/rsa/SunRsaSignEntries.java b/src/java.base/share/classes/sun/security/rsa/SunRsaSignEntries.java -index ca79f25cc44..a12fcbbd6e7 100644 ---- a/src/java.base/share/classes/sun/security/rsa/SunRsaSignEntries.java -+++ b/src/java.base/share/classes/sun/security/rsa/SunRsaSignEntries.java -@@ -27,6 +27,7 @@ package sun.security.rsa; - - import java.util.*; - import java.security.Provider; -+import jdk.internal.access.SharedSecrets; - import static sun.security.util.SecurityProviderConstants.getAliases; - - /** -@@ -36,6 +37,10 @@ import static sun.security.util.SecurityProviderConstants.getAliases; - */ - public final class SunRsaSignEntries { - -+ private static final boolean systemFipsEnabled = -+ SharedSecrets.getJavaSecuritySystemConfiguratorAccess() -+ .isSystemFipsEnabled(); -+ - private void add(Provider p, String type, String algo, String cn, - List aliases, HashMap attrs) { - services.add(new Provider.Service(p, type, algo, cn, -@@ -63,42 +68,49 @@ public final class SunRsaSignEntries { - add(p, "KeyFactory", "RSA", - "sun.security.rsa.RSAKeyFactory$Legacy", - getAliases("PKCS1"), null); -- add(p, "KeyPairGenerator", "RSA", -- "sun.security.rsa.RSAKeyPairGenerator$Legacy", -- getAliases("PKCS1"), null); -- addA(p, "Signature", "MD2withRSA", -- "sun.security.rsa.RSASignature$MD2withRSA", attrs); -- addA(p, "Signature", "MD5withRSA", -- "sun.security.rsa.RSASignature$MD5withRSA", attrs); -- addA(p, "Signature", "SHA1withRSA", -- "sun.security.rsa.RSASignature$SHA1withRSA", attrs); -- addA(p, "Signature", "SHA224withRSA", -- "sun.security.rsa.RSASignature$SHA224withRSA", attrs); -- addA(p, "Signature", "SHA256withRSA", -- "sun.security.rsa.RSASignature$SHA256withRSA", attrs); -- addA(p, "Signature", "SHA384withRSA", -- "sun.security.rsa.RSASignature$SHA384withRSA", attrs); -- addA(p, "Signature", "SHA512withRSA", -- "sun.security.rsa.RSASignature$SHA512withRSA", attrs); -- addA(p, "Signature", "SHA512/224withRSA", -- "sun.security.rsa.RSASignature$SHA512_224withRSA", attrs); -- addA(p, "Signature", "SHA512/256withRSA", -- "sun.security.rsa.RSASignature$SHA512_256withRSA", attrs); -- addA(p, "Signature", "SHA3-224withRSA", -- "sun.security.rsa.RSASignature$SHA3_224withRSA", attrs); -- addA(p, "Signature", "SHA3-256withRSA", -- "sun.security.rsa.RSASignature$SHA3_256withRSA", attrs); -- addA(p, "Signature", "SHA3-384withRSA", -- "sun.security.rsa.RSASignature$SHA3_384withRSA", attrs); -- addA(p, "Signature", "SHA3-512withRSA", -- "sun.security.rsa.RSASignature$SHA3_512withRSA", attrs); -+ -+ if (!systemFipsEnabled) { -+ add(p, "KeyPairGenerator", "RSA", -+ "sun.security.rsa.RSAKeyPairGenerator$Legacy", -+ getAliases("PKCS1"), null); -+ addA(p, "Signature", "MD2withRSA", -+ "sun.security.rsa.RSASignature$MD2withRSA", attrs); -+ addA(p, "Signature", "MD5withRSA", -+ "sun.security.rsa.RSASignature$MD5withRSA", attrs); -+ addA(p, "Signature", "SHA1withRSA", -+ "sun.security.rsa.RSASignature$SHA1withRSA", attrs); -+ addA(p, "Signature", "SHA224withRSA", -+ "sun.security.rsa.RSASignature$SHA224withRSA", attrs); -+ addA(p, "Signature", "SHA256withRSA", -+ "sun.security.rsa.RSASignature$SHA256withRSA", attrs); -+ addA(p, "Signature", "SHA384withRSA", -+ "sun.security.rsa.RSASignature$SHA384withRSA", attrs); -+ addA(p, "Signature", "SHA512withRSA", -+ "sun.security.rsa.RSASignature$SHA512withRSA", attrs); -+ addA(p, "Signature", "SHA512/224withRSA", -+ "sun.security.rsa.RSASignature$SHA512_224withRSA", attrs); -+ addA(p, "Signature", "SHA512/256withRSA", -+ "sun.security.rsa.RSASignature$SHA512_256withRSA", attrs); -+ addA(p, "Signature", "SHA3-224withRSA", -+ "sun.security.rsa.RSASignature$SHA3_224withRSA", attrs); -+ addA(p, "Signature", "SHA3-256withRSA", -+ "sun.security.rsa.RSASignature$SHA3_256withRSA", attrs); -+ addA(p, "Signature", "SHA3-384withRSA", -+ "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, "KeyPairGenerator", "RSASSA-PSS", -- "sun.security.rsa.RSAKeyPairGenerator$PSS", attrs); -- addA(p, "Signature", "RSASSA-PSS", -- "sun.security.rsa.RSAPSSSignature", attrs); -+ -+ if (!systemFipsEnabled) { -+ addA(p, "KeyPairGenerator", "RSASSA-PSS", -+ "sun.security.rsa.RSAKeyPairGenerator$PSS", attrs); -+ addA(p, "Signature", "RSASSA-PSS", -+ "sun.security.rsa.RSAPSSSignature", attrs); -+ } -+ - addA(p, "AlgorithmParameters", "RSASSA-PSS", - "sun.security.rsa.PSSParameters", null); - } -diff --git a/src/java.base/share/classes/sun/security/util/PBEUtil.java b/src/java.base/share/classes/sun/security/util/PBEUtil.java -new file mode 100644 -index 00000000000..dc8bc72fccb ---- /dev/null -+++ b/src/java.base/share/classes/sun/security/util/PBEUtil.java -@@ -0,0 +1,297 @@ -+/* -+ * Copyright (c) 2022, 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.util; -+ -+import java.security.AlgorithmParameters; -+import java.security.InvalidAlgorithmParameterException; -+import java.security.InvalidKeyException; -+import java.security.Key; -+import java.security.NoSuchAlgorithmException; -+import java.security.Provider; -+import java.security.SecureRandom; -+import java.security.spec.AlgorithmParameterSpec; -+import java.security.spec.InvalidParameterSpecException; -+import java.util.Arrays; -+import javax.crypto.Cipher; -+import javax.crypto.SecretKey; -+import javax.crypto.spec.IvParameterSpec; -+import javax.crypto.spec.PBEKeySpec; -+import javax.crypto.spec.PBEParameterSpec; -+ -+public final class PBEUtil { -+ -+ // Used by SunJCE and SunPKCS11 -+ public final static class PBES2Helper { -+ private int iCount; -+ private byte[] salt; -+ private IvParameterSpec ivSpec; -+ private final int defaultSaltLength; -+ private final int defaultCount; -+ -+ public PBES2Helper(int defaultSaltLength, int defaultCount) { -+ this.defaultSaltLength = defaultSaltLength; -+ this.defaultCount = defaultCount; -+ } -+ -+ public IvParameterSpec getIvSpec() { -+ return ivSpec; -+ } -+ -+ public AlgorithmParameters getAlgorithmParameters( -+ int blkSize, String pbeAlgo, Provider p, SecureRandom random) { -+ AlgorithmParameters params = null; -+ if (salt == null) { -+ // generate random salt and use default iteration count -+ salt = new byte[defaultSaltLength]; -+ random.nextBytes(salt); -+ iCount = defaultCount; -+ } -+ if (ivSpec == null) { -+ // generate random IV -+ byte[] ivBytes = new byte[blkSize]; -+ random.nextBytes(ivBytes); -+ ivSpec = new IvParameterSpec(ivBytes); -+ } -+ PBEParameterSpec pbeSpec = new PBEParameterSpec( -+ salt, iCount, ivSpec); -+ try { -+ params = (p == null) ? -+ AlgorithmParameters.getInstance(pbeAlgo) : -+ AlgorithmParameters.getInstance(pbeAlgo, p); -+ params.init(pbeSpec); -+ } catch (NoSuchAlgorithmException nsae) { -+ // should never happen -+ throw new RuntimeException("AlgorithmParameters for " -+ + pbeAlgo + " not configured"); -+ } catch (InvalidParameterSpecException ipse) { -+ // should never happen -+ throw new RuntimeException("PBEParameterSpec not supported"); -+ } -+ return params; -+ } -+ -+ public PBEKeySpec getPBEKeySpec( -+ int blkSize, int keyLength, int opmode, Key key, -+ AlgorithmParameterSpec params, SecureRandom random) -+ throws InvalidKeyException, InvalidAlgorithmParameterException { -+ -+ if (key == null) { -+ throw new InvalidKeyException("Null key"); -+ } -+ -+ byte[] passwdBytes = key.getEncoded(); -+ char[] passwdChars = null; -+ PBEKeySpec pbeSpec; -+ try { -+ if ((passwdBytes == null) || !(key.getAlgorithm().regionMatches( -+ true, 0, "PBE", 0, 3))) { -+ throw new InvalidKeyException("Missing password"); -+ } -+ -+ // TBD: consolidate the salt, ic and IV parameter checks below -+ -+ // Extract salt and iteration count from the key, if present -+ if (key instanceof javax.crypto.interfaces.PBEKey) { -+ salt = ((javax.crypto.interfaces.PBEKey)key).getSalt(); -+ if (salt != null && salt.length < 8) { -+ throw new InvalidAlgorithmParameterException( -+ "Salt must be at least 8 bytes long"); -+ } -+ iCount = ((javax.crypto.interfaces.PBEKey)key) -+ .getIterationCount(); -+ if (iCount == 0) { -+ iCount = defaultCount; -+ } else if (iCount < 0) { -+ throw new InvalidAlgorithmParameterException( -+ "Iteration count must be a positive number"); -+ } -+ } -+ -+ // Extract salt, iteration count and IV from the params, -+ // if present -+ if (params == null) { -+ if (salt == null) { -+ // generate random salt and use default iteration count -+ salt = new byte[defaultSaltLength]; -+ random.nextBytes(salt); -+ iCount = defaultCount; -+ } -+ if ((opmode == Cipher.ENCRYPT_MODE) || -+ (opmode == Cipher.WRAP_MODE)) { -+ // generate random IV -+ byte[] ivBytes = new byte[blkSize]; -+ random.nextBytes(ivBytes); -+ ivSpec = new IvParameterSpec(ivBytes); -+ } -+ } else { -+ if (!(params instanceof PBEParameterSpec)) { -+ throw new InvalidAlgorithmParameterException -+ ("Wrong parameter type: PBE expected"); -+ } -+ // salt and iteration count from the params take precedence -+ byte[] specSalt = ((PBEParameterSpec) params).getSalt(); -+ if (specSalt != null && specSalt.length < 8) { -+ throw new InvalidAlgorithmParameterException( -+ "Salt must be at least 8 bytes long"); -+ } -+ salt = specSalt; -+ int specICount = ((PBEParameterSpec) params) -+ .getIterationCount(); -+ if (specICount == 0) { -+ specICount = defaultCount; -+ } else if (specICount < 0) { -+ throw new InvalidAlgorithmParameterException( -+ "Iteration count must be a positive number"); -+ } -+ iCount = specICount; -+ -+ AlgorithmParameterSpec specParams = -+ ((PBEParameterSpec) params).getParameterSpec(); -+ if (specParams != null) { -+ if (specParams instanceof IvParameterSpec) { -+ ivSpec = (IvParameterSpec)specParams; -+ } else { -+ throw new InvalidAlgorithmParameterException( -+ "Wrong parameter type: IV expected"); -+ } -+ } else if ((opmode == Cipher.ENCRYPT_MODE) || -+ (opmode == Cipher.WRAP_MODE)) { -+ // generate random IV -+ byte[] ivBytes = new byte[blkSize]; -+ random.nextBytes(ivBytes); -+ ivSpec = new IvParameterSpec(ivBytes); -+ } else { -+ throw new InvalidAlgorithmParameterException( -+ "Missing parameter type: IV expected"); -+ } -+ } -+ -+ passwdChars = new char[passwdBytes.length]; -+ for (int i = 0; i < passwdChars.length; i++) -+ passwdChars[i] = (char) (passwdBytes[i] & 0x7f); -+ -+ pbeSpec = new PBEKeySpec(passwdChars, salt, iCount, keyLength); -+ // password char[] was cloned in PBEKeySpec constructor, -+ // so we can zero it out here -+ } finally { -+ if (passwdChars != null) Arrays.fill(passwdChars, '\0'); -+ if (passwdBytes != null) Arrays.fill(passwdBytes, (byte)0x00); -+ } -+ return pbeSpec; -+ } -+ -+ public static AlgorithmParameterSpec getParameterSpec( -+ AlgorithmParameters params) -+ throws InvalidAlgorithmParameterException { -+ AlgorithmParameterSpec pbeSpec = null; -+ if (params != null) { -+ try { -+ pbeSpec = params.getParameterSpec(PBEParameterSpec.class); -+ } catch (InvalidParameterSpecException ipse) { -+ throw new InvalidAlgorithmParameterException( -+ "Wrong parameter type: PBE expected"); -+ } -+ } -+ return pbeSpec; -+ } -+ } -+ -+ // Used by SunJCE and SunPKCS11 -+ public static PBEKeySpec getPBAKeySpec(Key key, AlgorithmParameterSpec params) -+ throws InvalidKeyException, InvalidAlgorithmParameterException { -+ char[] passwdChars; -+ byte[] salt = null; -+ int iCount = 0; -+ if (key instanceof javax.crypto.interfaces.PBEKey) { -+ javax.crypto.interfaces.PBEKey pbeKey = -+ (javax.crypto.interfaces.PBEKey) key; -+ passwdChars = pbeKey.getPassword(); -+ salt = pbeKey.getSalt(); // maybe null if unspecified -+ iCount = pbeKey.getIterationCount(); // maybe 0 if unspecified -+ } else if (key instanceof SecretKey) { -+ byte[] passwdBytes; -+ if (!(key.getAlgorithm().regionMatches(true, 0, "PBE", 0, 3)) || -+ (passwdBytes = key.getEncoded()) == null) { -+ throw new InvalidKeyException("Missing password"); -+ } -+ passwdChars = new char[passwdBytes.length]; -+ for (int i=0; i -+# Value: clear text PIN value. -+# 2) env: -+# Value: environment variable containing the PIN value. -+# 3) file: -+# Value: path to a file containing the PIN value in its first -+# line. -+# -+# If the system property fips.nssdb.pin is also specified, it supersedes -+# the security property value defined here. -+# -+# When used as a system property, UTF-8 encoded values are valid. When -+# used as a security property (such as in this file), encode non-Basic -+# Latin Unicode characters with \uXXXX. -+# -+fips.nssdb.pin=pin: -+ - # - # Controls compatibility mode for JKS and PKCS12 keystore types. - # -@@ -329,6 +381,13 @@ package.definition=sun.misc.,\ - # - security.overridePropertiesFile=true - -+# -+# Determines whether this properties file will be appended to -+# using the system properties file stored at -+# /etc/crypto-policies/back-ends/java.config -+# -+security.useSystemPropertiesFile=false -+ - # - # Determines the default key and trust manager factory algorithms for - # the javax.net.ssl package. -diff --git a/src/java.base/share/conf/security/nss.fips.cfg.in b/src/java.base/share/conf/security/nss.fips.cfg.in -new file mode 100644 -index 00000000000..55bbba98b7a ---- /dev/null -+++ b/src/java.base/share/conf/security/nss.fips.cfg.in -@@ -0,0 +1,8 @@ -+name = NSS-FIPS -+nssLibraryDirectory = @NSS_LIBDIR@ -+nssSecmodDirectory = ${fips.nssdb.path} -+nssDbMode = readWrite -+nssModule = fips -+ -+attributes(*,CKO_SECRET_KEY,CKK_GENERIC_SECRET)={ CKA_SIGN=true } -+ -diff --git a/src/java.base/share/lib/security/default.policy b/src/java.base/share/lib/security/default.policy -index b22f26947af..02bea84e210 100644 ---- a/src/java.base/share/lib/security/default.policy -+++ b/src/java.base/share/lib/security/default.policy -@@ -121,6 +121,7 @@ grant codeBase "jrt:/jdk.charsets" { - grant codeBase "jrt:/jdk.crypto.ec" { - permission java.lang.RuntimePermission - "accessClassInPackage.sun.security.*"; -+ permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.access"; - permission java.lang.RuntimePermission "loadLibrary.sunec"; - permission java.security.SecurityPermission "putProviderProperty.SunEC"; - permission java.security.SecurityPermission "clearProviderProperties.SunEC"; -@@ -130,6 +131,7 @@ grant codeBase "jrt:/jdk.crypto.ec" { - grant codeBase "jrt:/jdk.crypto.cryptoki" { - permission java.lang.RuntimePermission - "accessClassInPackage.com.sun.crypto.provider"; -+ permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.access"; - permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc"; - permission java.lang.RuntimePermission - "accessClassInPackage.sun.security.*"; -@@ -140,6 +142,8 @@ grant codeBase "jrt:/jdk.crypto.cryptoki" { - permission java.util.PropertyPermission "os.name", "read"; - permission java.util.PropertyPermission "os.arch", "read"; - permission java.util.PropertyPermission "jdk.crypto.KeyAgreement.legacyKDF", "read"; -+ permission java.util.PropertyPermission "fips.nssdb.path", "read,write"; -+ permission java.util.PropertyPermission "fips.nssdb.pin", "read"; - permission java.security.SecurityPermission "putProviderProperty.*"; - permission java.security.SecurityPermission "clearProviderProperties.*"; - permission java.security.SecurityPermission "removeProviderProperty.*"; -diff --git a/src/java.base/share/native/libsystemconf/systemconf.c b/src/java.base/share/native/libsystemconf/systemconf.c -new file mode 100644 -index 00000000000..ddf9befe5bc ---- /dev/null -+++ b/src/java.base/share/native/libsystemconf/systemconf.c -@@ -0,0 +1,236 @@ -+/* -+ * 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. -+ */ -+ -+#include -+#include -+#include "jvm_md.h" -+#include -+ -+#ifdef LINUX -+ -+#ifdef SYSCONF_NSS -+#include -+#else -+#include -+#endif //SYSCONF_NSS -+ -+#include "java_security_SystemConfigurator.h" -+ -+#define MSG_MAX_SIZE 256 -+#define FIPS_ENABLED_PATH "/proc/sys/crypto/fips_enabled" -+ -+typedef int (SECMOD_GET_SYSTEM_FIPS_ENABLED_TYPE)(void); -+ -+static SECMOD_GET_SYSTEM_FIPS_ENABLED_TYPE *getSystemFIPSEnabled; -+static jmethodID debugPrintlnMethodID = NULL; -+static jobject debugObj = NULL; -+ -+static void dbgPrint(JNIEnv *env, const char* msg) -+{ -+ jstring jMsg; -+ if (debugObj != NULL) { -+ jMsg = (*env)->NewStringUTF(env, msg); -+ CHECK_NULL(jMsg); -+ (*env)->CallVoidMethod(env, debugObj, debugPrintlnMethodID, jMsg); -+ } -+} -+ -+static void throwIOException(JNIEnv *env, const char *msg) -+{ -+ jclass cls = (*env)->FindClass(env, "java/io/IOException"); -+ if (cls != 0) -+ (*env)->ThrowNew(env, cls, msg); -+} -+ -+static void handle_msg(JNIEnv *env, const char* msg, int msg_bytes) -+{ -+ if (msg_bytes > 0 && msg_bytes < MSG_MAX_SIZE) { -+ dbgPrint(env, msg); -+ } else { -+ dbgPrint(env, "systemconf: cannot render message"); -+ } -+} -+ -+// Only used when NSS is not linked at build time -+#ifndef SYSCONF_NSS -+ -+static void *nss_handle; -+ -+static jboolean loadNSS(JNIEnv *env) -+{ -+ char msg[MSG_MAX_SIZE]; -+ int msg_bytes; -+ const char* errmsg; -+ -+ nss_handle = dlopen(JNI_LIB_NAME("nss3"), RTLD_LAZY); -+ if (nss_handle == NULL) { -+ errmsg = dlerror(); -+ msg_bytes = snprintf(msg, MSG_MAX_SIZE, "loadNSS: dlopen: %s\n", -+ errmsg); -+ handle_msg(env, msg, msg_bytes); -+ return JNI_FALSE; -+ } -+ dlerror(); /* Clear errors */ -+ getSystemFIPSEnabled = (SECMOD_GET_SYSTEM_FIPS_ENABLED_TYPE*)dlsym(nss_handle, "SECMOD_GetSystemFIPSEnabled"); -+ if ((errmsg = dlerror()) != NULL) { -+ msg_bytes = snprintf(msg, MSG_MAX_SIZE, "loadNSS: dlsym: %s\n", -+ errmsg); -+ handle_msg(env, msg, msg_bytes); -+ return JNI_FALSE; -+ } -+ return JNI_TRUE; -+} -+ -+static void closeNSS(JNIEnv *env) -+{ -+ char msg[MSG_MAX_SIZE]; -+ int msg_bytes; -+ const char* errmsg; -+ -+ if (dlclose(nss_handle) != 0) { -+ errmsg = dlerror(); -+ msg_bytes = snprintf(msg, MSG_MAX_SIZE, "closeNSS: dlclose: %s\n", -+ errmsg); -+ handle_msg(env, msg, msg_bytes); -+ } -+} -+ -+#endif -+ -+/* -+ * Class: java_security_SystemConfigurator -+ * Method: JNI_OnLoad -+ */ -+JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved) -+{ -+ JNIEnv *env; -+ jclass sysConfCls, debugCls; -+ jfieldID sdebugFld; -+ -+ if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_2) != JNI_OK) { -+ return JNI_EVERSION; /* JNI version not supported */ -+ } -+ -+ sysConfCls = (*env)->FindClass(env,"java/security/SystemConfigurator"); -+ if (sysConfCls == NULL) { -+ printf("libsystemconf: SystemConfigurator class not found\n"); -+ return JNI_ERR; -+ } -+ sdebugFld = (*env)->GetStaticFieldID(env, sysConfCls, -+ "sdebug", "Lsun/security/util/Debug;"); -+ if (sdebugFld == NULL) { -+ printf("libsystemconf: SystemConfigurator::sdebug field not found\n"); -+ return JNI_ERR; -+ } -+ debugObj = (*env)->GetStaticObjectField(env, sysConfCls, sdebugFld); -+ if (debugObj != NULL) { -+ debugCls = (*env)->FindClass(env,"sun/security/util/Debug"); -+ if (debugCls == NULL) { -+ printf("libsystemconf: Debug class not found\n"); -+ return JNI_ERR; -+ } -+ debugPrintlnMethodID = (*env)->GetMethodID(env, debugCls, -+ "println", "(Ljava/lang/String;)V"); -+ if (debugPrintlnMethodID == NULL) { -+ printf("libsystemconf: Debug::println(String) method not found\n"); -+ return JNI_ERR; -+ } -+ debugObj = (*env)->NewGlobalRef(env, debugObj); -+ } -+ -+#ifdef SYSCONF_NSS -+ getSystemFIPSEnabled = *SECMOD_GetSystemFIPSEnabled; -+#else -+ if (loadNSS(env) == JNI_FALSE) { -+ dbgPrint(env, "libsystemconf: Failed to load NSS library."); -+ } -+#endif -+ -+ return (*env)->GetVersion(env); -+} -+ -+/* -+ * Class: java_security_SystemConfigurator -+ * Method: JNI_OnUnload -+ */ -+JNIEXPORT void JNICALL DEF_JNI_OnUnload(JavaVM *vm, void *reserved) -+{ -+ JNIEnv *env; -+ -+ if (debugObj != NULL) { -+ if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_2) != JNI_OK) { -+ return; /* Should not happen */ -+ } -+#ifndef SYSCONF_NSS -+ closeNSS(env); -+#endif -+ (*env)->DeleteGlobalRef(env, debugObj); -+ } -+} -+ -+JNIEXPORT jboolean JNICALL Java_java_security_SystemConfigurator_getSystemFIPSEnabled -+ (JNIEnv *env, jclass cls) -+{ -+ int fips_enabled; -+ char msg[MSG_MAX_SIZE]; -+ int msg_bytes; -+ -+ if (getSystemFIPSEnabled != NULL) { -+ dbgPrint(env, "getSystemFIPSEnabled: calling SECMOD_GetSystemFIPSEnabled"); -+ fips_enabled = (*getSystemFIPSEnabled)(); -+ msg_bytes = snprintf(msg, MSG_MAX_SIZE, "getSystemFIPSEnabled:" \ -+ " SECMOD_GetSystemFIPSEnabled returned 0x%x", fips_enabled); -+ handle_msg(env, msg, msg_bytes); -+ return (fips_enabled == 1 ? JNI_TRUE : JNI_FALSE); -+ } else { -+ FILE *fe; -+ -+ dbgPrint(env, "getSystemFIPSEnabled: reading " FIPS_ENABLED_PATH); -+ if ((fe = fopen(FIPS_ENABLED_PATH, "r")) == NULL) { -+ throwIOException(env, "Cannot open " FIPS_ENABLED_PATH); -+ return JNI_FALSE; -+ } -+ fips_enabled = fgetc(fe); -+ fclose(fe); -+ if (fips_enabled == EOF) { -+ throwIOException(env, "Cannot read " FIPS_ENABLED_PATH); -+ return JNI_FALSE; -+ } -+ msg_bytes = snprintf(msg, MSG_MAX_SIZE, "getSystemFIPSEnabled:" \ -+ " read character is '%c'", fips_enabled); -+ handle_msg(env, msg, msg_bytes); -+ return (fips_enabled == '1' ? JNI_TRUE : JNI_FALSE); -+ } -+} -+ -+#else // !LINUX -+ -+JNIEXPORT jboolean JNICALL Java_java_security_SystemConfigurator_getSystemFIPSEnabled -+ (JNIEnv *env, jclass cls) -+{ -+ return JNI_FALSE; -+} -+ -+#endif -diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/FIPSKeyImporter.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/FIPSKeyImporter.java -new file mode 100644 -index 00000000000..d3f0bffb821 ---- /dev/null -+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/FIPSKeyImporter.java -@@ -0,0 +1,457 @@ -+/* -+ * 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.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.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 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; -+ -+final class FIPSKeyImporter { -+ -+ private static final Debug debug = -+ Debug.getInstance("sunpkcs11"); -+ -+ private static volatile P11Key importerKey = null; -+ private static SecretKeySpec exporterKey = null; -+ private static volatile P11Key exporterKeyP11 = null; -+ private static final ReentrantLock importerKeyLock = new ReentrantLock(); -+ // 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 volatile Provider sunECProvider = null; -+ private static final ReentrantLock sunECProviderLock = 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, -+ " fips key importer"); -+ } -+ 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 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 (debug != null) { -+ debug.println("Unrecognized private key type."); -+ } -+ throw new PKCS11Exception(CKR_GENERAL_ERROR, -+ " fips key importer"); -+ } -+ } 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, -+ " fips key importer"); -+ } -+ attributes = new CK_ATTRIBUTE[attrsMap.size()]; -+ attrsMap.values().toArray(attributes); -+ 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, -+ importerKeyMechanism, importerKeyID, encKeyBytes, attributes); -+ if (debug != null) { -+ debug.println("Imported key ID: " + keyID); -+ } -+ } catch (Throwable t) { -+ 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 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 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 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..."); -+ } -+ 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"); -+ 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"); -+ } -+ } -+ } -+} -diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/FIPSTokenLoginHandler.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/FIPSTokenLoginHandler.java -new file mode 100644 -index 00000000000..f8d505ca815 ---- /dev/null -+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/FIPSTokenLoginHandler.java -@@ -0,0 +1,149 @@ -+/* -+ * Copyright (c) 2022, 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.io.BufferedReader; -+import java.io.ByteArrayInputStream; -+import java.io.InputStream; -+import java.io.InputStreamReader; -+import java.io.IOException; -+import java.nio.charset.StandardCharsets; -+import java.nio.file.Files; -+import java.nio.file.Path; -+import java.nio.file.Paths; -+import java.nio.file.StandardOpenOption; -+import java.security.ProviderException; -+ -+import javax.security.auth.callback.Callback; -+import javax.security.auth.callback.CallbackHandler; -+import javax.security.auth.callback.PasswordCallback; -+import javax.security.auth.callback.UnsupportedCallbackException; -+ -+import sun.security.util.Debug; -+import sun.security.util.SecurityProperties; -+ -+final class FIPSTokenLoginHandler implements CallbackHandler { -+ -+ private static final String FIPS_NSSDB_PIN_PROP = "fips.nssdb.pin"; -+ -+ private static final Debug debug = Debug.getInstance("sunpkcs11"); -+ -+ public void handle(Callback[] callbacks) -+ throws IOException, UnsupportedCallbackException { -+ if (!(callbacks[0] instanceof PasswordCallback)) { -+ throw new UnsupportedCallbackException(callbacks[0]); -+ } -+ PasswordCallback pc = (PasswordCallback)callbacks[0]; -+ pc.setPassword(getFipsNssdbPin()); -+ } -+ -+ private static char[] getFipsNssdbPin() throws ProviderException { -+ if (debug != null) { -+ debug.println("FIPS: Reading NSS DB PIN for token..."); -+ } -+ String pinProp = SecurityProperties -+ .privilegedGetOverridable(FIPS_NSSDB_PIN_PROP); -+ if (pinProp != null && !pinProp.isEmpty()) { -+ String[] pinPropParts = pinProp.split(":", 2); -+ if (pinPropParts.length < 2) { -+ throw new ProviderException("Invalid " + FIPS_NSSDB_PIN_PROP + -+ " property value."); -+ } -+ String prefix = pinPropParts[0].toLowerCase(); -+ String value = pinPropParts[1]; -+ String pin = null; -+ if (prefix.equals("env")) { -+ if (debug != null) { -+ debug.println("FIPS: PIN value from the '" + value + -+ "' environment variable."); -+ } -+ pin = System.getenv(value); -+ } else if (prefix.equals("file")) { -+ if (debug != null) { -+ debug.println("FIPS: PIN value from the '" + value + -+ "' file."); -+ } -+ pin = getPinFromFile(Paths.get(value)); -+ } else if (prefix.equals("pin")) { -+ if (debug != null) { -+ debug.println("FIPS: PIN value from the " + -+ FIPS_NSSDB_PIN_PROP + " property."); -+ } -+ pin = value; -+ } else { -+ throw new ProviderException("Unsupported prefix for " + -+ FIPS_NSSDB_PIN_PROP + "."); -+ } -+ if (pin != null && !pin.isEmpty()) { -+ if (debug != null) { -+ debug.println("FIPS: non-empty PIN."); -+ } -+ /* -+ * C_Login in libj2pkcs11 receives the PIN in a char[] and -+ * discards the upper byte of each char, before passing -+ * the value to the NSS Software Token. However, the -+ * NSS Software Token accepts any UTF-8 PIN value. Thus, -+ * expand the PIN here to account for later truncation. -+ */ -+ byte[] pinUtf8 = pin.getBytes(StandardCharsets.UTF_8); -+ char[] pinChar = new char[pinUtf8.length]; -+ for (int i = 0; i < pinChar.length; i++) { -+ pinChar[i] = (char)(pinUtf8[i] & 0xFF); -+ } -+ return pinChar; -+ } -+ } -+ if (debug != null) { -+ debug.println("FIPS: empty PIN."); -+ } -+ return null; -+ } -+ -+ /* -+ * This method extracts the token PIN from the first line of a password -+ * file in the same way as NSS modutil. See for example the -newpwfile -+ * argument used to change the password for an NSS DB. -+ */ -+ private static String getPinFromFile(Path f) throws ProviderException { -+ try (InputStream is = -+ Files.newInputStream(f, StandardOpenOption.READ)) { -+ /* -+ * SECU_FilePasswd in NSS (nss/cmd/lib/secutil.c), used by modutil, -+ * reads up to 4096 bytes. In addition, the NSS Software Token -+ * does not accept PINs longer than 500 bytes (see SFTK_MAX_PIN -+ * in nss/lib/softoken/pkcs11i.h). -+ */ -+ BufferedReader in = -+ new BufferedReader(new InputStreamReader( -+ new ByteArrayInputStream(is.readNBytes(4096)), -+ StandardCharsets.UTF_8)); -+ return in.readLine(); -+ } catch (IOException ioe) { -+ throw new ProviderException("Error reading " + FIPS_NSSDB_PIN_PROP + -+ " from the '" + f + "' file.", ioe); -+ } -+ } -+} -\ No newline at end of file -diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java -index 39bd783dd25..1146e7f9d80 100644 ---- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java -+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java -@@ -37,6 +37,8 @@ import javax.crypto.*; - 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; -@@ -69,6 +71,9 @@ import sun.security.jca.JCAUtil; - */ - 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"; -@@ -139,9 +144,7 @@ abstract class P11Key implements Key, Length { - this.tokenObject = tokenObject; - this.sensitive = sensitive; - this.extractable = extractable; -- char[] tokenLabel = this.token.tokenInfo.label; -- isNSS = (tokenLabel[0] == 'N' && tokenLabel[1] == 'S' -- && tokenLabel[2] == 'S'); -+ isNSS = P11Util.isNSS(this.token); - boolean extractKeyInfo = (!DISABLE_NATIVE_KEYS_EXTRACTION && isNSS && - extractable && !tokenObject); - this.keyIDHolder = new NativeKeyHolder(this, keyID, session, -@@ -395,8 +398,10 @@ abstract class P11Key implements Key, Length { - new CK_ATTRIBUTE(CKA_EXTRACTABLE), - }); - -- boolean keySensitive = (attrs[0].getBoolean() || -- attrs[1].getBoolean() || !attrs[2].getBoolean()); -+ boolean exportable = plainKeySupportEnabled && !algorithm.equals("DH"); -+ boolean keySensitive = (!exportable && -+ (attrs[0].getBoolean() || -+ attrs[1].getBoolean() || !attrs[2].getBoolean())); - - switch (algorithm) { - case "RSA": -@@ -451,7 +456,8 @@ abstract class P11Key implements Key, Length { - - public String getFormat() { - token.ensureValid(); -- if (sensitive || !extractable || (isNSS && tokenObject)) { -+ if (!plainKeySupportEnabled && -+ (sensitive || !extractable || (isNSS && tokenObject))) { - return null; - } else { - return "RAW"; -diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Mac.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Mac.java -index ba0b7faf3f8..4840a116b34 100644 ---- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Mac.java -+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Mac.java -@@ -29,14 +29,17 @@ import java.nio.ByteBuffer; - - import java.security.*; - import java.security.spec.AlgorithmParameterSpec; -+import java.security.spec.InvalidKeySpecException; - - import javax.crypto.MacSpi; -+import javax.crypto.spec.PBEKeySpec; - - import sun.nio.ch.DirectBuffer; - - import sun.security.pkcs11.wrapper.*; - import static sun.security.pkcs11.wrapper.PKCS11Constants.*; - import static sun.security.pkcs11.wrapper.PKCS11Exception.*; -+import sun.security.util.PBEUtil; - - /** - * MAC implementation class. This class currently supports HMAC using -@@ -202,12 +205,23 @@ final class P11Mac extends MacSpi { - // see JCE spec - protected void engineInit(Key key, AlgorithmParameterSpec params) - throws InvalidKeyException, InvalidAlgorithmParameterException { -- if (params != null) { -- throw new InvalidAlgorithmParameterException -- ("Parameters not supported"); -+ if (algorithm.startsWith("HmacPBE")) { -+ PBEKeySpec pbeSpec = PBEUtil.getPBAKeySpec(key, params); -+ reset(true); -+ try { -+ p11Key = P11SecretKeyFactory.derivePBEKey( -+ token, pbeSpec, algorithm); -+ } catch (InvalidKeySpecException e) { -+ throw new InvalidKeyException(e); -+ } -+ } else { -+ if (params != null) { -+ throw new InvalidAlgorithmParameterException -+ ("Parameters not supported"); -+ } -+ reset(true); -+ p11Key = P11SecretKeyFactory.convertKey(token, key, algorithm); - } -- reset(true); -- p11Key = P11SecretKeyFactory.convertKey(token, key, algorithm); - try { - initialize(); - } catch (PKCS11Exception e) { -diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11PBECipher.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11PBECipher.java -new file mode 100644 -index 00000000000..ae4262703e6 ---- /dev/null -+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11PBECipher.java -@@ -0,0 +1,200 @@ -+/* -+ * Copyright (c) 2022, 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.security.AlgorithmParameters; -+import java.security.Key; -+import java.security.InvalidAlgorithmParameterException; -+import java.security.InvalidKeyException; -+import java.security.NoSuchAlgorithmException; -+import java.security.SecureRandom; -+import java.security.spec.AlgorithmParameterSpec; -+import java.security.spec.InvalidKeySpecException; -+import javax.crypto.BadPaddingException; -+import javax.crypto.CipherSpi; -+import javax.crypto.IllegalBlockSizeException; -+import javax.crypto.NoSuchPaddingException; -+import javax.crypto.ShortBufferException; -+import javax.crypto.spec.PBEKeySpec; -+ -+import static sun.security.pkcs11.wrapper.PKCS11Constants.*; -+import sun.security.jca.JCAUtil; -+import sun.security.pkcs11.wrapper.PKCS11Exception; -+import sun.security.util.PBEUtil; -+ -+final class P11PBECipher extends CipherSpi { -+ -+ private static final int DEFAULT_SALT_LENGTH = 20; -+ private static final int DEFAULT_COUNT = 4096; -+ -+ private final Token token; -+ private final String pbeAlg; -+ private final P11Cipher cipher; -+ private final int blkSize; -+ private final int keyLen; -+ private final PBEUtil.PBES2Helper pbes2Helper = new PBEUtil.PBES2Helper( -+ DEFAULT_SALT_LENGTH, DEFAULT_COUNT); -+ -+ P11PBECipher(Token token, String pbeAlg, long cipherMech) -+ throws PKCS11Exception, NoSuchAlgorithmException { -+ super(); -+ String cipherTrans; -+ if (cipherMech == CKM_AES_CBC_PAD || cipherMech == CKM_AES_CBC) { -+ cipherTrans = "AES/CBC/PKCS5Padding"; -+ } else { -+ throw new NoSuchAlgorithmException( -+ "Cipher transformation not supported."); -+ } -+ cipher = new P11Cipher(token, cipherTrans, cipherMech); -+ blkSize = cipher.engineGetBlockSize(); -+ assert P11Util.kdfDataMap.get(pbeAlg) != null; -+ keyLen = P11Util.kdfDataMap.get(pbeAlg).keyLen; -+ this.pbeAlg = pbeAlg; -+ this.token = token; -+ } -+ -+ // see JCE spec -+ @Override -+ protected void engineSetMode(String mode) -+ throws NoSuchAlgorithmException { -+ cipher.engineSetMode(mode); -+ } -+ -+ // see JCE spec -+ @Override -+ protected void engineSetPadding(String padding) -+ throws NoSuchPaddingException { -+ cipher.engineSetPadding(padding); -+ } -+ -+ // see JCE spec -+ @Override -+ protected int engineGetBlockSize() { -+ return cipher.engineGetBlockSize(); -+ } -+ -+ // see JCE spec -+ @Override -+ protected int engineGetOutputSize(int inputLen) { -+ return cipher.engineGetOutputSize(inputLen); -+ } -+ -+ // see JCE spec -+ @Override -+ protected byte[] engineGetIV() { -+ return cipher.engineGetIV(); -+ } -+ -+ // see JCE spec -+ @Override -+ protected AlgorithmParameters engineGetParameters() { -+ return pbes2Helper.getAlgorithmParameters( -+ blkSize, pbeAlg, null, JCAUtil.getSecureRandom()); -+ } -+ -+ // see JCE spec -+ @Override -+ protected void engineInit(int opmode, Key key, -+ SecureRandom random) throws InvalidKeyException { -+ try { -+ engineInit(opmode, key, (AlgorithmParameterSpec) null, random); -+ } catch (InvalidAlgorithmParameterException e) { -+ throw new InvalidKeyException("requires PBE parameters", e); -+ } -+ } -+ -+ // see JCE spec -+ @Override -+ protected void engineInit(int opmode, Key key, -+ AlgorithmParameterSpec params, SecureRandom random) -+ throws InvalidKeyException, -+ InvalidAlgorithmParameterException { -+ -+ PBEKeySpec pbeSpec = pbes2Helper.getPBEKeySpec(blkSize, keyLen, -+ opmode, key, params, random); -+ -+ Key derivedKey; -+ try { -+ derivedKey = P11SecretKeyFactory.derivePBEKey( -+ token, pbeSpec, pbeAlg); -+ } catch (InvalidKeySpecException e) { -+ throw new InvalidKeyException(e); -+ } -+ cipher.engineInit(opmode, derivedKey, pbes2Helper.getIvSpec(), random); -+ } -+ -+ // see JCE spec -+ @Override -+ protected void engineInit(int opmode, Key key, -+ AlgorithmParameters params, SecureRandom random) -+ throws InvalidKeyException, -+ InvalidAlgorithmParameterException { -+ engineInit(opmode, key, PBEUtil.PBES2Helper.getParameterSpec(params), -+ random); -+ } -+ -+ // see JCE spec -+ @Override -+ protected byte[] engineUpdate(byte[] input, int inputOffset, -+ int inputLen) { -+ return cipher.engineUpdate(input, inputOffset, inputLen); -+ } -+ -+ // see JCE spec -+ @Override -+ protected int engineUpdate(byte[] input, int inputOffset, -+ int inputLen, byte[] output, int outputOffset) -+ throws ShortBufferException { -+ return cipher.engineUpdate(input, inputOffset, inputLen, -+ output, outputOffset); -+ } -+ -+ // see JCE spec -+ @Override -+ protected byte[] engineDoFinal(byte[] input, int inputOffset, -+ int inputLen) -+ throws IllegalBlockSizeException, BadPaddingException { -+ return cipher.engineDoFinal(input, inputOffset, inputLen); -+ } -+ -+ // see JCE spec -+ @Override -+ protected int engineDoFinal(byte[] input, int inputOffset, -+ int inputLen, byte[] output, int outputOffset) -+ throws ShortBufferException, IllegalBlockSizeException, -+ BadPaddingException { -+ return cipher.engineDoFinal(input, inputOffset, inputLen, output, -+ outputOffset); -+ } -+ -+ // see JCE spec -+ @Override -+ protected int engineGetKeySize(Key key) -+ throws InvalidKeyException { -+ return cipher.engineGetKeySize(key); -+ } -+ -+} -diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11SecretKeyFactory.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11SecretKeyFactory.java -index 8d1b8ccb0ae..7ea9b4c5e7f 100644 ---- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11SecretKeyFactory.java -+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11SecretKeyFactory.java -@@ -31,6 +31,7 @@ import java.security.*; - import java.security.spec.*; - - import javax.crypto.*; -+import javax.crypto.interfaces.PBEKey; - import javax.crypto.spec.*; - - import static sun.security.pkcs11.TemplateManager.*; -@@ -194,6 +195,130 @@ final class P11SecretKeyFactory extends SecretKeyFactorySpi { - return p11Key; - } - -+ static P11Key derivePBEKey(Token token, PBEKeySpec keySpec, String algo) -+ throws InvalidKeySpecException { -+ token.ensureValid(); -+ if (keySpec == null) { -+ throw new InvalidKeySpecException("PBEKeySpec must not be null"); -+ } -+ Session session = null; -+ try { -+ session = token.getObjSession(); -+ P11Util.KDFData kdfData = P11Util.kdfDataMap.get(algo); -+ CK_MECHANISM ckMech; -+ char[] password = keySpec.getPassword(); -+ byte[] salt = keySpec.getSalt(); -+ int itCount = keySpec.getIterationCount(); -+ int keySize = keySpec.getKeyLength(); -+ if (kdfData.keyLen != -1) { -+ if (keySize == 0) { -+ keySize = kdfData.keyLen; -+ } else if (keySize != kdfData.keyLen) { -+ throw new InvalidKeySpecException( -+ "Key length is invalid for " + algo); -+ } -+ } -+ -+ if (kdfData.kdfMech == CKM_PKCS5_PBKD2) { -+ CK_INFO p11Info = token.p11.getInfo(); -+ CK_VERSION p11Ver = (p11Info != null ? p11Info.cryptokiVersion -+ : null); -+ if (P11Util.isNSS(token) || p11Ver != null && (p11Ver.major < -+ 2 || p11Ver.major == 2 && p11Ver.minor < 40)) { -+ // NSS keeps using the old structure beyond PKCS #11 v2.40 -+ ckMech = new CK_MECHANISM(kdfData.kdfMech, -+ new CK_PKCS5_PBKD2_PARAMS(password, salt, -+ itCount, kdfData.prfMech)); -+ } else { -+ ckMech = new CK_MECHANISM(kdfData.kdfMech, -+ new CK_PKCS5_PBKD2_PARAMS2(password, salt, -+ itCount, kdfData.prfMech)); -+ } -+ } else { -+ // PKCS #12 "General Method" PBKD (RFC 7292, Appendix B.2) -+ if (P11Util.isNSS(token)) { -+ // According to PKCS #11, "password" in CK_PBE_PARAMS has -+ // a CK_UTF8CHAR_PTR type. This suggests that it is encoded -+ // in UTF-8. However, NSS expects the password to be encoded -+ // as BMPString with a NULL terminator when C_GenerateKey -+ // is called for a PKCS #12 "General Method" derivation -+ // (see RFC 7292, Appendix B.1). -+ // -+ // The char size in Java is 2 bytes. When a char is -+ // converted to a CK_UTF8CHAR, the high-order byte is -+ // discarded (see jCharArrayToCKUTF8CharArray in -+ // p11_util.c). In order to have a BMPString passed to -+ // C_GenerateKey, we need to account for that and expand: -+ // the high and low parts of each char are split into 2 -+ // chars. As an example, this is the transformation for -+ // a NULL terminated password "a": -+ // char[] => [ 0x0061, 0x0000 ] -+ // / \ / \ -+ // Expansion => [0x0000, 0x0061, 0x0000, 0x0000] -+ // | | | | -+ // BMPString => [ 0x00, 0x61, 0x00, 0x00] -+ // -+ int inputLength = (password == null) ? 0 : password.length; -+ char[] expPassword = new char[inputLength * 2 + 2]; -+ for (int i = 0, j = 0; i < inputLength; i++, j += 2) { -+ expPassword[j] = (char) ((password[i] >>> 8) & 0xFF); -+ expPassword[j + 1] = (char) (password[i] & 0xFF); -+ } -+ password = expPassword; -+ } -+ ckMech = new CK_MECHANISM(kdfData.kdfMech, -+ new CK_PBE_PARAMS(password, salt, itCount)); -+ } -+ -+ long keyType = getKeyType(kdfData.keyAlgo); -+ CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[ -+ switch (kdfData.op) { -+ case ENCRYPTION, AUTHENTICATION -> 4; -+ case GENERIC -> 5; -+ }]; -+ attrs[0] = new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY); -+ attrs[1] = new CK_ATTRIBUTE(CKA_VALUE_LEN, keySize >> 3); -+ attrs[2] = new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType); -+ switch (kdfData.op) { -+ case ENCRYPTION -> attrs[3] = CK_ATTRIBUTE.ENCRYPT_TRUE; -+ case AUTHENTICATION -> attrs[3] = CK_ATTRIBUTE.SIGN_TRUE; -+ case GENERIC -> { -+ attrs[3] = CK_ATTRIBUTE.ENCRYPT_TRUE; -+ attrs[4] = CK_ATTRIBUTE.SIGN_TRUE; -+ } -+ } -+ CK_ATTRIBUTE[] attr = token.getAttributes( -+ O_GENERATE, CKO_SECRET_KEY, keyType, attrs); -+ long keyID = token.p11.C_GenerateKey(session.id(), ckMech, attr); -+ return (P11Key)P11Key.secretKey( -+ session, keyID, kdfData.keyAlgo, keySize, attr); -+ } catch (PKCS11Exception e) { -+ throw new InvalidKeySpecException("Could not create key", e); -+ } finally { -+ token.releaseSession(session); -+ } -+ } -+ -+ static P11Key derivePBEKey(Token token, PBEKey key, String algo) -+ throws InvalidKeyException { -+ token.ensureValid(); -+ if (key == null) { -+ throw new InvalidKeyException("PBEKey must not be null"); -+ } -+ P11Key p11Key = token.secretCache.get(key); -+ if (p11Key != null) { -+ return p11Key; -+ } -+ try { -+ p11Key = derivePBEKey(token, new PBEKeySpec(key.getPassword(), -+ key.getSalt(), key.getIterationCount()), algo); -+ } catch (InvalidKeySpecException e) { -+ throw new InvalidKeyException(e); -+ } -+ token.secretCache.put(key, p11Key); -+ return p11Key; -+ } -+ - static void fixDESParity(byte[] key, int offset) { - for (int i = 0; i < 8; i++) { - int b = key[offset] & 0xfe; -@@ -320,6 +445,9 @@ final class P11SecretKeyFactory extends SecretKeyFactorySpi { - keySpec = new SecretKeySpec(keyBytes, "DESede"); - return engineGenerateSecret(keySpec); - } -+ } else if (keySpec instanceof PBEKeySpec) { -+ return (SecretKey)derivePBEKey(token, -+ (PBEKeySpec)keySpec, algorithm); - } - throw new InvalidKeySpecException - ("Unsupported spec: " + keySpec.getClass().getName()); -@@ -373,6 +501,9 @@ final class P11SecretKeyFactory extends SecretKeyFactorySpi { - // see JCE spec - protected SecretKey engineTranslateKey(SecretKey key) - throws InvalidKeyException { -+ if (key instanceof PBEKey) { -+ return (SecretKey)derivePBEKey(token, (PBEKey)key, algorithm); -+ } - return (SecretKey)convertKey(token, key, algorithm); - } - -diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Util.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Util.java -index 262cfc062ad..72b64f72c0a 100644 ---- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Util.java -+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Util.java -@@ -27,6 +27,10 @@ package sun.security.pkcs11; - - import java.math.BigInteger; - import java.security.*; -+import java.util.HashMap; -+import java.util.Map; -+ -+import static sun.security.pkcs11.wrapper.PKCS11Constants.*; - - /** - * Collection of static utility methods. -@@ -40,10 +44,106 @@ public final class P11Util { - - private static volatile Provider sun, sunRsaSign, sunJce; - -+ // Used by PBE -+ static final class KDFData { -+ public enum Operation {ENCRYPTION, AUTHENTICATION, GENERIC} -+ public long kdfMech; -+ public long prfMech; -+ public String keyAlgo; -+ public int keyLen; -+ public Operation op; -+ KDFData(long kdfMech, long prfMech, String keyAlgo, -+ int keyLen, Operation op) { -+ this.kdfMech = kdfMech; -+ this.prfMech = prfMech; -+ this.keyAlgo = keyAlgo; -+ this.keyLen = keyLen; -+ this.op = op; -+ } -+ -+ public static void addPbkdf2Data(String algo, long kdfMech, -+ long prfMech) { -+ kdfDataMap.put(algo, new KDFData(kdfMech, prfMech, -+ "Generic", -1, Operation.GENERIC)); -+ } -+ -+ public static void addPbkdf2AesData(String algo, long kdfMech, -+ long prfMech, int keyLen) { -+ kdfDataMap.put(algo, new KDFData(kdfMech, prfMech, -+ "AES", keyLen, Operation.ENCRYPTION)); -+ } -+ -+ public static void addPkcs12KDData(String algo, long kdfMech, -+ int keyLen) { -+ kdfDataMap.put(algo, new KDFData(kdfMech, -1, -+ "Generic", keyLen, Operation.AUTHENTICATION)); -+ } -+ } -+ -+ static final Map kdfDataMap = new HashMap<>(); -+ -+ static { -+ KDFData.addPbkdf2AesData("PBEWithHmacSHA1AndAES_128", -+ CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA1, 128); -+ KDFData.addPbkdf2AesData("PBEWithHmacSHA224AndAES_128", -+ CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA224, 128); -+ KDFData.addPbkdf2AesData("PBEWithHmacSHA256AndAES_128", -+ CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA256, 128); -+ KDFData.addPbkdf2AesData("PBEWithHmacSHA384AndAES_128", -+ CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA384, 128); -+ KDFData.addPbkdf2AesData("PBEWithHmacSHA512AndAES_128", -+ CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA512, 128); -+ KDFData.addPbkdf2AesData("PBEWithHmacSHA1AndAES_256", -+ CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA1, 256); -+ KDFData.addPbkdf2AesData("PBEWithHmacSHA224AndAES_256", -+ CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA224, 256); -+ KDFData.addPbkdf2AesData("PBEWithHmacSHA256AndAES_256", -+ CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA256, 256); -+ KDFData.addPbkdf2AesData("PBEWithHmacSHA384AndAES_256", -+ CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA384, 256); -+ KDFData.addPbkdf2AesData("PBEWithHmacSHA512AndAES_256", -+ CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA512, 256); -+ -+ KDFData.addPbkdf2Data("PBKDF2WithHmacSHA1", -+ CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA1); -+ KDFData.addPbkdf2Data("PBKDF2WithHmacSHA224", -+ CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA224); -+ KDFData.addPbkdf2Data("PBKDF2WithHmacSHA256", -+ CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA256); -+ KDFData.addPbkdf2Data("PBKDF2WithHmacSHA384", -+ CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA384); -+ KDFData.addPbkdf2Data("PBKDF2WithHmacSHA512", -+ CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA512); -+ -+ KDFData.addPkcs12KDData("HmacPBESHA1", -+ CKM_PBA_SHA1_WITH_SHA1_HMAC, 160); -+ KDFData.addPkcs12KDData("HmacPBESHA224", -+ CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN, 224); -+ KDFData.addPkcs12KDData("HmacPBESHA256", -+ CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN, 256); -+ KDFData.addPkcs12KDData("HmacPBESHA384", -+ CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN, 384); -+ KDFData.addPkcs12KDData("HmacPBESHA512", -+ CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN, 512); -+ KDFData.addPkcs12KDData("HmacPBESHA512/224", -+ CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN, 512); -+ KDFData.addPkcs12KDData("HmacPBESHA512/256", -+ CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN, 512); -+ } -+ - private P11Util() { - // empty - } - -+ static boolean isNSS(Token token) { -+ char[] tokenLabel = token.tokenInfo.label; -+ if (tokenLabel != null && tokenLabel.length >= 3) { -+ return (tokenLabel[0] == 'N' && tokenLabel[1] == 'S' -+ && tokenLabel[2] == 'S'); -+ } -+ return false; -+ } -+ - static Provider getSunProvider() { - Provider p = sun; - if (p == null) { -diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java -index aa35e8fa668..1855e5631bd 100644 ---- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java -+++ b/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.*; -@@ -42,10 +45,12 @@ import javax.security.auth.callback.PasswordCallback; - - import com.sun.crypto.provider.ChaCha20Poly1305Parameters; - -+import jdk.internal.access.SharedSecrets; - import jdk.internal.misc.InnocuousThread; - import sun.security.util.Debug; - import sun.security.util.ResourcesMgr; - import static sun.security.util.SecurityConstants.PROVIDER_VER; -+import sun.security.util.SecurityProperties; - import static sun.security.util.SecurityProviderConstants.getAliases; - - import sun.security.pkcs11.Secmod.*; -@@ -62,6 +67,39 @@ import static sun.security.pkcs11.wrapper.PKCS11Exception.*; - */ - 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; -+ private static final MethodHandle fipsExportKey; -+ static { -+ MethodHandle fipsImportKeyTmp = null; -+ MethodHandle fipsExportKeyTmp = null; -+ if (plainKeySupportEnabled) { -+ try { -+ fipsImportKeyTmp = MethodHandles.lookup().findStatic( -+ FIPSKeyImporter.class, "importKey", -+ MethodType.methodType(Long.class, SunPKCS11.class, -+ long.class, CK_ATTRIBUTE[].class)); -+ fipsExportKeyTmp = MethodHandles.lookup().findStatic( -+ FIPSKeyImporter.class, "exportKey", -+ MethodType.methodType(void.class, SunPKCS11.class, -+ long.class, long.class, -+ long.class, long.class, Map.class)); -+ } catch (Throwable t) { -+ throw new SecurityException("FIPS key importer-exporter" + -+ " initialization failed", t); -+ } -+ } -+ fipsImportKey = fipsImportKeyTmp; -+ fipsExportKey = fipsExportKeyTmp; -+ } -+ -+ private static final String FIPS_NSSDB_PATH_PROP = "fips.nssdb.path"; -+ - private static final long serialVersionUID = -1354835039035306505L; - - static final Debug debug = Debug.getInstance("sunpkcs11"); -@@ -115,6 +153,29 @@ public final class SunPKCS11 extends AuthProvider { - return AccessController.doPrivileged(new PrivilegedExceptionAction<>() { - @Override - public SunPKCS11 run() throws Exception { -+ if (systemFipsEnabled) { -+ /* -+ * The nssSecmodDirectory attribute in the SunPKCS11 -+ * NSS configuration file takes the value of the -+ * fips.nssdb.path System property after expansion. -+ * Security properties expansion is unsupported. -+ */ -+ String nssdbPath = -+ SecurityProperties.privilegedGetOverridable( -+ FIPS_NSSDB_PATH_PROP); -+ if (System.getSecurityManager() != null) { -+ AccessController.doPrivileged( -+ (PrivilegedAction) () -> { -+ System.setProperty( -+ FIPS_NSSDB_PATH_PROP, -+ nssdbPath); -+ return null; -+ }); -+ } else { -+ System.setProperty( -+ FIPS_NSSDB_PATH_PROP, nssdbPath); -+ } -+ } - return new SunPKCS11(new Config(newConfigName)); - } - }); -@@ -320,10 +381,19 @@ public final class SunPKCS11 extends AuthProvider { - // request multithreaded access first - initArgs.flags = CKF_OS_LOCKING_OK; - PKCS11 tmpPKCS11; -+ MethodHandle fipsKeyImporter = null; -+ MethodHandle fipsKeyExporter = null; -+ if (plainKeySupportEnabled) { -+ fipsKeyImporter = MethodHandles.insertArguments( -+ fipsImportKey, 0, this); -+ fipsKeyExporter = MethodHandles.insertArguments( -+ fipsExportKey, 0, this); -+ } - try { - tmpPKCS11 = PKCS11.getInstance( - library, functionList, initArgs, -- config.getOmitInitialize()); -+ config.getOmitInitialize(), fipsKeyImporter, -+ fipsKeyExporter); - } catch (PKCS11Exception e) { - if (debug != null) { - debug.println("Multi-threaded initialization failed: " + e); -@@ -339,11 +409,12 @@ public final class SunPKCS11 extends AuthProvider { - initArgs.flags = 0; - } - tmpPKCS11 = PKCS11.getInstance(library, -- functionList, initArgs, config.getOmitInitialize()); -+ functionList, initArgs, config.getOmitInitialize(), fipsKeyImporter, -+ fipsKeyExporter); - } - p11 = tmpPKCS11; - -- CK_INFO p11Info = p11.C_GetInfo(); -+ CK_INFO p11Info = p11.getInfo(); - if (p11Info.cryptokiVersion.major < 2) { - throw new ProviderException("Only PKCS#11 v2.0 and later " - + "supported, library version is v" + p11Info.cryptokiVersion); -@@ -417,14 +488,19 @@ public final class SunPKCS11 extends AuthProvider { - final String className; - final List aliases; - final int[] mechanisms; -+ final int[] requiredMechs; - -+ // mechanisms is a list of possible mechanisms that implement the -+ // algorithm, at least one of them must be available. requiredMechs -+ // is a list of auxiliary mechanisms, all of them must be available - private Descriptor(String type, String algorithm, String className, -- List aliases, int[] mechanisms) { -+ List aliases, int[] mechanisms, int[] requiredMechs) { - this.type = type; - this.algorithm = algorithm; - this.className = className; - this.aliases = aliases; - this.mechanisms = mechanisms; -+ this.requiredMechs = requiredMechs; - } - private P11Service service(Token token, int mechanism) { - return new P11Service -@@ -458,18 +534,29 @@ public final class SunPKCS11 extends AuthProvider { - - private static void d(String type, String algorithm, String className, - int[] m) { -- register(new Descriptor(type, algorithm, className, null, m)); -+ register(new Descriptor(type, algorithm, className, null, m, null)); - } - - private static void d(String type, String algorithm, String className, - List aliases, int[] m) { -- register(new Descriptor(type, algorithm, className, aliases, m)); -+ register(new Descriptor(type, algorithm, className, aliases, m, null)); -+ } -+ -+ private static void d(String type, String algorithm, String className, -+ int[] m, int[] requiredMechs) { -+ register(new Descriptor(type, algorithm, className, null, m, -+ requiredMechs)); -+ } -+ private static void dA(String type, String algorithm, String className, -+ int[] m, int[] requiredMechs) { -+ register(new Descriptor(type, algorithm, className, -+ getAliases(algorithm), m, requiredMechs)); - } - - private static void dA(String type, String algorithm, String className, - int[] m) { - register(new Descriptor(type, algorithm, className, -- getAliases(algorithm), m)); -+ getAliases(algorithm), m, null)); - } - - private static void register(Descriptor d) { -@@ -525,6 +612,7 @@ public final class SunPKCS11 extends AuthProvider { - String P11Cipher = "sun.security.pkcs11.P11Cipher"; - String P11RSACipher = "sun.security.pkcs11.P11RSACipher"; - String P11AEADCipher = "sun.security.pkcs11.P11AEADCipher"; -+ String P11PBECipher = "sun.security.pkcs11.P11PBECipher"; - String P11Signature = "sun.security.pkcs11.P11Signature"; - String P11PSSSignature = "sun.security.pkcs11.P11PSSSignature"; - -@@ -587,6 +675,30 @@ public final class SunPKCS11 extends AuthProvider { - d(MAC, "SslMacSHA1", P11Mac, - m(CKM_SSL3_SHA1_MAC)); - -+ if (systemFipsEnabled) { -+ /* -+ * PBA HMacs -+ * -+ * KeyDerivationMech must be supported -+ * for these services to be available. -+ * -+ */ -+ d(MAC, "HmacPBESHA1", P11Mac, m(CKM_SHA_1_HMAC), -+ m(CKM_PBA_SHA1_WITH_SHA1_HMAC)); -+ d(MAC, "HmacPBESHA224", P11Mac, m(CKM_SHA224_HMAC), -+ m(CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN)); -+ d(MAC, "HmacPBESHA256", P11Mac, m(CKM_SHA256_HMAC), -+ m(CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN)); -+ d(MAC, "HmacPBESHA384", P11Mac, m(CKM_SHA384_HMAC), -+ m(CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN)); -+ d(MAC, "HmacPBESHA512", P11Mac, m(CKM_SHA512_HMAC), -+ m(CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN)); -+ d(MAC, "HmacPBESHA512/224", P11Mac, m(CKM_SHA512_224_HMAC), -+ m(CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN)); -+ d(MAC, "HmacPBESHA512/256", P11Mac, m(CKM_SHA512_256_HMAC), -+ m(CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN)); -+ } -+ - d(KPG, "RSA", P11KeyPairGenerator, - getAliases("PKCS1"), - m(CKM_RSA_PKCS_KEY_PAIR_GEN)); -@@ -685,6 +797,66 @@ public final class SunPKCS11 extends AuthProvider { - d(SKF, "ChaCha20", P11SecretKeyFactory, - m(CKM_CHACHA20_POLY1305)); - -+ if (systemFipsEnabled) { -+ /* -+ * PBE Secret Key Factories -+ * -+ * KeyDerivationPrf must be supported for these services -+ * to be available. -+ * -+ */ -+ d(SKF, "PBEWithHmacSHA1AndAES_128", -+ P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA_1_HMAC)); -+ d(SKF, "PBEWithHmacSHA224AndAES_128", -+ P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA224_HMAC)); -+ d(SKF, "PBEWithHmacSHA256AndAES_128", -+ P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA256_HMAC)); -+ d(SKF, "PBEWithHmacSHA384AndAES_128", -+ P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA384_HMAC)); -+ d(SKF, "PBEWithHmacSHA512AndAES_128", -+ P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA512_HMAC)); -+ d(SKF, "PBEWithHmacSHA1AndAES_256", -+ P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA_1_HMAC)); -+ d(SKF, "PBEWithHmacSHA224AndAES_256", -+ P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA224_HMAC)); -+ d(SKF, "PBEWithHmacSHA256AndAES_256", -+ P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA256_HMAC)); -+ d(SKF, "PBEWithHmacSHA384AndAES_256", -+ P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA384_HMAC)); -+ d(SKF, "PBEWithHmacSHA512AndAES_256", -+ P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA512_HMAC)); -+ /* -+ * PBA Secret Key Factories -+ */ -+ d(SKF, "HmacPBESHA1", P11SecretKeyFactory, -+ m(CKM_PBA_SHA1_WITH_SHA1_HMAC)); -+ d(SKF, "HmacPBESHA224", P11SecretKeyFactory, -+ m(CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN)); -+ d(SKF, "HmacPBESHA256", P11SecretKeyFactory, -+ m(CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN)); -+ d(SKF, "HmacPBESHA384", P11SecretKeyFactory, -+ m(CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN)); -+ d(SKF, "HmacPBESHA512", P11SecretKeyFactory, -+ m(CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN)); -+ d(SKF, "HmacPBESHA512/224", P11SecretKeyFactory, -+ m(CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN)); -+ d(SKF, "HmacPBESHA512/256", P11SecretKeyFactory, -+ m(CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN)); -+ /* -+ * PBKDF2 Secret Key Factories -+ */ -+ dA(SKF, "PBKDF2WithHmacSHA1", P11SecretKeyFactory, -+ m(CKM_PKCS5_PBKD2), m(CKM_SHA_1_HMAC)); -+ d(SKF, "PBKDF2WithHmacSHA224", P11SecretKeyFactory, -+ m(CKM_PKCS5_PBKD2), m(CKM_SHA224_HMAC)); -+ d(SKF, "PBKDF2WithHmacSHA256", P11SecretKeyFactory, -+ m(CKM_PKCS5_PBKD2), m(CKM_SHA256_HMAC)); -+ d(SKF, "PBKDF2WithHmacSHA384", P11SecretKeyFactory, -+ m(CKM_PKCS5_PBKD2), m(CKM_SHA384_HMAC)); -+ d(SKF, "PBKDF2WithHmacSHA512", P11SecretKeyFactory, -+ m(CKM_PKCS5_PBKD2), m(CKM_SHA512_HMAC)); -+ } -+ - // XXX attributes for Ciphers (supported modes, padding) - dA(CIP, "ARCFOUR", P11Cipher, - m(CKM_RC4)); -@@ -754,6 +926,46 @@ public final class SunPKCS11 extends AuthProvider { - d(CIP, "RSA/ECB/NoPadding", P11RSACipher, - m(CKM_RSA_X_509)); - -+ if (systemFipsEnabled) { -+ /* -+ * PBE Ciphers -+ * -+ * KeyDerivationMech and KeyDerivationPrf must be supported -+ * for these services to be available. -+ * -+ */ -+ d(CIP, "PBEWithHmacSHA1AndAES_128", P11PBECipher, -+ m(CKM_AES_CBC_PAD, CKM_AES_CBC), -+ m(CKM_PKCS5_PBKD2, CKM_SHA_1_HMAC)); -+ d(CIP, "PBEWithHmacSHA224AndAES_128", P11PBECipher, -+ m(CKM_AES_CBC_PAD, CKM_AES_CBC), -+ m(CKM_PKCS5_PBKD2, CKM_SHA224_HMAC)); -+ d(CIP, "PBEWithHmacSHA256AndAES_128", P11PBECipher, -+ m(CKM_AES_CBC_PAD, CKM_AES_CBC), -+ m(CKM_PKCS5_PBKD2, CKM_SHA256_HMAC)); -+ d(CIP, "PBEWithHmacSHA384AndAES_128", P11PBECipher, -+ m(CKM_AES_CBC_PAD, CKM_AES_CBC), -+ m(CKM_PKCS5_PBKD2, CKM_SHA384_HMAC)); -+ d(CIP, "PBEWithHmacSHA512AndAES_128", P11PBECipher, -+ m(CKM_AES_CBC_PAD, CKM_AES_CBC), -+ m(CKM_PKCS5_PBKD2, CKM_SHA512_HMAC)); -+ d(CIP, "PBEWithHmacSHA1AndAES_256", P11PBECipher, -+ m(CKM_AES_CBC_PAD, CKM_AES_CBC), -+ m(CKM_PKCS5_PBKD2, CKM_SHA_1_HMAC)); -+ d(CIP, "PBEWithHmacSHA224AndAES_256", P11PBECipher, -+ m(CKM_AES_CBC_PAD, CKM_AES_CBC), -+ m(CKM_PKCS5_PBKD2, CKM_SHA224_HMAC)); -+ d(CIP, "PBEWithHmacSHA256AndAES_256", P11PBECipher, -+ m(CKM_AES_CBC_PAD, CKM_AES_CBC), -+ m(CKM_PKCS5_PBKD2, CKM_SHA256_HMAC)); -+ d(CIP, "PBEWithHmacSHA384AndAES_256", P11PBECipher, -+ m(CKM_AES_CBC_PAD, CKM_AES_CBC), -+ m(CKM_PKCS5_PBKD2, CKM_SHA384_HMAC)); -+ d(CIP, "PBEWithHmacSHA512AndAES_256", P11PBECipher, -+ m(CKM_AES_CBC_PAD, CKM_AES_CBC), -+ m(CKM_PKCS5_PBKD2, CKM_SHA512_HMAC)); -+ } -+ - d(SIG, "RawDSA", P11Signature, - List.of("NONEwithDSA"), - m(CKM_DSA)); -@@ -1144,9 +1356,21 @@ public final class SunPKCS11 extends AuthProvider { - if (ds == null) { - continue; - } -+ descLoop: - for (Descriptor d : ds) { - Integer oldMech = supportedAlgs.get(d); - if (oldMech == null) { -+ if (d.requiredMechs != null) { -+ // Check that other mechanisms required for the -+ // service are supported before listing it as -+ // available for the first time. -+ for (int requiredMech : d.requiredMechs) { -+ if (token.getMechanismInfo( -+ requiredMech & 0xFFFFFFFFL) == null) { -+ continue descLoop; -+ } -+ } -+ } - supportedAlgs.put(d, integerMech); - continue; - } -@@ -1220,11 +1444,52 @@ public final class SunPKCS11 extends AuthProvider { - } - - @Override -+ @SuppressWarnings("removal") - public Object newInstance(Object param) - throws NoSuchAlgorithmException { - if (token.isValid() == false) { - throw new NoSuchAlgorithmException("Token has been removed"); - } -+ if (systemFipsEnabled && !token.fipsLoggedIn && -+ !getType().equals("KeyStore")) { -+ /* -+ * The NSS Software Token in FIPS 140-2 mode requires a -+ * user login for most operations. See sftk_fipsCheck -+ * (nss/lib/softoken/fipstokn.c). In case of a KeyStore -+ * service, let the caller perform the login with -+ * KeyStore::load. Keytool, for example, does this to pass a -+ * PIN from either the -srcstorepass or -deststorepass -+ * argument. In case of a non-KeyStore service, perform the -+ * login now with the PIN available in the fips.nssdb.pin -+ * property. -+ */ -+ try { -+ if (System.getSecurityManager() != null) { -+ try { -+ AccessController.doPrivileged( -+ (PrivilegedExceptionAction) () -> { -+ token.ensureLoggedIn(null); -+ return null; -+ }); -+ } catch (PrivilegedActionException pae) { -+ Exception e = pae.getException(); -+ if (e instanceof LoginException le) { -+ throw le; -+ } else if (e instanceof PKCS11Exception p11e) { -+ throw p11e; -+ } else { -+ throw new RuntimeException(e); -+ } -+ } -+ } else { -+ token.ensureLoggedIn(null); -+ } -+ } catch (PKCS11Exception | LoginException e) { -+ throw new ProviderException("FIPS: error during the Token" + -+ " login required for the " + getType() + -+ " service.", e); -+ } -+ } - try { - return newInstance0(param); - } catch (PKCS11Exception e) { -@@ -1244,6 +1509,8 @@ public final class SunPKCS11 extends AuthProvider { - } else if (algorithm.endsWith("GCM/NoPadding") || - algorithm.startsWith("ChaCha20-Poly1305")) { - return new P11AEADCipher(token, algorithm, mechanism); -+ } else if (algorithm.startsWith("PBE")) { -+ return new P11PBECipher(token, algorithm, mechanism); - } else { - return new P11Cipher(token, algorithm, mechanism); - } -@@ -1579,6 +1846,9 @@ public final class SunPKCS11 extends AuthProvider { - try { - session = token.getOpSession(); - p11.C_Logout(session.id()); -+ if (systemFipsEnabled) { -+ token.fipsLoggedIn = false; -+ } - if (debug != null) { - debug.println("logout succeeded"); - } -diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Token.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Token.java -index 1f94fe3e18a..99eec2114e4 100644 ---- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Token.java -+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Token.java -@@ -33,6 +33,7 @@ import java.lang.ref.*; - import java.security.*; - import javax.security.auth.login.LoginException; - -+import jdk.internal.access.SharedSecrets; - import sun.security.jca.JCAUtil; - - import sun.security.pkcs11.wrapper.*; -@@ -48,6 +49,9 @@ import static sun.security.pkcs11.wrapper.PKCS11Exception.*; - */ - class Token implements Serializable { - -+ private static final boolean systemFipsEnabled = SharedSecrets -+ .getJavaSecuritySystemConfiguratorAccess().isSystemFipsEnabled(); -+ - // need to be serializable to allow SecureRandom to be serialized - private static final long serialVersionUID = 2541527649100571747L; - -@@ -114,6 +118,10 @@ class Token implements Serializable { - // flag indicating whether we are logged in - private volatile boolean loggedIn; - -+ // Flag indicating the login status for the NSS Software Token in FIPS mode. -+ // This Token is never asynchronously removed. Used from SunPKCS11. -+ volatile boolean fipsLoggedIn; -+ - // time we last checked login status - private long lastLoginCheck; - -@@ -232,7 +240,12 @@ class Token implements Serializable { - // call provider.login() if not - void ensureLoggedIn(Session session) throws PKCS11Exception, LoginException { - if (isLoggedIn(session) == false) { -- provider.login(null, null); -+ if (systemFipsEnabled) { -+ provider.login(null, new FIPSTokenLoginHandler()); -+ fipsLoggedIn = true; -+ } else { -+ provider.login(null, null); -+ } - } - } - -diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_ECDH1_DERIVE_PARAMS.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_ECDH1_DERIVE_PARAMS.java -index 88ff8a71fc3..47a2f97eddf 100644 ---- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_ECDH1_DERIVE_PARAMS.java -+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_ECDH1_DERIVE_PARAMS.java -@@ -100,9 +100,9 @@ public class CK_ECDH1_DERIVE_PARAMS { - } - - /** -- * Returns the string representation of CK_PKCS5_PBKD2_PARAMS. -+ * Returns the string representation of CK_ECDH1_DERIVE_PARAMS. - * -- * @return the string representation of CK_PKCS5_PBKD2_PARAMS -+ * @return the string representation of CK_ECDH1_DERIVE_PARAMS - */ - public String toString() { - StringBuilder sb = new StringBuilder(); -diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM.java -index 0c9ebb289c1..b4b2448464d 100644 ---- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM.java -+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM.java -@@ -160,6 +160,18 @@ public class CK_MECHANISM { - init(mechanism, params); - } - -+ public CK_MECHANISM(long mechanism, CK_PBE_PARAMS params) { -+ init(mechanism, params); -+ } -+ -+ public CK_MECHANISM(long mechanism, CK_PKCS5_PBKD2_PARAMS params) { -+ init(mechanism, params); -+ } -+ -+ public CK_MECHANISM(long mechanism, CK_PKCS5_PBKD2_PARAMS2 params) { -+ init(mechanism, params); -+ } -+ - // For PSS. the parameter may be set multiple times, use the - // CK_MECHANISM(long) constructor and setParameter(CK_RSA_PKCS_PSS_PARAMS) - // methods instead of creating yet another constructor -diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PBE_PARAMS.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PBE_PARAMS.java -index e8b048869c4..a25fa1c39e5 100644 ---- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PBE_PARAMS.java -+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PBE_PARAMS.java -@@ -50,15 +50,15 @@ package sun.security.pkcs11.wrapper; - - - /** -- * class CK_PBE_PARAMS provides all of the necessary information required byte -+ * class CK_PBE_PARAMS provides all the necessary information required by - * the CKM_PBE mechanisms and the CKM_PBA_SHA1_WITH_SHA1_HMAC mechanism.

- * PKCS#11 structure: - *

-  * typedef struct CK_PBE_PARAMS {
-- *   CK_CHAR_PTR pInitVector;
-- *   CK_CHAR_PTR pPassword;
-+ *   CK_BYTE_PTR pInitVector;
-+ *   CK_UTF8CHAR_PTR pPassword;
-  *   CK_ULONG ulPasswordLen;
-- *   CK_CHAR_PTR pSalt;
-+ *   CK_BYTE_PTR pSalt;
-  *   CK_ULONG ulSaltLen;
-  *   CK_ULONG ulIteration;
-  * } CK_PBE_PARAMS;
-@@ -72,15 +72,15 @@ public class CK_PBE_PARAMS {
-     /**
-      * PKCS#11:
-      * 
--     *   CK_CHAR_PTR pInitVector;
-+     *   CK_BYTE_PTR pInitVector;
-      * 
- */ -- public char[] pInitVector; -+ public byte[] pInitVector; - - /** - * PKCS#11: - *
--     *   CK_CHAR_PTR pPassword;
-+     *   CK_UTF8CHAR_PTR pPassword;
-      *   CK_ULONG ulPasswordLen;
-      * 
- */ -@@ -89,11 +89,11 @@ public class CK_PBE_PARAMS { - /** - * PKCS#11: - *
--     *   CK_CHAR_PTR pSalt
-+     *   CK_BYTE_PTR pSalt
-      *   CK_ULONG ulSaltLen;
-      * 
- */ -- public char[] pSalt; -+ public byte[] pSalt; - - /** - * PKCS#11: -@@ -103,6 +103,12 @@ public class CK_PBE_PARAMS { - */ - public long ulIteration; - -+ public CK_PBE_PARAMS(char[] pPassword, byte[] pSalt, long ulIteration) { -+ this.pPassword = pPassword; -+ this.pSalt = pSalt; -+ this.ulIteration = ulIteration; -+ } -+ - /** - * Returns the string representation of CK_PBE_PARAMS. - * -diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS.java -index fb90bfced27..a01beb0753a 100644 ---- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS.java -+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS.java -@@ -47,7 +47,7 @@ - - package sun.security.pkcs11.wrapper; - -- -+import static sun.security.pkcs11.wrapper.PKCS11Constants.*; - - /** - * class CK_PKCS5_PBKD2_PARAMS provides the parameters to the CKM_PKCS5_PBKD2 -@@ -55,13 +55,15 @@ package sun.security.pkcs11.wrapper; - * PKCS#11 structure: - *
-  * typedef struct CK_PKCS5_PBKD2_PARAMS {
-- *   CK_PKCS5_PBKD2_SALT_SOURCE_TYPE saltSource;
-+ *   CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
-  *   CK_VOID_PTR pSaltSourceData;
-  *   CK_ULONG ulSaltSourceDataLen;
-  *   CK_ULONG iterations;
-  *   CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
-  *   CK_VOID_PTR pPrfData;
-  *   CK_ULONG ulPrfDataLen;
-+ *   CK_UTF8CHAR_PTR pPassword;
-+ *   CK_ULONG_PTR ulPasswordLen;
-  * } CK_PKCS5_PBKD2_PARAMS;
-  * 
- * -@@ -112,6 +114,24 @@ public class CK_PKCS5_PBKD2_PARAMS { - */ - public byte[] pPrfData; - -+ /** -+ * PKCS#11: -+ *
-+     *   CK_UTF8CHAR_PTR pPassword
-+     *   CK_ULONG_PTR ulPasswordLen;
-+     * 
-+ */ -+ public char[] pPassword; -+ -+ public CK_PKCS5_PBKD2_PARAMS(char[] pPassword, byte[] pSalt, -+ long iterations, long prf) { -+ this.pPassword = pPassword; -+ this.pSaltSourceData = pSalt; -+ this.iterations = iterations; -+ this.prf = prf; -+ this.saltSource = CKZ_SALT_SPECIFIED; -+ } -+ - /** - * Returns the string representation of CK_PKCS5_PBKD2_PARAMS. - * -diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS2.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS2.java -new file mode 100644 -index 00000000000..935db656639 ---- /dev/null -+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS2.java -@@ -0,0 +1,156 @@ -+/* -+ * Copyright (c) 2022, 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.wrapper; -+ -+import static sun.security.pkcs11.wrapper.PKCS11Constants.*; -+ -+/** -+ * class CK_PKCS5_PBKD2_PARAMS2 provides the parameters to the CKM_PKCS5_PBKD2 -+ * mechanism.

-+ * PKCS#11 structure: -+ *

-+ * typedef struct CK_PKCS5_PBKD2_PARAMS2 {
-+ *   CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
-+ *   CK_VOID_PTR pSaltSourceData;
-+ *   CK_ULONG ulSaltSourceDataLen;
-+ *   CK_ULONG iterations;
-+ *   CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
-+ *   CK_VOID_PTR pPrfData;
-+ *   CK_ULONG ulPrfDataLen;
-+ *   CK_UTF8CHAR_PTR pPassword;
-+ *   CK_ULONG ulPasswordLen;
-+ * } CK_PKCS5_PBKD2_PARAMS2;
-+ * 
-+ * -+ */ -+public class CK_PKCS5_PBKD2_PARAMS2 { -+ -+ /** -+ * PKCS#11: -+ *
-+     *   CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
-+     * 
-+ */ -+ public long saltSource; -+ -+ /** -+ * PKCS#11: -+ *
-+     *   CK_VOID_PTR pSaltSourceData;
-+     *   CK_ULONG ulSaltSourceDataLen;
-+     * 
-+ */ -+ public byte[] pSaltSourceData; -+ -+ /** -+ * PKCS#11: -+ *
-+     *   CK_ULONG iterations;
-+     * 
-+ */ -+ public long iterations; -+ -+ /** -+ * PKCS#11: -+ *
-+     *   CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
-+     * 
-+ */ -+ public long prf; -+ -+ /** -+ * PKCS#11: -+ *
-+     *   CK_VOID_PTR pPrfData;
-+     *   CK_ULONG ulPrfDataLen;
-+     * 
-+ */ -+ public byte[] pPrfData; -+ -+ /** -+ * PKCS#11: -+ *
-+     *   CK_UTF8CHAR_PTR pPassword
-+     *   CK_ULONG ulPasswordLen;
-+     * 
-+ */ -+ public char[] pPassword; -+ -+ public CK_PKCS5_PBKD2_PARAMS2(char[] pPassword, byte[] pSalt, -+ long iterations, long prf) { -+ this.pPassword = pPassword; -+ this.pSaltSourceData = pSalt; -+ this.iterations = iterations; -+ this.prf = prf; -+ this.saltSource = CKZ_SALT_SPECIFIED; -+ } -+ -+ /** -+ * Returns the string representation of CK_PKCS5_PBKD2_PARAMS2. -+ * -+ * @return the string representation of CK_PKCS5_PBKD2_PARAMS2 -+ */ -+ public String toString() { -+ StringBuilder sb = new StringBuilder(); -+ -+ sb.append(Constants.INDENT); -+ sb.append("saltSource: "); -+ sb.append(saltSource); -+ sb.append(Constants.NEWLINE); -+ -+ sb.append(Constants.INDENT); -+ sb.append("pSaltSourceData: "); -+ sb.append(Functions.toHexString(pSaltSourceData)); -+ sb.append(Constants.NEWLINE); -+ -+ sb.append(Constants.INDENT); -+ sb.append("ulSaltSourceDataLen: "); -+ sb.append(pSaltSourceData.length); -+ sb.append(Constants.NEWLINE); -+ -+ sb.append(Constants.INDENT); -+ sb.append("iterations: "); -+ sb.append(iterations); -+ sb.append(Constants.NEWLINE); -+ -+ sb.append(Constants.INDENT); -+ sb.append("prf: "); -+ sb.append(prf); -+ sb.append(Constants.NEWLINE); -+ -+ sb.append(Constants.INDENT); -+ sb.append("pPrfData: "); -+ sb.append(Functions.toHexString(pPrfData)); -+ sb.append(Constants.NEWLINE); -+ -+ sb.append(Constants.INDENT); -+ sb.append("ulPrfDataLen: "); -+ sb.append(pPrfData.length); -+ -+ return sb.toString(); -+ } -+ -+} -diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_X9_42_DH1_DERIVE_PARAMS.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_X9_42_DH1_DERIVE_PARAMS.java -index 1f9c4d39f57..5e3c1b9d29f 100644 ---- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_X9_42_DH1_DERIVE_PARAMS.java -+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_X9_42_DH1_DERIVE_PARAMS.java -@@ -94,9 +94,9 @@ public class CK_X9_42_DH1_DERIVE_PARAMS { - public byte[] pPublicData; - - /** -- * Returns the string representation of CK_PKCS5_PBKD2_PARAMS. -+ * Returns the string representation of CK_X9_42_DH1_DERIVE_PARAMS. - * -- * @return the string representation of CK_PKCS5_PBKD2_PARAMS -+ * @return the string representation of CK_X9_42_DH1_DERIVE_PARAMS - */ - public String toString() { - StringBuilder sb = new StringBuilder(); -diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11.java -index 5c0aacd1a67..d796aaa3075 100644 ---- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11.java -+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11.java -@@ -49,6 +49,9 @@ package sun.security.pkcs11.wrapper; - - import java.io.File; - import java.io.IOException; -+import java.lang.invoke.MethodHandle; -+import java.lang.invoke.MethodHandles; -+import java.lang.invoke.MethodType; - import java.util.*; - - import java.security.AccessController; -@@ -113,6 +116,8 @@ public class PKCS11 { - - private long pNativeData; - -+ private volatile CK_INFO pInfo; -+ - /** - * This method does the initialization of the native library. It is called - * exactly once for this class. -@@ -145,23 +150,48 @@ public class PKCS11 { - * @postconditions - */ - PKCS11(String pkcs11ModulePath, String functionListName) -- throws IOException { -+ throws IOException, PKCS11Exception { - connect(pkcs11ModulePath, functionListName); - this.pkcs11ModulePath = pkcs11ModulePath; - } - -+ /* -+ * Compatibility wrapper to allow this method to work as before -+ * when FIPS mode support is not active. -+ */ -+ public static synchronized PKCS11 getInstance(String pkcs11ModulePath, -+ String functionList, CK_C_INITIALIZE_ARGS pInitArgs, -+ boolean omitInitialize) throws IOException, PKCS11Exception { -+ return getInstance(pkcs11ModulePath, functionList, -+ pInitArgs, omitInitialize, null, null); -+ } -+ - public static synchronized PKCS11 getInstance(String pkcs11ModulePath, - String functionList, CK_C_INITIALIZE_ARGS pInitArgs, -- boolean omitInitialize) throws IOException, PKCS11Exception { -+ boolean omitInitialize, MethodHandle fipsKeyImporter, -+ MethodHandle fipsKeyExporter) -+ 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 && -+ fipsKeyExporter != null; - if ((pInitArgs != null) - && ((pInitArgs.flags & CKF_OS_LOCKING_OK) != 0)) { -- pkcs11 = new PKCS11(pkcs11ModulePath, functionList); -+ if (nssFipsMode) { -+ pkcs11 = new FIPSPKCS11(pkcs11ModulePath, functionList, -+ fipsKeyImporter, fipsKeyExporter); -+ } else { -+ pkcs11 = new PKCS11(pkcs11ModulePath, functionList); -+ } - } else { -- pkcs11 = new SynchronizedPKCS11(pkcs11ModulePath, functionList); -+ if (nssFipsMode) { -+ pkcs11 = new SynchronizedFIPSPKCS11(pkcs11ModulePath, -+ functionList, fipsKeyImporter, fipsKeyExporter); -+ } else { -+ pkcs11 = new SynchronizedPKCS11(pkcs11ModulePath, functionList); -+ } - } - if (omitInitialize == false) { - try { -@@ -179,6 +209,28 @@ public class PKCS11 { - return pkcs11; - } - -+ /** -+ * Returns the CK_INFO structure fetched at initialization with -+ * C_GetInfo. This structure represent Cryptoki library information. -+ */ -+ public CK_INFO getInfo() { -+ CK_INFO lPInfo = pInfo; -+ if (lPInfo == null) { -+ synchronized (this) { -+ lPInfo = pInfo; -+ if (lPInfo == null) { -+ try { -+ lPInfo = C_GetInfo(); -+ pInfo = lPInfo; -+ } catch (PKCS11Exception e) { -+ // Some PKCS #11 tokens require initialization first. -+ } -+ } -+ } -+ } -+ return lPInfo; -+ } -+ - /** - * Connects this object to the specified PKCS#11 library. This method is for - * internal use only. -@@ -1625,7 +1677,7 @@ public class PKCS11 { - static class SynchronizedPKCS11 extends PKCS11 { - - SynchronizedPKCS11(String pkcs11ModulePath, String functionListName) -- throws IOException { -+ throws IOException, PKCS11Exception { - super(pkcs11ModulePath, functionListName); - } - -@@ -1911,4 +1963,194 @@ 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; -+ private MethodHandle fipsKeyExporter; -+ private MethodHandle hC_GetAttributeValue; -+ FIPSPKCS11(String pkcs11ModulePath, String functionListName, -+ MethodHandle fipsKeyImporter, MethodHandle fipsKeyExporter) -+ throws IOException, PKCS11Exception { -+ super(pkcs11ModulePath, functionListName); -+ this.fipsKeyImporter = fipsKeyImporter; -+ this.fipsKeyExporter = fipsKeyExporter; -+ try { -+ hC_GetAttributeValue = MethodHandles.insertArguments( -+ MethodHandles.lookup().findSpecial(PKCS11.class, -+ "C_GetAttributeValue", MethodType.methodType( -+ void.class, long.class, long.class, -+ CK_ATTRIBUTE[].class), -+ FIPSPKCS11.class), 0, this); -+ } catch (Throwable t) { -+ throw new RuntimeException( -+ "sun.security.pkcs11.wrapper.PKCS11" + -+ "::C_GetAttributeValue method not found.", t); -+ } -+ } -+ -+ public 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) { -+ if (t instanceof PKCS11Exception) { -+ throw (PKCS11Exception)t; -+ } -+ throw new PKCS11Exception(CKR_GENERAL_ERROR, -+ t.getMessage()); -+ } -+ } -+ return super.C_CreateObject(hSession, pTemplate); -+ } -+ -+ public void C_GetAttributeValue(long hSession, long hObject, -+ CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception { -+ FIPSPKCS11Helper.C_GetAttributeValue(hC_GetAttributeValue, -+ fipsKeyExporter, hSession, hObject, pTemplate); -+ } -+} -+ -+// FIPSPKCS11 synchronized counterpart. -+static class SynchronizedFIPSPKCS11 extends SynchronizedPKCS11 { -+ private MethodHandle fipsKeyImporter; -+ private MethodHandle fipsKeyExporter; -+ private MethodHandle hC_GetAttributeValue; -+ SynchronizedFIPSPKCS11(String pkcs11ModulePath, String functionListName, -+ MethodHandle fipsKeyImporter, MethodHandle fipsKeyExporter) -+ throws IOException, PKCS11Exception { -+ super(pkcs11ModulePath, functionListName); -+ this.fipsKeyImporter = fipsKeyImporter; -+ this.fipsKeyExporter = fipsKeyExporter; -+ try { -+ hC_GetAttributeValue = MethodHandles.insertArguments( -+ MethodHandles.lookup().findSpecial(SynchronizedPKCS11.class, -+ "C_GetAttributeValue", MethodType.methodType( -+ void.class, long.class, long.class, -+ CK_ATTRIBUTE[].class), -+ SynchronizedFIPSPKCS11.class), 0, this); -+ } catch (Throwable t) { -+ throw new RuntimeException( -+ "sun.security.pkcs11.wrapper.SynchronizedPKCS11" + -+ "::C_GetAttributeValue method not found.", t); -+ } -+ } -+ -+ 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) { -+ if (t instanceof PKCS11Exception) { -+ throw (PKCS11Exception)t; -+ } -+ throw new PKCS11Exception(CKR_GENERAL_ERROR, -+ t.getMessage()); -+ } -+ } -+ return super.C_CreateObject(hSession, pTemplate); -+ } -+ -+ public synchronized void C_GetAttributeValue(long hSession, long hObject, -+ CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception { -+ FIPSPKCS11Helper.C_GetAttributeValue(hC_GetAttributeValue, -+ fipsKeyExporter, hSession, hObject, 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; -+ } -+ static void C_GetAttributeValue(MethodHandle hC_GetAttributeValue, -+ MethodHandle fipsKeyExporter, long hSession, long hObject, -+ CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception { -+ Map sensitiveAttrs = new HashMap<>(); -+ List nonSensitiveAttrs = new LinkedList<>(); -+ FIPSPKCS11Helper.getAttributesBySensitivity(pTemplate, -+ sensitiveAttrs, nonSensitiveAttrs); -+ try { -+ if (sensitiveAttrs.size() > 0) { -+ long keyClass = -1L; -+ long keyType = -1L; -+ try { -+ // Secret and private keys have both class and type -+ // attributes, so we can query them at once. -+ CK_ATTRIBUTE[] queryAttrs = new CK_ATTRIBUTE[]{ -+ new CK_ATTRIBUTE(CKA_CLASS), -+ new CK_ATTRIBUTE(CKA_KEY_TYPE), -+ }; -+ hC_GetAttributeValue.invoke(hSession, hObject, queryAttrs); -+ keyClass = queryAttrs[0].getLong(); -+ keyType = queryAttrs[1].getLong(); -+ } catch (PKCS11Exception e) { -+ // If the query fails, the object is neither a secret nor a -+ // private key. As this case won't be handled with the FIPS -+ // Key Exporter, we keep keyClass initialized to -1L. -+ } -+ if (keyClass == CKO_SECRET_KEY || keyClass == CKO_PRIVATE_KEY) { -+ fipsKeyExporter.invoke(hSession, hObject, keyClass, keyType, -+ sensitiveAttrs); -+ if (nonSensitiveAttrs.size() > 0) { -+ CK_ATTRIBUTE[] pNonSensitiveAttrs = -+ new CK_ATTRIBUTE[nonSensitiveAttrs.size()]; -+ int i = 0; -+ for (CK_ATTRIBUTE nonSensAttr : nonSensitiveAttrs) { -+ pNonSensitiveAttrs[i++] = nonSensAttr; -+ } -+ hC_GetAttributeValue.invoke(hSession, hObject, -+ pNonSensitiveAttrs); -+ // libj2pkcs11 allocates new CK_ATTRIBUTE objects, so we -+ // update the reference on the previous CK_ATTRIBUTEs -+ i = 0; -+ for (CK_ATTRIBUTE nonSensAttr : nonSensitiveAttrs) { -+ nonSensAttr.pValue = pNonSensitiveAttrs[i++].pValue; -+ } -+ } -+ return; -+ } -+ } -+ hC_GetAttributeValue.invoke(hSession, hObject, pTemplate); -+ } catch (Throwable t) { -+ if (t instanceof PKCS11Exception) { -+ throw (PKCS11Exception)t; -+ } -+ throw new PKCS11Exception(CKR_GENERAL_ERROR, -+ t.getMessage()); -+ } -+ } -+ private static void getAttributesBySensitivity(CK_ATTRIBUTE[] pTemplate, -+ Map sensitiveAttrs, -+ List nonSensitiveAttrs) { -+ for (CK_ATTRIBUTE attr : pTemplate) { -+ long type = attr.type; -+ // Aligned with NSS' sftk_isSensitive in lib/softoken/pkcs11u.c -+ if (type == CKA_VALUE || type == CKA_PRIVATE_EXPONENT || -+ type == CKA_PRIME_1 || type == CKA_PRIME_2 || -+ type == CKA_EXPONENT_1 || type == CKA_EXPONENT_2 || -+ type == CKA_COEFFICIENT) { -+ sensitiveAttrs.put(type, attr); -+ } else { -+ nonSensitiveAttrs.add(attr); -+ } -+ } -+ } -+} - } -diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11Constants.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11Constants.java -index 0d65ee26805..38fd4aff1f3 100644 ---- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11Constants.java -+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11Constants.java -@@ -1104,17 +1104,6 @@ public interface PKCS11Constants { - public static final long CKD_BLAKE2B_384_KDF = 0x00000019L; - public static final long CKD_BLAKE2B_512_KDF = 0x0000001aL; - -- public static final long CKP_PKCS5_PBKD2_HMAC_SHA1 = 0x00000001L; -- public static final long CKP_PKCS5_PBKD2_HMAC_GOSTR3411 = 0x00000002L; -- public static final long CKP_PKCS5_PBKD2_HMAC_SHA224 = 0x00000003L; -- public static final long CKP_PKCS5_PBKD2_HMAC_SHA256 = 0x00000004L; -- public static final long CKP_PKCS5_PBKD2_HMAC_SHA384 = 0x00000005L; -- public static final long CKP_PKCS5_PBKD2_HMAC_SHA512 = 0x00000006L; -- public static final long CKP_PKCS5_PBKD2_HMAC_SHA512_224 = 0x00000007L; -- public static final long CKP_PKCS5_PBKD2_HMAC_SHA512_256 = 0x00000008L; -- -- public static final long CKZ_SALT_SPECIFIED = 0x00000001L; -- - public static final long CK_OTP_VALUE = 0x00000000L; - public static final long CK_OTP_PIN = 0x00000001L; - public static final long CK_OTP_CHALLENGE = 0x00000002L; -@@ -1150,12 +1139,23 @@ public interface PKCS11Constants { - public static final long CKF_HKDF_SALT_KEY = 0x00000004L; - */ - -+ // PBKDF2 support, used in P11Util -+ public static final long CKZ_SALT_SPECIFIED = 0x00000001L; -+ public static final long CKP_PKCS5_PBKD2_HMAC_SHA1 = 0x00000001L; -+ public static final long CKP_PKCS5_PBKD2_HMAC_GOSTR3411 = 0x00000002L; -+ public static final long CKP_PKCS5_PBKD2_HMAC_SHA224 = 0x00000003L; -+ public static final long CKP_PKCS5_PBKD2_HMAC_SHA256 = 0x00000004L; -+ public static final long CKP_PKCS5_PBKD2_HMAC_SHA384 = 0x00000005L; -+ public static final long CKP_PKCS5_PBKD2_HMAC_SHA512 = 0x00000006L; -+ public static final long CKP_PKCS5_PBKD2_HMAC_SHA512_224 = 0x00000007L; -+ public static final long CKP_PKCS5_PBKD2_HMAC_SHA512_256 = 0x00000008L; -+ - // private NSS attribute (for DSA and DH private keys) - public static final long CKA_NETSCAPE_DB = 0xD5A0DB00L; - - // base number of NSS private attributes - public static final long CKA_NETSCAPE_BASE /*0x80000000L + 0x4E534350L*/ -- = 0xCE534350L; -+ /* now known as CKM_NSS ^ */ = 0xCE534350L; - - // object type for NSS trust - public static final long CKO_NETSCAPE_TRUST = 0xCE534353L; -@@ -1180,4 +1180,14 @@ public interface PKCS11Constants { - = 0xCE534355L; - public static final long CKT_NETSCAPE_VALID = 0xCE53435AL; - public static final long CKT_NETSCAPE_VALID_DELEGATOR = 0xCE53435BL; -+ -+ // Additional PKCS #12 PBE key derivation algorithms defined in NSS v3.29 -+ public static final long CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN -+ /* (CKM_NSS + 29) */ = 0xCE53436DL; -+ public static final long CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN -+ /* (CKM_NSS + 30) */ = 0xCE53436EL; -+ public static final long CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN -+ /* (CKM_NSS + 31) */ = 0xCE53436FL; -+ public static final long CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN -+ /* (CKM_NSS + 32) */ = 0xCE534370L; - } -diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c -index d941b574cc7..e2de13648be 100644 ---- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c -+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c -@@ -1515,6 +1515,10 @@ CK_VOID_PTR jMechParamToCKMechParamPtrSlow(JNIEnv *env, jobject jParam, - case CKM_PBE_SHA1_DES3_EDE_CBC: - case CKM_PBE_SHA1_DES2_EDE_CBC: - case CKM_PBA_SHA1_WITH_SHA1_HMAC: -+ case CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN: -+ case CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN: -+ case CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN: -+ case CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN: - ckpParamPtr = jPbeParamToCKPbeParamPtr(env, jParam, ckpLength); - break; - case CKM_PKCS5_PBKD2: -@@ -1658,13 +1662,13 @@ jPbeParamToCKPbeParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength) - // retrieve java values - jPbeParamsClass = (*env)->FindClass(env, CLASS_PBE_PARAMS); - if (jPbeParamsClass == NULL) { return NULL; } -- fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "pInitVector", "[C"); -+ fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "pInitVector", "[B"); - if (fieldID == NULL) { return NULL; } - jInitVector = (*env)->GetObjectField(env, jParam, fieldID); - fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "pPassword", "[C"); - if (fieldID == NULL) { return NULL; } - jPassword = (*env)->GetObjectField(env, jParam, fieldID); -- fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "pSalt", "[C"); -+ fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "pSalt", "[B"); - if (fieldID == NULL) { return NULL; } - jSalt = (*env)->GetObjectField(env, jParam, fieldID); - fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "ulIteration", "J"); -@@ -1680,15 +1684,15 @@ jPbeParamToCKPbeParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength) - - // populate using java values - ckParamPtr->ulIteration = jLongToCKULong(jIteration); -- jCharArrayToCKCharArray(env, jInitVector, &(ckParamPtr->pInitVector), &ckTemp); -+ jByteArrayToCKByteArray(env, jInitVector, &(ckParamPtr->pInitVector), &ckTemp); - if ((*env)->ExceptionCheck(env)) { - goto cleanup; - } -- jCharArrayToCKCharArray(env, jPassword, &(ckParamPtr->pPassword), &(ckParamPtr->ulPasswordLen)); -+ jCharArrayToCKUTF8CharArray(env, jPassword, &(ckParamPtr->pPassword), &(ckParamPtr->ulPasswordLen)); - if ((*env)->ExceptionCheck(env)) { - goto cleanup; - } -- jCharArrayToCKCharArray(env, jSalt, &(ckParamPtr->pSalt), &(ckParamPtr->ulSaltLen)); -+ jByteArrayToCKByteArray(env, jSalt, &(ckParamPtr->pSalt), &(ckParamPtr->ulSaltLen)); - if ((*env)->ExceptionCheck(env)) { - goto cleanup; - } -@@ -1767,31 +1771,59 @@ void copyBackPBEInitializationVector(JNIEnv *env, CK_MECHANISM *ckMechanism, job - } - } - -+#define PBKD2_PARAM_SET(member, value) \ -+ do { \ -+ if(ckParamPtr->version == PARAMS) { \ -+ ckParamPtr->params.v1.member = value; \ -+ } else { \ -+ ckParamPtr->params.v2.member = value; \ -+ } \ -+ } while(0) -+ -+#define PBKD2_PARAM_ADDR(member) \ -+ ( \ -+ (ckParamPtr->version == PARAMS) ? \ -+ (void*) &ckParamPtr->params.v1.member : \ -+ (void*) &ckParamPtr->params.v2.member \ -+ ) -+ - /* -- * converts the Java CK_PKCS5_PBKD2_PARAMS object to a CK_PKCS5_PBKD2_PARAMS -+ * converts a Java CK_PKCS5_PBKD2_PARAMS object to a CK_PKCS5_PBKD2_PARAMS -+ * pointer, or a Java CK_PKCS5_PBKD2_PARAMS2 object to a CK_PKCS5_PBKD2_PARAMS2 - * pointer - * -- * @param env - used to call JNI funktions to get the Java classes and objects -- * @param jParam - the Java CK_PKCS5_PBKD2_PARAMS object to convert -+ * @param env - used to call JNI functions to get the Java classes and objects -+ * @param jParam - the Java object to convert - * @param pLength - length of the allocated memory of the returned pointer -- * @return pointer to the new CK_PKCS5_PBKD2_PARAMS structure -+ * @return pointer to the new structure - */ --CK_PKCS5_PBKD2_PARAMS_PTR -+CK_VOID_PTR - jPkcs5Pbkd2ParamToCKPkcs5Pbkd2ParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength) - { -- CK_PKCS5_PBKD2_PARAMS_PTR ckParamPtr; -+ VersionedPbkd2ParamsPtr ckParamPtr; -+ ParamVersion paramVersion; -+ CK_ULONG_PTR pUlPasswordLen; - jclass jPkcs5Pbkd2ParamsClass; - jfieldID fieldID; - jlong jSaltSource, jIteration, jPrf; -- jobject jSaltSourceData, jPrfData; -+ jobject jSaltSourceData, jPrfData, jPassword; - - if (pLength != NULL) { - *pLength = 0L; - } - - // retrieve java values -- jPkcs5Pbkd2ParamsClass = (*env)->FindClass(env, CLASS_PKCS5_PBKD2_PARAMS); -- if (jPkcs5Pbkd2ParamsClass == NULL) { return NULL; } -+ if ((jPkcs5Pbkd2ParamsClass = -+ (*env)->FindClass(env, CLASS_PKCS5_PBKD2_PARAMS)) != NULL -+ && (*env)->IsInstanceOf(env, jParam, jPkcs5Pbkd2ParamsClass)) { -+ paramVersion = PARAMS; -+ } else if ((jPkcs5Pbkd2ParamsClass = -+ (*env)->FindClass(env, CLASS_PKCS5_PBKD2_PARAMS2)) != NULL -+ && (*env)->IsInstanceOf(env, jParam, jPkcs5Pbkd2ParamsClass)) { -+ paramVersion = PARAMS2; -+ } else { -+ return NULL; -+ } - fieldID = (*env)->GetFieldID(env, jPkcs5Pbkd2ParamsClass, "saltSource", "J"); - if (fieldID == NULL) { return NULL; } - jSaltSource = (*env)->GetLongField(env, jParam, fieldID); -@@ -1807,36 +1839,60 @@ jPkcs5Pbkd2ParamToCKPkcs5Pbkd2ParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pL - fieldID = (*env)->GetFieldID(env, jPkcs5Pbkd2ParamsClass, "pPrfData", "[B"); - if (fieldID == NULL) { return NULL; } - jPrfData = (*env)->GetObjectField(env, jParam, fieldID); -+ fieldID = (*env)->GetFieldID(env, jPkcs5Pbkd2ParamsClass, "pPassword", "[C"); -+ if (fieldID == NULL) { return NULL; } -+ jPassword = (*env)->GetObjectField(env, jParam, fieldID); - -- // allocate memory for CK_PKCS5_PBKD2_PARAMS pointer -- ckParamPtr = calloc(1, sizeof(CK_PKCS5_PBKD2_PARAMS)); -+ // allocate memory for VersionedPbkd2Params and store the structure version -+ ckParamPtr = calloc(1, sizeof(VersionedPbkd2Params)); - if (ckParamPtr == NULL) { - throwOutOfMemoryError(env, 0); - return NULL; - } -+ ckParamPtr->version = paramVersion; - - // populate using java values -- ckParamPtr->saltSource = jLongToCKULong(jSaltSource); -- jByteArrayToCKByteArray(env, jSaltSourceData, (CK_BYTE_PTR *) -- &(ckParamPtr->pSaltSourceData), &(ckParamPtr->ulSaltSourceDataLen)); -+ PBKD2_PARAM_SET(saltSource, jLongToCKULong(jSaltSource)); -+ jByteArrayToCKByteArray(env, jSaltSourceData, -+ (CK_BYTE_PTR *) PBKD2_PARAM_ADDR(pSaltSourceData), -+ PBKD2_PARAM_ADDR(ulSaltSourceDataLen)); - if ((*env)->ExceptionCheck(env)) { - goto cleanup; - } -- ckParamPtr->iterations = jLongToCKULong(jIteration); -- ckParamPtr->prf = jLongToCKULong(jPrf); -- jByteArrayToCKByteArray(env, jPrfData, (CK_BYTE_PTR *) -- &(ckParamPtr->pPrfData), &(ckParamPtr->ulPrfDataLen)); -+ PBKD2_PARAM_SET(iterations, jLongToCKULong(jIteration)); -+ PBKD2_PARAM_SET(prf, jLongToCKULong(jPrf)); -+ jByteArrayToCKByteArray(env, jPrfData, -+ (CK_BYTE_PTR *) PBKD2_PARAM_ADDR(pPrfData), -+ PBKD2_PARAM_ADDR(ulPrfDataLen)); -+ if ((*env)->ExceptionCheck(env)) { -+ goto cleanup; -+ } -+ if (ckParamPtr->version == PARAMS) { -+ pUlPasswordLen = calloc(1, sizeof(CK_ULONG)); -+ if (pUlPasswordLen == NULL) { -+ throwOutOfMemoryError(env, 0); -+ goto cleanup; -+ } -+ ckParamPtr->params.v1.ulPasswordLen = pUlPasswordLen; -+ } else { -+ pUlPasswordLen = &ckParamPtr->params.v2.ulPasswordLen; -+ } -+ jCharArrayToCKUTF8CharArray(env, jPassword, -+ (CK_CHAR_PTR *) PBKD2_PARAM_ADDR(pPassword), -+ pUlPasswordLen); - if ((*env)->ExceptionCheck(env)) { - goto cleanup; - } - - if (pLength != NULL) { -- *pLength = sizeof(CK_PKCS5_PBKD2_PARAMS); -+ *pLength = (ckParamPtr->version == PARAMS ? -+ sizeof(ckParamPtr->params.v1) : -+ sizeof(ckParamPtr->params.v2)); - } -+ // VersionedPbkd2ParamsPtr is equivalent to CK_PKCS5_PBKD2_PARAMS[2]_PTR - return ckParamPtr; - cleanup: -- free(ckParamPtr->pSaltSourceData); -- free(ckParamPtr->pPrfData); -+ FREE_VERSIONED_PBKD2_MEMBERS(ckParamPtr); - free(ckParamPtr); - return NULL; - -diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c -index 520bd52a2cd..aa76945283d 100644 ---- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c -+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c -@@ -410,11 +410,27 @@ void freeCKMechanismPtr(CK_MECHANISM_PTR mechPtr) { - case CKM_CAMELLIA_CTR: - // params do not contain pointers - break; -+ case CKM_PKCS5_PBKD2: -+ // get the versioned structure from behind memory -+ TRACE0(((VersionedPbkd2ParamsPtr)tmp)->version == PARAMS ? -+ "[ CK_PKCS5_PBKD2_PARAMS ]\n" : -+ "[ CK_PKCS5_PBKD2_PARAMS2 ]\n"); -+ FREE_VERSIONED_PBKD2_MEMBERS((VersionedPbkd2ParamsPtr)tmp); -+ break; -+ case CKM_PBA_SHA1_WITH_SHA1_HMAC: -+ case CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN: -+ case CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN: -+ case CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN: -+ case CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN: -+ free(((CK_PBE_PARAMS_PTR)tmp)->pInitVector); -+ free(((CK_PBE_PARAMS_PTR)tmp)->pPassword); -+ free(((CK_PBE_PARAMS_PTR)tmp)->pSalt); -+ break; - default: - // currently unsupported mechs by SunPKCS11 provider - // CKM_RSA_PKCS_OAEP, CKM_ECMQV_DERIVE, - // CKM_X9_42_*, CKM_KEA_DERIVE, CKM_RC2_*, CKM_RC5_*, -- // CKM_SKIPJACK_*, CKM_KEY_WRAP_SET_OAEP, CKM_PKCS5_PBKD2, -+ // CKM_SKIPJACK_*, CKM_KEY_WRAP_SET_OAEP, - // PBE mechs, WTLS mechs, CMS mechs, - // CKM_EXTRACT_KEY_FROM_KEY, CKM_OTP, CKM_KIP, - // CKM_DSA_PARAMETER_GEN?, CKM_GOSTR3410_* -@@ -517,12 +533,11 @@ void jBooleanArrayToCKBBoolArray(JNIEnv *env, const jbooleanArray jArray, CK_BBO - jboolean* jpTemp; - CK_ULONG i; - -- if(jArray == NULL) { -+ *ckpLength = jArray == NULL ? 0L : (*env)->GetArrayLength(env, jArray); -+ if(*ckpLength == 0L) { - *ckpArray = NULL_PTR; -- *ckpLength = 0L; - return; - } -- *ckpLength = (*env)->GetArrayLength(env, jArray); - jpTemp = (jboolean*) calloc(*ckpLength, sizeof(jboolean)); - if (jpTemp == NULL) { - throwOutOfMemoryError(env, 0); -@@ -559,12 +574,11 @@ void jByteArrayToCKByteArray(JNIEnv *env, const jbyteArray jArray, CK_BYTE_PTR * - jbyte* jpTemp; - CK_ULONG i; - -- if(jArray == NULL) { -+ *ckpLength = jArray == NULL ? 0L : (*env)->GetArrayLength(env, jArray); -+ if(*ckpLength == 0L) { - *ckpArray = NULL_PTR; -- *ckpLength = 0L; - return; - } -- *ckpLength = (*env)->GetArrayLength(env, jArray); - jpTemp = (jbyte*) calloc(*ckpLength, sizeof(jbyte)); - if (jpTemp == NULL) { - throwOutOfMemoryError(env, 0); -@@ -606,12 +620,11 @@ void jLongArrayToCKULongArray(JNIEnv *env, const jlongArray jArray, CK_ULONG_PTR - jlong* jTemp; - CK_ULONG i; - -- if(jArray == NULL) { -+ *ckpLength = jArray == NULL ? 0L : (*env)->GetArrayLength(env, jArray); -+ if(*ckpLength == 0L) { - *ckpArray = NULL_PTR; -- *ckpLength = 0L; - return; - } -- *ckpLength = (*env)->GetArrayLength(env, jArray); - jTemp = (jlong*) calloc(*ckpLength, sizeof(jlong)); - if (jTemp == NULL) { - throwOutOfMemoryError(env, 0); -@@ -648,12 +661,11 @@ void jCharArrayToCKCharArray(JNIEnv *env, const jcharArray jArray, CK_CHAR_PTR * - jchar* jpTemp; - CK_ULONG i; - -- if(jArray == NULL) { -+ *ckpLength = jArray == NULL ? 0L : (*env)->GetArrayLength(env, jArray); -+ if(*ckpLength == 0L) { - *ckpArray = NULL_PTR; -- *ckpLength = 0L; - return; - } -- *ckpLength = (*env)->GetArrayLength(env, jArray); - jpTemp = (jchar*) calloc(*ckpLength, sizeof(jchar)); - if (jpTemp == NULL) { - throwOutOfMemoryError(env, 0); -@@ -690,12 +702,11 @@ void jCharArrayToCKUTF8CharArray(JNIEnv *env, const jcharArray jArray, CK_UTF8CH - jchar* jTemp; - CK_ULONG i; - -- if(jArray == NULL) { -+ *ckpLength = jArray == NULL ? 0L : (*env)->GetArrayLength(env, jArray); -+ if(*ckpLength == 0L) { - *ckpArray = NULL_PTR; -- *ckpLength = 0L; - return; - } -- *ckpLength = (*env)->GetArrayLength(env, jArray); - jTemp = (jchar*) calloc(*ckpLength, sizeof(jchar)); - if (jTemp == NULL) { - throwOutOfMemoryError(env, 0); -diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h -index eb6d01b9e47..450e4d27d62 100644 ---- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h -+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h -@@ -68,6 +68,7 @@ - /* extra PKCS#11 constants not in the standard include files */ - - #define CKA_NETSCAPE_BASE (0x80000000 + 0x4E534350) -+/* ^ now known as CKM_NSS (CKM_VENDOR_DEFINED | NSSCK_VENDOR_NSS) */ - #define CKA_NETSCAPE_TRUST_BASE (CKA_NETSCAPE_BASE + 0x2000) - #define CKA_NETSCAPE_TRUST_SERVER_AUTH (CKA_NETSCAPE_TRUST_BASE + 8) - #define CKA_NETSCAPE_TRUST_CLIENT_AUTH (CKA_NETSCAPE_TRUST_BASE + 9) -@@ -76,6 +77,12 @@ - #define CKA_NETSCAPE_DB 0xD5A0DB00 - #define CKM_NSS_TLS_PRF_GENERAL 0x80000373 - -+/* additional PKCS #12 PBE key derivation algorithms defined in NSS v3.29 */ -+#define CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN (CKA_NETSCAPE_BASE + 29) -+#define CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN (CKA_NETSCAPE_BASE + 30) -+#define CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN (CKA_NETSCAPE_BASE + 31) -+#define CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN (CKA_NETSCAPE_BASE + 32) -+ - /* - - Define the PKCS#11 functions to include and exclude. Reduces the size -@@ -265,6 +272,7 @@ void printDebug(const char *format, ...); - #define CLASS_PBE_PARAMS "sun/security/pkcs11/wrapper/CK_PBE_PARAMS" - #define PBE_INIT_VECTOR_SIZE 8 - #define CLASS_PKCS5_PBKD2_PARAMS "sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS" -+#define CLASS_PKCS5_PBKD2_PARAMS2 "sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS2" - #define CLASS_EXTRACT_PARAMS "sun/security/pkcs11/wrapper/CK_EXTRACT_PARAMS" - - #define CLASS_ECDH1_DERIVE_PARAMS "sun/security/pkcs11/wrapper/CK_ECDH1_DERIVE_PARAMS" -@@ -378,7 +386,7 @@ CK_VOID_PTR jMechParamToCKMechParamPtr(JNIEnv *env, jobject jParam, CK_MECHANISM - CK_RSA_PKCS_OAEP_PARAMS_PTR jRsaPkcsOaepParamToCKRsaPkcsOaepParamPtr(JNIEnv *env, - jobject jParam, CK_ULONG* pLength); - CK_PBE_PARAMS_PTR jPbeParamToCKPbeParamPtr(JNIEnv *env, jobject jParam, CK_ULONG* pLength); --CK_PKCS5_PBKD2_PARAMS_PTR jPkcs5Pbkd2ParamToCKPkcs5Pbkd2ParamPtr(JNIEnv *env, jobject jParam, CK_ULONG* pLength); -+CK_VOID_PTR jPkcs5Pbkd2ParamToCKPkcs5Pbkd2ParamPtr(JNIEnv *env, jobject jParam, CK_ULONG* pLength); - CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR jSsl3MasterKeyDeriveParamToCKSsl3MasterKeyDeriveParamPtr(JNIEnv *env, jobject jParam, CK_ULONG* pLength); - CK_SSL3_KEY_MAT_PARAMS_PTR jSsl3KeyMatParamToCKSsl3KeyMatParamPtr(JNIEnv *env, jobject jParam, CK_ULONG* pLength); - CK_KEY_DERIVATION_STRING_DATA jKeyDerivationStringDataToCKKeyDerivationStringData(JNIEnv *env, jobject jParam); -@@ -388,6 +396,31 @@ CK_ECDH2_DERIVE_PARAMS_PTR jEcdh2DeriveParamToCKEcdh2DeriveParamPtr(JNIEnv *env, - CK_X9_42_DH1_DERIVE_PARAMS_PTR jX942Dh1DeriveParamToCKX942Dh1DeriveParamPtr(JNIEnv *env, jobject jParam, CK_ULONG* pLength); - CK_X9_42_DH2_DERIVE_PARAMS_PTR jX942Dh2DeriveParamToCKX942Dh2DeriveParamPtr(JNIEnv *env, jobject jParam, CK_ULONG* pLength); - -+/* handling of CK_PKCS5_PBKD2_PARAMS and CK_PKCS5_PBKD2_PARAMS2 */ -+typedef enum {PARAMS=0, PARAMS2} ParamVersion; -+ -+typedef struct { -+ union { -+ CK_PKCS5_PBKD2_PARAMS v1; -+ CK_PKCS5_PBKD2_PARAMS2 v2; -+ } params; -+ ParamVersion version; -+} VersionedPbkd2Params, *VersionedPbkd2ParamsPtr; -+ -+#define FREE_VERSIONED_PBKD2_MEMBERS(verParamsPtr) \ -+ do { \ -+ if ((verParamsPtr)->version == PARAMS) { \ -+ free((verParamsPtr)->params.v1.pSaltSourceData); \ -+ free((verParamsPtr)->params.v1.pPrfData); \ -+ free((verParamsPtr)->params.v1.pPassword); \ -+ free((verParamsPtr)->params.v1.ulPasswordLen); \ -+ } else { \ -+ free((verParamsPtr)->params.v2.pSaltSourceData); \ -+ free((verParamsPtr)->params.v2.pPrfData); \ -+ free((verParamsPtr)->params.v2.pPassword); \ -+ } \ -+ } while(0) -+ - /* functions to copy the returned values inside CK-mechanism back to Java object */ - - void copyBackPBEInitializationVector(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism); -diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java -index 8c9e4f9dbe6..883dc04758e 100644 ---- a/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java -+++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java -@@ -38,6 +38,7 @@ import java.util.HashMap; - import java.util.Iterator; - import java.util.List; - -+import jdk.internal.access.SharedSecrets; - import sun.security.ec.ed.EdDSAAlgorithmParameters; - import sun.security.ec.ed.EdDSAKeyFactory; - import sun.security.ec.ed.EdDSAKeyPairGenerator; -@@ -56,6 +57,10 @@ public final class SunEC extends Provider { - - private static final long serialVersionUID = -2279741672933606418L; - -+ private static final boolean systemFipsEnabled = -+ SharedSecrets.getJavaSecuritySystemConfiguratorAccess() -+ .isSystemFipsEnabled(); -+ - private static class ProviderServiceA extends ProviderService { - ProviderServiceA(Provider p, String type, String algo, String cn, - HashMap attrs) { -@@ -249,85 +254,86 @@ public final class SunEC extends Provider { - - putXDHEntries(); - putEdDSAEntries(); -- -- /* -- * Signature engines -- */ -- putService(new ProviderService(this, "Signature", -- "NONEwithECDSA", "sun.security.ec.ECDSASignature$Raw", -- null, ATTRS)); -- putService(new ProviderServiceA(this, "Signature", -- "SHA1withECDSA", "sun.security.ec.ECDSASignature$SHA1", -- ATTRS)); -- putService(new ProviderServiceA(this, "Signature", -- "SHA224withECDSA", "sun.security.ec.ECDSASignature$SHA224", -- ATTRS)); -- putService(new ProviderServiceA(this, "Signature", -- "SHA256withECDSA", "sun.security.ec.ECDSASignature$SHA256", -- ATTRS)); -- putService(new ProviderServiceA(this, "Signature", -- "SHA384withECDSA", "sun.security.ec.ECDSASignature$SHA384", -- ATTRS)); -- putService(new ProviderServiceA(this, "Signature", -- "SHA512withECDSA", "sun.security.ec.ECDSASignature$SHA512", -- ATTRS)); -- putService(new ProviderServiceA(this, "Signature", -- "SHA3-224withECDSA", "sun.security.ec.ECDSASignature$SHA3_224", -- ATTRS)); -- putService(new ProviderServiceA(this, "Signature", -- "SHA3-256withECDSA", "sun.security.ec.ECDSASignature$SHA3_256", -- ATTRS)); -- putService(new ProviderServiceA(this, "Signature", -- "SHA3-384withECDSA", "sun.security.ec.ECDSASignature$SHA3_384", -- ATTRS)); -- putService(new ProviderServiceA(this, "Signature", -- "SHA3-512withECDSA", "sun.security.ec.ECDSASignature$SHA3_512", -- ATTRS)); -- -- putService(new ProviderService(this, "Signature", -- "NONEwithECDSAinP1363Format", -- "sun.security.ec.ECDSASignature$RawinP1363Format")); -- putService(new ProviderService(this, "Signature", -- "SHA1withECDSAinP1363Format", -- "sun.security.ec.ECDSASignature$SHA1inP1363Format")); -- putService(new ProviderService(this, "Signature", -- "SHA224withECDSAinP1363Format", -- "sun.security.ec.ECDSASignature$SHA224inP1363Format")); -- putService(new ProviderService(this, "Signature", -- "SHA256withECDSAinP1363Format", -- "sun.security.ec.ECDSASignature$SHA256inP1363Format")); -- putService(new ProviderService(this, "Signature", -- "SHA384withECDSAinP1363Format", -- "sun.security.ec.ECDSASignature$SHA384inP1363Format")); -- putService(new ProviderService(this, "Signature", -- "SHA512withECDSAinP1363Format", -- "sun.security.ec.ECDSASignature$SHA512inP1363Format")); -- -- putService(new ProviderService(this, "Signature", -- "SHA3-224withECDSAinP1363Format", -- "sun.security.ec.ECDSASignature$SHA3_224inP1363Format")); -- putService(new ProviderService(this, "Signature", -- "SHA3-256withECDSAinP1363Format", -- "sun.security.ec.ECDSASignature$SHA3_256inP1363Format")); -- putService(new ProviderService(this, "Signature", -- "SHA3-384withECDSAinP1363Format", -- "sun.security.ec.ECDSASignature$SHA3_384inP1363Format")); -- putService(new ProviderService(this, "Signature", -- "SHA3-512withECDSAinP1363Format", -- "sun.security.ec.ECDSASignature$SHA3_512inP1363Format")); -- -- /* -- * Key Pair Generator engine -- */ -- putService(new ProviderService(this, "KeyPairGenerator", -- "EC", "sun.security.ec.ECKeyPairGenerator", -- List.of("EllipticCurve"), ATTRS)); -- -- /* -- * Key Agreement engine -- */ -- putService(new ProviderService(this, "KeyAgreement", -- "ECDH", "sun.security.ec.ECDHKeyAgreement", null, ATTRS)); -+ if (!systemFipsEnabled) { -+ /* -+ * Signature engines -+ */ -+ putService(new ProviderService(this, "Signature", -+ "NONEwithECDSA", "sun.security.ec.ECDSASignature$Raw", -+ null, ATTRS)); -+ putService(new ProviderServiceA(this, "Signature", -+ "SHA1withECDSA", "sun.security.ec.ECDSASignature$SHA1", -+ ATTRS)); -+ putService(new ProviderServiceA(this, "Signature", -+ "SHA224withECDSA", "sun.security.ec.ECDSASignature$SHA224", -+ ATTRS)); -+ putService(new ProviderServiceA(this, "Signature", -+ "SHA256withECDSA", "sun.security.ec.ECDSASignature$SHA256", -+ ATTRS)); -+ putService(new ProviderServiceA(this, "Signature", -+ "SHA384withECDSA", "sun.security.ec.ECDSASignature$SHA384", -+ ATTRS)); -+ putService(new ProviderServiceA(this, "Signature", -+ "SHA512withECDSA", "sun.security.ec.ECDSASignature$SHA512", -+ ATTRS)); -+ putService(new ProviderServiceA(this, "Signature", -+ "SHA3-224withECDSA", "sun.security.ec.ECDSASignature$SHA3_224", -+ ATTRS)); -+ putService(new ProviderServiceA(this, "Signature", -+ "SHA3-256withECDSA", "sun.security.ec.ECDSASignature$SHA3_256", -+ ATTRS)); -+ putService(new ProviderServiceA(this, "Signature", -+ "SHA3-384withECDSA", "sun.security.ec.ECDSASignature$SHA3_384", -+ ATTRS)); -+ putService(new ProviderServiceA(this, "Signature", -+ "SHA3-512withECDSA", "sun.security.ec.ECDSASignature$SHA3_512", -+ ATTRS)); -+ -+ putService(new ProviderService(this, "Signature", -+ "NONEwithECDSAinP1363Format", -+ "sun.security.ec.ECDSASignature$RawinP1363Format")); -+ putService(new ProviderService(this, "Signature", -+ "SHA1withECDSAinP1363Format", -+ "sun.security.ec.ECDSASignature$SHA1inP1363Format")); -+ putService(new ProviderService(this, "Signature", -+ "SHA224withECDSAinP1363Format", -+ "sun.security.ec.ECDSASignature$SHA224inP1363Format")); -+ putService(new ProviderService(this, "Signature", -+ "SHA256withECDSAinP1363Format", -+ "sun.security.ec.ECDSASignature$SHA256inP1363Format")); -+ putService(new ProviderService(this, "Signature", -+ "SHA384withECDSAinP1363Format", -+ "sun.security.ec.ECDSASignature$SHA384inP1363Format")); -+ putService(new ProviderService(this, "Signature", -+ "SHA512withECDSAinP1363Format", -+ "sun.security.ec.ECDSASignature$SHA512inP1363Format")); -+ -+ putService(new ProviderService(this, "Signature", -+ "SHA3-224withECDSAinP1363Format", -+ "sun.security.ec.ECDSASignature$SHA3_224inP1363Format")); -+ putService(new ProviderService(this, "Signature", -+ "SHA3-256withECDSAinP1363Format", -+ "sun.security.ec.ECDSASignature$SHA3_256inP1363Format")); -+ putService(new ProviderService(this, "Signature", -+ "SHA3-384withECDSAinP1363Format", -+ "sun.security.ec.ECDSASignature$SHA3_384inP1363Format")); -+ putService(new ProviderService(this, "Signature", -+ "SHA3-512withECDSAinP1363Format", -+ "sun.security.ec.ECDSASignature$SHA3_512inP1363Format")); -+ -+ /* -+ * Key Pair Generator engine -+ */ -+ putService(new ProviderService(this, "KeyPairGenerator", -+ "EC", "sun.security.ec.ECKeyPairGenerator", -+ List.of("EllipticCurve"), ATTRS)); -+ -+ /* -+ * Key Agreement engine -+ */ -+ putService(new ProviderService(this, "KeyAgreement", -+ "ECDH", "sun.security.ec.ECDHKeyAgreement", null, ATTRS)); -+ } - } - - private void putXDHEntries() { -@@ -344,23 +350,25 @@ public final class SunEC extends Provider { - "X448", "sun.security.ec.XDHKeyFactory.X448", - ATTRS)); - -- putService(new ProviderService(this, "KeyPairGenerator", -- "XDH", "sun.security.ec.XDHKeyPairGenerator", null, ATTRS)); -- putService(new ProviderServiceA(this, "KeyPairGenerator", -- "X25519", "sun.security.ec.XDHKeyPairGenerator.X25519", -- ATTRS)); -- putService(new ProviderServiceA(this, "KeyPairGenerator", -- "X448", "sun.security.ec.XDHKeyPairGenerator.X448", -- ATTRS)); -- -- putService(new ProviderService(this, "KeyAgreement", -- "XDH", "sun.security.ec.XDHKeyAgreement", null, ATTRS)); -- putService(new ProviderServiceA(this, "KeyAgreement", -- "X25519", "sun.security.ec.XDHKeyAgreement.X25519", -- ATTRS)); -- putService(new ProviderServiceA(this, "KeyAgreement", -- "X448", "sun.security.ec.XDHKeyAgreement.X448", -- ATTRS)); -+ if (!systemFipsEnabled) { -+ putService(new ProviderService(this, "KeyPairGenerator", -+ "XDH", "sun.security.ec.XDHKeyPairGenerator", null, ATTRS)); -+ putService(new ProviderServiceA(this, "KeyPairGenerator", -+ "X25519", "sun.security.ec.XDHKeyPairGenerator.X25519", -+ ATTRS)); -+ putService(new ProviderServiceA(this, "KeyPairGenerator", -+ "X448", "sun.security.ec.XDHKeyPairGenerator.X448", -+ ATTRS)); -+ -+ putService(new ProviderService(this, "KeyAgreement", -+ "XDH", "sun.security.ec.XDHKeyAgreement", null, ATTRS)); -+ putService(new ProviderServiceA(this, "KeyAgreement", -+ "X25519", "sun.security.ec.XDHKeyAgreement.X25519", -+ ATTRS)); -+ putService(new ProviderServiceA(this, "KeyAgreement", -+ "X448", "sun.security.ec.XDHKeyAgreement.X448", -+ ATTRS)); -+ } - } - - private void putEdDSAEntries() { -@@ -375,21 +383,23 @@ public final class SunEC extends Provider { - putService(new ProviderServiceA(this, "KeyFactory", - "Ed448", "sun.security.ec.ed.EdDSAKeyFactory.Ed448", ATTRS)); - -- putService(new ProviderService(this, "KeyPairGenerator", -- "EdDSA", "sun.security.ec.ed.EdDSAKeyPairGenerator", null, ATTRS)); -- putService(new ProviderServiceA(this, "KeyPairGenerator", -- "Ed25519", "sun.security.ec.ed.EdDSAKeyPairGenerator.Ed25519", -- ATTRS)); -- putService(new ProviderServiceA(this, "KeyPairGenerator", -- "Ed448", "sun.security.ec.ed.EdDSAKeyPairGenerator.Ed448", -- ATTRS)); -- -- putService(new ProviderService(this, "Signature", -- "EdDSA", "sun.security.ec.ed.EdDSASignature", null, ATTRS)); -- putService(new ProviderServiceA(this, "Signature", -- "Ed25519", "sun.security.ec.ed.EdDSASignature.Ed25519", ATTRS)); -- putService(new ProviderServiceA(this, "Signature", -- "Ed448", "sun.security.ec.ed.EdDSASignature.Ed448", ATTRS)); -+ if (!systemFipsEnabled) { -+ putService(new ProviderService(this, "KeyPairGenerator", -+ "EdDSA", "sun.security.ec.ed.EdDSAKeyPairGenerator", null, ATTRS)); -+ putService(new ProviderServiceA(this, "KeyPairGenerator", -+ "Ed25519", "sun.security.ec.ed.EdDSAKeyPairGenerator.Ed25519", -+ ATTRS)); -+ putService(new ProviderServiceA(this, "KeyPairGenerator", -+ "Ed448", "sun.security.ec.ed.EdDSAKeyPairGenerator.Ed448", -+ ATTRS)); -+ -+ putService(new ProviderService(this, "Signature", -+ "EdDSA", "sun.security.ec.ed.EdDSASignature", null, ATTRS)); -+ putService(new ProviderServiceA(this, "Signature", -+ "Ed25519", "sun.security.ec.ed.EdDSASignature.Ed25519", ATTRS)); -+ putService(new ProviderServiceA(this, "Signature", -+ "Ed448", "sun.security.ec.ed.EdDSASignature.Ed448", ATTRS)); -+ } - - } - } -diff --git a/test/jdk/sun/security/pkcs11/Cipher/PBECipher.java b/test/jdk/sun/security/pkcs11/Cipher/PBECipher.java -new file mode 100644 -index 00000000000..a184a169732 ---- /dev/null -+++ b/test/jdk/sun/security/pkcs11/Cipher/PBECipher.java -@@ -0,0 +1,233 @@ -+/* -+ * Copyright (c) 2022, 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. -+ * -+ * 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. -+ */ -+ -+import java.math.BigInteger; -+import java.security.AlgorithmParameters; -+import java.security.NoSuchAlgorithmException; -+import java.security.Provider; -+import java.security.SecureRandom; -+import java.security.Security; -+import java.util.Map; -+ -+import javax.crypto.Cipher; -+import javax.crypto.SecretKey; -+import javax.crypto.SecretKeyFactory; -+import javax.crypto.interfaces.PBEKey; -+import javax.crypto.spec.IvParameterSpec; -+import javax.crypto.spec.PBEKeySpec; -+import javax.crypto.spec.PBEParameterSpec; -+ -+/* -+ * @test -+ * @bug 9999999 -+ * @summary test password based encryption on SunPKCS11's Cipher service -+ * @requires (jdk.version.major >= 8) -+ * @library /test/lib .. -+ * @run main/othervm/timeout=30 PBECipher -+ */ -+ -+public final class PBECipher { -+ public static void main(String[] args) throws Exception { -+ java.security.Security.getProviders(); -+ PBECipher2.main(args); -+ } -+} -+ -+final class PBECipher2 extends PKCS11Test { -+ private static final char[] password = "123456".toCharArray(); -+ private static final byte[] salt = "abcdefgh".getBytes(); -+ private static final byte[] iv = new byte[16]; -+ private static final int iterations = 1000; -+ private static final String plainText = "This is a know plain text!"; -+ private static final String sep = -+ "========================================================================="; -+ -+ private static enum Configuration { -+ // Provide salt and iterations through a PBEParameterSpec instance -+ PBEParameterSpec, -+ -+ // Provide salt and iterations through a AlgorithmParameters instance -+ AlgorithmParameters, -+ -+ // Provide salt and iterations through an anonymous class implementing -+ // the javax.crypto.interfaces.PBEKey interface -+ AnonymousPBEKey, -+ } -+ -+ private static Provider sunJCE = Security.getProvider("SunJCE"); -+ -+ // Generated with SunJCE -+ private static final Map assertionData = Map.of( -+ "PBEWithHmacSHA1AndAES_128", new BigInteger("8eebe98a580fb09d026" + -+ "dbfe60b3733b079e0de9ea7b0b1ccba011a1652d1e257", 16), -+ "PBEWithHmacSHA224AndAES_128", new BigInteger("1cbabdeb5d483af4a" + -+ "841942f4b1095b7d6f60e46fabfd2609c015adc38cc227", 16), -+ "PBEWithHmacSHA256AndAES_128", new BigInteger("4d82f6591df3508d2" + -+ "4531f06cdc4f90f4bdab7aeb07fbb57a3712e999d5b6f59", 16), -+ "PBEWithHmacSHA384AndAES_128", new BigInteger("3a0ed0959d51f40b9" + -+ "ba9f506a5277f430521f2fbe1ba94bae368835f221b6cb9", 16), -+ "PBEWithHmacSHA512AndAES_128", new BigInteger("1388287a446009309" + -+ "1418f4eca3ba1735b1fa025423d74ced36ce578d8ebf9da", 16), -+ "PBEWithHmacSHA1AndAES_256", new BigInteger("80f8208daab27ed02dd" + -+ "8a354ef6f23ff7813c84dd1c8a1b081d6f4dee27182a2", 16), -+ "PBEWithHmacSHA224AndAES_256", new BigInteger("7e3b9ce20aec2e52f" + -+ "f6c781602d4f79a55a88495b5217f1e22e1a068268e6247", 16), -+ "PBEWithHmacSHA256AndAES_256", new BigInteger("9d6a8b6a351dfd0dd" + -+ "9e9f45924b2860dca7719c4c07e207a64ebc1acd16cc157", 16), -+ "PBEWithHmacSHA384AndAES_256", new BigInteger("6f1b386cee3a8e2d9" + -+ "8c2e81828da0467dec8b989d22258efeab5932580d01d53", 16), -+ "PBEWithHmacSHA512AndAES_256", new BigInteger("30aaa346b2edd394f" + -+ "50916187876ac32f1287b19d55c5eea6f7ef9b84aaf291e", 16) -+ ); -+ -+ private static final class NoRandom extends SecureRandom { -+ @Override -+ public void nextBytes(byte[] bytes) { -+ return; -+ } -+ } -+ -+ public void main(Provider sunPKCS11) throws Exception { -+ System.out.println("SunPKCS11: " + sunPKCS11.getName()); -+ for (Configuration conf : Configuration.values()) { -+ testWith(sunPKCS11, "PBEWithHmacSHA1AndAES_128", conf); -+ testWith(sunPKCS11, "PBEWithHmacSHA224AndAES_128", conf); -+ testWith(sunPKCS11, "PBEWithHmacSHA256AndAES_128", conf); -+ testWith(sunPKCS11, "PBEWithHmacSHA384AndAES_128", conf); -+ testWith(sunPKCS11, "PBEWithHmacSHA512AndAES_128", conf); -+ testWith(sunPKCS11, "PBEWithHmacSHA1AndAES_256", conf); -+ testWith(sunPKCS11, "PBEWithHmacSHA224AndAES_256", conf); -+ testWith(sunPKCS11, "PBEWithHmacSHA256AndAES_256", conf); -+ testWith(sunPKCS11, "PBEWithHmacSHA384AndAES_256", conf); -+ testWith(sunPKCS11, "PBEWithHmacSHA512AndAES_256", conf); -+ } -+ System.out.println("TEST PASS - OK"); -+ } -+ -+ private void testWith(Provider sunPKCS11, String algorithm, -+ Configuration conf) throws Exception { -+ System.out.println(sep + System.lineSeparator() + algorithm -+ + " (with " + conf.name() + ")"); -+ -+ Cipher pbeCipher = getCipher(sunPKCS11, algorithm, conf); -+ BigInteger cipherText = new BigInteger(1, pbeCipher.doFinal( -+ plainText.getBytes())); -+ printByteArray("Cipher Text", cipherText); -+ -+ BigInteger expectedCipherText = null; -+ if (sunJCE != null) { -+ Cipher c = getCipher(sunJCE, algorithm, conf); -+ if (c != null) { -+ expectedCipherText = new BigInteger(1, c.doFinal( -+ plainText.getBytes())); -+ } else { -+ // Move to assertionData as it's unlikely that any of -+ // the algorithms are available. -+ sunJCE = null; -+ } -+ } -+ if (expectedCipherText == null) { -+ // If SunJCE or the algorithm are not available, assertionData -+ // is used instead. -+ expectedCipherText = assertionData.get(algorithm); -+ } -+ -+ if (!cipherText.equals(expectedCipherText)) { -+ printByteArray("Expected Cipher Text", expectedCipherText); -+ throw new Exception("Expected Cipher Text did not match"); -+ } -+ } -+ -+ private Cipher getCipher(Provider p, String algorithm, -+ Configuration conf) throws Exception { -+ Cipher pbeCipher = null; -+ try { -+ pbeCipher = Cipher.getInstance(algorithm, p); -+ } catch (NoSuchAlgorithmException e) { -+ return null; -+ } -+ switch (conf) { -+ case PBEParameterSpec, AlgorithmParameters -> { -+ SecretKey key = getPasswordOnlyPBEKey(); -+ PBEParameterSpec paramSpec = new PBEParameterSpec( -+ salt, iterations, new IvParameterSpec(iv)); -+ switch (conf) { -+ case PBEParameterSpec -> { -+ pbeCipher.init(Cipher.ENCRYPT_MODE, key, paramSpec); -+ } -+ case AlgorithmParameters -> { -+ AlgorithmParameters algoParams = -+ AlgorithmParameters.getInstance("PBES2"); -+ algoParams.init(paramSpec); -+ pbeCipher.init(Cipher.ENCRYPT_MODE, key, algoParams); -+ } -+ } -+ } -+ case AnonymousPBEKey -> { -+ SecretKey key = getPasswordSaltIterationsPBEKey(); -+ pbeCipher.init(Cipher.ENCRYPT_MODE, key, new NoRandom()); -+ } -+ } -+ return pbeCipher; -+ } -+ -+ private static SecretKey getPasswordOnlyPBEKey() throws Exception { -+ PBEKeySpec keySpec = new PBEKeySpec(password); -+ SecretKeyFactory skFac = SecretKeyFactory.getInstance("PBE"); -+ SecretKey skey = skFac.generateSecret(keySpec); -+ keySpec.clearPassword(); -+ return skey; -+ } -+ -+ private static SecretKey getPasswordSaltIterationsPBEKey() { -+ return new PBEKey() { -+ public byte[] getSalt() { return salt.clone(); } -+ public int getIterationCount() { return iterations; } -+ public String getAlgorithm() { return "PBE"; } -+ public String getFormat() { return "RAW"; } -+ public char[] getPassword() { return null; } // unused in PBE Cipher -+ public byte[] getEncoded() { -+ byte[] passwdBytes = new byte[password.length]; -+ for (int i = 0; i < password.length; i++) -+ passwdBytes[i] = (byte) (password[i] & 0x7f); -+ return passwdBytes; -+ } -+ }; -+ } -+ -+ private static void printByteArray(String title, BigInteger b) { -+ String repr = (b == null) ? "buffer is null" : b.toString(16); -+ System.out.println(title + ": " + repr + System.lineSeparator()); -+ } -+ -+ public static void main(String[] args) throws Exception { -+ PBECipher2 test = new PBECipher2(); -+ Provider p = Security.getProvider("SunPKCS11-NSS-FIPS"); -+ if (p != null) { -+ test.main(p); -+ } else { -+ main(test); -+ } -+ } -+} -diff --git a/test/jdk/sun/security/pkcs11/KeyStore/ImportKeyToP12.java b/test/jdk/sun/security/pkcs11/KeyStore/ImportKeyToP12.java -new file mode 100644 -index 00000000000..360e11c339d ---- /dev/null -+++ b/test/jdk/sun/security/pkcs11/KeyStore/ImportKeyToP12.java -@@ -0,0 +1,137 @@ -+/* -+ * Copyright (c) 2022, 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. -+ * -+ * 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. -+ */ -+ -+import java.io.ByteArrayInputStream; -+import java.io.ByteArrayOutputStream; -+import java.security.Key; -+import java.security.KeyStore; -+import java.security.KeyStoreException; -+import java.security.MessageDigest; -+import java.security.Provider; -+import java.security.Security; -+ -+import javax.crypto.spec.SecretKeySpec; -+ -+/* -+ * @test -+ * @bug 9999999 -+ * @summary test SunPKCS11's password based privacy and integrity -+ * applied to PKCS#12 keystores -+ * @requires (jdk.version.major >= 8) -+ * @library /test/lib .. -+ * @modules java.base/sun.security.util -+ * @run main/othervm/timeout=30 -Dcom.redhat.fips=false -DNO_DEFAULT=true ImportKeyToP12 -+ */ -+ -+public final class ImportKeyToP12 { -+ public static void main(String[] args) throws Exception { -+ java.security.Security.getProviders(); -+ ImportKeyToP122.main(args); -+ } -+} -+ -+final class ImportKeyToP122 extends PKCS11Test { -+ private static final String alias = "alias"; -+ private static final char[] password = "123456".toCharArray(); -+ private static final Key key = new SecretKeySpec(new byte[] { -+ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, -+ 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf }, "AES"); -+ private static final String[] pbeCipherAlgs = new String[] { -+ "PBEWithHmacSHA1AndAES_128", "PBEWithHmacSHA224AndAES_128", -+ "PBEWithHmacSHA256AndAES_128", "PBEWithHmacSHA384AndAES_128", -+ "PBEWithHmacSHA512AndAES_128", "PBEWithHmacSHA1AndAES_256", -+ "PBEWithHmacSHA224AndAES_256", "PBEWithHmacSHA256AndAES_256", -+ "PBEWithHmacSHA384AndAES_256", "PBEWithHmacSHA512AndAES_256" -+ }; -+ private static final String[] pbeMacAlgs = new String[] { -+ "HmacPBESHA1", "HmacPBESHA224", "HmacPBESHA256", -+ "HmacPBESHA384", "HmacPBESHA512" -+ }; -+ private static final KeyStore p12; -+ private static final String sep = -+ "========================================================================="; -+ -+ static { -+ KeyStore tP12 = null; -+ try { -+ tP12 = KeyStore.getInstance("PKCS12"); -+ } catch (KeyStoreException e) {} -+ p12 = tP12; -+ } -+ -+ public void main(Provider sunPKCS11) throws Exception { -+ System.out.println("SunPKCS11: " + sunPKCS11.getName()); -+ // Test all privacy PBE algorithms with an integrity algorithm fixed -+ for (String pbeCipherAlg : pbeCipherAlgs) { -+ testWith(sunPKCS11, pbeCipherAlg, pbeMacAlgs[0]); -+ } -+ // Test all integrity PBE algorithms with a privacy algorithm fixed -+ for (String pbeMacAlg : pbeMacAlgs) { -+ testWith(sunPKCS11, pbeCipherAlgs[0], pbeMacAlg); -+ } -+ System.out.println("TEST PASS - OK"); -+ } -+ -+ /* -+ * Consistency test: 1) store a secret key in a PKCS#12 keystore using -+ * PBE algorithms from SunPKCS11 and, 2) read the secret key from the -+ * PKCS#12 keystore using PBE algorithms from other security providers -+ * such as SunJCE. -+ */ -+ private void testWith(Provider sunPKCS11, String pbeCipherAlg, -+ String pbeMacAlg) throws Exception { -+ System.out.println(sep + System.lineSeparator() + -+ "Cipher PBE: " + pbeCipherAlg + System.lineSeparator() + -+ "Mac PBE: " + pbeMacAlg); -+ -+ System.setProperty("keystore.pkcs12.macAlgorithm", pbeMacAlg); -+ System.setProperty("keystore.pkcs12.keyProtectionAlgorithm", -+ pbeCipherAlg); -+ -+ // Create an empty PKCS#12 keystore -+ ByteArrayOutputStream baos = new ByteArrayOutputStream(); -+ p12.load(null, password); -+ -+ // Use PBE privacy and integrity algorithms from SunPKCS11 to store -+ // the secret key -+ Security.insertProviderAt(sunPKCS11, 1); -+ p12.setKeyEntry(alias, key, password, null); -+ p12.store(baos, password); -+ -+ // Use PBE privacy and integrity algorithms from other security -+ // providers, such as SunJCE, to read the secret key -+ Security.removeProvider(sunPKCS11.getName()); -+ p12.load(new ByteArrayInputStream(baos.toByteArray()), password); -+ Key k = p12.getKey(alias, password); -+ -+ if (!MessageDigest.isEqual(key.getEncoded(), k.getEncoded())) { -+ throw new Exception("Keys differ. Consistency check failed."); -+ } -+ System.out.println("Secret key import successful" + System.lineSeparator() + sep); -+ } -+ -+ public static void main(String[] args) throws Exception { -+ main(new ImportKeyToP122()); -+ } -+} -diff --git a/test/jdk/sun/security/pkcs11/Mac/PBAMac.java b/test/jdk/sun/security/pkcs11/Mac/PBAMac.java -new file mode 100644 -index 00000000000..6b5662f6b4c ---- /dev/null -+++ b/test/jdk/sun/security/pkcs11/Mac/PBAMac.java -@@ -0,0 +1,187 @@ -+/* -+ * Copyright (c) 2022, 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. -+ * -+ * 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. -+ */ -+ -+import java.math.BigInteger; -+import java.security.NoSuchAlgorithmException; -+import java.security.Provider; -+import java.security.Security; -+import java.util.Map; -+ -+import javax.crypto.Mac; -+import javax.crypto.SecretKey; -+import javax.crypto.SecretKeyFactory; -+import javax.crypto.interfaces.PBEKey; -+import javax.crypto.spec.PBEKeySpec; -+import javax.crypto.spec.PBEParameterSpec; -+ -+/* -+ * @test -+ * @bug 9999999 -+ * @summary test password based authentication on SunPKCS11's Mac service -+ * @requires (jdk.version.major >= 8) -+ * @library /test/lib .. -+ * @run main/othervm/timeout=30 PBAMac -+ */ -+ -+public final class PBAMac { -+ public static void main(String[] args) throws Exception { -+ java.security.Security.getProviders(); -+ PBAMac2.main(args); -+ } -+} -+ -+final class PBAMac2 extends PKCS11Test { -+ private static final char[] password = "123456".toCharArray(); -+ private static final byte[] salt = "abcdefgh".getBytes(); -+ private static final int iterations = 1000; -+ private static final String plainText = "This is a know plain text!"; -+ private static final String sep = -+ "========================================================================="; -+ -+ private static enum Configuration { -+ // Provide salt & iterations through a PBEParameterSpec instance -+ PBEParameterSpec, -+ -+ // Provide salt & iterations through an anonymous class implementing -+ // the javax.crypto.interfaces.PBEKey interface -+ AnonymousPBEKey, -+ } -+ -+ // Generated with SunJCE -+ private static final Map assertionData = Map.of( -+ "HmacPBESHA1", new BigInteger("febd26da5d63ce819770a2af1fc2857e" + -+ "e2c9c41c", 16), -+ "HmacPBESHA224", new BigInteger("aa6a3a1c35a4b266fea62d1a871508" + -+ "bd45f8ec326bcf16e09699063", 16), -+ "HmacPBESHA256", new BigInteger("af4d71121fd4e9d52eb42944d99b77" + -+ "8ff64376fcf6af8d1dca3ec688dfada5c8", 16), -+ "HmacPBESHA384", new BigInteger("5d6d37764205985ffca7e4a6222752" + -+ "a8bbd0520858da08ecafdc57e6246894675e375b9ba084f9ce7142" + -+ "35f202cc3452", 16), -+ "HmacPBESHA512", new BigInteger("f586c2006cc2de73fd5743e5cca701" + -+ "c942d3741a7a54a2a649ea36898996cf3c483f2d734179b47751db" + -+ "e8373c980b4072136d2e2810f4e7276024a3e9081cc1", 16) -+ ); -+ -+ private static Provider sunJCE = Security.getProvider("SunJCE"); -+ -+ public void main(Provider sunPKCS11) throws Exception { -+ System.out.println("SunPKCS11: " + sunPKCS11.getName()); -+ for (Configuration conf : Configuration.values()) { -+ testWith(sunPKCS11, "HmacPBESHA1", conf); -+ testWith(sunPKCS11, "HmacPBESHA224", conf); -+ testWith(sunPKCS11, "HmacPBESHA256", conf); -+ testWith(sunPKCS11, "HmacPBESHA384", conf); -+ testWith(sunPKCS11, "HmacPBESHA512", conf); -+ } -+ System.out.println("TEST PASS - OK"); -+ } -+ -+ private void testWith(Provider sunPKCS11, String algorithm, -+ Configuration conf) throws Exception { -+ System.out.println(sep + System.lineSeparator() + algorithm -+ + " (with " + conf.name() + ")"); -+ -+ BigInteger macResult = computeMac(sunPKCS11, algorithm, conf); -+ printByteArray("HMAC Result", macResult); -+ -+ BigInteger expectedMacResult = computeExpectedMac(algorithm, conf); -+ -+ if (!macResult.equals(expectedMacResult)) { -+ printByteArray("Expected HMAC Result", expectedMacResult); -+ throw new Exception("Expected HMAC Result did not match"); -+ } -+ } -+ -+ private BigInteger computeMac(Provider p, String algorithm, -+ Configuration conf) throws Exception { -+ Mac pbaMac; -+ try { -+ pbaMac = Mac.getInstance(algorithm, p); -+ } catch (NoSuchAlgorithmException e) { -+ return null; -+ } -+ switch (conf) { -+ case PBEParameterSpec -> { -+ SecretKey key = getPasswordOnlyPBEKey(); -+ pbaMac.init(key, new PBEParameterSpec(salt, iterations)); -+ } -+ case AnonymousPBEKey -> { -+ SecretKey key = getPasswordSaltIterationsPBEKey(); -+ pbaMac.init(key); -+ } -+ } -+ return new BigInteger(1, pbaMac.doFinal(plainText.getBytes())); -+ } -+ -+ private BigInteger computeExpectedMac(String algorithm, Configuration conf) -+ throws Exception { -+ if (sunJCE != null) { -+ BigInteger macResult = computeMac(sunJCE, algorithm, conf); -+ if (macResult != null) { -+ return macResult; -+ } -+ // Move to assertionData as it's unlikely that any of -+ // the algorithms are available. -+ sunJCE = null; -+ } -+ // If SunJCE or the algorithm are not available, assertionData -+ // is used instead. -+ return assertionData.get(algorithm); -+ } -+ -+ private static SecretKey getPasswordOnlyPBEKey() throws Exception { -+ PBEKeySpec keySpec = new PBEKeySpec(password); -+ SecretKeyFactory skFac = SecretKeyFactory.getInstance("PBE"); -+ SecretKey skey = skFac.generateSecret(keySpec); -+ keySpec.clearPassword(); -+ return skey; -+ } -+ -+ private static SecretKey getPasswordSaltIterationsPBEKey() { -+ return new PBEKey() { -+ public byte[] getSalt() { return salt.clone(); } -+ public int getIterationCount() { return iterations; } -+ public String getAlgorithm() { return "PBE"; } -+ public String getFormat() { return "RAW"; } -+ public char[] getPassword() { return password.clone(); } -+ public byte[] getEncoded() { return null; } // unused in PBA Mac -+ }; -+ } -+ -+ private static void printByteArray(String title, BigInteger b) { -+ String repr = (b == null) ? "buffer is null" : b.toString(16); -+ System.out.println(title + ": " + repr + System.lineSeparator()); -+ } -+ -+ public static void main(String[] args) throws Exception { -+ PBAMac2 test = new PBAMac2(); -+ Provider p = Security.getProvider("SunPKCS11-NSS-FIPS"); -+ if (p != null) { -+ test.main(p); -+ } else { -+ main(test); -+ } -+ } -+} -diff --git a/test/jdk/sun/security/pkcs11/SecretKeyFactory/TestPBKD.java b/test/jdk/sun/security/pkcs11/SecretKeyFactory/TestPBKD.java -new file mode 100644 -index 00000000000..67c3cee5970 ---- /dev/null -+++ b/test/jdk/sun/security/pkcs11/SecretKeyFactory/TestPBKD.java -@@ -0,0 +1,296 @@ -+/* -+ * Copyright (c) 2022, 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. -+ * -+ * 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. -+ */ -+ -+import java.lang.reflect.Field; -+import java.lang.reflect.Method; -+import java.math.BigInteger; -+import java.security.NoSuchAlgorithmException; -+import java.security.Provider; -+import java.security.Security; -+import java.util.HashMap; -+import java.util.Map; -+ -+import javax.crypto.SecretKeyFactory; -+import javax.crypto.spec.PBEKeySpec; -+ -+/* -+ * @test -+ * @bug 9999999 -+ * @summary test key derivation on SunPKCS11's SecretKeyFactory service -+ * @requires (jdk.version.major >= 8) -+ * @library /test/lib .. -+ * @modules java.base/com.sun.crypto.provider:open -+ * @run main/othervm/timeout=30 TestPBKD -+ */ -+ -+public final class TestPBKD { -+ public static void main(String[] args) throws Exception { -+ java.security.Security.getProviders(); -+ TestPBKD2.main(args); -+ } -+} -+ -+final class TestPBKD2 extends PKCS11Test { -+ private static final char[] password = "123456".toCharArray(); -+ private static final byte[] salt = "abcdefgh".getBytes(); -+ private static final int iterations = 1000; -+ private static final String sep = -+ "========================================================================="; -+ -+ private static Provider sunJCE = Security.getProvider("SunJCE"); -+ -+ // Generated with SunJCE -+ private static final Map assertionData = -+ new HashMap<>() {{ -+ put("HmacPBESHA1", new BigInteger("5f7d1c360d1703cede76f47db" + -+ "2fa3facc62e7694", 16)); -+ put("HmacPBESHA224", new BigInteger("289563f799b708f522ab2a3" + -+ "8d283d0afa8fc1d3d227fcb9236c3a035", 16)); -+ put("HmacPBESHA256", new BigInteger("888defcf4ef37eb0647014a" + -+ "d172dd6fa3b3e9d024b962dba47608eea9b9c4b79", 16)); -+ put("HmacPBESHA384", new BigInteger("f5464b34253fadab8838d0d" + -+ "b11980c1787a99bf6f6304f2d8c942e30bada523494f9d5a0f3" + -+ "741e411de21add8b5718a8", 16)); -+ put("HmacPBESHA512", new BigInteger("18ae94337b132c68c611bc2" + -+ "e723ac24dcd44a46d900dae2dd6170380d4c34f90fef7bdeb5f" + -+ "6fddeb0d2230003e329b7a7eefcd35810d364ba95d31b68bb61" + -+ "e52", 16)); -+ put("PBEWithHmacSHA1AndAES_128", new BigInteger("fdb3dcc2e81" + -+ "244d4d56bf7ec8dd61dd7", 16)); -+ put("PBEWithHmacSHA224AndAES_128", new BigInteger("5ef9e5c6f" + -+ "df7c355f3b424233a9f24c2", 16)); -+ put("PBEWithHmacSHA256AndAES_128", new BigInteger("c5af597b0" + -+ "1b4f6baac8f62ff6f22bfb1", 16)); -+ put("PBEWithHmacSHA384AndAES_128", new BigInteger("c3208ebc5" + -+ "d6db88858988ec00153847d", 16)); -+ put("PBEWithHmacSHA512AndAES_128", new BigInteger("b27e8f7fb" + -+ "6a4bd5ebea892cd9a7f5043", 16)); -+ put("PBEWithHmacSHA1AndAES_256", new BigInteger("fdb3dcc2e81" + -+ "244d4d56bf7ec8dd61dd78a1b6fb3ad11d9ebd7f62027a2ccde" + -+ "98", 16)); -+ put("PBEWithHmacSHA224AndAES_256", new BigInteger("5ef9e5c6f" + -+ "df7c355f3b424233a9f24c2c9c41793cb0948b8ea3aac240b8d" + -+ "f64d", 16)); -+ put("PBEWithHmacSHA256AndAES_256", new BigInteger("c5af597b0" + -+ "1b4f6baac8f62ff6f22bfb1f319c3278c8b31cc616294716d4e" + -+ "ab08", 16)); -+ put("PBEWithHmacSHA384AndAES_256", new BigInteger("c3208ebc5" + -+ "d6db88858988ec00153847d5b1b7a8723640a022dc332bcaefe" + -+ "b356", 16)); -+ put("PBEWithHmacSHA512AndAES_256", new BigInteger("b27e8f7fb" + -+ "6a4bd5ebea892cd9a7f5043cefff9c38b07e599721e8d116189" + -+ "5482", 16)); -+ put("PBKDF2WithHmacSHA1", new BigInteger("fdb3dcc2e81244d4d5" + -+ "6bf7ec8dd61dd78a1b6fb3ad11d9ebd7f62027a2cc", 16)); -+ put("PBKDF2WithHmacSHA224", new BigInteger("5ef9e5c6fdf7c355" + -+ "f3b424233a9f24c2c9c41793cb0948b8ea3aac240b8df64d1a0" + -+ "736ec1c69eef1c7b2", 16)); -+ put("PBKDF2WithHmacSHA256", new BigInteger("c5af597b01b4f6ba" + -+ "ac8f62ff6f22bfb1f319c3278c8b31cc616294716d4eab080b9" + -+ "add9db34a42ceb2fea8d27adc00f4", 16)); -+ put("PBKDF2WithHmacSHA384", new BigInteger("c3208ebc5d6db888" + -+ "58988ec00153847d5b1b7a8723640a022dc332bcaefeb356995" + -+ "d076a949d35c42c7e1e1ca936c12f8dc918e497edf279a522b7" + -+ "c99580e2613846b3919af637da", 16)); -+ put("PBKDF2WithHmacSHA512", new BigInteger("b27e8f7fb6a4bd5e" + -+ "bea892cd9a7f5043cefff9c38b07e599721e8d1161895482da2" + -+ "55746844cc1030be37ba1969df10ff59554d1ac5468fa9b7297" + -+ "7bb7fd52103a0a7b488cdb8957616c3e23a16bca92120982180" + -+ "c6c11a4f14649b50d0ade3a", 16)); -+ }}; -+ -+ static interface AssertData { -+ BigInteger derive(String pbAlgo, PBEKeySpec keySpec) throws Exception; -+ } -+ -+ static final class P12PBKDAssertData implements AssertData { -+ private final int outLen; -+ private final String kdfAlgo; -+ private final int blockLen; -+ -+ P12PBKDAssertData(int outLen, String kdfAlgo, int blockLen) { -+ this.outLen = outLen; -+ this.kdfAlgo = kdfAlgo; -+ this.blockLen = blockLen; -+ } -+ -+ @Override -+ public BigInteger derive(String pbAlgo, PBEKeySpec keySpec) -+ throws Exception { -+ // Since we need to access an internal SunJCE API, we use reflection -+ Class PKCS12PBECipherCore = Class.forName( -+ "com.sun.crypto.provider.PKCS12PBECipherCore"); -+ -+ Field macKeyField = PKCS12PBECipherCore.getDeclaredField("MAC_KEY"); -+ macKeyField.setAccessible(true); -+ int MAC_KEY = (int) macKeyField.get(null); -+ -+ Method deriveMethod = PKCS12PBECipherCore.getDeclaredMethod( -+ "derive", char[].class, byte[].class, int.class, -+ int.class, int.class, String.class, int.class); -+ deriveMethod.setAccessible(true); -+ -+ return new BigInteger(1, (byte[]) deriveMethod.invoke(null, -+ keySpec.getPassword(), keySpec.getSalt(), -+ keySpec.getIterationCount(), this.outLen, -+ MAC_KEY, this.kdfAlgo, this.blockLen)); -+ } -+ } -+ -+ static final class PBKD2AssertData implements AssertData { -+ private final String kdfAlgo; -+ private final int keyLen; -+ -+ PBKD2AssertData(String kdfAlgo, int keyLen) { -+ // Key length is pinned by the algorithm name (not kdfAlgo, -+ // but the algorithm under test: PBEWithHmacSHA*AndAES_*) -+ this.kdfAlgo = kdfAlgo; -+ this.keyLen = keyLen; -+ } -+ -+ PBKD2AssertData(String kdfAlgo) { -+ // Key length is variable for the algorithm under test -+ // (kdfAlgo is the algorithm under test: PBKDF2WithHmacSHA*) -+ this(kdfAlgo, -1); -+ } -+ -+ @Override -+ public BigInteger derive(String pbAlgo, PBEKeySpec keySpec) -+ throws Exception { -+ if (this.keyLen != -1) { -+ keySpec = new PBEKeySpec( -+ keySpec.getPassword(), keySpec.getSalt(), -+ keySpec.getIterationCount(), this.keyLen); -+ } -+ if (sunJCE != null) { -+ try { -+ return new BigInteger(1, SecretKeyFactory.getInstance( -+ this.kdfAlgo, sunJCE).generateSecret(keySpec) -+ .getEncoded()); -+ } catch (NoSuchAlgorithmException e) { -+ // Move to assertionData as it's unlikely that any of -+ // the algorithms are available. -+ sunJCE = null; -+ } -+ } -+ // If SunJCE or the algorithm are not available, assertionData -+ // is used instead. -+ return assertionData.get(pbAlgo); -+ } -+ } -+ -+ public void main(Provider sunPKCS11) throws Exception { -+ System.out.println("SunPKCS11: " + sunPKCS11.getName()); -+ testWith(sunPKCS11, "HmacPBESHA1", -+ new P12PBKDAssertData(20, "SHA-1", 64)); -+ testWith(sunPKCS11, "HmacPBESHA224", -+ new P12PBKDAssertData(28, "SHA-224", 64)); -+ testWith(sunPKCS11, "HmacPBESHA256", -+ new P12PBKDAssertData(32, "SHA-256", 64)); -+ testWith(sunPKCS11, "HmacPBESHA384", -+ new P12PBKDAssertData(48, "SHA-384", 128)); -+ testWith(sunPKCS11, "HmacPBESHA512", -+ new P12PBKDAssertData(64, "SHA-512", 128)); -+ -+ testWith(sunPKCS11, "PBEWithHmacSHA1AndAES_128", -+ new PBKD2AssertData("PBKDF2WithHmacSHA1", 128)); -+ testWith(sunPKCS11, "PBEWithHmacSHA224AndAES_128", -+ new PBKD2AssertData("PBKDF2WithHmacSHA224", 128)); -+ testWith(sunPKCS11, "PBEWithHmacSHA256AndAES_128", -+ new PBKD2AssertData("PBKDF2WithHmacSHA256", 128)); -+ testWith(sunPKCS11, "PBEWithHmacSHA384AndAES_128", -+ new PBKD2AssertData("PBKDF2WithHmacSHA384", 128)); -+ testWith(sunPKCS11, "PBEWithHmacSHA512AndAES_128", -+ new PBKD2AssertData("PBKDF2WithHmacSHA512", 128)); -+ testWith(sunPKCS11, "PBEWithHmacSHA1AndAES_256", -+ new PBKD2AssertData("PBKDF2WithHmacSHA1", 256)); -+ testWith(sunPKCS11, "PBEWithHmacSHA224AndAES_256", -+ new PBKD2AssertData("PBKDF2WithHmacSHA224", 256)); -+ testWith(sunPKCS11, "PBEWithHmacSHA256AndAES_256", -+ new PBKD2AssertData("PBKDF2WithHmacSHA256", 256)); -+ testWith(sunPKCS11, "PBEWithHmacSHA384AndAES_256", -+ new PBKD2AssertData("PBKDF2WithHmacSHA384", 256)); -+ testWith(sunPKCS11, "PBEWithHmacSHA512AndAES_256", -+ new PBKD2AssertData("PBKDF2WithHmacSHA512", 256)); -+ -+ // Use 1,5 * digest size as the testing derived key length (in bits) -+ testWith(sunPKCS11, "PBKDF2WithHmacSHA1", 240, -+ new PBKD2AssertData("PBKDF2WithHmacSHA1")); -+ testWith(sunPKCS11, "PBKDF2WithHmacSHA224", 336, -+ new PBKD2AssertData("PBKDF2WithHmacSHA224")); -+ testWith(sunPKCS11, "PBKDF2WithHmacSHA256", 384, -+ new PBKD2AssertData("PBKDF2WithHmacSHA256")); -+ testWith(sunPKCS11, "PBKDF2WithHmacSHA384", 576, -+ new PBKD2AssertData("PBKDF2WithHmacSHA384")); -+ testWith(sunPKCS11, "PBKDF2WithHmacSHA512", 768, -+ new PBKD2AssertData("PBKDF2WithHmacSHA512")); -+ -+ System.out.println("TEST PASS - OK"); -+ } -+ -+ private static void testWith(Provider sunPKCS11, String algorithm, -+ AssertData assertData) throws Exception { -+ PBEKeySpec keySpec = new PBEKeySpec(password, salt, iterations); -+ testWith(sunPKCS11, algorithm, keySpec, assertData); -+ } -+ -+ private static void testWith(Provider sunPKCS11, String algorithm, -+ int keyLen, AssertData assertData) throws Exception { -+ PBEKeySpec keySpec = new PBEKeySpec(password, salt, iterations, keyLen); -+ testWith(sunPKCS11, algorithm, keySpec, assertData); -+ } -+ -+ private static void testWith(Provider sunPKCS11, String algorithm, -+ PBEKeySpec keySpec, AssertData assertData) throws Exception { -+ System.out.println(sep + System.lineSeparator() + algorithm); -+ -+ SecretKeyFactory skFac = SecretKeyFactory.getInstance( -+ algorithm, sunPKCS11); -+ BigInteger derivedKey = new BigInteger(1, -+ skFac.generateSecret(keySpec).getEncoded()); -+ printByteArray("Derived Key", derivedKey); -+ -+ BigInteger expectedDerivedKey = assertData.derive(algorithm, keySpec); -+ -+ if (!derivedKey.equals(expectedDerivedKey)) { -+ printByteArray("Expected Derived Key", expectedDerivedKey); -+ throw new Exception("Expected Derived Key did not match"); -+ } -+ } -+ -+ private static void printByteArray(String title, BigInteger b) { -+ String repr = (b == null) ? "buffer is null" : b.toString(16); -+ System.out.println(title + ": " + repr + System.lineSeparator()); -+ } -+ -+ public static void main(String[] args) throws Exception { -+ TestPBKD2 test = new TestPBKD2(); -+ Provider p = Security.getProvider("SunPKCS11-NSS-FIPS"); -+ if (p != null) { -+ test.main(p); -+ } else { -+ main(test); -+ } -+ } -+} -diff --git a/test/jdk/sun/security/pkcs11/fips/NssdbPin.java b/test/jdk/sun/security/pkcs11/fips/NssdbPin.java -new file mode 100644 -index 00000000000..ce01c655eb8 ---- /dev/null -+++ b/test/jdk/sun/security/pkcs11/fips/NssdbPin.java -@@ -0,0 +1,349 @@ -+/* -+ * Copyright (c) 2022, 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. -+ * -+ * 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. -+ */ -+ -+import java.lang.reflect.Method; -+import java.nio.charset.StandardCharsets; -+import java.nio.file.Files; -+import java.nio.file.Path; -+import java.security.KeyStore; -+import java.security.Provider; -+import java.security.Security; -+import java.util.Arrays; -+import java.util.function.Consumer; -+import java.util.List; -+import javax.crypto.Cipher; -+import javax.crypto.spec.SecretKeySpec; -+ -+import jdk.test.lib.process.Proc; -+import jdk.test.lib.util.FileUtils; -+ -+/* -+ * @test -+ * @bug 9999999 -+ * @summary -+ * Test that the fips.nssdb.path and fips.nssdb.pin properties can be used -+ * for a successful login into an NSS DB. Some additional unitary testing -+ * is then performed. This test depends on NSS modutil and must be run in -+ * FIPS mode (the SunPKCS11-NSS-FIPS security provider has to be available). -+ * @modules jdk.crypto.cryptoki/sun.security.pkcs11:+open -+ * @library /test/lib -+ * @requires (jdk.version.major >= 8) -+ * @run main/othervm/timeout=600 NssdbPin -+ * @author Martin Balao (mbalao@redhat.com) -+ */ -+ -+public final class NssdbPin { -+ -+ // Public properties and names -+ private static final String FIPS_NSSDB_PATH_PROP = "fips.nssdb.path"; -+ private static final String FIPS_NSSDB_PIN_PROP = "fips.nssdb.pin"; -+ private static final String FIPS_PROVIDER_NAME = "SunPKCS11-NSS-FIPS"; -+ private static final String NSSDB_TOKEN_NAME = -+ "NSS FIPS 140-2 Certificate DB"; -+ -+ // Data to be tested -+ private static final String[] PINS_TO_TEST = -+ new String[] { -+ "", -+ "1234567890abcdef1234567890ABCDEF\uA4F7" -+ }; -+ private static enum PropType { SYSTEM, SECURITY } -+ private static enum LoginType { IMPLICIT, EXPLICIT } -+ -+ // Internal test fields -+ private static final boolean DEBUG = true; -+ private static class TestContext { -+ String pin; -+ PropType propType; -+ Path workspace; -+ String nssdbPath; -+ Path nssdbPinFile; -+ LoginType loginType; -+ TestContext(String pin, Path workspace) { -+ this.pin = pin; -+ this.workspace = workspace; -+ this.nssdbPath = "sql:" + workspace; -+ this.loginType = LoginType.IMPLICIT; -+ } -+ } -+ -+ public static void main(String[] args) throws Throwable { -+ if (args.length == 3) { -+ // Executed by a child process. -+ mainChild(args[0], args[1], LoginType.valueOf(args[2])); -+ } else if (args.length == 0) { -+ // Executed by the parent process. -+ mainLauncher(); -+ // Test defaults -+ mainChild("sql:/etc/pki/nssdb", "", LoginType.IMPLICIT); -+ System.out.println("TEST PASS - OK"); -+ } else { -+ throw new Exception("Unexpected number of arguments."); -+ } -+ } -+ -+ private static void mainChild(String expectedPath, String expectedPin, -+ LoginType loginType) throws Throwable { -+ if (DEBUG) { -+ for (String prop : Arrays.asList(FIPS_NSSDB_PATH_PROP, -+ FIPS_NSSDB_PIN_PROP)) { -+ System.out.println(prop + " (System): " + -+ System.getProperty(prop)); -+ System.out.println(prop + " (Security): " + -+ Security.getProperty(prop)); -+ } -+ } -+ -+ /* -+ * Functional cross-test against an NSS DB generated by modutil -+ * with the same PIN. Check that we can perform a crypto operation -+ * that requires a login. The login might be explicit or implicit. -+ */ -+ Provider p = Security.getProvider(FIPS_PROVIDER_NAME); -+ if (DEBUG) { -+ System.out.println(FIPS_PROVIDER_NAME + ": " + p); -+ } -+ if (p == null) { -+ throw new Exception(FIPS_PROVIDER_NAME + " initialization failed."); -+ } -+ if (DEBUG) { -+ System.out.println("Login type: " + loginType); -+ } -+ if (loginType == LoginType.EXPLICIT) { -+ // Do the expansion to account for truncation, so C_Login in -+ // the NSS Software Token gets a UTF-8 encoded PIN. -+ byte[] pinUtf8 = expectedPin.getBytes(StandardCharsets.UTF_8); -+ char[] pinChar = new char[pinUtf8.length]; -+ for (int i = 0; i < pinChar.length; i++) { -+ pinChar[i] = (char)(pinUtf8[i] & 0xFF); -+ } -+ KeyStore.getInstance("PKCS11", p).load(null, pinChar); -+ if (DEBUG) { -+ System.out.println("Explicit login succeeded."); -+ } -+ } -+ if (DEBUG) { -+ System.out.println("Trying a crypto operation..."); -+ } -+ final int blockSize = 16; -+ Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding", p); -+ cipher.init(Cipher.ENCRYPT_MODE, -+ new SecretKeySpec(new byte[blockSize], "AES")); -+ if (cipher.doFinal(new byte[blockSize]).length != blockSize) { -+ throw new Exception("Could not perform a crypto operation."); -+ } -+ if (DEBUG) { -+ if (loginType == LoginType.IMPLICIT) { -+ System.out.println("Implicit login succeeded."); -+ } -+ System.out.println("Crypto operation after login succeeded."); -+ } -+ -+ if (loginType == LoginType.IMPLICIT) { -+ /* -+ * Additional unitary testing. Expected to succeed at this point. -+ */ -+ if (DEBUG) { -+ System.out.println("Trying unitary test..."); -+ } -+ String sysPathProp = System.getProperty(FIPS_NSSDB_PATH_PROP); -+ if (DEBUG) { -+ System.out.println("Path value (as a System property): " + -+ sysPathProp); -+ } -+ if (!expectedPath.equals(sysPathProp)) { -+ throw new Exception("Path is different than expected: " + -+ sysPathProp + " (actual) vs " + expectedPath + -+ " (expected)."); -+ } -+ Class c = Class -+ .forName("sun.security.pkcs11.FIPSTokenLoginHandler"); -+ Method m = c.getDeclaredMethod("getFipsNssdbPin"); -+ m.setAccessible(true); -+ String pin = null; -+ char[] pinChar = (char[]) m.invoke(c); -+ if (pinChar != null) { -+ byte[] pinUtf8 = new byte[pinChar.length]; -+ for (int i = 0; i < pinUtf8.length; i++) { -+ pinUtf8[i] = (byte) pinChar[i]; -+ } -+ pin = new String(pinUtf8, StandardCharsets.UTF_8); -+ } -+ if (!expectedPin.isEmpty() && !expectedPin.equals(pin) || -+ expectedPin.isEmpty() && pin != null) { -+ throw new Exception("PIN is different than expected: '" + pin + -+ "' (actual) vs '" + expectedPin + "' (expected)."); -+ } -+ if (DEBUG) { -+ System.out.println("PIN value: " + pin); -+ System.out.println("Unitary test succeeded."); -+ } -+ } -+ } -+ -+ private static void mainLauncher() throws Throwable { -+ for (String pin : PINS_TO_TEST) { -+ Path workspace = Files.createTempDirectory(null); -+ try { -+ TestContext ctx = new TestContext(pin, workspace); -+ createNSSDB(ctx); -+ { -+ ctx.loginType = LoginType.IMPLICIT; -+ for (PropType propType : PropType.values()) { -+ ctx.propType = propType; -+ pinLauncher(ctx); -+ envLauncher(ctx); -+ fileLauncher(ctx); -+ } -+ } -+ explicitLoginLauncher(ctx); -+ } finally { -+ FileUtils.deleteFileTreeWithRetry(workspace); -+ } -+ } -+ } -+ -+ private static void pinLauncher(TestContext ctx) throws Throwable { -+ launchTest(p -> {}, "pin:" + ctx.pin, ctx); -+ } -+ -+ private static void envLauncher(TestContext ctx) throws Throwable { -+ final String NSSDB_PIN_ENV_VAR = "NSSDB_PIN_ENV_VAR"; -+ launchTest(p -> p.env(NSSDB_PIN_ENV_VAR, ctx.pin), -+ "env:" + NSSDB_PIN_ENV_VAR, ctx); -+ } -+ -+ private static void fileLauncher(TestContext ctx) throws Throwable { -+ // The file containing the PIN (ctx.nssdbPinFile) was created by the -+ // generatePinFile method, called from createNSSDB. -+ launchTest(p -> {}, "file:" + ctx.nssdbPinFile, ctx); -+ } -+ -+ private static void explicitLoginLauncher(TestContext ctx) -+ throws Throwable { -+ ctx.loginType = LoginType.EXPLICIT; -+ ctx.propType = PropType.SYSTEM; -+ launchTest(p -> {}, "Invalid PIN, must be ignored", ctx); -+ } -+ -+ private static void launchTest(Consumer procCb, String pinPropVal, -+ TestContext ctx) throws Throwable { -+ if (DEBUG) { -+ System.out.println("Launching JVM with " + FIPS_NSSDB_PATH_PROP + -+ "=" + ctx.nssdbPath + " and " + FIPS_NSSDB_PIN_PROP + -+ "=" + pinPropVal); -+ } -+ Proc p = Proc.create(NssdbPin.class.getName()) -+ .args(ctx.nssdbPath, ctx.pin, ctx.loginType.name()); -+ if (ctx.propType == PropType.SYSTEM) { -+ p.prop(FIPS_NSSDB_PATH_PROP, ctx.nssdbPath); -+ p.prop(FIPS_NSSDB_PIN_PROP, pinPropVal); -+ // Make sure that Security properties defaults are not used. -+ p.secprop(FIPS_NSSDB_PATH_PROP, ""); -+ p.secprop(FIPS_NSSDB_PIN_PROP, ""); -+ } else if (ctx.propType == PropType.SECURITY) { -+ p.secprop(FIPS_NSSDB_PATH_PROP, ctx.nssdbPath); -+ pinPropVal = escapeForPropsFile(pinPropVal); -+ p.secprop(FIPS_NSSDB_PIN_PROP, pinPropVal); -+ } else { -+ throw new Exception("Unsupported property type."); -+ } -+ if (DEBUG) { -+ p.inheritIO(); -+ p.prop("java.security.debug", "sunpkcs11"); -+ p.debug(NssdbPin.class.getName()); -+ -+ // Need the launched process to connect to a debugger? -+ //System.setProperty("test.vm.opts", "-Xdebug -Xrunjdwp:" + -+ // "transport=dt_socket,address=localhost:8000,suspend=y"); -+ } else { -+ p.nodump(); -+ } -+ procCb.accept(p); -+ p.start().waitFor(0); -+ } -+ -+ private static String escapeForPropsFile(String str) throws Throwable { -+ StringBuffer sb = new StringBuffer(); -+ for (int i = 0; i < str.length(); i++) { -+ int cp = str.codePointAt(i); -+ if (Character.UnicodeBlock.of(cp) -+ == Character.UnicodeBlock.BASIC_LATIN) { -+ sb.append(Character.toChars(cp)); -+ } else { -+ sb.append("\\u").append(String.format("%04X", cp)); -+ } -+ } -+ return sb.toString(); -+ } -+ -+ private static void createNSSDB(TestContext ctx) throws Throwable { -+ ProcessBuilder pb = getModutilPB(ctx, "-create"); -+ if (DEBUG) { -+ System.out.println("Creating an NSS DB in " + ctx.workspace + -+ "..."); -+ System.out.println("cmd: " + String.join(" ", pb.command())); -+ } -+ if (pb.start().waitFor() != 0) { -+ throw new Exception("NSS DB creation failed."); -+ } -+ generatePinFile(ctx); -+ pb = getModutilPB(ctx, "-changepw", NSSDB_TOKEN_NAME, -+ "-newpwfile", ctx.nssdbPinFile.toString()); -+ if (DEBUG) { -+ System.out.println("NSS DB created."); -+ System.out.println("Changing NSS DB PIN..."); -+ System.out.println("cmd: " + String.join(" ", pb.command())); -+ } -+ if (pb.start().waitFor() != 0) { -+ throw new Exception("NSS DB PIN change failed."); -+ } -+ if (DEBUG) { -+ System.out.println("NSS DB PIN changed."); -+ } -+ } -+ -+ private static ProcessBuilder getModutilPB(TestContext ctx, String... args) -+ throws Throwable { -+ ProcessBuilder pb = new ProcessBuilder("modutil", "-force"); -+ List pbCommand = pb.command(); -+ if (args != null) { -+ pbCommand.addAll(Arrays.asList(args)); -+ } -+ pbCommand.add("-dbdir"); -+ pbCommand.add(ctx.nssdbPath); -+ if (DEBUG) { -+ pb.inheritIO(); -+ } else { -+ pb.redirectError(ProcessBuilder.Redirect.INHERIT); -+ } -+ return pb; -+ } -+ -+ private static void generatePinFile(TestContext ctx) throws Throwable { -+ ctx.nssdbPinFile = Files.createTempFile(ctx.workspace, null, null); -+ Files.writeString(ctx.nssdbPinFile, ctx.pin + System.lineSeparator() + -+ "2nd line with garbage"); -+ } -+} -diff --git a/test/jdk/sun/security/pkcs11/fips/VerifyMissingAttributes.java b/test/jdk/sun/security/pkcs11/fips/VerifyMissingAttributes.java -new file mode 100644 -index 00000000000..87f1ad04505 ---- /dev/null -+++ b/test/jdk/sun/security/pkcs11/fips/VerifyMissingAttributes.java -@@ -0,0 +1,77 @@ -+/* -+ * Copyright (c) 2022, 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. -+ * -+ * 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. -+ */ -+ -+import java.security.Provider; -+import java.security.Security; -+ -+/* -+ * @test -+ * @bug 9999999 -+ * @requires (jdk.version.major >= 8) -+ * @run main/othervm/timeout=30 VerifyMissingAttributes -+ * @author Martin Balao (mbalao@redhat.com) -+ */ -+ -+public final class VerifyMissingAttributes { -+ -+ private static final String[] svcAlgImplementedIn = { -+ "AlgorithmParameterGenerator.DSA", -+ "AlgorithmParameters.DSA", -+ "CertificateFactory.X.509", -+ "KeyStore.JKS", -+ "KeyStore.CaseExactJKS", -+ "KeyStore.DKS", -+ "CertStore.Collection", -+ "CertStore.com.sun.security.IndexedCollection" -+ }; -+ -+ public static void main(String[] args) throws Throwable { -+ Provider sunProvider = Security.getProvider("SUN"); -+ for (String svcAlg : svcAlgImplementedIn) { -+ String filter = svcAlg + " ImplementedIn:Software"; -+ doQuery(sunProvider, filter); -+ } -+ if (Double.parseDouble( -+ System.getProperty("java.specification.version")) >= 17) { -+ String filter = "KeyFactory.RSASSA-PSS SupportedKeyClasses:" + -+ "java.security.interfaces.RSAPublicKey" + -+ "|java.security.interfaces.RSAPrivateKey"; -+ doQuery(Security.getProvider("SunRsaSign"), filter); -+ } -+ System.out.println("TEST PASS - OK"); -+ } -+ -+ private static void doQuery(Provider expectedProvider, String filter) -+ throws Exception { -+ if (expectedProvider == null) { -+ throw new Exception("Provider not found."); -+ } -+ Provider[] providers = Security.getProviders(filter); -+ if (providers == null || providers.length != 1 || -+ providers[0] != expectedProvider) { -+ throw new Exception("Failure retrieving the provider with this" + -+ " query: " + filter); -+ } -+ } -+} diff --git a/fips-17u-e893be00150.patch b/fips-17u-e893be00150.patch new file mode 100644 index 0000000..e69de29 diff --git a/java-17-openjdk.spec b/java-17-openjdk.spec index 1ed746e..21b85e8 100644 --- a/java-17-openjdk.spec +++ b/java-17-openjdk.spec @@ -362,7 +362,7 @@ # Define IcedTea version used for SystemTap tapsets and desktop file %global icedteaver 6.0.0pre00-c848b93a8598 # Define current Git revision for the FIPS support patches -%global fipsver d63771ea660 +%global fipsver e893be00150 %global javaver %{featurever} %global newjavaver %{featurever}.%{interimver}.%{updatever}.%{patchver} @@ -2486,6 +2486,11 @@ require "copy_jdk_configs.lua" %endif %changelog +* Mon Jul 8 2024 Thomas Fitzsimmons - 1:17.0.12.0.6-0.1.ea +- Delete fips-17u-d63771ea660.patch +- Add fips-17u-e893be00150.patch +- Update fipsver to e893be00150 + * Mon Jul 8 2024 Anton Bobrov - 1:17.0.12.0.6-0.1.ea - generate_source_tarball.sh: Use tar exclude options for VCS files - generate_source_tarball.sh: Improve VCS exclusion