diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index d6438ca8e..30dd8e66a 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -46,6 +46,7 @@ on: - '.github/workflows/appimage.yml' - 'dist/linux/appimage/**' - 'dist/linux/common/**' + - 'dist/common/**' - 'dist/linux/resources/**' permissions: @@ -137,6 +138,8 @@ jobs: --compress zip-0 env: JMOD_PATHS: ${{ steps.jep-493-check.outputs.jmod_paths }} + - name: Remove distrusted CA certificates from runtime + run: ${JAVA_HOME}/bin/java dist/common/RemoveDistrustedCaCerts.java runtime/lib/security/cacerts - name: Run jpackage run: > ${JAVA_HOME}/bin/jpackage diff --git a/.github/workflows/debian.yml b/.github/workflows/debian.yml index a14b1a76d..5237faf6c 100644 --- a/.github/workflows/debian.yml +++ b/.github/workflows/debian.yml @@ -21,6 +21,7 @@ on: - '.github/workflows/debian.yml' - 'dist/linux/debian/**' - 'dist/linux/common/**' + - 'dist/common/**' - 'dist/linux/resources/**' env: @@ -113,6 +114,7 @@ jobs: cp -r target/mods pkgdir cp -r jmods pkgdir cp -r dist/linux/common/ pkgdir + cp dist/common/RemoveDistrustedCaCerts.java pkgdir/common cp target/cryptomator-*.jar pkgdir/mods tar -cJf cryptomator_${{ steps.deb-version.outputs.debVersion }}.orig.tar.xz -C pkgdir . - name: Patch and rename pkgdir diff --git a/.github/workflows/linux-flatpak.yml b/.github/workflows/linux-flatpak.yml index cf48a46c8..83d65a9ba 100644 --- a/.github/workflows/linux-flatpak.yml +++ b/.github/workflows/linux-flatpak.yml @@ -21,6 +21,7 @@ on: - '.github/workflows/linux-flatpak.yml' - 'dist/linux/flatpak/**' - 'dist/linux/common/**' + - 'dist/common/**' - 'dist/linux/resources/**' permissions: diff --git a/.github/workflows/linux-makepkg.yml b/.github/workflows/linux-makepkg.yml index 8d771bc45..8dee11cbc 100644 --- a/.github/workflows/linux-makepkg.yml +++ b/.github/workflows/linux-makepkg.yml @@ -21,6 +21,7 @@ on: - '.github/workflows/linux-makepkg.yml' - 'dist/linux/makepkg/**' - 'dist/linux/common/**' + - 'dist/common/**' - 'dist/linux/resources/**' permissions: diff --git a/.github/workflows/mac-dmg-x64.yml b/.github/workflows/mac-dmg-x64.yml index f43a38b2a..45c8382e7 100644 --- a/.github/workflows/mac-dmg-x64.yml +++ b/.github/workflows/mac-dmg-x64.yml @@ -140,6 +140,8 @@ jobs: --no-man-pages --strip-debug --compress zip-0 + - name: Remove distrusted CA certificates from runtime + run: ${JAVA_HOME}/bin/java dist/common/RemoveDistrustedCaCerts.java runtime/lib/security/cacerts - name: Run jpackage run: > ${JAVA_HOME}/bin/jpackage diff --git a/.github/workflows/mac-dmg.yml b/.github/workflows/mac-dmg.yml index c92f20154..2fb216459 100644 --- a/.github/workflows/mac-dmg.yml +++ b/.github/workflows/mac-dmg.yml @@ -51,6 +51,7 @@ on: paths: - '.github/workflows/mac-dmg.yml' - 'dist/mac/**' + - 'dist/common/**' env: JAVA_DIST: 'temurin' @@ -138,6 +139,8 @@ jobs: --no-man-pages --strip-debug --compress zip-0 + - name: Remove distrusted CA certificates from runtime + run: ${JAVA_HOME}/bin/java dist/common/RemoveDistrustedCaCerts.java runtime/lib/security/cacerts - name: Run jpackage run: > ${JAVA_HOME}/bin/jpackage diff --git a/.github/workflows/win-exe.yml b/.github/workflows/win-exe.yml index d955aa069..96e6befed 100644 --- a/.github/workflows/win-exe.yml +++ b/.github/workflows/win-exe.yml @@ -54,6 +54,7 @@ on: paths: - '.github/workflows/win-exe.yml' - 'dist/win/**' + - 'dist/common/**' env: @@ -159,6 +160,8 @@ jobs: --no-man-pages --strip-debug --compress zip-0 + - name: Remove distrusted CA certificates from runtime + run: ${JAVA_HOME}/bin/java dist/common/RemoveDistrustedCaCerts.java runtime/lib/security/cacerts - name: Run jpackage run: > ${JAVA_HOME}/bin/jpackage diff --git a/CHANGELOG.md b/CHANGELOG.md index a5dd3cc25..2a0ce9f76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,11 @@ Changes to prior versions can be found on the [Github release page](https://gith - `com.fasterxml.jackson.datatype:jackson-datatype-jsr310` from 2.21.4 to 2.21.6 +## [1.19.4](https://github.com/cryptomator/cryptomator/releases/1.19.4) - 2026-10-21 +### Security +* Removed compromised eMudhra certs from app internal CA store ([62a0f41](https://github.com/cryptomator/cryptomator/commit/62a0f41523d5e1818d76ef3e9b6f4560053f2445)) + + ## [1.19.3](https://github.com/cryptomator/cryptomator/releases/1.19.3) - 2026-06-29 ### Added * New error dialog if importing a vault fails ([#4243](https://github.com/cryptomator/cryptomator/pull/4243)) diff --git a/dist/common/RemoveDistrustedCaCerts.java b/dist/common/RemoveDistrustedCaCerts.java new file mode 100644 index 000000000..f261114fb --- /dev/null +++ b/dist/common/RemoveDistrustedCaCerts.java @@ -0,0 +1,58 @@ +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.KeyStore; +import java.security.MessageDigest; +import java.security.Security; +import java.util.Collections; +import java.util.HexFormat; +import java.util.Map; + +/** + * Removes distrusted root CA certificates from a JDK {@code cacerts} trust store, matching by SHA-256 fingerprint so that vendor-specific alias names don't matter. + *

+ * Run after {@code jlink} and before {@code jpackage} on the runtime image, e.g. {@code $JAVA_HOME/bin/java dist/common/RemoveDistrustedCaCerts.java runtime/lib/security/cacerts}. + * The trust store is written back password-less, as the JDK expects for {@code cacerts}. + */ +public class RemoveDistrustedCaCerts { + + // Roots affected by the eMudhra intermediate CA key compromise (2026-10-17), see https://emudhra.we-have-a-problem.com/roots.json and https://bugzilla.mozilla.org/show_bug.cgi?id=2083449 + private static final Map DISTRUSTED_SHA256 = Map.of( // + "emSign ECC Root CA - G3", "86A1ECBA089C4A8D3BBE2734C612BA341D813E043CF9E8A862CD5C57A36BBE6B", // + "emSign Root TLS CA - G3", "7DD78D5F4F13459A83DFF9ABBBA62EDBAF6F2D102BF257FD712F4D9F2746ED8D", // + "emSign Root CS CA - G3", "F2EDAAFF3D9B701FB4D14C9F285F8C0BAD90FC3BCC1FA07D47F4718EDABA34A5", // + "AAA Certificate Services", "D7A7A0FB5D7E2731D771E9484EBCDEF71D5F0C3E0A2948782BC83EE0EA699EF4" // Sectigo root that cross-signed the compromised intermediates + ); + + public static void main(String[] args) throws Exception { + if (args.length != 1) { + System.err.println("Usage: java RemoveDistrustedCaCerts.java "); + System.exit(2); + } + var cacerts = Path.of(args[0]); + var keyStore = KeyStore.getInstance(cacerts.toFile(), (char[]) null); + var sha256 = MessageDigest.getInstance("SHA-256"); + var hex = HexFormat.of().withUpperCase(); + int removed = 0; + for (var alias : Collections.list(keyStore.aliases())) { + var cert = keyStore.getCertificate(alias); + if (cert == null) { + continue; + } + var fingerprint = hex.formatHex(sha256.digest(cert.getEncoded())); + if (DISTRUSTED_SHA256.containsValue(fingerprint)) { + keyStore.deleteEntry(alias); + removed++; + System.out.println("Removed distrusted CA certificate \"" + alias + "\" (SHA-256: " + fingerprint + ")"); + } + } + if (removed > 0) { + // store without certificate encryption and MAC, i.e. password-less, otherwise the JDK can't read cacerts + Security.setProperty("keystore.pkcs12.certProtectionAlgorithm", "NONE"); + Security.setProperty("keystore.pkcs12.macAlgorithm", "NONE"); + try (var out = Files.newOutputStream(cacerts)) { + keyStore.store(out, null); + } + } + System.out.println("Removed " + removed + " distrusted CA certificate(s) from " + cacerts + ", " + keyStore.size() + " remaining"); + } +} diff --git a/dist/linux/appimage/build.sh b/dist/linux/appimage/build.sh index 6c6cfd595..a3ecea3b3 100755 --- a/dist/linux/appimage/build.sh +++ b/dist/linux/appimage/build.sh @@ -68,6 +68,8 @@ ${JAVA_HOME}/bin/jlink \ --no-man-pages \ --strip-debug \ --compress zip-0 +## remove distrusted CA certificates from runtime +${JAVA_HOME}/bin/java ../../common/RemoveDistrustedCaCerts.java runtime/lib/security/cacerts # create app dir ${JAVA_HOME}/bin/jpackage \ diff --git a/dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml b/dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml index c32020758..4f0693ccd 100644 --- a/dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml +++ b/dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml @@ -84,6 +84,9 @@ + + https://github.com/cryptomator/cryptomator/releases/1.19.4 + https://github.com/cryptomator/cryptomator/releases/1.19.3 diff --git a/dist/linux/debian/rules b/dist/linux/debian/rules index d2acc4cd4..5080cf1f9 100755 --- a/dist/linux/debian/rules +++ b/dist/linux/debian/rules @@ -34,6 +34,7 @@ override_dh_auto_build: --no-man-pages \ --strip-debug \ --compress zip-0 + $(JAVA_HOME)/bin/java common/RemoveDistrustedCaCerts.java runtime/lib/security/cacerts $(JAVA_HOME)/bin/jpackage \ --type app-image \ --runtime-image runtime \ diff --git a/dist/linux/flatpak/org.cryptomator.Cryptomator.TEMPLATE.yaml b/dist/linux/flatpak/org.cryptomator.Cryptomator.TEMPLATE.yaml index d65f6f1ea..99cb361b9 100644 --- a/dist/linux/flatpak/org.cryptomator.Cryptomator.TEMPLATE.yaml +++ b/dist/linux/flatpak/org.cryptomator.Cryptomator.TEMPLATE.yaml @@ -105,6 +105,7 @@ modules: --no-man-pages --strip-debug --compress=zip-0 + - $JAVA_HOME/bin/java dist/common/RemoveDistrustedCaCerts.java runtime/lib/security/cacerts - $JAVA_HOME/bin/jpackage --type app-image --runtime-image runtime diff --git a/dist/linux/makepkg/PKGBUILD.template b/dist/linux/makepkg/PKGBUILD.template index cad044b1d..c22802260 100644 --- a/dist/linux/makepkg/PKGBUILD.template +++ b/dist/linux/makepkg/PKGBUILD.template @@ -64,6 +64,8 @@ build() { --strip-debug \ --compress=zip-0 + "$JAVA_HOME/bin/java" ../dist/common/RemoveDistrustedCaCerts.java runtime/lib/security/cacerts + ##Note: jpackage does not allow -beta suffixes, have to strip those "$JAVA_HOME/bin/jpackage" \ --type app-image \ diff --git a/dist/mac/dmg/build.sh b/dist/mac/dmg/build.sh index 81587bb50..db816b17e 100755 --- a/dist/mac/dmg/build.sh +++ b/dist/mac/dmg/build.sh @@ -91,6 +91,8 @@ ${JAVA_HOME}/bin/jlink \ --no-man-pages \ --strip-debug \ --compress zip-0 +## remove distrusted CA certificates from runtime +${JAVA_HOME}/bin/java ../../common/RemoveDistrustedCaCerts.java runtime/lib/security/cacerts # create app dir ${JAVA_HOME}/bin/jpackage \ diff --git a/dist/win/build.ps1 b/dist/win/build.ps1 index 17a450f3e..b3b6916b9 100644 --- a/dist/win/build.ps1 +++ b/dist/win/build.ps1 @@ -151,6 +151,10 @@ Invoke-CommandWithExitCheck -Command ` "--compress", "zip-0" #do not compress and use msi compression ) +### remove distrusted CA certificates from runtime +Invoke-CommandWithExitCheck -Command ` + "$Env:JAVA_HOME\bin\java" -Arguments @("$buildDir\..\common\RemoveDistrustedCaCerts.java", "runtime\lib\security\cacerts") + $appPath = ".\$AppName" if ($clean -and (Test-Path -Path $appPath)) { Remove-Item -Path $appPath -Force -Recurse