From 47d1d31f3282fe81b7a9a0520ec65083d4f70675 Mon Sep 17 00:00:00 2001 From: Andrew Hughes Date: Thu, 10 Aug 2023 01:05:03 +0100 Subject: [PATCH] Update to jdk-18.0.2 release Update release notes to actually reflect OpenJDK 18 Support JVM variant zero following JDK-8273494 no longer installing Zero's libjvm.so in the server directory Rebase FIPS patches from fips-18u branch Rebase RH1648249 nss.cfg patch so it applies after the FIPS patch Drop now unused fresh_libjvm, build_hotspot_first and bootjdk variables, as we don't build a JDK here Drop tzdata patches added for 17.0.7 which will eventually appear in the upstream tarball when we reach OpenJDK 21 Disable tzdata tests until we are on the latest JDK and things are back in sync Adjust rh1684077-openjdk_should_depend_on_pcsc-lite-libs_instead_of_pcsc-lite-devel.patch Add new slave jwebserver and corresponding manpage Add javaver- and origin-specific javadoc and javadoczip alternatives. Use empty nss.fips.cfg until it is again available via the FIPS patch Related: RHEL-12996 --- .gitignore | 4 + fips-17u-bf363eecce3.patch | 7248 ----------------- fips-18u-60131cc7271.patch | 3682 +++++++++ generate_source_tarball.sh | 2 +- java-21-openjdk-portable.specfile | 86 +- java-21-openjdk.spec | 143 +- jdk8274864-remove_amman_cairo_hacks.patch | 53 - jdk8305113-tzdata2023c.patch | 1098 --- ...ut_nss_cfg_provider_to_java_security.patch | 8 +- ...lite-libs_instead_of_pcsc-lite-devel.patch | 20 +- sources | 2 +- 11 files changed, 3855 insertions(+), 8491 deletions(-) delete mode 100644 fips-17u-bf363eecce3.patch create mode 100644 fips-18u-60131cc7271.patch delete mode 100644 jdk8274864-remove_amman_cairo_hacks.patch delete mode 100644 jdk8305113-tzdata2023c.patch diff --git a/.gitignore b/.gitignore index caa7737..9cb9e7f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,6 @@ /openjdk-jdk17u-jdk-17.0.7+7.tar.xz /tapsets-icedtea-6.0.0pre00-c848b93a8598.tar.xz +/openjdk-jdk18u-jdk-18.0.1+0.tar.xz +/openjdk-jdk18u-jdk-18.0.1+10.tar.xz +/openjdk-jdk18u-jdk-18.0.1.1+2.tar.xz +/openjdk-jdk18u-jdk-18.0.2+9.tar.xz diff --git a/fips-17u-bf363eecce3.patch b/fips-17u-bf363eecce3.patch deleted file mode 100644 index cd8565c..0000000 --- a/fips-17u-bf363eecce3.patch +++ /dev/null @@ -1,7248 +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 a65d91ee974..a8f054c1397 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 9b69072280e..5696b904979 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"; -@@ -136,9 +141,7 @@ abstract class P11Key implements Key, Length { - this.tokenObject = tokenObject; - this.sensitive = sensitive; - this.extractable = extractable; -- char[] tokenLabel = this.token.tokenInfo.label; -- boolean isNSS = (tokenLabel[0] == 'N' && tokenLabel[1] == 'S' -- && tokenLabel[2] == 'S'); -+ boolean isNSS = P11Util.isNSS(this.token); - boolean extractKeyInfo = (!DISABLE_NATIVE_KEYS_EXTRACTION && isNSS && - extractable && !tokenObject); - this.keyIDHolder = new NativeKeyHolder(this, keyID, session, -@@ -379,7 +382,9 @@ abstract class P11Key implements Key, Length { - new CK_ATTRIBUTE(CKA_SENSITIVE), - new CK_ATTRIBUTE(CKA_EXTRACTABLE), - }); -- if (attributes[1].getBoolean() || (attributes[2].getBoolean() == false)) { -+ boolean exportable = plainKeySupportEnabled && !algorithm.equals("DH"); -+ if (!exportable && (attributes[1].getBoolean() || -+ (attributes[2].getBoolean() == false))) { - return new P11PrivateKey - (session, keyID, algorithm, keyLength, attributes); - } else { -@@ -461,7 +466,8 @@ abstract class P11Key implements Key, Length { - } - public String getFormat() { - token.ensureValid(); -- if (sensitive || (extractable == false)) { -+ if (!plainKeySupportEnabled && -+ (sensitive || (extractable == false))) { - 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 9858a5faedf..e63585486d9 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-18u-60131cc7271.patch b/fips-18u-60131cc7271.patch new file mode 100644 index 0000000..f807876 --- /dev/null +++ b/fips-18u-60131cc7271.patch @@ -0,0 +1,3682 @@ +diff --git a/make/autoconf/lib-sysconf.m4 b/make/autoconf/lib-sysconf.m4 +new file mode 100644 +index 00000000000..b2b1c1787da +--- /dev/null ++++ b/make/autoconf/lib-sysconf.m4 +@@ -0,0 +1,84 @@ ++# ++# 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([whether to use 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) ++]) +diff --git a/make/autoconf/libraries.m4 b/make/autoconf/libraries.m4 +index 8e4012910d8..f2a178b5734 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 +@@ -102,6 +103,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 bc13f30e5f1..04cb12f2763 100644 +--- a/make/autoconf/spec.gmk.in ++++ b/make/autoconf/spec.gmk.in +@@ -843,6 +843,10 @@ INSTALL_SYSCONFDIR=@sysconfdir@ + # Libraries + # + ++USE_SYSCONF_NSS:=@USE_SYSCONF_NSS@ ++NSS_LIBS:=@NSS_LIBS@ ++NSS_CFLAGS:=@NSS_CFLAGS@ ++ + USE_EXTERNAL_LCMS:=@USE_EXTERNAL_LCMS@ + LCMS_CFLAGS:=@LCMS_CFLAGS@ + LCMS_LIBS:=@LCMS_LIBS@ +diff --git a/make/modules/java.base/Lib.gmk b/make/modules/java.base/Lib.gmk +index eee488607f2..3c095802426 100644 +--- a/make/modules/java.base/Lib.gmk ++++ b/make/modules/java.base/Lib.gmk +@@ -164,6 +164,31 @@ 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 ++ ++ifeq ($(OPENJDK_BUILD_OS), linux) ++ $(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) ++endif ++ + ################################################################################ + # Create the symbols file for static builds. + +diff --git a/src/java.base/linux/native/libsystemconf/systemconf.c b/src/java.base/linux/native/libsystemconf/systemconf.c +new file mode 100644 +index 00000000000..8dcb7d9073f +--- /dev/null ++++ b/src/java.base/linux/native/libsystemconf/systemconf.c +@@ -0,0 +1,224 @@ ++/* ++ * 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 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); ++ } ++} +diff --git a/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java b/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java +index a020e1c15d8..6d459fdec01 100644 +--- a/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java ++++ b/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java +@@ -31,6 +31,7 @@ import java.security.SecureRandom; + import java.security.PrivilegedAction; + import java.util.HashMap; + import java.util.List; ++import jdk.internal.access.SharedSecrets; + import static sun.security.util.SecurityConstants.PROVIDER_VER; + import static sun.security.util.SecurityProviderConstants.*; + +@@ -78,6 +79,10 @@ import static sun.security.util.SecurityProviderConstants.*; + + public final class SunJCE extends Provider { + ++ private static final boolean systemFipsEnabled = ++ SharedSecrets.getJavaSecuritySystemConfiguratorAccess() ++ .isSystemFipsEnabled(); ++ + @java.io.Serial + private static final long serialVersionUID = 6812507587804302833L; + +@@ -143,285 +148,287 @@ public final class SunJCE extends Provider { + void putEntries() { + // reuse attribute map and reset before each reuse + HashMap 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 +@@ -531,197 +540,199 @@ public final class SunJCE extends Provider { + psA("AlgorithmParameters", "ChaCha20-Poly1305", + "com.sun.crypto.provider.ChaCha20Poly1305Parameters", null); + +- /* +- * Key factories +- */ +- psA("KeyFactory", "DiffieHellman", +- "com.sun.crypto.provider.DHKeyFactory", +- null); +- +- /* +- * Secret-key factories +- */ +- ps("SecretKeyFactory", "DES", +- "com.sun.crypto.provider.DESKeyFactory"); +- +- psA("SecretKeyFactory", "DESede", +- "com.sun.crypto.provider.DESedeKeyFactory", null); +- +- psA("SecretKeyFactory", "PBEWithMD5AndDES", +- "com.sun.crypto.provider.PBEKeyFactory$PBEWithMD5AndDES", +- null); +- +- /* +- * Internal in-house crypto algorithm used for +- * the JCEKS keystore type. Since this was developed +- * internally, there isn't an OID corresponding to this +- * algorithm. +- */ +- ps("SecretKeyFactory", "PBEWithMD5AndTripleDES", +- "com.sun.crypto.provider.PBEKeyFactory$PBEWithMD5AndTripleDES"); +- +- psA("SecretKeyFactory", "PBEWithSHA1AndDESede", +- "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndDESede", +- null); +- +- psA("SecretKeyFactory", "PBEWithSHA1AndRC2_40", +- "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndRC2_40", +- null); +- +- psA("SecretKeyFactory", "PBEWithSHA1AndRC2_128", +- "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndRC2_128", +- null); +- +- psA("SecretKeyFactory", "PBEWithSHA1AndRC4_40", +- "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndRC4_40", +- null); +- +- psA("SecretKeyFactory", "PBEWithSHA1AndRC4_128", +- "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndRC4_128", +- null); +- +- ps("SecretKeyFactory", "PBEWithHmacSHA1AndAES_128", +- "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA1AndAES_128"); +- +- ps("SecretKeyFactory", "PBEWithHmacSHA224AndAES_128", +- "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA224AndAES_128"); +- +- ps("SecretKeyFactory", "PBEWithHmacSHA256AndAES_128", +- "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA256AndAES_128"); +- +- ps("SecretKeyFactory", "PBEWithHmacSHA384AndAES_128", +- "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA384AndAES_128"); +- +- ps("SecretKeyFactory", "PBEWithHmacSHA512AndAES_128", +- "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA512AndAES_128"); +- +- ps("SecretKeyFactory", "PBEWithHmacSHA1AndAES_256", +- "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA1AndAES_256"); +- +- ps("SecretKeyFactory", "PBEWithHmacSHA224AndAES_256", +- "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA224AndAES_256"); +- +- ps("SecretKeyFactory", "PBEWithHmacSHA256AndAES_256", +- "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA256AndAES_256"); +- +- ps("SecretKeyFactory", "PBEWithHmacSHA384AndAES_256", +- "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA384AndAES_256"); +- +- 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) { ++ /* ++ * Key factories ++ */ ++ psA("KeyFactory", "DiffieHellman", ++ "com.sun.crypto.provider.DHKeyFactory", ++ null); ++ ++ /* ++ * Secret-key factories ++ */ ++ ps("SecretKeyFactory", "DES", ++ "com.sun.crypto.provider.DESKeyFactory"); ++ ++ psA("SecretKeyFactory", "DESede", ++ "com.sun.crypto.provider.DESedeKeyFactory", null); ++ ++ psA("SecretKeyFactory", "PBEWithMD5AndDES", ++ "com.sun.crypto.provider.PBEKeyFactory$PBEWithMD5AndDES", ++ null); ++ ++ /* ++ * Internal in-house crypto algorithm used for ++ * the JCEKS keystore type. Since this was developed ++ * internally, there isn't an OID corresponding to this ++ * algorithm. ++ */ ++ ps("SecretKeyFactory", "PBEWithMD5AndTripleDES", ++ "com.sun.crypto.provider.PBEKeyFactory$PBEWithMD5AndTripleDES"); ++ ++ psA("SecretKeyFactory", "PBEWithSHA1AndDESede", ++ "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndDESede", ++ null); ++ ++ psA("SecretKeyFactory", "PBEWithSHA1AndRC2_40", ++ "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndRC2_40", ++ null); ++ ++ psA("SecretKeyFactory", "PBEWithSHA1AndRC2_128", ++ "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndRC2_128", ++ null); ++ ++ psA("SecretKeyFactory", "PBEWithSHA1AndRC4_40", ++ "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndRC4_40", ++ null); ++ ++ psA("SecretKeyFactory", "PBEWithSHA1AndRC4_128", ++ "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndRC4_128", ++ null); ++ ++ ps("SecretKeyFactory", "PBEWithHmacSHA1AndAES_128", ++ "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA1AndAES_128"); ++ ++ ps("SecretKeyFactory", "PBEWithHmacSHA224AndAES_128", ++ "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA224AndAES_128"); ++ ++ ps("SecretKeyFactory", "PBEWithHmacSHA256AndAES_128", ++ "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA256AndAES_128"); ++ ++ ps("SecretKeyFactory", "PBEWithHmacSHA384AndAES_128", ++ "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA384AndAES_128"); ++ ++ ps("SecretKeyFactory", "PBEWithHmacSHA512AndAES_128", ++ "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA512AndAES_128"); ++ ++ ps("SecretKeyFactory", "PBEWithHmacSHA1AndAES_256", ++ "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA1AndAES_256"); ++ ++ ps("SecretKeyFactory", "PBEWithHmacSHA224AndAES_256", ++ "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA224AndAES_256"); ++ ++ ps("SecretKeyFactory", "PBEWithHmacSHA256AndAES_256", ++ "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA256AndAES_256"); ++ ++ ps("SecretKeyFactory", "PBEWithHmacSHA384AndAES_256", ++ "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA384AndAES_256"); ++ ++ 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); ++ } + } + + // 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 2ee706c2448..8f4c44a1436 100644 +--- a/src/java.base/share/classes/java/security/Security.java ++++ b/src/java.base/share/classes/java/security/Security.java +@@ -32,6 +32,7 @@ import java.net.URL; + + 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; +@@ -47,12 +48,20 @@ import sun.security.jca.*; + * implementation-specific location, which is typically the properties file + * {@code conf/security/java.security} in the Java installation directory. + * ++ *

Additional default values of security properties are read from a ++ * system-specific location, if available.

