Author Topic: TlsLib4Pascal  (Read 2656 times)

Xor-el

  • Sr. Member
  • ****
  • Posts: 428
TlsLib4Pascal
« on: August 12, 2026, 02:16:41 pm »
Hi all,

I'd like to share TlsLib4Pascal — a fully managed, from-scratch TLS 1.2 + TLS 1.3 stack written in pure Object Pascal (FreePascal/Lazarus and Delphi). No OpenSSL, no OS TLS engine — one implementation, identical on every platform. MIT licensed.

Highlights
  • TLS 1.3 + hardened 1.2 — client and server, AEAD-only and forward-secret
  • Post-quantum hybrid key exchange (X25519MLKEM768) on by default
  • Secure by default, fail-closed — every foot-gun sits behind one loudly-named "dangerous" surface
  • Full trust pipeline — PKIX validation, hostname/SAN checks, public-key pinning, stapled + live OCSP/CRL, opt-in OS system trust, mutual TLS
  • Resumption, PSK & 0-RTT — 1.3 tickets, 1.2 session resumption, RFC 9258 external PSKs
  • sans-IO engine — no sockets, threads, or timers baked in
Easy to plug in — three ways, all over the same engine:
  • a batteries-included TTlsLib facade
  • a TTlsStream over a tiny two-method transport interface
  • drop-in adapters for mORMot, Indy, Synapse, and fcl-net — TLS through each stack's own SSL seam
Trustworthy — conformance-tested against BoringSSL's BoGo suite (required CI gate), an OpenSSL interop matrix, RFC 8448 byte-exact vectors, and structure-aware fuzzing. Runs on Windows, Linux, macOS and the BSDs.

Only dependency is CryptoLib4Pascal (the crypto backend).

GitHub: https://github.com/Xor-el/TlsLib4Pascal

Feedback, issues and PRs welcome!

Tomxe

  • Full Member
  • ***
  • Posts: 163
Re: TlsLib4Pascal
« Reply #1 on: August 13, 2026, 04:26:49 am »
That's amazing, thanks!

Tomxe

  • Full Member
  • ***
  • Posts: 163
Re: TlsLib4Pascal
« Reply #2 on: August 13, 2026, 01:18:22 pm »
I changed my FTP client to use your library instead of OpenSSL and it works really nice!

Now it would be great to have SSH libraries in Pascal and FTP/SFTP/FTPS would work with no DLLs!
« Last Edit: August 13, 2026, 01:26:46 pm by Tomxe »

Xor-el

  • Sr. Member
  • ****
  • Posts: 428
Re: TlsLib4Pascal
« Reply #3 on: August 13, 2026, 01:50:38 pm »
I changed my FTP client to use your library instead of OpenSSL and it works really nice!

Now it would be great to have SSH libraries in Pascal and FTP/SFTP/FTPS would work with no DLLs!

Glad it worked for you and thanks for testing.

LemonParty

  • Hero Member
  • *****
  • Posts: 657
Re: TlsLib4Pascal
« Reply #4 on: August 13, 2026, 02:08:48 pm »
Cryptography is a complex thing. Nice work.
Could you give me a hint where in your project placed units that do an actual cryptography?
Lazarus v. 4.99. FPC v. 3.3.1. Windows 11

cdbc

  • Hero Member
  • *****
  • Posts: 2945
    • http://www.cdbc.dk
Re: TlsLib4Pascal
« Reply #5 on: August 13, 2026, 02:18:48 pm »
Hi
Only dependency is CryptoLib4Pascal (the crypto backend).
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6/QT6 -> FPC Release -> Lazarus Release &  FPC Main -> Lazarus Main

Xor-el

  • Sr. Member
  • ****
  • Posts: 428
Re: TlsLib4Pascal
« Reply #6 on: August 13, 2026, 03:06:13 pm »
Cryptography is a complex thing. Nice work.
Could you give me a hint where in your project placed units that do an actual cryptography?

The cryptographic operations are abstracted behind an `ICryptoProvider` interface, making it easy to swap the underlying cryptographic provider without requiring any changes to the library's core codebase. This provides a clean, pluggable architecture that allows users to integrate their preferred cryptographic backend.

The default provider is available here:
TlpDefaultCryptoProvider.pas

It currently uses CryptoLib4Pascal as its backing cryptographic provider.

PierceNg

  • Sr. Member
  • ****
  • Posts: 444
    • SamadhiWeb
Re: TlsLib4Pascal
« Reply #7 on: August 15, 2026, 10:01:15 am »
I cross compiled a simple HTTP client from Linux x86_64 to Linux aarch64 and Windows x86_64. Both cross compiled targets work fine.

A pure Pascal TLS library implementation is a great capability. Thank you for making this available.

Thaddy

  • Hero Member
  • *****
  • Posts: 19805
  • Glad to be alive.
