apple / swift-nio-ssl

TLS Support for SwiftNIO, based on BoringSSL.
https://swiftpackageindex.com/apple/swift-nio-ssl/main/documentation/niossl
Apache License 2.0
388 stars 139 forks source link

customVerificationCallback is executed only once #414

Closed borisreitman closed 1 year ago

borisreitman commented 1 year ago

I can only get the client certificate for the first request. Upon repeated browser refreshes I can't get the client certificate. I expect the customVerificationCallback function be called on every request. Is it not supposed to do that? If so, how can I get client certificate on every request?

Here is my code,

           .channelInitializer { channel in
                let ssl_handler = NIOSSLServerHandler(
                        context: sslContext,
                        customVerificationCallback: { cert, promise in
                            let cert = cert[0]
                            print("in customVerificationCallback")
                            promise.succeed(.certificateVerified)
                        }

I only get to see in customVerificationCallback once. If I keep refreshing the browser, it's not showing up. An equivalent code in Node.js gives me a client certificate on every refresh.

I will also try repeatedly with curl.

Lukasa commented 1 year ago

TLS handshakes occur once per connection, not per request. The certificate chains cannot change from one request to the next on the same connection. Because TLS is more general than just HTTP, swift-nio-ssl talks in terms of TLS, so it doesn't re-call this callback, and the callback isn't really intended as a general-purpose method for extracting the certificates.

The answer to your general question is that you need to save the certificates when the connection is constructed.

I'll note that SwiftNIO is not a direct comparison to NodeJS: it's substantially lower level, more equivalent to the internal libraries of NodeJS than to Node itself. It may be worth investigating a tool like Vapor or Hummingbird, rather than using SwiftNIO directly.

borisreitman commented 1 year ago

I have solved it on my end by adding Connection: close header in HTTP response. For reasons to be covered by a patent, I can't disclose what exactly I am doing.