[9.3.1] Remove distrusted eMudhra and Sectigo AAA root CA certificates from the bundled JDK (#31920) When building the reduced embedded JDK in `src/minimize_jdk.sh`, use `keytool` after `jlink` to remove the distrusted Sectigo (`CN=AAA Certificate Services`) and eMudhra (`CN=emSign ECC Root CA - G3`, `CN=emSign Root CA - G1`, `CN=emSign Root CA - G2`, `CN=emSign Root CA - C1`, `CN=emSign ECC Root CA - C3`) root CA certificates from `reduced/lib/security/cacerts` by matching their SHA-256 fingerprints, to address the eMudhra intermediate CA private key compromise (see https://emudhra.we-have-a-problem.com/). Also add `test_bundled_jdk_cacerts_excludes_distrusted_roots` to `src/test/shell/bazel/bazel_with_jdk_test.sh` to verify that none of the distrusted root certificates remain in the bundled JDK's `cacerts` keystore. RELNOTES: Removed distrusted eMudhra and Sectigo AAA root CA certificates from the bundled JDK, to address the private key leakage (see https://emudhra.we-have-a-problem.com/). PiperOrigin-RevId: 1003293459 Change-Id: I578bdeffb1882c20c351fa6289c20b3383ba19ec (cherry picked from commit efaf902c25d6af8e4d562f3b390def60d350be99)
diff --git a/src/minimize_jdk.sh b/src/minimize_jdk.sh index 32a2f27..fa652ce 100755 --- a/src/minimize_jdk.sh +++ b/src/minimize_jdk.sh
@@ -67,6 +67,36 @@ # Compact object headers reduce retained and peak memory usage. JVM_OPTIONS='--enable-native-access=ALL-UNNAMED -XX:+UseCompactObjectHeaders' +# Remove distrusted root CA certificates from the embedded JDK truststore +# (Sectigo AAA Certificate Services cross-sign root & eMudhra roots) to address +# the eMudhra intermediate CA private key compromise +# (see https://emudhra.we-have-a-problem.com/). +# Note: This must run AFTER jlink because jlink populates +# reduced/lib/security/cacerts from jmods/java.base.jmod. +remove_distrusted_certs() { + local keytool=$1 + local DISTRUSTED_SHA256=( + "D7:A7:A0:FB:5D:7E:27:31:D7:71:E9:48:4E:BC:DE:F7:1D:5F:0C:3E:0A:29:48:78:2B:C8:3E:E0:EA:69:9E:F4" # CN=AAA Certificate Services + "86:A1:EC:BA:08:9C:4A:8D:3B:BE:27:34:C6:12:BA:34:1D:81:3E:04:3C:F9:E8:A8:62:CD:5C:57:A3:6B:BE:6B" # CN=emSign ECC Root CA - G3 + "40:F6:AF:03:46:A9:9A:A1:CD:1D:55:5A:4E:9C:CE:62:C7:F9:63:46:03:EE:40:66:15:83:3D:C8:C8:D0:03:67" # CN=emSign Root CA - G1 + "1A:A0:C2:70:9E:83:1B:D6:E3:B5:12:9A:00:BA:41:F7:EE:EF:02:08:72:F1:E6:50:4B:F0:F6:C3:F2:4F:3A:F3" # CN=emSign Root CA - G2 + "12:56:09:AA:30:1D:A0:A2:49:B9:7A:82:39:CB:6A:34:21:6F:44:DC:AC:9F:39:54:B1:42:92:F2:E8:C8:60:8F" # CN=emSign Root CA - C1 + "BC:4D:80:9B:15:18:9D:78:DB:3E:1D:8C:F4:F9:72:6A:79:5D:A1:64:3C:A5:F1:35:8E:1D:DB:0E:DC:0D:7E:B3" # CN=emSign ECC Root CA - C3 + ) + local keytool_list + keytool_list=$("$keytool" -list -v -keystore reduced/lib/security/cacerts -storepass changeit 2>/dev/null) + for fp in "${DISTRUSTED_SHA256[@]}"; do + local alias + alias=$(echo "$keytool_list" | awk -v fp="$fp" ' + /^Alias name:/ { sub(/^Alias name: */, ""); sub(/\r$/, ""); a=$0 } + index($0, "SHA256: " fp) > 0 { print a } + ') + if [[ -n "$alias" ]]; then + "$keytool" -delete -alias "$alias" -keystore reduced/lib/security/cacerts -storepass changeit + fi + done +} + if [[ "$UNAME" =~ msys_nt* ]]; then unzip -q "$tooljdk" -d "tool_jdk.$$" unzip -q "$fulljdk" -d "full_jdk.$$" @@ -100,6 +130,7 @@ --vm=server --strip-debug --no-man-pages --no-header-files \ --add-options=" ${JVM_OPTIONS}"\ --output reduced + remove_distrusted_certs "$tool_jdk_home/bin/keytool" # Patch the app manifest of the java.exe launcher to force its active code # page to UTF-8 on Windows 1903 and later, which is required for proper # support of Unicode characters outside the system code page. @@ -142,6 +173,7 @@ --vm=server --strip-debug --no-man-pages --no-header-files \ --add-options=" ${JVM_OPTIONS}" \ --output reduced + remove_distrusted_certs "../tool_jdk/bin/keytool" for f in DISCLAIMER readme.txt legal/java.base/ASSEMBLY_EXCEPTION; do [ -f "$f" ] && cp "$f" reduced/; done # These are necessary for --host_jvm_debug to work. cp lib/libdt_socket.* lib/libjdwp.* reduced/lib
diff --git a/src/test/shell/bazel/bazel_with_jdk_test.sh b/src/test/shell/bazel/bazel_with_jdk_test.sh index 6f3bf24..4ac602e 100755 --- a/src/test/shell/bazel/bazel_with_jdk_test.sh +++ b/src/test/shell/bazel/bazel_with_jdk_test.sh
@@ -92,6 +92,24 @@ fail "bazel's java-home is not inside the install base" } +function test_bundled_jdk_cacerts_excludes_distrusted_roots() { + local -r bundled_java_home="$(bazel --batch info java-home 2>> "$TEST_log")" \ + || fail "bazel info java-home failed" + local -r cacerts="${bundled_java_home}/lib/security/cacerts" + [[ -f "$cacerts" ]] || fail "Bundled cacerts not found at $cacerts" + + local -r keytool="${javabase}/bin/keytool${EXE_EXT}" + "$keytool" -list -v -keystore "$cacerts" -storepass changeit \ + &> "$TEST_log" || fail "keytool -list failed on $cacerts" + + expect_not_log "D7:A7:A0:FB:5D:7E:27:31:D7:71:E9:48:4E:BC:DE:F7:1D:5F:0C:3E:0A:29:48:78:2B:C8:3E:E0:EA:69:9E:F4" + expect_not_log "86:A1:EC:BA:08:9C:4A:8D:3B:BE:27:34:C6:12:BA:34:1D:81:3E:04:3C:F9:E8:A8:62:CD:5C:57:A3:6B:BE:6B" + expect_not_log "40:F6:AF:03:46:A9:9A:A1:CD:1D:55:5A:4E:9C:CE:62:C7:F9:63:46:03:EE:40:66:15:83:3D:C8:C8:D0:03:67" + expect_not_log "1A:A0:C2:70:9E:83:1B:D6:E3:B5:12:9A:00:BA:41:F7:EE:EF:02:08:72:F1:E6:50:4B:F0:F6:C3:F2:4F:3A:F3" + expect_not_log "12:56:09:AA:30:1D:A0:A2:49:B9:7A:82:39:CB:6A:34:21:6F:44:DC:AC:9F:39:54:B1:42:92:F2:E8:C8:60:8F" + expect_not_log "BC:4D:80:9B:15:18:9D:78:DB:3E:1D:8C:F4:F9:72:6A:79:5D:A1:64:3C:A5:F1:35:8E:1D:DB:0E:DC:0D:7E:B3" +} + # Tests that "bazel license" prints the license of the bundled JDK by grepping for # representative strings from those files. If this test breaks after upgrading the version of the # bundled JDK, the strings may have to be updated.