![]() |
AW: Indy & OpenSSL 1.1.1 & TLS 1.3
Hallo,
zunächst möchte ich mich bedanken für die hier geleistete Arbeit :-) Aber auch gleich mit einem kleinen Problem um die Ecke kommen. Die Reaktion denn die OpenSSL DLL's nicht vorhanden sind - ist nicht so schön bei mir kommt es dann immer zu einer Schutzverletzung - im destructor der Klasse
Delphi-Quellcode:
Soweit ich durchdebuggt habe - ist die Aufrufkette folgende:
TIdOpenSSLContextClient
Delphi-Quellcode:
TIdTCPClientCustom.Connect( ) --> IOHandler := nil; (bedingt durch Exception) --> TIdTCPConnection.SetIOHandler --> IdDisposeAndNil(LIOHandler);
--> TIdOpenSSLIOHandlerClient.Destroy --> TIdOpenSSLContextClient.Destroy
Delphi-Quellcode:
Das Set IOhandler = nil führt dann zu:
TIdTCPClientCustom.Connect( )
try IOHandler.Open; --> Exception weil DLL's nicht verfügbar except if IOHandler <> nil then begin IOHandler.Close; if ManagedIOHandler then begin // Mein IOHandler ist ManagedIOHandler = true! (bedingt durch anderen Code zuvor) IOHandler := nil; // RLebeau - SetIOHandler() will free the IOHandler end; end; raise; end;
Delphi-Quellcode:
procedure TIdTCPConnection.SetIOHandler(AValue: TIdIOHandler);
if ManagedIOHandler then begin if Assigned(LIOHandler) then begin FIOHandler := nil; -- Zugriffsfehler im Destructor des IOHandlers IdDisposeAndNil(LIOHandler); end; ManagedIOHandler := False; end;
Delphi-Quellcode:
destructor TIdOpenSSLIOHandlerClient.Destroy;
FContext.Free(); --> Zugriffsfehler
Delphi-Quellcode:
Meine Lösung sieht jetzt so aus ich ändere die Routine:
destructor TIdOpenSSLContextClient.Destroy;
OpenSSLContext ist hier noch nil und die Methoden / Funktionszeiger -> SSL_CTX_sess_set_remove_cb -> SSL_CTX_sess_set_new_cb ebenso... da DLL ja nicht gefunden wurde
Delphi-Quellcode:
ist das so der richtige Weg?
procedure TIdOpenSSLIOHandlerClient.EnsureContext;
begin // schlägt das Laden der DLL fehl ist FContext noch <nil> und der Aufruf des TIdOpenSSLContextClient.Destroy entfällt. EnsureOpenSSLLoaded(); if not Assigned(FContext) then FContext := TIdOpenSSLContextClient.Create(); // EnsureOpenSSLLoaded(); --> führt ggf. zu Exception, wo FContext welches nicht komplett initialsiert ist abgeräumt wird try BeforeInitContext(FContext); TIdOpenSSLContextClient(FContext).Init(FOptions); AfterInitContext(FContext); except on E: EExternalException do begin try FreeAndNil(FContext); except on E: EExternalException do ; // Nothing end; raise EIdOpenSSLLoadError.Create('Failed to load OpenSSL'); end; end; end; Nachtrag: in der Funktion TOpenSSLLoader.Load steckt leider auch ein Bug, auch wenn diese Funktion beim ersten Versuch sauber false liefert wenn die DLL's nicht geladen werden konnten, liefert einer 2. Aufruf true - auch wenn die DLL's immer noch nicht da sind... daher habe ich folgende geändert: if not Result then begin // bei weiterem Aufruf nochmal versuchen die DLL's zu laden... FLoadCount.Decrement(); Exit; end; André |
AW: Indy & OpenSSL 1.1.1 & TLS 1.3
Hat sich bei Indy etwas mit dem TLS 1.3 Support getan? Gibt es eine Delphi Version, die das out of the box unterstützt?
|
AW: Indy & OpenSSL 1.1.1 & TLS 1.3
Ich habe es auch ans laufen bekommen.
Eine Frage, die IdOpenSSLConsts.pas kann man die wie hier auf die 3er DLL´s umbenennen? Oder gibt es da noch Probleme. Muss SSLDLLVers auch angepasst werden? Es Funktioniert so wie hier
Delphi-Quellcode:
unit IdOpenSSLConsts;
interface {$i IdCompilerDefines.inc} const CLibCryptoRaw = 'libcrypto'; CLibSSLRaw = 'libssl'; SSLDLLVers: array [0..1] of string = ('', '.1.1'); CLibCrypto = // {$IFDEF CPU32}CLibCryptoRaw + '-1_1.dll'{$ENDIF} // {$IFDEF CPU64}CLibCryptoRaw + '-1_1-x64.dll'{$ENDIF} {$IFDEF CPU32}CLibCryptoRaw + '-3.dll'{$ENDIF} {$IFDEF CPU64}CLibCryptoRaw + '-3-x64.dll'{$ENDIF} ; CLibSSL = // {$IFDEF CPU32}CLibSSLRaw + '-1_1.dll'{$ENDIF} // {$IFDEF CPU64}CLibSSLRaw + '-1_1-x64.dll'{$ENDIF} {$IFDEF CPU32}CLibSSLRaw + '-3.dll'{$ENDIF} {$IFDEF CPU64}CLibSSLRaw + '-3-x64.dll'{$ENDIF} ; implementation end. |
AW: Indy & OpenSSL 1.1.1 & TLS 1.3
@mezen, liest du hier noch mit? Ich verwende seit einiger Zeit deinen neuen Openssl IOHandler und bin recht zufrieden damit. Jetzt bin ich an einem Punkt wo ich Mails mit S/MIME signieren und verschlüsseln möchte. Die notwendigen Funktionen dazu gibt es ja in dem Openssl Dlls. Ich würde dazu gerne die restlichen Importe ergänzen, für einige der Funktionen kommt dieses Stack genannte Konstrukt zum Einsatz, damit nicht alles mit mehr oder minder typlosen pointern machen muss habe ich den Codegenerator erweitert, so dass er auch die Stack_of defines in Delphi inline Funktionen umsetzt.
Das würde ich gerne mit der Gemeinschaft teilen, wie lautet die URL / Branch deines github repositories? Ich würde davon einen Branch machen und meinen Änderungen dort einstellen, ggf. kannst du das ja mergen? |
AW: Indy & OpenSSL 1.1.1 & TLS 1.3
Zitat:
![]() oder dieser: ![]() |
AW: Indy & OpenSSL 1.1.1 & TLS 1.3
Hallo zusammen,
ich breche mir seit Tagen die Finger, um folgende Anforderung umsetzen zu können: Wir haben einen Rest-Webservice laufen, der mit Indy entwickelt wurde. Diesen WS ruft unser SAP auf, um uns Daten (IDOC) zu übermitteln. Aus Sicherheitsgründen soll nun auf der SAP-Seite "EMS" (Extended Master Secret) verwendet werden. AFAIK funktioniert das nur mit OpenSSL 1.1.1. Die Binaries dafür habe ich, aber ich stehe irgendwie komplett auf dem Schlauch, was ich jetzt für Indy 10 unter 10.1 Berlin alles herunterladen, patchen usw. muss. Kann mir da jemand Schritt für Schritt auf die Sprünge helfen? Tausend Dank im Voraus! |
AW: Indy & OpenSSL 1.1.1 & TLS 1.3
Zitat:
Eventuell hilft es, zuerst ein separates Testprojekt zu erstellen, und damit einen Verbindungsaufbau zu einem TLS 1.3 Server zu probieren. Alternativ kann auch ein kommerzieller SSL Handler verwendet werden. Der wird dann in Indy einfach anstelle des normalen Indy Handlers zugewiesen. Die werden z.B. hier genannt: ![]() |
AW: Indy & OpenSSL 1.1.1 & TLS 1.3
Den Code aus dem Repo hab' ich.
Die Idee war, einfach den "alten" IOHandler durch den neuen (TIdOpenSSLIOHandlerServer) zu ersetzen. Da unser WS als Server fungiert klang das naheliegend. War wohl zu einfach gedacht. Die Behebung eines Problems macht gleich 2 neue auf.
Code:
Der Typ ist in idGlobal definiert, in IdOpenSSLHeaders_async wird auf idGlobal verwiesen und das Verzeichnis steht im Suchpfad des Projektes.
[dcc32 Fehler] IdOpenSSLHeaders_async.pas(70): E2003 Undeklarierter Bezeichner: 'TIdC_SIZET'
Natürlich kann ich jetzt idGlobal in das Projekt mit aufnehmen. Dann kommt der nächste Fehler:
Code:
Das kann aber nicht Sinn und Zweck der Übung sein.
[dcc32 Fehler] IdOpenSSLHeaders_bio.pas(284): E2003 Undeklarierter Bezeichner: 'TIdC_SIZET'
Irgendwie krieg' ich das jetzt nicht mehr gewechselt ... |
AW: Indy & OpenSSL 1.1.1 & TLS 1.3
Zitat:
Wenn ich nun IOHandlerServer := TIdOpenSSLIOHandlerServer.Create; verwende, kompiliert das Projekt ohne Fehler. Ich vermute, entweder ist der Projektsuchpfad nicht korrekt oder es werden Units im Projektsuchpfad gefunden, die aus einer anderen Indy-Version kommen. |
AW: Indy & OpenSSL 1.1.1 & TLS 1.3
Zitat:
Ich versuche mal, die temporär woanders hinzuschieben ... |
AW: Indy & OpenSSL 1.1.1 & TLS 1.3
Kann man den neuen Code von diesem Link
![]() für dieses Beispiel hier unten verwenden?
Delphi-Quellcode:
unit uSendMail;
interface uses Vcl.ComCtrls, System.SysUtils, System.Classes, System.IOUtils, IdSmtp, IdMessage, IdAttachmentFile, IdText, IdExplicitTLSClientServerBase, IdSSLOpenSSL, IdBaseComponent, IdIOHandler, IdIOHandlerSocket, IdIOHandlerStack, IdSSL; type TLoginType = (ltNone, ltLogin); TMailPriority = (pHighest, pHigh, pNormal, pLow, pLowest); TSendMail = class private FLibeay32, FSSLeay32: string; FSmtp: TIdSMTP; FIdSSLIOHandler: TIdSSLIOHandlerSocketOpenSSL; FMsg: TIdMessage; FAttachmentList: TStringList; FiEMailSize: Integer; FUseSSL: Boolean; FTLSMode: Integer; procedure SetLibeay32(const aValue: string); procedure SetSSLeay32(const aValue: string); procedure SetHost(const aValue: string); procedure SetPort(const aValue: Word); procedure SetUserName(const aValue: string); procedure SetPassword(const aValue: string); procedure SetLoginType(const aValue: TLoginType); procedure SetMailAgent(const aValue: string); procedure SetReceiver(const aValue: string); procedure SetSender(const aValue: string); procedure SetSubject(const aValue: string); procedure SetPriority(const aValue: TMailPriority); procedure SetReturnReciept(const aValue: Boolean); procedure SetBody(aValue: TStrings); procedure SetUseSSL(const aValue: Boolean); procedure SetTLSMode(const aValue: Integer); function GetLibeay32: string; function GetSSLeay32: string; function GetHost: string; function GetPort: Word; function GetUserName: string; function GetPassword: string; function GetLoginType: TLoginType; function GetMailAgent: string; function GetReceiver: string; function GetSender: string; function GetSubject: string; function GetPriority: TMailPriority; function GetReturnReciept: Boolean; function GetBody: TStrings; function GetUseSSL: Boolean; function GetTLSMode: Integer; procedure setEmailSize(iEMailSize: Integer); protected // public constructor Create; destructor Destroy; override; property Libeay32: string read GetLibeay32 write SetLibeay32; property SSLeay32: string read GetSSLeay32 write SetSSLeay32; property Host: string read GetHost write SetHost; property Port: Word read GetPort write SetPort; property Username: string read GetUserName write SetUserName; property Password: string read GetPassword write SetPassword; property LoginType: TLoginType read GetLoginType write SetLoginType; property MailAgent: string read GetMailAgent write SetMailAgent; property Receiver: string read GetReceiver write SetReceiver; property Sender: string read GetSender write SetSender; property Subject: string read GetSubject write SetSubject; property Priority: TMailPriority read GetPriority write SetPriority; property ReturnReciept: Boolean read GetReturnReciept write SetReturnReciept; property Body: TStrings read GetBody write SetBody; property Attachments: TStringList read FAttachmentList; property UseSSL: Boolean read GetUseSSL write SetUseSSL; property TLSMode: Integer read GetTLSMode write SetTLSMode; function SendMail: Boolean; end; implementation function _MIMEConvert(const s: string): string; var i: Integer; begin Result := ''; for i := 1 to Length(s) do begin if s[i] = '€' then begin Result := Result + '?=ISO-8859-15?Q?=A4?=' end else if Ord(s[i]) > $99 then Result := Result + '=?ISO-8859-1?Q?=' + Format('%x', [Ord(s[i])]) + '?=' else Result := Result + s[i]; end; end; constructor TSendMail.Create; begin FSmtp := TIdSMTP.Create(nil); FIdSSLIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil); FMsg := TIdMessage.Create(nil); FAttachmentList := TStringList.Create; end; destructor TSendMail.Destroy; begin FreeAndNil(FSmtp); FreeAndNil(FIdSSLIOHandler); FreeAndNil(FMsg); FreeAndNil(FAttachmentList); inherited; end; function TSendMail.GetLoginType: TLoginType; begin if FSmtp.AuthType = satNone then Result := ltNone else Result := ltLogin; end; function TSendMail.GetHost: string; begin Result := FSmtp.Host; end; function TSendMail.GetPort: Word; begin Result := FSmtp.Port; end; function TSendMail.GetPassword: string; begin Result := FSmtp.Password; end; function TSendMail.GetUserName: string; begin Result := FSmtp.Username; end; procedure TSendMail.SetLoginType(const aValue: TLoginType); begin if aValue = ltNone then FSmtp.AuthType := satNone else FSmtp.AuthType := satDefault; end; procedure TSendMail.SetHost(const aValue: string); begin if aValue <> FSmtp.Host then FSmtp.Host := aValue; end; procedure TSendMail.SetPort(const aValue: Word); begin if aValue <> FSmtp.Port then FSmtp.Port := aValue; end; procedure TSendMail.SetPassword(const aValue: string); begin if aValue <> FSmtp.Password then FSmtp.Password := aValue; end; procedure TSendMail.SetUserName(const aValue: string); begin if aValue <> FSmtp.Username then FSmtp.Username := aValue; end; function TSendMail.GetMailAgent: string; begin Result := FSmtp.MailAgent; end; procedure TSendMail.SetMailAgent(const aValue: string); begin if aValue <> FSmtp.MailAgent then FSmtp.MailAgent := aValue; end; function TSendMail.GetBody: TStrings; begin Result := FMsg.Body; end; function TSendMail.GetUseSSL; begin Result := FUseSSL; end; function TSendMail.GetTLSMode; begin Result := FTLSMode; end; function TSendMail.GetPriority: TMailPriority; var iTmp: Byte; begin iTmp := Ord(FMsg.Priority); Result := TMailPriority(iTmp); end; function TSendMail.GetReceiver: string; begin Result := FMsg.Recipients.EMailAddresses; end; function TSendMail.GetReturnReciept: Boolean; begin Result := FMsg.ReceiptRecipient.Text <> ''; end; function TSendMail.GetSender: string; begin Result := FMsg.From.Text; end; function TSendMail.GetSSLeay32: string; begin Result := FSSLeay32; end; function TSendMail.GetLibeay32: string; begin Result := FLibeay32; end; function TSendMail.GetSubject: string; begin Result := FMsg.Subject; end; procedure TSendMail.SetBody(aValue: TStrings); begin FMsg.Body.Assign(aValue); end; procedure TSendMail.SetUseSSL(const aValue: Boolean); begin FUseSSL := aValue; end; procedure TSendMail.SetTLSMode(const aValue: Integer); begin FTLSMode := aValue; end; procedure TSendMail.SetPriority(const aValue: TMailPriority); var iTmp: Byte; begin iTmp := Ord(aValue); FMsg.Priority := TIdMessagePriority(iTmp); end; procedure TSendMail.SetReceiver(const aValue: string); begin FMsg.Recipients.EMailAddresses := aValue; end; procedure TSendMail.SetReturnReciept(const aValue: Boolean); begin if aValue then FMsg.ReceiptRecipient.Text := FMsg.From.Text else FMsg.ReceiptRecipient.Text := ''; end; procedure TSendMail.SetSender(const aValue: string); begin FMsg.From.Text := aValue; end; procedure TSendMail.SetSSLeay32(const aValue: string); begin FSSLeay32 := aValue; end; procedure TSendMail.SetLibeay32(const aValue: string); begin FLibeay32 := aValue; end; procedure TSendMail.SetSubject(const aValue: string); begin FMsg.Subject := aValue; end; procedure TSendMail.setEmailSize(iEMailSize: Integer); begin FiEMailSize := iEMailSize; end; function TSendMail.SendMail: Boolean; var i: Integer; begin Result := False; try FMsg.Subject := _MIMEConvert(FMsg.Subject); if FAttachmentList.Count > 0 then begin for i := 0 to FAttachmentList.Count - 1 do begin if TFile.Exists(FAttachmentList[i]) then begin TIdAttachmentFile.Create(FMsg.MessageParts, FAttachmentList[i]); TIdText.Create(FMsg.MessageParts).ContentType := 'text/html'; TIdText.Create(FMsg.MessageParts).CharSet := 'ISO-8859-1'; if i = 0 then TIdText.Create(FMsg.MessageParts).Body.Add(FMsg.Body.Text); end; end; end else begin FMsg.ContentType := 'text/html'; FMsg.CharSet := 'ISO-8859-1'; end; setEmailSize(Length(FMsg.Body.Text)); FSmtp.ConnectTimeout := 10000; if GetUseSSL and TFile.Exists(FLibeay32) and TFile.Exists(FSSLeay32) then begin FSmtp.IOHandler := FIdSSLIOHandler; // Not needed? // fIdSSLIOHandler.SSLOptions.Mode := sslmUnassigned; // fIdSSLIOHandler.SSLOptions.VerifyMode := []; // fIdSSLIOHandler.SSLOptions.VerifyDepth := 0; // // fIdSSLIOHandler.Destination := getHost + ':' + IntToStr(getPort); // fIdSSLIOHandler.Host := getHost; // fIdSSLIOHandler.Port := getPort; FSmtp.UseTLS := TIdUseTLS(GetTLSMode); {* 0 utNoTLSSupport 1 utUseImplicitTLS 2 utUseRequireTLS 3 utUseExplicitTLS *} end; try FSmtp.Connect; if FSmtp.Connected then begin try FSmtp.Send(FMsg); Result := True; finally FSmtp.Disconnect; end; end; except Result := False; end; except Result := False; end; end; end. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:15 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz