Skip to content

Add pluggable trust-verification hooks for NIOSSL and Network.framework - #11

Draft
o-nnerb wants to merge 3 commits into
mainfrom
trust-verification-hooks
Draft

o-nnerb wants to merge 3 commits into
mainfrom
trust-verification-hooks

Conversation

@o-nnerb

@o-nnerb o-nnerb commented Sep 8, 2026

Copy link
Copy Markdown
Member

Summary

  • Exposes HTTPClient.Configuration.tlsCustomVerification (NIOSSL backend) and .tlsCustomVerificationNetworkFramework (Network.framework backend): thin passthroughs into NIOSSLClientHandler's customVerificationCallback and sec_protocol_options_set_verify_block respectively.
  • Neither hook carries any built-in pinning/trust policy — the goal is to let a caller (e.g. a TrustEvaluator implemented downstream in request-dl-nio) fully own the accept/reject decision on whichever TLS backend actually negotiates the connection, including inspecting the full presented chain rather than just the leaf.
  • tlsCustomVerification overrides NIOSSL's trust-chain verification only — hostname/SNI matching stays a separate gate on TLSConfiguration.certificateVerification (documented on the property).
  • tlsCustomVerificationNetworkFramework receives the real SecTrust Network.framework already built, so a conforming implementation can call SecTrustEvaluateWithError itself to keep the OS's trust-store/revocation/Certificate-Transparency behavior before layering custom logic on top.

Test plan

  • TrustCustomVerificationTests: accept/reject on both backends, a plumbing-only test for getNWProtocolTLSOptions, and an mTLS-alongside-custom-verification test (client cert still presented when tlsCustomVerification is also set) — verified in both NIOSSL and Network.framework modes (DISABLE_TS_TESTS=true/unset).
  • swift build clean, swift format lint --strict clean.
  • Existing HTTPClientNIOTSTests/HTTPConnectionPool+FactoryTests/SSLContextCacheTests unaffected in both modes.

🤖 Generated with Claude Code

Exposes HTTPClient.Configuration.tlsCustomVerification (NIOSSL backend)
and .tlsCustomVerificationNetworkFramework (Network.framework backend),
thin passthroughs into NIOSSLClientHandler's customVerificationCallback
and Network.framework's sec_protocol_options_set_verify_block
respectively. Neither hook carries any built-in pinning policy — the
goal is to let a caller (e.g. a TrustEvaluator implemented downstream)
fully own the accept/reject decision on whichever TLS backend actually
negotiates the connection, including inspecting the full presented
chain rather than just the leaf.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…oc comment

Three double-backtick links in an unconditional doc comment pointed at
symbols that don't exist in every build this repo's CI produces
documentation for: tlsCustomVerificationNetworkFramework is
canImport(Network)-gated (absent from the Linux symbol graph
entirely), and TLSConfiguration.certificateVerification /
NIOSSLCustomVerificationCallback both live in the NIOSSL module, which
DocC can't resolve an unqualified cross-module link against in this
build. Switched all three to plain code spans -- still readable,
without a resolution DocC can't perform.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@o-nnerb o-nnerb added the 🆕 semver/minor Additive, non-breaking API change label Sep 8, 2026
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🆕 semver/minor Additive, non-breaking API change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant