Replies: 1 comment
|
Fechando esta discussion — foi criada por engano. O pedido original era documentar como Feature Proposal as mudanças de SPKI Pinning já implementadas na branch Além de não ser o que foi pedido, o conteúdo também não procede como "gap a corrigir": a própria PR #910 já documenta isso como requisito de design deliberado — "Requires OpenSSL/BoringSSL backend (Network.framework connections ignore pinning configuration)" — não uma limitação a ser removida depois. Proposta correta sendo publicada em seguida. |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Summary
SPKIPinning(this repo's wrapper aroundasync-http-client's native SPKI pinning) does not workwhen a session uses Network.framework —
Session().enableNetworkFramework(). This isn't a gap inRequestDL; it's a deliberate, documented limitation in
async-http-clientitself, and RequestDLcurrently works around it by silently downgrading the transport rather than actually supporting the
combination.
The gap
async-http-client'sHTTPConnectionPool+Factory.swift, in the Network.framework connection path,hard-fails as soon as pinning is configured:
The reason is structural, not a missing
if:SPKIPinningHandleris a NIOChannelInboundHandlerthat reads the peer certificate off
NIOSSLHandleronce the TLS handshake completes. WhenNetwork.framework performs the handshake itself (
NWConnection, outside NIO's channel pipeline),there is no
NIOSSLHandlerfor it to attach to — the handler has nothing to read.RequestDL's
Internals.SecureConnection.isCompatibleWithNetworkFrameworkalready treats any sessionwith
SPKIPinningconfigured as incompatible with Network.framework, and steers it ontoMultiThreadedEventLoopGroupinstead ofNIOTSEventLoopGroup— avoiding the runtime crash, but atthe cost of silently losing Network.framework's benefits (VPN awareness, constrained/expensive-path
integration, multipath) for any session that also wants pinning. That's a library-level workaround,
not a fix; a wrapper library can only choose which transport a session uses, it cannot make pinning
work on the Network.framework transport, because the hook to do that doesn't exist outside
async-http-client.Why there's a real path forward
async-http-clientalready has the right kind of hook for this, and already uses it for a similarpurpose:
TLSConfiguration+NIOTransportServices.swift'sgetNWProtocolTLSOptionsinstalls asec_protocol_options_set_verify_blockwhenever custom trust roots or non-default certificateverification is configured. That's Apple's own public API for custom certificate verification under
Network.framework — the same shape of problem as SPKI pin checking (given the
SecTrusthanded tothe verify block, extract the leaf certificate's public key and compare its hash against a known
set). Nothing about that requires a NIO pipeline.
Proposed change (full detail in a companion design doc kept alongside RequestDL's fork of
async-http-client):SPKIPinningConfigurationintogetNWProtocolTLSOptions.SPKIPinningHandlerdoes today, usingSecTrust/SecCertificateAPIs instead ofNIOSSLCertificate.extractPublicKey().SPKIPinningPolicy(.auditvs.strict) identically to the NIOSSL path.networkFrameworkNotSupportedthrow once the verify-block path exists and is tested.SPKIPinningConfiguration's doc comments to drop the Network.framework caveat.One open question to resolve during implementation:
SecTrustCopyKey(the most direct extractionAPI) requires macOS 11+/iOS 14+, while
SPKIPinningHandleritself is gated at macOS 10.15/iOS 13today — whether the Network.framework path needs a narrower availability window or an older
SecCertificateCopyKeyfallback isn't resolved yet.Out of scope
origin's TLS, not the tunnel).
can run.
Status
This has to land in
swift-server/async-http-client— RequestDL cannot implement it as a wrapper.Milestone: TBD, pending that upstream work and a released version including it. Once available,
RequestDL's
Internals.SecureConnection.isCompatibleWithNetworkFrameworkworkaround can be retiredand
SPKIPinning+enableNetworkFramework()can be used together.All reactions