Jsec provides production-quality TLS/DTLS integration for Janet. The APIs are designed to closely follow Janet's standard conventions:
TLS streams implement Janet's full stream interface (
ev/read,ev/write,ev/chunk,ev/close) with identical signatures. TLS streams can be used anywhere Janet streams are expected - no special-casing required.DTLS follows Janet's UDP conventions (
net/recv-from,net/send-to) for the server-side API, and stream conventions for 1:1 client connections.
This design allows TLS/DTLS to be a drop-in replacement in existing code.
Janet Stream API Compatibility
TLS streams are designed to be fully compatible with Janet's stream API. This means:
Same function signatures:
ev/read,ev/write,ev/chunk,ev/closework identically on TLS streams as they do on plain TCP streams.Drop-in replacement: Code written for
net/connectcan usetls/connectwith no other changes. Generic stream-processing functions work unchanged.Optional parameter convention: Where Janet stream functions accept one optional parameter (e.g., timeout), jsec accepts either:
- The original type (number for timeout)
- A table/struct containing that parameter and optionally TLS-specific options
Only initialization differs:
tls/connectvsnet/connectandtls/listen~/~tls/acceptvsnet/listen~/~net/accepthave different signatures to accommodate TLS options.These work identically on TLS or plain TCP streams:
(ev/read stream 1024) # Read up to 1024 bytes (ev/write stream "hello") # Write data (ev/chunk stream 100) # Read exactly 100 bytes (ev/close stream) # Close with proper shutdown
Generic stream function - works with any stream type
(defn echo-handler stream] (ev/write stream data)))
Works with plain TCP
(echo-handler (net/connect "localhost" "8080"))
Works with TLS - no changes needed
(echo-handler (tls/connect "localhost" "8443" {:verify false}))
Modules
jsec/tls: TCP/TLS operations (Client & Server). Implements full Janet stream interface.jsec/dtls: UDP/DTLS operations (Client & Server). Follows Janet UDP conventions.jsec/cert: Certificate generation utilities.jsec/bio: Basic I/O abstraction (memory BIOs).jsec/crypto: Cryptographic primitives (hashing, signing).
For working examples of all functionality, see the examples directory.
Module: jsec/tls
(tls/new-context opts)
Create a reusable TLS context.
- opts: Table/struct.
:cert: Path to certificate (PEM) or PEM content (string/buffer).:key: Path to private key (PEM) or PEM content (string/buffer).:verify: Boolean (defaulttruefor client).:ca-file: Path to CA certificate file or PEM content (string/buffer).:ca-path: Path to CA certificate directory.:security: Security options.:alpn: List of ALPN protocols (e.g.["h2" "http/1.1"]).:sni: (Server only) Table of hostname -> options for virtual hosting. Example:{"example.com" {:cert "..." :key "..."}}.
Returns: A TLS context object.
Example: See echo_server.janet for context creation and reuse.
(tls/connect host port &opt opts)
Connect to a TLS server.
- host: String (hostname or IP) or
:unixfor Unix sockets. - port: String (port number) or path for Unix sockets.
- opts: Optional table/struct OR a TLS context object.
- If a context is passed, it is used for the connection.
- If a table is passed:
:verify: Boolean (defaulttrue). Verify server certificate.:hostname: String. SNI hostname. Defaults tohostfor TCP, "localhost" for Unix.:verify-hostname: String. Hostname to verify against certificate (defaults to:hostname).:session: Byte string. Session data for resumption (fromget-session).:cert: String/buffer. Client certificate (PEM) for mTLS.:key: String/buffer. Client private key (PEM) for mTLS.:trusted-cert: String/buffer. Trust specific cert (for self-signed servers).:buffer-size: Integer. Internal TLS buffer size (default 16384).:tcp-nodelay: Boolean. Enable TCP_NODELAY (defaulttrue).:handshake-timing: Boolean. Track handshake duration (defaultfalse).:security: Table. Security options (see Security Options).:alpn: List of ALPN protocols.:ca-file: Path to CA certificate file or PEM content (string/buffer).:ca-path: Path to CA certificate directory.
Returns: A TLS stream object.
Examples:
- simple_https_client.janet - Basic HTTPS GET request
- session_resumption.janet - Using session resumption
- mtls_client_server.janet - Mutual TLS authentication
(tls/listen host port &opt opts)
Create a TCP listener. This is a wrapper around net/listen.
- host: Bind address.
- port: Bind port.
- opts: Optional table.
:backlog: Integer. Listen backlog (default 1024).
Returns: A listener object.
(tls/accept listener opts)
Accept a connection from a listener and perform the TLS handshake.
- listener: Listener object from
tls/listen. - opts: Table/struct OR a TLS context object.
- If a context is passed, it is used for the connection.
- If a table is passed:
:cert: String. Path to server certificate (PEM) or PEM content (string/buffer).:key: String. Path to private key (PEM) or PEM content (string/buffer).:verify: Boolean (defaultfalse). Require and verify client certificate (mTLS).:trusted-cert: String/buffer. Trust specific client certificate (for mTLS with self-signed).:ca: String. Path to CA file for client certificate verification.:buffer-size: Integer. Internal TLS buffer size (default 16384).:tcp-nodelay: Boolean. Enable TCP_NODELAY (defaulttrue).:handshake-timing: Boolean. Track handshake duration (defaultfalse).:security: Table. Security options.:alpn: List of ALPN protocols.:ca-file: Path to CA certificate file (for mTLS) or PEM content.:ca-path: Path to CA certificate directory (for mTLS).
Returns: A TLS stream object.
(tls/accept-loop listener context handler)
Continuously accept TLS connections on a listener.
- listener: Listener object from
tls/listen. - context: TLS context object OR options table (same as
tls/accept).- Can include
:buffer-size,:tcp-nodelay,:handshake-timing.
- Can include
- handler: Function taking a TLS stream.
Returns: The listener stream (when closed).
(tls/upgrade stream hostname &opt opts)
Upgrade an existing plaintext stream to TLS (STARTTLS).
- stream: Existing connected
JanetStream. - hostname: String. SNI hostname.
- opts: Optional table (same as
connect).
Returns: A TLS stream object. Note: The original stream is consumed.
Example: See starttls_smtp.janet for SMTP STARTTLS upgrade.
(tls/wrap stream &opt hostname-or-opts opts)
Wrap an existing stream with TLS. Used for both client and server modes.
Client mode (provides hostname):
- stream: Existing connected
JanetStream. - hostname-or-opts: String. SNI hostname.
- opts: Optional table:
:verify: Boolean (defaulttrue). Verify server certificate.:cert: String/buffer. Client certificate (PEM) for mTLS.:key: String/buffer. Client private key (PEM) for mTLS.:trusted-cert: String/buffer. Trust specific cert (for self-signed).:session: Buffer. Session data for resumption.:buffer-size: Integer. Internal TLS buffer size.:tcp-nodelay: Boolean. Enable TCP_NODELAY (defaulttrue).:handshake-timing: Boolean. Track handshake duration (defaultfalse).:security: Table. Security options.:alpn: List of ALPN protocols.
Server mode (provides cert/key):
- stream: Existing connected
JanetStreamfrom:accept. - hostname-or-opts: Table/struct with:
:cert: String/buffer. Server certificate (PEM). Required.:key: String/buffer. Server private key (PEM). Required.:verify: Boolean. Iftrue, require client certificate (mTLS).:trusted-cert: String/buffer. Trust specific client cert.:ca: String. Path to CA file for client cert verification.:buffer-size: Integer. Internal TLS buffer size.:tcp-nodelay: Boolean. Enable TCP_NODELAY (defaulttrue).:handshake-timing: Boolean. Track handshake duration (defaultfalse).:security: Table. Security options.:alpn: List of ALPN protocols.
Returns: A TLS stream object.
Examples:
# Client mode - connect with client certificate (mTLS)
(def tls (tls/wrap tcp-stream "example.com"
{:cert client-cert :key client-key :verify false}))
# Server mode - require client certificate (mTLS)
(def tls (tls/wrap accepted-stream
{:cert server-cert :key server-key
:verify true :trusted-cert client-cert}))
Stream Methods (Janet Stream API Compatible)
TLS streams implement Janet's standard stream interface. They work with:
ev/read/:read- Read data from the streamev/write/:write- Write data to the streamev/chunk/:chunk- Read exactly n bytes or until EOFev/close/:close- Close with proper TLS shutdown
(ev/read stream n &opt buf timeout)
Read up to n bytes from the TLS stream.
- stream: TLS stream object
- n: Maximum bytes to read
- buf: Optional buffer to read into
- timeout: Optional timeout in seconds
Returns: Buffer with data, or nil on EOF.
(ev/write stream data &opt timeout)
Write data to the TLS stream.
- stream: TLS stream object
- data: String or buffer to write
- timeout: Optional timeout in seconds
Returns: nil
(ev/chunk stream n &opt buf timeout)
Read exactly n bytes, or until EOF.
- stream: TLS stream object
- n: Exact number of bytes to read
- buf: Optional buffer to read into
- timeout: Optional timeout in seconds
Returns: Buffer with data.
(ev/close stream)
Close the TLS stream with proper RFC-compliant shutdown.
Performs async bidirectional close_notify exchange before closing the
underlying transport. Safe to use with Janet's with macro.
- stream: TLS stream object
Note: For unresponsive peers, use (:close stream true) to force immediate
close without TLS shutdown.
TLS Stream Methods (via jsec/tls-stream)
These methods are available on TLS stream objects. Access via method syntax
(:method stream args...) or import jsec/tls-stream for function versions.
Connection Information
(:connection-info stream)or(tls-stream/connection-info stream)Returns a struct with connection details::version: TLS version (e.g., "TLSv1.3"):cipher: Cipher suite name:cipher-bits: Cipher strength:alpn: Negotiated ALPN protocol:server-name: SNI hostname
(:version stream)or(tls-stream/version stream)Returns TLS version string (e.g., "TLSv1.3")(:cipher stream)or(tls-stream/cipher stream)Returns cipher suite name(:cipher-bits stream)or(tls-stream/cipher-bits stream)Returns cipher bit strength as integer
Session Management
(:session-reused? stream)or(tls-stream/session-reused? stream)Returnstrueif session was resumed(:get-session stream)or(tls-stream/get-session stream)Returns session data (byte string) for resumption(:set-session stream data)or(tls-stream/set-session stream data)Sets session data (usually passed inconnectoptions instead)
TLS Operations
(:key-update stream)or(tls-stream/key-update stream)Request TLS 1.3 key update (post-handshake key rotation)(:renegotiate stream)or(tls-stream/renegotiate stream)Request TLS 1.2 renegotiation (disabled by default for security)(:set-ocsp-response stream data)or(tls-stream/set-ocsp-response stream data)Set OCSP stapling response(:shutdown stream &opt force)or(tls-stream/shutdown stream &opt force)Perform TLS shutdown. Ifforceis true, skip close_notify.
Certificate Trust
(tls-stream/trust-cert ctx cert-pem)Add a trusted certificate to a context. Used for trusting self-signed certs.
Example: See session_resumption.janet for session management. Example: See tls_key_update.janet for key update usage. Example: See connection_info.janet for connection info retrieval.
Module: jsec/dtls
DTLS provides TLS security for UDP datagrams. The API design:
- Server-side: Follows Janet's UDP conventions (
net/recv-from,net/send-to) for multiplexed peer handling on a single socket. - Client-side: 1:1 connections with stream-like
read~/~writefor simplicity.
Both DTLSServer and DTLSClient embed JanetStream and expose methods via the
standard (:method obj args...) syntax, matching Janet's stream patterns.
Stream Method Access
Both DTLSServer and DTLSClient support method dispatch:
# Server methods
(:recv-from server nbytes buf)
(:send-to server addr data)
(:close server)
(:localname server)
# Client methods
(:read client nbytes)
(:write client data)
(:close client)
Server API (UDP-style, multiple peers)
(dtls/listen host port &opt opts)
Create a DTLS server bound to an address.
- host: Bind address (string)
- port: Bind port (integer or string)
- opts: Table
:cert: Server certificate (PEM string). Required.:key: Server private key (PEM string). Required.:verify: Boolean (defaultfalse). Request client certificates (mTLS).:ca: CA certificates for client verification.:session-timeout: Session timeout in seconds (default 300).
Returns: A DTLS server object.
(dtls/recv-from server nbytes buf &opt timeout-or-opts)
Receive a datagram from any peer. Handles DTLS handshakes transparently.
- server: DTLS server object
- nbytes: Maximum bytes to receive
- buf: Buffer to receive data into
- timeout-or-opts: Number (timeout in seconds) or table
{:timeout n}
Returns: Peer address object, or nil on timeout.
Matches Janet's net/recv-from convention.
(dtls/send-to server addr data &opt timeout)
Send a datagram to a specific peer.
- server: DTLS server object
- addr: Peer address (from
recv-from) - data: Data to send (string or buffer)
- timeout: Optional timeout in seconds
Returns: Number of bytes sent.
(dtls/close-server server &opt force)
Close the server and all sessions.
- server: DTLS server object
- force: If true, skip close_notify alerts (default false)
(dtls/localname server)
Get the local address the server is bound to.
Returns: [host port] tuple.
Client API (1:1 connection)
(dtls/connect host port &opt opts)
Create a DTLS client connection. Performs handshake.
- host: String (hostname or IP address)
- port: Integer or string (port number)
- opts: Optional table
:verify: Boolean (defaulttrue). Verify server certificate.:cert: Client certificate for mTLS (PEM string).:key: Client private key for mTLS (PEM string).:ca: CA certificate (PEM string).:sni: Server name for SNI (defaults to host).:verify-hostname: Hostname to verify against cert.:handshake-timing: Boolean. Track handshake duration.
Returns: A DTLS client object.
(dtls/read client n &opt buf timeout)
Read a datagram from the connection.
- client: DTLS client object
- n: Maximum bytes to read
- buf: Optional buffer to read into
- timeout: Optional timeout in seconds
Returns: Buffer with data, or nil on EOF.
(dtls/write client data &opt timeout)
Write a datagram to the connection.
- client: DTLS client object
- data: Data to send (string or buffer)
- timeout: Optional timeout in seconds
Returns: Number of bytes written.
(dtls/close client &opt force)
Close the client connection.
- client: DTLS client object
- force: If true, skip close_notify (default false)
Address Utilities
(dtls-stream/address host port): Create an address object.(dtls-stream/address-host addr): Get host string from address.(dtls-stream/address-port addr): Get port number from address.(dtls-stream/address? x): Check if x is a DTLS address object.
DTLS Stream Methods (via jsec/dtls-stream)
These methods are available on DTLS server and client objects. Access via method
syntax (:method obj args...) or import jsec/dtls-stream for function versions.
Connection Information (Client)
(:connection-info client)or(dtls-stream/connection-info client)Returns a struct with connection details::version: DTLS version (e.g., "DTLSv1.2"):cipher: Cipher suite name:cipher-bits: Cipher strength
(:version client)or(dtls-stream/version client)Returns DTLS version string(:cipher client)or(dtls-stream/cipher client)Returns cipher suite name(:cipher-bits client)or(dtls-stream/cipher-bits client)Returns cipher bit strength(:peername client)or(dtls-stream/peername client)Returns peer address as[host port]tuple
Session Management (Client)
(:session-reused? client)or(dtls-stream/session-reused? client)Returnstrueif session was resumed(:get-session client)or(dtls-stream/get-session client)Returns session data for resumption(:set-session client data)or(dtls-stream/set-session client data)Sets session data
DTLS Operations
(:shutdown client &opt force)or(dtls-stream/shutdown client &opt force)Perform DTLS shutdown. Ifforceis true, skip close_notify.(:chunk client n &opt buf timeout)or(dtls-stream/chunk client ...)Read exactly n bytes (for client connections)
Certificate Trust
(dtls-stream/trust-cert ctx cert-pem)Add a trusted certificate to a context.
Upgrade (STARTTLS equivalent)
(dtls-stream/upgrade stream &opt opts)Upgrade an existing UDP socket to DTLS.
Example: See dtls_echo.janet for complete DTLS usage. Example: See dtls_session_resumption.janet for session resumption. Example: See dtls_connection_info.janet for connection info.
Module: jsec/cert
(cert/generate-self-signed-cert opts)
Generate a self-signed X.509 certificate and private key.
- opts: Table.
:common-name: String (default "localhost").:days-valid: Integer (default 365).:bits: Integer, RSA key size (default 2048, only for RSA).:key-type: Keyword, key algorithm (default:rsa). Supported::rsa,:ec-p256,:ec-p384,:ec-p521,:ed25519:country: String (default "US").:organization: String (default "Test").
Note: Generated certificates have CA:TRUE basic constraint set.
Returns: Struct {:cert "PEM..." :key "PEM..."}.
(cert/generate-self-signed-from-key key-pem opts)
Generate a self-signed certificate using an existing private key.
- key-pem: Existing private key in PEM format.
- opts: Table.
:common-name: String (default "localhost").:days-valid: Integer (default 365).:country: String (default "US").:organization: String (default "Test").
Note: Generated certificates have CA:TRUE basic constraint set.
Returns: Certificate PEM string.
(cert/parse cert-pem)
Parse an X.509 certificate and return its details.
- cert-pem: Certificate in PEM format.
Returns: Table with:
:version- Certificate version (1, 2, or 3):serial- Serial number as hex string:subject- Subject fields{:cn :o :ou :c :st :l :email :dn}:issuer- Issuer fields (same structure as subject):not-before- Validity start (Unix timestamp):not-after- Validity end (Unix timestamp):public-key- Key info{:type :bits :curve}:san- Subject Alternative Names array:key-usage- Key usage array:ext-key-usage- Extended key usage array:is-ca- Boolean indicating if cert is a CA:fingerprint-sha256- SHA-256 fingerprint:fingerprint-sha1- SHA-1 fingerprint:signature-algorithm- Signature algorithm name:pem- Original PEM data
(cert/fingerprint cert-pem &opt algorithm)
Calculate certificate fingerprint.
- cert-pem: Certificate in PEM format.
- algorithm: Hash algorithm (default
:sha256). Supported::sha256,:sha384,:sha512,:sha1.
Returns: Fingerprint as hex string with colons.
(cert/verify-signature cert-pem issuer-cert-pem)
Verify that a certificate was signed by the issuer.
- cert-pem: Certificate to verify.
- issuer-cert-pem: Issuer's certificate.
Returns: Boolean (true if signature valid).
(cert/verify-chain cert-pem &opt opts)
Verify a certificate against a trust chain.
- cert-pem: Certificate to verify.
- opts: Optional table.
:chain- Array of intermediate certificate PEMs.:trusted- Array of trusted root certificate PEMs.:trusted-dir- Directory of trusted certs (OpenSSL hash format).:purpose- Certificate purpose (:server-auth,:client-auth,:code-signing,:email-protection,:timestamp,:any).:hostname- Verify hostname in SAN/CN.:time- Verify at specific Unix timestamp.:check-crl- Enable CRL checking.:crl- CRL PEM to check against.
Returns: Table:
{:valid true :chain [<pem> ...]}on success{:valid false :error "message" :depth N}on failure
(cert/build-chain cert-pem intermediates trusted)
Build a certificate chain from cert to trusted root.
- cert-pem: Certificate to start chain from.
- intermediates: Array of intermediate PEMs or single PEM with multiple certs.
- trusted: Array of trusted root PEMs or single PEM.
Returns: Array of PEM strings from cert to root, or nil if chain can't be built.
Example: See cert_gen.janet for certificate generation usage.
Module: jsec/ca
The CA module provides a complete Certificate Authority implementation for managing X.509 certificates.
For detailed examples, tutorials, and advanced usage patterns, see CA.org.
(ca/generate &opt opts)
Generate a new self-signed root CA.
- opts: Optional table.
:common-name- CA common name (default "Root CA").:days-valid- Validity period in days (default 3650).:key-type- Key type::ec-p256,:ec-p384,:rsa-2048, etc. (default:ec-p256).:serial- Starting serial number for issued certs (default 1).:track-issued- Track issued certificates in memory (defaultfalse).:organization- Organization name.:country- Two-letter country code.
Returns: CA object.
(ca/generate-intermediate parent-ca &opt opts)
Generate an intermediate CA signed by a parent CA.
- parent-ca: Parent CA object.
- opts: Same as
ca/generateplus::path-length- Maximum sub-CAs allowed (default 0).
Returns: CA object.
(ca/create cert-pem key-pem &opt opts)
Create a CA from existing certificate and private key.
- cert-pem: CA certificate in PEM format.
- key-pem: CA private key in PEM format.
- opts: Optional table.
:serial- Current serial number (for restoration).:track-issued- Track issued certificates.
Returns: CA object.
(:issue ca &opt opts) / (ca/issue ca &opt opts)
Generate a new certificate (key + cert in one step).
- ca: CA object.
- opts: Optional table.
:common-name- Certificate common name. Required.:san- Subject Alternative Names array (e.g.,["DNS:example.com" "IP:1.2.3.4"]).:days-valid- Validity period (default 365).:key-type- Key type (default:ec-p256).:extended-key-usage- e.g., "serverAuth", "clientAuth".:key-usage- Override key usage extension.:organization- Organization name.:country- Country code.
Returns: {:cert <pem> :key <pem>}
(:sign-csr ca csr-pem &opt opts) / (ca/sign ca csr-pem &opt opts)
Sign a Certificate Signing Request.
- ca: CA object.
- csr-pem: CSR in PEM format.
- opts: Optional table.
:days-valid- Validity period (default 365).:serial- Override serial number.:copy-extensions- Copy extensions from CSR (defaultfalse).:extended-key-usage- Extended key usage.:san- Subject Alternative Names.
Returns: Certificate in PEM format.
(:get-cert ca) / (ca/get-cert ca)
Get the CA's certificate in PEM format.
(:get-serial ca) / (ca/get-serial ca)
Get the CA's current serial number. Use for persistence.
(:set-serial ca serial) / (ca/set-serial ca serial)
Set the CA's serial number. Use to restore from persistence.
(:revoke ca serial &opt reason) / (ca/revoke ca serial &opt reason)
Revoke a certificate by serial number.
- serial: Certificate serial number.
- reason: Revocation reason keyword (
:key-compromise,:superseded, etc.).
(:generate-crl ca &opt opts) / (ca/crl ca &opt opts)
Generate a Certificate Revocation List.
- opts: Optional table.
:days-valid- CRL validity period (default 30).:revoked- Additional revocations array.
Returns: CRL in PEM format.
(:get-revoked ca) / (ca/get-revoked ca)
Get list of revoked certificate serials.
Returns: Array of {:serial N :reason <kw>} tables.
(ca/parse-ocsp-request request-bytes)
Parse an OCSP request (DER-encoded bytes).
Returns: {:issuer-name-hash :issuer-key-hash :serial :nonce}
(:create-ocsp-response ca request-info status &opt opts)
Create an OCSP response for a certificate status query.
- request-info: Parsed request from
ca/parse-ocsp-request. - status:
:good,:revoked, or:unknown. - opts: Optional table.
:revocation-time- When revoked (required if status:revoked).:revocation-reason- Why revoked.:this-update- Response validity start (default: now).:next-update- Response validity end (default: +1 day).:include-nonce- Echo nonce from request (defaulttrue).
Returns: DER-encoded OCSP response bytes.
(:is-tracking ca) / (ca/is-tracking ca)
Check if the CA is tracking issued certificates.
(:get-issued ca) / (ca/get-issued ca)
Get list of issued certificates (only if tracking enabled).
Returns: Array of PEM certificates, or nil if tracking disabled.
Module: jsec/bio
BIO (Basic I/O) provides OpenSSL's I/O abstraction layer for in-memory operations.
(bio/new-mem)
Create a memory BIO for in-memory I/O operations.
Returns: A BIO object.
(bio/read bio nbytes)
Read from a BIO.
- bio: BIO object
- nbytes: Maximum bytes to read
Returns: Buffer with data, or nil if no data available.
(bio/write bio data)
Write to a BIO.
- bio: BIO object
- data: Data to write (string or buffer)
Returns: Number of bytes written.
(bio/to-string bio)
Read all pending data from a BIO as a string.
- bio: BIO object
Returns: String with all pending data.
(bio/close bio)
Free a BIO object and release its resources.
- bio: BIO object
Example: See bio_memory.janet and custom_bio_transport.janet.
Module: jsec/crypto
Hashing and Message Authentication
(crypto/digest algorithm data)
Compute a cryptographic hash.
- algorithm: String ("sha256", "sha384", "sha512", "sha1", "md5", etc.)
- data: Data to hash (string or buffer)
Returns: Buffer with hash bytes.
(crypto/hmac algorithm key data)
Compute HMAC (Hash-based Message Authentication Code).
- algorithm: Hash algorithm ("sha256", etc.)
- key: Secret key (string or buffer)
- data: Data to authenticate (string or buffer)
Returns: Buffer with HMAC bytes.
Key Generation and Management
(crypto/generate-key alg &opt bits)
Generate a private key in PEM format.
- alg: Keyword for key algorithm:
:rsa- RSA key (optional bits param, default 2048):ed25519- Ed25519 key (signing):x25519- X25519 key (key exchange/ECDH):ec-p256or:p256- EC P-256 curve:ec-p384or:p384- EC P-384 curve:ec-p521or:p521- EC P-521 curve
- bits: Optional key size for RSA (default 2048)
Returns: PEM-encoded private key string.
(crypto/export-public-key private-key-pem)
Extract public key from a private key.
- private-key-pem: PEM-encoded private key string
Returns: PEM-encoded public key string.
Signing and Verification
(crypto/sign key-pem data)
Sign data with a private key.
- key-pem: Private key in PEM format
- data: Data to sign (string or buffer)
Returns: Signature buffer.
(crypto/verify key-pem data signature)
Verify a signature.
- key-pem: Key in PEM format (public or private)
- data: Original data
- signature: Signature to verify
Returns: Boolean (true if valid).
Key Derivation
(crypto/hkdf algorithm key salt info length)
HKDF (HMAC-based Key Derivation Function).
- algorithm: Hash algorithm ("sha256", etc.)
- key: Input key material
- salt: Salt value (can be empty string)
- info: Context/application info
- length: Desired output length in bytes
Returns: Derived key buffer.
(crypto/pbkdf2 algorithm password salt iterations length)
PBKDF2 (Password-Based Key Derivation Function 2).
- algorithm: Hash algorithm
- password: Password string
- salt: Salt value
- iterations: Number of iterations (minimum 10000 recommended)
- length: Desired output length in bytes
Returns: Derived key buffer.
Random Data
(crypto/random-bytes n)
Generate cryptographically secure random bytes.
- n: Number of bytes
Returns: Buffer with random bytes.
Certificate Signing Requests
(crypto/generate-csr private-key-pem options)
Generate a Certificate Signing Request (CSR).
- private-key-pem: Private key in PEM format
- options: Table with subject and options:
:common-name- CN field (required for most CAs):country- C field (2-letter code):state- ST field:locality- L field:organization- O field:organizational-unit- OU field:email- emailAddress field:san- Array of Subject Alt Names (e.g.["DNS:example.com" "IP:1.2.3.4"]):digest- Signing digest (default:sha256)
Returns: PEM-encoded CSR string.
(crypto/parse-csr csr-pem)
Parse a PEM-encoded CSR.
- csr-pem: CSR in PEM format
Returns: Table with CSR information.
Challenge-Response
(crypto/generate-challenge &opt length)
Generate a random challenge for authentication protocols.
- length: Challenge length in bytes (default 32)
Returns: Buffer with random challenge.
CMS/PKCS#7 Operations
For SCEP/ACME foundations and secure message exchange.
(crypto/cms-sign data cert key &opt opts)
Sign data using CMS (Cryptographic Message Syntax).
- data: Data to sign
- cert: Signer certificate (PEM)
- key: Signer private key (PEM)
- opts: Optional table
:detached: Boolean. If true, create detached signature.
Returns: CMS signed data (DER or PEM based on input).
(crypto/cms-verify cms-data &opt opts)
Verify a CMS signature.
- cms-data: CMS signed data
- opts: Optional table
:ca: CA certificate for verification:detached: Original data if signature is detached
Returns: Table {:valid true/false :content data :certs [...]}
(crypto/cms-encrypt data certs &opt opts)
Encrypt data for recipients using CMS.
- data: Data to encrypt
- certs: Array of recipient certificates (PEM)
- opts: Optional table
:cipher: Cipher to use (default "aes-256-cbc")
Returns: CMS encrypted data.
(crypto/cms-decrypt cms-data cert key)
Decrypt CMS encrypted data.
- cms-data: Encrypted CMS data
- cert: Recipient certificate (PEM)
- key: Recipient private key (PEM)
Returns: Decrypted data buffer.
(crypto/cms-certs-only certs)
Create a CMS certs-only message (certificate chain).
- certs: Array of certificates (PEM)
Returns: CMS data containing certificates.
(crypto/cms-get-certs cms-data)
Extract certificates from CMS data.
- cms-data: CMS signed or certs-only data
Returns: Array of PEM-encoded certificates.
Base64 Encoding
(crypto/base64-encode data)
Base64 encode data.
Returns: Base64 string.
(crypto/base64-decode data)
Base64 decode data.
Returns: Decoded buffer.
(crypto/base64url-encode data)
URL-safe Base64 encode (for JWT, etc.).
Returns: Base64url string.
(crypto/base64url-decode data)
URL-safe Base64 decode.
Returns: Decoded buffer.
Example: See crypto_signing.janet for signing operations. Example: See crypto_operations.janet for comprehensive crypto usage.
Symmetric Encryption (AEAD)
(crypto/encrypt algo key nonce plaintext &opt aad)
Encrypt data using authenticated encryption (AEAD).
- algo: Cipher algorithm keyword
:aes-128-gcm- AES-128 in GCM mode (16-byte key, 12-byte nonce):aes-256-gcm- AES-256 in GCM mode (32-byte key, 12-byte nonce):chacha20-poly1305- ChaCha20-Poly1305 (32-byte key, 12-byte nonce):aes-128-cbc- AES-128 in CBC mode (16-byte key, 16-byte IV):aes-256-cbc- AES-256 in CBC mode (32-byte key, 16-byte IV)
- key: Encryption key (buffer, correct length for algorithm)
- nonce: Nonce/IV (buffer, correct length for algorithm)
- plaintext: Data to encrypt
- aad: Optional additional authenticated data (AEAD only)
Returns: Struct {:ciphertext <buffer> :tag <buffer>}
IMPORTANT: Never reuse a nonce with the same key!
(crypto/decrypt algo key nonce ciphertext tag &opt aad)
Decrypt data using authenticated encryption.
- algo: Same as encrypt
- key: Encryption key
- nonce: Same nonce used for encryption
- ciphertext: Encrypted data
- tag: Authentication tag (required for AEAD, nil for CBC)
- aad: Must match AAD used during encryption
Returns: Decrypted plaintext buffer.
Errors: If authentication fails (tag mismatch).
(crypto/generate-nonce algo)
Generate a random nonce suitable for the specified cipher.
- algo: Cipher algorithm keyword
Returns: Buffer of appropriate length.
(crypto/cipher-info algo)
Get information about a cipher algorithm.
- algo: Cipher algorithm keyword
Returns: Struct with cipher details:
:name- Algorithm name:key-length- Required key length in bytes:nonce-length- Required nonce/IV length in bytes:tag-length- Authentication tag length (AEAD):aead- Boolean indicating if cipher is AEAD
Example: See symmetric_encryption.janet for AEAD encryption.
RSA Encryption
(crypto/rsa-encrypt key-pem plaintext &opt opts)
Encrypt data with RSA public key.
- key-pem: Public or private key in PEM format
- plaintext: Data to encrypt
- opts: Optional table
:padding- Padding mode (default:oaep-sha256):oaep-sha256(recommended):oaep-sha384:oaep-sha512:oaep-sha1(legacy):pkcs1(legacy, NOT recommended)
Returns: Encrypted ciphertext buffer.
Note: RSA can only encrypt limited data based on key size and padding.
Use rsa-max-plaintext to check limits. For larger data, use hybrid encryption.
(crypto/rsa-decrypt key-pem ciphertext &opt opts)
Decrypt data with RSA private key.
- key-pem: Private key in PEM format
- ciphertext: Encrypted data
- opts: Must match encryption options
Returns: Decrypted plaintext buffer.
(crypto/rsa-max-plaintext key-pem &opt opts)
Get maximum plaintext size for RSA encryption.
- key-pem: Key in PEM format
- opts: Same as rsa-encrypt
Returns: Maximum bytes that can be encrypted.
Example: See rsa_encryption.janet for RSA encryption and hybrid encryption.
Key/Certificate Format Conversion
(crypto/convert-key key-data target-format &opt opts)
Convert a key between formats.
- key-data: Key in any supported format
- target-format: Keyword
:pem- PEM format:der- DER (binary) format:pkcs8- PKCS#8 PEM format:pkcs8-der- PKCS#8 DER format
- opts: Optional table
:password- Password for encrypted PKCS#8 output
Returns: Key in target format.
(crypto/convert-cert cert-data target-format)
Convert a certificate between PEM and DER formats.
- cert-data: Certificate data
- target-format:
:pemor:der
Returns: Certificate in target format.
(crypto/detect-format data)
Detect if data is PEM or DER format.
Returns: :pem or :der
(crypto/load-key key-pem &opt password)
Load a private key, optionally decrypting it.
- key-pem: Key in PEM format
- password: Password if key is encrypted
Returns: Decrypted key in PEM format.
(crypto/export-key key-pem &opt opts)
Export a private key, optionally encrypting it.
- key-pem: Key in PEM format
- opts: Optional table
:password- Password for encryption:cipher- Encryption cipher (:aes-256-cbc,:aes-128-cbc,:des-ede3-cbc)
Returns: Key in PEM format.
(crypto/key-info key-pem)
Get metadata about a key without needing the password.
Returns: Table with:
:type-:rsa,:ec,:ed25519,:x25519, etc.:bits- Key size in bits:curve- EC curve name (for EC keys):encrypted- True if password-protected
Example: See format_conversion.janet for format conversion.
PKCS#12 Operations
(crypto/create-pkcs12 cert-pem key-pem opts)
Create a PKCS#12 (PFX) bundle.
- cert-pem: Certificate in PEM format
- key-pem: Private key in PEM format
- opts: Table
:password- Required password for bundle:chain- Optional array of CA certificate PEMs:friendly-name- Optional friendly name attribute
Returns: PKCS#12 bundle bytes (DER format).
(crypto/parse-pkcs12 pfx-data password)
Parse a PKCS#12 bundle.
- pfx-data: PKCS#12 data (from file or create-pkcs12)
- password: Bundle password
Returns: Table with:
:cert- Certificate PEM:key- Private key PEM:chain- Array of CA certificate PEMs:friendly-name- Friendly name if present
Example: See pkcs12_operations.janet for PKCS#12 usage.
Elliptic Curve Point Operations
Low-level EC point arithmetic for custom protocols, threshold cryptography, zero-knowledge proofs, and Bitcoin/Ethereum cryptography.
(crypto/ec-generate-scalar curve)
Generate a random scalar in [1, order-1] for the curve.
- curve: Curve identifier
:p-256(secp256r1) - NIST 256-bit:p-384(secp384r1) - NIST 384-bit:p-521(secp521r1) - NIST 521-bit:secp256k1- Bitcoin/Ethereum curve
Returns: Big-endian byte buffer.
(crypto/ec-point-mul curve scalar &opt point)
Scalar multiplication on elliptic curve.
- curve: Curve identifier
- scalar: Big-endian byte buffer
- point: Optional
{:x <buffer> :y <buffer>}. If nil, multiplies generator G.
Returns: {:x <buffer> :y <buffer>}
(crypto/ec-point-add curve point1 point2)
Point addition on elliptic curve.
Returns: {:x <buffer> :y <buffer>}
(crypto/ec-point-to-bytes curve point &opt opts)
Serialize EC point to SEC1 format.
- opts: Optional table
:compressed- If true, use compressed format
Returns: Bytes buffer.
(crypto/ec-point-from-bytes curve bytes)
Deserialize EC point from SEC1 format.
Returns: {:x <buffer> :y <buffer>}
Example: See ec_point_operations.janet for EC operations.
Module: jsec/utils
Utility functions for introspection and backend detection.
(utils/ssl-backend)
Returns the SSL backend keyword: :openssl or :libressl.
Useful for conditional code paths based on the SSL library.
(utils/ssl-version)
Returns detailed SSL library version info.
Returns: Struct with:
:backend-:opensslor:libressl:version- Version string (e.g., "OpenSSL 3.0.2" or "LibreSSL 4.0.0"):number- Numeric version for comparison
Additional TLS Stream Methods
(tls/get-handshake-time stream)
Get the TLS handshake duration.
Returns: Handshake time in seconds as floating-point number, or nil if handshake hasn't completed.
Requires :handshake-timing true option during connection.
Additional DTLS Functions
(dtls/new-context &opt opts)
Create a reusable DTLS context.
- opts: Optional table.
:cert- Certificate (PEM string or file path).:key- Private key (PEM string or file path).:verify- Verify peer certificates (defaulttruefor client,falsefor server).:ca- CA certificate path.:trusted-cert- Trust specific certificate (for self-signed).:ciphers- Cipher suite string.:security- Security options table.
If :cert and :key are provided, creates a server-capable context.
Otherwise creates a client-only context.
Returns: SSLContext that can be passed to dtls/connect or dtls/listen.
Security Options
The :security option in connect and accept allows fine-grained control:
:min-version: Keyword or string. For TLS: :TLS1_2, :TLS1_3, or "TLS1.2", "TLS1.3". For DTLS: :DTLS1_0, :DTLS1_2, or "DTLS1.0", "DTLS1.2".:max-version: Keyword or string. Same format as:min-version.:ciphers: Keyword or string. OpenSSL cipher list format (e.g., :HIGH, "ECDHE-RSA-AES256-GCM-SHA384").:curves: Keyword or string. Supported elliptic curves (e.g., :prime256v1, "prime256v1:secp384r1").:ca-file: CA certificate (path or PEM content).:ca-path: CA directory path.
Note: Keyword symbols are preferred for idiomatic Janet code.
Example: See policy_enforcement.janet for advanced security configuration.