Die Vorgeschichte
Dieser Tage habe ich mich mal wieder als Hobby-Pentester betätigt und versucht, mit dem Burp Proxy eine ACME-Enrollment-Transaktion mitzuschneiden.
Burp ist ein Tool, das als sogenannter "SSL-Breaker" agiert. D. h. er hat eine integrierte CA, die nur lokal gültige, nachgemachte –manche sagen euphemistisch "emulierte"– TLS-Serverzertifikate erstellt und damit die über den Proxy geleiteten HTTPS-Verbindungen terminiert und entschlüsselt. Vor dem Neuverschlüsseln und Weiterleiten an den echten angesprochenen HTTPS-Server ermöglicht er es dem geneigten Pentester, die übertragenen Daten im Klartext mitzulesen und bei Bedarf gezielt zu verändern.
Damit das ohne Zertifikatsfehler vonstattengeht, muss natürlich das (Root- = Issuing-) CA-Zertifikat des SSL-Breakers im Trust-Store des Browsers, in meinem Fall dem Local Machine Store des Windows-Betriebssystems, als vertrauenswürdig installiert werden.
Darüber konnte ich dann per Browser das ACME-Directory der angesprochenen CA (tatsächlich war es einmal eine andere als Let's Encrypt) abrufen und Anfrage wie Antwort im Detail in der Burp-Proxy-History nachlesen.
Danach wurde es seltsam...
Das Rätsel
Der gleiche Aufruf per PowerShells Invoke-Webrequest cmdlet ging schief:
Invoke-WebRequest: The remote certificate is invalid because of errors in the certificate chain: UntrustedRoot
Hey, ChatGPT...
Why does the Edge Browser recognize the CA certificate of my Burp Proxy but PowerShell Invoke-WebRequest does not?
Die Antwort war, wie zu erwarten, zwar nicht völlig falsch, trug letztlich aber auch wenig zur Erhellung des Problems bei. Und auch eine Internet-Suche (kann man eigentlich mit Bing googeln???) brachte keine nützlichen Treffer. Damit das dem/der Nächsten mit diesem Problem nicht auch so geht, schreibe ich diesen Blogbeitrag und wiederhole hier passende Suchbegriffe:
| PowerShell | Burp | Trust Store | UntrustedRoot |
Des Rätsels Lösung
Die Burp-Ersteller haben, wie auch der eine oder andere weitere Hersteller von Content Inspection Gateways vulgo SSL-Breakern, nachvollzierbarerweise keine große Lust, sich mit einer Vielzahl von Public/Private-Key Schlüsselpaaren abzugeben, bloß weil über ihr Produkt eine Vielzahl von Webservern und Webservices angesprochen wird.
Also verwenden sie in allen "emulierten" Serverzertifikaten denselben Schlüssel. Im Fall von Burp ist das sogar derselbe Schlüssel, den auch die integrierte CA verwendet, wie man am gleichlautenden SubjectKeyIdentifier und AuthorityKeyIdentifier des Fake-Serverzertifikats sehen kann:

Nach PKI-Lehrbuchwissen wird eine Zertifikatskette dadurch verknüpft, dass der Issuer-Distinguished-Name des darunterliegenden Zertifikats mit dem Subject-Distinguished-Name des Aussteller-Zertifikats der darüberliegenden CA abgeglichen wird. So implementiert das auch beispielsweise OpenSSL.
Nun ist es aber eine viel zu wenig bekannte Eigenschaft der Windows Crypto-API, dass sie die Zertifikatskette –wenn möglich– primär über den Abgleich der AuthorityKeyIdentifier-Erweiterung im darunterliegenden Zertifikat mit der SubjectKeyIdentifier-Erweiterung im Aussteller-Zertifikat verknüpft – im Zweifel selbst dann, wenn die Issuer-/Subject-Namen nicht matchen.
Genauer in Microsoft-Sprech gesagt, wird in der Binding-Phase der Kettenbildung ein "Exact Match" oder "Key Match" dem "Name Match" vorgezogen. Schon vor fast 15 Jahren hat der völlig zurecht weltbekannte PKI-Experte Vadims Podāns die Details dazu unter dem Titel Certificate Chaining Engine — how it works in seinem Blog beschrieben.
Aus Sicht der Crypto-API ist die Zertifikatskette also schon mit dem Serverzertifikat selbst zu Ende, auch wenn dessen Subject- und Issuer-Name sich unterscheiden. Ergo ist die angemahnte "UntrustedRoot" nicht, wie jedermann zuerst (und ChatGPT bis heute) vermuten würde, das Burp-CA-Zertifikat, sondern das von dieser CA ausgestellte Serverzertifikat.
Trommelwirbel...
Die einfache Lösung für Burp-Anwender, die dieses Phänomen unter Windows erleben, ist es also, nicht das Burp-CA-Zertifikat, sondern das bzw. die Serverzertifikate in den Windows Trusted-Root-Store des Client-Geräts aufzunehmen.
Die richtige Lösung für die Burp-Ersteller wäre es, dann doch statt einem satte zwei getrennte Schlüsselpaare für CA-Zertifikat und Serverzertifikate zu verwenden. Oder zumindest in den SubjectKeyIdentifier der Serverzertifikate einen anderen Wert hineinzuschreiben, der niemanden außer der Windows Crypto-API interessiert.
Und warum es mit dem Browser funktioniert hat? Offenbar verwendet selbst der Edge-Browser zur Validierung von HTTPS-Serverzertifikaten nicht die Windows Crypto API, sondern BoringSSL.
