# tls

> The tls identity: TLS records over TCP. Every directive and what is required.

`tls` speaks TLS records over TCP. The session persists across steps, so a solution can stage a handshake in one step and fire its payload in the next. The target is `host:port`. Send and receive raw record bytes as hex.

## Write it in English

A tls step reads as sentences, the same byte-session forms as [tcp](/docs/solution/identity/tcp/): `send hex "<hex>"` (or `send hex of "<text>"`), `receive <n> bytes`, `receive until "<hex>"`, `timeout <n> seconds`, `close the connection`, and `expect ...`.

## The directives

### send

`send hex "<hex>"` is the bytes to send, written as hex, or `send hex of "<text>"` for readable text (the quoted text is hex-encoded for you). TLS records are mostly binary, so raw hex is usually the clearer form.

### receive

`receive <n> bytes` reads at most that many.

### receive until

`receive until "<hex>"` stops the read once this hex marker appears, for example ServerHelloDone `0e000000`.

### timeout

`timeout <n> seconds` bounds the wait. Example: `timeout 5 seconds`.

### close

`close the connection` ends the session after this step.

### capture

`capture` pulls a value out of the received hex for later steps, and it reads as English. The `value after` shape captures the run of hex after a hex marker and hex-decodes it, the way a server-assigned port id rides in the stream:

```text
tls negotiate
  send hex "010203..."
  capture the value after "6f703a6f747270633a" as port_id
  expect "..." in the response
```

Later steps reference `{port_id}`. The regex form is still available: the pattern runs over the hex and group 1 is hex-decoded before storing (`capture port: "(....)"`).

## Example

```text
tls malformed-heartbeat
  # send a heartbeat request claiming a payload length with zero payload bytes
  send hex "1803030003014000"
  receive 70000 bytes
  timeout 5 seconds
  expect the response to match "18030[123]40"
```