Extensions API
TLS

TLS

Extensions can access detailed TLS connection data. The connection ID is found in the tls.connectionId field of a SessionEntry.


tls/get_connection

Returns the TLS record-layer events for a connection. Each event represents a message observed on one side of the connection, including handshake messages, alerts and cipher spec changes.

Parameters:

{
  connectionId: string;
}

Result: Option<Array<TlsEvent>>


TLS Event Types

type TlsEvent = {
  side: Side;
  message: TlsMessage;
};

type TlsMessage =
  | { type: "alert"; content: Alert }
  | { type: "change_cipher_spec"; content: ChangeCipherSpec }
  | { type: "handshake"; content: HandshakeMessage };

type Alert = {
  level: NamedU8;
  description: NamedU8;
};

type ChangeCipherSpec = {
  data: string;  // hex
};

Handshake Messages

type HandshakeMessage =
  | { type: "client_hello"; content: ClientHello }
  | { type: "server_hello"; content: ServerHello }
  | { type: "new_session_ticket"; content: NewSessionTicket }
  | { type: "encrypted_extensions"; content: EncryptedExtensions }
  | { type: "certificate"; content: Certificate }
  | { type: "server_key_exchange"; content: ServerKeyExchange }
  | { type: "certificate_request"; content: CertificateRequest }
  | { type: "server_hello_done" }
  | { type: "certificate_verify"; content: CertificateVerify }
  | { type: "client_key_exchange"; content: ClientKeyExchange }
  | { type: "finished"; content: Finished }
  | { type: "compressed_certificate"; content: CompressedCertificate };

type ClientHello = {
  version: NamedU16;
  random: string;                         // hex, 32 bytes
  sessionId: string;                      // hex
  cipherSuites: Array<NamedU16>;
  compressionMethods: Array<NamedU8>;
  extensions: Array<ClientExtension>;
};

type ServerHello = {
  version: NamedU16;
  random: string;                         // hex, 32 bytes
  sessionId: string;                      // hex
  cipherSuite: NamedU16;
  compressionMethod: NamedU8;
  extensions: Array<ServerExtension>;
};

type NewSessionTicket = {
  ticket: string;                         // hex
};

type EncryptedExtensions =
  | { type: "client"; content: Array<ClientExtension> }
  | { type: "server"; content: Array<ServerExtension> };

type Certificate =
  | { type: "tls13"; content: Tls13Certificate }
  | { type: "tls12"; content: Tls12Certificate };

type Tls13Certificate = {
  certificateRequestContext: string;      // hex
  certificateList: Array<CertificateEntry>;
};

type CertificateEntry = {
  certData: string;                       // hex
  extensions: string;                     // hex
};

type Tls12Certificate = {
  certificates: Array<string>;            // hex
};

type ServerKeyExchange =
  | { type: "dh"; content: DhServerKeyExchange }
  | { type: "ecdh"; content: EcdhServerKeyExchange };

type DhServerKeyExchange = {
  params: ServerDhParams;
  signedParams: Option<DigitallySigned>;
};

type ServerDhParams = {
  p: string;                              // hex
  g: string;                              // hex
  ys: string;                             // hex
};

type EcdhServerKeyExchange = {
  params: ServerEcdhParams;
  signedParams: Option<DigitallySigned>;
};

type ServerEcdhParams = {
  curveParams: EcParams;
  public: string;                         // hex
};

type EcParams =
  | { type: "explicit_prime"; content: ExplicitPrimeParams }
  | { type: "explicit_char2"; content: ExplicitChar2Params }
  | { type: "named_curve"; content: NamedCurveParams };

type ExplicitPrimeParams = {
  p: string;                              // hex
  curve: EcCurve;
  base: string;                           // hex
  order: string;                          // hex
  cofactor: string;                       // hex
};

type ExplicitChar2Params = {
  m: number;
  basis: Char2Basis;
  curve: EcCurve;
  base: string;                           // hex
  order: string;                          // hex
  cofactor: string;                       // hex
};

type NamedCurveParams = {
  namedCurve: NamedU16;
};

type EcCurve = {
  a: string;                              // hex
  b: string;                              // hex
};

type Char2Basis =
  | { type: "trinomial"; content: TrinomialBasis }
  | { type: "pentanomial"; content: PentanomialBasis };

type TrinomialBasis = {
  k: string;                              // hex
};

type PentanomialBasis = {
  k1: string;                             // hex
  k2: string;                             // hex
  k3: string;                             // hex
};

type DigitallySigned = {
  algorithm: NamedU16;
  signature: string;                      // hex
};

type CertificateRequest =
  | { type: "tls13"; content: Tls13CertificateRequest };

type Tls13CertificateRequest = {
  certificateRequestContext: string;      // hex
  extensions: Array<ServerExtension>;
};

type CertificateVerify = {
  algorithm: NamedU16;
  signature: string;                      // hex
};

