Java und StartSSL

FIRST : Das hier soll eher so eine Art kleines Tutorial / kleine Hilfestellung sein, keine Frage.

Ach ja, wer kennt es nicht : FREE SSL-Certs von StartSSL.com … aber nicht mit Java.

Warum eigentlich nicht? Im Browser funktionierts doch auch ohne Probleme.

Tja, das liegt daran das Java seine eigene CA-Verwaltung hat, also ein eigenes Set an als „vertrauenswürdig“ eingestuften Root-Zertifikaten die als Basis für die Bildung der Zertifikats-Ketten genutzt werden. Und in eben dieser Liste ist das StartSSL.com - Root-CA - Zertifikat nicht eingetragen. Man kann jetzt drüber spekulieren ob es vielleicht einfach daran liegt das Oracle als US-Unternehmen einer kleinen Hacker-Werkstatt aus Israel nicht traut, oder ob es irgendwelche US-Gesetzte diesbezüglich gibt (Dürfte es eigentlich nicht geben, sonst würde Microsoft den Internet Explorer auch nicht mit diesem Zertifikat ausstatten.), oder was oder wer auch immer sonst dafür verantwortlich ist. Fakt ist : so out-of-the-box rennt man bei StartSSL-Zertifikaten in ziemliche Probleme … oder ?

Und genau die Frage hat sich mir auch gestellt : Es gibt zwar Möglichkeiten über „import in den KeyStore“ oder „trust-all Implementierung“, aber das kann doch nicht die Lösung sein !
Also habe ich Google nach einer Möglichkeit gefragt wie man denn nun ein vorhandenes Root-Zertifikat zur Runtime on-the-fly „nachladen“ kann, und bin dabei auf folgendes gestoßen : java - Implementing X509TrustManager - passing on part of the verification to existing verifier - Stack Overflow
Im verlinkten Thema geht es um die Frage wie man einen TrustManager implementieren kann der zwar keine „trust-all Implementierung“, aber auch nicht auf den KeyStore beschränkt ist sondern mit eigenen Zertifikaten erweitert werden kann.

Mit Hilfe des Beispielcodes habe ich mich dann durch die API-Doc gewurstet um erstmal rauszubekommen ob, und wenn ja, wie man zur Runtime Zertifikate „nachladen“ kann.

Es ging erstmal damit los zu ergründen wie überhaupt eine HttpsURLConnection aufgebaut wird. Dabei wird intern auf javax.net.ssl.SSLSocket zurückgegriffen, welcher wiederum über die javax.net.SSLSocketFactory erzeugt werden kann. Gut, ein Ansatzpunkt, denn HttpsURLConnection bietet mit setSSLSocketFactory(SSLSocketFactory) die Möglichkeit eine eigene Factory zu setzen bevor die eigentliche Verbindung mit connect() hergestellt wird.

Der nächste Punkt war nun zu verstehen wie ich eine SSLSocketFactory mit dem von mir gewünschten Root-Zertifikat erzeuge ohne selbst irgendwas mit extends erweitern zu müssen und dabei möglicherweise Fehler mache. An eine SSLSocketFactory kommt man über zwei Wege : SSLSocketFactory.getDefault(), wie der Name schon sagt nicht das was ich suche … und SSLContext.getSocketFactory().

Ok, von SSLContext habe ich schon mal was im Netz gelesen, und dazu findet man auch so einiges. Also weiter : Wie baue ich mir eine SSLContext-Objekt mit dem gewünschten Zertifikat ?
Liest man sich den ganzen Krams durch den Google liefert fällt immer wieder : TrustManager. Und siehe da : SSLContext.init(KeyManager, TrustManager, SecureRandom).

Nun war ich aber wieder genau am Anfang meiner Suche : TrustManager. Und alles was Google dazu so liefert läuft fast immer wieder nur auf eine selbst-Implementierung mit extends hinaus. Aber genau das wollte ich doch nicht. DERP.

