Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
d16c2e8
Added new OpenSSL IO Handler for OpenSSL 1.1.1
mezen Jan 27, 2020
8f89f7f
Added results of an internal review
mezen May 27, 2020
c805f24
FTP data channel should reuse the session of the command channel
mezen Jun 25, 2020
eebe982
Added git attributes
mezen Oct 28, 2020
54855da
Fixed line endings and rebase error
mezen Oct 10, 2022
c1d56d0
Made intermediate code more compatible
mezen Oct 28, 2020
daa789c
Made new OpenSSL IO Handler more compatible
mezen Oct 28, 2020
f4399ac
Removed some unnecessary stuff from GenerateCode.dproj
mezen Oct 28, 2020
977a928
Do not use SafeLoadLibrary without second parameter
mezen Oct 28, 2020
47c1a32
Added code for loading OpenSSL on Linux
mezen Oct 28, 2020
8d0a344
Replaced %LINE% with %LINENUM%
mezen Oct 28, 2020
53e30de
IndyCheckWindowsVersion is only available under windows
mezen Oct 28, 2020
7318e42
Removed duplicated types
mezen Oct 28, 2020
ee17ddc
If the options of the IO handler change, the context must be reinitia…
mezen Oct 28, 2020
1b6029c
Corrected some header imports
mezen Oct 29, 2020
24f51a5
Used correct case
mezen Oct 29, 2020
6299317
Fixed another wrong type
mezen Oct 29, 2020
cffaecf
Fixed copy'n'paste error :(
mezen Oct 29, 2020
db6c612
Added missing raise
mezen Oct 29, 2020
4bbc062
Fixed line endings
mezen Nov 3, 2020
61579a7
Fixed small errors in crypto
mezen Nov 3, 2020
c96f577
Added CRYPTO_set_mem_functions to crypto
mezen Nov 3, 2020
8c9a63a
If OpenSSL is dynamically loaded, the DLLs should also be freed at un…
mezen Nov 3, 2020
57be390
Fixed MemLeak with handling TLS Sessions
mezen Nov 3, 2020
54bfdbc
Fixed missing _ to parameter named "out" & added dynlibs to Loader
mezen Nov 6, 2020
2137a77
Fixed used-after-free
mezen Nov 6, 2020
c033efd
The Server IO Handler does not immediately start a TLS handshake any …
mezen Nov 6, 2020
968cf79
Added SaveToFile and ctor overload for file loading to TIdOpenSSLX509
mezen Dec 1, 2020
63c6202
Added missing file header to IdOpenSSLX509
mezen Dec 1, 2020
2d8c9d9
Fixed using PBIO instead of BIO directly
mezen Jan 6, 2021
65480ac
Use existing CheckForError and RaiseError
mezen Mar 2, 2021
f5051e1
Add additional Infos to EIdOpenSSLAcceptError
mezen Mar 2, 2021
1dad0bf
Replaced `&parameter ` with `parameter_`
mezen Jul 23, 2021
90d7e99
Improved excpetion message for shutdown errors
mezen Jul 23, 2021
0aaee20
Fixed multiple `Load` / `Unload` calls
mezen Jul 23, 2021
08b9cf9
Resolved c macro for ASN1_INTEGER functions
mezen Jul 23, 2021
0cb24d7
Fixed wrong parameter definitin in bn
mezen Jul 23, 2021
91a9da3
Resolved c macro for ASN1_Time functions
mezen Jul 26, 2021
aaa2044
Resolved c macro for ASN1_UTCTIME & ASN1_GENERALIZEDTIME functions
mezen Jul 28, 2021
e6e6ef7
Resolved c macro for BIO_get/set_mem functions
mezen Jul 28, 2021
1431b6a
Removed duplicate type X509_REVOKED
mezen Jul 28, 2021
aba6517
Fixed small memory leak
mezen Jul 28, 2021
5ba5abc
Fix compile errors for Delphi 7
Aug 31, 2021
0b3b26d
Added initialization of result as addition to 9c37992275a514eb1c80369…
mezen Sep 9, 2021
3d4b46c
Added BeforeInitContext and AfterInitContext to TIdOpenSSLIOHandlerSe…
mezen Oct 18, 2021
ae1237f
Added some xml doc
mezen Nov 30, 2021
40e3346
Removed old code
mezen Nov 30, 2021
0042917
Use parameter instead of property
mezen Nov 30, 2021
f612a7b
TLS Client is now able to verify host name
mezen Nov 30, 2021
df7ee5b
Added small helpful comment
mezen Oct 10, 2022
f078888
Added header translation for pkcs12.h
mezen Oct 10, 2022
f200bec
Sort uses
mezen Oct 10, 2022
38fd1c3
Use newer function
mezen Oct 10, 2022
baf3c22
Added possibility to load trusted certs
mezen Oct 10, 2022
a75a5d0
Load x509 from memory directly
mezen Oct 10, 2022
c429db4
Fixed translation error in bio
mezen Oct 10, 2022
ab73d95
Added missing uses
mezen Oct 11, 2022
687183c
Expanded some c compiler macro
mezen Oct 12, 2022
d4f2d40
fixed warning cause of comparison of unsigned and signed integer
Delphi-FPC-Lazarus Feb 21, 2023
18a9e3b
* IdOpenSSLIOHandlerClient
Delphi-FPC-Lazarus Feb 21, 2023
65f1352
* Added properties for accessing context.
Delphi-FPC-Lazarus Feb 21, 2023
1e68a83
* added missing openssl_sk_num() and openssl_sk_value()
Delphi-FPC-Lazarus Feb 21, 2023
3c1df6f
fixed idopenssl loader wasn't loading IdOpenSSLHeaders_pkcs12
Delphi-FPC-Lazarus Feb 21, 2023
3504386
reverted duplicate declaration, sorry for confusion
Delphi-FPC-Lazarus Feb 21, 2023
c3537a0
Enabled IDOpenSSLhandler loading OpenSSL 3.0 dlls
Delphi-FPC-Lazarus Mar 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Lib/Protocols/OpenSSL/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Declare files that will always have CRLF line endings on checkout.
*.pas text eol=crlf
374 changes: 374 additions & 0 deletions Lib/Protocols/OpenSSL/GenerateCode/GenerateCode.dpr
Original file line number Diff line number Diff line change
@@ -0,0 +1,374 @@
{******************************************************************************}
{ }
{ Indy (Internet Direct) - Internet Protocols Simplified }
{ }
{ https://www.indyproject.org/ }
{ https://gitter.im/IndySockets/Indy }
{ }
{******************************************************************************}
{ }
{ This file is part of the Indy (Internet Direct) project, and is offered }
{ under the dual-licensing agreement described on the Indy website. }
{ (https://www.indyproject.org/license/) }
{ }
{ Copyright: }
{ (c) 1993-2020, Chad Z. Hower and the Indy Pit Crew. All rights reserved. }
{ }
{******************************************************************************}
{ }
{ Originally written by: Fabian S. Biehn }
{ fbiehn@aagon.com (German & English) }
{ }
{ Contributers: }
{ Here could be your name }
{ }
{******************************************************************************}

program GenerateCode;

{$APPTYPE CONSOLE}

{$R *.res}

uses
System.Classes,
System.IOUtils,
System.StrUtils,
System.SysUtils,
System.Types,
Winapi.Windows;

type
TGenerateMode = (gmDynamic, gmStatic);

function ExpandEnvironmentVariables(const AValue: string): string;
const
MAX_LENGTH = 32767;
begin
SetLength(Result, MAX_LENGTH);
SetLength(Result, ExpandEnvironmentStrings(@AValue[1], @Result[1], MAX_LENGTH)-1);
end;

function ReplaceStatic(const ALine: string; const AShouldUseLibSSL: Boolean): string;
const
CSemicolon: string = ';';
var
i: Integer;
begin
Result := ALine;
i := Result.LastIndexOf(CSemicolon);
if i = -1 then
Exit;
Result := Result.Remove(i, CSemicolon.Length);
Result := Result.Insert(i, Format(' cdecl; external %s;', [IfThen(AShouldUseLibSSL, 'CLibSSL', 'CLibCrypto')]));
end;

function ReplaceDynamic(const ALine: string; const AMethodList: TStringList): string;
var
i: Integer;
LMethodPrefix: string;
LMethod: string;
begin
Result := ALine;

if not Result.TrimLeft.StartsWith('function') and not Result.TrimLeft.StartsWith('procedure') then
Exit;

LMethodPrefix := 'function';
i := Result.IndexOf(LMethodPrefix);
if i = -1 then
begin
LMethodPrefix := 'procedure';
i := Result.IndexOf(LMethodPrefix);
if i = -1 then
Exit;
end;

// Remove LMethodPrefix
Result := Result.Remove(i, LMethodPrefix.Length + string(' ').Length);
// Keep Result for method name extracting later
LMethod := Result.TrimLeft();
// Add LMethodPrefix after parameters
if Result.Contains(')') then
Result := Result.Replace('(', ': ' + LMethodPrefix + '(')
// No Params? Add LMethodPrefix after before return type
else if Result.Contains(': ') then
Result := Result.Replace(': ', ': ' + LMethodPrefix + ': ')
// Also no return type? Add LMethodPrefix before semi colon
else
Result := Result.Replace(';', ': ' + LMethodPrefix + ';');

if Result[Result.Length] = ';' then
Result := Result.Remove(Result.Length-1) + ' cdecl = nil;';

// Ignore comments
i := LMethod.IndexOf('}');
if i > -1 then
// +1 for including } and Trim for removing whitespace of intendation
LMethod := LMethod.Substring(i + 1{, LMethod.Length - i}).TrimLeft;
i := LMethod.IndexOf(';');
if i > -1 then
LMethod := LMethod.Remove(i);
i := LMethod.IndexOf(' ');
if i > -1 then
LMethod := LMethod.Remove(i);
i := LMethod.IndexOf(':');
if i > -1 then
LMethod := LMethod.Remove(i);
i := LMethod.IndexOf('(');
if i > -1 then
LMethod := LMethod.Remove(i);
AMethodList.Add(LMethod);
end;

procedure AddDynamicLoadingMethods(
const AFile: TStringList;
const AMethods: TStringList;
const AUsesIndex: Integer;
const AVarIndex: Integer;
const AImplementationIndex: Integer);

procedure Insert(const AList: TStringList; const s: string; var Index: Integer);
begin
AList.Insert(Index, s);
Inc(Index);
end;

function Find(const AList: TStringList; const s: string; var Index: Integer; const AOffset: Integer = 0): Boolean;
var
i: Integer;
begin
Result := False;
for i := AOffset to AList.Count - 1 do
begin
if AList[i].Contains(s) then
begin
Index := i;
Exit(True);
end;
end;
end;

var
LOffset: Integer;
LMethod: string;
begin
if AImplementationIndex = -1 then
Exit;
LOffset := AImplementationIndex + 1;

if Find(AFile, 'uses', LOffset, LOffset) then
if Find(AFile, ';', LOffset, LOffset) then
Inc(LOffset);

Insert(AFile, '', LOffset);
Insert(AFile, 'procedure Load(const ADllHandle: TIdLibHandle; const AFailed: TStringList);', LOffset);
Insert(AFile, '', LOffset);
Insert(AFile, ' function LoadFunction(const AMethodName: string; const AFailed: TStringList): Pointer;', LOffset);
Insert(AFile, ' begin', LOffset);
Insert(AFile, ' Result := LoadLibFunction(ADllHandle, AMethodName);', LOffset);
Insert(AFile, ' if not Assigned(Result) then', LOffset);
Insert(AFile, ' AFailed.Add(AMethodName);', LOffset);
Insert(AFile, ' end;', LOffset);
Insert(AFile, '', LOffset);
Insert(AFile, 'begin', LOffset);
for LMethod in AMethods do
Insert(AFile, Format(' %0:s := LoadFunction(''%0:s'', AFailed);', [LMethod]), LOffset);
Insert(AFile, 'end;', LOffset);
Insert(AFile, '', LOffset);


Insert(AFile, 'procedure UnLoad;', LOffset);
Insert(AFile, 'begin', LOffset);
for LMethod in AMethods do
Insert(AFile, Format(' %s := nil;', [LMethod]), LOffset);
Insert(AFile, 'end;', LOffset);

if AVarIndex = -1 then
Exit;
LOffSet := Pred(AVarIndex);
Insert(AFile, '', LOffSet);
Insert(AFile, 'procedure Load(const ADllHandle: TIdLibHandle; const AFailed: TStringList);', LOffSet);
Insert(AFile, 'procedure UnLoad;', LOffSet);

LOffSet := Succ(AUsesIndex);
Insert(AFile, ' Classes,', LOffset);
// AFile.Insert(Pred(AVarIndex), 'function Load(const ADllHandle: THandle): TArray<string>;');
end;

function ShouldSkipLine(ALine: string): Boolean;
begin
ALine := ALine.Trim;
Result := ALine.IsEmpty;
Result := Result or ALine.StartsWith('//');
Result := Result or ALine.StartsWith('(*');
Result := Result or ALine.StartsWith('*');
end;

function ReadParameters(out ASource: string; out ATarget: string; out AMode: TGenerateMode): Boolean;
var
LMode: string;
begin
Result := True;
if not FindCmdLineSwitch('Source', ASource) then
begin
Writeln('No source folder!');
Exit(False);
end;
ASource := ExpandEnvironmentVariables(ASource);

if not FindCmdLineSwitch('Target', ATarget) then
begin
Writeln('No target folder!');
Exit(False);
end;
ATarget := ExpandEnvironmentVariables(ATarget);

if not FindCmdLineSwitch('Mode', LMode) then
begin
Writeln('No mode!');
Exit(False);
end;

if LMode = 'dynamic' then
AMode := gmDynamic
else if LMode = 'static' then
AMode := gmStatic
else
begin
Writeln('Invalid mode! Use "dynamic" or "static"!');
Exit(False);
end;
end;

procedure AddGeneratedHeader(const AFile: TStringList);

function Find(const AList: TStringList; const s: string; var Index: Integer): Boolean;
var
i: Integer;
begin
Index := -1;
Result := False;
for i := 0 to AList.Count-1 do
if AList[i].Contains(s) then
begin
Index := i;
Exit(True);
end;
end;

const
CHeader: array[0..4] of string =
(
'',
'// This File is auto generated!',
'// Any change to this file should be made in the',
'// corresponding unit in the folder "intermediate"!',
''
);
var
i: Integer;
LOffset: Integer;
begin
if not Find(AFile, 'unit ', LOffset) then
Exit;
// Keep a empty line before "unit"
Dec(LOffset);
for i := Low(CHeader) to High(CHeader) do
AFile.Insert(i + LOffset, CHeader[i]);
AFile.Insert(Length(CHeader) + LOffset, '// Generation date: ' + DateTimeToStr(Now()));
end;

procedure Main;
var
LFile: string;
LStringListFile: TStringList;
i: Integer;
LVarIndex: Integer;
LUsesIndex: Integer;
LImplementationIndex: Integer;
LSource: string;
LTarget: string;
LMode: TGenerateMode;
LStringListMethods: TStringList;
LFileName: string;
LShouldUseLibSSL: Boolean;
begin
if not ReadParameters(LSource, LTarget, LMode) then
begin
Readln;
Exit;
end;

for LFile in TDirectory.GetFiles(LSource, '*.pas') do
begin
Writeln('Converting ' + LFile);
LFileName := TPath.GetFileName(LFile);
LStringListFile := TStringList.Create();
LStringListMethods := TStringList.Create();
try
LStringListFile.LoadFromFile(LFile);
LUsesIndex := -1;
LVarIndex := -1;
LImplementationIndex := -1;
LShouldUseLibSSL := MatchText(LFileName,
['IdOpenSSLHeaders_ssl.pas', 'IdOpenSSLHeaders_sslerr.pas', 'IdOpenSSLHeaders_tls1.pas']);
for i := 0 to LStringListFile.Count - 1 do
begin
// Find fist uses
if (LVarIndex = -1) and (LUsesIndex = -1) then
if LStringListFile[i].StartsWith('uses') then
LUsesIndex := i;

// var block found?
if (LVarIndex = -1) and LStringListFile[i].StartsWith('var') then
LVarIndex := i;
// Skip until we find the var block
if (LVarIndex = -1) or ShouldSkipLine(LStringListFile[i]) then
Continue;

// No need to go further than "implementation"
if LStringListFile[i] = 'implementation' then
begin
LImplementationIndex := i;
Break;
end;

case LMode of
gmDynamic:
LStringListFile[i] := ReplaceDynamic(LStringListFile[i], LStringListMethods);
gmStatic:
LStringListFile[i] := ReplaceStatic(LStringListFile[i], LShouldUseLibSSL);
end;
end;

case LMode of
gmDynamic:
AddDynamicLoadingMethods(LStringListFile, LStringListMethods, LUsesIndex, LVarIndex, LImplementationIndex);
gmStatic:
if LVarIndex > -1 then
LStringListFile.Delete(LVarIndex);
end;

AddGeneratedHeader(LStringListFile);

LStringListFile.SaveToFile(TPath.Combine(LTarget, LFileName));
finally
LStringListMethods.Free();
LStringListFile.Free();
end;
end;
end;

begin
try
Main;
Writeln('done');
except
on E: Exception do
begin
Writeln(E.ClassName, ': ', E.Message);
end;
end;
// Readln;
end.
Loading