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
393 stars 143 forks source link

expose CNIOBoringSSL #484

Open xlc opened 1 month ago

xlc commented 1 month ago

We would like to use some low level openssl features directly and wanting to use CNIOBoringSSL. What is the reason of not exposing CNIOBoringSSL? If it is just some compiler warnings, some compiler flags should address them. Happy to contribute if needed.

Lukasa commented 1 month ago

Hi @xlc, thanks for asking. We discussed this on the Swift forums when we originally proposed cutting over to BoringSSL, but I'll reiterate here:

BoringSSL does not provide any API or ABI stability guarantees. They are free to, and indeed do, break APIs regularly. If BoringSSL were exposed as as Swift Package Manager package, it would bump its major version number every release. This would make it impossible for the wider community to depend on: different packages would be pinning to different major versions, and dependency resolution would immediately fail.

swift-nio-ssl will present an API that does not contain any part of BoringSSL. If users need to use libssl or libcrypto themselves, they will need to bring their own copy of libssl.

When we update our copy of BoringSSL, we fairly frequently get compile errors that we have to fix. This is despite the fact that we only use a relatively small amount of the API surface. Across the whole of the API surface we'd never be able to revise it.

What features do you want from BoringSSL? We may have good solutions for them in Swift in other packages.

xlc commented 1 month ago

Thanks for the explanation. That's a bit unfortunate but make sense. For the use case here, we are implementing this protocol over QUIC. It have some requirements of the X509 certificate, more specifically, require the peers using a published Ed25519 key. So we will need to be able to generate and verify such certificates.

Moreover, I am using https://github.com/microsoft/msquic as the QUIC implementation, and it requires PKCS12 format if I want to pass the keys in-memory (i.e. not loading from a PEM file).

I discovered CNIOBoringSSL from this issue: https://github.com/apple/swift-certificates/issues/114

Lukasa commented 1 month ago

Ok, so let's turn that into a series of feature requests on the higher-level projects. I think there are two features we need:

  1. Add support for Ed25519 keys in swift-certificates. This should be very do-able so long as we get the key formats right, and I expect you will have some sample certs laying around somewhere.
  2. Add support for serializing PKCS#12 in swift-nio-ssl. In the short term, PKCS12_create is sufficient for this.

    In the longer term I think the rightest solution is to add support for PKCS12 in Swift Crypto's _CryptoExtras. This should be done in a way that lets Swift ASN1 do the ASN.1 pieces, and just have CCryptoBoringSSL do the encryption/decryption steps. That will avoid us needing to offer API to use some of the horrible terrible crypto that PKCS12 requires, but still get support for the format in an arbitrary form.

    cc @0xTim who I know is interested in getting some p12 support in CryptoExtras, as the above would be the best way to do that.

xlc commented 1 month ago

That sounds good. Happy to help testing if needed. I decided to use openssl for now and see if we can refactor the low level C API usage to Swift API when they are ready.

Lukasa commented 1 month ago

Some updates. For Ed25519 keys, see apple/swift-certificates#205. For PKCS#12, see #486.

Would you like to investigate these two options for your use-case?

xlc commented 1 month ago

Thanks! I think those will work for us. Here is our current C code BTW https://github.com/open-web3-stack/boka/blob/master/Networking/Sources/CHelpers/helpers.c