Also der SSL-Verbindungsaufbau zum Server steht (ohne P12 hat noch nicht mal das funktioniert), nur der Server (eine Ebene weiter) lässt mich nicht zugreifen?
Danach sieht es aus, ja.
Code:
Failed to fetch.
Possible Reasons:
* CORS
* Network Failure
*
URL scheme must be "http" or "https" for CORS request.
Was auch immer das bedeutet.
Die Same-Origin-Policy soll verhindern, dass Skripte Daten von fremden Servern nachladen. Mit CORS kann man im Header angeben, dass Inhalte bestimmter Server erlaubt sind.
Was genau dabei dort das Problem ist, lässt sich aus der Fehlermeldung aber nicht ersehen. Dafür müsste man schauen, welche Requests dort abgesendet werden usw.
Ich kann dir also nicht folgen, so gern ich das auch möchte.
Das ist gar nicht so schwer. Man muss lediglich wissen, dass die virtuellen Methoden einer Klasse in einer Tabelle im Speicher liegen, die direkt hinter dem Pointer auf die Klasse selbst liegt.
Castet man also die Klasse auf Pointer und schaut an der Stelle in den Speicher (in der CPU-Ansicht), kann man dahinter nach der Adresse der Methode suchen, die man ersetzen möchte. Die Differenz zwischen dieser Speicherstelle und der der Klasse muss man dann zum Pointer auf die Klasse addieren.
An die Stelle kann man dann die Adresse der neuen Methode schreiben und schon wird diese statt der ursprünglichen Methode ausgeführt.
Erschwerend kommt hier hinzu, dass die Klasse TWinHTTPClient unterhalb von implementation steht, so dass ich an die Klasse gar nicht heran kam. Deshalb musste ich die Klassenadresse über die an das BeforePost übergebene Clientinstanz ermitteln (Client.ClassType). So konnte ich dann TWinHTTPClient.DoGetClientCertificates überschreiben.
DoGetClientCertificates wiederum bekommt den Request übergeben und so konnte ich im Speicher nach dem
Handle der Verbindung suchen und fand es 164 Byte hinter dem Pointer auf das Objekt. Auf diesem Wert konnte ich dann mit WinHttpSetOption(<
Handle>, WINHTTP_OPTION_CLIENT_CERT_CONTEXT, ...) den Zertifikatskontext als Clientzertifikat setzen.
Den Kontext wiederum konnte ich erhalten, indem ich im Speicher mit PFXImportCertStore einen temporären Zertifikats-Store erstellt habe und darin mit CertFindCertificateInStore den passenden Kontext ermittelt habe.
Das führt an der Stelle vielleicht zu weit, aber vielleicht interessiert es ja jemanden, wie man das bis Delphi 10.4 umgehen kann. Ab Delphi 11 gibt es einfach Properties, so dass man den Dateinamen oder einen Stream mit den Zertifikatsdaten angeben kann.