Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Indy & OpenSSL 1.1.1 & TLS 1.3 (https://www.delphipraxis.net/204185-indy-openssl-1-1-1-tls-1-3-a.html)

mezen 4. Mai 2020 11:14

Indy & OpenSSL 1.1.1 & TLS 1.3
 
Hi,

als ihr den Titel gelesen habt, habt ihr bestimmt bereits die Standard-Antwort im Kopf gehabt: "Geht mit Indy nicht, unterstützt nur maximal OpenSSL 1.0.2 und damit kein TLS 1.3".
Da kann ich euch beruhigen, darum geht es mir nicht. Bzw. eigentlich sogar genauer: Genau darum geht es mir ;-)

Ich hab jetzt "ein bissl" Zeit darin investiert die Indy Unterstützung für OpenSSL 1.1.1 zu schreiben und damit TLS 1.3. Dafür gibt auch einen Push Request zu Indy hin: #299. Gleichzeitig hab ich ein paar Issues, welche bei GitHub hinterlegt worden sind gleich mit gefixt (stehe im PR drin).

Dazu habe ich 2 neue IO Handler geschrieben (einmal Server und einmal Client), die bisherigen sind unverändert um keine Konflikte zu verursachen.
Geschrieben und getestet wurde alles in Delphi Berlin 10.1.2 auf Win32 und Win64. Ich hab weder macOS noch iOS noch Linux noch Android, noch FreePascal, noch ältere (bzw neuere) Delphi Versionen. Ich hab zwar versucht ältere Delphi Versionen im Hinterkopf zu behalten, damit es darauf auch läuft, allerdings gabs dazu noch keine Tests meinerseits.
Getestet habe ich es ausgiebig in kleinen Test Anwendungen auch mit anderen Servern/Clients. Zusätzlich hab ich in ein großes Real World Programm, mit TCP Server/Client, SMTP/IMAP/POP Clients, FTP Client, HTTP Client, eingebaut und auch dort lief es problemlos.

Leider hat der nette Herr, welcher bisher unter indy.fulgan.com neue Binär Dateien von OpenSSL zur Verfügung gestellt hat, gesagt dass er keine Versionen > 1.0.2 mehr anbietet. Daher habe ich anfangs die Versionen von slWebPro genutzt (funktionieren sogar noch auf WinXP), später dann die von Overbyte, da diese ohne externe Abhängigkeiten auskommen (und digital signiert sind, aber kein XP mehr^^). Aber beide haben problemlos funktioniert.

Alle Dateien befinden sich im Unterordner "Lib/Protocols/OpenSSL". Dort befinden sich auch Unterordner "static" und "dynamic" welche ziemlich umfangreiche Imports der OpenSSL API bietet, einmal für statische Verlinkung, einmal zum dynamischen Laden/Entladen. Fürs dynamische Laden gibt es auch in der "IdOpenSSLLoader.pas" Möglichkeiten das Laden/Entladen selbst anzutriggern, falls man die API mal außerhalb des IO Handlers benötigt (z.B. für eigene x509 Generierungen).
Um mir das doppelte Schreiben der Imports zu sparen, habe ich im Ordner "Intermediate" eine Art von ZwischenCode geschrieben, welche ich dann mit "GenerateCode" zu den beiden Varianten generieren lasse. Das Tool "GenerateCode" ist nur simples String Anpassen und tatsächlich auch nur auf Berlin ausgelegt, da hab ich mir keine Mühe für abwärts Kompatibilität gemacht. Als normaler Benutzer der IO Handler braucht man diese auch nicht, erst wenn man Änderungen an der API Implementierung vor nimmt.


So und jetzt kommt ihr. Es wäre schön wenn der ein oder andere dies mal testen würde, damit es nicht nur WOMM zertifiziert ist, sondern mehr Echt-Situationen durchsteht.
Bei mir läuft es auch mit dem Indy, welches bei Delphi Berlin mitgeliefert wird, wenn ich eine weitere Unit erstelle, welche ein paar neue Indy Typen und Funktionen zur Verfügung stellt. Natürlich müssen dann ein paar Units lokal angepasst werden, damit diese die neue Unit usen.

MfG
mezen

DieDolly 4. Mai 2020 11:51

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Erstmal danke für deine Arbeit, die der zukünftigen Sicherheit dient.

Zitat:

Leider hat der nette Herr, welcher bisher unter indy.fulgan.com neue Binär Dateien von OpenSSL zur Verfügung gestellt hat, gesagt dass er keine Versionen > 1.0.2 mehr anbietet.
Wie ist das zu verstehen? Wird es mal keine aktuellen ssl-dll-Dateien mehr geben?
Ich benutze bisher immer libeay32.dll und ssleay32.dll. Welche muss man denn jetzt von overhead nutzen?

mezen 4. Mai 2020 12:03

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Er würde neuere OpenSSL 1.0.2 Dateien vermutlich dort eintragen, wenn OpenSSL neue Versionen erstellen würde. Alles mit "würde", weil OpenSSL gesagt hat, dass 1.0.2 End of Life erreicht hat und nicht mehr weiter gepflegt wird.
Für OpenSSL 1.1.1 müsste er seine Build Umgebung und Prozess umbauen, was einiges an Aufwand in Anspruch nehmen würde. Daher keine neueren Versionszweige als 1.0.2.

