[gelöst] Indy, OpenSSL, Server Zertifikate prüfen,

Rund um die LCL und andere Komponenten
Antworten
Benutzeravatar
AlterPascaler
Beiträge: 87
Registriert: Mo 26. Jun 2023, 18:56
OS, Lazarus, FPC: Linux, Lazarus, Free Pascal
CPU-Target: xxBit
Wohnort: Deutschland, NRW

[gelöst] Indy, OpenSSL, Server Zertifikate prüfen,

Beitrag von AlterPascaler »

Moin,

mit Indy mache ich ein HTTPS Get Request und möchte prüfen ob die Server Zertifikate gültig sind. Im Ereignis OnVerifyPeer bekomme ich die Ergebnisse der Überprüfung.

Eingestellt ist VerifyDepth=2, VerifyMode=[sslvrfPeer].

Bei der Anfrage auf "https://www.google.de", bekomme ich folgende Ergebnisse:
IOHandlerSocketOpenSSLVerifyPeer:: AOk=0, ADepth=2, AError=20
IOHandlerSocketOpenSSLVerifyPeer:: AOk=1, ADepth=1, AError=20
IOHandlerSocketOpenSSLVerifyPeer:: AOk=1, ADepth=0, AError=20

AError=20 bedeutet "X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY", was nicht wirklich ein Fehler ist.
ADepth ist, glaube ich, die Position der Zertifikatkette bzw. der Aussteller.

AOk, ist das Ergebnis der Überprüfung, wobei 1 = True, und 0 = False ist.

Was ich nicht verstehe, warum ist immer das erste Event AOk=0. Getestet habe ich das mit mehren Servern und unterschiedlichen VerifyDepth Einstellung.

Hoffentlich kann mir jemand auf die Sprünge helfen.

Viele Grüße
AP
Zuletzt geändert von AlterPascaler am Di 21. Mai 2024, 19:12, insgesamt 1-mal geändert.
Viele Grüße
AlterPascaler

CCRDudeLaz
Beiträge: 54
Registriert: Do 25. Jan 2024, 08:33
OS, Lazarus, FPC: Win/macOS (L trunk FPC trunk)
CPU-Target: 32+64

Re: Indy, OpenSSL, Server Zertifikate prüfen,

Beitrag von CCRDudeLaz »

Ich habe das bisher nur mit Synapse versucht und hänge da leider an anderer Stelle, aber spontan würde ich fragen:

Welche Root-Zertifikate verwendest Du denn, wie übergibst Du die Indy? Es scheitert ja das tiefste, als vermutlich das Root-Zertifikat?

(oder nutzt Indy die des Systems?)

Benutzeravatar
AlterPascaler
Beiträge: 87
Registriert: Mo 26. Jun 2023, 18:56
OS, Lazarus, FPC: Linux, Lazarus, Free Pascal
CPU-Target: xxBit
Wohnort: Deutschland, NRW

Re: Indy, OpenSSL, Server Zertifikate prüfen,

Beitrag von AlterPascaler »

Raus gefunden habe ich, das bei "IOHandlerSocketOpenSSLVerifyPeer:: AOk=0, ADepth=2, AError=20" das CA-Root-Cert fehlt. Ein Browser holt sich das on the fly, Indy nicht. Jetzt könnte ich das Zertifikat mir downloaden, aber ich bekomme Indy auch nicht dazu in ein Verzeichnis zuschauen, wo diverse Zertifikate liegen. Deswegen wahrscheinlich auch die Fehlermeldung "X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY".

Jetzt könnte man noch Indy umbauen, und die OpenSLL Funktion "int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)" implementieren, aber da fehlt mir gerade jegliche Motivation :x

Ist immer wieder das gleiche, 98% fertig, 2% brauchen 98% Zeit.
Viele Grüße
AlterPascaler

Benutzeravatar
AlterPascaler
Beiträge: 87
Registriert: Mo 26. Jun 2023, 18:56
OS, Lazarus, FPC: Linux, Lazarus, Free Pascal
CPU-Target: xxBit
Wohnort: Deutschland, NRW

[gelöst] Indy, OpenSSL, Server Zertifikate prüfen,

Beitrag von AlterPascaler »

Es geht :) ,
mit einer kleinen Helper Klasse kann man Indy jetzt Root Zertifikate oder ein Root Zertifikateverzeichnis hinzufügen.
Ziel war es, die Änderung so zu implementieren, das man die original Indy Dateien nicht verändert.

