diff --git a/ssl_openssl.pas b/ssl_openssl.pas index 2dd1b14..ce77347 100644 --- a/ssl_openssl.pas +++ b/ssl_openssl.pas @@ -1,5 +1,5 @@ {==============================================================================| -| Project : Ararat Synapse | 001.003.000 | +| Project : Ararat Synapse | 001.004.000 | |==============================================================================| | Content: SSL support by OpenSSL | |==============================================================================| @@ -35,6 +35,7 @@ | The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).| | Portions created by Lukas Gebauer are Copyright (c)2005-2017. | | Portions created by Petr Fejfar are Copyright (c)2011-2012. | +| Portions created by Pepak are Copyright (c)2018. | | All Rights Reserved. | |==============================================================================| | Contributor(s): | @@ -76,6 +77,8 @@ Ad-Hoc key and certificate for each incomming connection by self. It slowdown accepting of new connections! } +{$INCLUDE 'jedi.inc'} + {$IFDEF FPC} {$MODE DELPHI} {$ENDIF} @@ -95,6 +98,9 @@ uses blcksock, synsock, synautil, {$IFDEF CIL} System.Text, +{$ENDIF} +{$IFDEF DELPHI23_UP} + AnsiStrings, {$ENDIF} ssl_openssl_lib; @@ -103,16 +109,20 @@ type Instance of this class will be created for each @link(TTCPBlockSocket). You not need to create instance of this class, all is done by Synapse itself!} TSSLOpenSSL = class(TCustomSSL) + private + FServer: boolean; protected FSsl: PSSL; Fctx: PSSL_CTX; + function NeedSigningCertificate: boolean; virtual; function SSLCheck: Boolean; - function SetSslKeys: boolean; - function Init(server:Boolean): Boolean; + function SetSslKeys: boolean; virtual; + function Init: Boolean; function DeInit: Boolean; - function Prepare(server:Boolean): Boolean; + function Prepare: Boolean; function LoadPFX(pfxdata: ansistring): Boolean; function CreateSelfSignedCert(Host: string): Boolean; override; + property Server: boolean read FServer; public {:See @inherited} constructor Create(const Value: TTCPBlockSocket); override; @@ -176,7 +186,7 @@ begin if Length(Password) > (Size - 1) then SetLength(Password, Size - 1); Result := Length(Password); - StrLCopy(buf, PAnsiChar(Password + #0), Result + 1); + {$IFDEF DELPHI23_UP}AnsiStrings.{$ENDIF}StrLCopy(buf, PAnsiChar(Password + #0), Result + 1); end; {$ENDIF} @@ -250,7 +260,7 @@ begin pk := EvpPkeynew; x := X509New; try - rsa := RsaGenerateKey(1024, $10001, nil, nil); + rsa := RsaGenerateKey(2048, $10001, nil, nil); EvpPkeyAssign(pk, EVP_PKEY_RSA, rsa); X509SetVersion(x, 2); Asn1IntegerSet(X509getSerialNumber(x), 0); @@ -411,7 +421,12 @@ begin end; end; -function TSSLOpenSSL.Init(server:Boolean): Boolean; +function TSSLOpenSSL.NeedSigningCertificate: boolean; +begin + Result := (FCertificateFile = '') and (FCertificate = '') and (FPFXfile = '') and (FPFX = ''); +end; + +function TSSLOpenSSL.Init: Boolean; var s: AnsiString; begin @@ -433,10 +448,10 @@ begin LT_all: begin //try new call for OpenSSL 1.1.0 first - Fctx := SslCtxNew(SslMethodTLS); - if Fctx=nil then - //callback to previous versions - Fctx := SslCtxNew(SslMethodV23); + Fctx := SslCtxNew(SslMethodTLS); + if Fctx=nil then + //callback to previous versions + Fctx := SslCtxNew(SslMethodV23); end; else Exit; @@ -459,8 +474,7 @@ begin SslCtxSetDefaultPasswdCbUserdata(FCtx, self); {$ENDIF} - if server and (FCertificateFile = '') and (FCertificate = '') - and (FPFXfile = '') and (FPFX = '') then + if server and NeedSigningCertificate then begin CreateSelfSignedcert(FSocket.ResolveIPToName(FSocket.GetRemoteSinIP)); end; @@ -496,11 +510,11 @@ begin FSSLEnabled := False; end; -function TSSLOpenSSL.Prepare(server:Boolean): Boolean; +function TSSLOpenSSL.Prepare: Boolean; begin Result := false; DeInit; - if Init(server) then + if Init then Result := true else DeInit; @@ -515,7 +529,8 @@ begin Result := False; if FSocket.Socket = INVALID_SOCKET then Exit; - if Prepare(False) then + FServer := False; + if Prepare then begin {$IFDEF CIL} if sslsetfd(FSsl, FSocket.Socket.Handle.ToInt32) < 1 then @@ -573,7 +588,8 @@ begin Result := False; if FSocket.Socket = INVALID_SOCKET then Exit; - if Prepare(True) then + FServer := True; + if Prepare then begin {$IFDEF CIL} if sslsetfd(FSsl, FSocket.Socket.Handle.ToInt32) < 1 then diff --git a/ssl_openssl_lib.pas b/ssl_openssl_lib.pas index 5681b64..fd5afad 100644 --- a/ssl_openssl_lib.pas +++ b/ssl_openssl_lib.pas @@ -1,5 +1,5 @@ {==============================================================================| -| Project : Ararat Synapse | 003.008.000 | +| Project : Ararat Synapse | 003.009.000 | |==============================================================================| | Content: SSL support by OpenSSL | |==============================================================================| @@ -35,10 +35,12 @@ | The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).| | Portions created by Lukas Gebauer are Copyright (c)2002-2017. | | Portions created by Petr Fejfar are Copyright (c)2011-2012. | +| Portions created by Pepak are Copyright (c)2018. | | All Rights Reserved. | |==============================================================================| | Contributor(s): | | Tomas Hajny (OS2 support) | +| Pepak (multiversion support) | |==============================================================================| | History: see HISTORY.HTM from distribution package | | (Found at URL: http://www.ararat.cz/synapse/) | @@ -96,6 +98,7 @@ uses {$ENDIF} SysUtils; {$ELSE} + SysUtils, Windows; {$ENDIF} @@ -134,6 +137,58 @@ var DLLSSLName2: string = 'libssl32.dll'; DLLUtilName: string = 'libeay32.dll'; {$ENDIF} +{$IFDEF MSWINDOWS} +const + LibCount = 5; + SSLLibNames: array[0..LibCount-1] of string = ( + // OpenSSL v3.0 + {$IFDEF WIN64} + 'libssl-3-x64.dll', + {$ELSE} + 'libssl-3.dll', + {$ENDIF} + // OpenSSL v1.1.x + {$IFDEF WIN64} + 'libssl-1_1-x64.dll', + {$ELSE} + 'libssl-1_1.dll', + {$ENDIF} + // OpenSSL v1.0.2 distinct names for x64 and x86 + {$IFDEF WIN64} + 'ssleay32-x64.dll', + {$ELSE} + 'ssleay32-x86.dll', + {$ENDIF} + // OpenSSL v1.0.2 + 'ssleay32.dll', + // OpenSSL (ancient) + 'libssl32.dll' + ); + CryptoLibNames: array[0..LibCount-1] of string = ( + // OpenSSL v3.0 + {$IFDEF WIN64} + 'libcrypto-3-x64.dll', + {$ELSE} + 'libcrypto-3.dll', + {$ENDIF} + // OpenSSL v1.1.x + {$IFDEF WIN64} + 'libcrypto-1_1-x64.dll', + {$ELSE} + 'libcrypto-1_1.dll', + {$ENDIF} + // OpenSSL v1.0.2 distinct names for x64 and x86 + {$IFDEF WIN64} + 'libeay32-x64.dll', + {$ELSE} + 'libeay32-x86.dll', + {$ENDIF} + // OpenSSL v1.0.2 + 'libeay32.dll', + // OpenSSL (ancient) + 'libeay32.dll' + ); +{$ENDIF} {$ENDIF} type @@ -1163,12 +1218,12 @@ begin end; function SslMethodTLS:PSSL_METHOD; -begin - if InitSSLInterface and Assigned(_SslMethodTLS) then - Result := _SslMethodTLS - else - Result := nil; -end; +begin + if InitSSLInterface and Assigned(_SslMethodTLS) then + Result := _SslMethodTLS + else + Result := nil; +end; function SslCtxUsePrivateKey(ctx: PSSL_CTX; pkey: SslPtr):Integer; begin @@ -1858,10 +1913,20 @@ begin {$ENDIF} end; +function GetLibFileName(Handle: THandle): string; +var + n: integer; +begin + n := MAX_PATH + 1024; + SetLength(Result, n); + n := GetModuleFilename(Handle, PChar(Result), n); + SetLength(Result, n); +end; + function InitSSLInterface: Boolean; var s: string; - x: integer; + i: integer; begin {pf} if SSLLoaded then @@ -1869,7 +1934,7 @@ begin Result := TRUE; exit; end; - {/pf} + {/pf} SSLCS.Enter; try if not IsSSLloaded then @@ -1878,12 +1943,24 @@ begin SSLLibHandle := 1; SSLUtilHandle := 1; {$ELSE} + // Note: It's important to ensure that the libraries both come from the + // same directory, preferably the one of the executable. Otherwise a + // version mismatch could easily occur. + {$IFDEF MSWINDOWS} + for i := 0 to Pred(LibCount) do + begin + SSLUtilHandle := LoadLib(CryptoLibNames[i]); + if SSLUtilHandle <> 0 then + begin + s := ExtractFilePath(GetLibFileName(SSLUtilHandle)); + SSLLibHandle := LoadLib(s + SSLLibNames[i]); + Break; + end; + end; + {$ELSE} SSLUtilHandle := LoadLib(DLLUtilName); SSLLibHandle := LoadLib(DLLSSLName); - {$IFDEF MSWINDOWS} - if (SSLLibHandle = 0) then - SSLLibHandle := LoadLib(DLLSSLName2); - {$ENDIF} + {$ENDIF} {$ENDIF} if (SSLLibHandle <> 0) and (SSLUtilHandle <> 0) then begin @@ -1999,14 +2076,8 @@ begin OPENSSLaddallalgorithms; RandScreen; {$ELSE} - SetLength(s, 1024); - x := GetModuleFilename(SSLLibHandle,PChar(s),Length(s)); - SetLength(s, x); - SSLLibFile := s; - SetLength(s, 1024); - x := GetModuleFilename(SSLUtilHandle,PChar(s),Length(s)); - SetLength(s, x); - SSLUtilFile := s; + SSLLibFile := GetLibFileName(SSLLibHandle); + SSLUtilFile := GetLibFileName(SSLUtilHandle); //init library if assigned(_SslLibraryInit) then _SslLibraryInit;