DieDolly 4. Mai 2020 12:20

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Das habe ich noch immer nicht richtig verstanden.
Was bedeutet das in normaler, deutscher Sprache für die Zukunft und Delphi? :P

mezen 4. Mai 2020 12:23

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Ok, kurz und in verständlicher Sprache: OpenSSL 1.0.2 End of Life (= tot), gibt keine Updates mehr. Sollte da eine Sicherheitslücke drin sein, wird diese nicht mehr gefixt.
(Außer OpenSSL sagt "Uh, da war sowas gravierendes drin, da könnten wir nochmal was für das uralte, und schon angeschimmelte, 1.0.2 was machen, weil das noch so viele nutzen)

DieDolly 4. Mai 2020 12:26

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Ach so ok. Und alles neuere wird fulgan nicht mehr unterstützen. Deswegen jetzt deine Umsetzung.
Wie kommt Indy denn dann mit den neuen DLLs klar denn die heißen doch bestimmt anders als die von fulgan.
Ich würde das sehr gerne testen aber habe keine Ahnung wie.

Hobbycoder 4. Mai 2020 19:11

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Erst mal ein fettes RESPEKT !!!

Wo könnte man sich denn deine neuen Bibliotheken herunterladen?

mezen 4. Mai 2020 20:15

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Über den PR kommst du auf diesen GitHub Fork: https://github.com/mezen/Indy/tree/NewOpenSSL_PR

TurboMagic 4. Mai 2020 20:20

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Zitat:

Zitat von DieDolly (Beitrag 1463595)
Ach so ok. Und alles neuere wird fulgan nicht mehr unterstützen. Deswegen jetzt deine Umsetzung.
Wie kommt Indy denn dann mit den neuen DLLs klar denn die heißen doch bestimmt anders als die von fulgan.
Ich würde das sehr gerne testen aber habe keine Ahnung wie.

Ich kenne diese angesprochene Person sogar persönlich, diese war der vorhergehende Maintainer der DEC Bibliothek, ist als Freelancer aber scheinbar so total ausgebucht und das derzeit leider nicht mehr mit Delphi Projekten, dass an andere Open Source Projekte scheinbar nicht mehr zu denken ist.

Er war früher auch hier im Forum unterwegs und hat auch mit diese OpenSSL Sache schon mal erklärt.
Aber wenn die OpenSSL Bibliotheken von ICS gut Funktionieren wäre das auch eine Lösung.

Da derzeit Delphi 10.4 in Entwicklung ist, wäre es super, wenn dieser Pull Request zeitnah in Indy einfließen könnte und EMBT dann gleich diese Fassung ausliefern würde.

Aber auch von mir: super, dass das umgesetzt wurde!

DieDolly 4. Mai 2020 20:25

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Zitat:

Da derzeit Delphi 10.4 in Entwicklung ist, wäre es super, wenn dieser Pull Request zeitnah in Indy einfließen könnte und EMBT dann gleich diese Fassung ausliefern würde.
Ich denke das kannst du gleich wieder streichen. Wenn du Gründe suchst, einfach das hier durchlesen https://www.delphipraxis.net/203977-...ml#post1463330

Ich habe trotzdem noch nicht verstanden, wie man diese angeblichen Änderungen denn jetzt nutzt und welche neue DLL man nutzen soll. Und wie überhaupt die funktionieren soll, wenn die einen anderen Dateinamen hat als die von fulgan,

mezen 5. Mai 2020 06:27

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Zitat:

Zitat von DieDolly (Beitrag 1463667)
Ich habe trotzdem noch nicht verstanden, wie man diese angeblichen Änderungen denn jetzt nutzt und welche neue DLL man nutzen soll. Und wie überhaupt die funktionieren soll, wenn die einen anderen Dateinamen hat als die von fulgan,

Du lädst dir den Code aus https://github.com/mezen/Indy/tree/NewOpenSSL_PR herunter und installierst ihn, dazu verwendest du das ganz normalen Indy Vorgehen http://ww2.indyproject.org/Sockets/D...lation.EN.aspx
Alternativ lädst du nur diesen Ordner https://github.com/mezen/Indy/tree/N...tocols/OpenSSL und nutzt dann das von EMBT mit gelieferte Indy. Je nach Delphi Version wirst du aber ein paar mehr oder ein paar weniger Typen fehlen, welche du selbst in einer neuen Unit anlegen musst und diese neue Unit muss an einigen Stellen dann ins uses hinzugefügt werden.

Anschließend sind deine Einstiegspunkte in https://github.com/mezen/Indy/blob/N...dlerClient.pas (für Clients) oder https://github.com/mezen/Indy/blob/N...dlerServer.pas (für Server). Dies sind ganz normale Indy IO Handler, welche du an deine Indy Komponenten zuweist.
Du benötigst für die Benutzung OpenSSL 1.1.1 Binaries. Ob du fertig kompilierte von slWebPro oder Overbytes (siehe Link im Eingangspost) oder von wem anders oder sogar selbst kompilierst, ist dabei egal.
Ja, die DLLs haben anderen Namen als die vom Fulgan (https://github.com/mezen/Indy/blob/N...nSSLConsts.pas). Das funktioniert deswegen, weil dieser IO Handler nichts mit dem alten existierenden IO Handler zu tun haben.

Hobbycoder 5. Mai 2020 13:09

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Zitat:

Zitat von DieDolly (Beitrag 1463667)
..., wie man diese angeblichen Änderungen denn jetzt nutzt ...

:shock::shock: Ich glaube nicht, dass die Änderungen nur "angeblich" sind

mezen 5. Mai 2020 13:35

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Zitat:

Zitat von Hobbycoder (Beitrag 1463710)
Zitat:

Zitat von DieDolly (Beitrag 1463667)
..., wie man diese angeblichen Änderungen denn jetzt nutzt ...

:shock::shock: Ich glaube nicht, dass die Änderungen "angeblich"

Laut dem PR sind es ja nur 242 Dateien mit insgesamt 87.372 Zeilen, aber wer zählt da schon mit?

Ok, fairer weise muss man sagen, dass da einiges an API Übersetzungen sind und die durch dynamisch und statisch (und Zwischencode) dreimal drin sind :-D

DieDolly 5. Mai 2020 17:45

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Klingt irgendwie alles viel zu kompliziert. Da warte ich lieber, bis das in Delphi selbst drin ist und fulgan oder irgendjemand die DLLs anpasst.

slemke76 6. Mai 2020 07:51

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Guten Morgen,

allergrößten Respekt vor deiner Arbeit! Das war sicherlich nicht ohne.

Grüße
Sebastian

Daniel 6. Mai 2020 07:55

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Zitat:

Zitat von DieDolly (Beitrag 1463667)
Zitat:

Da derzeit Delphi 10.4 in Entwicklung ist, wäre es super, wenn dieser Pull Request zeitnah in Indy einfließen könnte und EMBT dann gleich diese Fassung ausliefern würde.
Ich denke das kannst du gleich wieder streichen. [...]

Nein, ich kann nicht verstehen, warum solche vorschnellen Aussagen ohne jede Wissens-Grundlage getroffen werden. Für 10.4 mag es zu spät kommen, aber ich weiß von allen Beteiligten, dass sie das auf dem Radar haben.

TurboMagic 7. Mai 2020 22:48

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Ja, es haben definitiv alle auf dem Radar, nur muss dazu zuerst Remy Lebeau die Zeit zu finden den Pull Requerstm zu prüfen. Wenn der den für gut befindet wird der in Indy aufgnommen. Vorher ist von EMBT Seite verständlicherweise nix drin.

Kostas 3. Jul 2020 15:06

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Auch von mir den allergrößten Respekt vor deiner Arbeit!

Sorry jetzt kommen ein paar möglicherweise Dumme Frage da ich das Konzept nicht verstanden habe.

Ich habe ein Project indem ich get Anfragen über https durchführe. Der Server wurde aktualisiert und ich jetzt bekomme ich die Fehlermeldung Socket-Fehler # 10054 Die Verbindung wurde vom Peer getrennt. Ich vermute das hängt damit zusammen.

Ich würde jetzt gerne deine Komponente verwenden.
Ich habe Delphi 10.3.2 muss ich indy deinstallieren? wenn ja, wie da es in Delphi integriert ist und nicht über GetIt installiert wurde.

Für die Installation deiner Komponenten, habe ich das richtig verstanden dass Du das gesamte Indy10 Paket hergenommen hast und deine Komponenten integriert hast? Alle Komponenten die ich installiere, legen ich ab unter c:\Komponenten kann ich deinen Ordner unterhalb meinen platzieren c:\Komponenten\Indy-NewOpenSSL_PR oder muss er in den jetzigen Indy Ordner?

Nochals Sorry, aber ich habe es eben nicht verstanden.


Edit:
Ich habe jetzt versucht Indy nach Anleitung zu deinstallieren. Vermutlich habe ich nicht alles erwischt und hoffentlich habe ich nicht benötigte Files gelöscht, wird sich noch zeigen. Danach soll FullD#.bat ausgeführt werden. In den Sources ist alllerdings nur Fullc_Rio.bat enthalten. Für Delphi gibt es Fulld_5.bat bis FullD_2009.bat

Wie soll ich jetzt vorgehen?

mezen 4. Jul 2020 15:53

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Falls du ein aktuelles Indy installieren willst, dafür gibts diese Anleitung: http://ww2.indyproject.org/Sockets/D...lation.EN.aspx

Falls du nur den neuen OpenSSL IO Handler von mir ausprobieren willst, brauchst du theoretisch dafür keine komplette Neuinstallation von Indy. Tatsächlich hab ich es mit Stock Delphi Berlin entwickelt. Einfach die neuen Units ins uses aufnehmen. Allerdings wirst du dann leichte Anpassungen machen müssen, da dir neue Typen fehlen, welche mit dem neuen Indy kommen. Diese kann man aber einfach selbst definieren.

Kostas 5. Jul 2020 08:57

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Zitat:

Zitat von mezen (Beitrag 1468836)
Falls du ein aktuelles Indy installieren willst, dafür gibts diese Anleitung: http://ww2.indyproject.org/Sockets/D...lation.EN.aspx

...

Hi, genau nach dieser Anleitung bin ich vorgegangen, allerdings habe ich NICHT die Indy sources verwenden. Ich habe nach Anleitung versucht Indy zu deinstallieren und dann wollte ich aus deinem github indy unter c:\Komponenten\Indy installieren. Allerdings fehlt hier die FullD#.bat für Rio. Ich würde gerne deine Indy Variante einsetzen. Wie müsste ich bitte dafür vorgehen? Mit Komponentenentwicklung habe ich mich nicht beschäftigt. Ich wende Sie nur an. :-)

Kostas 5. Jul 2020 09:56

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Oh, ich glaube ich habe es "fast" geschafft.

Ich bin so vorgegangen:
- /Lib/Fullc_Rio.bat ausgeführt, am Ende ist der Hinweis erschienen: keine Fehler.
- Öffne IndySystem260.dpk, natürlich jede Menge Fehler Package kann nicht geladen werden. Beim nächsten Start neu laden alles mit Ja bestätigt.
IndySystem260.dpk konnte ohne Fehler erzeugt werden.
- dclIndyCore260.dpk wollte ich erzeugen und bekommen die Meldung IndyCore260.res nicht gefunden. Die Datei gibt es unter
\Indy-NewOpenSSL_PR\C26\Win32\Release. Der Order \C26\ wurde durch die .bat erzeugt. Ich habe den Pfad in die Bibliothek aufgenommen und konnte dann Fehlerfrei erzeugen.
- dclIndyProtocols260.dpk Fehlerfrei erzeugen und installieren können.
- dclIndyCore260.dpk Fehlerfrei erzeugen und installieren können.
- dclIndyProtocols260.dpk Fehlerfrei erzeugen und installieren können.
- Delphi neu gestartet und bekomme keine Fehler mehr. Scheint soweit funktioniert zu haben.

Deine zusätzlichen SSLIOHandler finde ich nicht. Wie muss ich diese bitte installieren?

mezen 5. Jul 2020 11:08

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Für die IO Handler gibt es noch keine Design Time Komponenten. Einfach mit ins uses aufnehmen, und selber instantiieren.

Kostas 5. Jul 2020 11:37

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
auf die Gefahr hin dass du mich jetzt steinigst,
auf meine Form habe ich ein TIdHTTP und ein TIdSSLIOHandlerSocketOpenSSL.
Ich nehme an, ich muss nur IdHTTP.IOHandler abhängen von IdSSLIOHandlerSocketOpenSSL und dafür deine Variante einbinden.
Welche Unit sollte ich dafür usen und welche Komponenten müsste ich bitte instantiieren und dem IdHTTP.IOHandler zuweisen?
Die DLLs libssl-1_1-x64.dll und libcrypto-1_1-x64.dll habe ich bereits von ICS abgerufen und in Programm Root kopiert.

mezen 5. Jul 2020 13:15

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Aus der IdOpenSSLIOHandlerClient.pas den TIdOpenSSLIOHandlerClient für Clients, bzw aus der IdOpenSSLIOHandlerServer.pas den TIdOpenSSLIOHandlerServer für Server.

Kostas 5. Jul 2020 14:52

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Hast du mir bitte noch ein Hinweis was ich alles in dem Bibliothekspfad aufnehmen muss, es hört gar nicht auf, da stimmt etwas nicht.
C:\Komponenten\Indy-NewOpenSSL_PR\C26\Win32\Release
C:\Komponenten\Indy-NewOpenSSL_PR\Lib\Protocols\OpenSSL
C:\Komponenten\Indy-NewOpenSSL_PR\Lib\Protocols
...

Aktuell wird TIdLibHandle in IdSSLOpenSSLHeaders vermisst.

mezen 6. Jul 2020 16:07

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Für meine Änderungen sind nur folgende Pfade notwendig:

C:\Komponenten\Indy-NewOpenSSL_PR\Lib\Protocols\OpenSSL
C:\Komponenten\Indy-NewOpenSSL_PR\Lib\Protocols\OpenSSL\dynamic bzw C:\Komponenten\Indy-NewOpenSSL_PR\Lib\Protocols\OpenSSL\static je nachdem ob du mit dynamischen Laden der DLL (
Delphi-Quellcode:
LoadLibrary
etc) oder statischem Linken gegen die DLLs (
Delphi-Quellcode:
procedure Foo; external 'MyDll.dll';
) arbeitest.

Indy hat dafür die Compiler Directive STATICLOAD_OPENSSL. Wenn ich mich richtig erinnere, ist dies etwas was bei der Installation von Indy bestimmt wurde. Du kannst beispielhaft mal in IdOpenSSLLoader.pas gucken, ohne STATICLOAD_OPENSSL ist die Unit quasi leer.

Die restlichen Pfade haben mit der Indy Installation zu tun und sich unabhängig von meinen Änderungen.

Kostas 6. Jul 2020 17:11

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Ich habe in den Bibliothekspfad von Delphi alle Pfade gelöscht und folgende hinzugefügt:
Delphi-Quellcode:
C:\Komponenten\Indy-NewOpenSSL_PR\Lib\Protocols\OpenSSL
C:\Komponenten\Indy-NewOpenSSL_PR\Lib\Protocols\OpenSSL\dynamic
C:\Komponenten\Indy-NewOpenSSL_PR\Lib\Protocols\OpenSSL\static
Da ich nicht weis was verwendet wird habe ich dynamic und static aufgenommen.
In meiner Form unter uses habe ich IdOpenSSLLoader aufgenommen und mit Strg+Enter die Datei geöffnet. Sie ist nicht leer und hat 349 Zeilen.

Auf der Form habe ich eine TIdHTTP Komponente.
Delphi-Quellcode:
uses IdOpenSSLIOHandlerClient, IdOpenSSLLoader;

//das wollte ich ausführen.
procedure TfrMain.Button1Click(Sender: TObject);
var IdOpenSSLIOHandlerClient :TIdOpenSSLIOHandlerClient;
begin
  IdOpenSSLIOHandlerClient.Create;
  try
    IdOpenSSLIOHandlerClient.SSLOptions.Method := sslvTLSv1_3;
    IdHTTP1.IOHandler := IdOpenSSLIOHandlerClient;
    LoadHistoryFile(ed.Text);
  finally
    IdHTTP1.IOHandler := nil;
    IdOpenSSLIOHandlerClient.Free;
  end;
end;
Wenn ich so versuche zu kompilieren, wird die Datei IdOpenSSLIOHandlerClient geöffnet und {$i IdCompilerDefines.inc} wurde nicht gefunden angezeigt.
Ich habe danach gesucht und gefunden unter:
C:\Komponenten\Indy-NewOpenSSL_PR\Lib\System
C:\Komponenten\Indy-NewOpenSSL_PR\Lib\SuperCode
C:\Komponenten\Indy-NewOpenSSL_PR\Lib\Protocols
C:\Komponenten\Indy-NewOpenSSL_PR\Lib\FCL
C:\Komponenten\Indy-NewOpenSSL_PR\Lib\Core

also habe ich C:\Komponenten\Indy-NewOpenSSL_PR\Lib\Protocols in den Bibliothekspfad aufgenommen und neu kompiliert. Dann bleibt er stehen bei
IdSSLOpenSSLHeaders und vermisst TIdLibHandle;

dschiffler 28. Nov 2020 11:36

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Hallo mezen,

erst einmal auch von mir ein großes Danke schön und Respekt für deine Arbeit.
Hoffentlich fließt deine Arbeit irgenwann auch in die Indy-Version von Delphi ein. :-D

Nun zu meinem Problem:
Ich habe eine Software die sich per SSL/TLS mit einem Webserver verbindet, den wir selbst in der Verwaltung haben. Auf dem Webserver ist ein Zertifikat installiert. Beim Verbindungsaufbau zum Webserver überprüft die Software den Fingerprint des Server-Zertifikats, um sicherzustellen, dass die Verbindung zum richtigen Webserver erfolgt.
Umgesetzt ist dies mit Indy 10 von Delphi 10.3 und funktioniert einwandfrei.

Hier der relevante Code-Ausschnitt dazu (FHttpClient ist eine Instanz von TIdHttp):
Delphi-Quellcode:
var
  lHandler: TIdSSLIOHandlerSocketOpenSSL;
begin
  FHttpClient.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(FHttpClient);

  lHandler := TIdSSLIOHandlerSocketOpenSSL(FHttpClient.IOHandler);
  lHandler.SSLOptions.Mode := sslmClient;
  lHandler.SSLOptions.VerifyMode := [sslvrfPeer];
  lHandler.OnVerifyPeer := DoVerifyPeer;
end;
Die Signatur von DoVerifyPeer ist folgende:
Code:
function DoVerifyPeer(ACertificate: TIdX509; AOk: Boolean; ADepth, AError: Integer): Boolean;
Mit dem Parameter ACertificate bekommt man Zugriff auf die Zertifikat-Informationen/-Eigenschaften und ich kann in DoVerifyPeer dann folgendes machen:
Delphi-Quellcode:
var
  sFingerprint: string
begin
  sFingerprint := ACertificate.Fingerprints.SHA1AsString;
  Result := <Vergleich mit dem erwarteten Fingerprint>
end
Im Getter von SHA1AsString wird folgendes aufgerufen:
Code:
Result := MDAsString(SHA1);
In der Funktion MDAsString wird lediglich die Rückgabe von SHA1 als Hex-Zahlen mit Doppelpunkt getrennt formatiert (was nicht weiter wichtig ist), denn das Entscheidende passiert in der Funktion SHA1, nämlich der Aufuf von X509_digest, was ja eine Funktion aus den OpenSSL-DLLs ist:
Delphi-Quellcode:
begin
  X509_digest(FX509, EVP_sha1, PByte(@Result.MD), Result.Length);
end

Wenn ich jetzt deinen OpenSSL-Client benutze (damit ich auch TLS 1.3 unterstützen kann), sieht die Implementierung so aus:
Delphi-Quellcode:
var
  lHandler: TIdOpenSSLIOHandlerClient;
begin
  FHttpClient.IOHandler := TIdOpenSSLIOHandlerClient.Create(FHttpClient);

  lHandler := TIdOpenSSLIOHandlerClient(FHttpClient.IOHandler);
  lHandler.Options.CipherList  := IdOpenSSLHeaders_ssl.SSL_DEFAULT_CIPHER_LIST;
  lHandler.Options.CipherSuites := IdOpenSSLHeaders_ssl.TLS_DEFAULT_CIPHERSUITES;
  lHandler.Options.UseServerCipherPreferences := False;
  lHandler.Options.VerifyServerCertificate := True;
  lHandler.Options.OnVerify := DoVerifyPeer;
end;
Die Signatur von DoVerifyPeer ist hier folgende:
Code:
procedure DoVerifyPeer(ASender: TObject; const ACertificate: TIdOpenSSLX509;
  const VerifyResult, Depth: Integer; var Accepted: Boolean);
Auch hier kann ich mit dem Parameter ACertificate auf die Zertifikat-Informationen/-Eigenschaften zugreifen und in DoVerifyPeer dann folgendes machen:
Delphi-Quellcode:
var
  sFingerprint: string
begin
  sFingerprint := ACertificate.ThumbprintAsSHA1;
  Accepted := <Vergleich mit dem erwarteten Fingerprint>
end
Im Getter von ThumbprintAsSHA1 wird folgndes aufgerufen:
Code:
Result := GetInternalThumbprint(EVP_sha1());
Das Entscheidende hier ist auch der Aufruf der Funktion X509_digest in der Methode GetInternalThumbprint:
Delphi-Quellcode:
var
  LBuffer: array[0 .. EVP_MAX_MD_SIZE -1] of Byte;
  LByteCount: TIdC_UINT;
  i: Integer;
begin
  Result := '';
  LByteCount := EVP_MAX_MD_SIZE;
  if X509_digest(FX509, md, @LBuffer, @LByteCount) = 1 then
  begin
    for i := 0 to LByteCount - 1 do
      Result := Result + ByteToHex(LBuffer[i]);
  end;
end;
Nach meinem Verständnis sollte doch hier die gleiche Bytefolge (also der Fingerprint des Server-Zertifikats) zurückkommen?
Das passiert aber nicht, denn die Bytefolge ist eine vollkommen andere.

Habe ich bei der Konfiguration des IO-Handlers etwas falsch gemacht oder vergessen oder wo liegt der Fehler?
Ich hoffe, dass der Fehler nicht in den OpenSSL-DLLs liegt?

mezen 28. Nov 2020 12:26

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Es sollte das selbe rauskommen. Ich kann das leider erst am Dienstag in der Firma mir detaillierter anschauen. Bei meinen Tests kam damals da aber der selbe SHA1 Wert raus als wenn ich mir das Zert direkt angeschaut habe.

Bedenke aber bitte, dass das OnVerifyPeer pro Zertifikat aufgerufen wird, welches der Server zurück schickt. Sollte der Server mehrere zurückschicken (z.B. sein Server Zert plus ein Intermediate Zert), dann wird die Funktion mehrmals aufgerufen.

Wenn dir das erwartete Zertifikat aber bekannt ist, gib es besser direkt als Datei an, anstatt im OnVerifyPeer den Thumbprint zu vergleichen.
Überlass damit besser die Zertifikats Validierung komplett OpenSSL, da genug Leute sagen, dass der gefährlichste selbst geschriebene Code eine eigene Zertifikats Validierung ist.

dschiffler 29. Nov 2020 20:12

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Hallo mezen,

danke für deine Antwort. Dann warte ich, bis du deine Überprüfung abgeschlossen hast. :-D

Zu deinen Bemerkungen:
Das Ereignis OnVerifyPeer wird in meinem Fall nur einmal aufgerufen, denn auf dem Webserver ist definitiv nur ein Zertifikat installiert. Wie gesagt, mit Indy 10 unter Delphi 10.3.x läuft ja alles wunschgemäß. Wenn ich jetzt also lediglich den SSL-IO-Handler von Indy auf deinen wechsle und anschließend kommt eine andere Bytefolge als Fingerprint zurück, liegt ja zumindest der Verdacht nahe, dass entweder in deinen Implementierungen oder aber in den neuen SSL-Bibliotheken etwas anders als in den Indy-Komponenten und den bisherigen SSL-Bibliotheken ist.

Dein Hinweis, die Überpüfung des Zertifikats OpenSSL zu überlassen, ist interessant.
In deinen SSL-Options gibt es ja die Properties CertFile und CertKey. Laut deiner Doku dazu muss hier ein Verzeichnis angegeben werden, in dem sogenannte pem-Dateien liegen müssen.
Dazu 3 Fragen:
  • Müssen beide Properties gesetzt sein oder reicht CertFile?
  • Wo bzw. von wem bekomme ich denn diese pem-Dateien und was beinhalten diese?
  • Wie läuft denn dann die Validierung des Zertifikats ab oder besser gesagt, wie bekomme ich die Info, ob die Validierung erfolgreich war oder nicht, so dass ich darauf entspr. reagieren kann?

hoika 30. Nov 2020 04:02

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Hallo,
das CertFile musst du dir meines Wissens separat vom Server holen.
Vielleicht stellt es der Server-Besitzer (also du selbst) über einen Download-Link zur Verfügung) ...
Das CetFile liegt dann also,Lokal,auf deiner Platte.

mezen 1. Dez 2020 10:08

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
So, ich hab mir das mal genauer angeguckt, wenn ich ein Cert mit dem TIdOpenSSLX509 von mir öffne (habs dafür noch ein SaveToFile und eine ctor Überladung mit einem Pfad hinzugefügt, werde das mal die Tage pushen), dann bekomme ich bei ThumbprintAsSHA1 genau das raus, was Windows einem in den Cert Details unter Thumbprint anzeigt.
Wenn das unterschiedlich zu dem alten IO Handler ist, ist dieser vllt nicht ganz korrekt gewesen?

Mein IO Handler bietet einmal FIOHandler.Options.VerifyCertificate oder alternativ FIOHandler.Options.VerifyCertDirectory. Du kannst eins von beiden, oder beide gleichzeitig nutzen. Grade beim letzteren ist OpenSSL allerdings ziemlich strict was die Benamung der Dateien angeht, da musste ich auch erst tüfteln bis ich eine funktionierende Variante heraus bekommen habe. Details stehen als XML Doc Kommentar über der Property (Der Teil mit "please look at OpenSSL documentation about "openssl verify -CApath""). Die Funktion ist perfekt darauf ausgelegt, wenn als VerifyCertDirectory ein Linux Cert Store angegeben wird.

mezen 1. Dez 2020 10:17

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Habs grade nochmal mit dem alten IO Handler ausprobiert: Da bekomme ich es exakt gleiche Ergebnis bei Certificate.Fingerprints.SHA1AsString raus (Ok, mein IO Handler packt keine : da rein^^).
Allerdings steht der Default von SSLOptions.VerifyDepth auf 0, daher würde er nur das Leaf-Cert prüfen und das OnVerifyPeer gar nicht mehrmals aufrufen.
Bei meinem IO Handler ist diese Option gar nicht mehr konfigurierbar und es wird der OpenSSL Standard Wert dafür genutzt (was 100 ist, siehe SSL_CTX_set_verify_depth )

dschiffler 1. Dez 2020 21:24

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Hallo mezen,

mit der Indy-Variante (also TIdSSLIOHandlerSocketOpenSSL) bekomme ich über Certificate.Fingerprints.SHA1AsString genau den gleichen Fingerprint wie er mir angezeigt wird, wenn ich die URL bspw. im Chrome eingebe und dann über das Schloßsysmbol auf das Zertifikat zugreife und in dem Dialog auf der Seite Details mir den Fingerprint ansehe. Die Indy-Variante funktioniert also wunschgemäß und ist auch bei unseren Kunden im produktiven Einsatz.

Mit deinem IO-Handler bekomme ich über Certificate.ThumbprintAsSHA1 eine andere Bytefolge als Fingerprint angezeigt und wenn die Eingenschaft VerifyDepth bei Indy auf 0 steht und du die zur Konfiguration nicht mehr anbietest und bei dir als Standardwert 100 benutzt wird, kann dieser Unterschied ja vielleicht die Ursache sein, oder? Ich würde sehr gerne für TLS 1.3 gewappnet sein und dafür ist deine Abeit und dein IO-Handler ja super, solange Indy noch kein TLS 1.3 unterstützt, aber dann muss ich beim Einsatz deines IO-Handlers natürlich das gleiche Ergebnis bekommen, sonst kann ich ihn ja nicht einsetzen. :cry:

Ich möchte noch einmal auf meine Fragen verweisen:
  • Müssen beide Properties (CertFile und CertKey) gesetzt sein oder reicht CertFile?
  • Wie läuft denn dann die Validierung des Zertifikats ab oder besser gesagt, wie bekomme ich die Info, ob die Validierung erfolgreich war oder nicht, so dass ich darauf entspr. reagieren kann?
Ich würde gerne die pem-Datei lediglich mit unserer Software ausliefern, sie in einem Verzeichnis ablegen und dann über CertFile angeben, so dass OpenSSL seine Validierung machen kann. Funktioniert das so?

dschiffler 2. Dez 2020 07:30

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Hallo mezen,

bzgl. des Fingerprints mache ich es mal etwas konkreter:

URL im Chrome eingegeben und über das Schloßsymbol links neben der URL mir die Zertifikatseigenschaften anzign lassen.
Fingerprint: f8 41 4f 2c ...

Im Programm mit Indy (TIdSSLIOHandlerSocketOpenSSL) und den OpenSSL-Bibliotheken libeay32.dll und ssleay32.dll in der Version 1.0.2.
Certificate.Fingerprints.SHA1AsString: F8:41:4F:2C ... (also der gleiche und erwartete Fingerprint des Zertifikats)

Im Programm mit deiner Implementierung (TIdOpenSSLIOHandlerClient) und den OpenSSL-Bibliotheken libcrypto-1_1.dll und libssl-1_1.dll in der Version 1.1.1.
Certificate.ThumbprintAsSHA1: 98 C6 A8 DC ... (eine andere Bytefolge :cry:)

Vielleicht hilft dir das ja irgendwie weiter, damit wir zusammen zu einer zufriedenstellenden Lösung kommen. :-)

