Running without OpenSSL

sgcWebSockets can run with no OpenSSL library at all. Two independent settings make that possible, and both are built on the pure Pascal sgcCrypto units, which ship from the Standard edition up.

An application that needs OpenSSL neither for its connections nor for its other cryptography uses both.

1. Runtime switch: sgcCryptoBackend

The unit sgcBase_Helpers declares the global variable sgcCryptoBackend of type TsgcCryptoBackend:

The switch is global, not per component. Set it once at startup, before any component is created. sgcUseNativeCrypto returns True when the native backend is in use. The native backend needs the sgcCrypto units compiled in (SGC_CRYPTO). Without them, cbNative raises the exception "Native crypto not available, sgcCrypto units are not compiled in". Call sgcCheckNativeCrypto to get that error at startup instead of on first use.

uses
  sgcBase_Helpers;

begin
  sgcCryptoBackend := cbNative;
  sgcCheckNativeCrypto;
  Application.Initialize;
  ...

These parts follow the switch:

Area What runs natively
Hash and HMAC helpers The hash and HMAC functions of sgcBase_Helpers, and sgcEncryptString / sgcDecryptString.
JWT, JWS signatures HMAC, RSA, RSA-PSS, ECDSA and EdDSA signing and verification (sgcSSL_RSA, sgcSSL_PS, sgcSSL_ES, sgcSSL_ED). sgcES_GetCurveFromPublicKey works only on an OpenSSL key and raises on the native backend.
Certificates The sgcSSL helpers: PEM and DER conversion, certificate loading, CRL URI and certificate chain verification.
OAuth2 and DPoP The OAuth2 JWK helper, and the DPoP proof check of the OAuth2 server (ES256, ES384, ES512, RS256, RS384, RS512). See DPoP.
Amazon AWS Signature V4, the CloudFront signed URL, and the Signature V4 authentication of the Amazon IoT MQTT client, whose SignatureV4.OpenSSL_Options are then ignored.
Web Push The VAPID ES256 token, the ECDH key agreement, HKDF and the AES-128-GCM payload encryption. Only an https connection to the push service loads a TLS library, through its IOHandler.
E2EE Key agreement, AES-GCM and the random generator. The public keys go on the wire as PEM on both backends, raw keys are still accepted, so peers on different backends interoperate.
WebAuthn, SAML, OIDC The WebAuthn certificate, COSE key and attestation checks, and the XMLDSig signature check used by SAML and OIDC.
NTLM The MD4 and DES code of NTLM authentication. It is native in every build and no longer needs any define.
AEAD, KEM, HKDF sgcSSL_AEAD (AES-128-GCM, AES-256-GCM, ChaCha20-Poly1305), sgcSSL_KEM (ML-KEM-768 and ECDH P-256) and sgcSSL_HKDF (now also with sgcHKDF_MD_SHA384). ML-KEM-768 does not need OpenSSL 3.5, and the keys use the same encodings as OpenSSL 3.5. In a FIPS build ChaCha20-Poly1305 is not available and raises.
QUIC, DTLS, SRTP QUIC packet protection, the DTLS certificate and SRTP. With iohNativeTLS they are already native per connection, whatever the switch says.

sgcCryptoBackend does not change the TLS connection of a component. A component that keeps IOHandler = iohOpenSSL still loads OpenSSL when it connects.

2. Optional define: SGC_NATIVE_CRYPTO

The define is off by default and is no longer needed to run without OpenSSL. Without it, both the OpenSSL and the native code are compiled and sgcCryptoBackend decides at runtime. With it, the native backend is forced whatever sgcCryptoBackend says, and the OpenSSL code is removed from the application crypto units, so the executable is smaller. To enable it, open sgcVer.inc and remove the dot from the line

{.$DEFINE SGC_NATIVE_CRYPTO}

or add SGC_NATIVE_CRYPTO to the conditional defines of your project. SGC_NATIVE_CRYPTO also turns on SGC_CRYPTO, the sgcCrypto units it needs. DISABLE_SGC_NATIVE_CRYPTO turns it off again.

3. Zero OpenSSL at runtime

Which settings you need depends on what the application uses:

Area Settings for no OpenSSL
TLS over TCP: WebSocket, HTTP/1, HTTP/2, TCP, MQTT and the other protocols TLSOptions.IOHandler (client) or SSLOptions.IOHandler (server) = iohNativeTLS. See Native TLS.
QUIC and HTTP/3 IOHandler = iohNativeTLS. The handshake, the packet protection, key update and the Retry tag are all native. See QUIC and HTTP/3.
DTLS and WebRTC DTLSOptions.IOHandler = iohNativeTLS. The handshake, the DTLS certificate and the SRTP keys are native. See DTLSOptions and WebRTC DTLS.
Application crypto: JWT, OAuth2, Web Push, Amazon Signature V4, E2EE, WebAuthn, SAML and the other areas of the first table sgcCryptoBackend := cbNative at startup, or the SGC_NATIVE_CRYPTO define.

The iohNativeTLS rows need no define and no sgcCryptoBackend setting. Selecting iohNativeTLS in a build without the sgcCrypto units raises an exception, it never falls back to OpenSSL silently.

iohNativeTLS

With iohNativeTLS the TLS 1.3 and TLS 1.2 handshake and the record layer run on the native engine. It works for the WebSocket, HTTP/1, HTTP/2 and TCP clients and servers, and for everything built on them: MQTT, AMQP, STOMP and the other protocols, the API components, the IoT clients (Certificate.IOHandler), the upstream connection of the proxy server (Proxy.TLSOptions) and the LDAP client. The certificate may be PEM, DER or a .pfx / .p12 file.