type ClientKeyExchange =
  | { type: "dh"; content: DhClientKeyExchange }
  | { type: "ecdh"; content: EcdhClientKeyExchange }
  | { type: "rsa"; content: RsaClientKeyExchange };

type DhClientKeyExchange = {
  yc: string;                             // hex
};

type EcdhClientKeyExchange = {
  yc: string;                             // hex
};

type RsaClientKeyExchange = {
  encryptedPreMasterSecret: string;       // hex
};

type Finished = {
  verifyData: string;                     // hex
};

type CompressedCertificate = {
  algorithm: NamedU16;
  uncompressedLen: number;
  compressedCertificateMessage: string;   // hex
};

TLS Extensions

TLS handshake messages contain extensions with parsed data. Client and server extensions share some types but have separate data enums.

type ClientExtension = {
  extensionType: NamedU16;
  extensionData: ClientExtensionData;
};

type ClientExtensionData =
  | { type: "grease"; content: Grease }
  | { type: "signed_certificate_timestamp" }
  | { type: "status_request"; content: CertificateStatusRequest }
  | { type: "alpn"; content: Alpn }
  | { type: "ech"; content: Ech }
  | { type: "compress_certificate"; content: CompressCertificateExt }
  | { type: "session_ticket"; content: SessionTicket }
  | { type: "supported_groups"; content: SupportedGroups }
  | { type: "renegotiation_info"; content: RenegotiationInfo }
  | { type: "extended_master_secret" }
  | { type: "key_share"; content: KeyShareClientHello }
  | { type: "signature_algorithms"; content: SignatureAlgorithms }
  | { type: "server_name"; content: ServerNameList }
  | { type: "ec_point_formats"; content: EcPointFormats }
  | { type: "supported_versions"; content: ClientSupportedVersions }
  | { type: "psk_key_exchange_modes"; content: PskKeyExchangeModes }
  | { type: "application_settings_support"; content: ApplicationSettingsSupport }
  | { type: "application_settings"; content: ApplicationSettings }
  | { type: "encrypt_then_mac" }
  | { type: "certificate_authorities"; content: CertificateAuthorities }
  | { type: "padding"; content: Padding }
  | { type: "unknown"; content: UnknownExtension };

type ServerExtension = {
  extensionType: NamedU16;
  extensionData: ServerExtensionData;
};

type ServerExtensionData =
  | { type: "server_name" }
  | { type: "signature_algorithms"; content: SignatureAlgorithms }
  | { type: "key_share_server_hello"; content: KeyShareServerHello }
  | { type: "key_share_hello_retry_request"; content: KeyShareHelloRetryRequest }
  | { type: "supported_versions"; content: ServerSupportedVersions }
  | { type: "extended_master_secret" }
  | { type: "alpn"; content: Alpn }
  | { type: "ech"; content: Ech }
  | { type: "application_settings"; content: ApplicationSettings }
  | { type: "session_ticket"; content: SessionTicket }
  | { type: "certificate_authorities"; content: CertificateAuthorities }
  | { type: "unknown"; content: UnknownExtension };

type Grease = {
  data: string;                           // hex
};

type CertificateStatusRequest = {
  statusType: NamedU8;
  request: StatusRequest;
};

type StatusRequest =
  | { type: "ocsp"; content: OcspStatusRequest };

type OcspStatusRequest = {
  responderIdList: Array<string>;         // hex
  extensions: string;                     // hex
};

type Alpn = {
  protocols: Array<string>;
};

type Ech = {
  ech: string;                            // hex
};

type CompressCertificateExt = {
  algorithms: Array<NamedU16>;
};

type SessionTicket = {
  ticket: string;                         // hex
};

type SupportedGroups = {
  namedGroupList: Array<NamedU16>;
};

type RenegotiationInfo = {
  renegotiatedConnection: string;         // hex
};

type KeyShareClientHello = {
  clientShares: Array<KeyShareEntry>;
};

type KeyShareEntry = {
  group: NamedU16;
  keyExchange: string;                    // hex
};

type SignatureAlgorithms = {
  supportedSignatureAlgorithms: Array<NamedU16>;
};

type ServerNameList = {
  serverNameList: Array<ServerName>;
};

type ServerName = {
  nameType: NamedU8;
  name: string;
};

type EcPointFormats = {
  ecPointFormatList: Array<NamedU8>;
};

type ClientSupportedVersions = {
  versions: Array<NamedU16>;
};

type ServerSupportedVersions = {
  selectedVersion: NamedU16;
};

type PskKeyExchangeModes = {
  keModes: Array<NamedU8>;
};

type ApplicationSettingsSupport = {
  supportedProtocols: Array<string>;
};

type ApplicationSettings = {
  settings: string;                       // hex
};

type CertificateAuthorities = {
  authorities: Array<string>;             // hex
};

type Padding = {
  data: string;                           // hex
};

type UnknownExtension = {
  data: string;                           // hex
};

type KeyShareServerHello = {
  serverShare: KeyShareEntry;
};

type KeyShareHelloRetryRequest = {
  selectedGroup: NamedU16;
};