macula_tls (macula v0.14.3)
View SourceTLS Certificate Management and Verification Module (v0.11.0+)
This module provides TLS certificate management for Macula nodes with two operating modes:
- **Production Mode**: Strict certificate verification with CA bundle - **Development Mode**: Self-signed certificates (auto-generated)
Configuration (sys.config)
{macula, [ %% TLS mode: production (strict) or development (permissive) {tls_mode, development}, % or production
%% CA certificate bundle (production mode) {tls_cacertfile, "/path/to/ca-bundle.crt"},
%% Server/client certificate and key {tls_certfile, "/path/to/server.crt"}, {tls_keyfile, "/path/to/server.key"},
%% Hostname verification (production mode, default: true) {tls_verify_hostname, true} ]}
Environment Variables
- MACULA_TLS_MODE: production | development - MACULA_TLS_CACERTFILE: Path to CA bundle - MACULA_TLS_CERTFILE: Path to certificate - MACULA_TLS_KEYFILE: Path to private key
Security Note
In production mode, TLS connections will: - Verify the server certificate chain against the CA bundle - Reject expired or invalid certificates - Optionally verify hostname matches certificate CN/SAN
Summary
Functions
Derive Node ID from certificate public key.
Ensure TLS certificate exists, generate if missing.
Generate self-signed TLS certificate using OpenSSL.
Get default certificate paths from application environment.
Get the current TLS mode (production or development).
TLS verify_fun callback for hostname verification.
Check if running in production TLS mode.
Get QUIC client TLS options based on current TLS mode.
Get QUIC client TLS options with overrides.
Get QUIC client TLS options with hostname verification.
Get QUIC server TLS options based on current TLS mode.
Get QUIC server TLS options with overrides.
Functions
Derive Node ID from certificate public key.
Extracts the public key from the PEM-encoded certificate and computes SHA-256 hash to create a stable, cryptographically-derived Node ID.
-spec ensure_cert_exists(CertPath :: file:filename(), KeyPath :: file:filename()) -> {ok, file:filename(), file:filename(), binary()} | {error, term()}.
Ensure TLS certificate exists, generate if missing.
Checks if certificate and key files exist at the specified paths. If they don't exist, generates new self-signed certificate and saves to disk. Returns the paths and derived Node ID.
-spec generate_self_signed_cert(Opts :: map()) -> {ok, CertPEM :: binary(), KeyPEM :: binary()} | {error, term()}.
Generate self-signed TLS certificate using OpenSSL.
Creates a new RSA key pair and self-signed X.509 certificate with: - RSA 2048-bit key - 10-year validity period - Subject: CN=macula-node - Self-signed (issuer = subject)
-spec get_cert_paths() -> {file:filename(), file:filename()}.
Get default certificate paths from application environment.
-spec get_tls_mode() -> production | development.
Get the current TLS mode (production or development).
Checks in order: 1. MACULA_TLS_MODE environment variable 2. tls_mode application environment setting 3. Defaults to 'development'
-spec hostname_verify_fun(Cert :: term(), Event :: {bad_cert, term()} | {extension, term()} | valid | valid_peer, State :: map()) -> {valid, map()} | {fail, term()} | {unknown, map()}.
TLS verify_fun callback for hostname verification.
This function is called during TLS handshake to verify the peer certificate. When used with hostname verification, it checks that the server's certificate contains the expected hostname in either the Subject CN or Subject Alt Names.
Usage:
{verify_fun, {fun macula_tls:hostname_verify_fun/3, #{hostname => "example.com"}}}
-spec is_production_mode() -> boolean().
Check if running in production TLS mode.
-spec quic_client_opts() -> list().
Get QUIC client TLS options based on current TLS mode.
In production mode: Returns options with certificate verification enabled. In development mode: Returns options with verification disabled.
Get QUIC client TLS options with overrides.
Get QUIC client TLS options with hostname verification.
In production mode, adds SNI and hostname verification if enabled. In development mode, hostname verification is skipped.
-spec quic_server_opts() -> list().
Get QUIC server TLS options based on current TLS mode.
Server always needs a certificate and key. In production mode: Also verifies client certificates if presented. In development mode: Auto-generates self-signed certificate if needed.
Get QUIC server TLS options with overrides.