Re: TlsLib4Pascal
« Reply #8 on: August 15, 2026, 11:11:16 am »
No more OpenSSL versioning problems! Simply use this. Great!
The dependency list is a bit obscured, though.
A simple example what what you actually need as packages, but it works great:
Code: Pascal  [Select][+][-]
  1. {$mode delphi}
  2. {
  3.   package dependencies:
  4.   // standard distro
  5.   - fcl-net
  6.   - fcl-web
  7.   // The main feature, i.e. Xor-El's packages.
  8.   - TlsLib4PascalPackage
  9.   // Options for TlsLib
  10.   - TlsLib.Adapter.FclNet;
  11.   - TlsLib.Trust.System
  12.   // The crypto
  13.   - CryptoLib4PascalPackage
  14.   - HashLib4PascalPackage
  15.   - SimpleBaseLib4PascalPackage
  16. }
  17. uses
  18.   ssockets,fphttpclient,TlpTlsLib, TlpITlsConfig,TlsLibFclNetTls;
  19.  
  20. begin
  21.   TlsLibFclNetTrustDefaults.UseSystemTrust := True;// do this once.
  22.   writeln(TFPHTTPClient.SimpleGet('https://example.com'));
  23.   readln;
  24. end.

No dll/so's, no versioning problems, self-contained.
This simple example does not handle redirects (http 301/308) but that is easy to handle in your own code as usual (but OpenSsl based code also would not handle that with this example).
Existing code needs hardly any changes, apart from the uses clause and the first line.
 
« Last Edit: August 15, 2026, 04:59:03 pm by Thaddy »
Any "programmer" that knows only one programming language is not a programmer

Thaddy

  • Hero Member
  • *****
  • Posts: 19805
  • Glad to be alive.
Re: TlsLib4Pascal
« Reply #9 on: August 15, 2026, 05:27:52 pm »
With redirects (avoids 301/308):
Code: Pascal  [Select][+][-]
  1. {$mode delphi}
  2. {
  3.   package dependencies:
  4.   // standard distro
  5.   - fcl-net
  6.   - fcl-web
  7.   // The main feature
  8.   - TlsLib4PascalPackage
  9.   // Options for TlsLib
  10.   - TlsLib.Adapter.FclNet;
  11.   - TlsLib.Trust.System
  12.   // The crypto
  13.   - CryptoLib4PascalPackage
  14.   - HashLib4PascalPackage
  15.   - SimpleBaseLib4PascalPackage
  16. }
  17. uses
  18.   ssockets, fphttpclient, TlpTlsLib, TlpITlsConfig,TlsLibFclNetTls;
  19. var
  20.   Client:TFpHttpClient;
  21. begin
  22.   TlsLibFclNetTrustDefaults.UseSystemTrust := True;
  23.   Client := TFpHttpClient.Create(nil);
  24.   try
  25.     Client.AllowRedirect := true;
  26.     writeln(Client.Get('https://freepascal.org'));
  27.   finally  
  28.     Client.Free;
  29.   end;
  30.   readln;
  31. end.
Any "programmer" that knows only one programming language is not a programmer

Thaddy

  • Hero Member
  • *****
  • Posts: 19805
  • Glad to be alive.
Re: TlsLib4Pascal
« Reply #10 on: August 17, 2026, 07:04:33 am »
After the forum problems this weekend I noticed it is better to add some exception handling  :D
Code: Pascal  [Select][+][-]
  1. {$mode delphi}
  2. {
  3.   package dependencies:
  4.   // standard distro
  5.   - fcl-net
  6.   - fcl-web
  7.   // The main feature
  8.   - TlsLib4PascalPackage
  9.   // Options for TlsLib
  10.   - TlsLib.Adapter.FclNet;
  11.   - TlsLib.Trust.System
  12.   // The crypto
  13.   - CryptoLib4PascalPackage
  14.   - HashLib4PascalPackage
  15.   - SimpleBaseLib4PascalPackage
  16. }
  17. uses
  18.   sysutils, ssockets, fphttpclient, TlpTlsLib, TlpITlsConfig,TlsLibFclNetTls;
  19. var
  20.   Client:TFpHttpClient;
  21. begin
  22.   TlsLibFclNetTrustDefaults.UseSystemTrust := True;
  23.   Client := TFpHttpClient.Create(nil);
  24.   try
  25.     Client.AllowRedirect := true;
  26.     try
  27.       writeln(Client.Get('https://forum.lazarus.freepascal.org'));
  28.     except
  29.       On E:Exception do writeln(e.message);
  30.     end;
  31.   finally
  32.     Client.Free;
  33.   end;
  34.   readln;
  35. end.
This catches time-outs, connection refused and the lot...
Sorry for the oversight, but the changes are minimal.
I usually limit the use of exceptions in examples, but in this case they are actually necessary.

[edit] Black Sheep mode:
Code: Pascal  [Select][+][-]
  1. {$mode unleashed}
  2. uses
  3.   sysutils, ssockets, fphttpclient, TlpTlsLib, TlpITlsConfig,TlsLibFclNetTls;
  4. begin
  5.   TlsLibFclNetTrustDefaults.UseSystemTrust := True;
  6.   with var Client := autofree TFpHttpClient.Create(nil) do
  7.   begin
  8.     AllowRedirect := true;
  9.     var s:string := try Get('https://forum.lazarus.freepascal.org') except
  10.       On E:Exception do e.message else '';
  11.     writeln(s);
  12.   end;
  13.   readln;
  14. end.

