Verlängerung eines CA Zertifikats

Das Auslaufen meines self-signed CA Zertifikates konfrontierte mich mal wieder mit dem openssl CLI und seinen Tücken.

Ausgehend von einer theoretischen Betrachtung sind nur wenige Schritte notwendig um ein CA Zertifikat zu verlängern, was eigentlich bedeutet es in einer erneuerten Version herauszugeben.

  1. Unter Berücksichtigung des private keys der CA erstellt man ein Certificate Request.
  2. Dies wird mit dem private key der CA signiert und erstellt somit ein neues CA Zertifikat.
  3. Dann überprüft man ob schon vormals ausgestellte Server-Zertifikate vom neuen CA Zertifikat akzeptiert werden.
  4. Das neue CA Zertifikat wird auf die Zielplattformen geladen.

Diese Punkte konnten auch ohne Schwierigkeiten mit folgender Kommandosequenz abgearbeitet werden.

openssl req -new -key <privateKey.pem> -out <certRequest.csr>
openssl x509 -req -in <certRequest.csr> -signkey <privateKey.pem> -out <caCert.pem>
openssl verify -CAfile <caCert.pem> -verbose <oldServerCert.pem>

Das letzte Kommando lieferte wie erwartet ein OK. Die Überraschung kam, als das neue Zertifikat auf einem Android System nicht akzeptiert wurde. Die Fehlermeldung lautete:

Privater Schlüssel zum Installieren des Zertifikats erforderlich.

Irreführend – was Android einem eigentlich sagen wollte, dass es dieses Zertifikat nicht akzeptiert, da es nicht dem x509v3 Standard entspricht und somit keine x509v3 Extension bzgl. Basic Constraints besitzt, siehe auch Installing the root CA on Android. Dieses Attribut klassifiziert seit x509v3 Zertifikate welche selber signieren können und somit ein Teil der PKI oder Trust of Chain sind.

Dies ist der einzige Grund. Legacy requirements wie das Vorliegen des Zertifikats im binären DER Format und gar Line Endings im CRLF Style spielen zumindest heute keine Rolle mehr. Pikanterweise wird das Zertifikat auf dem Linux Desktop auf Chrome Version 86 akzeptiert, obwohl – nach einer Überprüfung mit dem Kommando

openssl x509 -in <caCert.pem> -text -noout

tatsächlich feststeht, dass das mit den obigen Kommando erstellte CA Zertifikat auf dem x509v1 Standard basiert, ganz im Gegensatz zum bisherigen CA Zertifikat, welches sehr wohl den x509v3 Standard hat.

Dies wurde allerdings seinerzeit mit einem einzigen Kommando erzeugt, das gleichzeitig einen neuen private Key erzeugte.

openssl req -x509 -newkey rsa -out <caCert.pem> -outform PEM

Und genau hier wird das Problem sichtbarer. Die Konfigurationsdatei openssl.cnf legte folgendes fest (nur auszugsweise aufgeführt):

# OpenSSL example configuration file.
# This is mostly being used for generation of certificate requests.
#

...

# To use this configuration file with the "-extfile" option of the
# "openssl x509" utility, name here the section containing the
# X.509v3 extensions to use:
# extensions            =
# (Alternatively, use a configuration file that has only
# X.509v3 extensions in its main [= default] section.)

...

[ req ]
 default_bits            = 2048
 ...
 attributes              = req_attributes
 x509_extensions = v3_ca # The extentions to add to the self signed cert
 ...

[ v3_ca ]
 # Extensions for a typical CA
 # PKIX recommendation.
 subjectKeyIdentifier=hash
 authorityKeyIdentifier=keyid:always,issuer
 # This is what PKIX recommends but some broken software chokes on
 # critical extensions.
 # basicConstraints = critical,CA:true
 # So we do this instead.
 basicConstraints = CA:true

...

Die extension v3_ca wurde nur in der Sektion [req] angesprochen und ist somit nur für Kommandos der Form:

openssl req ...

gültig. Das neue CA Zertifikat wurde aber, wie oben gezeigt durch ein

openssl x509 ...

Kommando erzeugt, das wie im einleitenden Kommentar in der Konfigurationsdatei angedeutet, prinzipiell die extensions nicht direkt verarbeitet, das bedeutet dass auch eine erweitertes Kommando:

openssl x509 -req -extensions v3_ca -in <certRequest.csr> -signkey <privateKey.pem> -out <caCert.pem>

leider nicht zu einem x509v3 Zertifikat führt.
Erfolg brachte letztendlich nur die Auslagerung der [ v3_ca ] Extension in ein separates File und die Ausführung dieses Kommandos:

openssl x509 -req -extensions v3_ca -extfile ssl-extensions-x509.cnf -in <certRequest.csr> -signkey <privateKey.pem> -out <caCert.pem>

wobei der Inhalt von extfile exakt der obige [ v3_ca ] Block innerhalb der openssl.cnf ist.

Eine Diskussion darüber wurde auf stackexchange im Thread Missing X509 extensions with an openssl-generated certificate geführt.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.