A native module adding support for custom TLS extensions in Node.js, exposing OpenSSL's SSL_CTX_add_custom_ext to JavaScript with static data or dynamic callbacks.
npm install custom-tls-extensionsRequires a C++ compiler and OpenSSL headers (provided by Node.js).
const tls = require('tls');
const { addCustomExtension, constants } = require('custom-tls-extensions');
const ctx = tls.createSecureContext({ /* ... */ });
addCustomExtension(ctx, {
extensionType: 0xFF00,
context: constants.SSL_EXT_CLIENT_HELLO,
data: Buffer.from([0xDE, 0xAD, 0xBE, 0xEF]),
});addCustomExtension(ctx, {
extensionType: 0xFF01,
context: constants.SSL_EXT_CLIENT_HELLO,
add(extType, context) {
return Buffer.from([0x01]); // return null to skip
},
parse(extType, context, data) {
console.log('received:', data);
return true; // return false to reject
},
});const server = tls.createServer({ key, cert });
addCustomExtension(server, {
extensionType: 0xFF00,
context: constants.SSL_EXT_CLIENT_HELLO,
data: Buffer.alloc(0),
parse(extType, context, data) {
console.log('client sent:', data);
return true;
},
});Registers a custom TLS extension on an SSL context.
target - one of:
tls.SecureContextinstancetls.Serverinstance- Raw native context object (e.g.
ctx.context) for backward compat
options:
extensionType(number, required) - Extension type ID (0-65535)context(number, required) - Bitmask ofSSL_EXT_*constantsdata(Buffer) - Static extension data (mutually exclusive withadd)add(extType, context)(Function) - Dynamic data callback; return a Buffer, or null to skipparse(extType, context, data)(Function) - Called when extension is received; return false to reject
Returns true if the extension type is handled internally by OpenSSL (and therefore cannot be used as a custom extension).
OpenSSL SSL_EXT_* constants:
| Constant | Value | Description |
|---|---|---|
SSL_EXT_TLS_ONLY |
0x0001 | TLS only (not DTLS) |
SSL_EXT_DTLS_ONLY |
0x0002 | DTLS only |
SSL_EXT_TLS_IMPLEMENTATION_ONLY |
0x0004 | Internal implementation |
SSL_EXT_SSL3_ALLOWED |
0x0008 | Allowed in SSLv3 |
SSL_EXT_TLS1_2_AND_BELOW_ONLY |
0x0010 | TLS 1.2 and below |
SSL_EXT_TLS1_3_ONLY |
0x0020 | TLS 1.3 only |
SSL_EXT_IGNORE_ON_RESUMPTION |
0x0040 | Skip on session resumption |
SSL_EXT_CLIENT_HELLO |
0x0080 | ClientHello |
SSL_EXT_TLS1_2_SERVER_HELLO |
0x0100 | TLS 1.2 ServerHello |
SSL_EXT_TLS1_3_SERVER_HELLO |
0x0200 | TLS 1.3 ServerHello |
SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS |
0x0400 | EncryptedExtensions |
SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST |
0x0800 | HelloRetryRequest |
SSL_EXT_TLS1_3_CERTIFICATE |
0x1000 | Certificate |
SSL_EXT_TLS1_3_NEW_SESSION_TICKET |
0x2000 | NewSessionTicket |
SSL_EXT_TLS1_3_CERTIFICATE_REQUEST |
0x4000 | CertificateRequest |
- Extension order is not controllable; custom extensions appear after built-in ones
- ~25 extension types are blocked by OpenSSL (server_name=0, supported_groups=10, etc.) - use
isPredefinedExtension()to check - Extensions cannot be removed once added
- Prebuilt binaries are included for Linux, macOS, and Windows (x64 and ARM64) for Node.js 22, 24, and 25. Other platforms/versions fall back to source compilation (requires C++ toolchain).
Requires Node.js >= 22. Compiles against the OpenSSL headers bundled with Node.js.
Apache-2.0