[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.