python3 cryptography x509
Mein altes certrenew.sh skript vom März 2017 tut nicht mehr.
Da wurde mit tempfiles, awk, sed und wildem Gescripte ein Cert per openssl s_client
runtergeladen, umgebaut und mit neuem key zu einem CertificateSigningRequest zusammengebaut.
Vermutlich hat sich der Output von OpenSSL leicht veraendert und tschoing, schepper
nix geht mehr.
Also das ganze nochmal in Python, mit dem allseits verwendeten Module cryptography.
Das hat AFAICS keine Moeglichkeit, um ein Cert von einem laufenden Service
runterzuladen (dazu muesste es SSL, TLS und mindestens noch STARTTLS koennen). Also
mit socket + ssl (standard-libraries in Python) probiert. Das ssl hat tatsaechlich eine
getpeercert() Methode, aber die liefert ein Dictionary von Strings, zu denen man dann
raten kann, aus welcher abgedrehten X.503-Erweiterung sie stammen, bzw was die ObjectID
von der Erweiterung ist. Also doch wieder openssl, Zert rausparsen und in
cryptography.x509.load_pem_x509_certificate() stopfen. Das stirbt sofort, und liefert
als fehlermeldung einen Link aufs FAQ Why can't i import my pem file.
D.h. das ist eine beliebte Frage, es geht nicht, und sie fixens nicht. Ein wegdokumentierter Bug.
Der besteht darin, dass man einen String uebergeben muss, der mit
-----BEGIN
losgeht, mit dem passenden
-----END
endet, und dazwischen duerfen nur Zeilen zu exakt 64 Zeichen stehen. Also wiiiieeder
elendes Stringzerparsen und -umformen.
Ok, fein, er frisst das Zert, und man kann alle Extensions rausholen.
Aber die leben in einer eigenen Welt/Namensraum, der nicht der
gleiche ist, wie die, aus denen man CertificateRequests bauen kann.
Dort sinds naemlich ExtensionTypes statt Extensions.
Und es gibt keine Konvertierfunktionen AFAICS. Also wiiiieeeder von hand die OIDs
in absurde Aufrufe wie
csr.add_extension(x509.ExtendedKeyUsage([x509.oid.ObjectIdentifier('2.5.29.37.1')]), critical=True)
stopfen, und wenn das DFN-CERT mal beschliesst, andere in die Zerts zu packen, dann
verwerfen Sie die Antraege aus meinem Code...
Nebenbei bemerkt, dass die OIDs nicht etwa in zwei sauberen Dicts oder davon abgeleiteten
Strukturen gelagert werden, in denen man schnell mal in beide Richtungen nachschaun koennte,
sondern in
1. einer Methode, die einen String ala '1.2.3' kriegt (woher man den wissen sollte?)
x509.oid.ObjectIdentifier()
2. Konstanten, z.b.
x509.ExtensionOID.SUBJECT_ALTERNATIVE_NAME
3. implizit in Methoden
x509.BasicConstraints()
Die Parameter fuer KeyUsage in csr.add_extension sind etwas anders als in den Policies
von OpenSSL, so dass ich jetzt raten durfte, was nonrepudiation
in dieser Sprache ist.
Quintessenz/Takeaway/TL;DR
Alles was der Peter Gutmann vor Ewigkeiten ueber X.509 geschrieben hat
stimmt immer noch.