Extraktion der Zertifikatskette mit OpenSSL
Es kommt gelegentlich vor, dass bei Serveranwendungen die SSL-Zertifikate ausgetauscht werden. Insbesondere bei einem gleichzeitigen Austausch von CA-Zertifikaten (weil z.B. eine neue Sub-CA für die Signierung neuer Zertifikate verwendet wird) kann es dabei dazu kommen, dass eine Applikation, die als Client auf die Serveranwendung zugreift die Vertrauenskette des Serverzertifikates nicht mehr prüfen kann und dann z.B. in Java mit einer SSLHandShakeException aussteigt. Um hier Abhilfe zu schaffen, benötigt man die CA-Zertifikate, die bei SSL-Handshakes mitgeschickt werden. Um diese zu extrahieren bietet sich das Tool s_client der openssl-Bibliothek an.
Um beim Handshake die Zertifikate ausgeben zu lassen ruft man openssl folgendermaßen auf:
openssl s_client -connect targethost.domain.tld:443 -showcerts
damit liefert OpenSSL die im Handshake übermittelten Zertifikate im PEM-Format an die Standardausgabe. Mit dem folgenden kleinen Perl-Script certsplit.pl lassen sich diese in einzelne .pem-Dateien schreiben:
#!/usr/bin/perl -w
#
# take output from openssl s_client -showcerts and extract certificates
# as openssl-cert-$count.pem files
#
# (C) 2009 Jan Dittberner <jan.dittberner (at) communardo (dot) de>
# use strict;
my $state = 0;
my $count = 0;
my $filename;
my $fh;
while () {
if ($_ =~ /BEGIN CERT/) {
open($fh, '>', "openssl-cert-$count.pem") or die $!;
$count++;
$state=1;
}
if ($state == 1) {
print $fh $_;
}
if ($_ =~ /END CERT/) {
close($fh) or die $!;
$state=0;
}
}
Das Ganze lässt sich über Pipes auch schön automatisieren:
echo -e "HEAD / HTTP/1.1\nHost: targethost.domain.tld\nConnection: Close\n\n"|openssl s_client -connect targethost.domain.tld:443 -showcerts | perl certsplit.pl
Anschließend liegen die Zertifikatsdateien als openssl-cert-#.pem (# ist die Reihenfolge in der die Zertifikate beim Handshake übermittelt werden) im aktuellen Verzeichnis vor.
Die PEM-Dateien können dann z.B. mit
openssl x509 -in openssl-cert-0.pem -noout -text
genauer inspiziert werden. Die CA-Zertifikate können dann z.B. mit dem keytool des JDK in den trusted Keystore importiert werden:
cd $JAVA_HOME/jre/lib/security
keytool -importcert -trustcacerts -keystore cacerts -storepass changeit -alias ALIAS -file ZERTFIKAT.pem
wobei ZERTIFIKAT, ALIAS und bei einem ordentlich gepflegten System auch das bei -storepass angegebene Passwort durch passende Werte zu ersetzen sind.
ACHTUNG: Dieser Vorgang ist nur dann sinnvoll, wenn man wirklich sicher sein kann, dass die Zertifikate wirklich von einem vertrauenswürdigen System kommen, ansonsten kann man damit natürlich auch einem potentiellen Angreifer sein Vertrauen aussprechen.