AGB  ·  Datenschutz  ·  Impressum  







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

Indy & OpenSSL 1.1.1 & TLS 1.3

Ein Thema von mezen · begonnen am 4. Mai 2020 · letzter Beitrag vom 25. Aug 2021
Antwort Antwort
Seite 3 von 5     123 45   
Kostas

Registriert seit: 14. Mai 2003
Ort: Gerstrhofen
901 Beiträge
 
Delphi 10 Seattle Enterprise
 
#21

AW: Indy & OpenSSL 1.1.1 & TLS 1.3

  Alt 5. Jul 2020, 10:56
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?

Geändert von Kostas ( 5. Jul 2020 um 10:59 Uhr)
  Mit Zitat antworten Zitat
mezen

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

AW: Indy & OpenSSL 1.1.1 & TLS 1.3

  Alt 5. Jul 2020, 12:08
Für die IO Handler gibt es noch keine Design Time Komponenten. Einfach mit ins uses aufnehmen, und selber instantiieren.
  Mit Zitat antworten Zitat
Kostas

Registriert seit: 14. Mai 2003
Ort: Gerstrhofen
901 Beiträge
 
Delphi 10 Seattle Enterprise
 
#23

AW: Indy & OpenSSL 1.1.1 & TLS 1.3

  Alt 5. Jul 2020, 12:37
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.
  Mit Zitat antworten Zitat
mezen

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

AW: Indy & OpenSSL 1.1.1 & TLS 1.3

  Alt 5. Jul 2020, 14:15
Aus der IdOpenSSLIOHandlerClient.pas den TIdOpenSSLIOHandlerClient für Clients, bzw aus der IdOpenSSLIOHandlerServer.pas den TIdOpenSSLIOHandlerServer für Server.
  Mit Zitat antworten Zitat
Kostas

Registriert seit: 14. Mai 2003
Ort: Gerstrhofen
901 Beiträge
 
Delphi 10 Seattle Enterprise
 
#25

AW: Indy & OpenSSL 1.1.1 & TLS 1.3

  Alt 5. Jul 2020, 15:52
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.
  Mit Zitat antworten Zitat
mezen

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

AW: Indy & OpenSSL 1.1.1 & TLS 1.3

  Alt 6. Jul 2020, 17:07
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 (LoadLibrary etc) oder statischem Linken gegen die DLLs (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.
  Mit Zitat antworten Zitat
Kostas

Registriert seit: 14. Mai 2003
Ort: Gerstrhofen
901 Beiträge
 
Delphi 10 Seattle Enterprise
 
#27

AW: Indy & OpenSSL 1.1.1 & TLS 1.3

  Alt 6. Jul 2020, 18:11
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;
  Mit Zitat antworten Zitat
dschiffler

Registriert seit: 25. Okt 2006
22 Beiträge
 
Delphi 10.3 Rio
 
#28

AW: Indy & OpenSSL 1.1.1 & TLS 1.3

  Alt 28. Nov 2020, 12: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
28 Beiträge
 
Delphi 10.1 Berlin Professional
 
#29

AW: Indy & OpenSSL 1.1.1 & TLS 1.3

  Alt 28. Nov 2020, 13: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
22 Beiträge
 
Delphi 10.3 Rio
 
#30

AW: Indy & OpenSSL 1.1.1 & TLS 1.3

  Alt 29. Nov 2020, 21: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
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 14:29 Uhr.
Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf