fix(security): backport emSign distrust to 1.0.3

Update the patched verifier and bundled roots without unrelated dependency changes.
Disable the distrusted G3 native root and validate both Docker trust stores.

Refs #8819
This commit is contained in:
Chris An
2026-10-25 13:27:56 +08:00
parent 331fb89628
commit 0ad3afcf0a
7 changed files with 142 additions and 12 deletions
+1
View File
@@ -27,6 +27,7 @@ script-tests: ## Run shell script tests
trap 'status=$$?; printf "ERROR: script-tests failed (exit %s): %s\n" "$$status" "$$BASH_COMMAND" >&2; exit "$$status"' ERR
./scripts/test_build_rustfs_options.sh
./scripts/test_docker_runtime_timezone.sh
sh ./scripts/test_ca_bundle.sh
./scripts/test_entrypoint_credentials.sh
./scripts/test_internode_grpc_ab_bench.sh
./scripts/test_object_batch_bench_enhanced.sh
Generated
+11 -11
View File
@@ -6815,7 +6815,7 @@ dependencies = [
"tracing",
"twox-hash",
"url",
"webpki-roots 1.0.9",
"webpki-roots 1.0.10",
]
[[package]]
@@ -8524,7 +8524,7 @@ dependencies = [
"tracing",
"url",
"uuid",
"webpki-roots 1.0.9",
"webpki-roots 1.0.10",
]
[[package]]
@@ -10136,7 +10136,7 @@ dependencies = [
"tracing",
"twox-hash",
"uuid",
"webpki-roots 1.0.9",
"webpki-roots 1.0.10",
]
[[package]]
@@ -10159,7 +10159,7 @@ dependencies = [
"tokio-rustls",
"tracing",
"uuid",
"webpki-roots 1.0.9",
"webpki-roots 1.0.10",
]
[[package]]
@@ -11259,9 +11259,9 @@ checksum = "eec689c0bc40ff2458a5977b6619cb718087084a18e02a131c599b62d05e1a5f"
[[package]]
name = "rustls-webpki"
version = "0.103.15"
version = "0.103.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2"
checksum = "4443b1b6d39d7c663139942cc4558262562d2c84123bb6282ef177009ca8b281"
dependencies = [
"aws-lc-rs",
"ring",
@@ -13551,9 +13551,9 @@ dependencies = [
[[package]]
name = "webpki-root-certs"
version = "1.0.9"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b96554aa2acc8ccdb7e1c9a58a7a68dd5d13bccc69cd124cb09406db612a1c9b"
checksum = "58ec80e73fd8baf57bf0d9615554c75348bda990d6d5bbeab964dd068319fecb"
dependencies = [
"rustls-pki-types",
]
@@ -13564,14 +13564,14 @@ version = "0.26.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9"
dependencies = [
"webpki-roots 1.0.9",
"webpki-roots 1.0.10",
]
[[package]]
name = "webpki-roots"
version = "1.0.9"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a"
checksum = "1c1c8e20c8a38fc7d65abfe74eb7280e4aa667e8eec8bc84996d2874810748d9"
dependencies = [
"rustls-pki-types",
]
+14 -1
View File
@@ -18,6 +18,13 @@ ARG TARGETARCH
ARG RELEASE=latest
RUN apk add --no-cache ca-certificates curl jq unzip
# Keep the native store safe even if the distribution CA package lags distrust.
COPY scripts/check_ca_bundle.sh /tmp/check_ca_bundle.sh
RUN sed -i '/^mozilla\/emSign_ECC_Root_CA_-_G3.crt$/s/^/!/' /etc/ca-certificates.conf && \
update-ca-certificates --fresh && \
sh /tmp/check_ca_bundle.sh /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs && \
rm /tmp/check_ca_bundle.sh
WORKDIR /build
RUN set -eux; \
@@ -98,7 +105,13 @@ RUN apk upgrade --no-cache && \
tzdata \
&& test "$(TZ=Asia/Kolkata date +%z)" = "+0530"
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
# Keep the native store safe even if the distribution CA package lags distrust.
COPY scripts/check_ca_bundle.sh /tmp/check_ca_bundle.sh
RUN sed -i '/^mozilla\/emSign_ECC_Root_CA_-_G3.crt$/s/^/!/' /etc/ca-certificates.conf && \
update-ca-certificates --fresh && \
sh /tmp/check_ca_bundle.sh /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs && \
rm /tmp/check_ca_bundle.sh
COPY --from=build /build/rustfs /usr/bin/rustfs
COPY entrypoint.sh /entrypoint.sh
+14
View File
@@ -24,6 +24,13 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
unzip \
&& rm -rf /var/lib/apt/lists/*
# Keep the native store safe even if the distribution CA package lags distrust.
COPY scripts/check_ca_bundle.sh /tmp/check_ca_bundle.sh
RUN sed -i '/^mozilla\/emSign_ECC_Root_CA_-_G3.crt$/s/^/!/' /etc/ca-certificates.conf && \
update-ca-certificates --fresh && \
sh /tmp/check_ca_bundle.sh /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs && \
rm /tmp/check_ca_bundle.sh
WORKDIR /build
RUN set -eux; \
@@ -103,6 +110,13 @@ RUN apt-get update && apt-get upgrade -y \
&& test "$(TZ=Asia/Kolkata date +%z)" = "+0530" \
&& rm -rf /var/lib/apt/lists/*
# Keep the native store safe even if the distribution CA package lags distrust.
COPY scripts/check_ca_bundle.sh /tmp/check_ca_bundle.sh
RUN sed -i '/^mozilla\/emSign_ECC_Root_CA_-_G3.crt$/s/^/!/' /etc/ca-certificates.conf && \
update-ca-certificates --fresh && \
sh /tmp/check_ca_bundle.sh /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs && \
rm /tmp/check_ca_bundle.sh
COPY --from=build /build/rustfs /usr/bin/rustfs
COPY entrypoint.sh /entrypoint.sh
+43
View File
@@ -0,0 +1,43 @@
#!/bin/sh
# Reject the distrusted emSign ECC Root CA - G3 in native trust stores.
set -eu
bundle=${1:?Usage: check_ca_bundle.sh BUNDLE CERT_DIRECTORY}
cert_directory=${2:?Usage: check_ca_bundle.sh BUNDLE CERT_DIRECTORY}
distrusted_sha256=86a1ecba089c4a8d3bbe2734c612ba341d813e043cf9e8a862cd5c57a36bbe6b
scratch=$(mktemp -d)
trap 'rm -rf "$scratch"' EXIT HUP INT TERM
check_file() {
# Hash DER, not subject text or PEM formatting. Also inspect hashed links:
# native trust consumers may use the directory rather than the bundle.
awk '
/-----BEGIN CERTIFICATE-----/ { if (inside) exit 1; inside=1; cert=""; next }
/-----END CERTIFICATE-----/ { if (!inside) exit 1; print cert; inside=0; next }
inside { gsub(/[[:space:]]/, ""); cert=cert $0 }
END { if (inside) exit 1 }
' "$1" > "$scratch/certificates"
while IFS= read -r encoded; do
printf '%s' "$encoded" | base64 -d > "$scratch/certificate.der"
if [ ! -s "$scratch/certificate.der" ]; then
echo "Empty certificate in $1" >&2
return 1
fi
digest=$(sha256sum "$scratch/certificate.der")
digest=${digest%% *}
if [ "$digest" = "$distrusted_sha256" ]; then
echo "Distrusted emSign ECC Root CA - G3 found in $1" >&2
return 1
fi
done < "$scratch/certificates"
}
check_file "$bundle"
if [ ! -s "$scratch/certificates" ]; then
echo "CA bundle contains no certificates: $bundle" >&2
exit 1
fi
find -L "$cert_directory" -type f > "$scratch/files"
while IFS= read -r file; do
check_file "$file"
done < "$scratch/files"
+15
View File
@@ -0,0 +1,15 @@
-----BEGIN CERTIFICATE-----
MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG
EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo
bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g
RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ
TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s
b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw
djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0
WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS
fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB
zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq
hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB
CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD
+JbNR6iC8hZVdyR+EhCVBCyj
-----END CERTIFICATE-----
+44
View File
@@ -0,0 +1,44 @@
#!/bin/sh
set -eu
repo_root=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd)
scratch=$(mktemp -d)
trap 'rm -rf "$scratch"' EXIT HUP INT TERM
mkdir "$scratch/certs"
# A public root from webpki-roots 1.0.9, not a private key or active trust anchor.
distrusted="$repo_root/scripts/fixtures/distrusted-emsign-g3.pem"
openssl req -x509 -newkey rsa:2048 -nodes -days 1 -subj /CN=ca-bundle-test \
-keyout "$scratch/key.pem" -out "$scratch/valid.pem" >/dev/null 2>&1
cp "$scratch/valid.pem" "$scratch/bundle.pem"
check() {
sh "$repo_root/scripts/check_ca_bundle.sh" "$scratch/bundle.pem" "$scratch/certs"
}
reject() {
if check > "$scratch/output" 2>&1; then
echo "Expected CA rejection: $1" >&2
exit 1
fi
}
check
cat "$distrusted" >> "$scratch/bundle.pem"
reject 'G3 after a valid certificate in the bundle'
cp "$scratch/valid.pem" "$scratch/bundle.pem"
cp "$distrusted" "$scratch/certs/renamed-root.pem"
reject 'G3 in directory with an unrelated name'
rm "$scratch/certs/renamed-root.pem"
ln -s "$distrusted" "$scratch/certs/12345678.0"
reject 'G3 through a hashed trust-directory symlink'
rm "$scratch/certs/12345678.0"
# Equivalent PEM encodings must not defeat DER-based detection.
printf '%s\n' '-----BEGIN CERTIFICATE-----' > "$scratch/bundle.pem"
sed '/-----/d' "$distrusted" | tr -d '\n' >> "$scratch/bundle.pem"
printf '\n%s\n' '-----END CERTIFICATE-----' >> "$scratch/bundle.pem"
reject 'G3 with unwrapped PEM body'
printf '%s\n' '-----BEGIN CERTIFICATE-----' > "$scratch/bundle.pem"
reject 'truncated bundle'
printf '%s\n' '-----BEGIN CERTIFICATE-----' '-----END CERTIFICATE-----' > "$scratch/bundle.pem"
reject 'empty PEM body'
: > "$scratch/bundle.pem"
reject 'empty bundle'
cp "$scratch/valid.pem" "$scratch/bundle.pem"
check
printf '%s\n' 'CA bundle regression checks passed'