OpenExchange lehnt Import von validen S/MIME Zertifikaten in OX Guard ab

Hallo zusammen,

wir möchten von GlobalSign signierte S/MIME Zertifikate zu unserem OX Guard hinzufügen. Vorliegend ist eine PFX-Datei in der das Zertifikat mit Key und Fullchain vorhanden ist. Diese Datei lässt sich problemlos in die Schlüsselbundverwaltung von macOS 26, sowie in das aktuelle Outlook für Mac importieren. Auch das openssl Kommandozeilentool meldet bei entsprechenden verify-Commands, dass die Datei gültig und komplett verifizierbar ist.

Beim Uploadversuch in OX Guard gibt’s in der WebUI allerdings einen Fehler, dass die Zertifikatskette nicht vollständig als vertrauenswürdig verifiziert werden konnte. In den Logs steht: SMIME-0002 Categories=ERROR Message='Certificate failed verification'

Leider kann ich keinen anderen Issuer prüfen, da ich kein anderes S/MIME Zertifikat eines Issuers, der normalerweise bereits im Trust Store von macOS oder Linux vorhanden ist, besitze.

Da das Zertifikat aber, wie gesagt, nachweislich von OpenSSL und macOS verifiziert werden konnte, und nur OX hier Probleme bereitet, meine Frage in die Runde: Hat schon mal jemand solch eine Erfahrung gemacht, und wie wurde damit umgegangen?

Das klingt nach einem klassischen Truststore-Unterschied: macOS/Outlook/OpenSSL prüfen nicht zwingend gegen denselben Truststore wie OX Guard.

OX Guard S/MIME vertraut laut OX-Doku standardmäßig den CAs aus dem Java Keystore. Zusätzlich können CAs über das OX-smime-Tool importiert und über com.openexchange.smime.caGroupId bestimmten Benutzern/Gruppen zugeordnet werden:

Daher würde ich nicht zuerst davon ausgehen, dass die PFX-Datei kaputt ist. Eher:

Das Zertifikat ist für macOS/OpenSSL vertrauenswürdig, aber nicht für den Truststore, den OX Guard im Container/JVM tatsächlich verwendet.

Was ich prüfen würde

1. Die Prüfung im Guard-/OX-Container wiederholen

Nicht nur lokal auf dem Mac prüfen, sondern in derselben Runtime, in der Guard läuft.

Sinngemäß:

kubectl -n opendesk get pods | grep -i guard
kubectl -n opendesk exec -it <guard-pod> -- sh

Dann im Container prüfen, ob die GlobalSign-CA im Java Truststore vorhanden ist:

keytool -list -cacerts -storepass changeit | grep -i globalsign

Je nach Image kann der Truststore auch woanders liegen, z.B.:

echo "$JAVA_HOME"
find / -name cacerts 2>/dev/null

Wichtig: Wenn GlobalSign lokal auf macOS vorhanden ist, heißt das noch nicht, dass die CA auch im Java-Truststore des Guard-Containers vorhanden ist.

2. PFX sauber zerlegen und Chain prüfen

Zum Debuggen würde ich die PFX einmal in Leaf-Zertifikat und Chain zerlegen:

openssl pkcs12 -in cert.pfx -clcerts -nokeys -out leaf.pem
openssl pkcs12 -in cert.pfx -cacerts -nokeys -out chain.pem

Dann prüfen:

openssl x509 -in leaf.pem -noout -subject -issuer -dates -ext extendedKeyUsage
openssl verify -purpose smimesign -CAfile chain.pem leaf.pem

Dabei auf folgende Punkte achten:

  • Ist die Intermediate-CA wirklich enthalten?
  • Ist die Chain in plausibler Reihenfolge enthalten?
  • Ist das Zertifikat für S/MIME/E-Mail-Schutz geeignet?
  • Passt die E-Mail-Adresse im Zertifikat?
  • Ist die Root-CA nur Teil der Datei, oder ist sie auch wirklich im Truststore von OX Guard vertraut?

Eine vollständige Chain in der PFX bedeutet nicht automatisch, dass Guard ihr vertraut. Die Trust Anchor CA muss im Guard-/Java-Truststore oder in der Guard-S/MIME-CA-Datenbank vertrauenswürdig sein.

3. CA explizit für Guard importieren

Wenn die GlobalSign-Root oder Intermediate-CA im Guard-Kontext fehlt, würde ich die CA explizit für S/MIME importieren.

Laut OX-Doku geht das ungefähr so:

/opt/open-xchange/sbin/smime \
  -A <admin-user> \
  -P <admin-password> \
  -a /path/to/ca.pem \
  -g <groupId>

Danach muss die passende Gruppe/User-Konfiguration auf diese caGroupId zeigen:

com.openexchange.smime.caGroupId=<groupId>

Wichtig: Ich würde hier nicht das Benutzer-/Leaf-Zertifikat als CA importieren, sondern die ausstellende CA bzw. die relevante Root/Intermediate-CA.

4. CRL/Revocation prüfen

Falls CRL-Prüfung aktiv ist, kann auch Revocation Checking hineinspielen:

com.openexchange.smime.checkCRL=true

Wenn Guard die CRL-URLs der CA aus dem Container heraus nicht erreicht, kann die Verifikation ebenfalls fehlschlagen oder sehr langsam werden.

Zum Testen wäre interessant:

openssl x509 -in leaf.pem -noout -text | grep -A4 -i "CRL"
openssl x509 -in leaf.pem -noout -text | grep -A4 -i "Authority Information Access"

Dann aus dem Guard-Container prüfen, ob die dort genannten URLs erreichbar sind.

Mögliche Ursachen

Aus meiner Sicht kommen besonders diese Ursachen in Frage:

  1. GlobalSign-Root/Intermediate ist im Java-Truststore des Guard-Containers nicht vorhanden.
  2. Die PFX enthält zwar Chain-Material, aber Guard baut daraus keinen gültigen Trust Path.
  3. Die Intermediate-CA fehlt oder ist in einer Variante enthalten, die Guard/Java anders bewertet als macOS/OpenSSL.
  4. CRL/OCSP/Revocation-Informationen sind aus dem Container nicht erreichbar.
  5. Das Zertifikat hat nicht die von Guard erwarteten S/MIME-/E-Mail-Eigenschaften.
  6. Guard verwendet einen eigenen oder älteren Java Truststore.

Warum macOS/OpenSSL hier nicht der finale Beweis ist

macOS nutzt die macOS-Schlüsselbundverwaltung. Outlook auf Mac kann ebenfalls darauf aufbauen. OpenSSL nutzt wiederum die ihm konfigurierte CA-Datei bzw. CA-Pfade.

OX Guard läuft aber serverseitig, typischerweise in einer Java-basierten Runtime. Damit ist entscheidend, was dort als vertrauenswürdig gilt.

Kurz gesagt:

“Auf meinem Mac verifizierbar” heißt leider nicht automatisch “in OX Guard verifizierbar”.

Was ich als nächsten Schritt posten würde

Hilfreich wären anonymisiert:

openssl x509 -in leaf.pem -noout -subject -issuer -dates -ext extendedKeyUsage
openssl x509 -in leaf.pem -noout -text | grep -A4 -i "Authority Information Access"
openssl x509 -in leaf.pem -noout -text | grep -A4 -i "CRL"

Außerdem aus dem Guard-Container:

java -version
keytool -list -cacerts -storepass changeit | grep -i globalsign

Und falls möglich:

kubectl -n opendesk logs <guard-pod> | grep -i SMIME

Mein Bauchgefühl: Die PFX ist wahrscheinlich nicht das Hauptproblem. Wahrscheinlicher ist, dass OX Guard die CA-Kette nicht gegen seinen eigenen Java-/Guard-Truststore validieren kann. Dann wäre der saubere Weg, die passende GlobalSign-CA explizit für Guard/S/MIME zu importieren bzw. den Guard-Truststore entsprechend zu erweitern.