Skip to content

Add SPKI certificate pinning support - #910

Draft
o-nnerb wants to merge 42 commits into
swift-server:mainfrom
o-nnerb:main
Draft

o-nnerb wants to merge 42 commits into
swift-server:mainfrom
o-nnerb:main

Conversation

@o-nnerb

@o-nnerb o-nnerb commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

This PR introduces SPKI-based certificate pinning to AsyncHTTPClient to mitigate MITM attacks and compromised CAs.

Highlights:

  • Implements .strict and .audit modes with multi-algorithm hashing (SHA-256/384/512) and constant-time comparison.
  • Aligned with OWASP/NIST security standards, featuring rotation safety warnings and explicit error handling.
  • Requirement: Requires OpenSSL/BoringSSL backend (Network.framework connections ignore pinning configuration).

o-nnerb and others added 30 commits February 1, 2026 18:37
@o-nnerb

o-nnerb commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

@czechboy0 @FranzBusch can you review this?

@FranzBusch
FranzBusch requested review from Lukasa and glbrntt June 23, 2026 12:41

@glbrntt glbrntt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! This mostly looks good but I left some feedback inline which needs addressing.

Comment thread Sources/AsyncHTTPClient/ConnectionPool/ChannelHandler/SPKIPinningHandler.swift Outdated
Comment thread Sources/AsyncHTTPClient/AsyncAwait/HTTPClientRequest.swift
Comment thread Sources/AsyncHTTPClient/ConnectionPool/ChannelHandler/SPKIPinningHandler.swift Outdated
Comment thread Sources/AsyncHTTPClient/ConnectionPool/ChannelHandler/SPKIPinningHandler.swift Outdated
Comment thread Tests/AsyncHTTPClientTests/AsyncAwaitEndToEndTests.swift Outdated
Comment thread Sources/AsyncHTTPClient/ConnectionPool/ChannelHandler/SPKIPinningHandler.swift Outdated
Comment thread Tests/AsyncHTTPClientTests/SPKIHashTests.swift Outdated
Comment thread Tests/AsyncHTTPClientTests/AsyncAwaitEndToEndTests.swift Outdated
Comment thread Tests/AsyncHTTPClientTests/SPKIPinningTests.swift Outdated
@o-nnerb
o-nnerb requested a review from glbrntt June 24, 2026 19:30

@glbrntt glbrntt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking good, just a couple of small things left. The e2e tests are much better now as well 👍

Comment thread Sources/AsyncHTTPClient/ConnectionPool/ChannelHandler/SPKIPinningHandler.swift Outdated
Comment thread Sources/AsyncHTTPClient/ConnectionPool/ChannelHandler/SPKIPinningHandler.swift Outdated
@glbrntt glbrntt added the 🆕 semver/minor Adds new public API. label Jun 25, 2026
@o-nnerb
o-nnerb requested a review from glbrntt June 25, 2026 11:00

@glbrntt glbrntt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this looks great! I would like @Lukasa to have a look before this is merged though.

Comment thread Sources/AsyncHTTPClient/ConnectionPool/HTTPConnectionPool+Factory.swift Outdated
Comment thread Tests/AsyncHTTPClientTests/SPKIPinningTests.swift Outdated
Comment thread Tests/AsyncHTTPClientTests/SPKIPinningTests.swift
- Pure HTTP requests (without TLS) when tlsPinning is configured globally.
- HTTPS requests made via proxy (HTTP/SOCKS) on Apple platforms, even though the actual TLS is performed using NIOSSL (which supports pinning correctly).
@o-nnerb
o-nnerb requested a review from glbrntt August 6, 2026 10:35
@o-nnerb
o-nnerb marked this pull request as draft September 8, 2026 17:30
@o-nnerb

o-nnerb commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

I've marked this PR as a draft because I've identified some deeper architectural concerns with the original implementation. Specifically, it feels conceptually off to bundle the entire SSL Pinning functionality within the scope of AsyncHTTPClient.

If we look at URLSession, this kind of built-in functionality doesn't exist. Furthermore, the current implementation hits technical limitations due to Transport Services on NIO and its reliance on the underlying Network framework.

Because of these details, I'm stepping back to re-evaluate the approach. I'm exploring a deeper, more decoupled solution, similar to how URLSession handles it. I'll share more details and update the PR status once I've finished the new implementation and testing.

Thank you all for the reviews and the great discussions. I apologize for the extra effort and rework this pivot has caused on your end.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🆕 semver/minor Adds new public API.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants