swift-server/async-http-client

Not supported features at `TLSConfiguration`

o-nnerb opened this issue · 2 comments

I was making a correction in the implementation of a code I wrote to use NIOTSEventLoopGroup instead of MultiThreadedEventLoopGroup. However, when I ran some tests, I encountered a fatal error in the code snippet provided below.

        // cipher suites
        if self.cipherSuites.count > 0 {
            // TODO: Requires NIOSSL to provide list of cipher values before we can continue
            // https://github.com/apple/swift-nio-ssl/issues/207
        }

        // key log callback
        if self.keyLogCallback != nil {
            preconditionFailure("TLSConfiguration.keyLogCallback is not supported. \(useMTELGExplainer)")
        }

        // the certificate chain
        if self.certificateChain.count > 0 {
            preconditionFailure("TLSConfiguration.certificateChain is not supported. \(useMTELGExplainer)")
        }

        // private key
        if self.privateKey != nil {
            preconditionFailure("TLSConfiguration.privateKey is not supported. \(useMTELGExplainer)")
        }

        // renegotiation support key is unsupported

I was quite intrigued because one of the comments refers to an issue created in 2020, which left me with some doubts. Is it possible that this entire code snippet is outdated, and features like CipherSuites, certificateChain, and privateKey are currently compatible?

Another point that got me curious is regarding the use of certificateChain and privateKey. Wouldn't they be the way to configure client authorization following the definition of mTLS?

Lukasa commented

Cipher suites is conceptually supportable at this time, but the other two remain extremely difficult to support. You're right that certificate chain and private key are necessary for mTLS support. However, they can only be configured with Network.framework using a SecIdentity, which was sufficiently complex to achieve that support was not added originally and has not been added since. The particular source of the complexity was that we wanted to avoid inserting anything into the Keychain, as we judged it inappropriate to add these secrets to the user's keychain without their explicit consent.

Getting this to work across all of Apple's platforms is fairly subtle (requiring at least two function calls), and we're arguably doing a disservice to users by doing it. A potentially better strategy long-term is to adopt gRPC-Swift's API, which requires that you provide an appropriate TLS configuration for your environment. In this case, if you used NIOTS then we'd expect you to provide an NWProtocolTLS.Options.

If you (or someone else) is interested in trying to fix this issue then https://developer.apple.com/forums/thread/31711 outlines some of the complexities that need to be handled.

Thanks @Lukasa. Excellent explanation. The issue you referred is very well detailed 🫰🏻.

I'm not sure if I have the knowledge to implement this, but studying this problems will be a great start for a better comprehension of Network and Security frameworks.

I'll close this now.