tls: declare the peer's certificate in std/tls (commit 2 of 2 for #116) #463

Open
opened 2026-10-24 05:40:42 +00:00 by orion · 1 comment
Collaborator

Context

Commit 2 of 2 for FIRST-PARTY.md gap 18. CLAUDE.md "Seed and breaking changes": a new native that std/ declares has to be known to the seed first. #116 adds the runtime function and the natives row and declares nothing in std/; this issue declares it, after a seed that contains the merge of #116 is published (as #363 did after #362).

Depends on

#116 merged, and a published seed at or after its merge commit (seeds.txt of the seeds release lists one). Not ready before.

Design

  • Native in std/tls/src/lib.trb: native fn tlsPeerCertificate(session: Int, var into: Buffer<UInt8>): Int (appends the DER of the leaf certificate the peer sent, answers how many bytes; 0 where there is none or the handshake is not done).
  • Public method TlsStream.peerCertificate(): Bytes? beside protocol(): Some(der) of the peer's own certificate (leaf first, DER, not PEM), None on a server-side stream (no client certificate is requested until #117) and before the handshake is done (cannot happen through connect/accept, which finish it). Doc comment names channel binding (tls-server-end-point, RFC 5929) and pinning as the uses, and says the bytes are the certificate as sent, whether or not it was verified against trusted.
  • The hash for tls-server-end-point stays with the driver (torb/postgres): it needs the certificate's signature algorithm, which is not this issue.

Acceptance criteria

  • tlsPeerCertificate declared in std/tls; TlsStream.peerCertificate() documented with an example.
  • A test in std/tls (or tests/conformance/tls-loopback.trb extended): a loopback handshake with the test certificate; the client's peerCertificate() equals the DER of the server's certificate (decode the PEM of the test chain, first block), the server's is None.
  • Runs in the VM and natively (tier B).
  • docs/standard-library/tls.md documents the method; skills/ regenerated (torb docs skill docs skills).
  • FIRST-PARTY.md gap 18 marked done with the date, the "Until then" cell saying where it lives now.
  • No seed change (the seed already knows the native).

Seed impact

No: the native is known to the seed since #116's merge.

Size

One PR, one Conventional Commit: feat(tls): the peer's certificate from a TlsStream.

## Context Commit 2 of 2 for [FIRST-PARTY.md gap 18](https://git.torb.dev/torbscript/language/src/commit/393ef2608e4a60b8ff76d8b6b408951b822d887d/docs/design/FIRST-PARTY.md#L278). `CLAUDE.md` "Seed and breaking changes": a new native that `std/` declares has to be known to the seed first. #116 adds the runtime function and the natives row and declares nothing in `std/`; this issue declares it, after a seed that contains the merge of #116 is published (as #363 did after #362). ## Depends on #116 merged, and a published seed at or after its merge commit (`seeds.txt` of the `seeds` release lists one). Not `ready` before. ## Design - Native in `std/tls/src/lib.trb`: `native fn tlsPeerCertificate(session: Int, var into: Buffer<UInt8>): Int` (appends the DER of the leaf certificate the peer sent, answers how many bytes; 0 where there is none or the handshake is not done). - Public method `TlsStream.peerCertificate(): Bytes?` beside `protocol()`: `Some(der)` of the peer's own certificate (leaf first, DER, not PEM), `None` on a server-side stream (no client certificate is requested until #117) and before the handshake is done (cannot happen through `connect`/`accept`, which finish it). Doc comment names channel binding (`tls-server-end-point`, RFC 5929) and pinning as the uses, and says the bytes are the certificate as sent, whether or not it was verified against `trusted`. - The hash for `tls-server-end-point` stays with the driver (`torb/postgres`): it needs the certificate's signature algorithm, which is not this issue. ## Acceptance criteria - [ ] `tlsPeerCertificate` declared in `std/tls`; `TlsStream.peerCertificate()` documented with an example. - [ ] A test in `std/tls` (or `tests/conformance/tls-loopback.trb` extended): a loopback handshake with the test certificate; the client's `peerCertificate()` equals the DER of the server's certificate (decode the PEM of the test chain, first block), the server's is `None`. - [ ] Runs in the VM and natively (tier B). - [ ] `docs/standard-library/tls.md` documents the method; `skills/` regenerated (`torb docs skill docs skills`). - [ ] FIRST-PARTY.md gap 18 marked **done** with the date, the "Until then" cell saying where it lives now. - [ ] No seed change (the seed already knows the native). ## Seed impact No: the native is known to the seed since #116's merge. ## Size One PR, one Conventional Commit: `feat(tls): the peer's certificate from a TlsStream`.
Author
Collaborator

[loop:torbscript] refine: body written (design, acceptance criteria, seed impact, size are in it); step 2 of #116. next: waiting (depends on #116 merged and a published seed that contains it)

[loop:torbscript] refine: body written (design, acceptance criteria, seed impact, size are in it); step 2 of #116. next: waiting (depends on #116 merged and a published seed that contains it)
Sign in to join this conversation.
No labels
loop
ready
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
torbscript/language#463
No description provided.