Doch dann viel mir plötzlich der Code von StackOverflow wieder ein : TrustManagerFactory ! Aha, es gibt also einen Weg sich einen TrustManager durch eine Factory erstellen zu lassen. DAS muss es doch jetzt aber sein. Und ja, das ist auch der richtige Weg. Also, auf die Doc der Factory : TrustManagerFactory.init(KeyStore).

WAS IS ? Wo soll ich denn jetzt einen KeyStore herbekommen ? Ob ich mir das Root-CA runterlade und in den default-KeyStore packe oder in eine eigene Datei und die dann lade, macht doch keinen Unterschied (höchstens den das man an den „System“-KeyStore ohne Adminrechte nicht rankommt).
Aber naja, jetzt hab ich mich schon so wild durch die Doc geklickt, da kann ich jetzt auch noch in die Page gucken.

Und ach, gucke mal da, was springt mir denn da ins Auge :

KeyStore.TrustedCertificateEntry
This type of entry contains a single public key Certificate belonging to another party. It is called a trusted certificate because the keystore owner trusts that the public key in the certificate indeed belongs to the identity identified by the subject (owner) of the certificate.
This type of entry can be used to authenticate other parties.

Wenn das schon so beschrieben ist muss es doch einen Weg geben ein KeyStore im RAM zu erzeugen und dort das gewünschte Zertifikat zu hinterlegen. So schwer kanns doch echt nicht sein. Ob nun mit einem File oder ein paar Bytes im RAM, für die VM ist es letzten Endes gleich woher die Daten kommen.

