AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi Indy & OpenSSL 1.1.1 & TLS 1.3
Thema durchsuchen
Ansicht
Themen-Optionen

Indy & OpenSSL 1.1.1 & TLS 1.3

Ein Thema von mezen · begonnen am 4. Mai 2020 · letzter Beitrag vom 21. Nov 2022
Antwort Antwort
Seite 1 von 2  1 2      
mezen

Registriert seit: 13. Jul 2011
Ort: Lippstadt
30 Beiträge
 
Delphi 10.1 Berlin Professional
 
#1

Indy & OpenSSL 1.1.1 & TLS 1.3

  Alt 4. Mai 2020, 11:14
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
  Mit Zitat antworten Zitat
DieDolly

Registriert seit: 22. Jun 2018
2.175 Beiträge
 
#2

AW: Indy & OpenSSL 1.1.1 & TLS 1.3

  Alt 4. Mai 2020, 11:51
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?

Geändert von DieDolly ( 4. Mai 2020 um 11:53 Uhr)
  Mit Zitat antworten Zitat
mezen

Registriert seit: 13. Jul 2011
Ort: Lippstadt
30 Beiträge
 
Delphi 10.1 Berlin Professional
 
#3

AW: Indy & OpenSSL 1.1.1 & TLS 1.3

  Alt 4. Mai 2020, 12:03
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.
  Mit Zitat antworten Zitat
DieDolly

Registriert seit: 22. Jun 2018
2.175 Beiträge
 
#4

AW: Indy & OpenSSL 1.1.1 & TLS 1.3

  Alt 4. Mai 2020, 12:20
Das habe ich noch immer nicht richtig verstanden.
Was bedeutet das in normaler, deutscher Sprache für die Zukunft und Delphi?
  Mit Zitat antworten Zitat
mezen

Registriert seit: 13. Jul 2011
Ort: Lippstadt
30 Beiträge
 
Delphi 10.1 Berlin Professional
 
#5

AW: Indy & OpenSSL 1.1.1 & TLS 1.3

  Alt 4. Mai 2020, 12:23
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)
  Mit Zitat antworten Zitat
DieDolly

Registriert seit: 22. Jun 2018
2.175 Beiträge
 
#6

AW: Indy & OpenSSL 1.1.1 & TLS 1.3

  Alt 4. Mai 2020, 12:26
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.
  Mit Zitat antworten Zitat
dschiffler

Registriert seit: 25. Okt 2006
30 Beiträge
 
Delphi 10.4 Sydney
 
#7

AW: Indy & OpenSSL 1.1.1 & TLS 1.3

  Alt 28. Nov 2020, 11:36
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.

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?
Liebe Grüße
Dirk Schiffler
  Mit Zitat antworten Zitat
mezen

Registriert seit: 13. Jul 2011
Ort: Lippstadt
30 Beiträge
 
Delphi 10.1 Berlin Professional
 
#8

AW: Indy & OpenSSL 1.1.1 & TLS 1.3

  Alt 28. Nov 2020, 12:26
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.
  Mit Zitat antworten Zitat
dschiffler

Registriert seit: 25. Okt 2006
30 Beiträge
 
Delphi 10.4 Sydney
 
#9

AW: Indy & OpenSSL 1.1.1 & TLS 1.3

  Alt 29. Nov 2020, 20:12
Hallo mezen,

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

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?
Liebe Grüße
Dirk Schiffler
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.270 Beiträge
 
Delphi 10.4 Sydney
 
#10

AW: Indy & OpenSSL 1.1.1 & TLS 1.3

  Alt 30. Nov 2020, 04:02
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.
Heiko

Geändert von hoika (30. Nov 2020 um 04:40 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:20 Uhr.
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