mezen 8. Dez 2020 14:57

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Sorry, kam erst jetzt wieder dazu das weiter anzuschauen.

Folgender Code jeweils mit
Delphi-Quellcode:
HTTP1.Get('https://www.delphipraxis.net');
getestet.

Alter IO Handler:
Delphi-Quellcode:
function TForm1.IdSSLIOHandlerSocketOpenSSL1VerifyPeer(Certificate: TIdX509;
  AOk: Boolean; ADepth, AError: Integer): Boolean;
begin
  mmo1.Lines.Add('Depth: ' + ADepth.ToString());
  mmo1.Lines.Add('ErrorCode: ' + AError.ToString());
  mmo1.Lines.Add('Subject: ' + Certificate.Subject.OneLine);
  mmo1.Lines.Add('Thumbprint SHA1: ' + Certificate.Fingerprints.SHA1AsString);
  mmo1.Lines.Add('');
  Result := True;
end;
Code:
Depth: 0
ErrorCode: 20
Subject: /CN=*.delphipraxis.net
Thumbprint SHA1: 70:B1:AC:83:99:05:36:27:75:AE:7E:ED:92:5E:0F:A8:A0:0B:D0:52

Depth: 0
ErrorCode: 21
Subject: /CN=*.delphipraxis.net
Thumbprint SHA1: 70:B1:AC:83:99:05:36:27:75:AE:7E:ED:92:5E:0F:A8:A0:0B:D0:52
Neuer IO Handler:
Delphi-Quellcode:
procedure TForm1.HandleOnVerify(Sender: TObject; const x509: TIdOpenSSLX509;
  const VerifyResult, Depth: Integer; var Accepted: Boolean);