Also hatte ich dann mal eben schnell folgendes Ausprobiert :

		X509Certificate x509cert=(X509Certificate)factory.generateCertificate(new FileInputStream(new File("ca.crt")));
		
		KeyStore keyStore=KeyStore.getInstance(KeyStore.getDefaultType());

		keyStore.setCertificateEntry("StartSSL", x509cert);
		
		TrustManagerFactory tmFactory=TrustManagerFactory.getInstance("X509");
		tmFactory.init(keyStore);```
Zwei kleine Probleme gab es dann aber doch noch :

1) Ich musste erstmal rausbekommen welches Format nun eigentlich von der Factory genutzt werden kann, in der Doc steht was von nem Base64-encoded Type. Den gibt es so aber nicht direkt vom StartSSL-Server. Und da mir der Unterschied zwischen den unterschiedlichen Typen nicht bekannt und auch eigentlich ziemlich egal ist hab ich halt nach der Reihe ausprobiert. Man braucht für die x509-Factory das DER Format (welches sowohl im CRT als auch CER steckt, keine Ahnung was der Unterschied ist).

2) Kaum hatte ich es geschafft das Zertifikat ohne Fehler zu laden kam beim Verbindungsaufbau die nächste Expeption : KeyStore must be initialized!
HÄ ? Wat ? Also noch mal in die Doc !
...
Ach ja, da stehts ja auch :

> Before a keystore can be accessed, it must be loaded.

Und wie macht man das ? Gut das "loaded" als Hyperlink ausgelegt ist > draufklicken > und bei KeyStore.load(InputStream, char[]) landen.

In dem Moment hab ich erlich gesagt so leicht die Hoffnung verloren weil ich dachte : na toll, alles umsonst, musst doch mit nem File arbeiten. Aber dies mal hab ich zum Glück weiter gelesen :

> In order to create an empty keystore, or if the keystore cannot be initialized from a stream, pass null as the stream argument.

JA ! ENDLICH ! Die Suche hat ein Ende.
Also eingebaut : LÄUFT !


Mein Gotte, was für ein ewiges rumgeklicke. Aber letzten Endes hat es doch zum Erfolg geführt : ich war in der Lage mit Hilfe des geladenen Zertifikats und den ganzen Factories eine Socket zu erzeugen dessen SSL-Handshake das geladene StartSSL-Root-CA-Zertifikat zur Prüfung genutzt hat und konnte erfolgreich eine TLSv1.2 Verbindung herstellen.


Ich hatte dann noch die Idee : was machen wenn das StartSSL-Zertifikat nicht verfügbar ist ? Na klar, einfach runterladen. Denn zum Glück kann man das CA.crt auch über eine normale HTTP-Verbindung laden.
Tja, und als ich so diese Zeilen schreibe fällt mir ein : "Was für ein absoluter schwachsinn ! Wenn man sich schon die Mühe macht legt man sicher das CRT halt mit bei."

Rausgekommen ist dann am Ende das hier :
```package ssl;
// mal wieder großzügiges import, wenn man halt mal eben ohne IDE bastelt ...
import java.io.*;
import java.net.*;
import javax.net.ssl.*;
import java.security.*;
import java.security.cert.*;
public class Test
{
	public static void main(String[] args) throws Exception
	{
		CertificateFactory factory=CertificateFactory.getInstance("X.509");
		X509Certificate x509cert=(X509Certificate)factory.generateCertificate(Thread.currentThread().getContextClassLoader().getResourceAsStream("ssl/startssl_ca.crt"));
		
		KeyStore keyStore=KeyStore.getInstance(KeyStore.getDefaultType()); // laut Java-Doc wird, wenn nicht anders definiert, "jks" geliefert, könnte man also auch hard-coden
		keyStore.load(null, null);
		keyStore.setCertificateEntry("StartSSL", x509cert); // Alias-Name kann frei gewählt werden
		
		TrustManagerFactory tmFactory=TrustManagerFactory.getInstance("X509");
		tmFactory.init(keyStore);
		
		SSLContext context=SSLContext.getInstance("TLSv1.2"); // ggf. nur getInstance("TLS"); kommt auf den Server an
		context.init(null, tmFactory.getTrustManagers(), null); // erster Parameter KeyManager nur für Client-Auth wichtig / wenn SecureRandom == null wird (wie bei allen Crypto-Klassen) der "höchstwertigste" installierte Provider genutzt
		SSLSocketFactory socketFactory=context.getSocketFactory();
		
		URL url=new URL("https://www.startssl.com");
		
		HttpsURLConnection con=(HttpsURLConnection)url.openConnection();
		con.setSSLSocketFactory(socketFactory);
		con.connect();
		
		BufferedReader in=new BufferedReader(new InputStreamReader(con.getInputStream()));
		String line="";
		while((line=in.readLine())!=null)
		{
			System.out.println(line);
		}
		in.close();
		con.disconnect();
	}
}```
Sicher, erstmal als Test nur das Laden der Hauptseite. Aber als proof-of-concept durch aus ausreichend.

Das ist also der Weg wenn man "sauber" das StartSSL.com Root-CA Zertifikat zur Runtime laden will um eine Verbindung zu einem Server aufzubauen der ein von StartSSL signiertes Zertifikat nutzt.
Ist zwar etwas umständlich und um 100 Ecken und durch 1.000 Factories, aber irgendwie immer noch besser als irgendwas mit extends TrustManager zu basteln und dabei das ganze Sicherheitskonzept was dahinter steht doch wieder auszuhebeln.

Ich hoffe es ist dem einen oder anderen eine Hilfe bezüglich dieses Problems. Vielleicht hat ja noch jemand weitere Ideen ... immer her damit.


Ansonsten wars das erstmal wieder von mir soweit bis hier hin ...

euer Schnitzel
over and out

(Keine Ahnung worum’s hier geht (und eigentlich sollte wohl genau DAS ein Grund sein, mir das mal durchzulesen…), aber nebenbei: Vielleicht wäre das (wenn es “fertig” ist und hier jeder seinen unqualifizierten Senf dazu abgegeben hat) ein Kandidat für einen Blogeintrag…?)

Respekt erstmal. Möchtest du selbst gebaute Applikation damit versorgen, damit die deinen eigenen Server als vertrauenswürdig akzeptieren? Wird in der Praxis genauso gemacht. Alternativ kannst du aber auch ein Self-Signed Zertifikat nutzen. Dann brauchst du auch kein externes Unternehmen. Wenn es eh nur darum geht, dass die Clients den Server erkennen sollen, ist das genauso gut.

Die verschiedenen Formate finde ich auch verwirrend. Kann man aber alle jeweils umwandeln. Die Infos sind also alle enthalten.

Kann man sicherlich mal überlegen wenns soweit „fertig“ ist, denn was man so im Netz bezüglich dieses Themas findet ist leider meist nur „die einfache“ Variante ohne sich viel Gedanken zu machen.

[QUOTE=timbeau;112574]Respekt erstmal. Möchtest du selbst gebaute Applikation damit versorgen, damit die deinen eigenen Server als vertrauenswürdig akzeptieren? Wird in der Praxis genauso gemacht. Alternativ kannst du aber auch ein Self-Signed Zertifikat nutzen. Dann brauchst du auch kein externes Unternehmen. Wenn es eh nur darum geht, dass die Clients den Server erkennen sollen, ist das genauso gut.

Die verschiedenen Formate finde ich auch verwirrend. Kann man aber alle jeweils umwandeln. Die Infos sind also alle enthalten.[/QUOTE]
Es soll schon „produktiv“ gehen wenn ich dann mal selbst Software weiterverteile und halt noch auf ein kostenfreies (bzw kostengünstiges) Zertifikat angewiesen bin (was einige Verlangen ist echt WUCHER). Von daher soll es natürlich eine Möglichkeit sein das mein Code zuverlässigt läuft auch wenn ich ihn an ein 0-8-15 User weitergebe der von Java nur so viel Plan hat als das es als „Bloatware“ mit auf dem System drauf ist.
In wie weit es für andere eine Hilfe ist (immerhin steht dieses Forum recht hoch im Google-Ranking) bleibt abzuwarten, vielleicht noch mal als „saubere“ Version auf SO packen oder so …


Tja, da hängt man den ganzen Sonntag dran und versucht ein bisschen was zum laufen zu bekommen, da rennt man gleich erstmal frontal in die nächsten Probleme. Diesmal der Übeltäter : Thunderbird, LiveMail/Outlook und IMAP/SMTP.

Ich betreibe auf meinem Server einen eigenen Mail-Server, dafür nutze ich die Groupware Citadel. Natürlich wird auch Verschlüsselung über TLS unterstüzt, sowohl das „WebPanel“ WebCit als auch der eigentliche MTA citadel selbst. Beim Setup werden sogar in recht weiser voraussicht self-signed-Zertifikate installiert um vom ersten Start an direkt gesicherte Verbindungen zu ermöglichen.

Möchte man nun über den Browser auf die SSL-Variante von WebCit zugreifen oder sich mit einem Mail-Client via IMAP bzw POP3 und SMTP verbinden bekommt man auch gleich entsprechende Fehlermeldungen. Alles erstmal halbsowild und bei self-signed Zertifikaten auch noch alles völlig normal.

Da ich nun aber, wie oben schon zu erkennen, mich doch dazu entschlossen habe doch mal StartSSL auszuprobieren (keine Panik, natürlich hab ich die private-keys selbst erzeugt) hab ich mir den Luxus gegännt und halt gleich mal alles mit den passenden Zertifikaten ausgestattet. Soweit, so gut, keine Fehlermeldungen, und auch in Java dank des „on-the-fly-Ladens“ ohne zu meckern.
Also dachte ich : mensch, hast doch genug Power, setzte mal ne VM auf und versuchst was mit diesem S/MIME. Gesagt, getan … und BUMS !

Thunderbird will sich erst garnicht verbinden und meckert das Zertifikat als „nicht prüfbar“ an, obwohl das ROOT-CA in Thunderbird installiert ist und von meinem Server die Chain auch ausgeliefert wird, und Outlook machts gleich erstmal komplett und Sicherung direkt Plain.

Da kann doch was nicht stimmen. Leider bietet Citadel so keine Möglichkeit eine SSL / STARTTLS - Verbindung zu erzwingen, aber auch mit den Einstellungen am Client wirds schwierig.
Die „normalen“ SSL-Verbindungen funktionieren, über Java (wenn auch nur mit einem Trick), aber nicht in den Mail-Clients. Und auch STARTTLS ist nach install des Chain-Certs nicht möglich.

Windows LiveMail aus den Essentials 2012 schießt den Vogel komplett ab : es gibt in diesem Drecksteil von möchtegern-Schrott nicht mal die Möglichkeit überhaupt STARTTLS zu aktivieren. Einzig der Punkt „Verbinung über SSL“ wird angeboten. Ist ja auch nicht weiter schlimm. Der Unterschied ist ja nur das bei einer SSL-Verbindung der Stream selbst komplett gesichert ist und bei STARTTLS halt ein „offener“ Stream genutzt wird in den direkt verschlüsselte Daten geschüttet werden. Was durchs Netz läuft ist also so oder so Ende-zu-Ende gesichert. Also ziemlich Banane.
Was mir jedoch aufgefallen ist : nutzt man „Verbindung über SSL“ wird scheinbar versucht eine SSLv3.0 Verbindung herzustellen (was von meinem Server abgelehnt wird) obwohl das Zertifikat für TLSv1.2 ausgelegt ist.

Beim Thunderbird gabs ähnliche Probleme : obwohl mein Zertifikat samt Chain und ROOT-CA übertragen wird packt es Thunderbird nicht das Zertifikat korrekt gegen das bereits in Thunderbird vorhandene ROOT-CA-Zertifikat zu prüfen. Ich musste erst extra noch selbst das Intermediate-Zertifikat nachinstallieren bevor mein Zertifikat komplett aufgelöst und als gültig anerkannt wurde. Was mich sehr verwundert hat : der Button „Zertifikat laden und anzeigen“ im Fehler-Dialog funktioniert nicht mal. Na ups, wer hat denn da debug-Code im Release vergessen ? So eine schlampige Arbeit. Nicht mal das eigene Produkt testen bevor man es zum Download bereitstellt.
Naja, trotz das mein Zertifikat nun auch im Thunderbird funktioniert wird trotzdem keine Verbindung hergestellt, gleich ob über STARTTLS oder SSL, entweder hängt sich Thunderbird auf oder brucht ohne weitere Fehlermeldung einfach ab. Und beim senden einer Mail kommt die Meldung das angeblich was mit dem SMTP-Server nicht stimmen würde.

ABER : jetzt kommt der Hammer : mit Java gehts.
Gut, auch hier musste ich statt dem ROOT-CA das Intermediate nutzen (muss da noch mal genau in die Mail-Server-Einstellung gucken was da nich hinhaut), aber ich kann mich sowohl mit SSL (IMAPS/SMTPS) als auch mit STARTTLS verbinden, Mails verschicken und auch empfangen. Es geht also, die Verbindung und der Datenaustausch haut hin, wenn auch nur low-level, aber es läuft. Warum jetzt zwei der „größten“ Mail-Clients es nicht packen was ein paar Zeilen Java-Code können, eigentlich nur Fragezeichen über dem Kopf.

Klar : obs jetzt an Citadel oder StartSSL oder vielleicht an der Kombination aus beidem liegt kann ich jetzt nicht klären, aber ich seh halt das Ergebnis : mit eigenem Code gehts, mit fertig-Zeugs nicht.

Tja, werd ich mir wohl meinen eigenen kleinen Mail-Client basteln müssen, viel mehr als die JavaMail-lib und ein bisschen GUI-Grundlagen braucht man ja zum Glück nicht. Das sollte kein all zu großes Projekt werden.

Moin,

zumindest das eingestreute S/MIME wirkt an dieser Stelle missverständlich.

S/MIME ist eine Ende-zu-Ende Verschlüsselung / Signatur zwischen den jeweiligen Nutzern. Dazu werden Nutzerzertifikate eingesetzt, bei denen die Mailadresse zwingen gesetzt sein muss. Üblicherweise steht im CN des Zertifikats der Klarname des Zertifikatsinhabers (bei StartSSL nicht, da dieser in der kostenlosen Variante nicht geprüft wird). Wenn die Mail verschlüsselt versendet wird, wird Inhalt und Anhang verschlüsselt. Das ist vergleichbar mit PGP und unabhängig vom Mailserver.

Bei SSL/TLS/STARTTLS handelt es sich um eine Transportverschlüsselung zwischen Mailclient und Mailserver. Dazu werden Serverzertifikate genutzt, bei denen (mindestens) im CN der FQDN des Servers stehen muss. Auf den Servern selbst und auf dem Transport zwischen den Servern wird zumeist nichts verschlüsselt.

Beides ist unterschiedlich und beides setzt unterschiedliche Zertifikate voraus. Nach Möglichkeit sollte man trotzdem beides anwenden.

Als ehemaliger Mitarbeiter einer Zertifizierungsstelle würde ich das Zertifikatsverhalten von Firefox / Thunderbird und Outlook als sehr zuverlässig einschätzen. Wenn die sich weigern hat das normalerweise auch einen Grund.

Gruß
Fancy

Da muss ich dir erstmal den Wind aus den Segeln nehmen.
Die Unterschiede sind mir bewusst und ich weis auch was wofür gedacht ist.

Ich denke du hast meinen zugegeben ziemlich chaotischen Satzbau missverstanden : bzgl des S/MIME war halt die eigentliche Idee die ich halt mal mit den von StartSSL genutzten Client-Zertifikaten ausprobieren wollte (bzgl Signatur und Ende-zu-Ende-Verschlüsselung). Die Probleme die dann dabei auftraten und worum es in dem Post geht beziehen sich jedoch darauf das es schon alleine am Verbindungsaufbau zum Mail-Server gescheitert ist, ich so also nicht mal die Möglichkeit hatte überhaupt eine Mail zu versenden.

Was bei Microsoft schief läuft und warum es keine Einstellung bezüglich STARTTLS gibt ist mir eigentlich egal, aber es hat mich schon gewundert.
Ich hab mal für 1&1 in der Technik telefoniert und nach dieser “Zwangsumstellung” auf dieser “super” Idee EmiG (Mail-Server wurden so eingestellt das STARTTLS erzwungen wird) und hatte zahlreiche Kunden mit denen ich es doch hinbekommen habe. Das ich es selbst mit dieser Erfahrung nicht auf die Reihe bekomme das auf meiner VM selbst auf die Reihe zu kriegen weil halt schlicht eine entsprechende Einstellung fehlt, ich aber auch auf Grund Unkenntnis meinen Mail-Server bisher noch nicht dazu bringen konnte das STARTTLS zu erzwingen (wird sicher gehen, muss mich da noch mal im Forum umsehen) war die Verwunderung um so größer das LiveMail einfach mal so eine Plain-Verbindung nutzt. Mit “richtigem” Outlook konnte ich es mangels Lizenz (ich habs halt schlicht nicht) noch nicht testen. Gucken ob ich irgendwo her mal zumindest ne Test-Version der aktuellen Office-Version oder zumindest Outlook bekomme.

Und auch “mal eben” einen komplexen Mail-Client aus dem Ärmel zu schütteln ist auch nicht, ist halt doch schon ein größeres Projekt. Aber scheinbar ist bereits vorhandene Software nicht so meins …

Ja, ich weis, ich soll aufhören bullshit zu spammen, aber ich habe doch noch etwas hinzuzufügen :

Ich hab mir gerade mal die Testversion von Office 2013 geladen und das darin enthaltene “richtige” Outlook getestet : wenn man mal vom auto-discovery und der damit verbundenen Fehlermeldung absieht (hab mein Apache so konfiguriert das auf die SSL-Subdomain umgeleitet wird was Outlook mal überhaupt nicht mag) funktioniert es bei manueller Einrichtung sofort und ohne irgendeine Fehlermeldung direkt mit STARTTLS.

Ergo : da ich es sowohl mit Java als auch mit Outlook hinbekommen habe das der Zugriff problemlos funktioniert kann der oben beschriebene Fehler nur an Thunderbird/LiveMail liegen.
Warum sich M$ allerdings dazu entschieden hat LiveMail keine Absicherung via STARTTLS zu gönnen ist garantiert mal wieder “so eine tolle Marketing-Idee” von irgendwelchen Praktikanten die sich so erhoffen das sicherheitsbewusste User zum vollwertigen Office greifen und somit halt zahlen. Das da keiner aus der Qualitätssicherung eingegriffen hat … naja, lassen wir das einfach mal so im Raum stehen.

Aber doch erstaunlich zu sehen das es mit den richtigen Mail-Clients dann doch genau so funktioniert wie ich es halt wünsche. Ich hab eh so meine eigene Meinung gegen Mozilla im Allgemeinen, sei es der Browser FireFox, oder wie sich anhand dieses Experimentes gezeigt hat, der Mail-Client ThunderBird. Irgendwie packen die es einfach nicht so richtig.

Natürlich musste auch mein Android 4.4.4 Phone als Testobjekt herhalten, und obwohl auch hier das ROOT-CA installiert ist kommt vom Standard-Mail-Client die Fehlermeldung “Root-Zertifikat ungültig”. Beim Versuch das Intermediate-Zertifikat nachzuinstallieren kam eine Abfrage nach dem Kennwort für den Zertifikatsspeicher, das ich leider nicht kenne (Google dürfte helfen, aber muss nicht).
Dafür finde ich die Option “STARTTLS (allen Zertifikaten vertrauen)” auch recht interessant. Da hat zumindest mal wer mitgedacht und direkt die Möglichkeit gegeben auch die Nutzung von Zertifikaten zu ermöglichen die sonst so abgelehnt werden. Auch wenn nicht wirklich nachvollziehbar warum das gültige Zertifikat nicht korrekt aufgelöst werden kann (denn von meinem Mail-Server wird das Zertifikat samt Chain mit Intermediate-CA und ROOT-CA ausgeliefert) tut es der Sache nun auch keinen Beinbruch. Aber ich denke das sind halt so Dinge mit denen man bei einem kostenfreien Zertifikat halt leben muss.

— EDIT —

Also das Problem auf meinem Android-Phone konnte ich lösen. Wie? Eigentlich recht simpel : das CA-Bundle.pem (erneut) in das CER des Mail-Servers kopieren.
Ich hatte zwar vorher schon Google gefragt in dem halt Cert-Chain so beschrieben wurde das entsprechend der Reihe nach erst das eigene Cert kommt, gefolgt vom Intermediate und zum Schluss noch mal das ROOT-CA. So war es ja auch, was aber scheinbar nicht ganz ausgereicht hat. Naja egal, ich hab einfach den überflüssigen Mist aus meinem CER rausgeschmissen und das CA-Bundle noch mal neu reinkopiert. Damit läufts. Ich gehe von aus das ich damit auch die Probleme zumindest in Thunderbird in den Griff bekommen kann … gleich mal testen. Was LiveMail angeht : naja, wenn halt TLS-Support fehlt kann ich am Server auch nichts mehr machen.

— EDIT 2 —

Tja, sieht so aus als ob der “Fix” meines Zertifikates nun auch Thunderbird überzeugt. Es funktioniert jetzt zumindest auch dort korrekt über STARTTLS. Warum allerdings keine Fehlermeldung kam bleibt fraglich.

Das ROOT-CA sollte nie mit ausgeliefert werden und sollte auch nicht nötig sein, wenn es ja auf den Clients installiert ist.

Nochmal, was spricht gegen kostenlose self-signed Zertifikate?