Und so geht's
  1. Die Datei tb_indy_cert_helper.pas mit in die uses Klausel mit aufnehmen.
  2. In dem Ereignis "IOHandlerSocketOpenSSLStatus" folgenden Code einfügen.

    Code: Alles auswählen

    procedure TFHttp.IOHandlerSocketOpenSSLStatus(ASender: TObject;
      const AStatus: TIdStatus; const AStatusText: string);
    begin
      if IOHandlerSocketOpenSSL.Tag = 0 then begin
        //  Root Zertifikate hinzufügen
        //  StoreCertificatsPathE steckt in TIdSSLContextHelper
        IOHandlerSocketOpenSSL.SSLContext.StoreCertificatsPathE(
            GetCurrentDir + DirectorySeparator + 'certs');       
        // oder IOHandlerSocketOpenSSL.SSLContext.StoreCertificatE(
        //   'Oder eine Zertifikat- Datei');
        
        //  Nur einmal im Status Event.
        //  "Tag" wird in "IOHandlerSocketOpenSSLVerifyPeer" auf 0 gesetzt
        IOHandlerSocketOpenSSL.Tag:= 1;
      end;
    end;
    
  3. In dem Ereignis "IOHandlerSocketOpenSSLVerifyPeer" folgenden Code einfügen.

    Code: Alles auswählen

    function TFHttp.IOHandlerSocketOpenSSLVerifyPeer(Certificate: TIdX509;
      AOk: Boolean; ADepth, AError: Integer): Boolean;
    begin
      Result:= AOk;
      IOHandlerSocketOpenSSL.Tag:= 0;
    end; 
    
Wichtig ist, das man "IOHandlerSocketOpenSSL.Tag" nicht anderweitig verwendet.

Getestet habe ich das für 64Bit Linux und Windows.
Siehe http-demo

Grüße
AlterPascaler
Dateianhänge
http-demo-win64-x86_64.zip
(1.21 MiB) 42-mal heruntergeladen
http-demo-linux-x86_64.zip
(1.37 MiB) 39-mal heruntergeladen
Viele Grüße
AlterPascaler

Benutzeravatar
AlterPascaler
Beiträge: 87
Registriert: Mo 26. Jun 2023, 18:56
OS, Lazarus, FPC: Linux, Lazarus, Free Pascal
CPU-Target: xxBit
Wohnort: Deutschland, NRW

[update] Indy, OpenSSL, Server Zertifikate prüfen,

Beitrag von AlterPascaler »

Hallo,

habe es noch ein wenig erweitert. Geht jetzt ohne das verwenden einer "Tag" variablen.

Und so geht's
  1. Die Datei tb_indy_cert_helper.pas mit in die uses Klausel mit aufnehmen.
  2. In dem Ereignis "IOHandlerSocketOpenSSLStatus" folgenden Code einfügen.

    Code: Alles auswählen

    
    procedure TFHttp.IOHandlerSocketOpenSSLStatus(ASender: TObject;
      const AStatus: TIdStatus; const AStatusText: string);
    begin
      if IOHandlerSocketOpenSSL.SSLContext.SslContextAvailable
      and (not IOHandlerSocketOpenSSL.SSLContext.CertsStoredE) then begin
        //  Root Zertifikate, wenn nicht vorhanden, hinzufügen
        //  StoreCertificatsPathE steckt in TIdSSLContextHelper
        IOHandlerSocketOpenSSL.SSLContext.StoreCertificatsPathE(
            GetCurrentDir + DirectorySeparator + 'certs');
      end;
    end;
    
    
Getestet habe ich das für 64Bit Linux und Windows.

Grüße vom
AltenPascaler
Dateianhänge
http-demo-win-linux-x86_64.zip
(2.44 MiB) 43-mal heruntergeladen
Viele Grüße
AlterPascaler

Benutzeravatar
AlterPascaler
Beiträge: 87
Registriert: Mo 26. Jun 2023, 18:56
OS, Lazarus, FPC: Linux, Lazarus, Free Pascal
CPU-Target: xxBit
Wohnort: Deutschland, NRW

Re: [gelöst] Indy, OpenSSL, Server Zertifikate prüfen,

Beitrag von AlterPascaler »

Update:

Ich aktualisiere das Thema nochmal, damit es vielleicht von irgend jemanden gefunden wird, der das gleiche Problem hat.

Das kleine Projekt mit dem ihr RootCAs Indy OpenSSLSockets hinzufügen könnt findet ihr hier: https://gitlab.com/FpTuxe/tbindycerthelper
Viele Grüße
AlterPascaler

Antworten