« Last Edit: August 17, 2026, 07:46:57 am by Thaddy »
Any "programmer" that knows only one programming language is not a programmer

AlexTP

  • Hero Member
  • *****
  • Posts: 2740
    • UVviewsoft
Re: TlsLib4Pascal
« Reply #11 on: August 17, 2026, 09:59:40 am »
As I see in the example:

Code: Pascal  [Select][+][-]
  1. uses
  2.   sysutils, ssockets, fphttpclient, TlpTlsLib, TlpITlsConfig,TlsLibFclNetTls;

unit names have leading 'T' which is not nice. 'T' is for types. Also, 'Tlp' and 'Tls', different beginnings. Can you make one prefix (w/o 'T')? 'Xorel' will be nice.

All new types - maybe better use the similar prefix. 'TXorel' for example will be nice.
« Last Edit: August 17, 2026, 10:04:07 am by AlexTP »

Thaddy

  • Hero Member
  • *****
  • Posts: 19805
  • Glad to be alive.
Re: TlsLib4Pascal
« Reply #12 on: August 17, 2026, 10:58:52 am »
@AlexTP
Why? it is about Tls and related. I would not change a thing. Feels comfortable to me. Scan the source tree of the FPC and Lazarus distribution.
Been testing this for days.

Better complain about user defined types that do not have a T prefixed.... :-X

@Xor-El, I personally would not refactor this.
The Typinfo and Types units and all TestXXX units also will never get refactored.  :P :P (A lot more examples available....e.g. many of my units have a tdk prefix)

This is silly. :'(

474 real unit files start with T, broken down by top-level directory:

Directory   T-units
tests/ (test-support units, not test programs: then total is 5566)   277
packages/   145
compiler/   34
rtl/   12
utils/   4
ide/   2

Claude counted that for me...
Claude used a naive find . -iname 't*.pp' -o -iname 't*.pas' gives 5566 and filtered the unit names from programs.
« Last Edit: August 17, 2026, 11:27:35 am by Thaddy »
Any "programmer" that knows only one programming language is not a programmer

Xor-el

  • Sr. Member
  • ****
  • Posts: 428
Re: TlsLib4Pascal
« Reply #13 on: August 17, 2026, 12:05:11 pm »
As I see in the example:

Code: Pascal  [Select][+][-]
  1. uses
  2.   sysutils, ssockets, fphttpclient, TlpTlsLib, TlpITlsConfig,TlsLibFclNetTls;

unit names have leading 'T' which is not nice. 'T' is for types. Also, 'Tlp' and 'Tls', different beginnings. Can you make one prefix (w/o 'T')? 'Xorel' will be nice.

All new types - maybe better use the similar prefix. 'TXorel' for example will be nice.


Hi AlexTP,

The Tlp prefix on the core units is deliberate - it follows the same convention across my whole library family, so the internals stay consistent and collision-free:

  • CryptoLib4Pascal → Clp
  • HashLib4Pascal → Hlp
  • SimpleBaseLib4Pascal → Sbp
  • TlsLib4Pascal → Tlp
The adapters are the one intentional exception, and I think it's the right one. They aren't core engine units - they're the outward-facing integration shims a user explicitly adds to their uses clause (uses TlsLibIndyTls;, TlsLibSynapseTls, …). There, TlsLib<Framework>Tls is self-documenting: it says exactly what the unit is, which reads better at the point of integration than a terse namespace prefix would.

The sibling libraries have no adapters, so there's no family convention to break - the core keeps the prefix, and the adapters get a name that's clearest where it matters most, at the point of use.

So I'll leave them as-is. Appreciate the discussion. :)

Xor-el

  • Sr. Member
  • ****
  • Posts: 428
Re: TlsLib4Pascal
« Reply #14 on: August 17, 2026, 12:05:50 pm »
@AlexTP
Why? it is about Tls and related. I would not change a thing. Feels comfortable to me. Scan the source tree of the FPC and Lazarus distribution.
Been testing this for days.

Better complain about user defined types that do not have a T prefixed.... :-X

@Xor-El, I personally would not refactor this.
The Typinfo and Types units and all TestXXX units also will never get refactored.  :P :P (A lot more examples available....e.g. many of my units have a tdk prefix)

This is silly. :'(

474 real unit files start with T, broken down by top-level directory:

Directory   T-units
tests/ (test-support units, not test programs: then total is 5566)   277
packages/   145
compiler/   34
rtl/   12
utils/   4
ide/   2

Claude counted that for me...
Claude used a naive find . -iname 't*.pp' -o -iname 't*.pas' gives 5566 and filtered the unit names from programs.

Thanks for your input, Thaddy.

 

TinyPortal © 2005-2018