++ * + * @author Benjamin Renaud + * @since 1.1 + */ + + 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"); +@@ -67,6 +76,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, +@@ -84,6 +106,7 @@ public final class Security { + props = new Properties(); + boolean loadedProps = false; + boolean overrideAll = false; ++ boolean systemSecPropsEnabled = false; + + // first load the system properties file + // to determine the value of security.overridePropertiesFile +@@ -99,6 +122,7 @@ public final class Security { + if (sdebug != null) { + sdebug.println("reading security properties file: " + + propFile); ++ sdebug.println(props.toString()); + } + } catch (IOException e) { + if (sdebug != null) { +@@ -193,6 +217,61 @@ public final class Security { + } + } + ++ 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."); ++ } ++ } ++ ++ // FIPS support depends on the contents of java.security so ++ // ensure it has loaded first ++ if (loadedProps && 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."); ++ } ++ } + } + + /* +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..98ffced455b +--- /dev/null ++++ b/src/java.base/share/classes/java/security/SystemConfigurator.java +@@ -0,0 +1,249 @@ ++/* ++ * 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) { ++ boolean systemSecPropsLoaded = false; ++ ++ try (BufferedInputStream bis = ++ new BufferedInputStream( ++ new FileInputStream(CRYPTO_POLICIES_JAVA_CONFIG))) { ++ props.load(bis); ++ systemSecPropsLoaded = true; ++ if (sdebug != null) { ++ sdebug.println("reading system security properties file " + ++ CRYPTO_POLICIES_JAVA_CONFIG); ++ sdebug.println(props.toString()); ++ } ++ } catch (IOException e) { ++ if (sdebug != null) { ++ sdebug.println("unable to load security properties from " + ++ CRYPTO_POLICIES_JAVA_CONFIG); ++ e.printStackTrace(); ++ } ++ } ++ return systemSecPropsLoaded; ++ } ++ ++ /* ++ * 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 1e98e727b79..a79ae218d92 100644 +--- a/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java ++++ b/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java +@@ -39,6 +39,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 +@@ -80,6 +81,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; +@@ -441,4 +443,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 5fbaa8950e8..218dee0065d 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.net, +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..709d32912ca 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,99 +99,101 @@ 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); +- +- attrs.remove("KeySize"); ++ 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); + +- 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 +- */ +- attrs.clear(); +- attrs.put("ImplementedIn", "Software"); +- attrs.put("KeySize", "2048"); // for DSA KPG and APG only ++ /* ++ * 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"); ++ /* ++ * Key Pair Generator engines ++ */ ++ attrs.clear(); ++ 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); ++ String dsaKPGImplClass = "sun.security.provider.DSAKeyPairGenerator$"; ++ dsaKPGImplClass += (useLegacyDSA? "Legacy" : "Current"); ++ addWithAlias(p, "KeyPairGenerator", "DSA", dsaKPGImplClass, attrs); ++ } + + /* + * Algorithm Parameter Generator engines +@@ -201,40 +208,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..225517ac69b 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, +@@ -56,49 +61,58 @@ public final class SunRsaSignEntries { + // start populating content using the specified provider + // common attribute map + HashMap attrs = new HashMap<>(3); +- attrs.put("SupportedKeyClasses", +- "java.security.interfaces.RSAPublicKey" + +- "|java.security.interfaces.RSAPrivateKey"); ++ if (!systemFipsEnabled) { ++ attrs.put("SupportedKeyClasses", ++ "java.security.interfaces.RSAPublicKey" + ++ "|java.security.interfaces.RSAPrivateKey"); ++ } + + add(p, "KeyFactory", "RSA", + "sun.security.rsa.RSAKeyFactory$Legacy", + getAliases("PKCS1"), null); +- add(p, "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/ssl/SSLContextImpl.java b/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java +index 6ffdfeda18d..775b185fb06 100644 +--- a/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java ++++ b/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java +@@ -32,6 +32,7 @@ import java.security.cert.*; + import java.util.*; + import java.util.concurrent.locks.ReentrantLock; + import javax.net.ssl.*; ++import jdk.internal.access.SharedSecrets; + import sun.security.action.GetPropertyAction; + import sun.security.provider.certpath.AlgorithmChecker; + import sun.security.validator.Validator; +@@ -536,22 +537,40 @@ public abstract class SSLContextImpl extends SSLContextSpi { + private static final List serverDefaultCipherSuites; + + static { +- supportedProtocols = Arrays.asList( +- ProtocolVersion.TLS13, +- ProtocolVersion.TLS12, +- ProtocolVersion.TLS11, +- ProtocolVersion.TLS10, +- ProtocolVersion.SSL30, +- ProtocolVersion.SSL20Hello +- ); +- +- serverDefaultProtocols = getAvailableProtocols( +- new ProtocolVersion[] { +- ProtocolVersion.TLS13, +- ProtocolVersion.TLS12, +- ProtocolVersion.TLS11, +- ProtocolVersion.TLS10 +- }); ++ if (SharedSecrets.getJavaSecuritySystemConfiguratorAccess() ++ .isSystemFipsEnabled()) { ++ // RH1860986: TLSv1.3 key derivation not supported with ++ // the Security Providers available in system FIPS mode. ++ supportedProtocols = Arrays.asList( ++ ProtocolVersion.TLS12, ++ ProtocolVersion.TLS11, ++ ProtocolVersion.TLS10 ++ ); ++ ++ serverDefaultProtocols = getAvailableProtocols( ++ new ProtocolVersion[] { ++ ProtocolVersion.TLS12, ++ ProtocolVersion.TLS11, ++ ProtocolVersion.TLS10 ++ }); ++ } else { ++ supportedProtocols = Arrays.asList( ++ ProtocolVersion.TLS13, ++ ProtocolVersion.TLS12, ++ ProtocolVersion.TLS11, ++ ProtocolVersion.TLS10, ++ ProtocolVersion.SSL30, ++ ProtocolVersion.SSL20Hello ++ ); ++ ++ serverDefaultProtocols = getAvailableProtocols( ++ new ProtocolVersion[] { ++ ProtocolVersion.TLS13, ++ ProtocolVersion.TLS12, ++ ProtocolVersion.TLS11, ++ ProtocolVersion.TLS10 ++ }); ++ } + + supportedCipherSuites = getApplicableSupportedCipherSuites( + supportedProtocols); +@@ -842,12 +861,23 @@ public abstract class SSLContextImpl extends SSLContextSpi { + ProtocolVersion[] candidates; + if (refactored.isEmpty()) { + // Client and server use the same default protocols. +- candidates = new ProtocolVersion[] { +- ProtocolVersion.TLS13, +- ProtocolVersion.TLS12, +- ProtocolVersion.TLS11, +- ProtocolVersion.TLS10 +- }; ++ if (SharedSecrets.getJavaSecuritySystemConfiguratorAccess() ++ .isSystemFipsEnabled()) { ++ // RH1860986: TLSv1.3 key derivation not supported with ++ // the Security Providers available in system FIPS mode. ++ candidates = new ProtocolVersion[] { ++ ProtocolVersion.TLS12, ++ ProtocolVersion.TLS11, ++ ProtocolVersion.TLS10 ++ }; ++ } else { ++ candidates = new ProtocolVersion[] { ++ ProtocolVersion.TLS13, ++ ProtocolVersion.TLS12, ++ ProtocolVersion.TLS11, ++ ProtocolVersion.TLS10 ++ }; ++ } + } else { + // Use the customized TLS protocols. + candidates = +diff --git a/src/java.base/share/classes/sun/security/ssl/SunJSSE.java b/src/java.base/share/classes/sun/security/ssl/SunJSSE.java +index 894e26dfad8..8b16378b96b 100644 +--- a/src/java.base/share/classes/sun/security/ssl/SunJSSE.java ++++ b/src/java.base/share/classes/sun/security/ssl/SunJSSE.java +@@ -27,6 +27,8 @@ package sun.security.ssl; + + import java.security.*; + import java.util.*; ++ ++import jdk.internal.access.SharedSecrets; + import static sun.security.util.SecurityConstants.PROVIDER_VER; + + /** +@@ -102,8 +104,13 @@ public class SunJSSE extends java.security.Provider { + "sun.security.ssl.SSLContextImpl$TLS11Context", null, null); + ps("SSLContext", "TLSv1.2", + "sun.security.ssl.SSLContextImpl$TLS12Context", null, null); +- ps("SSLContext", "TLSv1.3", +- "sun.security.ssl.SSLContextImpl$TLS13Context", null, null); ++ if (!SharedSecrets.getJavaSecuritySystemConfiguratorAccess() ++ .isSystemFipsEnabled()) { ++ // RH1860986: TLSv1.3 key derivation not supported with ++ // the Security Providers available in system FIPS mode. ++ ps("SSLContext", "TLSv1.3", ++ "sun.security.ssl.SSLContextImpl$TLS13Context", null, null); ++ } + ps("SSLContext", "TLS", + "sun.security.ssl.SSLContextImpl$TLSContext", + List.of("SSL"), null); +diff --git a/src/java.base/share/conf/security/java.security b/src/java.base/share/conf/security/java.security +index 91b3a01ee57..33f9fdc6f84 100644 +--- a/src/java.base/share/conf/security/java.security ++++ b/src/java.base/share/conf/security/java.security +@@ -79,6 +79,16 @@ security.provider.tbd=Apple + #endif + security.provider.tbd=SunPKCS11 + ++# ++# Security providers used when FIPS mode support is active ++# ++fips.provider.1=SunPKCS11 ${java.home}/conf/security/nss.fips.cfg ++fips.provider.2=SUN ++fips.provider.3=SunEC ++fips.provider.4=SunJSSE ++fips.provider.5=SunJCE ++fips.provider.6=SunRsaSign ++ + # + # A list of preferred providers for specific algorithms. These providers will + # be searched for matching algorithms before the list of registered providers. +@@ -289,6 +299,11 @@ policy.ignoreIdentityScope=false + # + keystore.type=pkcs12 + ++# ++# Default keystore type used when global crypto-policies are set to FIPS. ++# ++fips.keystore.type=PKCS11 ++ + # + # Controls compatibility mode for JKS and PKCS12 keystore types. + # +@@ -326,6 +341,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/lib/security/default.policy b/src/java.base/share/lib/security/default.policy +index b22f26947af..3ee2ce6ea88 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.*"; +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..187be7295f3 +--- /dev/null ++++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/FIPSKeyImporter.java +@@ -0,0 +1,490 @@ ++/* ++ * 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.DHPrivateKeySpec; ++import javax.crypto.spec.IvParameterSpec; ++ ++import sun.security.jca.JCAUtil; ++import sun.security.pkcs11.TemplateManager; ++import sun.security.pkcs11.wrapper.CK_ATTRIBUTE; ++import sun.security.pkcs11.wrapper.CK_MECHANISM; ++import static sun.security.pkcs11.wrapper.PKCS11Constants.*; ++import static sun.security.pkcs11.wrapper.PKCS11Exception.RV.*; ++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(); ++ ++ private static volatile KeyFactory DHKF = null; ++ private static final ReentrantLock DHKFLock = new ReentrantLock(); ++ ++ static Long importKey(SunPKCS11 sunPKCS11, long hSession, CK_ATTRIBUTE[] attributes) ++ throws PKCS11Exception { ++ long keyID = -1; ++ Token token = sunPKCS11.getToken(); ++ if (debug != null) { ++ debug.println("Private or Secret key will be imported in" + ++ " system FIPS mode."); ++ } ++ if (importerKey == null) { ++ importerKeyLock.lock(); ++ try { ++ if (importerKey == null) { ++ if (importerKeyMechanism == null) { ++ // Importer Key creation has not been tried yet. Try it. ++ createImporterKey(token); ++ } ++ if (importerKey == null || importerCipher == null) { ++ if (debug != null) { ++ debug.println("Importer Key could not be" + ++ " generated."); ++ } ++ throw new PKCS11Exception(CKR_GENERAL_ERROR, ++ " 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 (keyType == CKK_DH) { ++ if (debug != null) { ++ debug.println("Importing a Diffie-Hellman private key..."); ++ } ++ if (DHKF == null) { ++ DHKFLock.lock(); ++ try { ++ if (DHKF == null) { ++ DHKF = KeyFactory.getInstance( ++ "DH", P11Util.getSunJceProvider()); ++ } ++ } finally { ++ DHKFLock.unlock(); ++ } ++ } ++ DHPrivateKeySpec spec = new DHPrivateKeySpec ++ (((v = attrsMap.get(CKA_VALUE).getBigInteger()) != null) ++ ? v : BigInteger.ZERO, ++ ((v = attrsMap.get(CKA_PRIME).getBigInteger()) != null) ++ ? v : BigInteger.ZERO, ++ ((v = attrsMap.get(CKA_BASE).getBigInteger()) != null) ++ ? v : BigInteger.ZERO); ++ keyBytes = DHKF.generatePrivate(spec).getEncoded(); ++ if (token.config.getNssNetscapeDbWorkaround() && ++ attrsMap.get(CKA_NETSCAPE_DB) == null) { ++ attrsMap.put(CKA_NETSCAPE_DB, ++ new CK_ATTRIBUTE(CKA_NETSCAPE_DB, BigInteger.ZERO)); ++ } ++ } else { ++ if (debug != null) { ++ debug.println("Unrecognized private key type."); ++ } ++ throw new PKCS11Exception(CKR_GENERAL_ERROR, ++ " 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/P11Key.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java +index bf0c5f2ba84..a4daed24b82 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"; +@@ -392,8 +397,9 @@ abstract class P11Key implements Key, Length { + new CK_ATTRIBUTE(CKA_EXTRACTABLE), + }); + +- boolean keySensitive = (attrs[0].getBoolean() || +- attrs[1].getBoolean() || !attrs[2].getBoolean()); ++ boolean keySensitive = (!plainKeySupportEnabled && ++ (attrs[0].getBoolean() || ++ attrs[1].getBoolean() || !attrs[2].getBoolean())); + + switch (algorithm) { + case "RSA": +@@ -448,7 +454,8 @@ abstract class P11Key implements Key, Length { + + public String getFormat() { + token.ensureValid(); +- if (sensitive || (extractable == false)) { ++ if (!plainKeySupportEnabled && ++ (sensitive || (extractable == false))) { + return null; + } else { + return "RAW"; +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 9cdbdfa9d6b..ea18bdb82a3 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,6 +45,7 @@ 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; +@@ -62,6 +66,37 @@ import static sun.security.pkcs11.wrapper.PKCS11Exception.RV.*; + */ + 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 long serialVersionUID = -1354835039035306505L; + + static final Debug debug = Debug.getInstance("sunpkcs11"); +@@ -326,9 +361,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()); ++ tmpPKCS11 = PKCS11.getInstance( ++ library, functionList, initArgs, ++ config.getOmitInitialize(), fipsKeyImporter, ++ fipsKeyExporter); + } catch (PKCS11Exception e) { + if (debug != null) { + debug.println("Multi-threaded initialization failed: " + e); +@@ -343,8 +388,9 @@ public final class SunPKCS11 extends AuthProvider { + } else { + initArgs.flags = 0; + } +- tmpPKCS11 = PKCS11.getInstance(library, functionList, initArgs, +- config.getOmitInitialize()); ++ tmpPKCS11 = PKCS11.getInstance(library, ++ functionList, initArgs, config.getOmitInitialize(), fipsKeyImporter, ++ fipsKeyExporter); + } + p11 = tmpPKCS11; + +@@ -384,6 +430,24 @@ public final class SunPKCS11 extends AuthProvider { + if (nssModule != null) { + nssModule.setProvider(this); + } ++ if (systemFipsEnabled) { ++ // The NSS Software Token in FIPS 140-2 mode requires a user ++ // login for most operations. See sftk_fipsCheck. The NSS DB ++ // (/etc/pki/nssdb) PIN is empty. ++ Session session = null; ++ try { ++ session = token.getOpSession(); ++ p11.C_Login(session.id(), CKU_USER, new char[] {}); ++ } catch (PKCS11Exception p11e) { ++ if (debug != null) { ++ debug.println("Error during token login: " + ++ p11e.getMessage()); ++ } ++ throw p11e; ++ } finally { ++ token.releaseSession(session); ++ } ++ } + } catch (Exception e) { + if (config.getHandleStartupErrors() == Config.ERR_IGNORE_ALL) { + throw new UnsupportedOperationException +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 f87690bc24f..79408353609 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; +@@ -167,18 +170,43 @@ public class PKCS11 { + return version; + } + ++ /* ++ * 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 { +@@ -1971,4 +1999,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 { ++ 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 { ++ 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/PKCS11Exception.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11Exception.java +index ad2ffc8623b..5441fdecea0 100644 +--- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11Exception.java ++++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11Exception.java +@@ -190,6 +190,14 @@ public class PKCS11Exception extends Exception { + return "0x" + Functions.toFullHexString((int)errorCode); + } + ++ /** ++ * Constructor taking the error code from the RV enum and ++ * extra info for error message. ++ */ ++ public PKCS11Exception(RV errorEnum, String extraInfo) { ++ this(errorEnum.value, extraInfo); ++ } ++ + /** + * Constructor taking the error code (the CKR_* constants in PKCS#11) and + * extra info for error message. +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/generate_source_tarball.sh b/generate_source_tarball.sh index d32c8d2..35ac458 100755 --- a/generate_source_tarball.sh +++ b/generate_source_tarball.sh @@ -38,7 +38,7 @@ set -e OPENJDK_URL_DEFAULT=https://github.com COMPRESSION_DEFAULT=xz # Corresponding IcedTea version -ICEDTEA_VERSION=12.0 +ICEDTEA_VERSION=13.0 if [ "x$1" = "xhelp" ] ; then echo -e "Behaviour may be specified by setting the following variables:\n" diff --git a/java-21-openjdk-portable.specfile b/java-21-openjdk-portable.specfile index 1f3ad8d..3420328 100644 --- a/java-21-openjdk-portable.specfile +++ b/java-21-openjdk-portable.specfile @@ -39,13 +39,6 @@ %global include_staticlibs 0 %endif -# Define whether to use the bootstrap JDK directly or with a fresh libjvm.so -%if %{with fresh_libjvm} -%global build_hotspot_first 1 -%else -%global build_hotspot_first 0 -%endif - %if %{with system_libs} %global system_libs 1 %global link_type system @@ -239,9 +232,6 @@ # Target to use to just build HotSpot %global hotspot_target hotspot -# JDK to use for bootstrapping -%global bootjdk /usr/lib/jvm/java-%{buildjdkver}-openjdk - # Filter out flags from the optflags macro that cause problems with the OpenJDK build # We filter out -O flags so that the optimization of HotSpot is not lowered from O3 to O2 # We filter out -Wall which will otherwise cause HotSpot to produce hundreds of thousands of warnings (100+mb logs) @@ -325,15 +315,15 @@ %endif # New Version-String scheme-style defines -%global featurever 17 +%global featurever 18 %global fakefeaturever 21 %global interimver 0 -%global updatever 7 +%global updatever 2 %global patchver 0 # buildjdkver is usually same as %%{featurever}, # but in time of bootstrap of next jdk, it is featurever-1, # and this it is better to change it here, on single place -%global buildjdkver 17 +%global buildjdkver %{fakefeaturever} # We don't add any LTS designator for STS packages (Fedora and EPEL). # We need to explicitly exclude EPEL as it would have the %%{rhel} macro defined. %if 0%{?rhel} && !0%{?epel} @@ -343,6 +333,16 @@ %global lts_designator "" %global lts_designator_zip "" %endif +# JDK to use for bootstrapping +%global bootjdk /usr/lib/jvm/java-%{buildjdkver}-openjdk +# Define whether to use the bootstrap JDK directly or with a fresh libjvm.so +# This will only work where the bootstrap JDK is the same major version +# as the JDK being built +%if %{with fresh_libjvm} && %{buildjdkver} == %{featurever} +%global build_hotspot_first 1 +%else +%global build_hotspot_first 0 +%endif # Define vendor information used by OpenJDK %global oj_vendor Red Hat, Inc. @@ -368,15 +368,15 @@ # 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 bf363eecce3 +%global fipsver 60131cc7271 # Standard JPackage naming and versioning defines %global origin openjdk %global origin_nice OpenJDK %global top_level_dir_name %{origin} %global top_level_dir_name_backup %{top_level_dir_name}-backup -%global buildver 7 -%global rpmrelease 2 +%global buildver 9 +%global rpmrelease 1 #%%global tagsuffix %%{nil} # Priority must be 8 digits in total; up to openjdk 1.8, we were using 18..... so when we moved to 11, we had to add another digit %if %is_system_jdk @@ -471,6 +471,12 @@ %global __requires_exclude ^(%{_privatelibs}|%{_publiclibs})$ %endif +# VM variant being built +%ifarch %{zero_arches} +%global vm_variant zero +%else +%global vm_variant server +%endif %global etcjavasubdir %{_sysconfdir}/java/java-%{javaver}-%{origin} %define etcjavadir() %{expand:%{etcjavasubdir}/%{uniquesuffix -- %{?1}}} @@ -630,8 +636,8 @@ Patch600: rh1750419-redhat_alt_java.patch Patch6: rh1684077-openjdk_should_depend_on_pcsc-lite-libs_instead_of_pcsc-lite-devel.patch # Crypto policy and FIPS support patches -# Patch is generated from the fips-17u tree at https://github.com/rh-openjdk/jdk/tree/fips-17u -# as follows: git diff %%{vcstag} src make test > fips-17u-$(git show -s --format=%h HEAD).patch +# Patch is generated from the fips-18u tree at https://github.com/rh-openjdk/jdk/tree/fips-18u +# as follows: git diff %%{vcstag} src make test > fips-18u-$(git show -s --format=%h HEAD).patch # Diff is limited to src and make subdirectories to exclude .github changes # Fixes currently included: # PR3183, RH1340845: Follow system wide crypto policy @@ -665,7 +671,7 @@ Patch6: rh1684077-openjdk_should_depend_on_pcsc-lite-libs_instead_of_pcsc-lite-d # test/jdk/sun/security/pkcs11/fips/VerifyMissingAttributes.java: fixed jtreg main class # RH1940064: Enable XML Signature provider in FIPS mode # RH2173781: Avoid calling C_GetInfo() too early, before cryptoki is initialized -Patch1001: fips-17u-%{fipsver}.patch +Patch1001: fips-18u-%{fipsver}.patch ############################################# # @@ -680,10 +686,6 @@ Patch1001: fips-17u-%{fipsver}.patch # OpenJDK patches appearing in 17.0.8 # ############################################# -# JDK-8274864: Remove Amman/Cairo hacks in ZoneInfoFile -Patch2001: jdk8274864-remove_amman_cairo_hacks.patch -# JDK-8305113: (tz) Update Timezone Data to 2023c -Patch2002: jdk8305113-tzdata2023c.patch ############################################# # @@ -728,7 +730,7 @@ BuildRequires: zip # to pack portable tarballs BuildRequires: tar BuildRequires: unzip -# No javapackages-filesystem on el7,nor is needed for portables +# Not needed for portables # BuildRequires: javapackages-filesystem BuildRequires: java-%{buildjdkver}-openjdk-devel # Zero-assembler build requirement @@ -942,6 +944,12 @@ if [ %{include_debug_build} -eq 0 -a %{include_normal_build} -eq 0 -a %{includ echo "You have disabled all builds (normal,fastdebug,slowdebug). That is a no go." exit 14 fi + +%if %{with fresh_libjvm} && ! %{build_hotspot_first} +echo "WARNING: The build of a fresh libjvm has been disabled due to a JDK version mismatch" +echo "Build JDK version is %{buildjdkver}, feature JDK version is %{featurever}" +%endif + %setup -q -c -n %{uniquesuffix ""} -T -a 0 # https://bugzilla.redhat.com/show_bug.cgi?id=1189084 prioritylength=`expr length %{priority}` @@ -966,9 +974,6 @@ pushd %{top_level_dir_name} %patch1001 -p1 # nss.cfg PKCS11 support; must come last as it also alters java.security %patch1000 -p1 -# tzdata update -%patch2001 -p1 -%patch2002 -p1 popd # openjdk %patch600 @@ -1006,7 +1011,7 @@ cp -r tapset tapset%{fastdebug_suffix} for suffix in %{build_loop} ; do for file in "tapset"$suffix/*.in; do OUTPUT_FILE=`echo $file | sed -e "s:\.stp\.in$:-%{version}-%{release}.%{_arch}.stp:g"` - sed -e "s:@ABS_SERVER_LIBJVM_SO@:%{_jvmdir}/%{sdkdir -- $suffix}/lib/server/libjvm.so:g" $file > $file.1 + sed -e "s:@ABS_SERVER_LIBJVM_SO@:%{_jvmdir}/%{sdkdir -- $suffix}/lib/%{vm_variant}/libjvm.so:g" $file > $file.1 sed -e "s:@JAVA_SPEC_VER@:%{javaver}:g" $file.1 > $file.2 # TODO find out which architectures other than i686 have a client vm %ifarch %{ix86} @@ -1321,7 +1326,7 @@ function packagejdk() { cp -LR --preserve=mode,timestamps %{bootjdk} newboot systemjdk=$(pwd)/newboot buildjdk build/newboot ${systemjdk} %{hotspot_target} "release" "bundled" "internal" - mv build/newboot/jdk/lib/server/libjvm.so newboot/lib/server + mv build/newboot/jdk/lib/%{vm_variant}/libjvm.so newboot/lib/%{vm_variant} %else systemjdk=%{bootjdk} %endif @@ -1403,8 +1408,7 @@ export JAVA_HOME=${top_dir_abs_main_build_path}/images/%{jdkimage} #sed -i -e "s:^security.useSystemPropertiesFile=.*:security.useSystemPropertiesFile=true:" \ #${JAVA_HOME}/conf/security/java.security - -#check Shenandoah is enabled +# Check Shenandoah is enabled %if %{use_shenandoah_hotspot} $JAVA_HOME//bin/java -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -version %endif @@ -1445,10 +1449,13 @@ if ! nm $JAVA_HOME/bin/%{alt_java_name} | grep set_speculation ; then true ; els # Check translations are available for new timezones (during flatpak builds, the # tzdb.dat used by this test is not where the test expects it, so this is # disabled for flatpak builds) +# Disable test until we are on the latest JDK +%if %{buildjdkver} == %{featurever} $JAVA_HOME/bin/javac -d . %{SOURCE18} $JAVA_HOME/bin/java $(echo $(basename %{SOURCE18})|sed "s|\.java||") JRE $JAVA_HOME/bin/java -Djava.locale.providers=CLDR $(echo $(basename %{SOURCE18})|sed "s|\.java||") CLDR %endif +%endif %if %{include_staticlibs} # Check debug symbols in static libraries (smoke test) @@ -1674,6 +1681,23 @@ done %{_jvmdir}/%{miscportablearchive}.sha256sum %changelog +* Thu Aug 10 2023 Andrew Hughes - 1:18.0.2.0.9-1 +- Update to jdk-18.0.2 release +- Update release notes to actually reflect OpenJDK 18 +- Support JVM variant zero following JDK-8273494 no longer installing Zero's libjvm.so in the server directory +- Rebase FIPS patches from fips-18u branch +- Rebase RH1648249 nss.cfg patch so it applies after the FIPS patch +- Automatically turn off building a fresh HotSpot first, if the bootstrap JDK is not the same major version as that being built +- Drop tzdata patches added for 17.0.7 which will eventually appear in the upstream tarball when we reach OpenJDK 21 +- Switch bootjdkver to java-21-openjdk +- Disable tzdata tests until we are on the latest JDK and things are back in sync +- Related: rhbz#2192749 + +* Thu Aug 10 2023 Petra Alice Mikova - 1:18.0.0.0.37-1 +- Update to ea version of jdk18 +- Adjust rh1684077-openjdk_should_depend_on_pcsc-lite-libs_instead_of_pcsc-lite-devel.patch +- Related: rhbz#2192749 + * Mon May 15 2023 Andrew Hughes - 1:17.0.7.0.7-2 - Create java-21-openjdk-portable package based on java-17-openjdk-portable - Related: rhbz#2192749 diff --git a/java-21-openjdk.spec b/java-21-openjdk.spec index 726e1b2..71d71da 100644 --- a/java-21-openjdk.spec +++ b/java-21-openjdk.spec @@ -21,8 +21,6 @@ %bcond_without release # Enable static library builds by default. %bcond_without staticlibs -# Build a fresh libjvm.so for use in a copy of the bootstrap JDK -%bcond_without fresh_libjvm # Build with system libraries %bcond_with system_libs @@ -34,13 +32,6 @@ %global include_staticlibs 0 %endif -# Define whether to use the bootstrap JDK directly or with a fresh libjvm.so -%if %{with fresh_libjvm} -%global build_hotspot_first 1 -%else -%global build_hotspot_first 0 -%endif - %if %{with system_libs} %global system_libs 1 %global link_type system @@ -223,9 +214,6 @@ # Target to use to just build HotSpot %global hotspot_target hotspot -# JDK to use for bootstrapping -%global bootjdk /usr/lib/jvm/java-%{buildjdkver}-openjdk - # debugedit tool for rewriting ELF file paths %global debugedit %{_rpmconfigdir}/debugedit @@ -311,15 +299,11 @@ %endif # New Version-String scheme-style defines -%global featurever 17 +%global featurever 18 %global fakefeaturever 21 %global interimver 0 -%global updatever 7 +%global updatever 2 %global patchver 0 -# buildjdkver is usually same as %%{featurever}, -# but in time of bootstrap of next jdk, it is featurever-1, -# and this it is better to change it here, on single place -%global buildjdkver 17 # We don't add any LTS designator for STS packages (Fedora and EPEL). # We need to explicitly exclude EPEL as it would have the %%{rhel} macro defined. %if 0%{?rhel} && !0%{?epel} @@ -354,17 +338,17 @@ # 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 bf363eecce3 +%global fipsver 60131cc7271 # Standard JPackage naming and versioning defines %global origin openjdk %global origin_nice OpenJDK %global top_level_dir_name %{origin} %global top_level_dir_name_backup %{top_level_dir_name}-backup -%global buildver 7 -%global rpmrelease 4 +%global buildver 9 +%global rpmrelease 1 # Settings used by the portable build -%global portablerelease 2 +%global portablerelease 1 %global portablesuffix el8 %global portablebuilddir /builddir/build/BUILD @@ -442,6 +426,12 @@ %global __requires_exclude ^(%{_privatelibs}|%{_publiclibs})$ %endif +# VM variant being built +%ifarch %{zero_arches} +%global vm_variant zero +%else +%global vm_variant server +%endif %global etcjavasubdir %{_sysconfdir}/java/java-%{javaver}-%{origin} %define etcjavadir() %{expand:%{etcjavasubdir}/%{uniquesuffix -- %{?1}}} @@ -660,6 +650,7 @@ alternatives \\ --slave %{_bindir}/jstack jstack %{sdkbindir -- %{?1}}/jstack \\ --slave %{_bindir}/jstat jstat %{sdkbindir -- %{?1}}/jstat \\ --slave %{_bindir}/jstatd jstatd %{sdkbindir -- %{?1}}/jstatd \\ + --slave %{_bindir}/jwebserver jwebserver %{sdkbindir -- %{?1}}/jwebserver \\ --slave %{_bindir}/serialver serialver %{sdkbindir -- %{?1}}/serialver \\ --slave %{_mandir}/man1/jar.1$ext jar.1$ext \\ %{_mandir}/man1/jar-%{uniquesuffix -- %{?1}}.1$ext \\ @@ -693,6 +684,8 @@ alternatives \\ %{_mandir}/man1/jstack-%{uniquesuffix -- %{?1}}.1$ext \\ --slave %{_mandir}/man1/jstat.1$ext jstat.1$ext \\ %{_mandir}/man1/jstat-%{uniquesuffix -- %{?1}}.1$ext \\ + --slave %{_mandir}/man1/jwebserver.1$ext jwebserver.1$ext \\ + %{_mandir}/man1/jwebserver-%{uniquesuffix -- %{?1}}.1$ext \\ --slave %{_mandir}/man1/jstatd.1$ext jstatd.1$ext \\ %{_mandir}/man1/jstatd-%{uniquesuffix -- %{?1}}.1$ext \\ --slave %{_mandir}/man1/serialver.1$ext serialver.1$ext \\ @@ -750,10 +743,19 @@ PRIORITY=%{priority} if [ "%{?1}" == %{debug_suffix} ]; then let PRIORITY=PRIORITY-1 fi + for X in %{origin} %{javaver} ; do + key=javadocdir_"$X" + alternatives --install %{_javadocdir}/java-"$X" $key %{_javadocdir}/%{uniquejavadocdir -- %{?1}}/api $PRIORITY --family %{family_noarch} + %{set_if_needed_alternatives $key %{family_noarch}} + done -key=javadocdir -alternatives --install %{_javadocdir}/java $key %{_javadocdir}/%{uniquejavadocdir -- %{?1}}/api $PRIORITY --family %{family_noarch} -%{set_if_needed_alternatives $key %{family_noarch}} + key=javadocdir_%{javaver}_%{origin} + alternatives --install %{_javadocdir}/java-%{javaver}-%{origin} $key %{_javadocdir}/%{uniquejavadocdir -- %{?1}}/api $PRIORITY --family %{family_noarch} + %{set_if_needed_alternatives $key %{family_noarch}} + + key=javadocdir + alternatives --install %{_javadocdir}/java $key %{_javadocdir}/%{uniquejavadocdir -- %{?1}}/api $PRIORITY --family %{family_noarch} + %{set_if_needed_alternatives $key %{family_noarch}} exit 0 } @@ -763,6 +765,9 @@ if [ "x$debug" == "xtrue" ] ; then fi post_state=$1 # from postun, https://docs.fedoraproject.org/en-US/packaging-guidelines/Scriptlets/#_syntax %{save_and_remove_alternatives javadocdir %{_javadocdir}/%{uniquejavadocdir -- %{?1}}/api $post_state %{family_noarch}} + %{save_and_remove_alternatives javadocdir_%{origin} %{_javadocdir}/%{uniquejavadocdir -- %{?1}}/api $post_state %{family_noarch}} + %{save_and_remove_alternatives javadocdir_%{javaver} %{_javadocdir}/%{uniquejavadocdir -- %{?1}}/api $post_state %{family_noarch}} + %{save_and_remove_alternatives javadocdir_%{javaver}_%{origin} %{_javadocdir}/%{uniquejavadocdir -- %{?1}}/api $post_state %{family_noarch}} exit 0 } @@ -774,9 +779,20 @@ PRIORITY=%{priority} if [ "%{?1}" == %{debug_suffix} ]; then let PRIORITY=PRIORITY-1 fi -key=javadoczip -alternatives --install %{_javadocdir}/java-zip $key %{_javadocdir}/%{uniquejavadocdir -- %{?1}}.zip $PRIORITY --family %{family_noarch} -%{set_if_needed_alternatives $key %{family_noarch}} + for X in %{origin} %{javaver} ; do + key=javadoczip_"$X" + alternatives --install %{_javadocdir}/java-"$X".zip $key %{_javadocdir}/%{uniquejavadocdir -- %{?1}}.zip $PRIORITY --family %{family_noarch} + %{set_if_needed_alternatives $key %{family_noarch}} + done + + key=javadoczip_%{javaver}_%{origin} + alternatives --install %{_javadocdir}/java-%{javaver}-%{origin}.zip $key %{_javadocdir}/%{uniquejavadocdir -- %{?1}}.zip $PRIORITY --family %{family_noarch} + %{set_if_needed_alternatives $key %{family_noarch}} + + # Weird legacy filename for backwards-compatibility + key=javadoczip + alternatives --install %{_javadocdir}/java-zip $key %{_javadocdir}/%{uniquejavadocdir -- %{?1}}.zip $PRIORITY --family %{family_noarch} + %{set_if_needed_alternatives $key %{family_noarch}} exit 0 } @@ -786,6 +802,9 @@ exit 0 fi post_state=$1 # from postun, https://docs.fedoraproject.org/en-US/packaging-guidelines/Scriptlets/#_syntax %{save_and_remove_alternatives javadoczip %{_javadocdir}/%{uniquejavadocdir -- %{?1}}.zip $post_state %{family_noarch}} + %{save_and_remove_alternatives javadoczip_%{origin} %{_javadocdir}/%{uniquejavadocdir -- %{?1}}.zip $post_state %{family_noarch}} + %{save_and_remove_alternatives javadoczip_%{javaver} %{_javadocdir}/%{uniquejavadocdir -- %{?1}}.zip $post_state %{family_noarch}} + %{save_and_remove_alternatives javadoczip_%{javaver}_%{origin} %{_javadocdir}/%{uniquejavadocdir -- %{?1}}.zip $post_state %{family_noarch}} exit 0 } @@ -875,9 +894,9 @@ exit 0 %{_mandir}/man1/%{alt_java_name}-%{uniquesuffix -- %{?1}}.1* %{_mandir}/man1/keytool-%{uniquesuffix -- %{?1}}.1* %{_mandir}/man1/rmiregistry-%{uniquesuffix -- %{?1}}.1* -%{_jvmdir}/%{sdkdir -- %{?1}}/lib/server/ +%{_jvmdir}/%{sdkdir -- %{?1}}/lib/%{vm_variant}/ %ifarch %{share_arches} -%attr(444, root, root) %ghost %{_jvmdir}/%{sdkdir -- %{?1}}/lib/server/classes.jsa +%attr(444, root, root) %ghost %{_jvmdir}/%{sdkdir -- %{?1}}/lib/%{vm_variant}/classes.jsa %endif %dir %{etcjavasubdir} %dir %{etcjavadir -- %{?1}} @@ -967,6 +986,7 @@ exit 0 %{_jvmdir}/%{sdkdir -- %{?1}}/bin/jstack %{_jvmdir}/%{sdkdir -- %{?1}}/bin/jstat %{_jvmdir}/%{sdkdir -- %{?1}}/bin/jstatd +%{_jvmdir}/%{sdkdir -- %{?1}}/bin/jwebserver %{_jvmdir}/%{sdkdir -- %{?1}}/bin/serialver %{_jvmdir}/%{sdkdir -- %{?1}}/include %{_jvmdir}/%{sdkdir -- %{?1}}/lib/ct.sym @@ -982,21 +1002,22 @@ exit 0 %{_mandir}/man1/jconsole-%{uniquesuffix -- %{?1}}.1* %{_mandir}/man1/jcmd-%{uniquesuffix -- %{?1}}.1* %{_mandir}/man1/jdb-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/jdeprscan-%{uniquesuffix -- %{?1}}.1* %{_mandir}/man1/jdeps-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/jfr-%{uniquesuffix -- %{?1}}.1* %{_mandir}/man1/jinfo-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/jlink-%{uniquesuffix -- %{?1}}.1* %{_mandir}/man1/jmap-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/jmod-%{uniquesuffix -- %{?1}}.1* %{_mandir}/man1/jps-%{uniquesuffix -- %{?1}}.1* %{_mandir}/man1/jpackage-%{uniquesuffix -- %{?1}}.1* %{_mandir}/man1/jrunscript-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/jshell-%{uniquesuffix -- %{?1}}.1* %{_mandir}/man1/jstack-%{uniquesuffix -- %{?1}}.1* %{_mandir}/man1/jstat-%{uniquesuffix -- %{?1}}.1* %{_mandir}/man1/jstatd-%{uniquesuffix -- %{?1}}.1* +%{_mandir}/man1/jwebserver-%{uniquesuffix -- %{?1}}.1* %{_mandir}/man1/serialver-%{uniquesuffix -- %{?1}}.1* -%{_mandir}/man1/jdeprscan-%{uniquesuffix -- %{?1}}.1* -%{_mandir}/man1/jlink-%{uniquesuffix -- %{?1}}.1* -%{_mandir}/man1/jmod-%{uniquesuffix -- %{?1}}.1* -%{_mandir}/man1/jshell-%{uniquesuffix -- %{?1}}.1* -%{_mandir}/man1/jfr-%{uniquesuffix -- %{?1}}.1* %if %{with_systemtap} %dir %{tapsetroot} @@ -1066,6 +1087,9 @@ exit 0 %if %is_system_jdk %if %{is_release_build -- %{?1}} %ghost %{_javadocdir}/java +%ghost %{_javadocdir}/java-%{origin} +%ghost %{_javadocdir}/java-%{javaver} +%ghost %{_javadocdir}/java-%{javaver}-%{origin} %endif %endif } @@ -1076,6 +1100,9 @@ exit 0 %if %is_system_jdk %if %{is_release_build -- %{?1}} %ghost %{_javadocdir}/java-zip +%ghost %{_javadocdir}/java-%{origin}.zip +%ghost %{_javadocdir}/java-%{javaver}.zip +%ghost %{_javadocdir}/java-%{javaver}-%{origin}.zip %endif %endif } @@ -1347,8 +1374,8 @@ Patch3: rh649512-remove_uses_of_far_in_jpeg_libjpeg_turbo_1_4_compat_for_jdk1 Patch6: rh1684077-openjdk_should_depend_on_pcsc-lite-libs_instead_of_pcsc-lite-devel.patch # Crypto policy and FIPS support patches -# Patch is generated from the fips-17u tree at https://github.com/rh-openjdk/jdk/tree/fips-17u -# as follows: git diff %%{vcstag} src make test > fips-17u-$(git show -s --format=%h HEAD).patch +# Patch is generated from the fips-18u tree at https://github.com/rh-openjdk/jdk/tree/fips-18u +# as follows: git diff %%{vcstag} src make test > fips-18u-$(git show -s --format=%h HEAD).patch # Diff is limited to src and make subdirectories to exclude .github changes # Fixes currently included: # PR3183, RH1340845: Follow system wide crypto policy @@ -1382,7 +1409,7 @@ Patch6: rh1684077-openjdk_should_depend_on_pcsc-lite-libs_instead_of_pcsc-lite-d # test/jdk/sun/security/pkcs11/fips/VerifyMissingAttributes.java: fixed jtreg main class # RH1940064: Enable XML Signature provider in FIPS mode # RH2173781: Avoid calling C_GetInfo() too early, before cryptoki is initialized -Patch1001: fips-17u-%{fipsver}.patch +Patch1001: fips-18u-%{fipsver}.patch ############################################# # @@ -1395,10 +1422,6 @@ Patch1001: fips-17u-%{fipsver}.patch # OpenJDK patches appearing in 17.0.8 # ############################################# -# JDK-8274864: Remove Amman/Cairo hacks in ZoneInfoFile -Patch2001: jdk8274864-remove_amman_cairo_hacks.patch -# JDK-8305113: (tz) Update Timezone Data to 2023c -Patch2002: jdk8305113-tzdata2023c.patch ############################################# # @@ -1829,6 +1852,7 @@ if [ %{include_debug_build} -eq 0 -a %{include_normal_build} -eq 0 -a %{includ echo "You have disabled all builds (normal,fastdebug,slowdebug). That is a no go." exit 14 fi + %setup -q -c -n %{uniquesuffix ""} -T -a 0 # https://bugzilla.redhat.com/show_bug.cgi?id=1189084 prioritylength=`expr length %{priority}` @@ -1854,9 +1878,6 @@ pushd %{top_level_dir_name} %patch1001 -p1 # nss.cfg PKCS11 support; must come last as it also alters java.security %patch1000 -p1 -# tzdata update -%patch2001 -p1 -%patch2002 -p1 popd # openjdk %patch600 @@ -1894,7 +1915,7 @@ cp -r tapset tapset%{fastdebug_suffix} for suffix in %{build_loop} ; do for file in "tapset"$suffix/*.in; do OUTPUT_FILE=`echo $file | sed -e "s:\.stp\.in$:-%{version}-%{release}.%{_arch}.stp:g"` - sed -e "s:@ABS_SERVER_LIBJVM_SO@:%{_jvmdir}/%{sdkdir -- $suffix}/lib/server/libjvm.so:g" $file > $file.1 + sed -e "s:@ABS_SERVER_LIBJVM_SO@:%{_jvmdir}/%{sdkdir -- $suffix}/lib/%{vm_variant}/libjvm.so:g" $file > $file.1 sed -e "s:@JAVA_SPEC_VER@:%{javaver}:g" $file.1 > $file.2 # TODO find out which architectures other than i686 have a client vm %ifarch %{ix86} @@ -1943,6 +1964,12 @@ function customisejdk() { # Use system-wide tzdata rm ${imagepath}/lib/tzdb.dat ln -s %{_datadir}/javazi-1.8/tzdb.dat ${imagepath}/lib/tzdb.dat + + # Add temporary empty nss.fips.cfg until full FIPS patches are restored +%if %{fakefeaturever} > %{featurever} + touch ${imagepath}/conf/security/nss.fips.cfg +%endif + fi } @@ -2037,10 +2064,13 @@ if ! nm $JAVA_HOME/bin/%{alt_java_name} | grep set_speculation ; then true ; els # Check translations are available for new timezones (during flatpak builds, the # tzdb.dat used by this test is not where the test expects it, so this is # disabled for flatpak builds) +# Disable test until we are on the latest JDK +%if %{fakefeaturever} == %{featurever} $JAVA_HOME/bin/javac -d . %{SOURCE18} $JAVA_HOME/bin/java $(echo $(basename %{SOURCE18})|sed "s|\.java||") JRE $JAVA_HOME/bin/java -Djava.locale.providers=CLDR $(echo $(basename %{SOURCE18})|sed "s|\.java||") CLDR %endif +%endif %if %{include_staticlibs} # Check debug symbols in static libraries (smoke test) @@ -2492,6 +2522,27 @@ require "copy_jdk_configs.lua" %endif %changelog +* Thu Aug 10 2023 Andrew Hughes - 1:18.0.2.0.9-1 +- Update to jdk-18.0.2 release +- Support JVM variant zero following JDK-8273494 no longer installing Zero's libjvm.so in the server directory +- Rebase FIPS patches from fips-18u branch +- Rebase RH1648249 nss.cfg patch so it applies after the FIPS patch +- Drop now unused fresh_libjvm, build_hotspot_first, bootjdk and buildjdkver variables, as we don't build a JDK here +- Drop tzdata patches added for 17.0.7 which will eventually appear in the upstream tarball when we reach OpenJDK 21 +- Disable tzdata tests until we are on the latest JDK and things are back in sync +- Use empty nss.fips.cfg until it is again available via the FIPS patch +- Related: RHEL-12996 + +* Thu Aug 10 2023 Petra Alice Mikova - 1:18.0.2.0.9-1 +- Update to ea version of jdk18 +- Add new slave jwebserver and corresponding manpage +- Adjust rh1684077-openjdk_should_depend_on_pcsc-lite-libs_instead_of_pcsc-lite-devel.patch +- Related: RHEL-12996 + +* Thu Aug 10 2023 FeRD (Frank Dana) - 1:18.0.2.0.9-1 +- Add javaver- and origin-specific javadoc and javadoczip alternatives. +- Related: RHEL-12996 + * Tue Aug 08 2023 Andrew Hughes - 1:17.0.7.0.7-4 - Add files missed by centpkg import. - Related: rhbz#2192749 diff --git a/jdk8274864-remove_amman_cairo_hacks.patch b/jdk8274864-remove_amman_cairo_hacks.patch deleted file mode 100644 index 5a5263a..0000000 --- a/jdk8274864-remove_amman_cairo_hacks.patch +++ /dev/null @@ -1,53 +0,0 @@ -commit 1b3825db8631e55771fb723d4fcd10040ea15b7e -Author: duke -Date: Wed Apr 12 17:25:27 2023 +0000 - - Backport ec199072c5867624d66840238cc8828e16ae8da7 - -diff --git a/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java b/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java -index 6f6e190efcd..ef278203182 100644 ---- a/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java -+++ b/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java -@@ -608,34 +608,6 @@ public final class ZoneInfoFile { - params[8] = endRule.secondOfDay * 1000; - params[9] = toSTZTime[endRule.timeDefinition]; - dstSavings = (startRule.offsetAfter - startRule.offsetBefore) * 1000; -- -- // Note: known mismatching -> Asia/Amman -- // ZoneInfo : startDayOfWeek=5 <= Thursday -- // startTime=86400000 <= 24 hours -- // This: startDayOfWeek=6 -- // startTime=0 -- // Similar workaround needs to be applied to Africa/Cairo and -- // its endDayOfWeek and endTime -- // Below is the workarounds, it probably slows down everyone a little -- if (params[2] == 6 && params[3] == 0 && -- (zoneId.equals("Asia/Amman"))) { -- params[2] = 5; -- params[3] = 86400000; -- } -- // Additional check for startDayOfWeek=6 and starTime=86400000 -- // is needed for Asia/Amman; -- if (params[2] == 7 && params[3] == 0 && -- (zoneId.equals("Asia/Amman"))) { -- params[2] = 6; // Friday -- params[3] = 86400000; // 24h -- } -- //endDayOfWeek and endTime workaround -- if (params[7] == 6 && params[8] == 0 && -- (zoneId.equals("Africa/Cairo"))) { -- params[7] = 5; -- params[8] = 86400000; -- } -- - } else if (nTrans > 0) { // only do this if there is something in table already - if (lastyear < LASTYEAR) { - // ZoneInfo has an ending entry for 2037 -@@ -908,7 +880,6 @@ public final class ZoneInfoFile { - this.dow = dowByte == 0 ? -1 : dowByte; - this.secondOfDay = timeByte == 31 ? in.readInt() : timeByte * 3600; - this.timeDefinition = (data & (3 << 12)) >>> 12; -- - this.standardOffset = stdByte == 255 ? in.readInt() : (stdByte - 128) * 900; - this.offsetBefore = beforeByte == 3 ? in.readInt() : standardOffset + beforeByte * 1800; - this.offsetAfter = afterByte == 3 ? in.readInt() : standardOffset + afterByte * 1800; diff --git a/jdk8305113-tzdata2023c.patch b/jdk8305113-tzdata2023c.patch deleted file mode 100644 index 6758dfd..0000000 --- a/jdk8305113-tzdata2023c.patch +++ /dev/null @@ -1,1098 +0,0 @@ -commit 9619cdb7b7f63f2d8a71d35c8672be93fd6255e9 -Author: Yoshiki Sato -Date: Wed Apr 5 01:19:00 2023 +0000 - - Backport ed9592c6e81f82e2bf6508ce45ba15aad8232181 - -diff --git a/make/data/tzdata/VERSION b/make/data/tzdata/VERSION -index 0f328a4a7ff..66bd061e8bc 100644 ---- a/make/data/tzdata/VERSION -+++ b/make/data/tzdata/VERSION -@@ -21,4 +21,4 @@ - # or visit www.oracle.com if you need additional information or have any - # questions. - # --tzdata2022g -+tzdata2023c -diff --git a/make/data/tzdata/africa b/make/data/tzdata/africa -index 830d7d10b7e..a73405fdb01 100644 ---- a/make/data/tzdata/africa -+++ b/make/data/tzdata/africa -@@ -344,6 +344,14 @@ Rule Egypt 2007 only - Sep Thu>=1 24:00 0 - - # From Mina Samuel (2016-07-04): - # Egyptian government took the decision to cancel the DST, - -+# From Ahmad ElDardiry (2023-03-01): -+# Egypt officially announced today that daylight savings will be -+# applied from last Friday of April to last Thursday of October. -+# From Paul Eggert (2023-03-01): -+# Assume transitions are at 00:00 and 24:00 respectively. -+# From Amir Adib (2023-03-07): -+# https://www.facebook.com/EgyptianCabinet/posts/638829614954129/ -+ - Rule Egypt 2008 only - Aug lastThu 24:00 0 - - Rule Egypt 2009 only - Aug 20 24:00 0 - - Rule Egypt 2010 only - Aug 10 24:00 0 - -@@ -353,6 +361,8 @@ Rule Egypt 2014 only - May 15 24:00 1:00 S - Rule Egypt 2014 only - Jun 26 24:00 0 - - Rule Egypt 2014 only - Jul 31 24:00 1:00 S - Rule Egypt 2014 only - Sep lastThu 24:00 0 - -+Rule Egypt 2023 max - Apr lastFri 0:00 1:00 S -+Rule Egypt 2023 max - Oct lastThu 24:00 0 - - - # Zone NAME STDOFF RULES FORMAT [UNTIL] - #STDOFF 2:05:08.9 -@@ -452,7 +462,7 @@ Zone Africa/Nairobi 2:27:16 - LMT 1908 May - # President William R. Tolbert, Jr., July 23, 1971-July 31, 1972. - # Monrovia: Executive Mansion. - # --# Use the abbreviation "MMT" before 1972, as the more-accurate numeric -+# Use the abbreviation "MMT" before 1972, as the more accurate numeric - # abbreviation "-004430" would be one byte over the POSIX limit. - # - # Zone NAME STDOFF RULES FORMAT [UNTIL] -@@ -589,8 +599,8 @@ Zone Africa/Tripoli 0:52:44 - LMT 1920 - # DST the coming summer... - # - # Some sources, in French: --# http://www.defimedia.info/news/946/Rashid-Beebeejaun-:-%C2%AB-L%E2%80%99heure-d%E2%80%99%C3%A9t%C3%A9-ne-sera-pas-appliqu%C3%A9e-cette-ann%C3%A9e-%C2%BB --# http://lexpress.mu/Story/3398~Beebeejaun---Les-objectifs-d-%C3%A9conomie-d-%C3%A9nergie-de-l-heure-d-%C3%A9t%C3%A9-ont-%C3%A9t%C3%A9-atteints- -+# http://www.defimedia.info/news/946/Rashid-Beebeejaun-:-«-L%E2%80%99heure-d%E2%80%99été-ne-sera-pas-appliquée-cette-année-» -+# http://lexpress.mu/Story/3398~Beebeejaun---Les-objectifs-d-économie-d-énergie-de-l-heure-d-été-ont-été-atteints- - # - # Our wrap-up: - # https://www.timeanddate.com/news/time/mauritius-dst-will-not-repeat.html -@@ -721,7 +731,7 @@ Zone Indian/Mauritius 3:50:00 - LMT 1907 # Port Louis - # More articles in the press - # https://www.yabiladi.com/articles/details/5058/secret-l-heure-d-ete-maroc-leve.html - # http://www.lematin.ma/Actualite/Express/Article.asp?id=148923 --# http://www.lavieeco.com/actualite/Le-Maroc-passe-sur-GMT%2B1-a-partir-de-dim -+# http://www.lavieeco.com/actualite/Le-Maroc-passe-sur-GMT+1-a-partir-de-dim - - # From Petr Machata (2011-03-30): - # They have it written in English here: -@@ -736,7 +746,7 @@ Zone Indian/Mauritius 3:50:00 - LMT 1907 # Port Louis - # According to Infomédiaire web site from Morocco (infomediaire.ma), - # on March 9, 2012, (in French) Heure légale: - # Le Maroc adopte officiellement l'heure d'été --# http://www.infomediaire.ma/news/maroc/heure-l%C3%A9gale-le-maroc-adopte-officiellement-lheure-d%C3%A9t%C3%A9 -+# http://www.infomediaire.ma/news/maroc/heure-légale-le-maroc-adopte-officiellement-lheure-dété - # Governing Council adopted draft decree, that Morocco DST starts on - # the last Sunday of March (March 25, 2012) and ends on - # last Sunday of September (September 30, 2012) -@@ -860,19 +870,28 @@ Zone Indian/Mauritius 3:50:00 - LMT 1907 # Port Louis - # Friday or Saturday (and so the 2 days off are on a weekend), the next time - # shift will be the next weekend. - # --# From Paul Eggert (2020-05-31): -+# From Milamber (2021-03-31, 2022-03-10): -+# https://www.mmsp.gov.ma/fr/actualites.aspx?id=2076 -+# https://www.ecoactu.ma/horaires-administration-ramadan-gmtheure-gmt-a-partir-de-dimanche-27-mars/ -+# -+# From Milamber (2023-03-14, 2023-03-15): -+# The return to legal GMT time will take place this Sunday, March 19 at 3 a.m. -+# ... the return to GMT+1 will be made on Sunday April 23, 2023 at 2 a.m. -+# https://www.mmsp.gov.ma/fr/actualites/passage-à-l%E2%80%99heure-gmt-à-partir-du-dimanche-19-mars-2023 -+# -+# From Paul Eggert (2023-03-14): - # For now, guess that in the future Morocco will fall back at 03:00 - # the last Sunday before Ramadan, and spring forward at 02:00 the --# first Sunday after two days after Ramadan. To implement this, -+# first Sunday after one day after Ramadan. To implement this, - # transition dates and times for 2019 through 2087 were determined by --# running the following program under GNU Emacs 26.3. (This algorithm -+# running the following program under GNU Emacs 28.2. (This algorithm - # also produces the correct transition dates for 2016 through 2018, - # though the times differ due to Morocco's time zone change in 2018.) - # (let ((islamic-year 1440)) - # (require 'cal-islam) - # (while (< islamic-year 1511) - # (let ((a (calendar-islamic-to-absolute (list 9 1 islamic-year))) --# (b (+ 2 (calendar-islamic-to-absolute (list 10 1 islamic-year)))) -+# (b (+ 1 (calendar-islamic-to-absolute (list 10 1 islamic-year)))) - # (sunday 0)) - # (while (/= sunday (mod (setq a (1- a)) 7))) - # (while (/= sunday (mod b 7)) -@@ -886,10 +905,6 @@ Zone Indian/Mauritius 3:50:00 - LMT 1907 # Port Louis - # (car (cdr (cdr a))) (calendar-month-name (car a) t) (car (cdr a)) - # (car (cdr (cdr b))) (calendar-month-name (car b) t) (car (cdr b))))) - # (setq islamic-year (+ 1 islamic-year)))) --# --# From Milamber (2021-03-31, 2022-03-10), confirming these predictions: --# https://www.mmsp.gov.ma/fr/actualites.aspx?id=2076 --# https://www.ecoactu.ma/horaires-administration-ramadan-gmtheure-gmt-a-partir-de-dimanche-27-mars/ - - # Rule NAME FROM TO - IN ON AT SAVE LETTER/S - Rule Morocco 1939 only - Sep 12 0:00 1:00 - -@@ -942,7 +957,7 @@ Rule Morocco 2021 only - May 16 2:00 0 - - Rule Morocco 2022 only - Mar 27 3:00 -1:00 - - Rule Morocco 2022 only - May 8 2:00 0 - - Rule Morocco 2023 only - Mar 19 3:00 -1:00 - --Rule Morocco 2023 only - Apr 30 2:00 0 - -+Rule Morocco 2023 only - Apr 23 2:00 0 - - Rule Morocco 2024 only - Mar 10 3:00 -1:00 - - Rule Morocco 2024 only - Apr 14 2:00 0 - - Rule Morocco 2025 only - Feb 23 3:00 -1:00 - -@@ -958,7 +973,7 @@ Rule Morocco 2029 only - Feb 18 2:00 0 - - Rule Morocco 2029 only - Dec 30 3:00 -1:00 - - Rule Morocco 2030 only - Feb 10 2:00 0 - - Rule Morocco 2030 only - Dec 22 3:00 -1:00 - --Rule Morocco 2031 only - Feb 2 2:00 0 - -+Rule Morocco 2031 only - Jan 26 2:00 0 - - Rule Morocco 2031 only - Dec 14 3:00 -1:00 - - Rule Morocco 2032 only - Jan 18 2:00 0 - - Rule Morocco 2032 only - Nov 28 3:00 -1:00 - -@@ -974,7 +989,7 @@ Rule Morocco 2036 only - Nov 23 2:00 0 - - Rule Morocco 2037 only - Oct 4 3:00 -1:00 - - Rule Morocco 2037 only - Nov 15 2:00 0 - - Rule Morocco 2038 only - Sep 26 3:00 -1:00 - --Rule Morocco 2038 only - Nov 7 2:00 0 - -+Rule Morocco 2038 only - Oct 31 2:00 0 - - Rule Morocco 2039 only - Sep 18 3:00 -1:00 - - Rule Morocco 2039 only - Oct 23 2:00 0 - - Rule Morocco 2040 only - Sep 2 3:00 -1:00 - -@@ -990,7 +1005,7 @@ Rule Morocco 2044 only - Aug 28 2:00 0 - - Rule Morocco 2045 only - Jul 9 3:00 -1:00 - - Rule Morocco 2045 only - Aug 20 2:00 0 - - Rule Morocco 2046 only - Jul 1 3:00 -1:00 - --Rule Morocco 2046 only - Aug 12 2:00 0 - -+Rule Morocco 2046 only - Aug 5 2:00 0 - - Rule Morocco 2047 only - Jun 23 3:00 -1:00 - - Rule Morocco 2047 only - Jul 28 2:00 0 - - Rule Morocco 2048 only - Jun 7 3:00 -1:00 - -@@ -1006,7 +1021,7 @@ Rule Morocco 2052 only - Jun 2 2:00 0 - - Rule Morocco 2053 only - Apr 13 3:00 -1:00 - - Rule Morocco 2053 only - May 25 2:00 0 - - Rule Morocco 2054 only - Apr 5 3:00 -1:00 - --Rule Morocco 2054 only - May 17 2:00 0 - -+Rule Morocco 2054 only - May 10 2:00 0 - - Rule Morocco 2055 only - Mar 28 3:00 -1:00 - - Rule Morocco 2055 only - May 2 2:00 0 - - Rule Morocco 2056 only - Mar 12 3:00 -1:00 - -@@ -1022,7 +1037,7 @@ Rule Morocco 2060 only - Mar 7 2:00 0 - - Rule Morocco 2061 only - Jan 16 3:00 -1:00 - - Rule Morocco 2061 only - Feb 27 2:00 0 - - Rule Morocco 2062 only - Jan 8 3:00 -1:00 - --Rule Morocco 2062 only - Feb 19 2:00 0 - -+Rule Morocco 2062 only - Feb 12 2:00 0 - - Rule Morocco 2062 only - Dec 31 3:00 -1:00 - - Rule Morocco 2063 only - Feb 4 2:00 0 - - Rule Morocco 2063 only - Dec 16 3:00 -1:00 - -@@ -1038,7 +1053,7 @@ Rule Morocco 2067 only - Dec 11 2:00 0 - - Rule Morocco 2068 only - Oct 21 3:00 -1:00 - - Rule Morocco 2068 only - Dec 2 2:00 0 - - Rule Morocco 2069 only - Oct 13 3:00 -1:00 - --Rule Morocco 2069 only - Nov 24 2:00 0 - -+Rule Morocco 2069 only - Nov 17 2:00 0 - - Rule Morocco 2070 only - Oct 5 3:00 -1:00 - - Rule Morocco 2070 only - Nov 9 2:00 0 - - Rule Morocco 2071 only - Sep 20 3:00 -1:00 - -@@ -1054,7 +1069,7 @@ Rule Morocco 2075 only - Sep 15 2:00 0 - - Rule Morocco 2076 only - Jul 26 3:00 -1:00 - - Rule Morocco 2076 only - Sep 6 2:00 0 - - Rule Morocco 2077 only - Jul 18 3:00 -1:00 - --Rule Morocco 2077 only - Aug 29 2:00 0 - -+Rule Morocco 2077 only - Aug 22 2:00 0 - - Rule Morocco 2078 only - Jul 10 3:00 -1:00 - - Rule Morocco 2078 only - Aug 14 2:00 0 - - Rule Morocco 2079 only - Jun 25 3:00 -1:00 - -@@ -1064,13 +1079,13 @@ Rule Morocco 2080 only - Jul 21 2:00 0 - - Rule Morocco 2081 only - Jun 1 3:00 -1:00 - - Rule Morocco 2081 only - Jul 13 2:00 0 - - Rule Morocco 2082 only - May 24 3:00 -1:00 - --Rule Morocco 2082 only - Jul 5 2:00 0 - -+Rule Morocco 2082 only - Jun 28 2:00 0 - - Rule Morocco 2083 only - May 16 3:00 -1:00 - - Rule Morocco 2083 only - Jun 20 2:00 0 - - Rule Morocco 2084 only - Apr 30 3:00 -1:00 - - Rule Morocco 2084 only - Jun 11 2:00 0 - - Rule Morocco 2085 only - Apr 22 3:00 -1:00 - --Rule Morocco 2085 only - Jun 3 2:00 0 - -+Rule Morocco 2085 only - May 27 2:00 0 - - Rule Morocco 2086 only - Apr 14 3:00 -1:00 - - Rule Morocco 2086 only - May 19 2:00 0 - - Rule Morocco 2087 only - Mar 30 3:00 -1:00 - -@@ -1213,15 +1228,15 @@ Zone Africa/Windhoek 1:08:24 - LMT 1892 Feb 8 - # From P Chan (2020-12-03): - # GMT was adopted as the standard time of Lagos on 1905-07-01. - # Lagos Weekly Record, 1905-06-24, p 3 --# http://ddsnext.crl.edu/titles/31558#?c=0&m=668&s=0&cv=2&r=0&xywh=1446%2C5221%2C1931%2C1235 -+# http://ddsnext.crl.edu/titles/31558#?c=0&m=668&s=0&cv=2&r=0&xywh=1446,5221,1931,1235 - # says "It is officially notified that on and after the 1st of July 1905 --# Greenwich Mean Solar Time will be adopted thought the Colony and -+# Greenwich Mean Solar Time will be adopted throughout the Colony and - # Protectorate, and that it will be necessary to put all clocks 13 minutes and - # 35 seconds back, recording local mean time." - # - # It seemed that Lagos returned to LMT on 1908-07-01. - # [The Lagos Standard], 1908-07-01, p 5 --# http://ddsnext.crl.edu/titles/31556#?c=0&m=78&s=0&cv=4&r=0&xywh=-92%2C3590%2C3944%2C2523 -+# http://ddsnext.crl.edu/titles/31556#?c=0&m=78&s=0&cv=4&r=0&xywh=-92,3590,3944,2523 - # says "Scarcely have the people become accustomed to this new time, when - # another official notice has now appeared announcing that from and after the - # 1st July next, return will be made to local mean time." -@@ -1233,7 +1248,7 @@ Zone Africa/Windhoek 1:08:24 - LMT 1892 Feb 8 - # https://libsysdigi.library.illinois.edu/ilharvest/Africana/Books2011-05/3064634/3064634_1914/3064634_1914_opt.pdf#page=27 - # "On January 1st [1914], a universal standard time for Nigeria was adopted, - # viz., half an hour fast on Greenwich mean time, corresponding to the meridian --# 7 [degrees] 30' E. long." -+# 7° 30' E. long." - # Lloyd's Register of Shipping (1915) says "Hitherto the time observed in Lagos - # was the local mean time. On 1st January, 1914, standard time for the whole of - # Nigeria was introduced ... Lagos time has been advanced about 16 minutes -@@ -1251,7 +1266,7 @@ Zone Africa/Windhoek 1:08:24 - LMT 1892 Feb 8 - # The Lagos Weekly Record, 1919-09-20, p 3 details discussion on the first - # reading of this Bill by the Legislative Council of the Colony of Nigeria on - # Thursday 1919-08-28: --# http://ddsnext.crl.edu/titles/31558?terms&item_id=303484#?m=1118&c=1&s=0&cv=2&r=0&xywh=1261%2C3408%2C2994%2C1915 -+# http://ddsnext.crl.edu/titles/31558?terms&item_id=303484#?m=1118&c=1&s=0&cv=2&r=0&xywh=1261,3408,2994,1915 - # "The proposal is that the Globe should be divided into twelve zones East and - # West of Greenwich, of one hour each, Nigeria falling into the zone with a - # standard of one hour fast on Greenwich Mean Time. Nigeria standard time is -diff --git a/make/data/tzdata/antarctica b/make/data/tzdata/antarctica -index 792542b9224..3de5e726eb4 100644 ---- a/make/data/tzdata/antarctica -+++ b/make/data/tzdata/antarctica -@@ -315,7 +315,7 @@ Zone Antarctica/Rothera 0 - -00 1976 Dec 1 - # but that he found it more convenient to keep GMT+12 - # as supplies for the station were coming from McMurdo Sound, - # which was on GMT+12 because New Zealand was on GMT+12 all year --# at that time (1957). (Source: Siple's book 90 Degrees South.) -+# at that time (1957). (Source: Siple's book 90° South.) - # - # From Susan Smith - # http://www.cybertours.com/whs/pole10.html -diff --git a/make/data/tzdata/asia b/make/data/tzdata/asia -index ff81978bc47..6a048c3ad28 100644 ---- a/make/data/tzdata/asia -+++ b/make/data/tzdata/asia -@@ -2714,6 +2714,40 @@ Zone Asia/Pyongyang 8:23:00 - LMT 1908 Apr 1 - - - # Lebanon -+# -+# From Saadallah Itani (2023-03-23): -+# Lebanon ... announced today delay of Spring forward from March 25 to April 20. -+# -+# From Paul Eggert (2023-03-27): -+# This announcement was by the Lebanese caretaker prime minister Najib Mikati. -+# https://www.mtv.com.lb/en/News/Local/1352516/lebanon-postpones-daylight-saving-time-adoption -+# A video was later leaked to the media of parliament speaker Nabih Berri -+# asking Mikati to postpone DST to aid observance of Ramadan, Mikati objecting -+# that this would cause problems such as scheduling airline flights, to which -+# Berri interjected, "What flights?" -+# -+# The change was controversial and led to a partly-sectarian divide. -+# Many Lebanese institutions, including the education ministry, the Maronite -+# church, and two news channels LCBI and MTV, ignored the announcement and -+# went ahead with the long-scheduled spring-forward on March 25/26, some -+# arguing that the prime minister had not followed the law because the change -+# had not been approved by the cabinet. Google went with the announcement; -+# Apple ignored it. At least one bank followed the announcement for its doors, -+# but ignored the announcement in internal computer systems. -+# Beirut international airport listed two times for each departure. -+# Dan Azzi wrote "My view is that this whole thing is a Dumb and Dumber movie." -+# Eventually the prime minister backed down, said the cabinet had decided to -+# stick with its 1998 decision, and that DST would begin midnight March 29/30. -+# https://www.nna-leb.gov.lb/en/miscellaneous/604093/lebanon-has-two-times-of-day-amid-daylight-savings -+# https://www.cnbc.com/2023/03/27/lebanon-in-two-different-time-zones-as-government-disagrees-on-daylight-savings.html -+# -+# Although we could model the chaos with two Zones, that would likely cause -+# more trouble than it would cure. Since so many manual clocks and -+# computer-based timestamps ignored the announcement, stick with official -+# cabinet resolutions in the data while recording the prime minister's -+# announcement as a comment. This is how we treated a similar situation in -+# Rio de Janeiro in spring 1993. -+# - # Rule NAME FROM TO - IN ON AT SAVE LETTER/S - Rule Lebanon 1920 only - Mar 28 0:00 1:00 S - Rule Lebanon 1920 only - Oct 25 0:00 0 - -@@ -2739,6 +2773,10 @@ Rule Lebanon 1992 only - Oct 4 0:00 0 - - Rule Lebanon 1993 max - Mar lastSun 0:00 1:00 S - Rule Lebanon 1993 1998 - Sep lastSun 0:00 0 - - Rule Lebanon 1999 max - Oct lastSun 0:00 0 - -+# This one-time rule, announced by the prime minister first for April 21 -+# then for March 30, is commented out for reasons described above. -+#Rule Lebanon 2023 only - Mar 30 0:00 1:00 S -+ - # Zone NAME STDOFF RULES FORMAT [UNTIL] - Zone Asia/Beirut 2:22:00 - LMT 1880 - 2:00 Lebanon EE%sT -@@ -2977,7 +3015,7 @@ Zone Asia/Kathmandu 5:41:16 - LMT 1920 - # 9pm and moving clocks forward by one hour for the next three months. ...." - # - # http://www.worldtimezone.com/dst_news/dst_news_pakistan01.html --# http://www.dailytimes.com.pk/default.asp?page=2008%5C05%5C15%5Cstory_15-5-2008_pg1_4 -+# http://www.dailytimes.com.pk/default.asp?page=2008\05\15\story_15-5-2008_pg1_4 - - # From Arthur David Olson (2008-05-19): - # XXX--midnight transitions is a guess; 2008 only is a guess. -@@ -3300,7 +3338,7 @@ Zone Asia/Karachi 4:28:12 - LMT 1907 - # Some of many sources in Arabic: - # http://www.samanews.com/index.php?act=Show&id=122638 - # --# http://safa.ps/details/news/74352/%D8%A8%D8%AF%D8%A1-%D8%A7%D9%84%D8%AA%D9%88%D9%82%D9%8A%D8%AA-%D8%A7%D9%84%D8%B5%D9%8A%D9%81%D9%8A-%D8%A8%D8%A7%D9%84%D8%B6%D9%81%D8%A9-%D9%88%D8%BA%D8%B2%D8%A9-%D9%84%D9%8A%D9%84%D8%A9-%D8%A7%D9%84%D8%AC%D9%85%D8%B9%D8%A9.html -+# http://safa.ps/details/news/74352/بدء-التوقيت-الصيفي-بالضفة-وغزة-ليلة-الجمعة.html - # - # Our brief summary: - # https://www.timeanddate.com/news/time/gaza-west-bank-dst-2012.html -@@ -3310,7 +3348,7 @@ Zone Asia/Karachi 4:28:12 - LMT 1907 - # time from midnight on Friday, March 29, 2013" (translated). - # [These are in Arabic and are for Gaza and for Ramallah, respectively.] - # http://www.samanews.com/index.php?act=Show&id=154120 --# http://safa.ps/details/news/99844/%D8%B1%D8%A7%D9%85-%D8%A7%D9%84%D9%84%D9%87-%D8%A8%D8%AF%D8%A1-%D8%A7%D9%84%D8%AA%D9%88%D9%82%D9%8A%D8%AA-%D8%A7%D9%84%D8%B5%D9%8A%D9%81%D9%8A-29-%D8%A7%D9%84%D8%AC%D8%A7%D8%B1%D9%8A.html -+# http://safa.ps/details/news/99844/رام-الله-بدء-التوقيت-الصيفي-29-الجاري.html - - # From Steffen Thorsen (2013-09-24): - # The Gaza and West Bank are ending DST Thursday at midnight -@@ -3408,9 +3446,41 @@ Zone Asia/Karachi 4:28:12 - LMT 1907 - # (2022-08-31): ... the Saturday before the last Sunday in March and October - # at 2:00 AM ,for the years from 2023 to 2026. - # (2022-09-05): https://mtit.pna.ps/Site/New/1453 --# --# From Paul Eggert (2022-08-31): --# For now, assume that this rule will also be used after 2026. -+ -+# From Heba Hamad (2023-03-22): -+# ... summer time will begin in Palestine from Saturday 04-29-2023, -+# 02:00 AM by 60 minutes forward. -+# -+# From Paul Eggert (2023-03-22): -+# For now, guess that spring and fall transitions will normally -+# continue to use 2022's rules, that during DST Palestine will switch -+# to standard time at 02:00 the last Saturday before Ramadan and back -+# to DST at 02:00 the first Saturday after Ramadan, and that -+# if the normal spring-forward or fall-back transition occurs during -+# Ramadan the former is delayed and the latter advanced. -+# To implement this, I predicted Ramadan-oriented transition dates for -+# 2023 through 2086 by running the following program under GNU Emacs 28.2, -+# with the results integrated by hand into the table below. -+# Predictions after 2086 are approximated without Ramadan. -+# -+# (let ((islamic-year 1444)) -+# (require 'cal-islam) -+# (while (< islamic-year 1510) -+# (let ((a (calendar-islamic-to-absolute (list 9 1 islamic-year))) -+# (b (+ 1 (calendar-islamic-to-absolute (list 10 1 islamic-year)))) -+# (saturday 6)) -+# (while (/= saturday (mod (setq a (1- a)) 7))) -+# (while (/= saturday (mod b 7)) -+# (setq b (1+ b))) -+# (setq a (calendar-gregorian-from-absolute a)) -+# (setq b (calendar-gregorian-from-absolute b)) -+# (insert -+# (format -+# (concat "Rule Palestine\t%d\tonly\t-\t%s\t%2d\t2:00\t0\t-\n" -+# "Rule Palestine\t%d\tonly\t-\t%s\t%2d\t2:00\t1:00\tS\n") -+# (car (cdr (cdr a))) (calendar-month-name (car a) t) (car (cdr a)) -+# (car (cdr (cdr b))) (calendar-month-name (car b) t) (car (cdr b))))) -+# (setq islamic-year (+ 1 islamic-year)))) - - # Rule NAME FROM TO - IN ON AT SAVE LETTER/S - Rule EgyptAsia 1957 only - May 10 0:00 1:00 S -@@ -3450,8 +3520,86 @@ Rule Palestine 2020 2021 - Mar Sat<=30 0:00 1:00 S - Rule Palestine 2020 only - Oct 24 1:00 0 - - Rule Palestine 2021 only - Oct 29 1:00 0 - - Rule Palestine 2022 only - Mar 27 0:00 1:00 S --Rule Palestine 2022 max - Oct Sat<=30 2:00 0 - --Rule Palestine 2023 max - Mar Sat<=30 2:00 1:00 S -+Rule Palestine 2022 2035 - Oct Sat<=30 2:00 0 - -+Rule Palestine 2023 only - Apr 29 2:00 1:00 S -+Rule Palestine 2024 only - Apr 13 2:00 1:00 S -+Rule Palestine 2025 only - Apr 5 2:00 1:00 S -+Rule Palestine 2026 2054 - Mar Sat<=30 2:00 1:00 S -+Rule Palestine 2036 only - Oct 18 2:00 0 - -+Rule Palestine 2037 only - Oct 10 2:00 0 - -+Rule Palestine 2038 only - Sep 25 2:00 0 - -+Rule Palestine 2039 only - Sep 17 2:00 0 - -+Rule Palestine 2039 only - Oct 22 2:00 1:00 S -+Rule Palestine 2039 2067 - Oct Sat<=30 2:00 0 - -+Rule Palestine 2040 only - Sep 1 2:00 0 - -+Rule Palestine 2040 only - Oct 13 2:00 1:00 S -+Rule Palestine 2041 only - Aug 24 2:00 0 - -+Rule Palestine 2041 only - Sep 28 2:00 1:00 S -+Rule Palestine 2042 only - Aug 16 2:00 0 - -+Rule Palestine 2042 only - Sep 20 2:00 1:00 S -+Rule Palestine 2043 only - Aug 1 2:00 0 - -+Rule Palestine 2043 only - Sep 12 2:00 1:00 S -+Rule Palestine 2044 only - Jul 23 2:00 0 - -+Rule Palestine 2044 only - Aug 27 2:00 1:00 S -+Rule Palestine 2045 only - Jul 15 2:00 0 - -+Rule Palestine 2045 only - Aug 19 2:00 1:00 S -+Rule Palestine 2046 only - Jun 30 2:00 0 - -+Rule Palestine 2046 only - Aug 11 2:00 1:00 S -+Rule Palestine 2047 only - Jun 22 2:00 0 - -+Rule Palestine 2047 only - Jul 27 2:00 1:00 S -+Rule Palestine 2048 only - Jun 6 2:00 0 - -+Rule Palestine 2048 only - Jul 18 2:00 1:00 S -+Rule Palestine 2049 only - May 29 2:00 0 - -+Rule Palestine 2049 only - Jul 3 2:00 1:00 S -+Rule Palestine 2050 only - May 21 2:00 0 - -+Rule Palestine 2050 only - Jun 25 2:00 1:00 S -+Rule Palestine 2051 only - May 6 2:00 0 - -+Rule Palestine 2051 only - Jun 17 2:00 1:00 S -+Rule Palestine 2052 only - Apr 27 2:00 0 - -+Rule Palestine 2052 only - Jun 1 2:00 1:00 S -+Rule Palestine 2053 only - Apr 12 2:00 0 - -+Rule Palestine 2053 only - May 24 2:00 1:00 S -+Rule Palestine 2054 only - Apr 4 2:00 0 - -+Rule Palestine 2054 only - May 16 2:00 1:00 S -+Rule Palestine 2055 only - May 1 2:00 1:00 S -+Rule Palestine 2056 only - Apr 22 2:00 1:00 S -+Rule Palestine 2057 only - Apr 7 2:00 1:00 S -+Rule Palestine 2058 max - Mar Sat<=30 2:00 1:00 S -+Rule Palestine 2068 only - Oct 20 2:00 0 - -+Rule Palestine 2069 only - Oct 12 2:00 0 - -+Rule Palestine 2070 only - Oct 4 2:00 0 - -+Rule Palestine 2071 only - Sep 19 2:00 0 - -+Rule Palestine 2072 only - Sep 10 2:00 0 - -+Rule Palestine 2072 only - Oct 15 2:00 1:00 S -+Rule Palestine 2073 only - Sep 2 2:00 0 - -+Rule Palestine 2073 only - Oct 7 2:00 1:00 S -+Rule Palestine 2074 only - Aug 18 2:00 0 - -+Rule Palestine 2074 only - Sep 29 2:00 1:00 S -+Rule Palestine 2075 only - Aug 10 2:00 0 - -+Rule Palestine 2075 only - Sep 14 2:00 1:00 S -+Rule Palestine 2075 max - Oct Sat<=30 2:00 0 - -+Rule Palestine 2076 only - Jul 25 2:00 0 - -+Rule Palestine 2076 only - Sep 5 2:00 1:00 S -+Rule Palestine 2077 only - Jul 17 2:00 0 - -+Rule Palestine 2077 only - Aug 28 2:00 1:00 S -+Rule Palestine 2078 only - Jul 9 2:00 0 - -+Rule Palestine 2078 only - Aug 13 2:00 1:00 S -+Rule Palestine 2079 only - Jun 24 2:00 0 - -+Rule Palestine 2079 only - Aug 5 2:00 1:00 S -+Rule Palestine 2080 only - Jun 15 2:00 0 - -+Rule Palestine 2080 only - Jul 20 2:00 1:00 S -+Rule Palestine 2081 only - Jun 7 2:00 0 - -+Rule Palestine 2081 only - Jul 12 2:00 1:00 S -+Rule Palestine 2082 only - May 23 2:00 0 - -+Rule Palestine 2082 only - Jul 4 2:00 1:00 S -+Rule Palestine 2083 only - May 15 2:00 0 - -+Rule Palestine 2083 only - Jun 19 2:00 1:00 S -+Rule Palestine 2084 only - Apr 29 2:00 0 - -+Rule Palestine 2084 only - Jun 10 2:00 1:00 S -+Rule Palestine 2085 only - Apr 21 2:00 0 - -+Rule Palestine 2085 only - Jun 2 2:00 1:00 S -+Rule Palestine 2086 only - Apr 13 2:00 0 - -+Rule Palestine 2086 only - May 18 2:00 1:00 S - - # Zone NAME STDOFF RULES FORMAT [UNTIL] - Zone Asia/Gaza 2:17:52 - LMT 1900 Oct -@@ -3655,7 +3803,7 @@ Zone Asia/Singapore 6:55:25 - LMT 1901 Jan 1 - # standard time is SLST. - # - # From Paul Eggert (2016-10-18): --# "SLST" seems to be reasonably recent and rarely-used outside time -+# "SLST" seems to be reasonably recent and rarely used outside time - # zone nerd sources. I searched Google News and found three uses of - # it in the International Business Times of India in February and - # March of this year when discussing cricket match times, but nothing -diff --git a/make/data/tzdata/australasia b/make/data/tzdata/australasia -index fbe3b8a6d72..893d7055eab 100644 ---- a/make/data/tzdata/australasia -+++ b/make/data/tzdata/australasia -@@ -346,7 +346,7 @@ Zone Antarctica/Macquarie 0 - -00 1899 Nov - - # From Steffen Thorsen (2013-01-10): - # Fiji will end DST on 2014-01-19 02:00: --# http://www.fiji.gov.fj/Media-Center/Press-Releases/DAYLIGHT-SAVINGS-TO-END-THIS-MONTH-%281%29.aspx -+# http://www.fiji.gov.fj/Media-Center/Press-Releases/DAYLIGHT-SAVINGS-TO-END-THIS-MONTH-(1).aspx - - # From Ken Rylander (2014-10-20): - # DST will start Nov. 2 this year. -@@ -746,7 +746,7 @@ Zone Pacific/Pago_Pago 12:37:12 - LMT 1892 Jul 5 - # - # Samoa's Daylight Saving Time Act 2009 is available here, but does not - # contain any dates: --# http://www.parliament.gov.ws/documents/acts/Daylight%20Saving%20Act%20%202009%20%28English%29%20-%20Final%207-7-091.pdf -+# http://www.parliament.gov.ws/documents/acts/Daylight%20Saving%20Act%20%202009%20(English)%20-%20Final%207-7-091.pdf - - # From Laupue Raymond Hughes (2010-10-07): - # Please see -@@ -1831,7 +1831,7 @@ Zone Pacific/Efate 11:13:16 - LMT 1912 Jan 13 # Vila - # period. It would probably be reasonable to assume Guam use GMT+9 during - # that period of time like the surrounding area. - --# From Paul Eggert (2018-11-18): -+# From Paul Eggert (2023-01-23): - # Howse writes (p 153) "The Spaniards, on the other hand, reached the - # Philippines and the Ladrones from America," and implies that the Ladrones - # (now called the Marianas) kept American date for quite some time. -@@ -1844,7 +1844,7 @@ Zone Pacific/Efate 11:13:16 - LMT 1912 Jan 13 # Vila - # they did as that avoids the need for a separate zone due to our 1970 cutoff. - # - # US Public Law 106-564 (2000-12-23) made UT +10 the official standard time, --# under the name "Chamorro Standard Time". There is no official abbreviation, -+# under the name "Chamorro standard time". There is no official abbreviation, - # but Congressman Robert A. Underwood, author of the bill that became law, - # wrote in a press release (2000-12-27) that he will seek the use of "ChST". - -@@ -2222,24 +2222,18 @@ Zone Pacific/Efate 11:13:16 - LMT 1912 Jan 13 # Vila - # an international standard, there are some places on the high seas where the - # correct date is ambiguous. - --# From Wikipedia (2005-08-31): --# Before 1920, all ships kept local apparent time on the high seas by setting --# their clocks at night or at the morning sight so that, given the ship's --# speed and direction, it would be 12 o'clock when the Sun crossed the ship's --# meridian (12 o'clock = local apparent noon). During 1917, at the --# Anglo-French Conference on Time-keeping at Sea, it was recommended that all --# ships, both military and civilian, should adopt hourly standard time zones --# on the high seas. Whenever a ship was within the territorial waters of any --# nation it would use that nation's standard time. The captain was permitted --# to change his ship's clocks at a time of his choice following his ship's --# entry into another zone time - he often chose midnight. These zones were --# adopted by all major fleets between 1920 and 1925 but not by many --# independent merchant ships until World War II. -- --# From Paul Eggert, using references suggested by Oscar van Vlijmen --# (2005-03-20): --# --# The American Practical Navigator (2002) --# http://pollux.nss.nima.mil/pubs/pubs_j_apn_sections.html?rid=187 --# talks only about the 180-degree meridian with respect to ships in --# international waters; it ignores the international date line. -+# From Wikipedia (2023-01-23): -+# The nautical time zone system is analogous to the terrestrial time zone -+# system for use on high seas. Under the system time changes are required for -+# changes of longitude in one-hour steps. The one-hour step corresponds to a -+# time zone width of 15° longitude. The 15° gore that is offset from GMT or -+# UT1 (not UTC) by twelve hours is bisected by the nautical date line into two -+# 7°30' gores that differ from GMT by ±12 hours. A nautical date line is -+# implied but not explicitly drawn on time zone maps. It follows the 180th -+# meridian except where it is interrupted by territorial waters adjacent to -+# land, forming gaps: it is a pole-to-pole dashed line. -+ -+# From Paul Eggert (2023-01-23): -+# The American Practical Navigator , -+# 2019 edition, merely says that the International Date Line -+# "coincides with the 180th meridian over most of its length." -diff --git a/make/data/tzdata/backward b/make/data/tzdata/backward -index fa44f655009..c0746d6dd1b 100644 ---- a/make/data/tzdata/backward -+++ b/make/data/tzdata/backward -@@ -297,6 +297,7 @@ Link America/Argentina/Cordoba America/Rosario - Link America/Tijuana America/Santa_Isabel - Link America/Denver America/Shiprock - Link America/Toronto America/Thunder_Bay -+Link America/Edmonton America/Yellowknife - Link Pacific/Auckland Antarctica/South_Pole - Link Asia/Shanghai Asia/Chongqing - Link Asia/Shanghai Asia/Harbin -diff --git a/make/data/tzdata/europe b/make/data/tzdata/europe -index acc5da3ec79..446d2e1e658 100644 ---- a/make/data/tzdata/europe -+++ b/make/data/tzdata/europe -@@ -540,9 +540,7 @@ Zone Europe/London -0:01:15 - LMT 1847 Dec 1 - # other form with a traditional approximation for Irish timestamps - # after 1971-10-31 02:00 UTC; although this approximation has tm_isdst - # flags that are reversed, its UTC offsets are correct and this often --# suffices. This source file currently uses only nonnegative SAVE --# values, but this is intended to change and downstream code should --# not rely on it. -+# suffices.... - # - # The following is like GB-Eire and EU, except with standard time in - # summer and negative daylight saving time in winter. It is for when -@@ -1136,19 +1134,18 @@ Zone Atlantic/Faroe -0:27:04 - LMT 1908 Jan 11 # Tórshavn - # - # From Jürgen Appel (2022-11-25): - # https://ina.gl/samlinger/oversigt-over-samlinger/samling/dagsordener/dagsorden.aspx?lang=da&day=24-11-2022 --# If I understand this correctly, from the next planned switch to --# summer time, Greenland will permanently stay at that time, i.e. no --# switch back to winter time in 2023 will occur. --# --# From Paul Eggert (2022-11-28): --# The official document in Danish --# https://naalakkersuisut.gl/-/media/naalakkersuisut/filer/kundgoerelser/2022/11/2511/31_da_inatsisartutlov-om-tidens-bestemmelse.pdf?la=da&hash=A33597D8A38CC7038465241119EF34F3 --# says standard time for Greenland is -02, that Naalakkersuisut can lay down --# rules for DST and can require some areas to use a different time zone, --# and that this all takes effect 2023-03-25 22:00. The abovementioned --# "bekymringer" URL says the intent is no transition March 25, that --# Greenland will not go back to winter time in fall 2023, and that --# only America/Nuuk is affected (though further changes may occur). -+# -+# From Thomas M. Steenholdt (2022-12-02): -+# - The bill to move America/Nuuk from UTC-03 to UTC-02 passed. -+# - The bill to stop observing DST did not (Greenland will stop observing DST -+# when EU does). -+# Details on the implementation are here (section 6): -+# https://ina.gl/dvd/EM%202022/pdf/media/2553529/pkt17_em2022_tidens_bestemmelse_bem_da.pdf -+# This is how the change will be implemented: -+# 1. The shift *to* DST in 2023 happens as normal. -+# 2. The shift *from* DST in 2023 happens as normal, but coincides with the -+# shift to UTC-02 normaltime (people will not change their clocks here). -+# 3. After this, DST is still observed, but as -02/-01 instead of -03/-02. - - # Rule NAME FROM TO - IN ON AT SAVE LETTER/S - Rule Thule 1991 1992 - Mar lastSun 2:00 1:00 D -@@ -1172,8 +1169,8 @@ Zone America/Scoresbysund -1:27:52 - LMT 1916 Jul 28 # Ittoqqortoormiit - -1:00 EU -01/+00 - Zone America/Nuuk -3:26:56 - LMT 1916 Jul 28 # Godthåb - -3:00 - -03 1980 Apr 6 2:00 -- -3:00 EU -03/-02 2023 Mar 25 22:00 -- -2:00 - -02 -+ -3:00 EU -03/-02 2023 Oct 29 1:00u -+ -2:00 EU -02/-01 - Zone America/Thule -4:35:08 - LMT 1916 Jul 28 # Pituffik - -4:00 Thule A%sT - -@@ -1509,9 +1506,9 @@ Zone Europe/Paris 0:09:21 - LMT 1891 Mar 16 - Rule Germany 1946 only - Apr 14 2:00s 1:00 S - Rule Germany 1946 only - Oct 7 2:00s 0 - - Rule Germany 1947 1949 - Oct Sun>=1 2:00s 0 - --# http://www.ptb.de/de/org/4/44/441/salt.htm says the following transition --# occurred at 3:00 MEZ, not the 2:00 MEZ given in Shanks & Pottenger. --# Go with the PTB. -+# https://www.ptb.de/cms/en/ptb/fachabteilungen/abt4/fb-44/ag-441/realisation-of-legal-time-in-germany/dst-and-midsummer-dst-in-germany-until-1979.html -+# says the following transition occurred at 3:00 MEZ, not the 2:00 MEZ -+# given in Shanks & Pottenger. Go with the PTB. - Rule Germany 1947 only - Apr 6 3:00s 1:00 S - Rule Germany 1947 only - May 11 2:00s 2:00 M - Rule Germany 1947 only - Jun 29 3:00 1:00 S -@@ -2272,7 +2269,7 @@ Zone Europe/Bucharest 1:44:24 - LMT 1891 Oct - # the State Duma has approved ... the draft bill on returning to - # winter time standard and return Russia 11 time zones. The new - # regulations will come into effect on October 26, 2014 at 02:00 ... --# http://asozd2.duma.gov.ru/main.nsf/%28Spravka%29?OpenAgent&RN=431985-6&02 -+# http://asozd2.duma.gov.ru/main.nsf/(Spravka)?OpenAgent&RN=431985-6&02 - # Here is a link where we put together table (based on approved Bill N - # 431985-6) with proposed 11 Russian time zones and corresponding - # areas/cities/administrative centers in the Russian Federation (in English): -@@ -2682,13 +2679,13 @@ Zone Europe/Volgograd 2:57:40 - LMT 1920 Jan 3 - 3:00 - +03 1930 Jun 21 - 4:00 - +04 1961 Nov 11 - 4:00 Russia +04/+05 1988 Mar 27 2:00s -- 3:00 Russia +03/+04 1991 Mar 31 2:00s -+ 3:00 Russia MSK/MSD 1991 Mar 31 2:00s - 4:00 - +04 1992 Mar 29 2:00s -- 3:00 Russia +03/+04 2011 Mar 27 2:00s -- 4:00 - +04 2014 Oct 26 2:00s -- 3:00 - +03 2018 Oct 28 2:00s -+ 3:00 Russia MSK/MSD 2011 Mar 27 2:00s -+ 4:00 - MSK 2014 Oct 26 2:00s -+ 3:00 - MSK 2018 Oct 28 2:00s - 4:00 - +04 2020 Dec 27 2:00s -- 3:00 - +03 -+ 3:00 - MSK - - # From Paul Eggert (2016-11-11): - # Europe/Saratov covers: -@@ -2719,11 +2716,11 @@ Zone Europe/Saratov 3:04:18 - LMT 1919 Jul 1 0:00u - Zone Europe/Kirov 3:18:48 - LMT 1919 Jul 1 0:00u - 3:00 - +03 1930 Jun 21 - 4:00 Russia +04/+05 1989 Mar 26 2:00s -- 3:00 Russia +03/+04 1991 Mar 31 2:00s -+ 3:00 Russia MSK/MSD 1991 Mar 31 2:00s - 4:00 - +04 1992 Mar 29 2:00s -- 3:00 Russia +03/+04 2011 Mar 27 2:00s -- 4:00 - +04 2014 Oct 26 2:00s -- 3:00 - +03 -+ 3:00 Russia MSK/MSD 2011 Mar 27 2:00s -+ 4:00 - MSK 2014 Oct 26 2:00s -+ 3:00 - MSK - - # From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25): - # Europe/Samara covers... -diff --git a/make/data/tzdata/iso3166.tab b/make/data/tzdata/iso3166.tab -index fbfb74bec45..cea17732dd1 100644 ---- a/make/data/tzdata/iso3166.tab -+++ b/make/data/tzdata/iso3166.tab -@@ -261,7 +261,7 @@ SY Syria - SZ Eswatini (Swaziland) - TC Turks & Caicos Is - TD Chad --TF French Southern Territories -+TF French S. Terr. - TG Togo - TH Thailand - TJ Tajikistan -diff --git a/make/data/tzdata/leapseconds b/make/data/tzdata/leapseconds -index d6fb840f512..89ce8b89cd2 100644 ---- a/make/data/tzdata/leapseconds -+++ b/make/data/tzdata/leapseconds -@@ -95,11 +95,11 @@ Leap 2016 Dec 31 23:59:60 + S - # Any additional leap seconds will come after this. - # This Expires line is commented out for now, - # so that pre-2020a zic implementations do not reject this file. --#Expires 2023 Jun 28 00:00:00 -+#Expires 2023 Dec 28 00:00:00 - - # POSIX timestamps for the data in this file: - #updated 1467936000 (2016-07-08 00:00:00 UTC) --#expires 1687910400 (2023-06-28 00:00:00 UTC) -+#expires 1703721600 (2023-12-28 00:00:00 UTC) - --# Updated through IERS Bulletin C64 --# File expires on: 28 June 2023 -+# Updated through IERS Bulletin C65 -+# File expires on: 28 December 2023 -diff --git a/make/data/tzdata/northamerica b/make/data/tzdata/northamerica -index a5fd701f88c..e240cf35103 100644 ---- a/make/data/tzdata/northamerica -+++ b/make/data/tzdata/northamerica -@@ -1,4 +1,3 @@ --# - # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - # - # This code is free software; you can redistribute it and/or modify it -@@ -299,9 +298,10 @@ Zone PST8PDT -8:00 US P%sT - # -10 Standard Alaska Time (AST) Alaska-Hawaii standard time (AHST) - # -11 (unofficial) Nome (NST) Bering standard time (BST) - # --# From Paul Eggert (2000-01-08), following a heads-up from Rives McDow: --# Public law 106-564 (2000-12-23) introduced ... "Chamorro Standard Time" -+# From Paul Eggert (2023-01-23), from a 2001-01-08 heads-up from Rives McDow: -+# Public law 106-564 (2000-12-23) introduced "Chamorro standard time" - # for time in Guam and the Northern Marianas. See the file "australasia". -+# Also see 15 U.S.C. §263 . - # - # From Paul Eggert (2015-04-17): - # HST and HDT are standardized abbreviations for Hawaii-Aleutian -@@ -618,7 +618,7 @@ Zone America/Los_Angeles -7:52:58 - LMT 1883 Nov 18 20:00u - # local times of other Alaskan locations so that they change simultaneously. - - # From Paul Eggert (2014-07-18): --# One opinion of the early-1980s turmoil in Alaska over time zones and -+# One opinion of the early 1980s turmoil in Alaska over time zones and - # daylight saving time appeared as graffiti on a Juneau airport wall: - # "Welcome to Juneau. Please turn your watch back to the 19th century." - # See: Turner W. Alaska's four time zones now two. NY Times 1983-11-01. -@@ -690,6 +690,10 @@ Zone America/Los_Angeles -7:52:58 - LMT 1883 Nov 18 20:00u - # So they won't be waiting for Alaska to join them on 2019-03-10, but will - # rather change their clocks twice in seven weeks. - -+# From Paul Eggert (2023-01-23): -+# America/Adak is for the Aleutian Islands that are part of Alaska -+# and are west of 169.5° W. -+ - # Zone NAME STDOFF RULES FORMAT [UNTIL] - Zone America/Juneau 15:02:19 - LMT 1867 Oct 19 15:33:32 - -8:57:41 - LMT 1900 Aug 20 12:00 -@@ -2148,10 +2152,6 @@ Zone America/Fort_Nelson -8:10:47 - LMT 1884 - # Nunavut ... moved ... to incorporate the whole territory into one time zone. - # Nunavut moves to single time zone Oct. 31 - # http://www.nunatsiaq.com/nunavut/nvt90903_13.html --# --# From Antoine Leca (1999-09-06): --# We then need to create a new timezone for the Kitikmeot region of Nunavut --# to differentiate it from the Yellowknife region. - - # From Paul Eggert (1999-09-20): - # Basic Facts: The New Territory -@@ -2345,9 +2345,6 @@ Zone America/Cambridge_Bay 0 - -00 1920 # trading post est.? - -5:00 - EST 2000 Nov 5 0:00 - -6:00 - CST 2001 Apr 1 3:00 - -7:00 Canada M%sT --Zone America/Yellowknife 0 - -00 1935 # Yellowknife founded? -- -7:00 NT_YK M%sT 1980 -- -7:00 Canada M%sT - Zone America/Inuvik 0 - -00 1953 # Inuvik founded - -8:00 NT_YK P%sT 1979 Apr lastSun 2:00 - -7:00 NT_YK M%sT 1980 -@@ -2584,7 +2581,7 @@ Zone America/Dawson -9:17:40 - LMT 1900 Aug 20 - # and in addition changes all of Chihuahua to -06 with no DST. - - # From Heitor David Pinto (2022-11-28): --# Now the northern municipalities want to have the same time zone as the -+# Now the northern [municipios] want to have the same time zone as the - # respective neighboring cities in the US, for example Juárez in UTC-7 with - # DST, matching El Paso, and Ojinaga in UTC-6 with DST, matching Presidio.... - # the president authorized the publication of the decree for November 29, -@@ -2621,7 +2618,7 @@ Zone America/Merida -5:58:28 - LMT 1922 Jan 1 6:00u - -5:00 - EST 1982 Dec 2 - -6:00 Mexico C%sT - # Coahuila, Nuevo León, Tamaulipas (near US border) --# This includes the following municipalities: -+# This includes the following municipios: - # in Coahuila: Acuña, Allende, Guerrero, Hidalgo, Jiménez, Morelos, Nava, - # Ocampo, Piedras Negras, Villa Unión, Zaragoza - # in Nuevo León: Anáhuac -@@ -2647,8 +2644,8 @@ Zone America/Mexico_City -6:36:36 - LMT 1922 Jan 1 7:00u - -6:00 - CST 2002 Feb 20 - -6:00 Mexico C%sT - # Chihuahua (near US border - western side) --# This includes the municipalities of Janos, Ascensión, Juárez, Guadalupe, --# and Práxedis G Guerrero. -+# This includes the municipios of Janos, Ascensión, Juárez, Guadalupe, and -+# Práxedis G Guerrero. - # http://gaceta.diputados.gob.mx/PDF/65/2a022/nov/20221124-VII.pdf - Zone America/Ciudad_Juarez -7:05:56 - LMT 1922 Jan 1 7:00u - -7:00 - MST 1927 Jun 10 23:00 -@@ -2662,7 +2659,8 @@ Zone America/Ciudad_Juarez -7:05:56 - LMT 1922 Jan 1 7:00u - -6:00 - CST 2022 Nov 30 0:00 - -7:00 US M%sT - # Chihuahua (near US border - eastern side) --# The municipalities of Coyame del Sotol, Ojinaga, and Manuel Benavides. -+# This includes the municipios of Coyame del Sotol, Ojinaga, and Manuel -+# Benavides. - # http://gaceta.diputados.gob.mx/PDF/65/2a022/nov/20221124-VII.pdf - Zone America/Ojinaga -6:57:40 - LMT 1922 Jan 1 7:00u - -7:00 - MST 1927 Jun 10 23:00 -@@ -3083,7 +3081,7 @@ Zone America/Costa_Rica -5:36:13 - LMT 1890 # San José - # - # He supplied these references: - # --# http://www.prensalatina.com.mx/article.asp?ID=%7B4CC32C1B-A9F7-42FB-8A07-8631AFC923AF%7D&language=ES -+# http://www.prensalatina.com.mx/article.asp?ID={4CC32C1B-A9F7-42FB-8A07-8631AFC923AF}&language=ES - # http://actualidad.terra.es/sociedad/articulo/cuba_llama_ahorrar_energia_cambio_1957044.htm - # - # From Alex Krivenyshev (2007-10-25): -diff --git a/make/data/tzdata/southamerica b/make/data/tzdata/southamerica -index 81fdd793df4..4024e7180cd 100644 ---- a/make/data/tzdata/southamerica -+++ b/make/data/tzdata/southamerica -@@ -231,7 +231,7 @@ Rule Arg 2008 only - Oct Sun>=15 0:00 1:00 - - # Hora de verano para la República Argentina - # http://buenasiembra.com.ar/esoterismo/astrologia/hora-de-verano-de-la-republica-argentina-27.html - # says that standard time in Argentina from 1894-10-31 --# to 1920-05-01 was -4:16:48.25. Go with this more-precise value -+# to 1920-05-01 was -4:16:48.25. Go with this more precise value - # over Shanks & Pottenger. It is upward compatible with Milne, who - # says Córdoba time was -4:16:48.2. - -diff --git a/make/data/tzdata/zone.tab b/make/data/tzdata/zone.tab -index 939432d3456..3edb0d61c80 100644 ---- a/make/data/tzdata/zone.tab -+++ b/make/data/tzdata/zone.tab -@@ -144,9 +144,8 @@ CA +744144-0944945 America/Resolute Central - NU (Resolute) - CA +624900-0920459 America/Rankin_Inlet Central - NU (central) - CA +5024-10439 America/Regina CST - SK (most areas) - CA +5017-10750 America/Swift_Current CST - SK (midwest) --CA +5333-11328 America/Edmonton Mountain - AB; BC (E); SK (W) -+CA +5333-11328 America/Edmonton Mountain - AB; BC (E); NT (E); SK (W) - CA +690650-1050310 America/Cambridge_Bay Mountain - NU (west) --CA +6227-11421 America/Yellowknife Mountain - NT (central) - CA +682059-1334300 America/Inuvik Mountain - NT (west) - CA +4906-11631 America/Creston MST - BC (Creston) - CA +5546-12014 America/Dawson_Creek MST - BC (Dawson Cr, Ft St John) -@@ -162,7 +161,7 @@ CG -0416+01517 Africa/Brazzaville - CH +4723+00832 Europe/Zurich - CI +0519-00402 Africa/Abidjan - CK -2114-15946 Pacific/Rarotonga --CL -3327-07040 America/Santiago Chile (most areas) -+CL -3327-07040 America/Santiago most of Chile - CL -5309-07055 America/Punta_Arenas Region of Magallanes - CL -2709-10926 Pacific/Easter Easter Island - CM +0403+00942 Africa/Douala -@@ -174,10 +173,10 @@ CU +2308-08222 America/Havana - CV +1455-02331 Atlantic/Cape_Verde - CW +1211-06900 America/Curacao - CX -1025+10543 Indian/Christmas --CY +3510+03322 Asia/Nicosia Cyprus (most areas) -+CY +3510+03322 Asia/Nicosia most of Cyprus - CY +3507+03357 Asia/Famagusta Northern Cyprus - CZ +5005+01426 Europe/Prague --DE +5230+01322 Europe/Berlin Germany (most areas) -+DE +5230+01322 Europe/Berlin most of Germany - DE +4742+00841 Europe/Busingen Busingen - DJ +1136+04309 Africa/Djibouti - DK +5540+01235 Europe/Copenhagen -@@ -210,7 +209,7 @@ GF +0456-05220 America/Cayenne - GG +492717-0023210 Europe/Guernsey - GH +0533-00013 Africa/Accra - GI +3608-00521 Europe/Gibraltar --GL +6411-05144 America/Nuuk Greenland (most areas) -+GL +6411-05144 America/Nuuk most of Greenland - GL +7646-01840 America/Danmarkshavn National Park (east coast) - GL +7029-02158 America/Scoresbysund Scoresbysund/Ittoqqortoormiit - GL +7634-06847 America/Thule Thule/Pituffik -@@ -258,7 +257,7 @@ KP +3901+12545 Asia/Pyongyang - KR +3733+12658 Asia/Seoul - KW +2920+04759 Asia/Kuwait - KY +1918-08123 America/Cayman --KZ +4315+07657 Asia/Almaty Kazakhstan (most areas) -+KZ +4315+07657 Asia/Almaty most of Kazakhstan - KZ +4448+06528 Asia/Qyzylorda Qyzylorda/Kyzylorda/Kzyl-Orda - KZ +5312+06337 Asia/Qostanay Qostanay/Kostanay/Kustanay - KZ +5017+05710 Asia/Aqtobe Aqtobe/Aktobe -@@ -282,12 +281,12 @@ MD +4700+02850 Europe/Chisinau - ME +4226+01916 Europe/Podgorica - MF +1804-06305 America/Marigot - MG -1855+04731 Indian/Antananarivo --MH +0709+17112 Pacific/Majuro Marshall Islands (most areas) -+MH +0709+17112 Pacific/Majuro most of Marshall Islands - MH +0905+16720 Pacific/Kwajalein Kwajalein - MK +4159+02126 Europe/Skopje - ML +1239-00800 Africa/Bamako - MM +1647+09610 Asia/Yangon --MN +4755+10653 Asia/Ulaanbaatar Mongolia (most areas) -+MN +4755+10653 Asia/Ulaanbaatar most of Mongolia - MN +4801+09139 Asia/Hovd Bayan-Olgiy, Govi-Altai, Hovd, Uvs, Zavkhan - MN +4804+11430 Asia/Choibalsan Dornod, Sukhbaatar - MO +221150+1133230 Asia/Macau -@@ -325,7 +324,7 @@ NO +5955+01045 Europe/Oslo - NP +2743+08519 Asia/Kathmandu - NR -0031+16655 Pacific/Nauru - NU -1901-16955 Pacific/Niue --NZ -3652+17446 Pacific/Auckland New Zealand (most areas) -+NZ -3652+17446 Pacific/Auckland most of New Zealand - NZ -4357-17633 Pacific/Chatham Chatham Islands - OM +2336+05835 Asia/Muscat - PA +0858-07932 America/Panama -@@ -333,7 +332,7 @@ PE -1203-07703 America/Lima - PF -1732-14934 Pacific/Tahiti Society Islands - PF -0900-13930 Pacific/Marquesas Marquesas Islands - PF -2308-13457 Pacific/Gambier Gambier Islands --PG -0930+14710 Pacific/Port_Moresby Papua New Guinea (most areas) -+PG -0930+14710 Pacific/Port_Moresby most of Papua New Guinea - PG -0613+15534 Pacific/Bougainville Bougainville - PH +1435+12100 Asia/Manila - PK +2452+06703 Asia/Karachi -@@ -379,7 +378,7 @@ RU +4310+13156 Asia/Vladivostok MSK+07 - Amur River - RU +643337+1431336 Asia/Ust-Nera MSK+07 - Oymyakonsky - RU +5934+15048 Asia/Magadan MSK+08 - Magadan - RU +4658+14242 Asia/Sakhalin MSK+08 - Sakhalin Island --RU +6728+15343 Asia/Srednekolymsk MSK+08 - Sakha (E); North Kuril Is -+RU +6728+15343 Asia/Srednekolymsk MSK+08 - Sakha (E); N Kuril Is - RU +5301+15839 Asia/Kamchatka MSK+09 - Kamchatka - RU +6445+17729 Asia/Anadyr MSK+09 - Bering Sea - RW -0157+03004 Africa/Kigali -@@ -420,7 +419,7 @@ TT +1039-06131 America/Port_of_Spain - TV -0831+17913 Pacific/Funafuti - TW +2503+12130 Asia/Taipei - TZ -0648+03917 Africa/Dar_es_Salaam --UA +5026+03031 Europe/Kyiv Ukraine (most areas) -+UA +5026+03031 Europe/Kyiv most of Ukraine - UG +0019+03225 Africa/Kampala - UM +2813-17722 Pacific/Midway Midway Islands - UM +1917+16637 Pacific/Wake Wake Island -@@ -443,7 +442,7 @@ US +465042-1012439 America/North_Dakota/New_Salem Central - ND (Morton rural) - US +471551-1014640 America/North_Dakota/Beulah Central - ND (Mercer) - US +394421-1045903 America/Denver Mountain (most areas) - US +433649-1161209 America/Boise Mountain - ID (south); OR (east) --US +332654-1120424 America/Phoenix MST - Arizona (except Navajo) -+US +332654-1120424 America/Phoenix MST - AZ (except Navajo) - US +340308-1181434 America/Los_Angeles Pacific - US +611305-1495401 America/Anchorage Alaska (most areas) - US +581807-1342511 America/Juneau Alaska - Juneau area -@@ -451,7 +450,7 @@ US +571035-1351807 America/Sitka Alaska - Sitka area - US +550737-1313435 America/Metlakatla Alaska - Annette Island - US +593249-1394338 America/Yakutat Alaska - Yakutat - US +643004-1652423 America/Nome Alaska (west) --US +515248-1763929 America/Adak Aleutian Islands -+US +515248-1763929 America/Adak Alaska - western Aleutians - US +211825-1575130 Pacific/Honolulu Hawaii - UY -345433-0561245 America/Montevideo - UZ +3940+06648 Asia/Samarkand Uzbekistan (west) -diff --git a/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java b/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java -index ef278203182..3762eb820bb 100644 ---- a/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java -+++ b/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java -@@ -608,6 +608,17 @@ public final class ZoneInfoFile { - params[8] = endRule.secondOfDay * 1000; - params[9] = toSTZTime[endRule.timeDefinition]; - dstSavings = (startRule.offsetAfter - startRule.offsetBefore) * 1000; -+ -+ // Note: known mismatching -> Africa/Cairo -+ // ZoneInfo : startDayOfWeek=5 <= Thursday -+ // startTime=86400000 <= 24:00 -+ // This: startDayOfWeek=6 <= Friday -+ // startTime=0 <= 0:00 -+ if (zoneId.equals("Africa/Cairo") && -+ params[7] == Calendar.FRIDAY && params[8] == 0) { -+ params[7] = Calendar.THURSDAY; -+ params[8] = SECONDS_PER_DAY * 1000; -+ } - } else if (nTrans > 0) { // only do this if there is something in table already - if (lastyear < LASTYEAR) { - // ZoneInfo has an ending entry for 2037 -diff --git a/src/java.base/share/classes/sun/util/resources/TimeZoneNames.java b/src/java.base/share/classes/sun/util/resources/TimeZoneNames.java -index bf7918659ae..2763ac30ca7 100644 ---- a/src/java.base/share/classes/sun/util/resources/TimeZoneNames.java -+++ b/src/java.base/share/classes/sun/util/resources/TimeZoneNames.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -845,9 +845,7 @@ public final class TimeZoneNames extends TimeZoneNamesBundle { - {"Europe/Jersey", GMTBST}, - {"Europe/Kaliningrad", EET}, - {"Europe/Kiev", EET}, -- {"Europe/Kirov", new String[] {"Kirov Standard Time", "GMT+03:00", -- "Kirov Daylight Time", "GMT+03:00", -- "Kirov Time", "GMT+03:00"}}, -+ {"Europe/Kirov", MSK}, - {"Europe/Lisbon", WET}, - {"Europe/Ljubljana", CET}, - {"Europe/London", GMTBST}, -diff --git a/test/jdk/java/util/TimeZone/TimeZoneData/VERSION b/test/jdk/java/util/TimeZone/TimeZoneData/VERSION -index 0f66ee12c94..c5483b48512 100644 ---- a/test/jdk/java/util/TimeZone/TimeZoneData/VERSION -+++ b/test/jdk/java/util/TimeZone/TimeZoneData/VERSION -@@ -1 +1 @@ --tzdata2022g -+tzdata2023c -diff --git a/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt b/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt -index d495743b268..07c5edbafee 100644 ---- a/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt -+++ b/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt -@@ -211,6 +211,7 @@ Link America/Argentina/Cordoba America/Rosario - Link America/Tijuana America/Santa_Isabel - Link America/Denver America/Shiprock - Link America/Toronto America/Thunder_Bay -+Link America/Edmonton America/Yellowknife - Link Pacific/Auckland Antarctica/South_Pole - Link Asia/Shanghai Asia/Chongqing - Link Asia/Shanghai Asia/Harbin -diff --git a/test/jdk/java/util/TimeZone/TimeZoneData/displaynames.txt b/test/jdk/java/util/TimeZone/TimeZoneData/displaynames.txt -index 44db4dbdb81..03f5305e65e 100644 ---- a/test/jdk/java/util/TimeZone/TimeZoneData/displaynames.txt -+++ b/test/jdk/java/util/TimeZone/TimeZoneData/displaynames.txt -@@ -92,7 +92,6 @@ America/Vancouver PST PDT - America/Whitehorse MST - America/Winnipeg CST CDT - America/Yakutat AKST AKDT --America/Yellowknife MST MDT - Antarctica/Macquarie AEST AEDT - Asia/Beirut EET EEST - Asia/Famagusta EET EEST -@@ -144,6 +143,7 @@ Europe/Dublin IST/GMT IST/GMT - Europe/Gibraltar CET CEST - Europe/Helsinki EET EEST - Europe/Kaliningrad EET -+Europe/Kirov MSK - Europe/Kyiv EET EEST - Europe/Lisbon WET WEST - Europe/London GMT/BST GMT/BST -@@ -160,6 +160,7 @@ Europe/Tallinn EET EEST - Europe/Tirane CET CEST - Europe/Vienna CET CEST - Europe/Vilnius EET EEST -+Europe/Volgograd MSK - Europe/Warsaw CET CEST - Europe/Zurich CET CEST - HST HST -diff --git a/test/jdk/java/util/TimeZone/TimeZoneTest.java b/test/jdk/java/util/TimeZone/TimeZoneTest.java -index d31d1722b7b..8e5d403f87b 100644 ---- a/test/jdk/java/util/TimeZone/TimeZoneTest.java -+++ b/test/jdk/java/util/TimeZone/TimeZoneTest.java -@@ -1,5 +1,5 @@ - /* -- * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it -@@ -25,7 +25,7 @@ - * @test - * @bug 4028006 4044013 4096694 4107276 4107570 4112869 4130885 7039469 7126465 7158483 - * 8008577 8077685 8098547 8133321 8138716 8148446 8151876 8159684 8166875 8181157 -- * 8228469 8274407 -+ * 8228469 8274407 8305113 - * @modules java.base/sun.util.resources - * @library /java/text/testlib - * @summary test TimeZone -@@ -121,7 +121,7 @@ public class TimeZoneTest extends IntlTest - new ZoneDescriptor("GMT", 0, false), - new ZoneDescriptor("UTC", 0, false), - new ZoneDescriptor("ECT", 60, true), -- new ZoneDescriptor("ART", 120, false), -+ new ZoneDescriptor("ART", 120, true), - new ZoneDescriptor("EET", 120, true), - new ZoneDescriptor("EAT", 180, false), - new ZoneDescriptor("MET", 60, true), diff --git a/rh1648249-add_commented_out_nss_cfg_provider_to_java_security.patch b/rh1648249-add_commented_out_nss_cfg_provider_to_java_security.patch index 6d2342a..c178077 100644 --- a/rh1648249-add_commented_out_nss_cfg_provider_to_java_security.patch +++ b/rh1648249-add_commented_out_nss_cfg_provider_to_java_security.patch @@ -1,7 +1,7 @@ -diff --git a/src/java.base/share/conf/security/java.security b/src/java.base/share/conf/security/java.security -index adfaf57d29e..abf89bbf327 100644 ---- a/src/java.base/share/conf/security/java.security -+++ b/src/java.base/share/conf/security/java.security +diff --git openjdk.orig/src/java.base/share/conf/security/java.security openjdk/src/java.base/share/conf/security/java.security +index 68a9c1a2d08..7aa25eb2cb7 100644 +--- openjdk.orig/src/java.base/share/conf/security/java.security ++++ openjdk/src/java.base/share/conf/security/java.security @@ -78,6 +78,7 @@ security.provider.tbd=SunMSCAPI security.provider.tbd=Apple #endif diff --git a/rh1684077-openjdk_should_depend_on_pcsc-lite-libs_instead_of_pcsc-lite-devel.patch b/rh1684077-openjdk_should_depend_on_pcsc-lite-libs_instead_of_pcsc-lite-devel.patch index 5e2b254..4c1476f 100644 --- a/rh1684077-openjdk_should_depend_on_pcsc-lite-libs_instead_of_pcsc-lite-devel.patch +++ b/rh1684077-openjdk_should_depend_on_pcsc-lite-libs_instead_of_pcsc-lite-devel.patch @@ -1,13 +1,15 @@ ---- openjdk/src/java.smartcardio/unix/classes/sun/security/smartcardio/PlatformPCSC.java 2013-03-01 10:48:12.038189968 +0100 -+++ openjdk/src/java.smartcardio/unix/classes/sun/security/smartcardio/PlatformPCSC.java 2013-03-01 10:48:11.913188505 +0100 -@@ -48,8 +48,8 @@ +diff --git a/openjdk/src/java.smartcardio/unix/classes/sun/security/smartcardio/PlatformPCSC.java b/src/java.smartcardio/unix/classes/sun/security/smartcardio/PlatformPCSC.java +index bacff32efbc..ff7b3dcc81c 100644 +--- openjdk/src/java.smartcardio/unix/classes/sun/security/smartcardio/PlatformPCSC.java ++++ openjdk/src/java.smartcardio/unix/classes/sun/security/smartcardio/PlatformPCSC.java +@@ -46,8 +46,8 @@ class PlatformPCSC { - private final static String PROP_NAME = "sun.security.smartcardio.library"; + private static final String PROP_NAME = "sun.security.smartcardio.library"; -- private final static String LIB1 = "/usr/$LIBISA/libpcsclite.so"; -- private final static String LIB2 = "/usr/local/$LIBISA/libpcsclite.so"; -+ private final static String LIB1 = "/usr/$LIBISA/libpcsclite.so.1"; -+ private final static String LIB2 = "/usr/local/$LIBISA/libpcsclite.so.1"; - private final static String PCSC_FRAMEWORK = "/System/Library/Frameworks/PCSC.framework/Versions/Current/PCSC"; +- private static final String LIB1 = "/usr/$LIBISA/libpcsclite.so"; +- private static final String LIB2 = "/usr/local/$LIBISA/libpcsclite.so"; ++ private static final String LIB1 = "/usr/$LIBISA/libpcsclite.so.1"; ++ private static final String LIB2 = "/usr/local/$LIBISA/libpcsclite.so.1"; + private static final String PCSC_FRAMEWORK = "/System/Library/Frameworks/PCSC.framework/Versions/Current/PCSC"; PlatformPCSC() { diff --git a/sources b/sources index ec61884..8b03eaa 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (openjdk-jdk17u-jdk-17.0.7+7.tar.xz) = 2f231e83fabef6299b16beee1e0c8d52501e22fd71a26ed2ace6fadabe38e73e66f3b8fb8bc994e8b2b9bbdb91d1143661941f623bb94793500f4f3b6495bf58 SHA512 (tapsets-icedtea-6.0.0pre00-c848b93a8598.tar.xz) = 97d026212363b3c83f6a04100ad7f6fdde833d16579717f8756e2b8c2eb70e144a41a330cb9ccde9c3badd37a2d54fdf4650a950ec21d8b686d545ecb2a64d30 +SHA512 (openjdk-jdk18u-jdk-18.0.2+9.tar.xz) = 08b06407deb4a13f36b29738b8038c7b2ce953eb526abe732fb4a256d968511c9ef705c5d568b4b3c98867665b748e331c9f293e69fc13bea1eed6879b6095d0