Skip to content

fix!: refuse text sealing keys, and offer only ECDHE AES-GCM under TLS 1.2 - #689

Merged
osanderson merged 2 commits into
mainfrom
fix/keys-tls-review
Oct 20, 2026
Merged

osanderson merged 2 commits into
mainfrom
fix/keys-tls-review

Conversation

@osanderson

Copy link
Copy Markdown
Collaborator

Batch H of the 2026-10-18 review: L8 and L14, as decided. Both are breaking. Each has a section under ## v0.58.0 in UPGRADING.md.

L8: sealing keys must not be text

The gap: pairwise keys refused a key made entirely of printable text (a passphrase, or a hex or base64 key passed without decoding). The other sealers accepted one and sealed everything under it:

  • token sets;
  • CIBA sessions;
  • client/sessioncookie;
  • server/interactioncookie.

The fix:

  • sealkeys.Check, which every sealer uses, now refuses such a key, and pairwise's own copy of the check is gone.
  • A random 32-byte key is all printable with probability about 4×10⁻¹⁴.
  • Test fixtures that used text keys now end in a non-printable byte.

L14: outbound TLS 1.2 cipher suites

The spec: FAPI-CIBA §7.9 (as FAPI 1.0 Part 2 §8.5) permits only the ECDHE AES-GCM suites under TLS 1.2. fapihttp.NewClient offered Go's defaults, CBC included.

The fix:

  • The transport now offers exactly the four ECDHE AES-GCM suites under TLS 1.2. Go has no DHE suites, the other two the specs list. TLS 1.3 is unaffected.
  • HardeningOf counts a transport as hardened only while its TLS 1.2 suites are some of those four. Adding a CBC suite, or clearing the list back to Go's defaults, makes it unhardened.

Behaviour change: a server offering only CBC suites under TLS 1.2 is no longer reachable through a NewClient client.

Testing

  • L8:
    • sealkeys cases for a passphrase and an undecoded hex key;
    • the pairwise text-key tests still pass through the shared check.
  • L14:
    • real handshakes against a TLS 1.2 server: an ECDHE-GCM suite is reached, a CBC-only one isn't;
    • HardeningOf refuses an added CBC suite and cleared defaults, and accepts a subset of the permitted suites.
  • Checks:
    • go vet, go test ./..., and go test -race on Go 1.26.9 for the affected packages;
    • golangci-lint (0 issues);
    • arm vet;
    • every demo module.
  • Downstream: OID4VCgo's whole test suite passes against this branch. Its only sealer key, passport-vdc's interaction cookie key, comes from crypto/rand.

🤖 Generated with Claude Code

osanderson and others added 2 commits October 20, 2026 07:07
Pairwise keys refused a key made entirely of printable text (a
passphrase, or a hex or base64 key passed without decoding it), but the
other sealers, token sets, CIBA sessions and the session and
interaction cookies, accepted one and sealed everything under a key with
far less entropy than 32 random bytes.

sealkeys.Check, which every sealer uses, now refuses such a key, and
pairwise's own copy of the check is gone. A random key is all printable
with probability about 4e-14. Test fixtures that used text keys now end
in a non-printable byte. UPGRADING.md has a section.

BREAKING CHANGE: client.NewTokenSetSealer, client.NewBackchannelSessionSealer, client/sessioncookie and server/interactioncookie refuse a key made entirely of printable text. Generate keys with crypto/rand and decode an encoded key before passing it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
FAPI-CIBA §7.9 (as FAPI 1.0 Part 2 §8.5) permits only the ECDHE AES-GCM
cipher suites under TLS 1.2. NewClient's transport offered Go's
defaults, CBC suites included, and HardeningOf refused only the suites
Go itself calls insecure.

The transport now offers exactly the four ECDHE AES-GCM suites under
TLS 1.2 (Go has no DHE suites, the other two the specs list); TLS 1.3
is unaffected. HardeningOf counts a transport as hardened only while its
TLS 1.2 suites are some of those four, so adding a CBC suite, or
clearing the list back to Go's defaults, makes it unhardened.
UPGRADING.md has a section.

BREAKING CHANGE: a fapihttp.NewClient client no longer connects to a server that offers, under TLS 1.2, only cipher suites other than the four ECDHE AES-GCM ones.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@codecov

codecov Bot commented Oct 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@osanderson
osanderson merged commit 0d3441f into main Oct 20, 2026
19 checks passed
@osanderson
osanderson deleted the fix/keys-tls-review branch October 20, 2026 00:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant