import * as plugins from '../../plugins.js'; /** * TLS record types as defined in various RFCs */ export enum TlsRecordType { CHANGE_CIPHER_SPEC = 20, ALERT = 21, HANDSHAKE = 22, APPLICATION_DATA = 23, HEARTBEAT = 24, // RFC 6520 } /** * TLS handshake message types */ export enum TlsHandshakeType { HELLO_REQUEST = 0, CLIENT_HELLO = 1, SERVER_HELLO = 2, NEW_SESSION_TICKET = 4, ENCRYPTED_EXTENSIONS = 8, // TLS 1.3 CERTIFICATE = 11, SERVER_KEY_EXCHANGE = 12, CERTIFICATE_REQUEST = 13, SERVER_HELLO_DONE = 14, CERTIFICATE_VERIFY = 15, CLIENT_KEY_EXCHANGE = 16, FINISHED = 20, } /** * TLS extension types */ export enum TlsExtensionType { SERVER_NAME = 0, // SNI MAX_FRAGMENT_LENGTH = 1, CLIENT_CERTIFICATE_URL = 2, TRUSTED_CA_KEYS = 3, TRUNCATED_HMAC = 4, STATUS_REQUEST = 5, // OCSP SUPPORTED_GROUPS = 10, // Previously named "elliptic_curves" EC_POINT_FORMATS = 11, SIGNATURE_ALGORITHMS = 13, APPLICATION_LAYER_PROTOCOL_NEGOTIATION = 16, // ALPN SIGNED_CERTIFICATE_TIMESTAMP = 18, // Certificate Transparency PADDING = 21, SESSION_TICKET = 35, PRE_SHARED_KEY = 41, // TLS 1.3 EARLY_DATA = 42, // TLS 1.3 0-RTT SUPPORTED_VERSIONS = 43, // TLS 1.3 COOKIE = 44, // TLS 1.3 PSK_KEY_EXCHANGE_MODES = 45, // TLS 1.3 CERTIFICATE_AUTHORITIES = 47, // TLS 1.3 POST_HANDSHAKE_AUTH = 49, // TLS 1.3 SIGNATURE_ALGORITHMS_CERT = 50, // TLS 1.3 KEY_SHARE = 51, // TLS 1.3 } /** * TLS alert levels */ export enum TlsAlertLevel { WARNING = 1, FATAL = 2, } /** * TLS alert description codes */ export enum TlsAlertDescription { CLOSE_NOTIFY = 0, UNEXPECTED_MESSAGE = 10, BAD_RECORD_MAC = 20, DECRYPTION_FAILED = 21, // TLS 1.0 only RECORD_OVERFLOW = 22, DECOMPRESSION_FAILURE = 30, // TLS 1.2 and below HANDSHAKE_FAILURE = 40, NO_CERTIFICATE = 41, // SSLv3 only BAD_CERTIFICATE = 42, UNSUPPORTED_CERTIFICATE = 43, CERTIFICATE_REVOKED = 44, CERTIFICATE_EXPIRED = 45, CERTIFICATE_UNKNOWN = 46, ILLEGAL_PARAMETER = 47, UNKNOWN_CA = 48, ACCESS_DENIED = 49, DECODE_ERROR = 50, DECRYPT_ERROR = 51, EXPORT_RESTRICTION = 60, // TLS 1.0 only PROTOCOL_VERSION = 70, INSUFFICIENT_SECURITY = 71, INTERNAL_ERROR = 80, INAPPROPRIATE_FALLBACK = 86, USER_CANCELED = 90, NO_RENEGOTIATION = 100, // TLS 1.2 and below MISSING_EXTENSION = 109, // TLS 1.3 UNSUPPORTED_EXTENSION = 110, // TLS 1.3 CERTIFICATE_REQUIRED = 111, // TLS 1.3 UNRECOGNIZED_NAME = 112, BAD_CERTIFICATE_STATUS_RESPONSE = 113, BAD_CERTIFICATE_HASH_VALUE = 114, // TLS 1.2 and below UNKNOWN_PSK_IDENTITY = 115, CERTIFICATE_REQUIRED_1_3 = 116, // TLS 1.3 NO_APPLICATION_PROTOCOL = 120, } /** * TLS version codes (major.minor) */ export const TlsVersion = { SSL3: [0x03, 0x00], TLS1_0: [0x03, 0x01], TLS1_1: [0x03, 0x02], TLS1_2: [0x03, 0x03], TLS1_3: [0x03, 0x04], }; /** * Utility functions for TLS protocol operations */ export class TlsUtils { /** * Checks if a buffer contains a TLS handshake record * @param buffer The buffer to check * @returns true if the buffer starts with a TLS handshake record */ public static isTlsHandshake(buffer: Buffer): boolean { return buffer.length > 0 && buffer[0] === TlsRecordType.HANDSHAKE; } /** * Checks if a buffer contains TLS application data * @param buffer The buffer to check * @returns true if the buffer starts with a TLS application data record */ public static isTlsApplicationData(buffer: Buffer): boolean { return buffer.length > 0 && buffer[0] === TlsRecordType.APPLICATION_DATA; } /** * Checks if a buffer contains a TLS alert record * @param buffer The buffer to check * @returns true if the buffer starts with a TLS alert record */ public static isTlsAlert(buffer: Buffer): boolean { return buffer.length > 0 && buffer[0] === TlsRecordType.ALERT; } /** * Checks if a buffer contains a TLS ClientHello message * @param buffer The buffer to check * @returns true if the buffer appears to be a ClientHello message */ public static isClientHello(buffer: Buffer): boolean { // Minimum ClientHello size (TLS record header + handshake header) if (buffer.length < 9) { return false; } // Check record type (must be TLS_HANDSHAKE_RECORD_TYPE) if (buffer[0] !== TlsRecordType.HANDSHAKE) { return false; } // Skip version and length in TLS record header (5 bytes total) // Check handshake type at byte 5 (must be CLIENT_HELLO) return buffer[5] === TlsHandshakeType.CLIENT_HELLO; } /** * Gets the record length from a TLS record header * @param buffer Buffer containing a TLS record * @returns The record length if the buffer is valid, -1 otherwise */ public static getTlsRecordLength(buffer: Buffer): number { if (buffer.length < 5) { return -1; } // Bytes 3-4 contain the record length (big-endian) return (buffer[3] << 8) + buffer[4]; } /** * Creates a connection ID based on source/destination information * Used to track fragmented ClientHello messages across multiple packets * * @param connectionInfo Object containing connection identifiers * @returns A string ID for the connection */ public static createConnectionId(connectionInfo: { sourceIp?: string; sourcePort?: number; destIp?: string; destPort?: number; }): string { const { sourceIp, sourcePort, destIp, destPort } = connectionInfo; return `${sourceIp}:${sourcePort}-${destIp}:${destPort}`; } }