diff --git a/.gitignore b/.gitignore index 3f711a8..1f1fc8c 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,24 @@ /openjdk-jdk21u-jdk-21+35.tar.xz /openjdk-21+35.tar.xz /openjdk-21.0.1+12.tar.xz +/openjdk-21.0.2+11.tar.xz +/openjdk-21.0.2+12.tar.xz +/openjdk-21.0.2+13.tar.xz +/openjdk-22+32-ea.tar.xz +/openjdk-jdk-22+36-ea.tar.xz +/openjdk-jdk-22.0.1+8.tar.xz +/openjdk-jdk-22.0.2+9.tar.xz +/openjdk-jdk-23+37.tar.xz +/openjdk-jdk-23.0.1+11.tar.xz +/openjdk-23.0.2+7.tar.xz +/openjdk-24+34-ea.tar.xz +/openjdk-24+36.tar.xz +/openjdk-24.0.1+9.tar.xz +/openjdk-24.0.2+12.tar.xz +/openjdk-25+13-ea.tar.xz +/openjdk-25+26-ea.tar.xz +/openjdk-25+32-ea.tar.xz +/openjdk-jdk-25+36.tar.xz +/openjdk-25+36.tar.xz +/openjdk-25.0.1+8.tar.xz +/openjdk-26+29-ea.tar.xz diff --git a/JDK-8373246-8351842_broke_native_debugging_on_Linux.patch b/JDK-8373246-8351842_broke_native_debugging_on_Linux.patch new file mode 100644 index 0000000..1f6ca4d --- /dev/null +++ b/JDK-8373246-8351842_broke_native_debugging_on_Linux.patch @@ -0,0 +1,154 @@ +diff --git a/make/Bundles.gmk b/make/Bundles.gmk +index 8161b3b036254..0b324e7e3f3fc 100644 +--- a/make/Bundles.gmk ++++ b/make/Bundles.gmk +@@ -185,77 +185,30 @@ endif + + ifneq ($(filter product-bundles% legacy-bundles, $(MAKECMDGOALS)), ) + +- SYMBOLS_EXCLUDE_PATTERN := %.debuginfo %.diz %.map +- +- # There may be files with spaces in the names, so use ShellFindFiles +- # explicitly. ++ # There may be files with spaces in the names, so use ShellFindFiles explicitly. + ALL_JDK_FILES := $(call ShellFindFiles, $(JDK_IMAGE_DIR)) +- ifneq ($(JDK_IMAGE_DIR), $(JDK_SYMBOLS_IMAGE_DIR)) +- ALL_JDK_SYMBOLS_FILES := $(call ShellFindFiles, $(JDK_SYMBOLS_IMAGE_DIR)) +- else +- ALL_JDK_SYMBOLS_FILES := $(ALL_JDK_FILES) +- endif + ifneq ($(JDK_IMAGE_DIR), $(JDK_DEMOS_IMAGE_DIR)) + ALL_JDK_DEMOS_FILES := $(call ShellFindFiles, $(JDK_DEMOS_IMAGE_DIR)) + else + ALL_JDK_DEMOS_FILES := $(ALL_JDK_FILES) + endif + +- # Create special filter rules when dealing with unzipped .dSYM directories on +- # macosx +- ifeq ($(call isTargetOs, macosx), true) +- ifeq ($(ZIP_EXTERNAL_DEBUG_SYMBOLS), false) +- JDK_SYMBOLS_EXCLUDE_PATTERN := $(addprefix %, \ +- $(call containing, .dSYM/, $(patsubst $(JDK_IMAGE_DIR)/%, %, \ +- $(ALL_JDK_SYMBOLS_FILES)))) +- endif +- endif +- +- # Create special filter rules when dealing with debug symbols on windows +- ifeq ($(call isTargetOs, windows), true) +- ifeq ($(SHIP_DEBUG_SYMBOLS), ) +- JDK_SYMBOLS_EXCLUDE_PATTERN := %.pdb +- endif +- endif +- + JDK_BUNDLE_FILES := \ + $(filter-out \ +- $(JDK_SYMBOLS_EXCLUDE_PATTERN) \ + $(JDK_EXTRA_EXCLUDES) \ +- $(SYMBOLS_EXCLUDE_PATTERN) \ + $(JDK_IMAGE_HOMEDIR)/demo/% \ + , \ + $(ALL_JDK_FILES) \ + ) + +- JDK_SYMBOLS_BUNDLE_FILES := \ +- $(call FindFiles, $(SYMBOLS_IMAGE_DIR)) ++ JDK_SYMBOLS_BUNDLE_FILES := $(call FindFiles, $(SYMBOLS_IMAGE_DIR)) + + TEST_DEMOS_BUNDLE_FILES := $(filter $(JDK_DEMOS_IMAGE_HOMEDIR)/demo/%, \ + $(ALL_JDK_DEMOS_FILES)) + + ALL_JRE_FILES := $(call ShellFindFiles, $(JRE_IMAGE_DIR)) + +- # Create special filter rules when dealing with unzipped .dSYM directories on +- # macosx +- ifeq ($(OPENJDK_TARGET_OS), macosx) +- ifeq ($(ZIP_EXTERNAL_DEBUG_SYMBOLS), false) +- JRE_SYMBOLS_EXCLUDE_PATTERN := $(addprefix %, \ +- $(call containing, .dSYM/, $(patsubst $(JRE_IMAGE_DIR)/%, %, $(ALL_JRE_FILES)))) +- endif +- endif +- +- # Create special filter rules when dealing with debug symbols on windows +- ifeq ($(call isTargetOs, windows), true) +- ifeq ($(SHIP_DEBUG_SYMBOLS), ) +- JRE_SYMBOLS_EXCLUDE_PATTERN := %.pdb +- endif +- endif +- +- JRE_BUNDLE_FILES := $(filter-out \ +- $(JRE_SYMBOLS_EXCLUDE_PATTERN) \ +- $(SYMBOLS_EXCLUDE_PATTERN), \ +- $(ALL_JRE_FILES)) ++ JRE_BUNDLE_FILES := $(ALL_JRE_FILES) + + ifeq ($(MACOSX_CODESIGN_MODE), hardened) + # Macosx release build and code signing available. +diff --git a/make/CreateJmods.gmk b/make/CreateJmods.gmk +index 3280b24924a34..32f107b6bb6a0 100644 +--- a/make/CreateJmods.gmk ++++ b/make/CreateJmods.gmk +@@ -218,10 +218,14 @@ ifeq ($(call isTargetOs, windows), true) + ifeq ($(SHIP_DEBUG_SYMBOLS), ) + JMOD_FLAGS += --exclude '**{_the.*,_*.marker*,*.diz,*.pdb,*.map}' + else +- JMOD_FLAGS += --exclude '**{_the.*,_*.marker*,*.diz,*.map}' ++ JMOD_FLAGS += --exclude '**{_the.*,_*.marker*,*.map}' + endif + else +- JMOD_FLAGS += --exclude '**{_the.*,_*.marker*,*.diz,*.debuginfo,*.dSYM/**,*.dSYM}' ++ ifeq ($(SHIP_DEBUG_SYMBOLS), ) ++ JMOD_FLAGS += --exclude '**{_the.*,_*.marker*,*.diz,*.debuginfo,*.dSYM/**,*.dSYM}' ++ else ++ JMOD_FLAGS += --exclude '**{_the.*,_*.marker*}' ++ endif + endif + + # Unless we are creating a very large module, use the small tool JVM options +diff --git a/make/autoconf/jdk-options.m4 b/make/autoconf/jdk-options.m4 +index bb18877800192..87d147d4f074b 100644 +--- a/make/autoconf/jdk-options.m4 ++++ b/make/autoconf/jdk-options.m4 +@@ -316,23 +316,36 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_DEBUG_SYMBOLS], + AC_MSG_CHECKING([if we should add external native debug symbols to the shipped bundles]) + AC_ARG_WITH([external-symbols-in-bundles], + [AS_HELP_STRING([--with-external-symbols-in-bundles], +- [which type of external native debug symbol information shall be shipped in product bundles (none, public, full) +- (e.g. ship full/stripped pdbs on Windows) @<:@none@:>@])]) ++ [which type of external native debug symbol information shall be shipped with bundles/images (none, public, full). ++ @<:@none in release builds, full otherwise. --with-native-debug-symbols=external/zipped is a prerequisite. public is only supported on Windows@:>@])], ++ [], ++ [with_external_symbols_in_bundles=default]) + + if test "x$with_external_symbols_in_bundles" = x || test "x$with_external_symbols_in_bundles" = xnone ; then + AC_MSG_RESULT([no]) + elif test "x$with_external_symbols_in_bundles" = xfull || test "x$with_external_symbols_in_bundles" = xpublic ; then +- if test "x$OPENJDK_TARGET_OS" != xwindows ; then +- AC_MSG_ERROR([--with-external-symbols-in-bundles currently only works on windows!]) +- elif test "x$COPY_DEBUG_SYMBOLS" != xtrue ; then +- AC_MSG_ERROR([--with-external-symbols-in-bundles only works when --with-native-debug-symbols=external is used!]) +- elif test "x$with_external_symbols_in_bundles" = xfull ; then ++ if test "x$COPY_DEBUG_SYMBOLS" != xtrue ; then ++ AC_MSG_ERROR([--with-external-symbols-in-bundles only works when --with-native-debug-symbols=external/zipped is used!]) ++ elif test "x$with_external_symbols_in_bundles" = xpublic && test "x$OPENJDK_TARGET_OS" != xwindows ; then ++ AC_MSG_ERROR([--with-external-symbols-in-bundles=public is only supported on Windows!]) ++ fi ++ ++ if test "x$with_external_symbols_in_bundles" = xfull ; then + AC_MSG_RESULT([full]) + SHIP_DEBUG_SYMBOLS=full + else + AC_MSG_RESULT([public]) + SHIP_DEBUG_SYMBOLS=public + fi ++ elif test "x$with_external_symbols_in_bundles" = xdefault ; then ++ if test "x$DEBUG_LEVEL" = xrelease ; then ++ AC_MSG_RESULT([no (default)]) ++ elif test "x$COPY_DEBUG_SYMBOLS" = xtrue ; then ++ AC_MSG_RESULT([full (default)]) ++ SHIP_DEBUG_SYMBOLS=full ++ else ++ AC_MSG_RESULT([no (default, native debug symbols are not external/zipped)]) ++ fi + else + AC_MSG_ERROR([$with_external_symbols_in_bundles is an unknown value for --with-external-symbols-in-bundles]) + fi diff --git a/NEWS b/NEWS index 09d1dfe..0a4a628 100644 --- a/NEWS +++ b/NEWS @@ -3,210 +3,100 @@ Key: JDK-X - https://bugs.openjdk.java.net/browse/JDK-X CVE-XXXX-YYYY: https://cve.mitre.org/cgi-bin/cvename.cgi?name=XXXX-YYYY -New in release OpenJDK 21.0.1 (2023-10-17): +New in release OpenJDK 25.0.1 (2025-10-21): =========================================== * CVEs - - CVE-2023-22081 - - CVE-2023-22025 -* Security fixes - - JDK-8286503, JDK-8312367: Enhance security classes - - JDK-8296581: Better system proxy support - - JDK-8297856: Improve handling of Bidi characters - - JDK-8309966: Enhanced TLS connections - - JDK-8312248: Enhanced archival support redux - - JDK-8314649: Enhanced archival support redux - - JDK-8317121: vector_masked_load instruction is moved too early after JDK-8286941 -* Other changes - - JDK-8240567: MethodTooLargeException thrown while creating a jlink image - - JDK-8284772: GHA: Use GCC Major Version Dependencies Only - - JDK-8293114: JVM should trim the native heap - - JDK-8299658: C1 compilation crashes in LinearScan::resolve_exception_edge - - JDK-8302017: Allocate BadPaddingException only if it will be thrown - - JDK-8303815: Improve Metaspace test speed - - JDK-8304954: SegmentedCodeCache fails when using large pages - - JDK-8307766: Linux: Provide the option to override the timer slack - - JDK-8308042: [macos] Developer ID Application Certificate not picked up by jpackage if it contains UNICODE characters - - JDK-8308047: java/util/concurrent/ScheduledThreadPoolExecutor/BasicCancelTest.java timed out and also had jcmd pipe errors - - JDK-8308184: Launching java with large number of jars in classpath with java.protocol.handler.pkgs system property set can lead to StackOverflowError - - JDK-8308474: DSA does not reset SecureRandom when initSign is called again - - JDK-8308609: java/lang/ScopedValue/StressStackOverflow.java fails with "-XX:-VMContinuations" - - JDK-8309032: jpackage does not work for module projects unless --module-path is specified - - JDK-8309088: security/infra/java/security/cert/CertPathValidator/certification/AmazonCA.java fails - - JDK-8309214: sun/security/pkcs11/KeyStore/CertChainRemoval.java fails after 8301154 - - JDK-8309475: Test java/foreign/TestByteBuffer.java fails: a problem with msync (aix) - - JDK-8309502: RISC-V: String.indexOf intrinsic may produce misaligned memory loads - - JDK-8309591: Socket.setOption(TCP_QUICKACK) uses wrong level - - JDK-8309746: Reconfigure check should include make/conf/version-numbers.conf - - JDK-8309889: [s390] Missing return statement after calling jump_to_native_invoker method in generate_method_handle_dispatch. - - JDK-8310106: sun.security.ssl.SSLHandshake.getHandshakeProducer() incorrectly checks handshakeConsumers - - JDK-8310171: Bump version numbers for 21.0.1 - - JDK-8310211: serviceability/jvmti/thread/GetStackTrace/getstacktr03/getstacktr03.java failing - - JDK-8310233: Fix THP detection on Linux - - JDK-8310268: RISC-V: misaligned memory access in String.Compare intrinsic - - JDK-8310321: make JDKOPT_CHECK_CODESIGN_PARAMS more verbose - - JDK-8310586: ProblemList java/lang/ScopedValue/StressStackOverflow.java#default with virtual threads on linux-all - - JDK-8310687: JDK-8303215 is incomplete - - JDK-8310873: Re-enable locked_create_entry symbol check in runtime/NMT/CheckForProperDetailStackTrace.java for RISC-V - - JDK-8311026: Some G1 specific tests do not set -XX:+UseG1GC - - JDK-8311033: [macos] PrinterJob does not take into account Sides attribute - - JDK-8311160: [macOS, Accessibility] VoiceOver: No announcements on JRadioButtonMenuItem and JCheckBoxMenuItem - - JDK-8311249: Remove unused MemAllocator::obj_memory_range - - JDK-8311285: report some fontconfig related environment variables in hs_err file - - JDK-8311511: Improve description of NativeLibrary JFR event - - JDK-8311592: ECKeySizeParameterSpec causes too many exceptions on third party providers - - JDK-8311682: Change milestone to fcs for all releases - - JDK-8311862: RISC-V: small improvements to shift immediate instructions - - JDK-8311917: MAP_FAILED definition seems to be obsolete in src/java.desktop/unix/native/common/awt/fontpath.c - - JDK-8311921: Inform about MaxExpectedDataSegmentSize in case of pthread_create failures on AIX - - JDK-8311923: TestIRMatching.java fails on RISC-V - - JDK-8311926: java/lang/ScopedValue/StressStackOverflow.java takes 9mins in tier1 - - JDK-8311955: c++filt is now ibm-llvm-cxxfilt when using xlc17 / clang on AIX - - JDK-8311981: Test gc/stringdedup/TestStringDeduplicationAgeThreshold.java#ZGenerational timed out - - JDK-8312127: FileDescriptor.sync should temporarily increase parallelism - - JDK-8312180: (bf) MappedMemoryUtils passes incorrect arguments to msync (aix) - - JDK-8312182: THPs cause huge RSS due to thread start timing issue - - JDK-8312394: [linux] SIGSEGV if kernel was built without hugepage support - - JDK-8312395: Improve assertions in growableArray - - JDK-8312401: SymbolTable::do_add_if_needed hangs when called in InstanceKlass::add_initialization_error path with requesting length exceeds max_symbol_length - - JDK-8312489: Increase jdk.jar.maxSignatureFileSize default which is too low for JARs such as WhiteSource/Mend unified agent jar - - JDK-8312525: New test runtime/os/TestTrimNative.java#trimNative is failing: did not see the expected RSS reduction - - JDK-8312535: MidiSystem.getSoundbank() throws unexpected SecurityException - - JDK-8312555: Ideographic characters aren't stretched by AffineTransform.scale(2, 1) - - JDK-8312573: Failure during CompileOnly parsing leads to ShouldNotReachHere - - JDK-8312585: Rename DisableTHPStackMitigation flag to THPStackMitigation - - JDK-8312591: GCC 6 build failure after JDK-8280982 - - JDK-8312619: Strange error message when switching over long - - JDK-8312620: WSL Linux build crashes after JDK-8310233 - - JDK-8312625: Test serviceability/dcmd/vm/TrimLibcHeapTest.java failed: RSS use increased - - JDK-8312909: C1 should not inline through interface calls with non-subtype receiver - - JDK-8312976: MatchResult produces StringIndexOutOfBoundsException for groups outside match - - JDK-8312984: javac may crash on a record pattern with too few components - - JDK-8313081: MonitoringSupport_lock should be unconditionally initialized after 8304074 - - JDK-8313248: C2: setScopedValueCache intrinsic exposes nullptr pre-values to store barriers - - JDK-8313262: C2: Sinking node may cause required cast to be dropped - - JDK-8313307: java/util/Formatter/Padding.java fails on some Locales - - JDK-8313312: Add missing classpath exception copyright header - - JDK-8313323: javac -g on a java file which uses unnamed variable leads to ClassFormatError when launching that class - - JDK-8313402: C1: Incorrect LoadIndexed value numbering - - JDK-8313428: GHA: Bump GCC versions for July 2023 updates - - JDK-8313576: GCC 7 reports compiler warning in bundled freetype 2.13.0 - - JDK-8313602: increase timeout for jdk/classfile/CorpusTest.java - - JDK-8313626: C2 crash due to unexpected exception control flow - - JDK-8313657: com.sun.jndi.ldap.Connection.cleanup does not close connections on SocketTimeoutErrors - - JDK-8313676: Amend TestLoadIndexedMismatch test to target intrinsic directly - - JDK-8313678: SymbolTable can leak Symbols during cleanup - - JDK-8313691: use close after failing os::fdopen in vmError and ciEnv - - JDK-8313701: GHA: RISC-V should use the official repository for bootstrap - - JDK-8313707: GHA: Bootstrap sysroots with --variant=minbase - - JDK-8313752: InstanceKlassFlags::print_on doesn't print the flag names - - JDK-8313765: Invalid CEN header (invalid zip64 extra data field size) - - JDK-8313796: AsyncGetCallTrace crash on unreadable interpreter method pointer - - JDK-8313874: JNI NewWeakGlobalRef throws exception for null arg - - JDK-8313901: [TESTBUG] test/hotspot/jtreg/compiler/codecache/CodeCacheFullCountTest.java fails with java.lang.VirtualMachineError - - JDK-8313904: [macos] All signing tests which verifies unsigned app images are failing - - JDK-8314020: Print instruction blocks in byte units - - JDK-8314024: SIGSEGV in PhaseIdealLoop::build_loop_late_post_work due to bad immediate dominator info - - JDK-8314063: The socket is not closed in Connection::createSocket when the handshake failed for LDAP connection - - JDK-8314117: RISC-V: Incorrect VMReg encoding in RISCV64Frame.java - - JDK-8314118: Update JMH devkit to 1.37 - - JDK-8314139: TEST_BUG: runtime/os/THPsInThreadStackPreventionTest.java could fail on machine with large number of cores - - JDK-8314144: gc/g1/ihop/TestIHOPStatic.java fails due to extra concurrent mark with -Xcomp - - JDK-8314216: Case enumConstant, pattern compilation fails - - JDK-8314262: GHA: Cut down cross-compilation sysroots deeper - - JDK-8314423: Multiple patterns without unnamed variables - - JDK-8314426: runtime/os/TestTrimNative.java is failing on slow machines - - JDK-8314501: Shenandoah: sun/tools/jhsdb/heapconfig/JMapHeapConfigTest.java fails - - JDK-8314517: some tests fail in case ipv6 is disabled on the machine - - JDK-8314618: RISC-V: -XX:MaxVectorSize does not work as expected - - JDK-8314656: GHA: No need for Debian ports keyring installation after JDK-8313701 - - JDK-8314679: SA fails to properly attach to JVM after having just detached from a different JVM - - JDK-8314730: GHA: Drop libfreetype6-dev transitional package in favor of libfreetype-dev - - JDK-8314850: SharedRuntime::handle_wrong_method() gets called too often when resolving Continuation.enter - - JDK-8314960: Add Certigna Root CA - 2 - - JDK-8315020: The macro definition for LoongArch64 zero build is not accurate. - - JDK-8315051: jdk/jfr/jvm/TestGetEventWriter.java fails with non-JVMCI GCs - - JDK-8315534: Incorrect warnings about implicit annotation processing + - CVE-2025-53057 + - CVE-2025-53066 + - CVE-2025-61748 +* Changes + - JDK-8315131: Clarify VarHandle set/get access on 32-bit platforms + - JDK-8352637: Enhance bytecode verification + - JDK-8356294: Enhance Path Factories + - JDK-8356587: Missing object ID X in pool jdk.types.Method + - JDK-8357826: Avoid running some jtreg tests when asan is configured + - JDK-8358452: JNI exception pending in Java_sun_awt_screencast_ScreencastHelper_remoteDesktopKeyImpl of screencast_pipewire.c:1214 (ID: 51119) + - JDK-8358577: Test serviceability/jvmti/thread/GetCurrentContendedMonitor/contmon01/contmon01.java failed: unexpexcted monitor object + - JDK-8358819: The first year is not displayed correctly in Japanese Calendar + - JDK-8359059: Bump version numbers for 25.0.1 + - JDK-8359218: RISC-V: Only enable CRC32 intrinsic when AvoidUnalignedAccess == false + - JDK-8359270: C2: alignment check should consider base offset when emitting arraycopy runtime call + - JDK-8359454: Enhance String handling + - JDK-8359596: Behavior change when both -Xlint:options and -Xlint:-options flags are given + - JDK-8360179: RISC-V: Only enable BigInteger intrinsics when AvoidUnalignedAccess == false + - JDK-8360533: ContainerRuntimeVersionTestUtils fromVersionString fails with some docker versions + - JDK-8360647: [XWayland] [OL10] NumPad keys are not triggered + - JDK-8360679: Shenandoah: AOT saved adapter calls into broken GC barrier stub + - JDK-8360937: Enhance certificate handling + - JDK-8361212: Remove AffirmTrust root CAs + - JDK-8361532: RISC-V: Several vector tests fail after JDK-8354383 + - JDK-8361829: [TESTBUG] RISC-V: compiler/vectorization/runner/BasicIntOpTest.java fails with RVV but not Zvbb + - JDK-8362109: Change milestone to fcs for all releases + - JDK-8362882: Update SubmissionPublisher() specification to reflect use of ForkJoinPool.asyncCommonPool() + - JDK-8366223: ZGC: ZPageAllocator::cleanup_failed_commit_multi_partition is broken + - JDK-8367031: [backout] Change java.time month/day field types to 'byte' + - JDK-8368308: ISO 4217 Amendment 180 Update Notes on individual issues: =========================== -core-libs/java.util.jar: +core-libs/java.io:serialization: -JDK-8313765: Invalid CEN header (invalid zip64 extra data field size) -===================================================================== -Additional validity checks in the handling of Zip64 files, -JDK-8302483, introduced in 21.0.0, caused the use of some valid zip -files to now fail with the error, `Invalid CEN header (invalid zip64 -extra data field size)` +JDK-8367031: [backout] Change java.time month/day field types to 'byte' +======================================================================= +In the initial release of OpenJDK 25, attempting to read serialised +Class objects created by earlier versions of OpenJDK for several of +the `java.time` classes would fail with a +`InvalidClassException`. Similarly, `java.time` Class objects +serialised with OpenJDK 25 could not be read by older OpenJDK +versions. This was due to the type of the day and month fields in +these classes being changed to `byte`. This change has now been +reverted and compatibility between OpenJDK 25 and older versions +restored. -This release, 21.0.1, allows for zero length headers and additional -padding produced by some Zip64 creation tools. +Note that this incompatibility occurred with the `Class` object and +not an instance of the object i.e. `writeObject(LocalDate.class)` +would produce incompatible serialised data, but +`writeObject(LocalDate.now())` would not. -The following third party tools have also released patches to better -adhere to the ZIP File Format Specification: +security-libs/java.security: -* Apache Commons Compress fix for Empty CEN Zip64 Extra Headers fixed in Commons Compress release 1.11 -* Apache Ant fix for Empty CEN Zip64 Extra Headers fixed in Ant 1.10.14 -* BND issue with writing invalid Extra Headers fixed in BND 5.3 +JDK-8361212: Remove AffirmTrust root CAs +======================================== +The following root certificates from AffirmTrust, which were +deactivated in the 21.0.5 release of October 2024, have been removed +from the `cacerts` keystore: -The maven-bundle-plugin 5.1.5 includes the BND 5.3 patch. +Alias name: affirmtrustcommercialca [jdk] +CN=AffirmTrust Commercial +O=AffirmTrust +C=US +SHA256: 03:76:AB:1D:54:C5:F9:80:3C:E4:B2:E2:01:A0:EE:7E:EF:7B:57:B6:36:E8:A9:3C:9B:8D:48:60:C9:6F:5F:A7 -If these improved validation checks cause issues for deployed zip or -jar files, check how the file was created and whether patches are -available from the generating software to resolve the issue. With -both JDK releases, the checks can be disabled by setting the new -system property, `jdk.util.zip.disableZip64ExtraFieldValidation` to -`true`. +Alias name: affirmtrustnetworkingca [jdk] +CN=AffirmTrust Networking +O=AffirmTrust +C=US +SHA256: 0A:81:EC:5A:92:97:77:F1:45:90:4A:F3:8D:5D:50:9F:66:B5:E2:C5:8F:CD:B5:31:05:8B:0E:17:F3:F0B4:1B -hotspot/runtime: +Alias name: affirmtrustpremiumca [jdk] +CN=AffirmTrust Premium +O=AffirmTrust +C=US +SHA256: 70:A7:3F:7F:37:6B:60:07:42:48:90:45:34:B1:14:82:D5:BF:0E:69:8E:CC:49:8D:F5:25:77:EB:F2:E9:3B:9A -JDK-8311981: JVM May Hang When Using Generational ZGC if a VM Handshake Stalls on Memory -======================================================================================== -The JVM can hang under an uncommon condition that involves the JVM -running out of heap memory, the GC just starting a relocation phase to -reclaim memory, and a JVM thread-local Handshake asking to relocate an -object. This potential deadlock should now be avoided in this -release. +Alias name: affirmtrustpremiumeccca [jdk] +CN=AffirmTrust Premium ECC +O=AffirmTrust +C=US +SHA256: BD:71:FD:F6:DA:97:E4:CF:62:D1:64:7A:DD:25:81:B0:7D:79:AD:F8:39:7E:B4:EC:BA:9C:5E:84:88:82:14:23 -core-libs/java.util.regex: - -JDK-8312976: `java.util.regex.MatchResult` Might Throw `StringIndexOutOfBoundsException` on Regex Patterns Containing Lookaheads and Lookbehinds -================================================================================================================================================ -JDK-8132995 introduced an unintended regression when using instances -returned by `java.util.regex.Matcher.toMatchResult()`. - -This regression happens with a `java.util.regex.Pattern`s containing -lookaheads and lookbehinds that, in turn, contain groups. If these are -located outside the match, a `StringIndexOutOfBoundsException` is -thrown when accessing these groups. See JDK-8312976 for an example. - -The issue is resolved in this release by calculating a minimum start -location as part of the match result and using this in constructing -String objects, rather than the location of the first match. - -JDK-8314960: Added Certigna Root CA Certificate -=============================================== -The following root certificate has been added to the cacerts -truststore: - -Name: Certigna (Dhimyotis) -Alias Name: certignarootca -Distinguished Name: CN=Certigna Root CA, OU=0002 48146308100036, O=Dhimyotis, C=FR - -JDK-8312489: Increase Default Value of the System Property `jdk.jar.maxSignatureFileSize` -========================================================================================= -A maximum signature file size property, jdk.jar.maxSignatureFileSize, -was introduced in the 21.0.0 release of OpenJDK by JDK-8300596 to -control the maximum size of signature files in a signed JAR. The -default value of 8MB proved to be too small for some JAR files. This -release, 21.0.1, increases it to 16MB. - -New in release OpenJDK 21.0.0 (2023-09-XX): +New in release OpenJDK 25.0.0 (2025-09-16): =========================================== Major changes are listed below. Some changes may have been backported -to earlier releases following their first appearance in OpenJDK 18 -through to 21. +to earlier releases following their first appearance in OpenJDK 22 +through to 25. NEW FEATURES ============ @@ -214,99 +104,124 @@ NEW FEATURES Language Features ================= -Pattern Matching for switch -=========================== -https://openjdk.org/jeps/406 -https://openjdk.org/jeps/420 -https://openjdk.org/jeps/427 -https://openjdk.org/jeps/433 -https://openjdk.org/jeps/441 +Flexible Constructor Bodies +============================ +https://openjdk.org/jeps/447 +https://openjdk.org/jeps/482 +https://openjdk.org/jeps/492 +https://openjdk.org/jeps/513 -Enhance the Java programming language with pattern matching for -`switch` expressions and statements, along with extensions to the -language of patterns. Extending pattern matching to `switch` allows an -expression to be tested against a number of patterns, each with a -specific action, so that complex data-oriented queries can be -expressed concisely and safely. +In constructors in the Java programming language, allow statements to +appear before an explicit constructor invocation, i.e., super(..) or +this(..). The statements cannot reference the instance under +construction, but they can initialize its fields. Initializing fields +before invoking another constructor makes a class more reliable when +methods are overridden. -This was a preview feature (http://openjdk.java.net/jeps/12) -introduced in OpenJDK 17 (JEP 406), which saw a second preview in -OpenJDK 18 (JEP 420), a third in OpenJDK 19 (JEP 427) and a fourth -(JEP 427) in OpenJDK 20. It became final with OpenJDK 21 (JEP 441). - -Record Patterns -=============== -https://openjdk.org/jeps/405 -https://openjdk.org/jeps/432 -https://openjdk.org/jeps/440 - -Enhance the Java programming language with record patterns to -deconstruct record values. Record patterns and type patterns can be -nested to enable a powerful, declarative, and composable form of data -navigation and processing. - -This was a preview feature (http://openjdk.java.net/jeps/12) introduced -in OpenJDK 19 (JEP 405) with a second preview (JEP 432) in OpenJDK 20. -It became final with OpenJDK 21 (JEP 440). - -String Templates -================ -https://openjdk.org/jeps/430 - -Enhance the Java programming language with string templates. String -templates complement Java's existing string literals and text blocks -by coupling literal text with embedded expressions and template -processors to produce specialized results. - -This is a preview feature (http://openjdk.java.net/jeps/12) introduced -in OpenJDK 21 (JEP 430). +This language feature is now finalised (JEP 513). It was first +introduced as a preview language feature +(http://openjdk.java.net/jeps/12) in OpenJDK 22 (JEP 447) under the +name "Statements before super(...)". It reached a second preview in +OpenJDK 23 (JEP 482) with the addition of allowing fields to be +initialized before invoking another constructor. It reached a third +preview in OpenJDK 24 (JEP 492). Unnamed Patterns and Variables ============================== https://openjdk.org/jeps/443 +https://openjdk.org/jeps/456 Enhance the Java language with unnamed patterns, which match a record component without stating the component's name or type, and unnamed variables, which can be initialized but not used. Both are denoted by an underscore character, _. -This is a preview feature (http://openjdk.java.net/jeps/12) introduced -in OpenJDK 21 (JEP 443). +This feature is now finalised (JEP 456). It was a preview feature +(http://openjdk.java.net/jeps/12) in OpenJDK 21 (JEP 443). -Unnamed Classes and Instance Main Methods (Preview) +Primitive Types in Patterns, instanceof, and switch =================================================== -https://openjdk.org/jeps/445 +https://openjdk.org/jeps/455 +https://openjdk.org/jeps/488 +https://openjdk.org/jeps/507 -Evolve the Java language so that students can write their first -programs without needing to understand language features designed for -large programs. Far from using a separate dialect of Java, students -can write streamlined declarations for single-class programs and then -seamlessly expand their programs to use more advanced features as -their skills grow. +Enhance pattern matching by allowing primitive type patterns in all +pattern contexts, and extend instanceof and switch to work with all +primitive types. -This is a preview feature (http://openjdk.java.net/jeps/12) introduced -in OpenJDK 21 (JEP 445). +This is a preview language feature (http://openjdk.java.net/jeps/12) +introduced in OpenJDK 23 (JEP 455) with a second preview in OpenJDK 24 +(JEP 488) and reaching a third in OpenJDK 25 (JEP 507). + +Module Import Declarations +========================== +https://openjdk.org/jeps/476 +https://openjdk.org/jeps/494 +https://openjdk.org/jeps/511 + +Enhance the Java programming language with the ability to succinctly +import all of the packages exported by a module. This simplifies the +reuse of modular libraries, but does not require the importing code to +be in a module itself. + +This language feature is now finalised (JEP 511). It was introduced as +a preview language feature (http://openjdk.java.net/jeps/12) in +OpenJDK 23 (JEP 476) and had a second preview in OpenJDK 24 (JEP 494). Library Features ================ -UTF-8 by Default -================ -https://openjdk.org/jeps/400 +Foreign Function & Memory API +============================= +https://openjdk.org/jeps/412 +https://openjdk.org/jeps/419 +https://openjdk.org/jeps/424 +https://openjdk.org/jeps/434 +https://openjdk.org/jeps/442 +https://openjdk.org/jeps/454 -Specify UTF-8 as the default charset of the standard Java APIs. With -this change, APIs that depend upon the default charset will behave -consistently across all implementations, operating systems, locales, -and configurations. +Introduce an API by which Java programs can interoperate with code and +data outside of the Java runtime. By efficiently invoking foreign +functions (i.e., code outside the JVM), and by safely accessing +foreign memory (i.e., memory not managed by the JVM), the API enables +Java programs to call native libraries and process native data without +the brittleness and danger of JNI. -Reimplement Core Reflection with Method Handles -=============================================== -https://openjdk.org/jeps/416 +This API is now finalised (JEP 454). It was first introduced in +incubation (https://openjdk.java.net/jeps/11) in OpenJDK 17 (JEP 412), +and is an evolution of the Foreign Memory Access API (OpenJDK 14 +through 16) and Foreign Linker API (OpenJDK 16) (see release notes for +java-17-openjdk). OpenJDK 18 saw a second round of incubation (JEP +419) before its inclusion as a preview feature +(http://openjdk.java.net/jeps/12) in OpenJDK 19 (JEP 424). A second +preview took place in OpenJDK 20 (JEP 434) and a third and final +preview in OpenJDK 21 (JEP 442). -Reimplement java.lang.reflect.Method, Constructor, and Field on top of -java.lang.invoke method handles. Making method handles the underlying -mechanism for reflection will reduce the maintenance and development -cost of both the java.lang.reflect and java.lang.invoke APIs. +Prepare to Restrict the Use of JNI +================================== +https://openjdk.org/jeps/472 + +Issue warnings about uses of the Java Native Interface (JNI) and +adjust the Foreign Function & Memory (FFM) API to issue warnings in a +consistent manner. All such warnings aim to prepare developers for a +future release that ensures integrity by default by uniformly +restricting JNI and the FFM API. Application developers can avoid both +current warnings and future restrictions by selectively enabling these +interfaces where essential using the --enable-native-access +command-line option. + +Class-File API +============== +https://openjdk.org/jeps/457 +https://openjdk.org/jeps/466 +https://openjdk.org/jeps/484 + +Provide a standard API for parsing, generating, and transforming Java +class files. + +This API is now finalised (JEP 484). It was introduced as a preview +library feature (http://openjdk.java.net/jeps/12) in OpenJDK 22 (JEP +457) with a second preview in OpenJDK 23 (JEP 466). Vector API ========== @@ -316,6 +231,10 @@ https://openjdk.org/jeps/417 https://openjdk.org/jeps/426 https://openjdk.org/jeps/438 https://openjdk.org/jeps/448 +https://openjdk.org/jeps/460 +https://openjdk.org/jeps/469 +https://openjdk.org/jeps/489 +https://openjdk.org/jeps/508 Introduce an API to express vector computations that reliably compile at runtime to optimal vector hardware instructions on supported CPU @@ -325,61 +244,34 @@ scalar computations. This is an incubation feature (https://openjdk.java.net/jeps/11) introduced in OpenJDK 16 (JEP 338). A second round of incubation took place in OpenJDK 17 (JEP 414), OpenJDK 18 (JEP 417) saw a third, -OpenJDK 19 a fourth (JEP 426), OpenJDK 20 (JEP 438) a fifth and -OpenJDK 21 a sixth (JEP 448). +OpenJDK 19 a fourth (JEP 426), OpenJDK 20 (JEP 438) a fifth, OpenJDK +21 a sixth (JEP 448), OpenJDK 22 a seventh (JEP 460), OpenJDK 23 an +eighth (JEP 469), OpenJDK 24 a ninth (JEP 489) and it reaches its +tenth in OpenJDK 25 (JEP 508). -Internet-Address Resolution SPI -=============================== -https://openjdk.org/jeps/418 +Stream Gatherers +================ +https://openjdk.org/jeps/461 +https://openjdk.org/jeps/473 +https://openjdk.org/jeps/485 -Define a service-provider interface (SPI) for host name and address -resolution, so that java.net.InetAddress can make use of resolvers -other than the platform's built-in resolver. +Enhance the Stream API to support custom intermediate operations. This +will allow stream pipelines to transform data in ways that are not +easily achievable with the existing built-in intermediate operations. -Foreign Function & Memory API -============================= -https://openjdk.org/jeps/412 -https://openjdk.org/jeps/419 -https://openjdk.org/jeps/424 -https://openjdk.org/jeps/434 -https://openjdk.org/jeps/442 - -Introduce an API by which Java programs can interoperate with code and -data outside of the Java runtime. By efficiently invoking foreign -functions (i.e., code outside the JVM), and by safely accessing -foreign memory (i.e., memory not managed by the JVM), the API enables -Java programs to call native libraries and process native data without -the brittleness and danger of JNI. - -This API is now a preview feature (http://openjdk.java.net/jeps/12). -It was first introduced in incubation -(https://openjdk.java.net/jeps/11) in OpenJDK 17 (JEP 412), and is an -evolution of the Foreign Memory Access API (OpenJDK 14 through 16) and -Foreign Linker API (OpenJDK 16) (see release notes for -java-17-openjdk). OpenJDK 18 saw a second round of incubation (JEP -419) before its inclusion as a preview in OpenJDK 19 (JEP 424) and a -second in OpenJDK 20 (JEP 434). It reaches a third preview in OpenJDK -21 (JEP 442). - -Virtual Threads -=============== -https://openjdk.org/jeps/425 -https://openjdk.org/jeps/436 -https://openjdk.org/jeps/444 - -Introduce virtual threads to the Java Platform. Virtual threads are -lightweight threads that dramatically reduce the effort of writing, -maintaining, and observing high-throughput concurrent applications. - -This was a preview feature (http://openjdk.java.net/jeps/12) -introduced in OpenJDK 19 (JEP 425) and reaching its second preview in -OpenJDK 20 (JEP 436). It became final with OpenJDK 21 (JEP 444). +This API is now finalised (JEP 485). It was introduced as a preview +library feature (http://openjdk.java.net/jeps/12) in OpenJDK 22 (JEP +461) with a second preview in OpenJDK 23 (JEP 473). Structured Concurrency ====================== https://openjdk.org/jeps/428 https://openjdk.org/jeps/437 https://openjdk.org/jeps/453 +https://openjdk.org/jeps/462 +https://openjdk.org/jeps/480 +https://openjdk.org/jeps/499 +https://openjdk.org/jeps/505 Simplify multithreaded programming by introducing an API for structured concurrency. Structured concurrency treats multiple tasks @@ -387,115 +279,392 @@ running in different threads as a single unit of work, thereby streamlining error handling and cancellation, improving reliability, and enhancing observability. -This API is now a preview feature (http://openjdk.java.net/jeps/12) in -OpenJDK 21 (JEP 453). It was first introduced in incubation +This API was first introduced in incubation (https://openjdk.java.net/jeps/11) in OpenJDK 19 (JEP 428) and had a -second round of incubation in OpenJDK 20 (JEP 437). +second round of incubation in OpenJDK 20 (JEP 437). It became a +preview feature (http://openjdk.java.net/jeps/12) in OpenJDK 21 (JEP +453), reached its second preview in OpenJDK 22 (JEP 462), had a third +preview in OpenJDK 23 (JEP 480), a fourth in OpenJDK 24 (JEP 499) and +reaches its fifth in OpenJDK 25 (JEP 505). + +Compact Source Files and Instance Main Methods +============================================== +https://openjdk.org/jeps/445 +https://openjdk.org/jeps/463 +https://openjdk.org/jeps/477 +https://openjdk.org/jeps/495 +https://openjdk.org/jeps/512 + +Evolve the Java programming language so that beginners can write their +first programs without needing to understand language features +designed for large programs. Far from using a separate dialect of the +language, beginners can write streamlined declarations for +single-class programs and then seamlessly expand their programs to use +more advanced features as their skills grow. Experienced developers +can likewise enjoy writing small programs succinctly, without the need +for constructs intended for programming in the large. + +This library feature is now finalised (JEP 512) with some minor +changes from the last release. It was first introduced as a preview +(http://openjdk.java.net/jeps/12) in OpenJDK 21 (JEP 445) under the +name "Unnamed Classes and Instance Main Methods". It reached a second +preview in OpenJDK 22 (JEP 463) and a third in OpenJDK 23 (JEP 477) +under the new name, "Implicitly Declared Classes and Instance Main +Methods", due to the move away from unnamed classes to an implicitly +declared name chosen by the host system. It had a fourth preview in +OpenJDK 24 (JEP 495) with new terminology and a revised title ("Simple +Source Files and Instance Main Methods"), but otherwise unchanged. Scoped Values ============= https://openjdk.org/jeps/429 +https://openjdk.org/jeps/446 +https://openjdk.org/jeps/464 +https://openjdk.org/jeps/481 +https://openjdk.org/jeps/487 +https://openjdk.org/jeps/506 Introduce scoped values, which enable the sharing of immutable data within and across threads. They are preferred to thread-local variables, especially when using large numbers of virtual threads. -This API is now a preview feature (http://openjdk.java.net/jeps/12) -in OpenJDK 21 (JEP 429). It was first introduced in incubation -(https://openjdk.java.net/jeps/11) in OpenJDK 20 (JEP 429). +This API is now finalised (JEP 506). This API was first introduced in +incubation (https://openjdk.java.net/jeps/11) in OpenJDK 20 (JEP +429). It became a preview feature (http://openjdk.java.net/jeps/12) in +OpenJDK 21 (JEP 446), had a second preview in OpenJDK 22 (JEP 464), a +third in OpenJDK 23 (JEP 481) and a fourth in OpenJDK 24 (JEP 487). -Sequenced Collections -===================== -https://openjdk.org/jeps/431 +Key Derivation Function API +=========================== +https://openjdk.org/jeps/478 +https://openjdk.org/jeps/510 -Introduce new interfaces to represent collections with a defined -encounter order. Each such collection has a well-defined first -element, second element, and so forth, up to the last element. It also -provides uniform APIs for accessing its first and last elements, and -for processing its elements in reverse order. +Introduce an API for Key Derivation Functions (KDFs), which are +cryptographic algorithms for deriving additional keys from a secret +key and other data. -Key Encapsulation Mechanism API -=============================== -https://openjdk.org/jeps/452 +This API is now finalised (JEP 510). It was first introduced as a +preview library feature (http://openjdk.java.net/jeps/12) in OpenJDK +24 (JEP 478). -Introduce an API for key encapsulation mechanisms (KEMs), an -encryption technique for securing symmetric keys using public key -cryptography. +Quantum-Resistant Module-Lattice-Based Key Encapsulation Mechanism +================================================================== +https://openjdk.org/jeps/496 + +Enhance the security of Java applications by providing an +implementation of the quantum-resistant Module-Lattice-Based +Key-Encapsulation Mechanism (ML-KEM). Key encapsulation mechanisms +(KEMs) are used to secure symmetric keys over insecure communication +channels using public key cryptography. ML-KEM is designed to be +secure against future quantum computing attacks. It has been +standardized by the United States National Institute of Standards and +Technology (NIST) in FIPS 203 [0]. + +[0] https://csrc.nist.gov/pubs/fips/203/final + +Quantum-Resistant Module-Lattice-Based Digital Signature Algorithm +================================================================== +https://openjdk.org/jeps/497 + +Enhance the security of Java applications by providing an +implementation of the quantum-resistant Module-Lattice-Based Digital +Signature Algorithm (ML-DSA). Digital signatures are used to detect +unauthorized modifications to data and to authenticate the identity of +signatories. ML-DSA is designed to be secure against future quantum +computing attacks. It has been standardized by the United States +National Institute of Standards and Technology (NIST) in FIPS 204 [0]. + +[0] https://csrc.nist.gov/pubs/fips/204/final + +PEM Encodings of Cryptographic Objects +====================================== +https://openjdk.org/jeps/470 + +Introduce an API for encoding objects that represent cryptographic +keys, certificates, and certificate revocation lists into the +widely-used Privacy-Enhanced Mail (PEM) transport format, and for +decoding from that format back into objects. + +This is a preview library feature (http://openjdk.java.net/jeps/12) +introduced in OpenJDK 25 (JEP 470). + +Stable Values +============= +https://openjdk.org/jeps/502 + +Introduce an API for stable values, which are objects that hold +immutable data. Stable values are treated as constants by the JVM, +enabling the same performance optimizations that are enabled by +declaring a field final. Compared to final fields, however, stable +values offer greater flexibility as to the timing of their +initialization. + +This is a preview library feature (http://openjdk.java.net/jeps/12) +introduced in OpenJDK 25 (JEP 502). Virtual Machine Enhancements ============================ -Generational ZGC -================ -https://openjdk.org/jeps/439 +Region Pinning for G1 +===================== +https://openjdk.org/jeps/423 -Improve application performance by extending the Z Garbage Collector -(ZGC) to maintain separate generations for young and old objects. This -will allow ZGC to collect young objects — which tend to die young — -more frequently. +Reduce latency by implementing region pinning in G1, so that garbage +collection need not be disabled during Java Native Interface (JNI) +critical regions. + +ZGC: Generational Mode by Default +================================= +https://openjdk.org/jeps/439 +https://openjdk.org/jeps/474 + +Switch the default mode of the Z Garbage Collector (ZGC) to the +generational mode. Deprecate the non-generational mode, with the +intent to remove it in a future release. + +Late Barrier Expansion for G1 +============================= +https://openjdk.org/jeps/475 + +Simplify the implementation of the G1 garbage collector's barriers, +which record information about application memory accesses, by +shifting their expansion from early in the C2 JIT's compilation +pipeline to later. + +Ahead-of-Time Class Loading & Linking +===================================== +https://openjdk.org/jeps/483 +https://openjdk.org/jeps/514 + +Improve startup time by making the classes of an application instantly +available, in a loaded and linked state, when the HotSpot Java Virtual +Machine starts. Achieve this by monitoring the application during one +run and storing the loaded and linked forms of all classes in a cache +for use in subsequent runs. Lay a foundation for future improvements +to both startup and warmup time. + +Using this feature requires a two stage process: + +1. Create the Ahead-of-Time cache from a training run of the +application using the option `--XX:AOTCacheOutput=` where +`` is the cache reference to use in later runs. + +2. When running the application in testing or production, use the +option `-XX:AOTCache=` to run the application with the +cache generated in #2. + +Previously, in OpenJDK 24 (JEP 483), the training run and cache +creation were handled by two separate steps: + +1. Populate the Ahead-of-Time configuration data with a training run +of the application using the options `-XX:AOTMode=record +-XX:AOTConfiguration=` where `` is the +configuration reference to use in #2. + +2. Create the Ahead-of-Time cache using the options +`-XX:AOTMode=create -XX:AOTConfiguration= +-XX:AOTCache=` where `` is the configuration +reference from #1 and `` is the cache reference to use in +later runs. + +JEP 514 ("Ahead-of-Time Command-Line Ergonomics") in OpenJDK 25 adds +the option `--XX:AOTCacheOutput` which performs both the above steps +from a single command-line invocation using a temporary configuration +file. A new environment variable, `JDK_AOT_VM_OPTIONS`, can be used +to pass options to the cache creation step without affecting the +training run step. + +Ahead-of-Time Method Profiling +============================== +https://openjdk.org/jeps/515 + +Improve warmup time by making method-execution profiles from a +previous run of an application instantly available, when the HotSpot +Java Virtual Machine starts. This will enable the JIT compiler to +generate native code immediately upon application startup, rather than +having to wait for profiles to be collected. + +Synchronize Virtual Threads without Pinning +=========================================== +https://openjdk.org/jeps/491 + +Improve the scalability of Java code that uses synchronized methods +and statements by arranging for virtual threads that block in such +constructs to release their underlying platform threads for use by +other virtual threads. This will eliminate nearly all cases of virtual +threads being pinned to platform threads, which severely restricts the +number of virtual threads available to handle an application's +workload. + +Compact Object Headers +====================== +https://openjdk.org/jeps/450 +https://openjdk.org/jeps/519 + +Reduce the size of object headers in the HotSpot JVM from between 96 +and 128 bits down to 64 bits on 64-bit architectures. This will reduce +heap size, improve deployment density, and increase data locality. + +This is now a production feature in OpenJDK 25 (JEP 519) enabled using +`-XX:+UseCompactObjectHeaders`. It was first introduced as an +experimental feature (JEP 450) that also required the use of +`-XX:+UnlockExperimentalVMOptions`. + +Generational Shenandoah +======================= +https://openjdk.org/jeps/404 +https://openjdk.org/jeps/521 + +Enhance the Shenandoah garbage collector with experimental +generational collection capabilities to improve sustainable +throughput, load-spike resilience, and memory utilization. + +This is now a production feature in OpenJDK 25 (JEP 521) enabled using +`-XX:ShenandoahGCMode=generational`. It was first introduced as an +experimental feature (JEP 404) that also required the use of +`-XX:+UnlockExperimentalVMOptions`. + +JFR Cooperative Sampling +======================== +https://openjdk.org/jeps/518 + +Improve the stability of the JDK Flight Recorder (JFR) when it +asynchronously samples Java thread stacks. Achieve this by walking +call stacks only at safepoints, while minimizing safepoint bias. + +JFR Method Timing & Tracing +=========================== +https://openjdk.org/jeps/520 + +Extend the JDK Flight Recorder (JFR) with facilities for method timing +and tracing via bytecode instrumentation. + +JFR CPU-Time Profiling +====================== +https://openjdk.org/jeps/509 + +Enhance the JDK Flight Recorder (JFR) to capture more accurate +CPU-time profiling information on Linux. + +This is an experimental feature so its JFR events are tagged with the +`@Experimental` annotation. Unlike other experimental virtual machine +features, it does not need to be explicitly enabled with +`-XX:+UnlockExperimentalVMOptions`. Tools ===== -Simple Web Server -================= -https://openjdk.org/jeps/408 +Launch Multi-File Source-Code Programs +====================================== +https://openjdk.org/jeps/458 -Provide a command-line tool, `jwebserver`, to start a minimal web -server that serves static files only. No CGI or servlet-like -functionality is available. This tool will be useful for prototyping, -ad-hoc coding, and testing purposes, particularly in educational -contexts. +Enhance the java application launcher to be able to run a program +supplied as multiple files of Java source code. This will make the +transition from small programs to larger ones more gradual, enabling +developers to choose whether and when to go to the trouble of +configuring a build tool. -Code Snippets in Java API Documentation -======================================= -https://openjdk.org/jeps/413 +Markdown Documentation Comments +=============================== +https://openjdk.org/jeps/467 -Introduce an @snippet tag for JavaDoc's Standard Doclet, to simplify -the inclusion of example source code in API documentation. +Enable JavaDoc documentation comments to be written in Markdown rather +than solely in a mixture of HTML and JavaDoc @-tags. -Ports -===== +Linking Run-Time Images without JMODs +===================================== +https://openjdk.org/jeps/493 -Linux/RISC-V Port -================= -https://openjdk.org/jeps/422 +Reduce the size of the JDK by approximately 25% by enabling the jlink +tool to create custom run-time images without using the JDK's JMOD +files. -RISC-V is a free and open-source RISC instruction set architecture -(ISA) designed originally at the University of California, Berkeley, -and now developed collaboratively under the sponsorship of RISC-V -International. It is already supported by a wide range of language -toolchains. With the increasing availability of RISC-V hardware, a -port of the JDK would be valuable. +This feature must be enabled when the JDK is built using the +--enable-linkable-runtime option. It will not be enabled by default, +and some JDK vendors may choose not to enable it. DEPRECATIONS ============ -Deprecate Finalization for Removal -================================== -https://openjdk.org/jeps/421 +Deprecate the Memory-Access Methods in sun.misc.Unsafe for Removal +================================================================== +https://openjdk.org/jeps/471 -Deprecate finalization for removal in a future release. Finalization -remains enabled by default for now, but can be disabled to facilitate -early testing. In a future release it will be disabled by default, and -in a later release it will be removed. Maintainers of libraries and -applications that rely upon finalization should consider migrating to -other resource management techniques such as the try-with-resources -statement and cleaners. +Deprecate the memory-access methods in sun.misc.Unsafe for removal in +a future release. These unsupported methods have been superseded by +standard APIs, namely the VarHandle API (JEP 193, OpenJDK 9) and the +Foreign Function & Memory API (JEP 454, OpenJDK 22). We strongly +encourage library developers to migrate from sun.misc.Unsafe to +supported replacements, so that applications can migrate smoothly to +modern JDK releases. -Deprecate the Windows 32-bit x86 Port for Removal -================================================= +Warn upon Use of Memory-Access Methods in sun.misc.Unsafe +========================================================= +https://openjdk.org/jeps/498 + +Issue a warning at run time on the first occasion that any +memory-access method in sun.misc.Unsafe is invoked. All of these +unsupported methods were terminally deprecated in JDK 23 (see JEP 471 +above). They have been superseded by standard APIs, namely the +VarHandle API (JEP 193, OpenJDK 9) and the Foreign Function & Memory +API (JEP 454, OpenJDK 22). We strongly encourage library developers to +migrate from sun.misc.Unsafe to supported replacements, so that +applications can migrate smoothly to modern JDK releases. + +Permanently Disable the Security Manager +======================================== +https://openjdk.org/jeps/486 + +The Security Manager has not been the primary means of securing +client-side Java code for many years, it has rarely been used to +secure server-side code, and it is costly to maintain. We therefore +deprecated it for removal in OpenJDK 17 via JEP 411 (2021). As the +next step toward removing the Security Manager, we will revise the +Java Platform specification so that developers cannot enable it and +other Platform classes do not refer to it. This change will have no +impact on the vast majority of applications, libraries, and tools. We +will remove the Security Manager API in a future release. + +REMOVALS +======== + +String Templates +================ +https://openjdk.org/jeps/430 +https://openjdk.org/jeps/459 +https://openjdk.org/jeps/465 + +This was a preview feature (http://openjdk.java.net/jeps/12) +introduced in OpenJDK 21 (JEP 430) with a second preview in OpenJDK 22 +(JEP 459). A third preview was proposed but ultimately withdrawn for +OpenJDK 23 (JEP 465) and the feature is no longer present. See [0] +for further explanation. + +[0] https://mail.openjdk.org/pipermail/amber-spec-experts/2024-April/004106.html + +Remove the Windows & Linux 32-bit x86 Ports +=========================================== https://openjdk.org/jeps/449 +https://openjdk.org/jeps/479 +https://openjdk.org/jeps/501 +https://openjdk.org/jeps/503 -Deprecate the Windows 32-bit x86 port, with the intent to remove it in -a future release. +Remove the source code and build support for the Windows (JEP 479) & +Linux (JEP 503) 32-bit x86 ports. The Windows port was deprecated for +removal in JDK 21 by JEP 449 and the Linux port was deprecated for +removal in JDK 24 by JEP 501. Both deprecations took place with the +express intent to remove the ports in a future release. -Prepare to Disallow the Dynamic Loading of Agents -================================================= -https://openjdk.org/jeps/451 +Following this removal of these 32-bit x86 ports, the +architecture-agnostic Zero port is the only way to run Java programs +on 32-bit x86 processors. -Issue warnings when agents are loaded dynamically into a running -JVM. These warnings aim to prepare users for a future release which -disallows the dynamic loading of agents by default in order to improve -integrity by default. Serviceability tools that load agents at startup -will not cause warnings to be issued in any release. +ZGC: Remove the Non-Generational Mode +===================================== +https://openjdk.org/jeps/439 +https://openjdk.org/jeps/474 +https://openjdk.org/jeps/490 + +Remove the non-generational mode of the Z Garbage Collector (ZGC), +keeping the generational mode as the default for ZGC (see JEP 439 & +474). diff --git a/README.md b/README.md index 55536ce..9a97482 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,16 @@ +# java-latest-openjdk-portable + This package contains the latest rolling release of OpenJDK. OpenJDK has a release cadence of six months, with a new release in March and September each year. -The current release is OpenJDK 21. For a list of major changes from -OpenJDK 20, see the NEWS file included in this package and the +The current release is OpenJDK 25. For a list of major changes from +OpenJDK 21, see the NEWS file included in this package and the upstream release page: -https://openjdk.java.net/projects/jdk/21/ +https://openjdk.org/projects/jdk/25/ This package is intended for those who want to follow the latest OpenJDK releases. Long term support versions of OpenJDK are available -in the java-1.8.0-openjdk, java-11-openjdk and java-17-openjdk +in the java-1.8.0-openjdk, java-11-openjdk, java-17-openjdk and java-21-openjdk packages. diff --git a/TestTranslations.java b/TestTranslations.java index f6a4fe2..1b02c06 100644 --- a/TestTranslations.java +++ b/TestTranslations.java @@ -50,11 +50,11 @@ public class TestTranslations { "Mountain Daylight Time", "MDT", "MDT", "Mountain Time", "MT", "MT"}); map.put(Locale.FRANCE, new String[] { "heure normale des Rocheuses", "UTC\u221207:00", "MST", - "heure d\u2019\u00e9t\u00e9 des Rocheuses", "UTC\u221206:00", "MDT", - "heure des Rocheuses", "UTC\u221207:00", "MT"}); - map.put(Locale.GERMANY, new String[] { "Rocky-Mountain-Normalzeit", "GMT-07:00", "MST", - "Rocky-Mountain-Sommerzeit", "GMT-06:00", "MDT", - "Rocky-Mountain-Zeit", "GMT-07:00", "MT"}); + "heure d\u2019\u00e9t\u00e9 des Rocheuses", "UTC\u221206:00", "MST", + "heure des Rocheuses", "UTC\u221207:00", "MST"}); + map.put(Locale.GERMANY, new String[] { "Rocky-Mountains-Normalzeit", "GMT-07:00", "MST", + "Rocky-Mountains-Sommerzeit", "GMT-06:00", "MST", + "Rocky-Mountains-Zeit", "GMT-07:00", "MST"}); CIUDAD_JUAREZ = Collections.unmodifiableMap(map); } @@ -97,14 +97,10 @@ public class TestTranslations { System.out.printf("Checking locale %s for %s...\n", l, id); - if ("JRE".equals(localeProvider)) { + if ("JRE".equals(localeProvider) || "CLDR".equals(localeProvider)) { expectedShortStd = expected[2]; expectedShortDST = expected[5]; expectedShortGen = expected[8]; - } else if ("CLDR".equals(localeProvider)) { - expectedShortStd = expected[1]; - expectedShortDST = expected[4]; - expectedShortGen = expected[7]; } else { System.err.printf("Invalid locale provider %s\n", localeProvider); System.exit(3); diff --git a/fips-21u-75ffdc48eda.patch b/fips-21u-75ffdc48eda.patch deleted file mode 100644 index 8413fe1..0000000 --- a/fips-21u-75ffdc48eda.patch +++ /dev/null @@ -1,4233 +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 a1fc81564b1..ebad69d9dcf 100644 ---- a/make/autoconf/libraries.m4 -+++ b/make/autoconf/libraries.m4 -@@ -35,6 +35,7 @@ m4_include([lib-std.m4]) - m4_include([lib-x11.m4]) - - m4_include([lib-tests.m4]) -+m4_include([lib-sysconf.m4]) - - ################################################################################ - # Determine which libraries are needed for this configuration -@@ -134,6 +135,7 @@ AC_DEFUN_ONCE([LIB_SETUP_LIBRARIES], - LIB_SETUP_X11 - - LIB_TESTS_SETUP_GTEST -+ LIB_SETUP_SYSCONF_LIBS - - BASIC_JDKLIB_LIBS="" - BASIC_JDKLIB_LIBS_TARGET="" -diff --git a/make/autoconf/spec.gmk.in b/make/autoconf/spec.gmk.in -index 0f85917814e..9419562b654 100644 ---- a/make/autoconf/spec.gmk.in -+++ b/make/autoconf/spec.gmk.in -@@ -867,6 +867,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 9e5cfe2d0fc..434ade8e182 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 1e0f66726d0..59fe923f2c5 100644 ---- a/make/modules/java.base/Lib.gmk -+++ b/make/modules/java.base/Lib.gmk -@@ -163,6 +163,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/SunJCE.java b/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java -index 10093137151..b023c63ae58 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.*; - -@@ -82,6 +83,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; - -@@ -147,298 +152,299 @@ 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", "PBEWithHmacSHA512/224AndAES_128", -- "com.sun.crypto.provider.PBES2Core$HmacSHA512_224AndAES_128"); -- -- ps("Cipher", "PBEWithHmacSHA512/256AndAES_128", -- "com.sun.crypto.provider.PBES2Core$HmacSHA512_256AndAES_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"); -- -- ps("Cipher", "PBEWithHmacSHA512/224AndAES_256", -- "com.sun.crypto.provider.PBES2Core$HmacSHA512_224AndAES_256"); -- -- ps("Cipher", "PBEWithHmacSHA512/256AndAES_256", -- "com.sun.crypto.provider.PBES2Core$HmacSHA512_256AndAES_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", "PBEWithHmacSHA512/224AndAES_128", -+ "com.sun.crypto.provider.PBES2Core$HmacSHA512_224AndAES_128"); -+ -+ ps("Cipher", "PBEWithHmacSHA512/256AndAES_128", -+ "com.sun.crypto.provider.PBES2Core$HmacSHA512_256AndAES_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"); -+ -+ ps("Cipher", "PBEWithHmacSHA512/224AndAES_256", -+ "com.sun.crypto.provider.PBES2Core$HmacSHA512_224AndAES_256"); -+ -+ ps("Cipher", "PBEWithHmacSHA512/256AndAES_256", -+ "com.sun.crypto.provider.PBES2Core$HmacSHA512_256AndAES_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 -@@ -447,15 +453,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 -@@ -625,10 +633,10 @@ public final class SunJCE extends Provider { - "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA512AndAES_128"); - - ps("SecretKeyFactory", "PBEWithHmacSHA512/224AndAES_128", -- "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA512_224AndAES_128"); -+ "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA512_224AndAES_128"); - - ps("SecretKeyFactory", "PBEWithHmacSHA512/256AndAES_128", -- "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA512_256AndAES_128"); -+ "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA512_256AndAES_128"); - - ps("SecretKeyFactory", "PBEWithHmacSHA1AndAES_256", - "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA1AndAES_256"); -@@ -651,136 +659,137 @@ public final class SunJCE extends Provider { - ps("SecretKeyFactory", "PBEWithHmacSHA512/256AndAES_256", - "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA512_256AndAES_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"); -- ps("SecretKeyFactory", "PBKDF2WithHmacSHA512/224", -- "com.sun.crypto.provider.PBKDF2Core$HmacSHA512_224"); -- ps("SecretKeyFactory", "PBKDF2WithHmacSHA512/256", -- "com.sun.crypto.provider.PBKDF2Core$HmacSHA512_256"); -- -- /* -- * 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", "PBEWithHmacSHA512/224", -- "com.sun.crypto.provider.PBMAC1Core$HmacSHA512_224", null, attrs); -- ps("Mac", "PBEWithHmacSHA512/256", -- "com.sun.crypto.provider.PBMAC1Core$HmacSHA512_256", 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"); -- -- /* -- * KEMs -- */ -- attrs.clear(); -- attrs.put("ImplementedIn", "Software"); -- attrs.put("SupportedKeyClasses", "java.security.interfaces.ECKey" + -- "|java.security.interfaces.XECKey"); -- ps("KEM", "DHKEM", "com.sun.crypto.provider.DHKEM", null, attrs); -- -- /* -- * 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"); -+ ps("SecretKeyFactory", "PBKDF2WithHmacSHA512/224", -+ "com.sun.crypto.provider.PBKDF2Core$HmacSHA512_224"); -+ ps("SecretKeyFactory", "PBKDF2WithHmacSHA512/256", -+ "com.sun.crypto.provider.PBKDF2Core$HmacSHA512_256"); -+ -+ /* -+ * 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", "PBEWithHmacSHA512/224", -+ "com.sun.crypto.provider.PBMAC1Core$HmacSHA512_224", null, attrs); -+ ps("Mac", "PBEWithHmacSHA512/256", -+ "com.sun.crypto.provider.PBMAC1Core$HmacSHA512_256", 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"); -+ -+ /* -+ * KEMs -+ */ -+ attrs.clear(); -+ attrs.put("ImplementedIn", "Software"); -+ attrs.put("SupportedKeyClasses", "java.security.interfaces.ECKey" + -+ "|java.security.interfaces.XECKey"); -+ ps("KEM", "DHKEM", "com.sun.crypto.provider.DHKEM", null, attrs); -+ -+ /* -+ * 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 671529f71a1..af632936921 100644 ---- a/src/java.base/share/classes/java/security/Security.java -+++ b/src/java.base/share/classes/java/security/Security.java -@@ -34,6 +34,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; -@@ -58,6 +59,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"); -@@ -75,6 +81,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, -@@ -96,6 +115,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 -@@ -116,6 +136,61 @@ 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()) { -@@ -126,7 +201,7 @@ public final class Security { - - } - -- 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 919d758a6e3..b1e5fbaf84a 100644 ---- a/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java -+++ b/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java -@@ -43,6 +43,7 @@ import java.io.PrintStream; - import java.io.PrintWriter; - 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 -@@ -90,6 +91,7 @@ public class SharedSecrets { - private static JavaxCryptoSealedObjectAccess javaxCryptoSealedObjectAccess; - private static JavaxCryptoSpecAccess javaxCryptoSpecAccess; - private static JavaTemplateAccess javaTemplateAccess; -+ private static JavaSecuritySystemConfiguratorAccess javaSecuritySystemConfiguratorAccess; - - public static void setJavaUtilCollectionAccess(JavaUtilCollectionAccess juca) { - javaUtilCollectionAccess = juca; -@@ -537,4 +539,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 06b141dcf22..e8cbf7f15d7 100644 ---- a/src/java.base/share/classes/module-info.java -+++ b/src/java.base/share/classes/module-info.java -@@ -158,6 +158,7 @@ module java.base { - java.naming, - java.rmi, - jdk.charsets, -+ 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 f036a411f1d..1e9de933bd9 100644 ---- a/src/java.base/share/classes/sun/security/provider/SunEntries.java -+++ b/src/java.base/share/classes/sun/security/provider/SunEntries.java -@@ -38,6 +38,7 @@ import java.util.HashMap; - import java.util.Iterator; - import java.util.LinkedHashSet; - -+import jdk.internal.access.SharedSecrets; - import jdk.internal.util.StaticProperty; - import sun.security.action.GetBooleanAction; - -@@ -91,6 +92,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; - -@@ -102,89 +107,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"); -+ } - - attrs.clear(); - attrs.put("ImplementedIn", "Software"); -@@ -196,9 +204,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 -@@ -213,44 +223,46 @@ public final class SunEntries { - addWithAlias(p, "AlgorithmParameters", "DSA", - "sun.security.provider.DSAParameters", attrs); - -- /* -- * Key factories -- */ -- addWithAlias(p, "KeyFactory", "DSA", -- "sun.security.provider.DSAKeyFactory", attrs); -- addWithAlias(p, "KeyFactory", "HSS/LMS", -- "sun.security.provider.HSS$KeyFactoryImpl", attrs); -- -- /* -- * Digest engines -- */ -- addWithAlias(p, "MessageDigest", "MD2", "sun.security.provider.MD2", -- attrs); -- addWithAlias(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, "KeyFactory", "HSS/LMS", -+ "sun.security.provider.HSS$KeyFactoryImpl", 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 -+ */ -+ addWithAlias(p, "MessageDigest", "MD2", "sun.security.provider.MD2", -+ attrs); -+ addWithAlias(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 539ef1e8ee8..435f57e3ff2 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/conf/security/java.security b/src/java.base/share/conf/security/java.security -index 5149edba0e5..8227d650a03 100644 ---- a/src/java.base/share/conf/security/java.security -+++ b/src/java.base/share/conf/security/java.security -@@ -85,6 +85,17 @@ 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 -+fips.provider.7=XMLDSig -+ - # - # A list of preferred providers for specific algorithms. These providers will - # be searched for matching algorithms before the list of registered providers. -@@ -295,6 +306,47 @@ policy.ignoreIdentityScope=false - # - keystore.type=pkcs12 - -+# -+# Default keystore type used when global crypto-policies are set to FIPS. -+# -+fips.keystore.type=pkcs12 -+ -+# -+# Location of the NSS DB keystore (PKCS11) in FIPS mode. -+# -+# The syntax for this property is identical to the 'nssSecmodDirectory' -+# attribute available in the SunPKCS11 NSS configuration file. Use the -+# 'sql:' prefix to refer to an SQLite DB. -+# -+# If the system property fips.nssdb.path is also specified, it supersedes -+# the security property value defined here. -+# -+# Note: the default value for this property points to an NSS DB that might be -+# readable by multiple operating system users and unsuitable to store keys. -+# -+fips.nssdb.path=sql:/etc/pki/nssdb -+ -+# -+# PIN for the NSS DB keystore (PKCS11) in FIPS mode. -+# -+# Values must take any of the following forms: -+# 1) pin: -+# 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. - # -@@ -332,6 +384,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 86d45147709..22fd8675503 100644 ---- a/src/java.base/share/lib/security/default.policy -+++ b/src/java.base/share/lib/security/default.policy -@@ -130,6 +130,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"; -@@ -150,6 +151,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..48d6d656a28 ---- /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.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(); -+ -+ 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 6b26297b1b4..7ee5e07756c 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; -@@ -72,6 +74,9 @@ abstract class P11Key implements Key, Length { - @Serial - private static final long serialVersionUID = -2575874101938349339L; - -+ private static final boolean plainKeySupportEnabled = SharedSecrets -+ .getJavaSecuritySystemConfiguratorAccess().isPlainKeySupportEnabled(); -+ - private static final String PUBLIC = "public"; - private static final String PRIVATE = "private"; - private static final String SECRET = "secret"; -@@ -401,8 +406,10 @@ abstract class P11Key implements Key, Length { - new CK_ATTRIBUTE(CKA_EXTRACTABLE), - }); - -- boolean keySensitive = (attrs[0].getBoolean() || -- attrs[1].getBoolean() || !attrs[2].getBoolean()); -+ boolean exportable = plainKeySupportEnabled && !algorithm.equals("DH"); -+ boolean keySensitive = (!exportable && -+ (attrs[0].getBoolean() || -+ attrs[1].getBoolean() || !attrs[2].getBoolean())); - - return switch (algorithm) { - case "RSA" -> P11RSAPrivateKeyInternal.of(session, keyID, algorithm, -@@ -454,7 +461,8 @@ abstract class P11Key implements Key, Length { - - public String getFormat() { - token.ensureValid(); -- if (sensitive || !extractable || (isNSS && tokenObject)) { -+ if (!plainKeySupportEnabled && -+ (sensitive || !extractable || (isNSS && tokenObject))) { - return null; - } else { - return "RAW"; -@@ -1624,4 +1632,3 @@ final class SessionKeyRef extends PhantomReference { - this.clear(); - } - } -- -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 5cd6828d293..bae49c4e8a9 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.*; -@@ -65,6 +70,39 @@ public final class SunPKCS11 extends AuthProvider { - @Serial - private static final long serialVersionUID = -1354835039035306505L; - -+ 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"; -+ - static final Debug debug = Debug.getInstance("sunpkcs11"); - // the PKCS11 object through which we make the native calls - @SuppressWarnings("serial") // Type of field is not Serializable; -@@ -123,6 +161,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)); - } - }); -@@ -325,9 +386,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); -@@ -342,8 +413,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; - -@@ -1389,11 +1461,52 @@ public final class SunPKCS11 extends AuthProvider { - } - - @Override -+ @SuppressWarnings("removal") - public Object newInstance(Object param) - throws NoSuchAlgorithmException { - if (!token.isValid()) { - 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) { -@@ -1750,6 +1863,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 3378409ca1c..7602a92a252 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.RV.*; - */ - final class Token implements Serializable { - -+ private static final boolean systemFipsEnabled = SharedSecrets -+ .getJavaSecuritySystemConfiguratorAccess().isSystemFipsEnabled(); -+ - // need to be serializable to allow SecureRandom to be serialized - @Serial - private static final long serialVersionUID = 2541527649100571747L; -@@ -125,6 +129,10 @@ final 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; - -@@ -242,7 +250,12 @@ final class Token implements Serializable { - // call provider.login() if not - void ensureLoggedIn(Session session) throws PKCS11Exception, LoginException { - if (!isLoggedIn(session)) { -- 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/PKCS11.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11.java -index 4b06daaf264..55e14945469 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; -@@ -174,18 +177,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 { -@@ -1976,4 +2004,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 920422376f8..6aa308fa5f8 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 -@@ -215,6 +215,14 @@ public class PKCS11Exception extends Exception { - return res; - } - -+ /** -+ * 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 7f8c4dba002..e65b11fc3ee 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 -@@ -34,6 +34,7 @@ import java.security.ProviderException; - import java.util.HashMap; - import java.util.List; - -+import jdk.internal.access.SharedSecrets; - import sun.security.ec.ed.EdDSAKeyFactory; - import sun.security.ec.ed.EdDSAKeyPairGenerator; - import sun.security.ec.ed.EdDSASignature; -@@ -50,6 +51,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) { -@@ -240,83 +245,85 @@ 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 ProviderServiceA(this, "KeyPairGenerator", -- "EC", "sun.security.ec.ECKeyPairGenerator", 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 ProviderServiceA(this, "KeyPairGenerator", -+ "EC", "sun.security.ec.ECKeyPairGenerator", ATTRS)); -+ -+ /* -+ * Key Agreement engine -+ */ -+ putService(new ProviderService(this, "KeyAgreement", -+ "ECDH", "sun.security.ec.ECDHKeyAgreement", null, ATTRS)); -+ } - } - - private void putXDHEntries() { -@@ -333,23 +340,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() { -@@ -364,21 +373,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/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-25u-df044414ef4.patch b/fips-25u-df044414ef4.patch new file mode 100644 index 0000000..8b210e6 --- /dev/null +++ b/fips-25u-df044414ef4.patch @@ -0,0 +1,92 @@ +diff --git a/src/java.base/share/classes/java/security/Provider.java b/src/java.base/share/classes/java/security/Provider.java +index de2845fb550..b1e416b90f4 100644 +--- a/src/java.base/share/classes/java/security/Provider.java ++++ b/src/java.base/share/classes/java/security/Provider.java +@@ -1203,6 +1203,39 @@ public Set getServices() { + return serviceSet; + } + ++ /* vvvvvvvvvvvvvvvvvvvvvvvvvvvvv FIPS PATCH vvvvvvvvvvvvvvvvvvvvvvvvvvvvv */ ++ private static final class RedHatFIPSFilter { ++ static final boolean IS_ON = Boolean.parseBoolean( ++ Security.getProperty("__redhat_fips_filter__")); ++ private static final Set ANY_SERVICE_TYPE = Set.of(); ++ private static final Map> ALLOW_LIST = Map.of( ++ "SunPKCS11-FIPS", ANY_SERVICE_TYPE, ++ "SUN", Set.of( ++ "AlgorithmParameterGenerator", ++ "AlgorithmParameters", "CertificateFactory", ++ "CertPathBuilder", "CertPathValidator", "CertStore", ++ "Configuration", "KeyStore"), ++ "SunEC", Set.of( ++ "AlgorithmParameters", "KeyFactory"), ++ "SunJSSE", ANY_SERVICE_TYPE, ++ "SunJCE", Set.of( ++ "AlgorithmParameters", ++ "AlgorithmParameterGenerator", "KeyFactory", ++ "SecretKeyFactory"), ++ "SunRsaSign", Set.of( ++ "KeyFactory", "AlgorithmParameters"), ++ "XMLDSig", ANY_SERVICE_TYPE ++ ); ++ ++ static boolean isAllowed(String provName, String serviceType) { ++ Set allowedServiceTypes = ALLOW_LIST.get(provName); ++ return allowedServiceTypes != null && ++ (allowedServiceTypes == ANY_SERVICE_TYPE || ++ allowedServiceTypes.contains(serviceType)); ++ } ++ } ++ /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FIPS PATCH ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ ++ + /** + * Add a service. If a service of the same type with the same algorithm + * name exists, and it was added using {@link #putService putService()}, +@@ -1231,6 +1264,15 @@ protected void putService(Service s) { + ("service.getProvider() must match this Provider object"); + } + String type = s.getType(); ++ /* vvvvvvvvvvvvvvvvvvvvvvvvvvv FIPS PATCH vvvvvvvvvvvvvvvvvvvvvvvvvvv */ ++ if (RedHatFIPSFilter.IS_ON && !RedHatFIPSFilter.isAllowed(name, type)) { ++ if (debug != null) { ++ debug.println("The previous " + name + ".putService() call " + ++ "was skipped by " + RedHatFIPSFilter.class.getName()); ++ } ++ return; ++ } ++ /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^ FIPS PATCH ^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ + String algorithm = s.getAlgorithm(); + ServiceKey key = new ServiceKey(type, algorithm, true); + implRemoveService(serviceMap.get(key)); +diff --git a/src/java.base/share/classes/java/security/Security.java b/src/java.base/share/classes/java/security/Security.java +index 6969fe8a8e1..4501d5971c4 100644 +--- a/src/java.base/share/classes/java/security/Security.java ++++ b/src/java.base/share/classes/java/security/Security.java +@@ -323,7 +323,27 @@ public Properties getInitialProperties() { + } + + private static void initialize() { ++ /* vvvvvvvvvvvvvvvvvvvvvvvvvvv FIPS PATCH vvvvvvvvvvvvvvvvvvvvvvvvvvv */ ++ /* This 'include'-directives-only magic property is an internal */ ++ /* implementation detail that could (and probably will!) change. */ ++ /* Red Hat customers should NOT rely on this for their own use. */ ++ String fipsKernelFlag = "/proc/sys/crypto/fips_enabled"; ++ boolean fipsModeOn; ++ try (InputStream is = new java.io.FileInputStream(fipsKernelFlag)) { ++ fipsModeOn = is.read() == '1'; ++ } catch (IOException ioe) { ++ fipsModeOn = false; ++ if (sdebug != null) { ++ sdebug.println("Failed to read FIPS kernel file: " + ioe); ++ } ++ } ++ String fipsMagicPropName = "__redhat_fips__"; ++ System.setProperty(fipsMagicPropName, "" + fipsModeOn); ++ /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^ FIPS PATCH ^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ + SecPropLoader.loadAll(); ++ /* vvvvvvvvvvvvvvvvvvvvvvvvvvv FIPS PATCH vvvvvvvvvvvvvvvvvvvvvvvvvvv */ ++ System.clearProperty(fipsMagicPropName); ++ /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^ FIPS PATCH ^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ + initialSecurityProperties = (Properties) props.clone(); + if (sdebug != null) { + for (String key : props.stringPropertyNames()) { diff --git a/generate_source_tarball.sh b/generate_source_tarball.sh deleted file mode 100755 index 5d6efd9..0000000 --- a/generate_source_tarball.sh +++ /dev/null @@ -1,186 +0,0 @@ -#!/bin/bash -# Generates the 'source tarball' for JDK projects. -# -# Example: -# When used from local repo set REPO_ROOT pointing to file:// with your repo -# If your local repo follows upstream forests conventions, it may be enough to set OPENJDK_URL -# -# In any case you have to set PROJECT_NAME REPO_NAME and VERSION. eg: -# PROJECT_NAME=openjdk -# REPO_NAME=jdk21u -# VERSION=jdk-21.0.1+12 -# or to eg prepare systemtap: -# icedtea7's jstack and other tapsets -# VERSION=6327cf1cea9e -# REPO_NAME=icedtea7-2.6 -# PROJECT_NAME=release -# OPENJDK_URL=http://icedtea.classpath.org/hg/ -# TO_COMPRESS="*/tapset" -# -# They are used to create correct name and are used in construction of sources url (unless REPO_ROOT is set) - -# This script creates a single source tarball out of the repository -# based on the given tag and removes code not allowed in fedora/rhel. For -# consistency, the source tarball will always contain 'openjdk' as the top -# level folder, name is created, based on parameter -# - -set -e - -OPENJDK_URL_DEFAULT=https://github.com -COMPRESSION_DEFAULT=xz - -if [ "x$1" = "xhelp" ] ; then - if [ "x$VERSION" = "x" ] ; then - VERSION=""; - fi - echo -e "Behaviour may be specified by setting the following variables:\n" - echo "VERSION - the version of the specified OpenJDK project" - echo "PROJECT_NAME -- the name of the OpenJDK project being archived (optional; only needed by defaults)" - echo "REPO_NAME - the name of the OpenJDK repository (optional; only needed by defaults)" - echo "OPENJDK_URL - the URL to retrieve code from (optional; defaults to ${OPENJDK_URL_DEFAULT})" - echo "COMPRESSION - the compression type to use (optional; defaults to ${COMPRESSION_DEFAULT})" - echo "FILE_NAME_ROOT - name of the archive, minus extensions (optional; defaults to PROJECT_NAME-REPO_NAME-VERSION)" - echo "REPO_ROOT - the location of the Git repository to archive (optional; defaults to OPENJDK_URL/PROJECT_NAME/REPO_NAME.git)" - echo "TO_COMPRESS - what part of clone to pack (default is ${VERSION})" - echo "BOOT_JDK - the bootstrap JDK to satisfy the configure run" - exit 1; -fi - - -if [ "x$VERSION" = "x" ] ; then - echo "No VERSION specified" - exit 2 -fi -echo "Version: ${VERSION}" - -NUM_VER=${VERSION##jdk-} -RELEASE_VER=${NUM_VER%%+*} -BUILD_VER=${NUM_VER##*+} -MAJOR_VER=${RELEASE_VER%%.*} -echo "Major version is ${MAJOR_VER}, release ${RELEASE_VER}, build ${BUILD_VER}" - -if [ "x$BOOT_JDK" = "x" ] ; then - echo "No boot JDK specified". - BOOT_JDK=/usr/lib/jvm/java-${MAJOR_VER}-openjdk; - echo -n "Checking for ${BOOT_JDK}..."; - if [ -d ${BOOT_JDK} -a -x ${BOOT_JDK}/bin/java ] ; then - echo "Boot JDK found at ${BOOT_JDK}"; - else - echo "Not found"; - PREV_VER=$((${MAJOR_VER} - 1)); - BOOT_JDK=/usr/lib/jvm/java-${PREV_VER}-openjdk; - echo -n "Checking for ${BOOT_JDK}..."; - if [ -d ${BOOT_JDK} -a -x ${BOOT_JDK}/bin/java ] ; then - echo "Boot JDK found at ${BOOT_JDK}"; - else - echo "Not found"; - exit 4; - fi - fi -else - echo "Boot JDK: ${BOOT_JDK}"; -fi - -# REPO_NAME is only needed when we default on REPO_ROOT and FILE_NAME_ROOT -if [ "x$FILE_NAME_ROOT" = "x" -o "x$REPO_ROOT" = "x" ] ; then - if [ "x$PROJECT_NAME" = "x" ] ; then - echo "No PROJECT_NAME specified" - exit 1 - fi - echo "Project name: ${PROJECT_NAME}" - if [ "x$REPO_NAME" = "x" ] ; then - echo "No REPO_NAME specified" - exit 3 - fi - echo "Repository name: ${REPO_NAME}" -fi - -if [ "x$OPENJDK_URL" = "x" ] ; then - OPENJDK_URL=${OPENJDK_URL_DEFAULT} - echo "No OpenJDK URL specified; defaulting to ${OPENJDK_URL}" -else - echo "OpenJDK URL: ${OPENJDK_URL}" -fi - -if [ "x$COMPRESSION" = "x" ] ; then - # rhel 5 needs tar.gz - COMPRESSION=${COMPRESSION_DEFAULT} -fi -echo "Creating a tar.${COMPRESSION} archive" - -if [ "x$FILE_NAME_ROOT" = "x" ] ; then - FILE_NAME_ROOT=${PROJECT_NAME}-${REPO_NAME}-${VERSION} - echo "No file name root specified; default to ${FILE_NAME_ROOT}" -fi -if [ "x$REPO_ROOT" = "x" ] ; then - REPO_ROOT="${OPENJDK_URL}/${PROJECT_NAME}/${REPO_NAME}.git" - echo "No repository root specified; default to ${REPO_ROOT}" -fi; - -if [ "x$TO_COMPRESS" = "x" ] ; then - TO_COMPRESS="${VERSION}" - echo "No targets to be compressed specified ; default to ${TO_COMPRESS}" -fi; - -echo -e "Settings:" -echo -e "\tVERSION: ${VERSION}" -echo -e "\tPROJECT_NAME: ${PROJECT_NAME}" -echo -e "\tREPO_NAME: ${REPO_NAME}" -echo -e "\tOPENJDK_URL: ${OPENJDK_URL}" -echo -e "\tCOMPRESSION: ${COMPRESSION}" -echo -e "\tFILE_NAME_ROOT: ${FILE_NAME_ROOT}" -echo -e "\tREPO_ROOT: ${REPO_ROOT}" -echo -e "\tTO_COMPRESS: ${TO_COMPRESS}" -echo -e "\tBOOT_JDK: ${BOOT_JDK}" - -if [ -d ${FILE_NAME_ROOT} ] ; then - echo "exists exists exists exists exists exists exists " - echo "reusing reusing reusing reusing reusing reusing " - echo ${FILE_NAME_ROOT} -else - mkdir "${FILE_NAME_ROOT}" - pushd "${FILE_NAME_ROOT}" - echo "Cloning ${VERSION} root repository from ${REPO_ROOT}" - git clone -b ${VERSION} ${REPO_ROOT} ${VERSION} - popd -fi -pushd "${FILE_NAME_ROOT}" - - # Generate .src-rev so build has knowledge of the revision the tarball was created from - mkdir build - pushd build - sh ${PWD}/../${VERSION}/configure --with-boot-jdk=${BOOT_JDK} - make store-source-revision - popd - rm -rf build - - # Remove commit checks - echo "Removing $(find ${VERSION} -name '.jcheck' -print)" - find ${VERSION} -name '.jcheck' -print0 | xargs -0 rm -r - - # Remove history and GHA - echo "find ${VERSION} -name '.hgtags'" - find ${VERSION} -name '.hgtags' -exec rm -fv '{}' '+' - echo "find ${VERSION} -name '.hgignore'" - find ${VERSION} -name '.hgignore' -exec rm -fv '{}' '+' - echo "find ${VERSION} -name '.gitattributes'" - find ${VERSION} -name '.gitattributes' -exec rm -fv '{}' '+' - echo "find ${VERSION} -name '.gitignore'" - find ${VERSION} -name '.gitignore' -exec rm -fv '{}' '+' - echo "find ${VERSION} -name '.git'" - find ${VERSION} -name '.git' -exec rm -rfv '{}' '+' - echo "find ${VERSION} -name '.github'" - find ${VERSION} -name '.github' -exec rm -rfv '{}' '+' - - echo "Compressing remaining forest" - if [ "X$COMPRESSION" = "Xxz" ] ; then - SWITCH=cJf - else - SWITCH=czf - fi - TARBALL_NAME=${FILE_NAME_ROOT}.tar.${COMPRESSION} - tar --exclude-vcs -$SWITCH ${TARBALL_NAME} $TO_COMPRESS - mv ${TARBALL_NAME} .. -popd -echo "Done. You may want to remove the uncompressed version - $FILE_NAME_ROOT." diff --git a/java-latest-openjdk-portable.spec b/java-latest-openjdk-portable.spec index 96d8be9..16bb5eb 100644 --- a/java-latest-openjdk-portable.spec +++ b/java-latest-openjdk-portable.spec @@ -1,10 +1,5 @@ -%if (0%{?rhel} > 0 && 0%{?rhel} < 8) -# portable jdk 17 specific bug, _jvmdir being missing -%define _jvmdir /usr/lib/jvm -%endif - # debug_package %%{nil} is portable-jdks specific -%define debug_package %{nil} +%define debug_package %{nil} # RPM conditionals so as to be able to dynamically produce # slowdebug/release builds. See: @@ -29,15 +24,16 @@ %bcond_without release # Enable static library builds by default. %bcond_without staticlibs +# Remove build artifacts by default +%bcond_with artifacts # 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 - -%if (0%{?rhel} > 0 && 0%{?rhel} < 8) # This is RHEL 7 specific as it doesn't seem to have the # __brp_strip_static_archive macro. +%if 0%{?rhel} == 7 %define __os_install_post %{nil} %endif @@ -64,6 +60,10 @@ # See: https://bugzilla.redhat.com/show_bug.cgi?id=1520879 %global _find_debuginfo_opts -g +# Disable LTO as this causes build failures at the moment. +# See RHBZ#1861401 +%define _lto_cflags %{nil} + # note: parametrized macros are order-sensitive (unlike not-parametrized) even with normal macros # also necessary when passing it as parameter to other macros. If not macro, then it is considered a switch # see the difference between global and define: @@ -129,7 +129,7 @@ # Set of architectures for which we build fastdebug builds %global fastdebug_arches x86_64 ppc64le aarch64 # Set of architectures with a Just-In-Time (JIT) compiler -%global jit_arches %{arm} %{aarch64} %{ix86} %{power64} s390x sparcv9 sparc64 x86_64 +%global jit_arches %{arm} %{aarch64} %{ix86} %{power64} s390x sparcv9 sparc64 x86_64 riscv64 # Set of architectures which use the Zero assembler port (!jit_arches) %global zero_arches ppc s390 # Set of architectures which run a full bootstrap cycle @@ -139,15 +139,15 @@ # Set of architectures with a Ahead-Of-Time (AOT) compiler %global aot_arches x86_64 %{aarch64} # Set of architectures which support the serviceability agent -%global sa_arches %{ix86} x86_64 sparcv9 sparc64 %{aarch64} %{power64} %{arm} +%global sa_arches %{ix86} x86_64 sparcv9 sparc64 %{aarch64} %{power64} %{arm} riscv64 # Set of architectures which support class data sharing # As of JDK-8005165 in OpenJDK 10, class sharing is not arch-specific # However, it does segfault on the Zero assembler port, so currently JIT only %global share_arches %{jit_arches} # Set of architectures for which we build the Shenandoah garbage collector -%global shenandoah_arches x86_64 %{aarch64} +%global shenandoah_arches x86_64 %{aarch64} riscv64 # Set of architectures for which we build the Z garbage collector -%global zgc_arches x86_64 +%global zgc_arches x86_64 riscv64 # Set of architectures for which alt-java has SSB mitigation %global ssbd_arches x86_64 # Set of architectures for which java has short vector math library (libjsvml.so) @@ -159,6 +159,8 @@ %else %global gdb_arches %{jit_arches} %{zero_arches} %endif +# Architecture on which we run Java only tests +%global jdk_test_arch x86_64 # By default, we build a slowdebug build during main build on JIT architectures %if %{with slowdebug} @@ -226,7 +228,7 @@ # other targets since this target is configured to use in-tree # AWT dependencies: lcms, libjpeg, libpng, libharfbuzz, giflib # and possibly others -%global static_libs_target static-libs-image +%global static_libs_target static-libs-graal-image %else %global static_libs_target %{nil} %endif @@ -242,12 +244,83 @@ # Target to use to just build HotSpot %global hotspot_target hotspot -# DTS toolset to use to provide gcc & binutils -%global dtsversion 10 -# Disable LTO as this causes build failures at the moment. -# See RHBZ#1861401 -%define _lto_cflags %{nil} +# Individual build frameworks this specfile supports +# if elif ... elif ... elif ... else is unluckily buggy +# On rhel7 we need software collection +%if (0%{?rhel} == 7) +%global is_dtstoolchain collection +%global dtsversion 10 +%global dtsname devtoolset-%{dtsversion} +%global dts_command scl enable %{dtsname} -- +%global exclusive_arches %{nil} +%define dts_brs # Brs for collection\ +BuildRequires: %{dtsname}-gcc \ +BuildRequires: %{dtsname}-gcc-c++ +%else +# On rhel8 we have self built custom devkit +%if ((0%{?rhel} == 8) && (0%{?epel} == 0)) +%global is_dtstoolchain devkit +%global dtsversion 1.0-9 +%global dtsname %{origin}-devkit +%global dts_command %{nil} +%if 0%{?centos} == 0 +# centos had originally smaller set of devkit arches +%global exclusive_arches %{aarch64} %{ppc64le} s390x x86_64 riscv64 +%else +%global exclusive_arches %{aarch64} %{ppc64le} s390x x86_64 riscv64 +%endif +%define dts_brs # Brs for devkit\ +BuildRequires: %{dtsname} >= %{dtsversion} +%else +# On newest systems we use system gcc and friens +%if ((0%{?fedora} > 0) || (0%{?rhel} >= 9) || (0%{?epel} >= 9)) +%global is_dtstoolchain system +%global dtsversion %{nil} +%global dtsname %{nil} +%global exclusive_arches %{java_arches} +%define dts_brs # Brs for system\ +BuildRequires: gcc >= 4.8.3-8 \ +BuildRequires: gcc-c++ \ +# We link statically against libstdc++ to increase portability \ +BuildRequires: libstdc++-static +# When building on epel8, we need system, legacy toolchain of explicit version +%else +%if ((0%{?epel}) > 0 && (0%{?epel} <= 8)) +%global is_dtstoolchain toolset +%global dtsversion 14 +%global dtsname gcc-toolset-%{dtsversion} +%global exclusive_arches %{java_arches} +%define dts_brs # Brs for toolset\ +BuildRequires: %{dtsname}-gcc \ +BuildRequires: %{dtsname}-gcc-c++ \ +BuildRequires: %{dtsname}-annobin-annocheck \ +BuildRequires: %{dtsname}-annobin-plugin-gcc \ +BuildRequires: %{dtsname}-binutils \ +BuildRequires: %{dtsname}-gcc-plugin-annobin \ +# We link statically against libstdc++ to increase portability \ +BuildRequires: libstdc++-static +# no go +%else +"Unsupported system: fedora=0%{?fedora} rhel=0%{?rhel} epel=0%{?epel} centos=0%{?centos}" +exit 1 +%endif +%endif +%endif +%endif + +%if ((0%{?epel}) > 0 || (0%{?fedora} > 8)) +%global use_portable_bootjdk 0 +%else +%global use_portable_bootjdk 1 +%endif + +# Check if pandoc is available to generate docs (including man pages) +%if 0%{?rhel} == 8 || 0%{?epel} > 0 || 0%{?fedora} > 0 +%global pandoc_available 1 +%else +%global pandoc_available 0 +%endif # 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 @@ -302,6 +375,10 @@ %global archinstall aarch64 %global stapinstall arm64 %endif +%ifarch riscv64 +%global archinstall riscv64 +%global stapinstall %{_target_cpu} +%endif # 32 bit sparc, optimized for v9 %ifarch sparcv9 %global archinstall sparc @@ -318,7 +395,8 @@ %global stapinstall %{nil} %endif -# always off for portable builds +# on fedora and epel, we build systemtap in repacking to rpms +# thus having it disabled, and keeping the lines just for sync reasons %ifarch %{systemtap_arches} %global with_systemtap 0 %else @@ -326,14 +404,14 @@ %endif # New Version-String scheme-style defines -%global featurever 21 +%global featurever 26 %global interimver 0 -%global updatever 1 +%global updatever 0 %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 %{featurever} +%global buildjdkver 25 # 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,16 +421,6 @@ %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. @@ -360,11 +428,11 @@ # Define what url should JVM offer in case of a crash report # order may be important, epel may have rhel declared %if 0%{?epel} -%global oj_vendor_bug_url https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora%20EPEL&component=%{name}&version=epel%{epel} +%global oj_vendor_bug_url https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora%20EPEL&component=%{component}&version=epel%{epel} %else %if 0%{?fedora} # Does not work for rawhide, keeps the version field empty -%global oj_vendor_bug_url https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora&component=%{name}&version=%{fedora} +%global oj_vendor_bug_url https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora&component=%{component}&version=%{fedora} %else %if 0%{?rhel} %global oj_vendor_bug_url https://access.redhat.com/support/cases/ @@ -378,7 +446,7 @@ # Define IcedTea version used for SystemTap tapsets and desktop file %global icedteaver 6.0.0pre00-c848b93a8598 # Define current Git revision for the FIPS support patches -%global fipsver 75ffdc48eda +%global fipsver df044414ef4 # Define JDK versions %global newjavaver %{featurever}.%{interimver}.%{updatever}.%{patchver} %global javaver %{featurever} @@ -392,8 +460,8 @@ %global origin_nice OpenJDK %global top_level_dir_name %{vcstag} %global top_level_dir_name_backup %{top_level_dir_name}-backup -%global buildver 12 -%global rpmrelease 2 +%global buildver 29 +%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 @@ -412,7 +480,7 @@ # Release will be (where N is usually a number starting at 1): # - 0.N%%{?extraver}%%{?dist} for EA releases, # - N%%{?extraver}{?dist} for GA releases -%global is_ga 1 +%global is_ga 0 %if %{is_ga} %global build_type GA %global ea_designator "" @@ -432,11 +500,12 @@ %global fullversion %{compatiblename}-%{version}-%{release} # images directories from upstream build %global jdkimage jdk -%global static_libs_image static-libs +%global static_libs_image static-libs-graal # output dir stub %define buildoutputdir() %{expand:build/jdk%{featurever}.build%{?1}} %define installoutputdir() %{expand:install/jdk%{featurever}.install%{?1}} -%global altjavaoutputdir install/altjava.install +%global miscinstalloutputdir install +%global altjavaoutputdir %{miscinstalloutputdir}/altjava.install %define packageoutputdir() %{expand:packages/jdk%{featurever}.packages%{?1}} # we can copy the javadoc to not arched dir, or make it not noarch %define uniquejavadocdir() %{expand:%{fullversion}.%{_arch}%{?1}} @@ -444,23 +513,30 @@ %define uniquesuffix() %{expand:%{fullversion}.%{_arch}%{?1}} # portable only declarations %global jreimage jre -%define jreportablenameimpl() %(echo %{uniquesuffix ""} | sed "s;%{version}-%{release};\\0.portable%{1}.jre;g" | sed "s;openjdkportable;el;g") -%define jdkportablenameimpl() %(echo %{uniquesuffix ""} | sed "s;%{version}-%{release};\\0.portable%{1}.jdk;g" | sed "s;openjdkportable;el;g") -%define jdkportablesourcesnameimpl() %(echo %{uniquesuffix ""} | sed "s;%{version}-%{release};\\0.portable%{1}.sources;g" | sed "s;openjdkportable;el;g" | sed "s;.%{_arch};.noarch;g") -%define staticlibsportablenameimpl() %(echo %{uniquesuffix ""} | sed "s;%{version}-%{release};\\0.portable%{1}.static-libs;g" | sed "s;openjdkportable;el;g") +%if ((0%{?fedora} > 0) || (0%{?epel} > 0)) +%define regexBase %{version}-%{release} +%else +%define regexBase el%{rhel}\\(_[0-9]\\)* +%endif +%define jreportablenameimpl() %(echo %{uniquesuffix ""} | sed "s;%{regexBase};\\0.portable%{1}.jre;g" | sed "s;openjdkportable;el;g") +%define jdkportablenameimpl() %(echo %{uniquesuffix ""} | sed "s;%{regexBase};\\0.portable%{1}.jdk;g" | sed "s;openjdkportable;el;g") +%define jdkportablesourcesnameimpl() %(echo %{uniquesuffix ""} | sed "s;%{regexBase};\\0.portable%{1}.sources;g" | sed "s;openjdkportable;el;g" | sed "s;.%{_arch};.noarch;g") +%define staticlibsportablenameimpl() %(echo %{uniquesuffix ""} | sed "s;%{regexBase};\\0.portable%{1}.static-libs;g" | sed "s;openjdkportable;el;g") +%define jmodsportablenameimpl() %(echo %{uniquesuffix ""} | sed "s;%{regexBase};\\0.portable%{1}.jmods;g" | sed "s;openjdkportable;el;g") %define jreportablearchive() %{expand:%{jreportablenameimpl -- %%{1}}.tar.xz} %define jdkportablearchive() %{expand:%{jdkportablenameimpl -- %%{1}}.tar.xz} %define jdkportablesourcesarchive() %{expand:%{jdkportablesourcesnameimpl -- %%{1}}.tar.xz} %define staticlibsportablearchive() %{expand:%{staticlibsportablenameimpl -- %%{1}}.tar.xz} +%define jmodsportablearchive() %{expand:%{jmodsportablenameimpl -- %%{1}}.tar.xz} %define jreportablename() %{expand:%{jreportablenameimpl -- %%{1}}} %define jdkportablename() %{expand:%{jdkportablenameimpl -- %%{1}}} %define jdkportablesourcesname() %{expand:%{jdkportablesourcesnameimpl -- %%{1}}} # Intentionally use jdkportablenameimpl here since we want to have static-libs files overlayed on # top of the JDK archive %define staticlibsportablename() %{expand:%{jdkportablenameimpl -- %%{1}}} -%define docportablename() %(echo %{uniquesuffix ""} | sed "s;%{version}-%{release};\\0.portable.docs;g" | sed "s;openjdkportable;el;g") +%define docportablename() %(echo %{uniquesuffix ""} | sed "s;%{regexBase};\\0.portable.docs;g" | sed "s;openjdkportable;el;g") %define docportablearchive() %{docportablename}.tar.xz -%define miscportablename() %(echo %{uniquesuffix ""} | sed "s;%{version}-%{release};\\0.portable.misc;g" | sed "s;openjdkportable;el;g") +%define miscportablename() %(echo %{uniquesuffix ""} | sed "s;%{regexBase};\\0.portable.misc;g" | sed "s;openjdkportable;el;g") %define miscportablearchive() %{miscportablename}.tar.xz # RPM 4.19 no longer accept our double percentaged %%{nil} passed to %%{1} @@ -469,7 +545,30 @@ %define jdkportablearchiveForFiles() %(echo %{jdkportablearchive -- ""}) %define jdkportablesourcesarchiveForFiles() %(echo %{jdkportablesourcesarchive -- ""}) %define staticlibsportablearchiveForFiles() %(echo %{staticlibsportablearchive -- ""}) -%define jdkportablesourcesnameForFiles() %(echo %{jdkportablesourcesname -- ""}) +%define jmodsportablearchiveForFiles() %(echo %{jmodsportablearchive -- ""}) + +# JDK to use for bootstrapping +%ifarch %{fastdebug_arches} +%global bootdebugpkg fastdebug +%endif +%if %{use_portable_bootjdk} +%global bootjdkpkg_name java-%{featurever}-%{origin} +%global bootjdkpkg %{bootjdkpkg_name}-portable-devel%{?bootdebugpkg:-%{bootdebugpkg}} >= %{buildjdkver} +%global bootjdkzip %{_jvmdir}/%{bootjdkpkg_name}-*.portable%{?bootdebugpkg:.%{bootdebugpkg}}.jdk.%{_arch}.tar.xz +%global bootjdk %{_builddir}/%{uniquesuffix -- ""}/%{bootjdkpkg_name}.boot +%else +%global bootjdkpkg_name java-latest-openjdk +%global bootjdkpkg %{bootjdkpkg_name}-devel%{?bootdebugpkg:-%{bootdebugpkg}} +%global bootjdk /usr/lib/jvm/%{bootjdkpkg_name}%{?bootdebugpkg:-%{bootdebugpkg}} +%endif +# 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 ################################################################# # fix for https://bugzilla.redhat.com/show_bug.cgi?id=1111349 @@ -508,6 +607,7 @@ %define jrebindir() %{expand:%{_jvmdir}/%{sdkdir -- %{?1}}/bin} %global alt_java_name alt-java +%global generated_sources_name generated_sources %global rpm_state_dir %{_localstatedir}/lib/rpm-state/ @@ -519,13 +619,6 @@ %global alternatives_requires %{_sbindir}/alternatives %endif -# x86 is no longer supported -%if 0%{?java_arches:1} -ExclusiveArch: %{java_arches} -%else -ExcludeArch: %{ix86} -%endif - # Portables have no repo (requires/provides), but these are awesome for orientation in spec # Also scriptlets are happily missing and files are handled old fashion # not-duplicated requires/provides/obsoletes for normal/debug packages @@ -538,9 +631,6 @@ ExcludeArch: %{ix86} %define java_static_libs_rpo() %{expand: } -%define java_unstripped_rpo() %{expand: -} - %define java_docs_rpo() %{expand: } @@ -550,7 +640,20 @@ ExcludeArch: %{ix86} # Prevent brp-java-repack-jars from being run %global __jar_repack 0 -Name: java-latest-%{origin}-portable +# portables have grown out of its component, moving back to java-x-vendor +# this expression, when declared as global, filled component with java-x-vendor portable +%define component %(echo %{name} | sed "s;-portable%{?pkgos:-%{pkgos}};;g") + +# Define the architectures on which we build +# On RHEL, this should be the architectures with a devkit +%if "%{?exclusive_arches}" == "%{nil}" +# x86 is no longer supported +ExcludeArch: %{ix86} +%else +ExclusiveArch: %{exclusive_arches} +%endif + +Name: java-latest-%{origin}-portable%{?pkgos:-%{pkgos}} Version: %{newjavaver}.%{buildver} # This package needs `.rolling` as part of Release so as to not conflict on install with # java-X-openjdk. I.e. when latest rolling release is also an LTS release packaged as @@ -567,11 +670,6 @@ Release: %{?eaprefix}%{rpmrelease}%{?extraver}.rolling%{?dist} # provides >= 1.6.0 must specify the epoch, "java >= 1:1.6.0". Epoch: 1 - -# portables have grown out of its component, moving back to java-x-vendor -# this expression, when declared as global, filled component with java-x-vendor portable -%define component %(echo %{name} | sed "s;-portable;;g") - Summary: %{origin_nice} %{featurever} Runtime Environment portable edition # Groups are only used up to RHEL 8 and on Fedora versions prior to F30 %if (0%{?rhel} > 0 && 0%{?rhel} <= 8) || (0%{?fedora} >= 0 && 0%{?fedora} < 30) @@ -592,7 +690,8 @@ Group: Development/Languages # The test code includes copies of NSS under the Mozilla Public License v2.0 # The PCSClite headers are under a BSD with advertising license # The elliptic curve cryptography (ECC) source code is licensed under the LGPLv2.1 or any later version -License: ASL 1.1 and ASL 2.0 and BSD and BSD with advertising and GPL+ and GPLv2 and GPLv2 with exceptions and IJG and LGPLv2+ and MIT and MPLv2.0 and Public Domain and W3C and zlib and ISC and FTL and RSA +# Automatically converted from old format: ASL 1.1 and ASL 2.0 and BSD and BSD with advertising and GPL+ and GPLv2 and GPLv2 with exceptions and IJG and LGPLv2+ and MIT and MPLv2.0 and Public Domain and W3C and zlib and ISC and FTL and RSA - review is highly recommended. +License: Apache-1.1 AND Apache-2.0 AND LicenseRef-Callaway-BSD AND LicenseRef-Callaway-BSD-with-advertising AND GPL-1.0-or-later AND GPL-2.0-only AND LicenseRef-Callaway-GPLv2-with-exceptions AND IJG AND LicenseRef-Callaway-LGPLv2+ AND LicenseRef-Callaway-MIT AND MPL-2.0 AND LicenseRef-Callaway-Public-Domain AND W3C AND Zlib AND ISC AND FTL AND LicenseRef-RSA URL: http://openjdk.java.net/ # The source tarball, generated using generate_source_tarball.sh @@ -637,11 +736,12 @@ Source18: TestTranslations.java # RPM/distribution specific patches # ############################################ - # Crypto policy and FIPS support patches -# Patch is generated from the fips-21u tree at https://github.com/rh-openjdk/jdk/tree/fips-21u -# as follows: git diff %%{vcstag} src make test > fips-21u-$(git show -s --format=%h HEAD).patch +# Patch is generated from the fips-25u tree at https://github.com/rh-openjdk/jdk/tree/fips-25u +# as follows: git diff %%{vcstag} src make test > fips-25u-$(git show -s --format=%h HEAD).patch # Diff is limited to src and make subdirectories to exclude .github changes +# The following list is generated by: +# git log %%{vcstag}.. --no-merges --format=%s --reverse: # Fixes currently included: # PR3183, RH1340845: Follow system wide crypto policy # PR3695: Allow use of system crypto policy to be disabled by the user @@ -674,7 +774,8 @@ Source18: TestTranslations.java # 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 [now part of JDK-8301553 upstream] -Patch1001: fips-%{featurever}u-%{fipsver}.patch +# usage in jdk >25 is experimental and may disapear +Patch1001: fips-25u-%{fipsver}.patch ############################################# # @@ -682,10 +783,6 @@ Patch1001: fips-%{featurever}u-%{fipsver}.patch # ############################################# -# JDK-8009550, RH910107: Depend on pcsc-lite-libs instead of pcsc-lite-devel as this is only in optional repo -# PR: https://github.com/openjdk/jdk/pull/15409 -Patch6: jdk8009550-rh910107-fail_to_load_pcsc_library.patch - # Currently empty ############################################# @@ -694,8 +791,7 @@ Patch6: jdk8009550-rh910107-fail_to_load_pcsc_library.patch # ############################################# -# JDK-8311630: [s390] Implementation of Foreign Function & Memory API (Preview) -Patch100: jdk8311630-s390_ffmapi.patch +Patch1: JDK-8373246-8351842_broke_native_debugging_on_Linux.patch ############################################# # @@ -715,20 +811,8 @@ BuildRequires: desktop-file-utils BuildRequires: elfutils-devel BuildRequires: file BuildRequires: fontconfig-devel -%if (0%{?rhel} > 0 && 0%{?rhel} < 8) -BuildRequires: devtoolset-%{dtsversion}-gcc -BuildRequires: devtoolset-%{dtsversion}-gcc-c++ -%else -BuildRequires: gcc -# gcc-c++ is already needed -BuildRequires: java-%{buildjdkver}-openjdk-devel -%endif -BuildRequires: gcc-c++ +%{dts_brs} BuildRequires: gdb -%if (0%{?rhel} > 0 && 0%{?rhel} < 8) -# rhel7 only, portables only. Rhel8 have gtk3, rpms have runtime recommends of gtk -BuildRequires: gtk2-devel -%endif BuildRequires: libxslt BuildRequires: libX11-devel BuildRequires: libXi-devel @@ -740,7 +824,7 @@ BuildRequires: libXtst-devel # Requirement for setting up nss.fips.cfg BuildRequires: nss-devel # Requirement for system security property test -# N/A for portable. RHEL7 doesn't provide them +# N/A for portable as we don't enable support for them #BuildRequires: crypto-policies BuildRequires: pkgconfig BuildRequires: xorg-x11-proto-devel @@ -748,25 +832,20 @@ BuildRequires: zip # to pack portable tarballs BuildRequires: tar BuildRequires: unzip -%if (0%{?rhel} > 0 && 0%{?rhel} < 8) -# No javapackages-filesystem on el7,nor is needed for portables -%else -# BuildRequires: javapackages-filesystem -BuildRequires: java-latest-openjdk-devel -%endif +BuildRequires: javapackages-filesystem +BuildRequires: %{bootjdkpkg} # Zero-assembler build requirement %ifarch %{zero_arches} BuildRequires: libffi-devel %endif # Full documentation build requirements +# pandoc is only available on RHEL/CentOS 8, epels, and fedoras +%if %{pandoc_available} BuildRequires: graphviz BuildRequires: pandoc -# 2023c required as of JDK-8305113 -BuildRequires: tzdata-java >= 2023c +%endif # cacerts build requirement in portable mode BuildRequires: ca-certificates -# Earlier versions have a bug in tree vectorization on PPC -BuildRequires: gcc >= 4.8.3-8 %if %{with_systemtap} BuildRequires: systemtap-sdt-devel @@ -780,21 +859,22 @@ BuildRequires: harfbuzz-devel BuildRequires: lcms2-devel BuildRequires: libjpeg-devel BuildRequires: libpng-devel +BuildRequires: zlib-devel %else # Version in src/java.desktop/share/legal/freetype.md -Provides: bundled(freetype) = 2.13.0 +Provides: bundled(freetype) = 2.13.3 # Version in src/java.desktop/share/native/libsplashscreen/giflib/gif_lib.h -Provides: bundled(giflib) = 5.2.1 +Provides: bundled(giflib) = 5.2.2 # Version in src/java.desktop/share/native/libharfbuzz/hb-version.h -Provides: bundled(harfbuzz) = 7.2.0 +Provides: bundled(harfbuzz) = 10.4.0 # Version in src/java.desktop/share/native/liblcms/lcms2.h -Provides: bundled(lcms2) = 2.15.0 +Provides: bundled(lcms2) = 2.17.0 # Version in src/java.desktop/share/native/libjavajpeg/jpeglib.h Provides: bundled(libjpeg) = 6b # Version in src/java.desktop/share/native/libsplashscreen/libpng/png.h -Provides: bundled(libpng) = 1.6.39 -# We link statically against libstdc++ to increase portability -BuildRequires: libstdc++-static +Provides: bundled(libpng) = 1.6.47 +# Version in src/java.base/share/native/libzip/zlib/zlib.h +Provides: bundled(zlib) = 1.3.1 %endif # this is always built, also during debug-only build @@ -908,17 +988,6 @@ The %{origin_nice} %{featurever} libraries for static linking - portable edition # staticlibs %endif -%if %{include_normal_build} -%package unstripped -Summary: The %{origin_nice} %{featurever} runtime environment. - -%{java_unstripped_rpo %{nil}} - -%description unstripped -The %{origin_nice} %{featurever} runtime environment. - -%endif - %if %{include_normal_build} %package docs Summary: %{origin_nice} %{featurever} API documentation @@ -945,13 +1014,15 @@ The %{origin_nice} %{featurever} full patched sources of portable JDK to build, %prep -echo "Preparing %{oj_vendor_version}" - # Using the echo macro breaks rpmdev-bumpspec, as it parses the first line of stdout :-( +echo "Preparing %{oj_vendor_version}" +echo "System is RHEL=%{?rhel}%{!?rhel:0}, CentOS=%{?centos}%{!?centos:0}, EPEL=%{?epel}%{!?epel:0}, Fedora=%{?fedora}%{!?fedora:0}" +echo "Build JDK version is %{buildjdkver}, bootstrap JDK package is %{bootjdkpkg}" + %if 0%{?_build_cpu:1} echo "CPU: %{_target_cpu}, arch install directory: %{archinstall}, SystemTap install directory: %{_build_cpu}" %else - %{error:Unrecognised architecture %{_build_cpu}} + %{error:Unrecognised architecture %{_target_cpu}} %endif if [ %{include_normal_build} -eq 0 -o %{include_normal_build} -eq 1 ] ; then @@ -978,10 +1049,11 @@ if [ %{include_debug_build} -eq 0 -a %{include_normal_build} -eq 0 -a %{includ 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}" +%{warn: The build of a fresh libjvm has been disabled due to a JDK version mismatch} +%{warn: Build JDK version is %{buildjdkver}, feature JDK version is %{featurever}} %endif +export XZ_OPT="-T0" %setup -q -c -n %{uniquesuffix ""} -T -a 0 # https://bugzilla.redhat.com/show_bug.cgi?id=1189084 prioritylength=`expr length %{priority}` @@ -991,22 +1063,38 @@ if [ $prioritylength -ne 8 ] ; then fi # OpenJDK patches - %if %{system_libs} # Remove libraries that are linked by both static and dynamic builds sh %{SOURCE12} %{top_level_dir_name} %endif # Patch the JDK +# This syntax is deprecated: +# %%patchN [...] +# and should be replaced with: +# %%patch -PN [...] +# For example: +# %%patch1001 -p1 +# becomes: +# %%patch -P1001 -p1 +# The replacement format suggested by recent (circa Fedora 38) RPM +# deprecation messages: +# %%patch N [...] +# is not backward-compatible with prior (circa RHEL-8) versions of +# rpmbuild. pushd %{top_level_dir_name} # Add crypto policy and FIPS support -%patch1001 -p1 -# Patches in need of upstreaming -%patch6 -p1 -# Patches in next release -%patch100 -p1 +# usage in jdk >25 is experimental and may disapear +%patch -P1001 -p1 +%patch -P1 -p1 popd # openjdk +echo "Generating %{alt_java_name} man page" +altjavamanpage=%{top_level_dir_name}/src/java.base/share/man/%{alt_java_name}.md +altjavatext="Hardened java binary recommended for launching untrusted code from the Web e.g. javaws" +sed -r -e 's|([^/.])java([^./])|\1alt-java\2|g' %{top_level_dir_name}/src/java.base/share/man/java.md | \ + sed -e 's|JAVA(|ALT-JAVA(|' | \ + sed -e "s|java - launch a Java application|alt-java - ${altjavatext}|" >> ${altjavamanpage} # The OpenJDK version file includes the current # upstream version information. For some reason, @@ -1028,13 +1116,41 @@ if [ "x${UPSTREAM_EA_DESIGNATOR}" != "x%{ea_designator}" ] ; then exit 17 fi -# Systemtap is processed in rpms +# Systemtap is processed in rpms on fedoras and epels # Prepare desktop files # Portables do not have desktop integration -%build +# Extract devkit +%if "%{is_dtstoolchain}" == "devkit" + devkittarball=%{_datadir}/%{dtsname}/sdk-%{_target_cpu}-%{_target_os}-gnu*.tar.gz + echo "Extracting devkit ${devkittarball}"; + mkdir devkit; + tar -C devkit --strip-components=1 -xzf ${devkittarball} + DEVKIT_ROOT=$(pwd)/devkit + source ${DEVKIT_ROOT}/devkit.info + echo "Installed ${DEVKIT_NAME} devkit" +%else +%if 0%{?centos} > 0 + echo "No devkit for CentOS %{?centos}" +%else + echo "No devkit for %{_target_cpu} on RHEL %{?rhel}"; +%endif +%endif +%if %{use_portable_bootjdk} + # Extract build JDK + pushd %{_jvmdir} + sha256sum --check %{bootjdkzip}.sha256sum + popd + tar -xJf %{bootjdkzip} + mv java-%{featurever}-openjdk-%{buildjdkver}* %{bootjdk} + # Print release information + echo "Installed boot JDK:" + cat %{bootjdk}/release +%endif + +%build # How many CPU's do we have? export NUM_PROC=%(/usr/bin/getconf _NPROCESSORS_ONLN 2> /dev/null || :) export NUM_PROC=${NUM_PROC:-1} @@ -1042,8 +1158,9 @@ export NUM_PROC=${NUM_PROC:-1} # Honor %%_smp_ncpus_max [ ${NUM_PROC} -gt %{?_smp_ncpus_max} ] && export NUM_PROC=%{?_smp_ncpus_max} %endif +export XZ_OPT="-T0" -%ifarch s390x sparc64 alpha %{power64} %{aarch64} +%ifarch s390x sparc64 alpha %{power64} %{aarch64} riscv64 export ARCH_DATA_MODEL=64 %endif %ifarch alpha @@ -1065,13 +1182,61 @@ EXTRA_CFLAGS="$EXTRA_CFLAGS -fno-strict-aliasing" EXTRA_CFLAGS="$(echo ${EXTRA_CFLAGS} | sed -e 's|-mstackrealign|-mincoming-stack-boundary=2 -mpreferred-stack-boundary=4|')" EXTRA_CPP_FLAGS="$(echo ${EXTRA_CPP_FLAGS} | sed -e 's|-mstackrealign|-mincoming-stack-boundary=2 -mpreferred-stack-boundary=4|')" %endif +%if "%{is_dtstoolchain}" == "devkit" +# Remove annobin plugin reference which isn't available in the devkit +EXTRA_CFLAGS="$(echo ${EXTRA_CFLAGS} | sed -e 's|-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1||')" +EXTRA_CPP_FLAGS="$(echo ${EXTRA_CPP_FLAGS} | sed -e 's|-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1||')" +# Force DWARF 4 for compatibility +EXTRA_CFLAGS="${EXTRA_CFLAGS} -gdwarf-4" +EXTRA_CPP_FLAGS="${EXTRA_CPP_FLAGS} -gdwarf-4" +%endif + export EXTRA_CFLAGS EXTRA_CPP_FLAGS -echo "Building %{SOURCE11}" -mkdir -p %{altjavaoutputdir} -gcc ${EXTRA_CFLAGS} -o %{altjavaoutputdir}/%{alt_java_name} %{SOURCE11} - -echo "Building %{newjavaver}-%{buildver}, pre=%{ea_designator}, opt=%{lts_designator}" +# Set modification times (mtimes) of files within JAR files generated +# by the OpenJDK build to a timestamp that is constant across RPM +# rebuilds. OpenJDK provides the --with-source-date configure option +# for this purpose. Potential arguments in the RPM build context are: +# +# A) --with-source-date="${SOURCE_DATE_EPOCH}" +# B) --with-source-date=version +# C) --with-source-date="${OPENJDK_UPSTREAM_TAG_EPOCH}" +# +# Consider Option A. Fedora 38 (rpm-4.18.2) and RHEL-8 (rpm-4.14.3) +# have different support for SOURCE_DATE_EPOCH. To keep +# SOURCE_DATE_EPOCH constant across RPM rebuilds, one could set the +# source_date_epoch_from_changelog macro to 1 on both Fedora 38 and +# RHEL-8. However, on RHEL-8, this results in the RPM build times +# being set to the timestamp of the most recent changelog. This is +# bad for tracing when RPMs were actually built. Fedora 38 supports a +# better behaviour via the introduction of the +# use_source_date_epoch_as_buildtime macro, set to 0 by default. +# There is no way to make this work on RHEL-8 as well though, so +# option A is suboptimal. +# +# Option B uses the value of the DEFAULT_VERSION_DATE field from +# make/conf/version-numbers.conf. DEFAULT_VERSION_DATE represents the +# aspirational eventual JDK general availability (GA) release date. +# When the RPM build occurs prior to GA, generated JAR files will have +# payload mtimes in the future relative to the RPM build time. +# Whereas for tarballs some tools will issue warnings about future +# mtimes, per OPENJDK-2583 apparently this is no problem for Java and +# JAR files. +# +# Option C uses the modification timestamp of files in the source +# tarball. The reproducibility logic in generate_source_tarball.sh +# sets them all to the commit time of the release-tagged OpenJDK +# commit, as archived in the tarball. This timestamp is deterministic +# across RPM rebuilds and is reliably in the past. Any file's mtime +# will do, so use version-numbers.conf's. +# +# Use option B for JAR files, based on the discussion in OPENJDK-2583. +# +# For portable tarballs, use option C (OPENJDK_UPSTREAM_TAG_EPOCH) for +# the modification times of all files in the portable tarballs. Doing +# so eliminates one source of variability across RPM rebuilds. +VERSION_FILE="$(pwd)"/"%{top_level_dir_name}"/make/conf/version-numbers.conf +OPENJDK_UPSTREAM_TAG_EPOCH="$(stat --format=%Y "${VERSION_FILE}")" function buildjdk() { local outputdir=${1} @@ -1080,6 +1245,7 @@ function buildjdk() { local debuglevel=${4} local link_opt=${5} local debug_symbols=${6} + local devkit=${7} local top_dir_abs_src_path=$(pwd)/%{top_level_dir_name} local top_dir_abs_build_path=$(pwd)/${outputdir} @@ -1101,6 +1267,20 @@ function buildjdk() { echo "Using debug_symbols: ${debug_symbols}" echo "Building %{newjavaver}-%{buildver}, pre=%{ea_designator}, opt=%{lts_designator}" +%if "%{is_dtstoolchain}" == "devkit" + LIBPATH="${devkit}/lib:${devkit}/lib64" + echo "Setting library path to ${LIBPATH}" +%else +%if "%{is_dtstoolchain}" == "toolset" + toolset=/opt/rh/%{dtsname}/root/ + LIBPATH="${toolset}/lib:${toolset}/lib64" + echo "Setting library path to ${LIBPATH}" +%else + LIBPATH=${LD_LIBRARY_PATH} + echo "Keeping library path as ${LIBPATH}" +%endif +%endif + mkdir -p ${outputdir} pushd ${outputdir} @@ -1108,16 +1288,17 @@ function buildjdk() { # rather than ${link_opt} as the system versions # are always used in a system_libs build, even # for the static library build -%if (0%{?rhel} > 0 && 0%{?rhel} < 8) - scl enable devtoolset-%{dtsversion} -- bash ${top_dir_abs_src_path}/configure \ -%else - bash ${top_dir_abs_src_path}/configure \ -%endif + LD_LIBRARY_PATH=${LIBPATH} \ + %{?dts_command} bash ${top_dir_abs_src_path}/configure \ %ifarch %{zero_arches} --with-jvm-variants=zero \ %endif -%ifarch %{ppc64le} - --with-jobs=1 \ +%if "%{is_dtstoolchain}" == "devkit" + --with-devkit=${devkit} \ +%endif +%if "%{is_dtstoolchain}" == "toolset" + --with-extra-path="/opt/rh/%{dtsname}/root/bin:/opt/rh/%{dtsname}/root/usr/bin" \ + --with-toolchain-path="/opt/rh/%{dtsname}/root/bin:/opt/rh/%{dtsname}/root/usr/bin" \ %endif --with-version-build=%{buildver} \ --with-version-pre="%{ea_designator}" \ @@ -1130,8 +1311,10 @@ function buildjdk() { --with-boot-jdk=${buildjdk} \ --with-debug-level=${debuglevel} \ --with-native-debug-symbols="${debug_symbols}" \ - --disable-sysconf-nss \ + --disable-absolute-paths-in-output \ --enable-unlimited-crypto \ + --enable-linkable-runtime \ + --enable-keep-packaged-modules \ --with-zlib=%{link_type} \ --with-freetype=%{link_type} \ --with-libjpeg=${link_opt} \ @@ -1144,79 +1327,28 @@ function buildjdk() { --with-extra-cflags="$EXTRA_CFLAGS" \ --with-extra-ldflags="%{ourldflags}" \ --with-num-cores="$NUM_PROC" \ - --with-source-date="${SOURCE_DATE_EPOCH}" \ + --with-source-date="version" \ --disable-javac-server \ %ifarch %{zgc_arches} --with-jvm-features=zgc \ %endif - --disable-warnings-as-errors + --disable-warnings-as-errors \ + || ( pwd; cat $(find | grep config.log) && false ) cat spec.gmk -%if (0%{?rhel} > 0 && 0%{?rhel} < 8) - scl enable devtoolset-%{dtsversion} -- make \ -%else - make \ -%endif - LOG=trace \ + LD_LIBRARY_PATH=${LIBPATH} \ + %{?dts_command} make LOG=trace \ WARNINGS_ARE_ERRORS="-Wno-error" \ - CFLAGS_WARNINGS_ARE_ERRORS="-Wno-error" \ - $maketargets || ( pwd; find ${top_dir_abs_src_path} ${top_dir_abs_build_path} -name "hs_err_pid*.log" | xargs cat && false ) + CFLAGS_WARNINGS_ARE_ERRORS="-Wno-error" $maketargets ||\ + ( pwd; find ${top_dir_abs_src_path} ${top_dir_abs_build_path} -name \"hs_err_pid*.log\" | xargs cat && false ) popd } -function stripjdk() { - local outputdir=${1} - local jdkimagepath=${outputdir}/images/%{jdkimage} - local jreimagepath=${outputdir}/images/%{jreimage} - local jmodimagepath=${outputdir}/images/jmods - local supportdir=${outputdir}/support - - if [ "x$suffix" = "x" ] ; then - # Keep the unstripped version for consumption by RHEL RPMs - cp -a ${jdkimagepath}{,.unstripped} - - # Strip the files - for file in $(find ${jdkimagepath} ${jreimagepath} ${supportdir} -type f) ; do - if file ${file} | grep -q 'ELF'; then - noextfile=${file/.so/}; - objcopy --only-keep-debug ${file} ${noextfile}.debuginfo; - objcopy --add-gnu-debuglink=${noextfile}.debuginfo ${file}; - strip -g ${file}; - fi - done - - # Rebuild jmod files against the stripped binaries - if [ ! -d ${supportdir} ] ; then - echo "Support directory missing."; - exit 15 - fi - for cmd in $(find ${supportdir} -name '*.jmod_exec.cmdline') ; do - pre=${cmd/_exec/_pre}; - post=${cmd/_exec/_post}; - jmod=$(echo ${cmd}|sed 's#.*_create_##'|sed 's#_exec.cmdline##') - echo "Rebuilding ${jmod} against stripped binaries..."; - if [ -e ${pre} ] ; then - echo "Executing ${pre}..."; - cat ${pre} | sh -s ; - fi - echo "Executing ${cmd}..."; - cat ${cmd} | sh -s ; - if [ -e ${post} ] ; then - echo "Executing ${post}..."; - cat ${post} | sh -s ; - fi - done - rm -rf ${jdkimagepath}/jmods - cp -a ${jmodimagepath} ${jdkimagepath} - fi -} - function installjdk() { local outputdir=${1} local installdir=${2} local jdkimagepath=${installdir}/images/%{jdkimage} local jreimagepath=${installdir}/images/%{jreimage} - local unstripped=${jdkimagepath}.unstripped echo "Installing build from ${outputdir} to ${installdir}..." mkdir -p ${installdir} @@ -1235,6 +1367,7 @@ function installjdk() { # legacy-jre-image target does not install any man pages for the JRE # We copy the jdk man directory and then remove pages for binaries that # don't exist in the JRE +%if %{pandoc_available} cp -a ${jdkimagepath}/man ${jreimagepath} for manpage in $(find ${jreimagepath}/man -name '*.1'); do filename=$(basename ${manpage}); @@ -1244,8 +1377,9 @@ function installjdk() { rm -f ${manpage}; fi; done +%endif - for imagepath in ${jdkimagepath} ${jreimagepath} ${unstripped}; do + for imagepath in ${jdkimagepath} ${jreimagepath}; do if [ -d ${imagepath} ] ; then # the build (erroneously) removes read permissions from some jars @@ -1261,13 +1395,6 @@ function installjdk() { # Install local files which are distributed with the JDK install -m 644 %{SOURCE10} ${imagepath} - # Create fake alt-java as a placeholder for future alt-java - pushd ${imagepath} - # add alt-java man page - echo "Hardened java binary recommended for launching untrusted code from the Web e.g. javaws" > man/man1/%{alt_java_name}.1 - cat man/man1/java.1 >> man/man1/%{alt_java_name}.1 - popd - # Print release information cat ${imagepath}/release fi @@ -1289,10 +1416,39 @@ function genchecksum() { function packFullPatchedSources() { srcpackagesdir=`pwd` - tar -cJf ${srcpackagesdir}/%{jdkportablesourcesarchive -- ""} --transform "s|^|%{jdkportablesourcesname -- ""}/|" %{top_level_dir_name} + createtar ${srcpackagesdir}/%{jdkportablesourcesarchive -- ""} --transform "s|^|%{jdkportablesourcesname -- ""}/|" %{top_level_dir_name} genchecksum ${srcpackagesdir}/%{jdkportablesourcesarchive -- ""} } +function findgeneratedsources() { + local targetDir=${1} + local targetDirParent=$(dirname ${targetDir}) + local builtJdk=${2} + local builtJdkName=$(basename ${builtJdk}) + local sources=${3} + local sourcesName=$(basename ${sources}) + local sourcesParent=$(dirname ${sources}) + local target=${sourcesParent}/${targetDirParent}/%{generated_sources_name} + local suffixes="cpp\|hpp\|h\|hh\|rl" + suffixes=".*\.\($suffixes\)$" + mkdir -p $target + pushd ${builtJdk} + mkdir -p ${target}/${builtJdkName} + cp --parents $(find . | grep -e "$suffixes" -e "NONE$") ${target}/${builtJdkName} + popd + pushd ${sources} + mkdir -p ${target}/${sourcesName} + cp --parents $(find make | grep -e ".$suffixes" -e "NONE$") ${target}/${sourcesName} + popd +} + +# Create a reproducible tarball in an appropriate way for +# the version of tar in use +function createtar() { + #FIXME, not finished + tar -cJf "$@" +} + function packagejdk() { local imagesdir=$(pwd)/${1}/images local docdir=$(pwd)/${1}/images/docs @@ -1301,14 +1457,12 @@ function packagejdk() { local srcdir=$(pwd)/%{top_level_dir_name} local tapsetdir=$(pwd)/tapset local altjavadir=$(pwd)/${3} + local gensources=$(pwd)/%{miscinstalloutputdir}/%{generated_sources_name} echo "Packaging build from ${imagesdir} to ${packagesdir}..." mkdir -p ${packagesdir} pushd ${imagesdir} - echo "Packaging build from ${imagesdir} to ${packagesdir}..." - mkdir -p ${packagesdir} - if [ "x$suffix" = "x" ] ; then nameSuffix="" else @@ -1317,12 +1471,12 @@ function packagejdk() { jdkname=%{jdkportablename -- "$nameSuffix"} jdkarchive=${packagesdir}/%{jdkportablearchive -- "$nameSuffix"} + jmodsarchive=${packagesdir}/%{jmodsportablearchive -- "$nameSuffix"} jrename=%{jreportablename -- "$nameSuffix"} jrearchive=${packagesdir}/%{jreportablearchive -- "$nameSuffix"} staticname=%{staticlibsportablename -- "$nameSuffix"} staticarchive=${packagesdir}/%{staticlibsportablearchive -- "$nameSuffix"} debugarchive=${packagesdir}/%{jdkportablearchive -- "${nameSuffix}.debuginfo"} - unstrippedarchive=${packagesdir}/%{jdkportablearchive -- "${nameSuffix}.unstripped"} if [ "x$suffix" = "x" ] ; then docname=%{docportablename} docarchive=${packagesdir}/%{docportablearchive} @@ -1332,27 +1486,22 @@ function packagejdk() { miscname=%{miscportablename} miscarchive=${packagesdir}/%{miscportablearchive} - if [ "x$suffix" = "x" ] ; then - # Keep the unstripped version for consumption by RHEL RPMs - mv %{jdkimage}.unstripped ${jdkname} - tar -cJf ${unstrippedarchive} ${jdkname} - genchecksum ${unstrippedarchive} - mv ${jdkname} %{jdkimage}.unstripped - fi - # Rename directories for packaging mv %{jdkimage} ${jdkname} mv %{jreimage} ${jrename} # Release images have external debug symbols if [ "x$suffix" = "x" ] ; then - tar -cJf ${debugarchive} $(find ${jdkname} -name \*.debuginfo) + # jdk26 is putting debugsymbols out of main image, + # we later reconstruct debuginfo subpakckages manually, so putting them back + cp -r symbols/* ${jdkname}/ + createtar ${debugarchive} $(find ${jdkname} -name \*.debuginfo) genchecksum ${debugarchive} mkdir ${docname} mv ${docdir} ${docname} mv ${bundledir}/${built_doc_archive} ${docname} - tar -cJf ${docarchive} ${docname} + createtar ${docarchive} ${docname} genchecksum ${docarchive} mkdir ${miscname} @@ -1363,21 +1512,26 @@ function packagejdk() { cp -a ${tapsetdir}* ${miscname} %endif cp -av ${altjavadir}/%{alt_java_name} ${miscname} - tar -cJf ${miscarchive} ${miscname} + cp -avr ${gensources} ${miscname} + createtar ${miscarchive} ${miscname} genchecksum ${miscarchive} fi - tar -cJf ${jdkarchive} --exclude='**.debuginfo' ${jdkname} + createtar ${jmodsarchive} --exclude='**.debuginfo' ${jdkname}/jmods + genchecksum ${jmodsarchive} + rm -rv ${jdkname}/jmods + + createtar ${jdkarchive} --exclude='**.debuginfo' ${jdkname} genchecksum ${jdkarchive} - tar -cJf ${jrearchive} --exclude='**.debuginfo' ${jrename} + createtar ${jrearchive} --exclude='**.debuginfo' ${jrename} genchecksum ${jrearchive} %if %{include_staticlibs} # Static libraries (needed for building graal vm with native image) # Tar as overlay. Transform to the JDK name, since we just want to "add" # static libraries to that folder - tar -cJf ${staticarchive} \ + createtar ${staticarchive} \ --transform "s|^%{static_libs_image}/lib/*|${staticname}/lib/static/linux-%{archinstall}/glibc/|" "%{static_libs_image}/lib" genchecksum ${staticarchive} %endif @@ -1393,28 +1547,54 @@ function packagejdk() { packFullPatchedSources +%if "%{is_dtstoolchain}" == "devkit" + DEVKIT_ROOT=$(pwd)/devkit + source ${DEVKIT_ROOT}/devkit.info + GCC="${DEVKIT_TOOLCHAIN_PATH}/gcc --sysroot=${DEVKIT_SYSROOT}" + LIBPATH="${DEVKIT_ROOT}/lib:${DEVKIT_ROOT}/lib64" +%else +%if "%{is_dtstoolchain}" == "toolset" + toolset=/opt/rh/%{dtsname}/root/ + GCC="${toolset}/usr/bin/gcc" + LIBPATH="${toolset}/lib:${toolset}/lib64" +%else + GCC=$(which gcc) +%endif +%endif + +echo "Building %{SOURCE11}" +mkdir %{miscinstalloutputdir} +mkdir %{altjavaoutputdir} +LD_LIBRARY_PATH="${LIBPATH}" ${GCC} ${EXTRA_CFLAGS} -o %{altjavaoutputdir}/%{alt_java_name} %{SOURCE11} + +echo "Building %{newjavaver}-%{buildver}, pre=%{ea_designator}, opt=%{lts_designator}" + %if %{build_hotspot_first} # Build a fresh libjvm.so first and use it to bootstrap + echo "Building HotSpot only for the latest libjvm.so" cp -LR --preserve=mode,timestamps %{bootjdk} newboot systemjdk=$(pwd)/newboot - buildjdk build/newboot ${systemjdk} %{hotspot_target} "release" "bundled" "internal" + buildjdk build/newboot ${systemjdk} %{hotspot_target} "release" "bundled" "internal" ${DEVKIT_ROOT} mv build/newboot/jdk/lib/%{vm_variant}/libjvm.so newboot/lib/%{vm_variant} %else systemjdk=%{bootjdk} %endif for suffix in %{build_loop} ; do - if [ "x$suffix" = "x" ] ; then debugbuild=release else # change --something to something debugbuild=`echo $suffix | sed "s/-//g"` fi - # We build with internal debug symbols and do - # our own stripping for one version of the - # release build - debug_symbols=internal + # We build with 'external' debug symbols for the + # release build and build with 'internal' for + # slowdebug/fastdebug variants + if [ "x$suffix" = "x" ] ; then + debug_symbols=external + else + debug_symbols=internal + fi builddir=%{buildoutputdir -- ${suffix}} bootbuilddir=boot${builddir} @@ -1440,15 +1620,15 @@ for suffix in %{build_loop} ; do run_bootstrap=%{bootstrap_build} fi if ${run_bootstrap} ; then - buildjdk ${bootbuilddir} ${systemjdk} "%{bootstrap_targets}" ${debugbuild} ${link_opt} ${debug_symbols} + buildjdk ${bootbuilddir} ${systemjdk} "%{bootstrap_targets}" ${debugbuild} ${link_opt} ${debug_symbols} ${DEVKIT_ROOT} installjdk ${bootbuilddir} ${bootinstalldir} - buildjdk ${builddir} $(pwd)/${bootinstalldir}/images/%{jdkimage} "${maketargets}" ${debugbuild} ${link_opt} ${debug_symbols} - stripjdk ${builddir} + buildjdk ${builddir} $(pwd)/${bootinstalldir}/images/%{jdkimage} "${maketargets}" ${debugbuild} ${link_opt} ${debug_symbols} ${DEVKIT_ROOT} + findgeneratedsources ${installdir} ${builddir} $(pwd)/%{top_level_dir_name} installjdk ${builddir} ${installdir} %{!?with_artifacts:rm -rf ${bootinstalldir}} else - buildjdk ${builddir} ${systemjdk} "${maketargets}" ${debugbuild} ${link_opt} ${debug_symbols} - stripjdk ${builddir} + buildjdk ${builddir} ${systemjdk} "${maketargets}" ${debugbuild} ${link_opt} ${debug_symbols} ${DEVKIT_ROOT} + findgeneratedsources ${installdir} ${builddir} $(pwd)/%{top_level_dir_name} installjdk ${builddir} ${installdir} fi packagejdk ${installdir} ${packagesdir} %{altjavaoutputdir} @@ -1467,7 +1647,7 @@ done # end of release / debug cycle loop # We test debug first as it will give better diagnostics on a crash for suffix in %{build_loop} ; do -# portable builds have static_libs embedded, thus top_dir_abs_main_build_path is same as top_dir_abs_staticlibs_build_path +# portable builds have static_libs embedded, thus top_dir_abs_main_build_path is same as top_dir_abs_staticlibs_build_path top_dir_abs_main_build_path=$(pwd)/%{installoutputdir -- ${suffix}} %if %{include_staticlibs} top_dir_abs_staticlibs_build_path=${top_dir_abs_main_build_path} @@ -1482,51 +1662,91 @@ 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 +# Set up tools +%if "%{is_dtstoolchain}" == "devkit" + DEVKIT_ROOT=$(pwd)/devkit + source ${DEVKIT_ROOT}/devkit.info + NM="${DEVKIT_TOOLCHAIN_PATH}/nm" +%else + NM=$(which nm) +%endif +# elfutils readelf supports more binaries than binutils version on RHEL 8 +# and debug symbols tests below were designed around this version +READELF=$(which eu-readelf) +# Only native gdb seems to work +# The devkit gdb needs the devkit stdc++ library but then the JVM +# segfaults when this is on the LD_LIBRARY_PATH +GDB=$(which gdb) + # Check Shenandoah is enabled %if %{use_shenandoah_hotspot} -$JAVA_HOME/bin/java -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -version +$JAVA_HOME/bin/java -XX:+UseShenandoahGC -version %endif -# Check unlimited policy has been used -$JAVA_HOME/bin/javac -d . %{SOURCE13} -$JAVA_HOME/bin/java --add-opens java.base/javax.crypto=ALL-UNNAMED TestCryptoLevel +# Only test on one architecture (the fastest) for Java only tests +%ifarch %{jdk_test_arch} -# Check ECC is working -$JAVA_HOME/bin/javac -d . %{SOURCE14} -$JAVA_HOME/bin/java $(echo $(basename %{SOURCE14})|sed "s|\.java||") + # Check unlimited policy has been used + $JAVA_HOME/bin/javac -d . %{SOURCE13} + $JAVA_HOME/bin/java --add-opens java.base/javax.crypto=ALL-UNNAMED TestCryptoLevel -# Check system crypto (policy) is deactive and can not be enabled -# Test takes a single argument - true or false - to state whether system -# security properties are enabled or not. -$JAVA_HOME/bin/javac -d . %{SOURCE15} -export PROG=$(echo $(basename %{SOURCE15})|sed "s|\.java||") -export SEC_DEBUG="-Djava.security.debug=properties" -# Specific to portable:System security properties to be off by default -$JAVA_HOME/bin/java ${SEC_DEBUG} ${PROG} false -$JAVA_HOME/bin/java ${SEC_DEBUG} -Djava.security.disableSystemPropertiesFile=false ${PROG} false + # Check ECC is working + $JAVA_HOME/bin/javac -d . %{SOURCE14} + $JAVA_HOME/bin/java $(echo $(basename %{SOURCE14})|sed "s|\.java||") -# Check correct vendor values have been set -$JAVA_HOME/bin/javac -d . %{SOURCE16} -$JAVA_HOME/bin/java $(echo $(basename %{SOURCE16})|sed "s|\.java||") "%{oj_vendor}" "%{oj_vendor_url}" "%{oj_vendor_bug_url}" "%{oj_vendor_version}" + # Check system crypto (policy) is deactive and can not be enabled + # Test takes a single argument - true or false - to state whether system + # security properties are enabled or not. + $JAVA_HOME/bin/javac -d . %{SOURCE15} + export PROG=$(echo $(basename %{SOURCE15})|sed "s|\.java||") + export SEC_DEBUG="-Djava.security.debug=properties" + # Specific to portable:System security properties to be off by default + $JAVA_HOME/bin/java ${SEC_DEBUG} ${PROG} false + $JAVA_HOME/bin/java ${SEC_DEBUG} -Djava.security.disableSystemPropertiesFile=false ${PROG} false + + # Check correct vendor values have been set + $JAVA_HOME/bin/javac -d . %{SOURCE16} + $JAVA_HOME/bin/java $(echo $(basename %{SOURCE16})|sed "s|\.java||") "%{oj_vendor}" "%{oj_vendor_url}" "%{oj_vendor_bug_url}" "%{oj_vendor_version}" + +%if ! 0%{?flatpak} + # 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 + $JAVA_HOME/bin/javac -d . %{SOURCE18} + $JAVA_HOME/bin/java $(echo $(basename %{SOURCE18})|sed "s|\.java||") JRE || echo "Fedora is often ahead in timezones, ignoring" + $JAVA_HOME/bin/java -Djava.locale.providers=CLDR $(echo $(basename %{SOURCE18})|sed "s|\.java||") CLDR || echo "Fedora is often ahead in timezones, ignoring" +%endif + + # Check src.zip has all sources. See RHBZ#1130490 + unzip -l $JAVA_HOME/lib/src.zip | grep 'sun.misc.Unsafe' + + # Check class files include useful debugging information + $JAVA_HOME/bin/javap -c -l java.lang.Object | grep "Compiled from" + $JAVA_HOME/bin/javap -c -l java.lang.Object | grep LineNumberTable + $JAVA_HOME/bin/javap -c -l java.lang.Object | grep LocalVariableTable + + # Check generated class files include useful debugging information + $JAVA_HOME/bin/javap -c -l java.nio.ByteBuffer | grep "Compiled from" + $JAVA_HOME/bin/javap -c -l java.nio.ByteBuffer | grep LineNumberTable + $JAVA_HOME/bin/javap -c -l java.nio.ByteBuffer | grep LocalVariableTable + +%else + + # Just run a basic java -version test on other architectures + $JAVA_HOME/bin/java -version + +%endif # Check java launcher has no SSB mitigation -if ! nm $JAVA_HOME/bin/java | grep set_speculation ; then true ; else false; fi +if ! ${NM} $JAVA_HOME/bin/java | grep set_speculation ; then true ; else false; fi # Check alt-java launcher has SSB mitigation on supported architectures # set_speculation function exists in both cases, so check for prctl call %ifarch %{ssbd_arches} -nm %{altjavaoutputdir}/%{alt_java_name} | grep prctl +${NM} %{altjavaoutputdir}/%{alt_java_name} | grep prctl %else -if ! nm %{altjavaoutputdir}/%{alt_java_name} | grep prctl ; then true ; else false; fi -%endif - -%if ! 0%{?flatpak} -# 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) -$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 +if ! ${NM} %{altjavaoutputdir}/%{alt_java_name} | grep prctl ; then true ; else false; fi %endif %if %{include_staticlibs} @@ -1534,8 +1754,8 @@ $JAVA_HOME/bin/java -Djava.locale.providers=CLDR $(echo $(basename %{SOURCE18})| export STATIC_LIBS_HOME=${top_dir_abs_staticlibs_build_path}/images/%{static_libs_image} ls -l $STATIC_LIBS_HOME ls -l $STATIC_LIBS_HOME/lib -readelf --debug-dump $STATIC_LIBS_HOME/lib/libnet.a | grep Inet4AddressImpl.c -readelf --debug-dump $STATIC_LIBS_HOME/lib/libnet.a | grep Inet6AddressImpl.c +${READELF} --debug-dump $STATIC_LIBS_HOME/lib/libnet.a | grep Inet4AddressImpl.c +${READELF} --debug-dump $STATIC_LIBS_HOME/lib/libnet.a | grep Inet6AddressImpl.c %endif # Release builds strip the debug symbols into external .debuginfo files @@ -1554,15 +1774,15 @@ do # Test for .debug_* sections in the shared object. This is the main test # Stripped objects will not contain these - eu-readelf -S "$lib" | grep "] .debug_" - test $(eu-readelf -S "$lib" | grep -E "\]\ .debug_(info|abbrev)" | wc --lines) == 2 + ${READELF} -S "$lib" | grep "] .debug_" + test $(${READELF} -S "$lib" | grep -E "\]\ .debug_(info|abbrev)" | wc --lines) == 2 # Test FILE symbols. These will most likely be removed by anything that # manipulates symbol tables because it's generally useless. So a nice test # that nothing has messed with symbols old_IFS="$IFS" IFS=$'\n' - for line in $(eu-readelf -s "$lib" | grep "00000000 0 FILE LOCAL DEFAULT") + for line in $(${READELF} -s "$lib" | grep "00000000 0 FILE LOCAL DEFAULT") do # We expect to see .cpp and .S files, except for architectures like aarch64 and # s390 where we expect .o and .oS files @@ -1572,17 +1792,17 @@ do # If this is the JVM, look for javaCalls.(cpp|o) in FILEs, for extra sanity checking if [ "`basename $lib`" = "libjvm.so" ]; then - eu-readelf -s "$lib" | \ + ${READELF} -s "$lib" | \ grep -E "00000000 0 FILE LOCAL DEFAULT ABS javaCalls.(cpp|o)$" fi # Test that there are no .gnu_debuglink sections pointing to another # debuginfo file. There shouldn't be any debuginfo files, so the link makes # no sense either - eu-readelf -S "$lib" | grep 'gnu' - if eu-readelf -S "$lib" | grep '] .gnu_debuglink' | grep PROGBITS; then + ${READELF} -S "$lib" | grep 'gnu' + if ${READELF} -S "$lib" | grep '] .gnu_debuglink' | grep PROGBITS; then echo "bad .gnu_debuglink section." - eu-readelf -x .gnu_debuglink "$lib" + ${READELF} -x .gnu_debuglink "$lib" false fi fi @@ -1594,7 +1814,7 @@ done # Using line number 1 might cause build problems. See: # https://bugzilla.redhat.com/show_bug.cgi?id=1539664 # https://bugzilla.redhat.com/show_bug.cgi?id=1538767 -gdb -q "$JAVA_HOME/bin/java" < - 1:21.0.1.0.12-2.rolling -- updated to OpenJDK 21.0.1 (2023-10-17) -- adjsuted generate_source_tarball -- removed icedtea_sync -- dropped standalone licenses -- added usntripped subpkg -- added docs subpkg -- adjsuted versions of bundled libraries -- build refactored to several solid methods following gnu_andrew -- removed no longer needed jdk8296108-tzdata2022f.patch, jdk8296715-cldr2022f.patch, rh1648644-java_access_bridge_privileged_security.patch -- added jdk8311630-s390_ffmapi.patch to support virtual threads on s390x -- aligned fips-21u-75ffdc48eda.patch (gnu_andrew) -- fixed '--without release' build-ability by moving docs and misc to if-release only - -* Wed Sep 20 2023 Jiri Vanek - 1:21.0.0.0.35-4.rolling -- removed %{1} from miscportablename - -* Fri Sep 15 2023 Andrew Hughes - 1:21.0.0.0.35-3.rolling -- Update documentation (README.md, add missing JEP to release notes) -- Replace alt-java patch with a binary separate from the JDK -- Drop stale patches that are of little use any more: -- * nss.cfg has been disabled since early PKCS11 work and long superseded by FIPS work -- * No accessibility subpackage to warrant RH1648242 patch any more -- * No use of system libjpeg turbo to warrant RH649512 patch any more -- Replace RH1684077 pcsc-lite-libs patch with better JDK-8009550 fix being upstreamed -- Update generate_tarball.sh to sync with upstream vanilla script -- Change top_level_dir_name to use the VCS tag, matching new upstream release style tarball -- Use upstream release URL for OpenJDK source -- Port misc tarball from RHEL to house alt-java outside the JDK tree -- Port improved tarball creation and checking from RHEL so tarballs are verified - -* Thu Sep 14 2023 Andrew Hughes - 1:21.0.0.0.35-2.rolling -- Bump buildjdkver now that java-21-openjdk is available in the buildroot - -* Tue Aug 08 2023 Petra Alice Mikova 1:21.0.0.0.35-1.rolling -- updated to jdk-21+35, which is no longer EA - -* Tue Aug 08 2023 Petra Alice Mikova 1:21.0.0.0.34-0.1.ea.rolling -- initial update to jdk21 -- commented out fips patches -- updated to jdk21 ea -- updated patch 1001 - rh1648249-add_commented_out_nss_cfg_provider_to_java_security -- replace smoketests in staticlibs test, as the previous files used were removed by a patch in JDK -- require tzdata 2023c -- Update FIPS support to bring in latest changes -- * RH2048582: Support PKCS#12 keystores -- * RH2020290: Support TLS 1.3 in FIPS mode -- * Add nss.fips.cfg support to OpenJDK tree -- * RH2117972: Extend the support for NSS DBs (PKCS11) in FIPS mode -- * Remove forgotten dead code from RH2020290 and RH2104724 -- * OJ1357: Fix issue on FIPS with a SecurityManager in place -- * RH2134669: Add missing attributes when registering services in FIPS mode. -- * test/jdk/sun/security/pkcs11/fips/VerifyMissingAttributes.java: fixed jtreg main class -- * RH1940064: Enable XML Signature provider in FIPS mode -- * Remove GCC minor versioning (JDK-8284772) to unbreak testing -- Drop local nss.fips.cfg.in handling now this is handled in the patched OpenJDK build - -* Thu Aug 03 2023 Jiri Vanek - 1:20.0.2.0.9-1.rolling -- Update to jdk-20.0.2+9 -- Update release notes to 20.0.2+9 - -* Thu Jul 20 2023 Fedora Release Engineering - 1:20.0.1.0.9-5.rolling.1 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild - -* Tue Jun 27 2023 Kalev Lember - 1:20.0.1.0.9-5.rolling -- Simplify portable archive name macros - -* Mon May 15 2023 Jiri Vanek - 1:20.0.1.0.9-4.rolling -- Redeclared ForFiles release sections as %%nil no longer works with %%1 -- RPM 4.19 no longer accept our double percentaged %%{nil} passed to %%{1} -- so we have to pass in "" but evaluate it, otherwise files record will include it - -* Mon May 15 2023 Jiri Vanek - 1:20.0.1.0.9-3.rolling -- no longer using system cacerts during build -- they are already mv-ed as .upstream in rpms - -* Wed May 10 2023 Jiri Vanek - 1:20.0.1.0.9-2.rolling -- enabled all crypto - -* Wed Apr 26 2023 Andrew Hughes - 1:20.0.1.0.9-1.rolling -- Update to jdk-20.0.1+9 -- Update release notes to 20.0.1+9 - -* Fri Apr 14 2023 Jiri Vanek - 1:20.0.0.0.36-3.rolling -- introduced archfull src archive -- replaced nasty handling of icons. -- needed for icons and src reference for rpms (debuginfo, src subpkg) -- licences moved to proper sharable noarch - -* Mon Apr 10 2023 Andrew Hughes - 1:20.0.0.0.36-2.rolling -- Complete update to OpenJDK 20 -- Update NEWS -- Update system crypto policy & FIPS patch from new fips-20u tree -- * RH2104724: Avoid import/export of DH private keys -- * RH2092507: P11Key.getEncoded does not work for DH keys in FIPS mode -- * Build the systemconf library on all platforms -- Update generate_tarball.sh ICEDTEA_VERSION and add support for passing a boot JDK to the configure run -- Revert changes to generate_tarball.sh which break error handling -- Add POSIX-friendly error codes to generate_tarball.sh and fix whitespace -- Remove .jcheck and GitHub support when generating tarballs, as done in upstream release tarballs -- Revert changes to patch macro which break on older versions of rpm (4.16) -- Revert changes to configure run -- Revert RH1648429 patch changes -- Update CLDR reference data following update to 42 (Rocky Mountain-Normalzeit => Rocky-Mountain-Normalzeit) -- Re-enable disabled translation test -- Automatically turn off building a fresh HotSpot first, if the bootstrap JDK is not the same major version as that being built - -* Tue Mar 28 2023 Jiri Vanek - 1:20.0.0.0.36-1.rolling -- moved to jdk20 -- remvoed already upstreamed patches patch2006,2007,2008,2009 -- commented out not yet adapted patch1001 - fips support -- removed --disable-sysconf-nss due to missing patch 1001 from configure --- todo return both patch1001 and disable-sysconf-nss! -- adapted rh1648249-add_commented_out_nss_cfg_provider_to_java_security.patch and rh1750419-redhat_alt_java.patch patches -- inverted fresh_libjvm behavior to be disabled by default. fails: --- See: https://koji.fedoraproject.org/koji/taskinfo?taskID=99242677 -- commented out tzdata tests -- moved from deprecated patchN to patch N - -* Tue Feb 07 2023 Jiri Vanel - 1:19.0.2.0.7-2.rolling -- added png icons from x11 source package, so they can be reused by rpms - - * Thu Jan 26 2023 Andrew Hughes - 1:19.0.2.0.7-1.rolling -- Update to jdk-19.0.2 release -- Update release notes to 19.0.2 -- Drop JDK-8293834 (CLDR update for Kyiv) which is now upstream -- Drop JDK-8294357 (tzdata2022d), JDK-8295173 (tzdata2022e) & JDK-8296108 (tzdata2022f) local patches which are now upstream -- Drop JDK-8296715 (CLDR update for 2022f) which is now upstream -- Add local patch JDK-8295447 (javac NPE) which was accepted into 19u upstream but not in the GA tag -- Add local patches for JDK-8296239 & JDK-8299439 (Croatia Euro update) which are present in 8u, 11u & 17u releases - -* Thu Jan 19 2023 Andrew Hughes - 1:19.0.1.0.10-3.rolling - - Update in-tree tzdata & CLDR to 2022g with JDK-8296108, JDK-8296715 & JDK-8297804 - - Update TestTranslations.java to test the new America/Ciudad_Juarez zone - -* Thu Jan 19 2023 Stephan Bergmann - 1:19.0.1.0.10-3.rolling - - Fix flatpak builds by disabling TestTranslations test due to missing tzdb.dat - -* Thu Jan 19 2023 Fedora Release Engineering - 1:19.0.1.0.10-3.rolling.1 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild - -* Thu Jan 12 2023 Jiri Vanel - 1:19.0.1.0.10-3.rolling -- keep system crypto policy honoring disabled (test adapted) -- keep upstream cacerts -- call installjdk also for jreimage. -- add alt-java man page conditionaly (se install openjdk for jre above) -- convert man pages to utf8 (conditionally, man pages are not in jre) -- stabilised permissions as was in rpms -- use NEWS both in tarball and outside -- for release sdk use javadoc archive. -- remove STRIP_KEEP_SYMTAB=libjvm* and all todo as it is going to continue in rpms only - (hopefully) - -* Thu Dec 01 2022 Petra Alice Mikova - 1:19.0.1.0.10-2.rolling -- initial import - +%autochangelog diff --git a/jconsole.desktop.in b/jconsole.desktop.in deleted file mode 100644 index c1b8f6a..0000000 --- a/jconsole.desktop.in +++ /dev/null @@ -1 +0,0 @@ -# this file is intentionally not here, as portable builds do not have desktop integration diff --git a/jdk8009550-rh910107-fail_to_load_pcsc_library.patch b/jdk8009550-rh910107-fail_to_load_pcsc_library.patch deleted file mode 100644 index 9213937..0000000 --- a/jdk8009550-rh910107-fail_to_load_pcsc_library.patch +++ /dev/null @@ -1,125 +0,0 @@ -commit d0523302416bc6507696f20d1068f16427bcf6b8 -Author: Andrew Hughes -Date: Thu Aug 24 01:23:49 2023 +0100 - - 8009550: PlatformPCSC should load versioned so - -diff --git a/src/java.base/share/classes/sun/security/util/Debug.java b/src/java.base/share/classes/sun/security/util/Debug.java -index bff273c6548..e5a6b288ff8 100644 ---- a/src/java.base/share/classes/sun/security/util/Debug.java -+++ b/src/java.base/share/classes/sun/security/util/Debug.java -@@ -81,6 +81,7 @@ public static void Help() - System.err.println("logincontext login context results"); - System.err.println("jca JCA engine class debugging"); - System.err.println("keystore KeyStore debugging"); -+ System.err.println("pcsc Smartcard library debugging"); - System.err.println("policy loading and granting"); - System.err.println("provider security provider debugging"); - System.err.println("pkcs11 PKCS11 session manager debugging"); -diff --git a/src/java.smartcardio/unix/classes/sun/security/smartcardio/PlatformPCSC.java b/src/java.smartcardio/unix/classes/sun/security/smartcardio/PlatformPCSC.java -index bacff32efbc..d9f605ada1e 100644 ---- a/src/java.smartcardio/unix/classes/sun/security/smartcardio/PlatformPCSC.java -+++ b/src/java.smartcardio/unix/classes/sun/security/smartcardio/PlatformPCSC.java -@@ -1,5 +1,6 @@ - /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2023, Red Hat Inc. 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 -@@ -46,8 +47,13 @@ class PlatformPCSC { - - private static final String PROP_NAME = "sun.security.smartcardio.library"; - -- private static final String LIB1 = "/usr/$LIBISA/libpcsclite.so"; -- private static final String LIB2 = "/usr/local/$LIBISA/libpcsclite.so"; -+ private static final String[] LIB_TEMPLATES = { "/usr/$LIBISA/libpcsclite.so", -+ "/usr/local/$LIBISA/libpcsclite.so", -+ "/usr/lib/$ARCH-linux-gnu/libpcsclite.so", -+ "/usr/lib/arm-linux-gnueabi/libpcsclite.so", -+ "/usr/lib/arm-linux-gnueabihf/libpcsclite.so", -+ "/usr/lib/$ARCH-kfreebsd-gnu/libpcsclite.so" }; -+ private static final String[] LIB_SUFFIXES = { ".1", ".0", "" }; - private static final String PCSC_FRAMEWORK = "/System/Library/Frameworks/PCSC.framework/Versions/Current/PCSC"; - - PlatformPCSC() { -@@ -73,23 +79,38 @@ public Throwable run() { - }); - - // expand $LIBISA to the system specific directory name for libraries -+ // expand $ARCH to the Debian system architecture in use - private static String expand(String lib) { - int k = lib.indexOf("$LIBISA"); -- if (k == -1) { -- return lib; -+ if (k != -1) { -+ String libDir; -+ if ("64".equals(System.getProperty("sun.arch.data.model"))) { -+ // assume Linux convention -+ libDir = "lib64"; -+ } else { -+ // must be 32-bit -+ libDir = "lib"; -+ } -+ lib = lib.replace("$LIBISA", libDir); - } -- String s1 = lib.substring(0, k); -- String s2 = lib.substring(k + 7); -- String libDir; -- if ("64".equals(System.getProperty("sun.arch.data.model"))) { -- // assume Linux convention -- libDir = "lib64"; -- } else { -- // must be 32-bit -- libDir = "lib"; -+ -+ k = lib.indexOf("$ARCH"); -+ if (k != -1) { -+ String arch = System.getProperty("os.arch"); -+ lib = lib.replace("$ARCH", getDebianArchitecture(arch)); - } -- String s = s1 + libDir + s2; -- return s; -+ -+ return lib; -+ } -+ -+ private static String getDebianArchitecture(String jdkArch) { -+ return switch (jdkArch) { -+ case "amd64" -> "x86_64"; -+ case "ppc" -> "powerpc"; -+ case "ppc64" -> "powerpc64"; -+ case "ppc64le" -> "powerpc64le"; -+ default -> jdkArch; -+ }; - } - - private static String getLibraryName() throws IOException { -@@ -98,15 +119,18 @@ private static String getLibraryName() throws IOException { - if (lib.length() != 0) { - return lib; - } -- lib = expand(LIB1); -- if (new File(lib).isFile()) { -- // if LIB1 exists, use that -- return lib; -- } -- lib = expand(LIB2); -- if (new File(lib).isFile()) { -- // if LIB2 exists, use that -- return lib; -+ -+ for (String template : LIB_TEMPLATES) { -+ for (String suffix : LIB_SUFFIXES) { -+ lib = expand(template) + suffix; -+ if (debug != null) { -+ debug.println("Looking for " + lib); -+ } -+ if (new File(lib).isFile()) { -+ // if library exists, use that -+ return lib; -+ } -+ } - } - - // As of macos 11, framework libraries have been removed from the file diff --git a/jdk8311630-s390_ffmapi.patch b/jdk8311630-s390_ffmapi.patch deleted file mode 100644 index cd3bc08..0000000 --- a/jdk8311630-s390_ffmapi.patch +++ /dev/null @@ -1,1906 +0,0 @@ -commit 27f635fabe7c2933674ad40443906fc35eecf785 -Author: Sidraya Jayagond -Date: Tue Sep 12 09:07:09 2023 +0000 - - 8311630: [s390] Implementation of Foreign Function & Memory API (Preview) - - Backport-of: ec1f7a8480db025a6f405817a106af8e92b69c44 - -diff --git a/src/hotspot/cpu/s390/downcallLinker_s390.cpp b/src/hotspot/cpu/s390/downcallLinker_s390.cpp -index baee7d7a043..f831da90755 100644 ---- a/src/hotspot/cpu/s390/downcallLinker_s390.cpp -+++ b/src/hotspot/cpu/s390/downcallLinker_s390.cpp -@@ -23,8 +23,76 @@ - */ - - #include "precompiled.hpp" -+#include "asm/macroAssembler.inline.hpp" -+#include "code/codeBlob.hpp" -+#include "code/codeCache.hpp" -+#include "code/vmreg.inline.hpp" -+#include "compiler/oopMap.hpp" -+#include "logging/logStream.hpp" -+#include "memory/resourceArea.hpp" - #include "prims/downcallLinker.hpp" --#include "utilities/debug.hpp" -+#include "runtime/globals.hpp" -+#include "runtime/stubCodeGenerator.hpp" -+ -+#define __ _masm-> -+ -+class DowncallStubGenerator : public StubCodeGenerator { -+ BasicType* _signature; -+ int _num_args; -+ BasicType _ret_bt; -+ const ABIDescriptor& _abi; -+ -+ const GrowableArray& _input_registers; -+ const GrowableArray& _output_registers; -+ -+ bool _needs_return_buffer; -+ int _captured_state_mask; -+ bool _needs_transition; -+ -+ int _frame_complete; -+ int _frame_size_slots; -+ OopMapSet* _oop_maps; -+ public: -+ DowncallStubGenerator(CodeBuffer* buffer, -+ BasicType* signature, -+ int num_args, -+ BasicType ret_bt, -+ const ABIDescriptor& abi, -+ const GrowableArray& input_registers, -+ const GrowableArray& output_registers, -+ bool needs_return_buffer, -+ int captured_state_mask, -+ bool needs_transition) -+ :StubCodeGenerator(buffer, PrintMethodHandleStubs), -+ _signature(signature), -+ _num_args(num_args), -+ _ret_bt(ret_bt), -+ _abi(abi), -+ _input_registers(input_registers), -+ _output_registers(output_registers), -+ _needs_return_buffer(needs_return_buffer), -+ _captured_state_mask(captured_state_mask), -+ _needs_transition(needs_transition), -+ _frame_complete(0), -+ _frame_size_slots(0), -+ _oop_maps(nullptr) { -+ } -+ void generate(); -+ int frame_complete() const { -+ return _frame_complete; -+ } -+ -+ int framesize() const { -+ return (_frame_size_slots >> (LogBytesPerWord - LogBytesPerInt)); -+ } -+ -+ OopMapSet* oop_maps() const { -+ return _oop_maps; -+ } -+}; -+ -+static const int native_invoker_code_base_size = 512; -+static const int native_invoker_size_per_args = 8; - - RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, - int num_args, -@@ -35,6 +103,197 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, - bool needs_return_buffer, - int captured_state_mask, - bool needs_transition) { -- Unimplemented(); -- return nullptr; -+ -+ int code_size = native_invoker_code_base_size + (num_args * native_invoker_size_per_args); -+ int locs_size = 1; //must be non zero -+ CodeBuffer code("nep_invoker_blob", code_size, locs_size); -+ -+ DowncallStubGenerator g(&code, signature, num_args, ret_bt, abi, -+ input_registers, output_registers, -+ needs_return_buffer, captured_state_mask, -+ needs_transition); -+ g.generate(); -+ code.log_section_sizes("nep_invoker_blob"); -+ -+ RuntimeStub* stub = -+ RuntimeStub::new_runtime_stub("nep_invoker_blob", -+ &code, -+ g.frame_complete(), -+ g.framesize(), -+ g.oop_maps(), false); -+ -+#ifndef PRODUCT -+ LogTarget(Trace, foreign, downcall) lt; -+ if (lt.is_enabled()) { -+ ResourceMark rm; -+ LogStream ls(lt); -+ stub->print_on(&ls); -+ } -+#endif -+ -+ return stub; -+} -+ -+void DowncallStubGenerator::generate() { -+ Register call_target_address = Z_R1_scratch, -+ tmp = Z_R0_scratch; -+ -+ VMStorage shuffle_reg = _abi._scratch1; -+ -+ JavaCallingConvention in_conv; -+ NativeCallingConvention out_conv(_input_registers); -+ ArgumentShuffle arg_shuffle(_signature, _num_args, _signature, _num_args, &in_conv, &out_conv, shuffle_reg); -+ -+#ifndef PRODUCT -+ LogTarget(Trace, foreign, downcall) lt; -+ if (lt.is_enabled()) { -+ ResourceMark rm; -+ LogStream ls(lt); -+ arg_shuffle.print_on(&ls); -+ } -+#endif -+ -+ assert(_abi._shadow_space_bytes == frame::z_abi_160_size, "expected space according to ABI"); -+ int allocated_frame_size = _abi._shadow_space_bytes; -+ allocated_frame_size += arg_shuffle.out_arg_bytes(); -+ -+ assert(!_needs_return_buffer, "unexpected needs_return_buffer"); -+ RegSpiller out_reg_spiller(_output_registers); -+ int spill_offset = allocated_frame_size; -+ allocated_frame_size += BytesPerWord; -+ -+ StubLocations locs; -+ locs.set(StubLocations::TARGET_ADDRESS, _abi._scratch2); -+ -+ if (_captured_state_mask != 0) { -+ __ block_comment("{ _captured_state_mask is set"); -+ locs.set_frame_data(StubLocations::CAPTURED_STATE_BUFFER, allocated_frame_size); -+ allocated_frame_size += BytesPerWord; -+ __ block_comment("} _captured_state_mask is set"); -+ } -+ -+ allocated_frame_size = align_up(allocated_frame_size, StackAlignmentInBytes); -+ _frame_size_slots = allocated_frame_size >> LogBytesPerInt; -+ -+ _oop_maps = _needs_transition ? new OopMapSet() : nullptr; -+ address start = __ pc(); -+ -+ __ save_return_pc(); -+ __ push_frame(allocated_frame_size, Z_R11); // Create a new frame for the wrapper. -+ -+ _frame_complete = __ pc() - start; // frame build complete. -+ -+ if (_needs_transition) { -+ __ block_comment("{ thread java2native"); -+ __ get_PC(Z_R1_scratch); -+ address the_pc = __ pc(); -+ __ set_last_Java_frame(Z_SP, Z_R1_scratch); -+ -+ OopMap* map = new OopMap(_frame_size_slots, 0); -+ _oop_maps->add_gc_map(the_pc - start, map); -+ -+ // State transition -+ __ set_thread_state(_thread_in_native); -+ __ block_comment("} thread java2native"); -+ } -+ __ block_comment("{ argument shuffle"); -+ arg_shuffle.generate(_masm, shuffle_reg, frame::z_jit_out_preserve_size, _abi._shadow_space_bytes, locs); -+ __ block_comment("} argument shuffle"); -+ -+ __ call(as_Register(locs.get(StubLocations::TARGET_ADDRESS))); -+ -+ ////////////////////////////////////////////////////////////////////////////// -+ -+ if (_captured_state_mask != 0) { -+ __ block_comment("{ save thread local"); -+ -+ out_reg_spiller.generate_spill(_masm, spill_offset); -+ -+ __ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, DowncallLinker::capture_state)); -+ __ z_lg(Z_ARG1, Address(Z_SP, locs.data_offset(StubLocations::CAPTURED_STATE_BUFFER))); -+ __ load_const_optimized(Z_ARG2, _captured_state_mask); -+ __ call(call_target_address); -+ -+ out_reg_spiller.generate_fill(_masm, spill_offset); -+ -+ __ block_comment("} save thread local"); -+ } -+ -+ ////////////////////////////////////////////////////////////////////////////// -+ -+ Label L_after_safepoint_poll; -+ Label L_safepoint_poll_slow_path; -+ Label L_reguard; -+ Label L_after_reguard; -+ -+ if (_needs_transition) { -+ __ block_comment("{ thread native2java"); -+ __ set_thread_state(_thread_in_native_trans); -+ -+ if (!UseSystemMemoryBarrier) { -+ __ z_fence(); // Order state change wrt. safepoint poll. -+ } -+ -+ __ safepoint_poll(L_safepoint_poll_slow_path, tmp); -+ -+ __ load_and_test_int(tmp, Address(Z_thread, JavaThread::suspend_flags_offset())); -+ __ z_brne(L_safepoint_poll_slow_path); -+ -+ __ bind(L_after_safepoint_poll); -+ -+ // change thread state -+ __ set_thread_state(_thread_in_Java); -+ -+ __ block_comment("reguard stack check"); -+ __ z_cli(Address(Z_thread, JavaThread::stack_guard_state_offset() + in_ByteSize(sizeof(StackOverflow::StackGuardState) - 1)), -+ StackOverflow::stack_guard_yellow_reserved_disabled); -+ __ z_bre(L_reguard); -+ __ bind(L_after_reguard); -+ -+ __ reset_last_Java_frame(); -+ __ block_comment("} thread native2java"); -+ } -+ -+ __ pop_frame(); -+ __ restore_return_pc(); // This is the way back to the caller. -+ __ z_br(Z_R14); -+ -+ ////////////////////////////////////////////////////////////////////////////// -+ -+ if (_needs_transition) { -+ __ block_comment("{ L_safepoint_poll_slow_path"); -+ __ bind(L_safepoint_poll_slow_path); -+ -+ // Need to save the native result registers around any runtime calls. -+ out_reg_spiller.generate_spill(_masm, spill_offset); -+ -+ __ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, JavaThread::check_special_condition_for_native_trans)); -+ __ z_lgr(Z_ARG1, Z_thread); -+ __ call(call_target_address); -+ -+ out_reg_spiller.generate_fill(_masm, spill_offset); -+ -+ __ z_bru(L_after_safepoint_poll); -+ __ block_comment("} L_safepoint_poll_slow_path"); -+ -+ ////////////////////////////////////////////////////////////////////////////// -+ __ block_comment("{ L_reguard"); -+ __ bind(L_reguard); -+ -+ // Need to save the native result registers around any runtime calls. -+ out_reg_spiller.generate_spill(_masm, spill_offset); -+ -+ __ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, SharedRuntime::reguard_yellow_pages)); -+ __ call(call_target_address); -+ -+ out_reg_spiller.generate_fill(_masm, spill_offset); -+ -+ __ z_bru(L_after_reguard); -+ -+ __ block_comment("} L_reguard"); -+ } -+ -+ ////////////////////////////////////////////////////////////////////////////// -+ -+ __ flush(); - } -diff --git a/src/hotspot/cpu/s390/foreignGlobals_s390.cpp b/src/hotspot/cpu/s390/foreignGlobals_s390.cpp -index d3a318536bd..9796ab4ffe4 100644 ---- a/src/hotspot/cpu/s390/foreignGlobals_s390.cpp -+++ b/src/hotspot/cpu/s390/foreignGlobals_s390.cpp -@@ -23,34 +23,209 @@ - */ - - #include "precompiled.hpp" --#include "code/vmreg.hpp" -+#include "asm/macroAssembler.inline.hpp" -+#include "code/vmreg.inline.hpp" -+#include "runtime/jniHandles.hpp" -+#include "runtime/jniHandles.inline.hpp" -+#include "oops/typeArrayOop.inline.hpp" -+#include "oops/oopCast.inline.hpp" - #include "prims/foreignGlobals.hpp" --#include "utilities/debug.hpp" -+#include "prims/foreignGlobals.inline.hpp" -+#include "prims/vmstorage.hpp" -+#include "utilities/formatBuffer.hpp" - --class MacroAssembler; -+#define __ masm-> -+ -+bool ABIDescriptor::is_volatile_reg(Register reg) const { -+ return _integer_volatile_registers.contains(reg); -+} -+ -+bool ABIDescriptor::is_volatile_reg(FloatRegister reg) const { -+ return _float_argument_registers.contains(reg) -+ || _float_additional_volatile_registers.contains(reg); -+} - - bool ForeignGlobals::is_foreign_linker_supported() { -- return false; -+ return true; - } - - const ABIDescriptor ForeignGlobals::parse_abi_descriptor(jobject jabi) { -- Unimplemented(); -- return {}; -+ oop abi_oop = JNIHandles::resolve_non_null(jabi); -+ ABIDescriptor abi; -+ -+ objArrayOop inputStorage = jdk_internal_foreign_abi_ABIDescriptor::inputStorage(abi_oop); -+ parse_register_array(inputStorage, StorageType::INTEGER, abi._integer_argument_registers, as_Register); -+ parse_register_array(inputStorage, StorageType::FLOAT, abi._float_argument_registers, as_FloatRegister); -+ -+ objArrayOop outputStorage = jdk_internal_foreign_abi_ABIDescriptor::outputStorage(abi_oop); -+ parse_register_array(outputStorage, StorageType::INTEGER, abi._integer_return_registers, as_Register); -+ parse_register_array(outputStorage, StorageType::FLOAT, abi._float_return_registers, as_FloatRegister); -+ -+ objArrayOop volatileStorage = jdk_internal_foreign_abi_ABIDescriptor::volatileStorage(abi_oop); -+ parse_register_array(volatileStorage, StorageType::INTEGER, abi._integer_volatile_registers, as_Register); -+ parse_register_array(volatileStorage, StorageType::FLOAT, abi._float_additional_volatile_registers, as_FloatRegister); -+ -+ abi._stack_alignment_bytes = jdk_internal_foreign_abi_ABIDescriptor::stackAlignment(abi_oop); -+ abi._shadow_space_bytes = jdk_internal_foreign_abi_ABIDescriptor::shadowSpace(abi_oop); -+ -+ abi._scratch1 = parse_vmstorage(jdk_internal_foreign_abi_ABIDescriptor::scratch1(abi_oop)); -+ abi._scratch2 = parse_vmstorage(jdk_internal_foreign_abi_ABIDescriptor::scratch2(abi_oop)); -+ -+ return abi; - } - - int RegSpiller::pd_reg_size(VMStorage reg) { -- Unimplemented(); -- return -1; -+ if (reg.type() == StorageType::INTEGER || reg.type() == StorageType::FLOAT) { -+ return 8; -+ } -+ return 0; // stack and BAD - } - - void RegSpiller::pd_store_reg(MacroAssembler* masm, int offset, VMStorage reg) { -- Unimplemented(); -+ if (reg.type() == StorageType::INTEGER) { -+ __ reg2mem_opt(as_Register(reg), Address(Z_SP, offset), true); -+ } else if (reg.type() == StorageType::FLOAT) { -+ __ freg2mem_opt(as_FloatRegister(reg), Address(Z_SP, offset), true); -+ } else { -+ // stack and BAD -+ } - } - - void RegSpiller::pd_load_reg(MacroAssembler* masm, int offset, VMStorage reg) { -- Unimplemented(); -+ if (reg.type() == StorageType::INTEGER) { -+ __ mem2reg_opt(as_Register(reg), Address(Z_SP, offset), true); -+ } else if (reg.type() == StorageType::FLOAT) { -+ __ mem2freg_opt(as_FloatRegister(reg), Address(Z_SP, offset), true); -+ } else { -+ // stack and BAD -+ } -+} -+ -+static int reg2offset(VMStorage vms, int stk_bias) { -+ assert(!vms.is_reg(), "wrong usage"); -+ return vms.index_or_offset() + stk_bias; -+} -+ -+static void move_reg(MacroAssembler* masm, int out_stk_bias, -+ VMStorage from_reg, VMStorage to_reg) { -+ int out_bias = 0; -+ switch (to_reg.type()) { -+ case StorageType::INTEGER: -+ if (to_reg.segment_mask() == REG64_MASK && from_reg.segment_mask() == REG32_MASK ) { -+ // see CCallingConventionRequiresIntsAsLongs -+ __ z_lgfr(as_Register(to_reg), as_Register(from_reg)); -+ } else { -+ __ lgr_if_needed(as_Register(to_reg), as_Register(from_reg)); -+ } -+ break; -+ case StorageType::STACK: -+ out_bias = out_stk_bias; //fallthrough -+ case StorageType::FRAME_DATA: { -+ // Integer types always get a 64 bit slot in C. -+ if (from_reg.segment_mask() == REG32_MASK) { -+ // see CCallingConventionRequiresIntsAsLongs -+ __ z_lgfr(as_Register(from_reg), as_Register(from_reg)); -+ } -+ switch (to_reg.stack_size()) { -+ case 8: __ reg2mem_opt(as_Register(from_reg), Address(Z_SP, reg2offset(to_reg, out_bias)), true); break; -+ case 4: __ reg2mem_opt(as_Register(from_reg), Address(Z_SP, reg2offset(to_reg, out_bias)), false); break; -+ default: ShouldNotReachHere(); -+ } -+ } break; -+ default: ShouldNotReachHere(); -+ } -+} -+ -+static void move_float(MacroAssembler* masm, int out_stk_bias, -+ VMStorage from_reg, VMStorage to_reg) { -+ switch (to_reg.type()) { -+ case StorageType::FLOAT: -+ if (from_reg.segment_mask() == REG64_MASK) -+ __ move_freg_if_needed(as_FloatRegister(to_reg), T_DOUBLE, as_FloatRegister(from_reg), T_DOUBLE); -+ else -+ __ move_freg_if_needed(as_FloatRegister(to_reg), T_FLOAT, as_FloatRegister(from_reg), T_FLOAT); -+ break; -+ case StorageType::STACK: -+ if (from_reg.segment_mask() == REG64_MASK) { -+ assert(to_reg.stack_size() == 8, "size should match"); -+ __ freg2mem_opt(as_FloatRegister(from_reg), Address(Z_SP, reg2offset(to_reg, out_stk_bias)), true); -+ } else { -+ assert(to_reg.stack_size() == 4, "size should match"); -+ __ freg2mem_opt(as_FloatRegister(from_reg), Address(Z_SP, reg2offset(to_reg, out_stk_bias)), false); -+ } -+ break; -+ default: ShouldNotReachHere(); -+ } -+} -+ -+static void move_stack(MacroAssembler* masm, Register tmp_reg, int in_stk_bias, int out_stk_bias, -+ VMStorage from_reg, VMStorage to_reg) { -+ int out_bias = 0; -+ Address from_addr(Z_R11, reg2offset(from_reg, in_stk_bias)); -+ switch (to_reg.type()) { -+ case StorageType::INTEGER: -+ switch (from_reg.stack_size()) { -+ case 8: __ mem2reg_opt(as_Register(to_reg), from_addr, true);break; -+ case 4: __ mem2reg_opt(as_Register(to_reg), from_addr, false);break; -+ default: ShouldNotReachHere(); -+ } -+ break; -+ case StorageType::FLOAT: -+ switch (from_reg.stack_size()) { -+ case 8: __ mem2freg_opt(as_FloatRegister(to_reg), from_addr, true);break; -+ case 4: __ mem2freg_opt(as_FloatRegister(to_reg), from_addr, false);break; -+ default: ShouldNotReachHere(); -+ } -+ break; -+ case StorageType::STACK: -+ out_bias = out_stk_bias; // fallthrough -+ case StorageType::FRAME_DATA: { -+ switch (from_reg.stack_size()) { -+ case 8: __ mem2reg_opt(tmp_reg, from_addr, true); break; -+ case 4: if (to_reg.stack_size() == 8) { -+ __ mem2reg_signed_opt(tmp_reg, from_addr); -+ } else { -+ __ mem2reg_opt(tmp_reg, from_addr, false); -+ } -+ break; -+ default: ShouldNotReachHere(); -+ } -+ switch (to_reg.stack_size()) { -+ case 8: __ reg2mem_opt(tmp_reg, Address (Z_SP, reg2offset(to_reg, out_bias)), true); break; -+ case 4: __ reg2mem_opt(tmp_reg, Address (Z_SP, reg2offset(to_reg, out_bias)), false); break; -+ default: ShouldNotReachHere(); -+ } -+ } break; -+ default: ShouldNotReachHere(); -+ } - } - - void ArgumentShuffle::pd_generate(MacroAssembler* masm, VMStorage tmp, int in_stk_bias, int out_stk_bias, const StubLocations& locs) const { -- Unimplemented(); -+ Register tmp_reg = as_Register(tmp); -+ for (int i = 0; i < _moves.length(); i++) { -+ Move move = _moves.at(i); -+ VMStorage from_reg = move.from; -+ VMStorage to_reg = move.to; -+ -+ // replace any placeholders -+ if (from_reg.type() == StorageType::PLACEHOLDER) { -+ from_reg = locs.get(from_reg); -+ } -+ if (to_reg.type() == StorageType::PLACEHOLDER) { -+ to_reg = locs.get(to_reg); -+ } -+ -+ switch (from_reg.type()) { -+ case StorageType::INTEGER: -+ move_reg(masm, out_stk_bias, from_reg, to_reg); -+ break; -+ case StorageType::FLOAT: -+ move_float(masm, out_stk_bias, from_reg, to_reg); -+ break; -+ case StorageType::STACK: -+ move_stack(masm, tmp_reg, in_stk_bias, out_stk_bias, from_reg, to_reg); -+ break; -+ default: ShouldNotReachHere(); -+ } -+ } - } -diff --git a/src/hotspot/cpu/s390/foreignGlobals_s390.hpp b/src/hotspot/cpu/s390/foreignGlobals_s390.hpp -index 8b86a2b06a6..4ff3b3e40b4 100644 ---- a/src/hotspot/cpu/s390/foreignGlobals_s390.hpp -+++ b/src/hotspot/cpu/s390/foreignGlobals_s390.hpp -@@ -24,6 +24,23 @@ - #ifndef CPU_S390_VM_FOREIGN_GLOBALS_S390_HPP - #define CPU_S390_VM_FOREIGN_GLOBALS_S390_HPP - --class ABIDescriptor {}; -+struct ABIDescriptor { -+ GrowableArray _integer_argument_registers; -+ GrowableArray _integer_return_registers; -+ GrowableArray _float_argument_registers; -+ GrowableArray _float_return_registers; -+ -+ GrowableArray _integer_volatile_registers; -+ GrowableArray _float_additional_volatile_registers; -+ -+ int32_t _stack_alignment_bytes; -+ int32_t _shadow_space_bytes; -+ -+ VMStorage _scratch1; -+ VMStorage _scratch2; -+ -+ bool is_volatile_reg(Register reg) const; -+ bool is_volatile_reg(FloatRegister reg) const; -+}; - - #endif // CPU_S390_VM_FOREIGN_GLOBALS_S390_HPP -diff --git a/src/hotspot/cpu/s390/frame_s390.cpp b/src/hotspot/cpu/s390/frame_s390.cpp -index 23547fa6617..ac24e43f00c 100644 ---- a/src/hotspot/cpu/s390/frame_s390.cpp -+++ b/src/hotspot/cpu/s390/frame_s390.cpp -@@ -218,13 +218,32 @@ frame frame::sender_for_entry_frame(RegisterMap *map) const { - } - - UpcallStub::FrameData* UpcallStub::frame_data_for_frame(const frame& frame) const { -- ShouldNotCallThis(); -- return nullptr; -+ assert(frame.is_upcall_stub_frame(), "wrong frame"); -+ // need unextended_sp here, since normal sp is wrong for interpreter callees -+ return reinterpret_cast( -+ reinterpret_cast
(frame.unextended_sp()) + in_bytes(_frame_data_offset)); - } - - bool frame::upcall_stub_frame_is_first() const { -- ShouldNotCallThis(); -- return false; -+ assert(is_upcall_stub_frame(), "must be optimized entry frame"); -+ UpcallStub* blob = _cb->as_upcall_stub(); -+ JavaFrameAnchor* jfa = blob->jfa_for_frame(*this); -+ return jfa->last_Java_sp() == nullptr; -+} -+ -+frame frame::sender_for_upcall_stub_frame(RegisterMap* map) const { -+ assert(map != nullptr, "map must be set"); -+ UpcallStub* blob = _cb->as_upcall_stub(); -+ // Java frame called from C; skip all C frames and return top C -+ // frame of that chunk as the sender -+ JavaFrameAnchor* jfa = blob->jfa_for_frame(*this); -+ assert(!upcall_stub_frame_is_first(), "must have a frame anchor to go back to"); -+ assert(jfa->last_Java_sp() > sp(), "must be above this frame on stack"); -+ map->clear(); -+ assert(map->include_argument_oops(), "should be set by clear"); -+ frame fr(jfa->last_Java_sp(), jfa->last_Java_pc()); -+ -+ return fr; - } - - frame frame::sender_for_interpreter_frame(RegisterMap *map) const { -diff --git a/src/hotspot/cpu/s390/frame_s390.inline.hpp b/src/hotspot/cpu/s390/frame_s390.inline.hpp -index dfa68940bac..c188618653d 100644 ---- a/src/hotspot/cpu/s390/frame_s390.inline.hpp -+++ b/src/hotspot/cpu/s390/frame_s390.inline.hpp -@@ -352,12 +352,10 @@ inline frame frame::sender(RegisterMap* map) const { - // update it accordingly. - map->set_include_argument_oops(false); - -- if (is_entry_frame()) { -- return sender_for_entry_frame(map); -- } -- if (is_interpreted_frame()) { -- return sender_for_interpreter_frame(map); -- } -+ if (is_entry_frame()) return sender_for_entry_frame(map); -+ if (is_upcall_stub_frame()) return sender_for_upcall_stub_frame(map); -+ if (is_interpreted_frame()) return sender_for_interpreter_frame(map); -+ - assert(_cb == CodeCache::find_blob(pc()),"Must be the same"); - if (_cb != nullptr) return sender_for_compiled_frame(map); - -diff --git a/src/hotspot/cpu/s390/globalDefinitions_s390.hpp b/src/hotspot/cpu/s390/globalDefinitions_s390.hpp -index 99906bb369e..2232215a587 100644 ---- a/src/hotspot/cpu/s390/globalDefinitions_s390.hpp -+++ b/src/hotspot/cpu/s390/globalDefinitions_s390.hpp -@@ -28,7 +28,7 @@ - - #define ShortenBranches true - --const int StackAlignmentInBytes = 16; -+const int StackAlignmentInBytes = 8; - - #define SUPPORTS_NATIVE_CX8 - -diff --git a/src/hotspot/cpu/s390/methodHandles_s390.cpp b/src/hotspot/cpu/s390/methodHandles_s390.cpp -index 6392ba45a6c..ef8722f2499 100644 ---- a/src/hotspot/cpu/s390/methodHandles_s390.cpp -+++ b/src/hotspot/cpu/s390/methodHandles_s390.cpp -@@ -349,7 +349,16 @@ address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* - - void MethodHandles::jump_to_native_invoker(MacroAssembler* _masm, Register nep_reg, Register temp_target) { - BLOCK_COMMENT("jump_to_native_invoker {"); -- __ should_not_reach_here(); -+ assert(nep_reg != noreg, "required register"); -+ -+ // Load the invoker, as NEP -> .invoker -+ __ verify_oop(nep_reg); -+ -+ __ z_lg(temp_target, Address(nep_reg, -+ NONZERO(jdk_internal_foreign_abi_NativeEntryPoint::downcall_stub_address_offset_in_bytes()))); -+ -+ __ z_br(temp_target); -+ - BLOCK_COMMENT("} jump_to_native_invoker"); - } - -diff --git a/src/hotspot/cpu/s390/upcallLinker_s390.cpp b/src/hotspot/cpu/s390/upcallLinker_s390.cpp -index 3e1fb04218b..b748ec547cc 100644 ---- a/src/hotspot/cpu/s390/upcallLinker_s390.cpp -+++ b/src/hotspot/cpu/s390/upcallLinker_s390.cpp -@@ -22,15 +22,287 @@ - */ - - #include "precompiled.hpp" -+#include "asm/macroAssembler.inline.hpp" -+#include "logging/logStream.hpp" -+#include "memory/resourceArea.hpp" - #include "prims/upcallLinker.hpp" --#include "utilities/debug.hpp" -+#include "runtime/sharedRuntime.hpp" -+#include "runtime/signature.hpp" -+#include "runtime/stubRoutines.hpp" -+#include "utilities/formatBuffer.hpp" -+#include "utilities/globalDefinitions.hpp" - -+#define __ _masm-> -+ -+// for callee saved regs, according to the caller's ABI -+static int compute_reg_save_area_size(const ABIDescriptor& abi) { -+ int size = 0; -+ for (int i = 0; i < Register::number_of_registers; i++) { -+ Register reg = as_Register(i); -+ // Z_SP saved/restored by prologue/epilogue -+ if (reg == Z_SP) continue; -+ if (!abi.is_volatile_reg(reg)) { -+ size += 8; // bytes -+ } -+ } -+ -+ for (int i = 0; i < FloatRegister::number_of_registers; i++) { -+ FloatRegister reg = as_FloatRegister(i); -+ if (!abi.is_volatile_reg(reg)) { -+ size += 8; // bytes -+ } -+ } -+ -+ return size; -+} -+ -+static void preserve_callee_saved_registers(MacroAssembler* _masm, const ABIDescriptor& abi, int reg_save_area_offset) { -+ // 1. iterate all registers in the architecture -+ // - check if they are volatile or not for the given abi -+ // - if NOT, we need to save it here -+ -+ int offset = reg_save_area_offset; -+ -+ __ block_comment("{ preserve_callee_saved_regs "); -+ for (int i = 0; i < Register::number_of_registers; i++) { -+ Register reg = as_Register(i); -+ // Z_SP saved/restored by prologue/epilogue -+ if (reg == Z_SP) continue; -+ if (!abi.is_volatile_reg(reg)) { -+ __ z_stg(reg, Address(Z_SP, offset)); -+ offset += 8; -+ } -+ } -+ -+ for (int i = 0; i < FloatRegister::number_of_registers; i++) { -+ FloatRegister reg = as_FloatRegister(i); -+ if (!abi.is_volatile_reg(reg)) { -+ __ z_std(reg, Address(Z_SP, offset)); -+ offset += 8; -+ } -+ } -+ -+ __ block_comment("} preserve_callee_saved_regs "); -+} -+ -+static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescriptor& abi, int reg_save_area_offset) { -+ // 1. iterate all registers in the architecture -+ // - check if they are volatile or not for the given abi -+ // - if NOT, we need to restore it here -+ -+ int offset = reg_save_area_offset; -+ -+ __ block_comment("{ restore_callee_saved_regs "); -+ for (int i = 0; i < Register::number_of_registers; i++) { -+ Register reg = as_Register(i); -+ // Z_SP saved/restored by prologue/epilogue -+ if (reg == Z_SP) continue; -+ if (!abi.is_volatile_reg(reg)) { -+ __ z_lg(reg, Address(Z_SP, offset)); -+ offset += 8; -+ } -+ } -+ -+ for (int i = 0; i < FloatRegister::number_of_registers; i++) { -+ FloatRegister reg = as_FloatRegister(i); -+ if (!abi.is_volatile_reg(reg)) { -+ __ z_ld(reg, Address(Z_SP, offset)); -+ offset += 8; -+ } -+ } -+ -+ __ block_comment("} restore_callee_saved_regs "); -+} -+ -+static const int upcall_stub_code_base_size = 1024; // depends on GC (resolve_jobject) -+static const int upcall_stub_size_per_arg = 16; // arg save & restore + move - address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, - BasicType* in_sig_bt, int total_in_args, - BasicType* out_sig_bt, int total_out_args, - BasicType ret_type, - jobject jabi, jobject jconv, - bool needs_return_buffer, int ret_buf_size) { -- ShouldNotCallThis(); -- return nullptr; -+ ResourceMark rm; -+ const ABIDescriptor abi = ForeignGlobals::parse_abi_descriptor(jabi); -+ const CallRegs call_regs = ForeignGlobals::parse_call_regs(jconv); -+ int code_size = upcall_stub_code_base_size + (total_in_args * upcall_stub_size_per_arg); -+ CodeBuffer buffer("upcall_stub", code_size, /* locs_size = */ 0); -+ -+ Register call_target_address = Z_R1_scratch; -+ -+ VMStorage shuffle_reg = abi._scratch1; -+ JavaCallingConvention out_conv; -+ NativeCallingConvention in_conv(call_regs._arg_regs); -+ ArgumentShuffle arg_shuffle(in_sig_bt, total_in_args, out_sig_bt, total_out_args, &in_conv, &out_conv, shuffle_reg); -+ -+ // The Java call uses the JIT ABI, but we also call C. -+ int out_arg_area = MAX2(frame::z_jit_out_preserve_size + arg_shuffle.out_arg_bytes(), (int)frame::z_abi_160_size); -+ -+#ifndef PRODUCT -+ LogTarget(Trace, foreign, upcall) lt; -+ if (lt.is_enabled()) { -+ ResourceMark rm; -+ LogStream ls(lt); -+ arg_shuffle.print_on(&ls); -+ } -+#endif -+ -+ -+ int reg_save_area_size = compute_reg_save_area_size(abi); -+ RegSpiller arg_spiller(call_regs._arg_regs); -+ RegSpiller result_spiller(call_regs._ret_regs); -+ -+ int res_save_area_offset = out_arg_area; -+ int arg_save_area_offset = res_save_area_offset + result_spiller.spill_size_bytes(); -+ int reg_save_area_offset = arg_save_area_offset + arg_spiller.spill_size_bytes(); -+ int frame_data_offset = reg_save_area_offset + reg_save_area_size; -+ int frame_bottom_offset = frame_data_offset + sizeof(UpcallStub::FrameData); -+ -+ int frame_size = align_up(frame_bottom_offset, StackAlignmentInBytes); -+ StubLocations locs; -+ -+ // The space we have allocated will look like: -+ // -+ // -+ // FP-> | | -+ // |---------------------| = frame_bottom_offset = frame_size -+ // | | -+ // | FrameData | -+ // |---------------------| = frame_data_offset -+ // | | -+ // | reg_save_area | -+ // |---------------------| = reg_save_are_offset -+ // | | -+ // | arg_save_area | -+ // |---------------------| = arg_save_are_offset -+ // | | -+ // | res_save_area | -+ // |---------------------| = res_save_are_offset -+ // | | -+ // SP-> | out_arg_area | needs to be at end for shadow space -+ // -+ // -+ -+ ////////////////////////////////////////////////////////////////////////////// -+ -+ MacroAssembler* _masm = new MacroAssembler(&buffer); -+ address start = __ pc(); -+ -+ __ save_return_pc(); -+ assert((abi._stack_alignment_bytes % StackAlignmentInBytes) == 0, "must be 8 byte aligned"); -+ // allocate frame (frame_size is also aligned, so stack is still aligned) -+ __ push_frame(frame_size); -+ -+ // we have to always spill args since we need to do a call to get the thread -+ // (and maybe attach it). -+ arg_spiller.generate_spill(_masm, arg_save_area_offset); -+ // Java methods won't preserve them, so save them here: -+ preserve_callee_saved_registers(_masm, abi, reg_save_area_offset); -+ -+ __ block_comment("{ on_entry"); -+ __ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::on_entry)); -+ __ z_aghik(Z_ARG1, Z_SP, frame_data_offset); -+ __ call(call_target_address); -+ __ z_lgr(Z_thread, Z_RET); -+ __ block_comment("} on_entry"); -+ -+ arg_spiller.generate_fill(_masm, arg_save_area_offset); -+ __ block_comment("{ argument shuffle"); -+ arg_shuffle.generate(_masm, shuffle_reg, abi._shadow_space_bytes, frame::z_jit_out_preserve_size, locs); -+ __ block_comment("} argument shuffle"); -+ -+ __ block_comment("{ receiver "); -+ __ load_const_optimized(Z_ARG1, (intptr_t)receiver); -+ __ resolve_jobject(Z_ARG1, Z_tmp_1, Z_tmp_2); -+ __ block_comment("} receiver "); -+ -+ __ load_const_optimized(Z_method, (intptr_t)entry); -+ __ z_stg(Z_method, Address(Z_thread, in_bytes(JavaThread::callee_target_offset()))); -+ -+ __ z_lg(call_target_address, Address(Z_method, in_bytes(Method::from_compiled_offset()))); -+ __ call(call_target_address); -+ -+ // return value shuffle -+ assert(!needs_return_buffer, "unexpected needs_return_buffer"); -+ // CallArranger can pick a return type that goes in the same reg for both CCs. -+ if (call_regs._ret_regs.length() > 0) { // 0 or 1 -+ VMStorage ret_reg = call_regs._ret_regs.at(0); -+ // Check if the return reg is as expected. -+ switch (ret_type) { -+ case T_BOOLEAN: -+ case T_BYTE: -+ case T_SHORT: -+ case T_CHAR: -+ case T_INT: -+ __ z_lgfr(Z_RET, Z_RET); // Clear garbage in high half. -+ // fallthrough -+ case T_LONG: -+ assert(as_Register(ret_reg) == Z_RET, "unexpected result register"); -+ break; -+ case T_FLOAT: -+ case T_DOUBLE: -+ assert(as_FloatRegister(ret_reg) == Z_FRET, "unexpected result register"); -+ break; -+ default: -+ fatal("unexpected return type: %s", type2name(ret_type)); -+ } -+ } -+ -+ result_spiller.generate_spill(_masm, res_save_area_offset); -+ -+ __ block_comment("{ on_exit"); -+ __ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::on_exit)); -+ __ z_aghik(Z_ARG1, Z_SP, frame_data_offset); -+ __ call(call_target_address); -+ __ block_comment("} on_exit"); -+ -+ restore_callee_saved_registers(_masm, abi, reg_save_area_offset); -+ -+ result_spiller.generate_fill(_masm, res_save_area_offset); -+ -+ __ pop_frame(); -+ __ restore_return_pc(); -+ __ z_br(Z_R14); -+ -+ ////////////////////////////////////////////////////////////////////////////// -+ -+ __ block_comment("{ exception handler"); -+ -+ intptr_t exception_handler_offset = __ pc() - start; -+ -+ // Native caller has no idea how to handle exceptions, -+ // so we just crash here. Up to callee to catch exceptions. -+ __ verify_oop(Z_ARG1); -+ __ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::handle_uncaught_exception)); -+ __ call_c(call_target_address); -+ __ should_not_reach_here(); -+ -+ __ block_comment("} exception handler"); -+ -+ _masm->flush(); -+ -+#ifndef PRODUCT -+ stringStream ss; -+ ss.print("upcall_stub_%s", entry->signature()->as_C_string()); -+ const char* name = _masm->code_string(ss.as_string()); -+#else // PRODUCT -+ const char* name = "upcall_stub"; -+#endif // PRODUCT -+ -+ buffer.log_section_sizes(name); -+ UpcallStub* blob -+ = UpcallStub::create(name, -+ &buffer, -+ exception_handler_offset, -+ receiver, -+ in_ByteSize(frame_data_offset)); -+#ifndef PRODUCT -+ if (lt.is_enabled()) { -+ ResourceMark rm; -+ LogStream ls(lt); -+ blob->print_on(&ls); -+ } -+#endif -+ -+ return blob->code_begin(); - } -diff --git a/src/hotspot/cpu/s390/vmstorage_s390.hpp b/src/hotspot/cpu/s390/vmstorage_s390.hpp -index 192159adc4c..6a595670920 100644 ---- a/src/hotspot/cpu/s390/vmstorage_s390.hpp -+++ b/src/hotspot/cpu/s390/vmstorage_s390.hpp -@@ -29,24 +29,79 @@ - #include "asm/register.hpp" - - enum class StorageType : int8_t { -- STACK = 0, -- PLACEHOLDER = 1, --// special locations used only by native code -- FRAME_DATA = PLACEHOLDER + 1, -+ INTEGER = 0, -+ FLOAT = 1, -+ STACK = 2, -+ PLACEHOLDER = 3, -+ // special locations used only by native code -+ FRAME_DATA = 4, - INVALID = -1 - }; - - // need to define this before constructing VMStorage (below) - constexpr inline bool VMStorage::is_reg(StorageType type) { -- return false; -+ return type == StorageType::INTEGER || type == StorageType::FLOAT; - } - constexpr inline StorageType VMStorage::stack_type() { return StorageType::STACK; } - constexpr inline StorageType VMStorage::placeholder_type() { return StorageType::PLACEHOLDER; } - constexpr inline StorageType VMStorage::frame_data_type() { return StorageType::FRAME_DATA; } - -+// Needs to be consistent with S390Architecture.java. -+constexpr uint16_t REG32_MASK = 0b0000000000000001; -+constexpr uint16_t REG64_MASK = 0b0000000000000011; -+ -+inline Register as_Register(VMStorage vms) { -+ assert(vms.type() == StorageType::INTEGER, "not the right type"); -+ return ::as_Register(vms.index()); -+} -+ -+inline FloatRegister as_FloatRegister(VMStorage vms) { -+ assert(vms.type() == StorageType::FLOAT, "not the right type"); -+ return ::as_FloatRegister(vms.index()); -+} -+ -+inline VMStorage as_VMStorage(Register reg, uint16_t segment_mask = REG64_MASK) { -+ return VMStorage::reg_storage(StorageType::INTEGER, segment_mask, reg->encoding()); -+} -+ -+inline VMStorage as_VMStorage(FloatRegister reg, uint16_t segment_mask = REG64_MASK) { -+ return VMStorage::reg_storage(StorageType::FLOAT, segment_mask, reg->encoding()); -+} -+ - inline VMStorage as_VMStorage(VMReg reg, BasicType bt) { -+ if (reg->is_Register()) { -+ uint16_t segment_mask = 0; -+ switch (bt) { -+ case T_BOOLEAN: -+ case T_CHAR : -+ case T_BYTE : -+ case T_SHORT : -+ case T_INT : segment_mask = REG32_MASK; break; -+ default : segment_mask = REG64_MASK; break; -+ } -+ return as_VMStorage(reg->as_Register(), segment_mask); -+ } else if (reg->is_FloatRegister()) { -+ // FP regs always use double format. However, we need the correct format for loads /stores. -+ return as_VMStorage(reg->as_FloatRegister(), (bt == T_FLOAT) ? REG32_MASK : REG64_MASK); -+ } else if (reg->is_stack()) { -+ uint16_t size = 0; -+ switch (bt) { -+ case T_BOOLEAN: -+ case T_CHAR : -+ case T_BYTE : -+ case T_SHORT : -+ case T_INT : -+ case T_FLOAT : size = 4; break; -+ default : size = 8; break; -+ } -+ return VMStorage(StorageType::STACK, size, -+ checked_cast(reg->reg2stack() * VMRegImpl::stack_slot_size)); -+ } else if (!reg->is_valid()) { -+ return VMStorage::invalid(); -+ } -+ - ShouldNotReachHere(); - return VMStorage::invalid(); - } - --#endif // CPU_S390_VMSTORAGE_S390_INLINE_HPP -\ No newline at end of file -+#endif // CPU_S390_VMSTORAGE_S390_INLINE_HPP -diff --git a/src/java.base/share/classes/jdk/internal/foreign/CABI.java b/src/java.base/share/classes/jdk/internal/foreign/CABI.java -index eee4ae67457..d376a196333 100644 ---- a/src/java.base/share/classes/jdk/internal/foreign/CABI.java -+++ b/src/java.base/share/classes/jdk/internal/foreign/CABI.java -@@ -41,6 +41,7 @@ public enum CABI { - WIN_AARCH_64, - LINUX_PPC_64_LE, - LINUX_RISCV_64, -+ LINUX_S390, - FALLBACK, - UNSUPPORTED; - -@@ -81,7 +82,11 @@ public enum CABI { - if (OperatingSystem.isLinux()) { - return LINUX_RISCV_64; - } -- } -+ } else if (arch.equals("s390x")) { -+ if (OperatingSystem.isLinux()) { -+ return LINUX_S390; -+ } -+ } - } else if (FallbackLinker.isSupported()) { - return FALLBACK; // fallback linker - } -diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/AbstractLinker.java b/src/java.base/share/classes/jdk/internal/foreign/abi/AbstractLinker.java -index b5eb1029ff5..8a322cdcf7a 100644 ---- a/src/java.base/share/classes/jdk/internal/foreign/abi/AbstractLinker.java -+++ b/src/java.base/share/classes/jdk/internal/foreign/abi/AbstractLinker.java -@@ -32,6 +32,7 @@ import jdk.internal.foreign.abi.aarch64.windows.WindowsAArch64Linker; - import jdk.internal.foreign.abi.fallback.FallbackLinker; - import jdk.internal.foreign.abi.ppc64.linux.LinuxPPC64leLinker; - import jdk.internal.foreign.abi.riscv64.linux.LinuxRISCV64Linker; -+import jdk.internal.foreign.abi.s390.linux.LinuxS390Linker; - import jdk.internal.foreign.abi.x64.sysv.SysVx64Linker; - import jdk.internal.foreign.abi.x64.windows.Windowsx64Linker; - import jdk.internal.foreign.layout.AbstractLayout; -@@ -60,7 +61,8 @@ import java.util.Set; - public abstract sealed class AbstractLinker implements Linker permits LinuxAArch64Linker, MacOsAArch64Linker, - SysVx64Linker, WindowsAArch64Linker, - Windowsx64Linker, LinuxPPC64leLinker, -- LinuxRISCV64Linker, FallbackLinker { -+ LinuxRISCV64Linker, LinuxS390Linker, -+ FallbackLinker { - - public interface UpcallStubFactory { - MemorySegment makeStub(MethodHandle target, Arena arena); -diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/SharedUtils.java b/src/java.base/share/classes/jdk/internal/foreign/abi/SharedUtils.java -index 1e417245543..92d10a1dbdf 100644 ---- a/src/java.base/share/classes/jdk/internal/foreign/abi/SharedUtils.java -+++ b/src/java.base/share/classes/jdk/internal/foreign/abi/SharedUtils.java -@@ -35,6 +35,7 @@ import jdk.internal.foreign.abi.aarch64.windows.WindowsAArch64Linker; - import jdk.internal.foreign.abi.fallback.FallbackLinker; - import jdk.internal.foreign.abi.ppc64.linux.LinuxPPC64leLinker; - import jdk.internal.foreign.abi.riscv64.linux.LinuxRISCV64Linker; -+import jdk.internal.foreign.abi.s390.linux.LinuxS390Linker; - import jdk.internal.foreign.abi.x64.sysv.SysVx64Linker; - import jdk.internal.foreign.abi.x64.windows.Windowsx64Linker; - import jdk.internal.vm.annotation.ForceInline; -@@ -242,6 +243,7 @@ public final class SharedUtils { - case WIN_AARCH_64 -> WindowsAArch64Linker.getInstance(); - case LINUX_PPC_64_LE -> LinuxPPC64leLinker.getInstance(); - case LINUX_RISCV_64 -> LinuxRISCV64Linker.getInstance(); -+ case LINUX_S390 -> LinuxS390Linker.getInstance(); - case FALLBACK -> FallbackLinker.getInstance(); - case UNSUPPORTED -> throw new UnsupportedOperationException("Platform does not support native linker"); - }; -diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/s390/S390Architecture.java b/src/java.base/share/classes/jdk/internal/foreign/abi/s390/S390Architecture.java -new file mode 100644 -index 00000000000..bbafef2f3dc ---- /dev/null -+++ b/src/java.base/share/classes/jdk/internal/foreign/abi/s390/S390Architecture.java -@@ -0,0 +1,151 @@ -+/* -+ * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2023 IBM Corp. 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 -+ * 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.foreign.abi.s390; -+ -+import jdk.internal.foreign.abi.ABIDescriptor; -+import jdk.internal.foreign.abi.Architecture; -+import jdk.internal.foreign.abi.StubLocations; -+import jdk.internal.foreign.abi.VMStorage; -+ -+public final class S390Architecture implements Architecture { -+ public static final Architecture INSTANCE = new S390Architecture(); -+ -+ // Needs to be consistent with vmstorage_s390.hpp. -+ public static final short REG32_MASK = 0b0000_0000_0000_0001; -+ public static final short REG64_MASK = 0b0000_0000_0000_0011; -+ -+ private static final int INTEGER_REG_SIZE = 8; -+ private static final int FLOAT_REG_SIZE = 8; -+ private static final int STACK_SLOT_SIZE = 8; -+ -+ // Suppresses default constructor, ensuring non-instantiability. -+ private S390Architecture() { -+ } -+ -+ @Override -+ public boolean isStackType(int cls) { -+ return cls == StorageType.STACK; -+ } -+ -+ @Override -+ public int typeSize(int cls) { -+ switch (cls) { -+ case StorageType.INTEGER: -+ return INTEGER_REG_SIZE; -+ case StorageType.FLOAT: -+ return FLOAT_REG_SIZE; -+ // STACK is deliberately omitted -+ } -+ -+ throw new IllegalArgumentException("Invalid Storage Class: " + cls); -+ } -+ -+ public interface StorageType { -+ byte INTEGER = 0; -+ byte FLOAT = 1; -+ byte STACK = 2; -+ byte PLACEHOLDER = 3; -+ } -+ -+ public static class Regs { // break circular dependency -+ public static final VMStorage r0 = integerRegister(0); -+ public static final VMStorage r1 = integerRegister(1); -+ public static final VMStorage r2 = integerRegister(2); -+ public static final VMStorage r3 = integerRegister(3); -+ public static final VMStorage r4 = integerRegister(4); -+ public static final VMStorage r5 = integerRegister(5); -+ public static final VMStorage r6 = integerRegister(6); -+ public static final VMStorage r7 = integerRegister(7); -+ public static final VMStorage r8 = integerRegister(8); -+ public static final VMStorage r9 = integerRegister(9); -+ public static final VMStorage r10 = integerRegister(10); -+ public static final VMStorage r11 = integerRegister(11); -+ public static final VMStorage r12 = integerRegister(12); -+ public static final VMStorage r13 = integerRegister(13); -+ public static final VMStorage r14 = integerRegister(14); -+ public static final VMStorage r15 = integerRegister(15); -+ -+ public static final VMStorage f0 = floatRegister(0); -+ public static final VMStorage f1 = floatRegister(1); -+ public static final VMStorage f2 = floatRegister(2); -+ public static final VMStorage f3 = floatRegister(3); -+ public static final VMStorage f4 = floatRegister(4); -+ public static final VMStorage f5 = floatRegister(5); -+ public static final VMStorage f6 = floatRegister(6); -+ public static final VMStorage f7 = floatRegister(7); -+ public static final VMStorage f8 = floatRegister(8); -+ public static final VMStorage f9 = floatRegister(9); -+ public static final VMStorage f10 = floatRegister(10); -+ public static final VMStorage f11 = floatRegister(11); -+ public static final VMStorage f12 = floatRegister(12); -+ public static final VMStorage f13 = floatRegister(13); -+ public static final VMStorage f14 = floatRegister(14); -+ public static final VMStorage f15 = floatRegister(15); -+ } -+ -+ private static VMStorage integerRegister(int index) { -+ return new VMStorage(StorageType.INTEGER, REG64_MASK, index, "r" + index); -+ } -+ -+ private static VMStorage floatRegister(int index) { -+ return new VMStorage(StorageType.FLOAT, REG64_MASK, index, "f" + index); -+ } -+ -+ public static VMStorage stackStorage(short size, int byteOffset) { -+ return new VMStorage(StorageType.STACK, size, byteOffset); -+ } -+ -+ public static ABIDescriptor abiFor(VMStorage[] inputIntRegs, -+ VMStorage[] inputFloatRegs, -+ VMStorage[] outputIntRegs, -+ VMStorage[] outputFloatRegs, -+ VMStorage[] volatileIntRegs, -+ VMStorage[] volatileFloatRegs, -+ int stackAlignment, -+ int shadowSpace, -+ VMStorage scratch1, VMStorage scratch2) { -+ return new ABIDescriptor( -+ INSTANCE, -+ new VMStorage[][] { -+ inputIntRegs, -+ inputFloatRegs, -+ }, -+ new VMStorage[][] { -+ outputIntRegs, -+ outputFloatRegs, -+ }, -+ new VMStorage[][] { -+ volatileIntRegs, -+ volatileFloatRegs, -+ }, -+ stackAlignment, -+ shadowSpace, -+ scratch1, scratch2, -+ StubLocations.TARGET_ADDRESS.storage(StorageType.PLACEHOLDER), -+ StubLocations.RETURN_BUFFER.storage(StorageType.PLACEHOLDER), -+ StubLocations.CAPTURED_STATE_BUFFER.storage(StorageType.PLACEHOLDER)); -+ } -+} -diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/LinuxS390CallArranger.java b/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/LinuxS390CallArranger.java -new file mode 100644 -index 00000000000..84392e45089 ---- /dev/null -+++ b/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/LinuxS390CallArranger.java -@@ -0,0 +1,311 @@ -+/* -+ * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2023 IBM Corp. 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 -+ * 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.foreign.abi.s390.linux; -+ -+import java.lang.foreign.AddressLayout; -+import java.lang.foreign.FunctionDescriptor; -+import java.lang.foreign.GroupLayout; -+import java.lang.foreign.MemoryLayout; -+import java.lang.foreign.MemorySegment; -+import jdk.internal.foreign.abi.ABIDescriptor; -+import jdk.internal.foreign.abi.AbstractLinker.UpcallStubFactory; -+import jdk.internal.foreign.abi.Binding; -+import jdk.internal.foreign.abi.CallingSequence; -+import jdk.internal.foreign.abi.CallingSequenceBuilder; -+import jdk.internal.foreign.abi.DowncallLinker; -+import jdk.internal.foreign.abi.LinkerOptions; -+import jdk.internal.foreign.abi.UpcallLinker; -+import jdk.internal.foreign.abi.SharedUtils; -+import jdk.internal.foreign.abi.VMStorage; -+import jdk.internal.foreign.Utils; -+ -+import java.lang.foreign.ValueLayout; -+import java.lang.invoke.MethodHandle; -+import java.lang.invoke.MethodType; -+import java.util.List; -+import java.util.Map; -+import java.util.Optional; -+ -+import static jdk.internal.foreign.abi.s390.linux.TypeClass.*; -+import static jdk.internal.foreign.abi.s390.S390Architecture.*; -+import static jdk.internal.foreign.abi.s390.S390Architecture.Regs.*; -+ -+/** -+ * For the S390 C ABI specifically, this class uses CallingSequenceBuilder -+ * to translate a C FunctionDescriptor into a CallingSequence, which can then be turned into a MethodHandle. -+ * -+ * This includes taking care of synthetic arguments like pointers to return buffers for 'in-memory' returns. -+ */ -+public class LinuxS390CallArranger { -+ -+ private static final int STACK_SLOT_SIZE = 8; -+ public static final int MAX_REGISTER_ARGUMENTS = 5; -+ public static final int MAX_FLOAT_REGISTER_ARGUMENTS = 4; -+ -+ private static final ABIDescriptor CLinux = abiFor( -+ new VMStorage[] { r2, r3, r4, r5, r6, }, // GP input -+ new VMStorage[] { f0, f2, f4, f6 }, // FP input -+ new VMStorage[] { r2, }, // GP output -+ new VMStorage[] { f0, }, // FP output -+ new VMStorage[] { r0, r1, r2, r3, r4, r5, r14 }, // volatile GP -+ new VMStorage[] { f1, f3, f5, f7 }, // volatile FP (excluding argument registers) -+ 8, // Stack is always 8 byte aligned on S390 -+ 160, // ABI header -+ r0, r1 // scratch reg r0 & r1 -+ ); -+ -+ public record Bindings(CallingSequence callingSequence, boolean isInMemoryReturn) {} -+ -+ public static Bindings getBindings(MethodType mt, FunctionDescriptor cDesc, boolean forUpcall) { -+ return getBindings(mt, cDesc, forUpcall, LinkerOptions.empty()); -+ } -+ -+ public static Bindings getBindings(MethodType mt, FunctionDescriptor cDesc, boolean forUpcall, LinkerOptions options) { -+ CallingSequenceBuilder csb = new CallingSequenceBuilder(CLinux, forUpcall, options); -+ -+ BindingCalculator argCalc = forUpcall ? new BoxBindingCalculator(true) : new UnboxBindingCalculator(true); -+ BindingCalculator retCalc = forUpcall ? new UnboxBindingCalculator(false) : new BoxBindingCalculator(false); -+ -+ boolean returnInMemory = isInMemoryReturn(cDesc.returnLayout()); -+ if (returnInMemory) { -+ Class carrier = MemorySegment.class; -+ MemoryLayout layout =SharedUtils.C_POINTER; -+ csb.addArgumentBindings(carrier, layout, argCalc.getBindings(carrier, layout)); -+ } else if (cDesc.returnLayout().isPresent()) { -+ Class carrier = mt.returnType(); -+ MemoryLayout layout = cDesc.returnLayout().get(); -+ csb.setReturnBindings(carrier, layout, retCalc.getBindings(carrier, layout)); -+ } -+ -+ for (int i = 0; i < mt.parameterCount(); i++) { -+ Class carrier = mt.parameterType(i); -+ MemoryLayout layout = cDesc.argumentLayouts().get(i); -+ csb.addArgumentBindings(carrier, layout, argCalc.getBindings(carrier, layout)); -+ } -+ -+ return new Bindings(csb.build(), returnInMemory); -+ } -+ -+ public static MethodHandle arrangeDowncall(MethodType mt, FunctionDescriptor cDesc, LinkerOptions options) { -+ Bindings bindings = getBindings(mt, cDesc, false, options); -+ -+ MethodHandle handle = new DowncallLinker(CLinux, bindings.callingSequence).getBoundMethodHandle(); -+ -+ if (bindings.isInMemoryReturn) { -+ handle = SharedUtils.adaptDowncallForIMR(handle, cDesc, bindings.callingSequence); -+ } -+ -+ return handle; -+ } -+ -+ public static UpcallStubFactory arrangeUpcall(MethodType mt, FunctionDescriptor cDesc, LinkerOptions options) { -+ Bindings bindings = getBindings(mt, cDesc, true, options); -+ -+ final boolean dropReturn = true; /* drop return, since we don't have bindings for it */ -+ return SharedUtils.arrangeUpcallHelper(mt, bindings.isInMemoryReturn, dropReturn, CLinux, -+ bindings.callingSequence); -+ } -+ -+ private static boolean isInMemoryReturn(Optional returnLayout) { -+ return returnLayout -+ .filter(layout -> layout instanceof GroupLayout) -+ .isPresent(); -+ } -+ -+ static class StorageCalculator { -+ private final boolean forArguments; -+ -+ private final int[] nRegs = new int[] { 0, 0 }; -+ private long stackOffset = 0; -+ -+ public StorageCalculator(boolean forArguments) { -+ this.forArguments = forArguments; -+ } -+ -+ VMStorage stackAlloc(long size, long alignment) { -+ long alignedStackOffset = Utils.alignUp(stackOffset, alignment); -+ -+ short encodedSize = (short) size; -+ assert (encodedSize & 0xFFFF) == size; -+ -+ VMStorage storage = stackStorage(encodedSize, (int) alignedStackOffset); -+ stackOffset = alignedStackOffset + size; -+ return storage; -+ } -+ -+ VMStorage regAlloc(int type) { -+ int gpRegCnt = (type == StorageType.INTEGER) ? 1 : 0; -+ int fpRegCnt = (type == StorageType.FLOAT) ? 1 : 0; -+ -+ // Use stack if not enough registers available. -+ if ((type == StorageType.FLOAT && (nRegs[StorageType.FLOAT] + fpRegCnt) > MAX_FLOAT_REGISTER_ARGUMENTS) -+ || (type == StorageType.INTEGER && (nRegs[StorageType.INTEGER] + gpRegCnt) > MAX_REGISTER_ARGUMENTS)) return null; -+ -+ VMStorage[] source = (forArguments ? CLinux.inputStorage : CLinux.outputStorage)[type]; -+ VMStorage result = source[nRegs[type]]; -+ -+ nRegs[StorageType.INTEGER] += gpRegCnt; -+ nRegs[StorageType.FLOAT] += fpRegCnt; -+ return result; -+ -+ } -+ VMStorage getStorage(int type, boolean is32Bit) { -+ VMStorage reg = regAlloc(type); -+ if (reg != null) { -+ if (is32Bit) { -+ reg = new VMStorage(reg.type(), REG32_MASK, reg.indexOrOffset()); -+ } -+ return reg; -+ } -+ VMStorage stack; -+ if (is32Bit) { -+ stackAlloc(4, STACK_SLOT_SIZE); // Skip first half of stack slot. -+ stack = stackAlloc(4, 4); -+ } else -+ stack = stackAlloc(8, STACK_SLOT_SIZE); -+ -+ return stack; -+ } -+ } -+ -+ abstract static class BindingCalculator { -+ protected final StorageCalculator storageCalculator; -+ -+ protected BindingCalculator(boolean forArguments) { -+ this.storageCalculator = new LinuxS390CallArranger.StorageCalculator(forArguments); -+ } -+ -+ abstract List getBindings(Class carrier, MemoryLayout layout); -+ } -+ -+ // Compute recipe for transferring arguments / return values to C from Java. -+ static class UnboxBindingCalculator extends BindingCalculator { -+ UnboxBindingCalculator(boolean forArguments) { -+ super(forArguments); -+ } -+ -+ @Override -+ List getBindings(Class carrier, MemoryLayout layout) { -+ TypeClass argumentClass = TypeClass.classifyLayout(layout); -+ Binding.Builder bindings = Binding.builder(); -+ switch (argumentClass) { -+ case STRUCT_REGISTER -> { -+ assert carrier == MemorySegment.class; -+ VMStorage storage = storageCalculator.getStorage(StorageType.INTEGER, false); -+ Class type = SharedUtils.primitiveCarrierForSize(layout.byteSize(), false); -+ bindings.bufferLoad(0, type) -+ .vmStore(storage, type); -+ } -+ case STRUCT_SFA -> { -+ assert carrier == MemorySegment.class; -+ VMStorage storage = storageCalculator.getStorage(StorageType.FLOAT, layout.byteSize() == 4); -+ Class type = SharedUtils.primitiveCarrierForSize(layout.byteSize(), true); -+ bindings.bufferLoad(0, type) -+ .vmStore(storage, type); -+ } -+ case STRUCT_REFERENCE -> { -+ assert carrier == MemorySegment.class; -+ bindings.copy(layout) -+ .unboxAddress(); -+ VMStorage storage = storageCalculator.getStorage(StorageType.INTEGER, false); -+ bindings.vmStore(storage, long.class); -+ } -+ case POINTER -> { -+ VMStorage storage = storageCalculator.getStorage(StorageType.INTEGER, false); -+ bindings.unboxAddress() -+ .vmStore(storage, long.class); -+ } -+ case INTEGER -> { -+ // ABI requires all int types to get extended to 64 bit. -+ VMStorage storage = storageCalculator.getStorage(StorageType.INTEGER, false); -+ bindings.vmStore(storage, carrier); -+ } -+ case FLOAT -> { -+ VMStorage storage = storageCalculator.getStorage(StorageType.FLOAT, carrier == float.class); -+ bindings.vmStore(storage, carrier); -+ } -+ default -> throw new UnsupportedOperationException("Unhandled class " + argumentClass); -+ } -+ return bindings.build(); -+ } -+ } -+ -+ // Compute recipe for transferring arguments / return values from C to Java. -+ static class BoxBindingCalculator extends BindingCalculator { -+ BoxBindingCalculator(boolean forArguments) { -+ super(forArguments); -+ } -+ -+ @Override -+ List getBindings(Class carrier, MemoryLayout layout) { -+ TypeClass argumentClass = TypeClass.classifyLayout(layout); -+ Binding.Builder bindings = Binding.builder(); -+ switch (argumentClass) { -+ case STRUCT_REGISTER -> { -+ assert carrier == MemorySegment.class; -+ bindings.allocate(layout) -+ .dup(); -+ VMStorage storage = storageCalculator.getStorage(StorageType.INTEGER, false); -+ Class type = SharedUtils.primitiveCarrierForSize(layout.byteSize(), false); -+ bindings.vmLoad(storage, type) -+ .bufferStore(0, type); -+ } -+ case STRUCT_SFA -> { -+ assert carrier == MemorySegment.class; -+ bindings.allocate(layout) -+ .dup(); -+ VMStorage storage = storageCalculator.getStorage(StorageType.FLOAT, layout.byteSize() == 4); -+ Class type = SharedUtils.primitiveCarrierForSize(layout.byteSize(), true); -+ bindings.vmLoad(storage, type) -+ .bufferStore(0, type); -+ } -+ case STRUCT_REFERENCE -> { -+ assert carrier == MemorySegment.class; -+ VMStorage storage = storageCalculator.getStorage(StorageType.INTEGER, false); -+ bindings.vmLoad(storage, long.class) -+ .boxAddress(layout); -+ } -+ case POINTER -> { -+ AddressLayout addressLayout = (AddressLayout) layout; -+ VMStorage storage = storageCalculator.getStorage(StorageType.INTEGER, false); -+ bindings.vmLoad(storage, long.class) -+ .boxAddressRaw(Utils.pointeeByteSize(addressLayout), Utils.pointeeByteAlign(addressLayout)); -+ } -+ case INTEGER -> { -+ // We could use carrier != long.class for BoxBindingCalculator, but C always uses 64 bit slots. -+ VMStorage storage = storageCalculator.getStorage(StorageType.INTEGER, false); -+ bindings.vmLoad(storage, carrier); -+ } -+ case FLOAT -> { -+ VMStorage storage = storageCalculator.getStorage(StorageType.FLOAT, carrier == float.class); -+ bindings.vmLoad(storage, carrier); -+ } -+ default -> throw new UnsupportedOperationException("Unhandled class " + argumentClass); -+ } -+ return bindings.build(); -+ } -+ } -+} -diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/LinuxS390Linker.java b/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/LinuxS390Linker.java -new file mode 100644 -index 00000000000..ac004b9e1e0 ---- /dev/null -+++ b/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/LinuxS390Linker.java -@@ -0,0 +1,64 @@ -+/* -+ * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2023 IBM Corp. 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 -+ * 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.foreign.abi.s390.linux; -+ -+import jdk.internal.foreign.abi.AbstractLinker; -+import jdk.internal.foreign.abi.LinkerOptions; -+ -+import java.lang.foreign.FunctionDescriptor; -+import java.lang.invoke.MethodHandle; -+import java.lang.invoke.MethodType; -+import java.nio.ByteOrder; -+ -+public final class LinuxS390Linker extends AbstractLinker { -+ -+ public static LinuxS390Linker getInstance() { -+ final class Holder { -+ private static final LinuxS390Linker INSTANCE = new LinuxS390Linker(); -+ } -+ -+ return Holder.INSTANCE; -+ } -+ -+ private LinuxS390Linker() { -+ // Ensure there is only one instance -+ } -+ -+ @Override -+ protected MethodHandle arrangeDowncall(MethodType inferredMethodType, FunctionDescriptor function, LinkerOptions options) { -+ return LinuxS390CallArranger.arrangeDowncall(inferredMethodType, function, options); -+ } -+ -+ @Override -+ protected UpcallStubFactory arrangeUpcall(MethodType targetType, FunctionDescriptor function, LinkerOptions options) { -+ return LinuxS390CallArranger.arrangeUpcall(targetType, function, options); -+ } -+ -+ @Override -+ protected ByteOrder linkerByteOrder() { -+ return ByteOrder.BIG_ENDIAN; -+ } -+} -diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/TypeClass.java b/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/TypeClass.java -new file mode 100644 -index 00000000000..095cb2c08a8 ---- /dev/null -+++ b/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/TypeClass.java -@@ -0,0 +1,126 @@ -+/* -+ * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2023 IBM Corp. 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 -+ * 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.foreign.abi.s390.linux; -+ -+import java.lang.foreign.GroupLayout; -+import java.lang.foreign.MemoryLayout; -+import java.lang.foreign.MemorySegment; -+import java.lang.foreign.SequenceLayout; -+import java.lang.foreign.ValueLayout; -+import java.util.List; -+import java.util.ArrayList; -+ -+public enum TypeClass { -+ STRUCT_REGISTER, -+ STRUCT_SFA, // Single Float Aggregate -+ STRUCT_REFERENCE, -+ POINTER, -+ INTEGER, -+ FLOAT; -+ -+ private static TypeClass classifyValueType(ValueLayout type) { -+ Class carrier = type.carrier(); -+ if (carrier == boolean.class || carrier == byte.class || carrier == char.class || -+ carrier == short.class || carrier == int.class || carrier == long.class) { -+ return INTEGER; -+ } else if (carrier == float.class || carrier == double.class) { -+ return FLOAT; -+ } else if (carrier == MemorySegment.class) { -+ return POINTER; -+ } else { -+ throw new IllegalStateException("Cannot get here: " + carrier.getName()); -+ } -+ } -+ -+ private static boolean isRegisterAggregate(MemoryLayout type) { -+ long byteSize = type.byteSize(); -+ if (byteSize > 8 || byteSize == 3 || byteSize == 5 || byteSize == 6 || byteSize == 7) -+ return false; -+ return true; -+ } -+ -+ static List scalarLayouts(GroupLayout gl) { -+ List out = new ArrayList<>(); -+ scalarLayoutsInternal(out, gl); -+ return out; -+ } -+ -+ private static void scalarLayoutsInternal(List out, GroupLayout gl) { -+ for (MemoryLayout member : gl.memberLayouts()) { -+ if (member instanceof GroupLayout memberGl) { -+ scalarLayoutsInternal(out, memberGl); -+ } else if (member instanceof SequenceLayout memberSl) { -+ for (long i = 0; i < memberSl.elementCount(); i++) { -+ out.add(memberSl.elementLayout()); -+ } -+ } else { -+ // padding or value layouts -+ out.add(member); -+ } -+ } -+ } -+ -+ static boolean isSingleFloatAggregate(MemoryLayout type) { -+ List scalarLayouts = scalarLayouts((GroupLayout) type); -+ -+ final int numElements = scalarLayouts.size(); -+ if (numElements > 1 || numElements == 0) -+ return false; -+ -+ MemoryLayout baseType = scalarLayouts.get(0); -+ -+ if (!(baseType instanceof ValueLayout)) -+ return false; -+ -+ TypeClass baseArgClass = classifyValueType((ValueLayout) baseType); -+ if (baseArgClass != FLOAT) -+ return false; -+ -+ return true; -+ } -+ -+ private static TypeClass classifyStructType(MemoryLayout layout) { -+ -+ if (!isRegisterAggregate(layout)) { -+ return TypeClass.STRUCT_REFERENCE; -+ } -+ -+ if (isSingleFloatAggregate(layout)) { -+ return TypeClass.STRUCT_SFA; -+ } -+ return TypeClass.STRUCT_REGISTER; -+ } -+ -+ public static TypeClass classifyLayout(MemoryLayout type) { -+ if (type instanceof ValueLayout) { -+ return classifyValueType((ValueLayout) type); -+ } else if (type instanceof GroupLayout) { -+ return classifyStructType(type); -+ } else { -+ throw new IllegalArgumentException("Unsupported layout: " + type); -+ } -+ } -+} -diff --git a/test/jdk/java/foreign/TestClassLoaderFindNative.java b/test/jdk/java/foreign/TestClassLoaderFindNative.java -index 3f5fec0c195..44ec8732ed4 100644 ---- a/test/jdk/java/foreign/TestClassLoaderFindNative.java -+++ b/test/jdk/java/foreign/TestClassLoaderFindNative.java -@@ -31,9 +31,10 @@ - import java.lang.foreign.Arena; - import java.lang.foreign.MemorySegment; - import java.lang.foreign.SymbolLookup; -+import java.nio.ByteOrder; - import org.testng.annotations.Test; - --import static java.lang.foreign.ValueLayout.JAVA_BYTE; -+import static java.lang.foreign.ValueLayout.JAVA_INT; - import static org.testng.Assert.*; - - // FYI this test is run on 64-bit platforms only for now, -@@ -58,8 +59,8 @@ public class TestClassLoaderFindNative { - - @Test - public void testVariableSymbolLookup() { -- MemorySegment segment = SymbolLookup.loaderLookup().find("c").get().reinterpret(1); -- assertEquals(segment.get(JAVA_BYTE, 0), 42); -+ MemorySegment segment = SymbolLookup.loaderLookup().find("c").get().reinterpret(4); -+ assertEquals(segment.get(JAVA_INT, 0), 42); - } - - @Test -diff --git a/test/jdk/java/foreign/TestIllegalLink.java b/test/jdk/java/foreign/TestIllegalLink.java -index 677f0bce62f..5d8277a5d4c 100644 ---- a/test/jdk/java/foreign/TestIllegalLink.java -+++ b/test/jdk/java/foreign/TestIllegalLink.java -@@ -54,6 +54,7 @@ import static org.testng.Assert.fail; - public class TestIllegalLink extends NativeTestHelper { - - private static final boolean IS_SYSV = CABI.current() == CABI.SYS_V; -+ private static final boolean IS_LE = ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN; - - private static final MemorySegment DUMMY_TARGET = MemorySegment.ofAddress(1); - private static final MethodHandle DUMMY_TARGET_MH = MethodHandles.empty(MethodType.methodType(void.class)); -@@ -113,27 +114,27 @@ public class TestIllegalLink extends NativeTestHelper { - { - FunctionDescriptor.of(MemoryLayout.sequenceLayout(2, C_INT)), - NO_OPTIONS, -- "Unsupported layout: [2:i4]" -+ IS_LE ? "Unsupported layout: [2:i4]" : "Unsupported layout: [2:I4]" - }, - { - FunctionDescriptor.ofVoid(MemoryLayout.sequenceLayout(2, C_INT)), - NO_OPTIONS, -- "Unsupported layout: [2:i4]" -+ IS_LE ? "Unsupported layout: [2:i4]" : "Unsupported layout: [2:I4]" - }, - { - FunctionDescriptor.ofVoid(C_INT.withByteAlignment(2)), - NO_OPTIONS, -- "Unsupported layout: 2%i4" -+ IS_LE ? "Unsupported layout: 2%i4" : "Unsupported layout: 2%I4" - }, - { - FunctionDescriptor.ofVoid(C_POINTER.withByteAlignment(2)), - NO_OPTIONS, -- "Unsupported layout: 2%a8" -+ IS_LE ? "Unsupported layout: 2%a8" : "Unsupported layout: 2%A8" - }, - { - FunctionDescriptor.ofVoid(ValueLayout.JAVA_CHAR.withByteAlignment(4)), - NO_OPTIONS, -- "Unsupported layout: 4%c2" -+ IS_LE ? "Unsupported layout: 4%c2" : "Unsupported layout: 4%C2" - }, - { - FunctionDescriptor.ofVoid(MemoryLayout.structLayout( -@@ -142,7 +143,7 @@ public class TestIllegalLink extends NativeTestHelper { - C_INT.withName("z").withByteAlignment(1) - ).withByteAlignment(1)), - NO_OPTIONS, -- "Unsupported layout: 1%s2" -+ IS_LE ? "Unsupported layout: 1%s2" : "Unsupported layout: 1%S2" - }, - { - FunctionDescriptor.ofVoid(MemoryLayout.structLayout( -@@ -152,7 +153,7 @@ public class TestIllegalLink extends NativeTestHelper { - C_INT.withName("z").withByteAlignment(1) - ))), - NO_OPTIONS, -- "Unsupported layout: 1%s2" -+ IS_LE ? "Unsupported layout: 1%s2" : "Unsupported layout: 1%S2" - }, - { - FunctionDescriptor.ofVoid(MemoryLayout.structLayout( -@@ -160,7 +161,7 @@ public class TestIllegalLink extends NativeTestHelper { - C_INT.withByteAlignment(1) - ))), - NO_OPTIONS, -- "Unsupported layout: 1%i4" -+ IS_LE ? "Unsupported layout: 1%i4" : "Unsupported layout: 1%I4" - }, - { - FunctionDescriptor.ofVoid(MemoryLayout.structLayout( -@@ -173,17 +174,17 @@ public class TestIllegalLink extends NativeTestHelper { - { - FunctionDescriptor.of(C_INT.withOrder(nonNativeOrder())), - NO_OPTIONS, -- "Unsupported layout: I4" -+ IS_LE ? "Unsupported layout: I4" : "Unsupported layout: i4" - }, - { - FunctionDescriptor.of(MemoryLayout.structLayout(C_INT.withOrder(nonNativeOrder()))), - NO_OPTIONS, -- "Unsupported layout: I4" -+ IS_LE ? "Unsupported layout: I4" : "Unsupported layout: i4" - }, - { - FunctionDescriptor.of(MemoryLayout.structLayout(MemoryLayout.sequenceLayout(C_INT.withOrder(nonNativeOrder())))), - NO_OPTIONS, -- "Unsupported layout: I4" -+ IS_LE ? "Unsupported layout: I4" : "Unsupported layout: i4" - }, - { - FunctionDescriptor.ofVoid(MemoryLayout.structLayout( -@@ -227,5 +228,4 @@ public class TestIllegalLink extends NativeTestHelper { - ? ByteOrder.BIG_ENDIAN - : ByteOrder.LITTLE_ENDIAN; - } -- - } -diff --git a/test/jdk/java/foreign/callarranger/platform/PlatformLayouts.java b/test/jdk/java/foreign/callarranger/platform/PlatformLayouts.java -index 1646063fb08..97856075bef 100644 ---- a/test/jdk/java/foreign/callarranger/platform/PlatformLayouts.java -+++ b/test/jdk/java/foreign/callarranger/platform/PlatformLayouts.java -@@ -305,5 +305,4 @@ public final class PlatformLayouts { - public static final AddressLayout C_POINTER = SharedUtils.C_POINTER; - - } -- - } diff --git a/openjdk_news.sh b/openjdk_news.sh deleted file mode 100755 index 386aa53..0000000 --- a/openjdk_news.sh +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/bash - -# Copyright (C) 2022 Red Hat, Inc. -# Written by Andrew John Hughes , 2012-2022 -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program 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 Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -OLD_RELEASE=$1 -NEW_RELEASE=$2 -REPO=$3 -SUBDIR=$4 -SCRIPT_DIR=$(dirname ${0}) - -if test "x${SUBDIR}" = "x"; then - echo "No subdirectory specified; using ."; - SUBDIR="."; -fi - -if test "x$REPO" = "x"; then - echo "No repository specified; using ${PWD}" - REPO=${PWD} -fi - -if test x${TMPDIR} = x; then - TMPDIR=/tmp; -fi - -echo "Repository: ${REPO}" - -if [ -e ${REPO}/.git ] ; then - TYPE=git; -elif [ -e ${REPO}/.hg ] ; then - TYPE=hg; -else - echo "No Mercurial or Git repository detected."; - exit 1; -fi - -if test "x$OLD_RELEASE" = "x" || test "x$NEW_RELEASE" = "x"; then - echo "ERROR: Need to specify old and new release"; - exit 2; -fi - -echo "Listing fixes between $OLD_RELEASE and $NEW_RELEASE in $REPO" -rm -f ${TMPDIR}/fixes2 ${TMPDIR}/fixes3 ${TMPDIR}/fixes -for repos in . $(${SCRIPT_DIR}/discover_trees.sh ${REPO}); -do - if test "x$TYPE" = "xhg"; then - hg log -r "tag('$NEW_RELEASE'):tag('$OLD_RELEASE') - tag('$OLD_RELEASE')" -R $REPO/$repos -G -M ${REPO}/${SUBDIR} | \ - egrep '^[o:| ]*summary'|grep -v 'Added tag'|sed -r 's#^[o:| ]*summary:\W*([0-9])# - JDK-\1#'| \ - sed 's#^[o:| ]*summary:\W*# - #' >> ${TMPDIR}/fixes2; - hg log -v -r "tag('$NEW_RELEASE'):tag('$OLD_RELEASE') - tag('$OLD_RELEASE')" -R $REPO/$repos -G -M ${REPO}/${SUBDIR} | \ - egrep '^[o:| ]*[0-9]{7}'|sed -r 's#^[o:| ]*([0-9]{7})# - JDK-\1#' >> ${TMPDIR}/fixes3; - else - git -C ${REPO} log --no-merges --pretty=format:%B ${NEW_RELEASE}...${OLD_RELEASE} -- ${SUBDIR} |egrep '^[0-9]{7}' | \ - sed -r 's#^([0-9])# - JDK-\1#' >> ${TMPDIR}/fixes2; - touch ${TMPDIR}/fixes3 ; # unused - fi -done - -sort ${TMPDIR}/fixes2 ${TMPDIR}/fixes3 | uniq > ${TMPDIR}/fixes -rm -f ${TMPDIR}/fixes2 ${TMPDIR}/fixes3 - -echo "In ${TMPDIR}/fixes:" -cat ${TMPDIR}/fixes diff --git a/discover_trees.sh b/scripts/discover_trees.sh similarity index 57% rename from discover_trees.sh rename to scripts/discover_trees.sh index 8c31278..7a0b800 100755 --- a/discover_trees.sh +++ b/scripts/discover_trees.sh @@ -1,6 +1,6 @@ #!/bin/sh -# Copyright (C) 2020 Red Hat, Inc. +# Copyright (C) 2024 Red Hat, Inc. # Written by Andrew John Hughes . # # This program is free software: you can redistribute it and/or modify @@ -18,37 +18,44 @@ TREE=${1} -if test "x${TREE}" = "x"; then +if test "${TREE}" = ""; then TREE=${PWD} fi -if [ -e ${TREE}/nashorn/.hg -o -e ${TREE}/nashorn/merge.changeset ] ; then +if [ -e "${TREE}"/nashorn/.hg ] || [ -e "${TREE}"/nashorn/merge.changeset ] ; then NASHORN="nashorn" ; fi -if [ -e ${TREE}/corba/.hg -o -e ${TREE}/corba/merge.changeset ] ; then +if [ -e "${TREE}"/corba/.hg ] || [ -e "${TREE}"/corba/merge.changeset ] ; then CORBA="corba"; fi -if [ -e ${TREE}/jaxp/.hg -o -e ${TREE}/jaxp/merge.changeset ] ; then +if [ -e "${TREE}"/jaxp/.hg ] || [ -e "${TREE}"/jaxp/merge.changeset ] ; then JAXP="jaxp"; fi -if [ -e ${TREE}/jaxws/.hg -o -e ${TREE}/jaxws/merge.changeset ] ; then +if [ -e "${TREE}"/jaxws/.hg ] || [ -e "${TREE}"/jaxws/merge.changeset ] ; then JAXWS="jaxws"; fi -if [ -e ${TREE}/langtools/.hg -o -e ${TREE}/langtools/merge.changeset ] ; then +if [ -e "${TREE}"/langtools/.hg ] || [ -e "${TREE}"/langtools/merge.changeset ] ; then LANGTOOLS="langtools"; fi -if [ -e ${TREE}/jdk/.hg -o -e ${TREE}/jdk/merge.changeset ] ; then +if [ -e "${TREE}"/jdk/.hg ] || [ -e "${TREE}"/jdk/merge.changeset ] ; then JDK="jdk"; fi -if [ -e ${TREE}/hotspot/.hg -o -e ${TREE}/hotspot/merge.changeset ] ; then +if [ -e "${TREE}"/hotspot/.hg ] || [ -e "${TREE}"/hotspot/merge.changeset ] ; then HOTSPOT="hotspot"; fi SUBTREES="${CORBA} ${JAXP} ${JAXWS} ${LANGTOOLS} ${NASHORN} ${JDK} ${HOTSPOT}"; -echo ${SUBTREES} +echo "${SUBTREES}" + +# Local Variables: +# compile-command: "shellcheck discover_trees.sh" +# fill-column: 80 +# indent-tabs-mode: nil +# sh-basic-offset: 4 +# End: diff --git a/scripts/generate_source_tarball.sh b/scripts/generate_source_tarball.sh new file mode 100755 index 0000000..e01043d --- /dev/null +++ b/scripts/generate_source_tarball.sh @@ -0,0 +1,294 @@ +#!/bin/bash + +# Copyright (C) 2024 Red Hat, Inc. +# Written by: +# Andrew John Hughes +# Thomas Fitzsimmons +# Jiri Vanek +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +# Generates the source tarball for OpenJDK projects. +# +# There are multiple ways to specify the source code location and version: +# +# 1. Specify the version (VERSION), the location of the Git repository +# (REPO_ROOT) and the root of the output tarball name (FILE_NAME_ROOT) +# 2. Specify the version (VERSION) along with an upstream project name +# (PROJECT_NAME) and repository name (REPO_NAME) that can be used +# to construct the URL of the upstream OpenJDK repository. +# 3. Specify OPENJDK_LATEST=1 and allow the script to obtain the JDK +# feature version from the spec file, which is then used to +# obtain the latest build promotion from the upstream repository. +# +# An appropriate bootstrap JDK is also required for when ./configure +# is run within the checked out repository to generate the .src-rev. +# file. This can be specified by setting BOOT_JDK. +# +# Example 1: +# This will check out the specified version from the specified +# repository and construct a tarball called openjdk-17.0.3+5.tar.xz: +# +# $ VERSION=jdk-17.0.3+5 FILE_NAME_ROOT=open${VERSION} \ +# REPO_ROOT=$HOME/projects/openjdk/upstream/17u \ +# BOOT_JDK=/usr/lib/jvm/java-17-openjdk ./generate_source_tarball.sh +# +# Example 2: +# This will check out the same version as example 1, but from the +# upstream repository: +# +# $ VERSION=jdk-25+36 PROJECT_NAME=openjdk REPO_NAME=jdk25u \ +# BOOT_JDK=/usr/lib/jvm/java-17-openjdk sh scripts/generate_source_tarball.sh +# +# Example 3: +# This will read the OpenJDK feature version from the spec file, then create a +# tarball from the most recent tag for that version in the upstream Git +# repository. +# +# $ OPENJDK_LATEST=1 \ +# BOOT_JDK=/usr/lib/jvm/java-17-openjdk ./generate_source_tarball.sh +# + +set -e + +OPENJDK_URL_DEFAULT=https://github.com +COMPRESSION_DEFAULT=xz + +if [ "$1" = "help" ] ; then + echo "Behaviour may be specified by setting the following variables:" + echo + echo "VERSION - the version of the specified OpenJDK project" + echo " (required unless OPENJDK_LATEST is set)" + echo "PROJECT_NAME - the name of the OpenJDK project being archived" + echo " (needed to compute REPO_ROOT and/or" + echo " FILE_NAME_ROOT automatically;" + echo " optional if they are set explicitly)" + echo "REPO_NAME - the name of the OpenJDK repository" + echo " (needed to compute REPO_ROOT automatically;" + echo " optional if REPO_ROOT is set explicitly)" + echo "OPENJDK_URL - the URL to retrieve code from" + echo " (defaults to ${OPENJDK_URL_DEFAULT})" + echo "COMPRESSION - the compression type to use" + echo " (defaults to ${COMPRESSION_DEFAULT})" + echo "FILE_NAME_ROOT - name of the archive, minus extensions" + echo " (defaults to PROJECT_NAME-VERSION)" + echo "REPO_ROOT - the location of the Git repository to archive" + echo " (defaults to OPENJDK_URL/PROJECT_NAME/REPO_NAME.git)" + echo "TO_COMPRESS - what part of clone to pack" + echo " (defaults to ${VERSION})" + echo "BOOT_JDK - the bootstrap JDK to satisfy the configure run" + echo " (defaults to packaged JDK version)" + echo "WITH_TEMP - run in a temporary directory" + echo " (defaults to disabled)" + echo "OPENJDK_LATEST - deduce VERSION from most recent upstream tag" + echo " (implies WITH_TEMP, computes everything else" + echo " automatically; Note: accesses network to read" + echo " tag list from remote Git repository)" + exit 1; +fi + +if [ "$OPENJDK_LATEST" != "" ] ; then + FEATURE_VERSION=$(echo '%featurever' \ + | rpmspec --shell ./*.spec 2>/dev/null \ + | grep --after-context 1 featurever \ + | tail --lines 1) + PROJECT_NAME=openjdk + REPO_NAME=jdk"${FEATURE_VERSION}"u + # Skip -ga tags since those are the same as the most recent non-ga tag, and + # the non-ga tag is the one that is used to generated the official source + # tarball. For example: + # ca760c86642aa2e0d9b571aaabac054c0239fbdc refs/tags/jdk-17.0.10-ga^{} + # 25a2e6c20c9a96853714284cabc6b456eb095070 refs/tags/jdk-17.0.10-ga + # ca760c86642aa2e0d9b571aaabac054c0239fbdc refs/tags/jdk-17.0.10+7^{} + # e49c5749b10f3e90274b72e9279f794fdd191d27 refs/tags/jdk-17.0.10+7 + VERSION=$(git ls-remote --tags --refs --sort=-version:refname \ + "${OPENJDK_URL_DEFAULT}/${PROJECT_NAME}/${REPO_NAME}.git" \ + "jdk-${FEATURE_VERSION}*" \ + | grep --invert-match '\-ga$' \ + | head --lines 1 | cut --characters 52-) + FILE_NAME_ROOT=open${VERSION} + WITH_TEMP=1 +fi + +if [ "$WITH_TEMP" != "" ] ; then + pushd "$(mktemp --directory --tmpdir temp-generated-source-tarball-XXX)" +fi + +if [ "$VERSION" = "" ] ; then + echo "No VERSION specified" + exit 2 +fi +echo "Version: ${VERSION}" + +NUM_VER=${VERSION##jdk-} +RELEASE_VER=${NUM_VER%%+*} +BUILD_VER=${NUM_VER##*+} +MAJOR_VER=${RELEASE_VER%%.*} +echo "Major version is ${MAJOR_VER}, release ${RELEASE_VER}, build ${BUILD_VER}" + +if [ "$BOOT_JDK" = "" ] ; then + echo "No boot JDK specified". + BOOT_JDK=/usr/lib/jvm/java-${MAJOR_VER}-openjdk; + echo -n "Checking for ${BOOT_JDK}..."; + if [ -d "${BOOT_JDK}" ] && [ -x "${BOOT_JDK}"/bin/java ] ; then + echo "Boot JDK found at ${BOOT_JDK}"; + else + echo "Not found"; + PREV_VER=$((MAJOR_VER - 1)); + BOOT_JDK=/usr/lib/jvm/java-${PREV_VER}-openjdk; + echo -n "Checking for ${BOOT_JDK}..."; + if [ -d ${BOOT_JDK} ] && [ -x ${BOOT_JDK}/bin/java ] ; then + echo "Boot JDK found at ${BOOT_JDK}"; + else + echo "Not found"; + exit 4; + fi + fi +else + echo "Boot JDK: ${BOOT_JDK}"; +fi + +if [ "$OPENJDK_URL" = "" ] ; then + OPENJDK_URL=${OPENJDK_URL_DEFAULT} + echo "No OpenJDK URL specified; defaulting to ${OPENJDK_URL}" +else + echo "OpenJDK URL: ${OPENJDK_URL}" +fi + +if [ "$COMPRESSION" = "" ] ; then + # rhel 5 needs tar.gz + COMPRESSION=${COMPRESSION_DEFAULT} +fi +echo "Creating a tar.${COMPRESSION} archive" + +if [ "$FILE_NAME_ROOT" = "" ] ; then + if [ "$PROJECT_NAME" = "" ] ; then + echo "No PROJECT_NAME specified, needed by FILE_NAME_ROOT" + exit 1 + fi + FILE_NAME_ROOT=${PROJECT_NAME}-${VERSION} + echo "No file name root specified; default to ${FILE_NAME_ROOT}" +fi +if [ "$REPO_ROOT" = "" ] ; then + if [ "$PROJECT_NAME" = "" ] ; then + echo "No PROJECT_NAME specified, needed by REPO_ROOT" + exit 1 + fi + if [ "$REPO_NAME" = "" ] ; then + echo "No REPO_NAME specified, needed by REPO_ROOT" + exit 3 + fi + REPO_ROOT="${OPENJDK_URL}/${PROJECT_NAME}/${REPO_NAME}.git" + echo "No repository root specified; default to ${REPO_ROOT}" +fi; + +if [ "$TO_COMPRESS" = "" ] ; then + TO_COMPRESS="${VERSION}" + echo "No targets to be compressed specified ; default to ${TO_COMPRESS}" +fi; + +echo -e "Settings:" +echo -e "\tVERSION: ${VERSION}" +echo -e "\tPROJECT_NAME: ${PROJECT_NAME}" +echo -e "\tREPO_NAME: ${REPO_NAME}" +echo -e "\tOPENJDK_URL: ${OPENJDK_URL}" +echo -e "\tCOMPRESSION: ${COMPRESSION}" +echo -e "\tFILE_NAME_ROOT: ${FILE_NAME_ROOT}" +echo -e "\tREPO_ROOT: ${REPO_ROOT}" +echo -e "\tTO_COMPRESS: ${TO_COMPRESS}" +echo -e "\tBOOT_JDK: ${BOOT_JDK}" +echo -e "\tWITH_TEMP: ${WITH_TEMP}" +echo -e "\tOPENJDK_LATEST: ${OPENJDK_LATEST}" + +if [ -d "${FILE_NAME_ROOT}" ] ; then + echo "Reusing existing ${FILE_NAME_ROOT}" + STAT_TIME="$(stat --format=%Y "${FILE_NAME_ROOT}")" + TAR_TIME="$(date --date=@"${STAT_TIME}" --iso-8601=seconds)" +else + mkdir "${FILE_NAME_ROOT}" + pushd "${FILE_NAME_ROOT}" + echo "Cloning ${VERSION} root repository from ${REPO_ROOT}" + if realpath -q "${REPO_ROOT}"; then + echo "Local path detected; not adding depth argument"; + DEPTH="--"; + else + DEPTH="--depth=1"; + echo "Remote repository detected; adding ${DEPTH}"; + fi + git clone -b "${VERSION}" "${DEPTH}" "${REPO_ROOT}" "${VERSION}" + pushd "${VERSION}" + TAR_TIME="$(git log --max-count 1 --format=%cI)" + popd + popd +fi +pushd "${FILE_NAME_ROOT}" + # Generate .src-rev so build has knowledge of the revision the tarball was + # created from + mkdir build + pushd build + sh "${PWD}"/../"${VERSION}"/configure --with-boot-jdk="${BOOT_JDK}" + make store-source-revision + popd + rm -rf build + + # Remove commit checks + echo "Removing $(find "${VERSION}" -name '.jcheck' -print)" + find "${VERSION}" -name '.jcheck' -print0 | xargs -0 rm -r + + # Remove history and GHA + echo "find ${VERSION} -name '.hgtags'" + find "${VERSION}" -name '.hgtags' -exec rm -v '{}' '+' + echo "find ${VERSION} -name '.hgignore'" + find "${VERSION}" -name '.hgignore' -exec rm -v '{}' '+' + echo "find ${VERSION} -name '.gitattributes'" + find "${VERSION}" -name '.gitattributes' -exec rm -v '{}' '+' + echo "find ${VERSION} -name '.gitignore'" + find "${VERSION}" -name '.gitignore' -exec rm -v '{}' '+' + # Work around some Git objects not having write permissions. + echo "chmod --recursive u+w ${VERSION}/.git" + chmod --recursive u+w "${VERSION}"/.git + echo "find ${VERSION} -name '.git'" + find "${VERSION}" -name '.git' -exec rm -rv '{}' '+' + echo "find ${VERSION} -name '.github'" + find "${VERSION}" -name '.github' -exec rm -rv '{}' '+' + + echo "Compressing remaining forest" + if [ "$COMPRESSION" = "xz" ] ; then + SWITCH=cJf + else + SWITCH=czf + fi + EA_PART="$(awk -F= \ + '/^DEFAULT_PROMOTED_VERSION_PRE/ { if ($2) print "-"$2 }' \ + "${VERSION}"/make/conf/version-numbers.conf)" + TARBALL_NAME=${FILE_NAME_ROOT}${EA_PART}.tar.${COMPRESSION} + XZ_OPT=${XZ_OPT-"-T0"} \ + tar --mtime="${TAR_TIME}" --owner=root --group=root --sort=name \ + --exclude-vcs -$SWITCH "${TARBALL_NAME}" "${TO_COMPRESS}" + mv "${TARBALL_NAME}" .. +popd +if [ "$WITH_TEMP" != "" ] ; then + echo "Tarball is: $(realpath .)/${TARBALL_NAME}" + popd +else + echo -n "Done. You may want to remove the uncompressed version" + echo " - $FILE_NAME_ROOT" +fi + +# Local Variables: +# compile-command: "shellcheck generate_source_tarball.sh" +# fill-column: 80 +# indent-tabs-mode: nil +# sh-basic-offset: 4 +# End: diff --git a/scripts/get_bundle_versions.sh b/scripts/get_bundle_versions.sh new file mode 100755 index 0000000..dddbee4 --- /dev/null +++ b/scripts/get_bundle_versions.sh @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +# Copyright (C) 2025 Red Hat, Inc. +# Original written by Antonio Vieiro +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +if [ $# -ne 1 ]; then + echo "Usage: $0 openjdk-root-directory" + exit 1 +fi + +JDKROOT=$1 + +if [ ! -d "${JDKROOT}" ] ; then + echo "${JDKROOT} is not a directory."; + exit 2 +fi + +# Work out the OpenJDK version +# OpenJDK >= 10 has its version in the build machinery +# OpenJDK >= 17 stores it in a new location (JDK-8258246) +VERSION_FILE="${JDKROOT}"/make/conf/version-numbers.conf +printf "Checking for %s..." "${VERSION_FILE}"; +if [ ! -f "${VERSION_FILE}" ] ; then + VERSION_FILE="${JDKROOT}"/make/autoconf/version-numbers + echo "Not found; using old version file ${VERSION_FILE}"; +else + echo "found."; +fi +if [ -e "${VERSION_FILE}" ] ; then + openjdk_version=$(grep '^DEFAULT_VERSION_FEATURE' "${VERSION_FILE}" | cut -d '=' -f 2) +elif [ -e "${JDKROOT}"/jdk/src/java.base/share/classes/java/lang/Object.java ] ; then + openjdk_version=9; +elif [ -e "${JDKROOT}"/common/autoconf ] ; then + openjdk_version=8; +else + openjdk_version=7; +fi +echo "OpenJDK version: ${openjdk_version}"; + +# +# Freetype +# +if [ "${openjdk_version}" -gt 8 ] ; then + FREETYPE=src/java.desktop/share/native/libfreetype/include/freetype/freetype.h + ABS_FREETYPE="${JDKROOT}"/"${FREETYPE}" + if [ ! -f "${ABS_FREETYPE}" ]; then + echo "Freetype header not found!" + exit 2 + fi + FREETYPE_VERSION=$(awk '/#define FREETYPE_MAJOR/ {MAJOR=$3} /#define FREETYPE_MINOR/ {MINOR=$3} /#define FREETYPE_PATCH/ {PATCH=$3} END {printf "%s.%s.%s", MAJOR, MINOR, PATCH}' "${ABS_FREETYPE}") +else + echo "No bundled FreeType on ${openjdk_version}"; +fi + +# giflib +if [ "${openjdk_version}" -gt 8 ] ; then + GIFLIB=src/java.desktop/share/native/libsplashscreen/giflib/gif_lib.h +else + GIFLIB=jdk/src/share/native/sun/awt/giflib/gif_lib.h +fi +ABS_GIFLIB="${JDKROOT}"/"${GIFLIB}" +if [ ! -f "${ABS_GIFLIB}" ]; then + echo "giflib header not found!" + exit 3 +fi +GIFLIB_VERSION=$(awk '/#define GIFLIB_MAJOR/ {MAJOR=$3} /#define GIFLIB_MINOR/ {MINOR=$3} /#define GIFLIB_RELEASE/ {PATCH=$3} END {printf "%s.%s.%s", MAJOR, MINOR, PATCH}' "${ABS_GIFLIB}") + +# harfbuzz +if [ "${openjdk_version}" -gt 8 ] ; then + HARFBUZZ=src/java.desktop/share/native/libharfbuzz/hb-version.h + ABS_HARFBUZZ="${JDKROOT}/${HARFBUZZ}" + if [ ! -f "${ABS_HARFBUZZ}" ]; then + echo "HarfBuzz header not found!" + exit 4 + fi + HARFBUZZ_VERSION=$(awk '/#define HB_VERSION_MAJOR/ {MAJOR=$3} /#define HB_VERSION_MINOR/ {MINOR=$3} /#define HB_VERSION_MICRO/ {PATCH=$3} END {printf "%s.%s.%s", MAJOR, MINOR, PATCH}' "${ABS_HARFBUZZ}") +else + echo "No HarfBuzz on ${openjdk_version}"; +fi + +# lcms +if [ "${openjdk_version}" -gt 8 ] ; then + LCMS=src/java.desktop/share/native/liblcms/lcms2.h +else + LCMS=jdk/src/share/native/sun/java2d/cmm/lcms/lcms2.h +fi +ABS_LCMS="${JDKROOT}"/"${LCMS}" +if [ ! -f "${ABS_LCMS}" ]; then + echo "lcms header not found!" + exit 5 +fi +LCMS_VERSION=$(awk '/#define LCMS_VERSION/ { MAJOR=int($3 / 1000); REST=$3 % 1000; MINOR=int(REST / 10); PATCH=REST % 10; } END {printf "%s.%s.%s", MAJOR, MINOR, PATCH}' "${ABS_LCMS}") + +# jpeg +if [ "${openjdk_version}" -gt 8 ] ; then + JPEG=src/java.desktop/share/native/libjavajpeg/jpeglib.h +else + JPEG=jdk/src/share/native/sun/awt/image/jpeg/jpeglib.h +fi +ABS_JPEG="${JDKROOT}"/"${JPEG}" +if [ ! -f "${ABS_JPEG}" ]; then + echo "jpeg header not found!" + exit 6 +fi +JPEG_VERSION=$(awk '/#define JPEG_LIB_VERSION/ { VERSION=$3; MAJOR=int(VERSION / 10); MINOR=VERSION%10; } END {printf "%s%c", MAJOR, (MINOR+96)}' "${ABS_JPEG}") + +# png +if [ "${openjdk_version}" -gt 8 ] ; then + PNG=src/java.desktop/share/native/libsplashscreen/libpng/png.h +else + PNG=jdk/src/share/native/sun/awt/libpng/png.h +fi +ABS_PNG="${JDKROOT}"/"${PNG}" +if [ ! -f "${ABS_PNG}" ]; then + echo "png header not found!" + exit 7 +fi +PNG_VERSION=$(awk '/#define PNG_LIBPNG_VER_STRING/ { VERSION=$3; gsub("\"", "", VERSION) } END {print VERSION}' "${ABS_PNG}") + +# zlib +if [ "${openjdk_version}" -gt 8 ] ; then + ZLIB=src/java.base/share/native/libzip/zlib/zlib.h +else + ZLIB=jdk/src/share/native/java/util/zip/zlib/zlib.h +fi +ABS_ZLIB="${JDKROOT}"/"${ZLIB}" +if [ ! -f "${ABS_ZLIB}" ]; then + echo "zlib header not found!" + exit 8 +fi +ZLIB_VERSION=$(awk '/#define ZLIB_VERSION/ { VERSION=$3; gsub("\"", "", VERSION) } END {print VERSION}' "${ABS_ZLIB}") + +# Print output +printf "\nRPM definitions:\n" +if [ "${openjdk_version}" -gt 8 ] ; then + echo "# Version in ${FREETYPE}" + echo "Provides: bundled(freetype) = ${FREETYPE_VERSION}" +fi +echo "# Version in ${GIFLIB}" +echo "Provides: bundled(giflib) = ${GIFLIB_VERSION}" +if [ "${openjdk_version}" -gt 8 ] ; then + echo "# Version in ${HARFBUZZ}" + echo "Provides: bundled(harfbuzz) = ${HARFBUZZ_VERSION}" +fi +echo "# Version in ${LCMS}" +echo "Provides: bundled(lcms2) = ${LCMS_VERSION}" +echo "# Version in ${JPEG}" +echo "Provides: bundled(libjpeg) = ${JPEG_VERSION}" +echo "# Version in ${PNG}" +echo "Provides: bundled(libpng) = ${PNG_VERSION}" +echo "# Version in ${ZLIB}" +echo "Provides: bundled(zlib) = ${ZLIB_VERSION}" + +# Local Variables: +# compile-command: "shellcheck get_bundle_versions.sh" +# fill-column: 80 +# indent-tabs-mode: nil +# sh-basic-offset: 4 +# End: diff --git a/icedtea_sync.sh b/scripts/icedtea_sync.sh similarity index 100% rename from icedtea_sync.sh rename to scripts/icedtea_sync.sh diff --git a/scripts/openjdk_news.sh b/scripts/openjdk_news.sh new file mode 100755 index 0000000..9574915 --- /dev/null +++ b/scripts/openjdk_news.sh @@ -0,0 +1,114 @@ +#!/bin/bash + +# Copyright (C) 2024 Red Hat, Inc. +# Written by Andrew John Hughes , 2012-2022 +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +OLD_RELEASE=$1 +NEW_RELEASE=$2 +REPO=$3 +SUBDIR=$4 +SCRIPT_DIR=$(dirname "${0}") + +if test "${SUBDIR}" = ""; then + echo "No subdirectory specified; using ."; + SUBDIR="."; +fi + +if test "$REPO" = ""; then + echo "No repository specified; using ${PWD}" + REPO=${PWD} +fi + +if test "${TMPDIR}" = ""; then + TMPDIR=/tmp; +fi + +echo "Repository: ${REPO}" + +if [ -e "${REPO}/.git" ] ; then + TYPE=git; +elif [ -e "${REPO}/.hg" ] ; then + TYPE=hg; +else + echo "No Mercurial or Git repository detected."; + exit 1; +fi + +if test "$OLD_RELEASE" = "" || test "$NEW_RELEASE" = ""; then + echo "ERROR: Need to specify old and new release"; + exit 2; +fi + +echo "Listing fixes between $OLD_RELEASE and $NEW_RELEASE in $REPO" +rm -f "${TMPDIR}/fixes2" "${TMPDIR}/fixes3" "${TMPDIR}/fixes" +for repos in . $("${SCRIPT_DIR}/discover_trees.sh" "${REPO}"); +do + if test "$TYPE" = "hg"; then + hg log -r "tag('$NEW_RELEASE'):tag('$OLD_RELEASE') - tag('$OLD_RELEASE')" -R "$REPO/$repos" -G -M "${REPO}/${SUBDIR}" | \ + grep -E '^[o:| ]*summary'|grep -v 'Added tag'|sed -r 's#^[o:| ]*summary:\W*([0-9])# - JDK-\1#'| \ + sed 's#^[o:| ]*summary:\W*# - #' >> "${TMPDIR}/fixes2"; + hg log -v -r "tag('$NEW_RELEASE'):tag('$OLD_RELEASE') - tag('$OLD_RELEASE')" -R "$REPO/$repos" -G -M "${REPO}/${SUBDIR}" | \ + grep -E '^[o:| ]*[0-9]{7}'|sed -r 's#^[o:| ]*([0-9]{7})# - JDK-\1#' >> "${TMPDIR}/fixes3"; + else + git -C "${REPO}" log --no-merges --pretty=format:%B "${NEW_RELEASE}...${OLD_RELEASE}" -- "${SUBDIR}" |grep -E '^[0-9]{7}' | \ + sed -r 's#^([0-9])# - JDK-\1#' >> "${TMPDIR}/fixes2"; + touch "${TMPDIR}/fixes3" ; # unused + fi +done + +sort "${TMPDIR}/fixes2" "${TMPDIR}/fixes3" > "${TMPDIR}/fixes4" +uniq "${TMPDIR}/fixes4" > "${TMPDIR}/fixes" +rm -f "${TMPDIR}/fixes2" "${TMPDIR}/fixes3" + +if ! [ -s "${TMPDIR}/fixes" ] ; then + echo "Failed to obtain fixes."; + exit 3; +fi + +echo "In ${TMPDIR}/fixes:" +cat "${TMPDIR}/fixes" + +printf "\nChecking for duplicates..."; +if uniq -d "${TMPDIR}/fixes4" | grep 'JDK' > "${TMPDIR}/dupes"; then + printf "found.\nWARNING: Review the following duplicates:\n"; + cat "${TMPDIR}/dupes"; +else + echo "No apparent duplicates."; +fi +rm -f "${TMPDIR}/fixes4"; + +printf "\nChecking for backouts..."; +if grep -i 'backout' "${TMPDIR}/fixes" > "${TMPDIR}/backouts"; then + printf "found.\nWARNING: Review the following backouts:\n" + cat "${TMPDIR}/backouts"; +else + echo "No apparent backouts."; +fi +printf "\nChecking for bundled library updates..."; +if grep -iE ':( \(tz\))? update.*(freetype|gif|harfbuzz|lcms|jpeg|png|timezone|zlib)' "${TMPDIR}/fixes" > "${TMPDIR}/bundles"; then + printf "found.\nWARNING: Review the following with respect to bundled provides:\n"; + cat "${TMPDIR}/bundles"; + echo "Compare the output of $(dirname "${0}")/get_bundle_versions.sh with the RPM using the JDK source tree" +else + echo "No apparent library updates."; +fi + +# Local Variables: +# compile-command: "shellcheck openjdk_news.sh" +# fill-column: 80 +# indent-tabs-mode: nil +# sh-basic-offset: 4 +# End: diff --git a/sources b/sources index b2b5901..404d038 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (openjdk-21.0.1+12.tar.xz) = 96513e1346dea623183ae68f88690aa7ea41d65f6a2499b7f9c08954643dd2a6f10d3f4f529fc34e00ff14e8c1bd3764ac78a5c669937a200c910ebcc74e782b +SHA512 (openjdk-26+29-ea.tar.xz) = 4e80882e0de26eff7d46d762e255911d42544473cc5f12ab0af1997969a14cc697e1164cb3c90d894359b58cc42dbd2b233f00fa807dbfad41583da278e26666