begin
  mmo1.Lines.Add('Depth: ' + Depth.ToString());
  mmo1.Lines.Add('ErrorCode: ' + VerifyResult.ToString());
  mmo1.Lines.Add('Subject: ' + x509.Subject.AsString);
  mmo1.Lines.Add('Thumbprint SHA1: ' + x509.ThumbprintAsSHA1);
  mmo1.Lines.Add('');
  Accepted := True;
end;
Code:
Depth: 2
ErrorCode: 19
Subject: /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root G2
Thumbprint SHA1: DF3C24F9BFD666761B268073FE06D1CC8D4F82A4

Depth: 2
ErrorCode: 19
Subject: /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root G2
Thumbprint SHA1: DF3C24F9BFD666761B268073FE06D1CC8D4F82A4

Depth: 1
ErrorCode: 19
Subject: /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=Thawte TLS RSA CA G1
Thumbprint SHA1: C9FEFC763D9548B487696F047ACBA0ABE45C7BC1

Depth: 0
ErrorCode: 19
Subject: /CN=*.delphipraxis.net
Thumbprint SHA1: 70B1AC839905362775AE7EED925E0FA8A00BD052
Wie du siehst ist bei Depth 0 der SHA1 Thumbprint identisch.

mezen 8. Dez 2020 15:01

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Und so sieht es aus, wenn man beim alten IO Handler mal das VerifyDepth hoch dreht:
Code:
Depth: 2
ErrorCode: 19
Subject: /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root G2
Thumbprint SHA1: DF:3C:24:F9:BF:D6:66:76:1B:26:80:73:FE:06:D1:CC:8D:4F:82:A4

