private-octopus / picoquic

Minimal implementation of the QUIC protocol
MIT License
561 stars 165 forks source link

Modular support of crypto suites #1057

Open huitema opened 4 years ago

huitema commented 4 years ago

Would it be possible to remove the dependency of Picoquic on OpenSSL? That dependency is somewhat annoying on Windows because it forces using a component not part of the system, and may be a blocker in some IOT deployments. Ideally, Picoquic should work just fine if OpenSSL was not present, and would only use the OpenSSL components if they are available and better than the default components.

Picoquic depends on the implementation of TLS 1.3 in Picotls, but it also depends on OpenSSL for the implementation of several algorithms: AESGCM, ChaCha/Poly, AES128_ECB, SHA256, secp256r1, x25519, SHA384. The encryption and key exchanges algorithms are provided to Picotls through an API, when the master TLS context is initialized. In Windows, the AESGCM, SHA256, SHA384 and secp256r1 components are available in the Bcrypt library. The Picotls library includes implementations of all algorithms as part of the minicrypto library. The new implementation of AESGCM in the fusion library is as fast or faster as that of OpenSSL, but the implementation of ChaCha/Poly is much slower. If we solve the performance issues, or if we decide that they are not important, we could initialize the TLS context using the Windows and/or Minicrypto libraries, removing that dependency.

These are not the only dependencies. The code calls "ptls_openssl_init_sign_certificate" to set up the public key of the server and "ptls_openssl_dispose_sign_certificate" to dispose it, "ptls_openssl_init_verify_certificate" to create and "ptls_openssl_dispose_verify_certificate" to remove the certificate verification code, "ptls_openssl_random_bytes" to initialize the random number generator. There are also error tracing functions that access open_ssl error messages. The Picotls code allows for calling substitutes for these functions, but apart from "random_bytes" these alternatives are limited to the support of "PTLS_SIGNATURE_ECDSA_SECP256R1_SHA256" in the minicrypto library: servers could only support ECDSA certificates and not RSA certificates; clients do not have good alternative for verifying certificates. Those would have to be developed.

Most dependencies are concentrated in "tls_api.c" for the Picoquic-core library, and in a few files for the test library.

Removing OpenSSL dependencies is a large body of work. We should decided whether we want to simply remove OpenSSL and always use a different code, use compile time #ifdef to compile with OpenSSL or an alternative crypto provider, or use an API to let application select among existing providers, or bring their own. Out of these, the "single option" has the advantage of simplicity, while the compile option makes testing hard. An API design would allow testing the "matrix" of providers, and could be the best solution, if the complexity can be mastered.

BitFis commented 4 years ago

I would recommend to go for a refactor and force all calls to a slim crypto api. So all crypto library calls are independent and can be replaced easily during compilation.

I think bring your own with example implementations (like OpenSSL, fusion / minicrypto mix - what i am going for for embedded) Is the best option. Like passing it in as an build variable, aka. -DCRYPTO_ENGINE.

BitFis commented 4 years ago

I started a pull request, I will continue the work and would be happy if parts of it can make it into picoQuic.