Catalog · How the catalog works
DelphiLibOpenSSL
Static OpenSSL bindings for Delphi - provides a complete Pascal translation of OpenSSL APIs and pre-compiled object files for Win32/Win64 static linking.
- ★ 9 on GitHub
Anyone may press Interesting, signed in or not. It helps others find this project.
README
DelphiLibOpenSSL
A Delphi unit that provides complete static bindings to OpenSSL. Instead of dynamically loading OpenSSL DLLs at runtime, this project compiles OpenSSL C source code into .obj files and statically links them into Delphi applications.
This eliminates DLL deployment complexity and ensures version consistency.
Core Features
- Static linking - zero DLL deployment; everything compiles into a single
.exeor.bpl - Most complete Pascal translation of OpenSSL API headers (~16,000 lines), 4,993 API functions (~99.2% api coverage),
support for all major OpenSSL subsystems ( SSL/TLS, X.509, EVP, BIO, ASN.1, PKCS, CMS etc). see
Supported API Surfacechapter - Win32 + Win64 - pre-built objects for both platforms, multiple compiler toolchains
- Reproducible builds - build scripts for OpenSSL 3.x / 4.x branches see
Building Object Fileschapter - DUnitX test suite - 144 tests for OpenSSL 3.6.1 and 146 for OpenSSL 4.1.0, including TLS handshakes and ABI regressions
Supported API Surface
| Module | Functions | Description |
|---|---|---|
ASN.1 (ASN1_, d2i_, i2d_) |
760 | ASN.1 types, DER encoding/decoding |
EVP (EVP_) |
640 | High-level cryptographic operations |
X.509 (X509_, X509V3_) |
556 | Certificate creation, verification, extensions |
SSL/TLS (SSL_, TLS_, DTLS_) |
522 | Protocol handling, contexts, sessions |
OSSL (OSSL_) |
513 | OpenSSL 3 provider API, parameters, decoders |
Big Numbers (BN_) |
185 | Arbitrary-precision integer arithmetic |
BIO (BIO_) |
170 | Abstracted I/O (memory, file, socket, SSL) |
EC (EC_, ECDSA_) |
146 | Elliptic curve keys and signatures |
PEM (PEM_) |
140 | PEM-format read/write for keys and certs |
PKCS (PKCS5_, PKCS7_, PKCS8_, PKCS12_) |
136 | PKCS standards (key derivation, envelopes, keystores) |
Timestamp (TS_) |
124 | RFC 3161 timestamping |
CMS (CMS_) |
111 | Cryptographic Message Syntax (S/MIME) |
CRYPTO (CRYPTO_) |
101 | Core crypto utilities, memory, locking |
Legacy Ciphers (AES_, DES_, BF_, …) |
92 | Block cipher low-level API |
OPENSSL (OPENSSL_) |
92 | Library initialization, version, utilities |
DH / DSA (DH_, DSA_) |
91 | Diffie-Hellman and DSA key agreement/signatures |
OCSP (OCSP_) |
85 | Online Certificate Status Protocol |
RSA (RSA_) |
81 | RSA key operations |
Certificate Transparency (CT_, SCT_) |
49 | SCT verification, CT policy |
Other (UI_, SRP_, ERR_, OBJ_, RAND_, …) |
192 | UI prompts, SRP, errors, OIDs, random, HMAC, CONF |
Quick Start
- Add
libOpenSSL3to theusesclause of your project - In
libOpenSSL3.pas, verify the version define matches your needs (OPENSSL_3XorOPENSSL_4X) - Build for the desired platform (Win32 or Win64)
uses libOpenSSL3;
begin
OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS or
OPENSSL_INIT_LOAD_CRYPTO_STRINGS, nil);
// Ready to use SSL/TLS, EVP, X.509, etc.
end.By default the unit links 4.x objects. To switch to 3.x, comment out {$DEFINE OPENSSL_4X} and uncomment {$DEFINE OPENSSL_3X} at the top of libOpenSSL3.pas.
Compiler / Platform Matrix
| Configuration | Compiler | Platform | Object Format | Convention | Symbol Prefix |
|---|---|---|---|---|---|
| BORLAND_32 (default Win32) | BCC32 classic | Win32 | OMF | register |
(none) |
| BCC32C | BCC32C (Clang) | Win32 | OMF | cdecl |
_ |
| MSC_32 | MSVC x86 | Win32 | COFF | cdecl |
_ |
| MSC_64 (default Win64) | MSVC x64 | Win64 | COFF | single ABI | (none) |
| BORLAND_64 | BCC64 (Clang) | Win64 | ELF | single ABI | (none) |
To switch compilers, edit libOpenSSL3.pas — comment/uncomment the {$DEFINE C_COMPILER_*} lines in the compiler detection block (lines 86–97). For example, to use BCC64 for Win64 instead of the default MSVC:
{$IFDEF CPUX64}
//{$DEFINE C_COMPILER_MSC_64} // < comment out MSVC
{$DEFINE C_COMPILER_BORLAND_64} // < uncomment BCC64
{$ENDIF}Building Object Files
Since static linking of C code in Delphi imposes certain requirements on the source code (such as the use of case-insensitive identifier names, linking order, and dependencies on external code), and the OpenSSL source code does not fully meet these requirements, this project uses an approach based on dynamically modifying the source file tree. This task is performed by a set of scripts located in the helpers/ directory. I have tried to describe the changes made in detail directly within these scripts. A huge thanks to Rudy Velthuis for his series of posts in which he described the potential challenges associated with directly using compiled C code. You are no longer with us, but your contribution remains invaluable.
Prerequisites
| Tool | Required for | Notes |
|---|---|---|
| RAD Studio 12+ | BCC32 / BCC32C / BCC64 builds | Provides bcc32, bcc32c, bcc64 compilers |
| Visual Studio 2019+ | MSVC Win32 / Win64 builds | C++ workload with cl.exe |
| Perl (Strawberry Perl) | OpenSSL Configure step |
Required by all build scripts |
| Python 3.x | Helper/patch scripts | C89 patching, Makefile patching, symbol fixups |
OpenSSL Branch Selection
The project supports two OpenSSL branches simultaneously:
| Branch | Source Path | Object Dir | Pascal Define |
|---|---|---|---|
| 3.x | c_src/openssl-openssl-3.6.1/ |
obj3/ |
OPENSSL_3X |
| 4.x (default) | c_src/openssl-openssl-4.1.0/ |
obj4/ |
OPENSSL_4X |
In Pascal: set {$DEFINE OPENSSL_3X} or {$DEFINE OPENSSL_4X} at the top of libOpenSSL3.pas.
Only one may be active at a time (a compile-time guard enforces this).
In build scripts: set the OPENSSL_BRANCH environment variable before running:
set OPENSSL_BRANCH=3
build_openssl3_msvc_win64.batIf OPENSSL_BRANCH is not set, it defaults to 4.
Building Object Files
Prerequisites
| Tool | Version | Required For | Notes |
|---|---|---|---|
| RAD Studio | 12 Athens+ | BCC32 / BCC32C / BCC64 builds | Provides bcc32, bcc32c, bcc64, Borland make |
| Visual Studio | 2019+ | MSVC Win32 / Win64 builds | "Desktop development with C++" workload (cl.exe, nmake.exe) |
| Perl | Strawberry Perl 5.x | OpenSSL Configure step |
Required by all build scripts |
| Python | 3.8+ | Helper/patch scripts | C89 patching, Makefile patching, symbol fixups |
| NASM | 2.15+ (optional) | Assembly-optimized builds | MSVC scripts accept no-asm to skip; Embarcadero scripts always use no-asm |
Build Configuration — build_config.bat
All build scripts delegate environment setup to build_config.bat. Edit this file once to match your machine:
REM === Machine-specific paths (edit for your environment) ====================
set "PERL_DIR=C:\programdata\strawberry\perl\bin"
set "RAD_STUDIO=D:\Embarcadero RAD Studio\23.0"
set "VS_BUILD=D:\VisualStudio2019\VC\Auxiliary\Build"build_config.bat reads OPENSSL_BRANCH (default 4) and resolves the source path and output directory automatically:
| Variable | How it's set | Example (branch 4) |
|---|---|---|
OPENSSL_BRANCH |
Environment or default 4 |
4 |
OPENSSL_SRC |
Auto from branch | c_src\openssl-openssl-4.1.0 |
OBJ_DIR |
Auto from branch | obj4 |
RSVARS |
Per target | ...\rsvars.bat or ...\vcvars64.bat |
OBJ_OUT |
Per target | obj4\win64\vc |
Supported targets: bcc32_classic, bcc32c, bcc64, msvc_win32, msvc_win64
Build Scripts
| Script | Compiler | Platform | OpenSSL Target | Arguments |
|---|---|---|---|---|
build_openssl3_cbuilder_classic_win32.bat |
bcc32 (C89) | Win32 | BC-32-classic | (none) |
build_openssl3_cbuilder_win32.bat |
bcc32c (Clang) | Win32 | BC-32 | (none) |
build_openssl3_cbuilder_win64.bat |
bcc64 (Clang) | Win64 | BC-64 | (none) |
build_openssl3_msvc_win32.bat |
cl.exe x86 | Win32 | VC-WIN32 | [no-asm] |
build_openssl3_msvc_win64.bat |
cl.exe x64 | Win64 | VC-WIN64A | [no-asm] |
Each script:
- Calls
build_config.bat <target>to set up paths and compiler environment - Checks prerequisites (
perl, compiler,make/nmake) - Runs OpenSSL
Configurefor the target toolchain - Applies helper patches (C89, Makefile, static link, case collisions)
- Compiles with the platform-native
maketool - Renames outputs with
_win32/_win64suffixes into%OBJ_DIR%\<platform>\<compiler>\
Example — build OpenSSL 4.x objects for MSVC Win64:
set OPENSSL_BRANCH=4
build_openssl3_msvc_win64.batExample — build OpenSSL 3.x objects for BCC32 classic Win32:
set OPENSSL_BRANCH=3
build_openssl3_cbuilder_classic_win32.batNote: Embarcadero compiler scripts always build with
no-asmbecause NASM output is incompatible with the Embarcadero linker.
Helper Scripts
Build Pipeline Helpers (helpers/)
| File | Used By | Purpose |
|---|---|---|
patch_static_link.py |
all 5 scripts | Patch OpenSSL C sources for Delphi-compatible static linking |
patch_c89.py |
bcc32 classic | Downgrade C11 → C89 syntax for the classic Borland compiler |
patch_makefile_borland.py |
bcc32, bcc32c, bcc64 | Adapt generated Makefile for Embarcadero make |
ensure_bcc32_classic_conf.py |
bcc32 classic | Add BC-32-classic target to OpenSSL 50-cppbuilder.conf |
gen_case_collision_fixes.py |
bcc32, bcc32c, msvc32 | Verify / generate #define renames for case-colliding symbols |
openssl_fix_case_collisions.h |
bcc32c, bcc64, msvc32, msvc64 | C header force-included via /FI — renames case-colliding internals |
patch_coff_symbol.py |
bcc64 (Win64) | Demote a symbol from GLOBAL → LOCAL in COFF/ELF .obj to resolve W1028 linker conflicts; --scan / --demote |
patch_omf_symbol.py |
bcc32 (Win32) | Rename a symbol inside an OMF .obj (updates length-prefixed names, record lengths, checksums); --scan |
ossl3_ucrt_helper_win64.obj |
msvc64 | Pre-compiled UCRT shim stubs copied into Win64 output |
ossl3_ucrt_helper_win64.c |
(reference) | C source for the UCRT shim (rebuild manually if needed) |
Testing
Run both OpenSSL branches across all five compiler configurations:
tests\run_tests.bat allSet OPENSSL_BRANCH=3 or OPENSSL_BRANCH=4 to test one branch. The platform argument
can be win32, win64, or all. Compiler paths come from build_config.bat.
To repeat the matrix with an installed EurekaLog:
powershell -NoProfile -ExecutionPolicy Bypass -File tests\verify-matrix.ps1 -EurekaLogThe suite contains 144 DUnitX tests for OpenSSL 3.6.1 and 146 for OpenSSL 4.1.0
in tests/TestOpenSSL3API.pas, tests/TestOpenSSLRegressions.pas,
tests/TestOpenSSLAdditionalABI.pas, and tests/TestOpenSSLCallbackABI.pas. Coverage includes
verified TLS 1.2/1.3 handshakes over paired memory BIOs, binary application data,
untrusted certificate rejection, negotiated session duplication, and close_notify.
Crypto regressions cover RSA signing and tamper rejection, ECDH, AES-GCM known vectors
and invalid tags, CBC padding rejection, PBKDF2, and provider HMAC. Interop tests cover
OSSL_PARAM record returns and scalar widths, time_t, IPv4/IPv6 address formatting,
BIO backpressure, ASN.1 time boundaries, and isolated provider reloads. OpenSSL 4.x
adds SKEY and SKEYMGMT reference-counting tests. Additional ABI regressions cover
callback conventions, CRYPTO_EX_DATA layout, per-toolchain BN_ULONG widths,
parameter builders, octet output lengths, BIO va_list formatting, and version-specific
X509_ALGOR_set_md return types, narrow TLS scalars, and HPKE suite records by value.
Callback regressions cover four-argument legacy EVP enumeration, mutable ex-data
duplication, BIO method getters and observers, async callback output pointers,
provider dispatch tables, RAND method callbacks, and encrypted PEM passwords.
The matrix compiles a small C probe from the selected release archive with each
target C compiler and compares its sizeof/offsetof results for 13 public records
with the Delphi declarations. This requires Python and the five C toolchains.
The probe and its generated sources stay in the validation output directory;
ABI_LAYOUT_PROBE enables these two C interop tests in the matrix runner.
The runner checks that every discovered test executes, rejects warnings and failed
or ignored tests, and checks process termination as well as the test summary. Build
outputs and logs are written to
%LOCALAPPDATA%\DelphiLibOpenSSL-validation.
License
OpenSSL is licensed under the Apache License 2.0. The Delphi bindings in this repository follow the same license.
PostScriptum
I don't have enough time to fully maintain this project, so I've decided to make it publicly available; I hope others will find it useful.