Depth: 2
ErrorCode: 19
Subject: /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root G2
Thumbprint SHA1: DF:3C:24:F9:BF:D6:66:76:1B:26:80:73:FE:06:D1:CC:8D:4F:82:A4

Depth: 1
ErrorCode: 19
Subject: /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=Thawte TLS RSA CA G1
Thumbprint SHA1: C9:FE:FC:76:3D:95:48:B4:87:69:6F:04:7A:CB:A0:AB:E4:5C:7B:C1

Depth: 0
ErrorCode: 19
Subject: /CN=*.delphipraxis.net
Thumbprint SHA1: 70:B1:AC:83:99:05:36:27:75:AE:7E:ED:92:5E:0F:A8:A0:0B:D0:52

dschiffler 12. Dez 2020 17:14

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Hallo mezen,

ich habe deinen Test so bei mir mit meiner URL nachvollzogen und komme zu dem gleichen Ergebnis.
Der erwartete Fingerprint wird bei Depth = 0 zurückgegeben.
Somit können wir erst einmal feststellen, dass dein IO-Handler funktioniert. :-D

Ich habe dann offensichtlich im Verify-Ereignis etwas falsch gemacht und werde das jetzt analysieren. Dabei ist dein Hinweis, dass das Verify-Ereignis durchaus mehrmals ausgelöst werden kann, sehr hilfeich. Sollte ich bei dieser Überprüfungsvariante bleiben, darf ich also den Fingerprint erst bei Depth = 0 auswerten und überprüfen.

Ich bedanke mich schon einmal recht herzlich für deine Hilfe.

Kannst du mir zum Abschluss bitte noch ein Code-Beispiel geben, wie ich deinen Vorschlag, die Zertifikatsüberprüfung OpenSSL zu überlassen, umsetzen kann und die Nutzung von CertFile richtig gemacht wird?

THonscha 6. Mär 2021 15:26

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Weiß jemand, ob die neuen TLS Versionen auf Delphi 10.4.2 unterstützt werden?

Stevie 6. Mär 2021 16:15

AW: Indy & OpenSSL 1.1.1 & TLS 1.3
 
Nicht von Indy, von Komponenten wie TRestClient, der nicht auf Indy basiert schon.


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:21 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz