CCF/src/tls
Eddy Ashton 95a2e9d849
Remove duplicate lines (#3826) (#3844)
2022-05-17 14:55:05 +01:00
..
test Improve handling of X509 times (#3739) 2022-04-08 13:00:18 +01:00
README.md Fix TLS certificate verification (#3449) 2022-01-28 13:37:11 +00:00
ca.h Remove CBuffer/Buffer in favour of std::span (#3575) 2022-02-23 13:04:38 +00:00
cert.h Public C++ crypto API (#3569) 2022-02-18 08:19:22 +00:00
client.h More TLS cleanups (#3472) 2022-01-28 14:16:08 +00:00
context.h Remove duplicate lines (#3826) (#3844) 2022-05-17 14:55:05 +01:00
msg_types.h TLS Cleanup + OpenSSL Base64 (#3217) 2021-11-18 07:41:20 +00:00
server.h Add ALPN extension to CCF servers, advertising HTTP/1.1 (#3643) 2022-03-11 11:02:16 +00:00
tls.h Remove the final MbedTLS references from the code (#3430) 2022-01-19 15:44:41 +00:00

README.md

OpenSSL TLS Implementation

This is a TLS implementation using OpenSSL that mimics the existing MbedTLS one in a similar fashion. Because of that, some structures and call backs look odd and have some work-arounds to make it fit the current workflow.

Once we completely deprecate the MbedTLS implementation from CCF, we should re-write the TLS implementation to fit the OpenSSL coding flow, which would make it much simpler and easier to use.

CAs and Certificates

In the MbedTLS world, certificates can be null and have methods to change some configurations in the TLS config/session objects. There isn't a lot of cross-over, so updating the config does the trick.

However, in OpenSSL, session objects (ssl) are created from config objects (cfg) and inherit all its properties. Therefore, to emulate MbedTLS, we need to do to the session object every action we do to the config object, which is not only redundant, but could be unsafe, if the calls are slightly different.

Validation

Certificate validation can be complex to handle if you can accept connections with certificates or not, and if they come, when and how to validate.

MbedTLS is a lot more lenient on checks. For example, CAs are not tested for validity of actually signing other certificates, while OpenSSL has extensive checks, which can fail functionality that was previously passing.

For this reason, a number of extra checks in the OpenSSL side were disabled. Once we get rid of MbedTLS we should revisit those checks again and improve CCF's usage of TLS, and perhaps also creating weaker checks for non-CA certificates, etc.

Context

BIOs

MbedTLS operates reads and writes solely via callbacks, with a buffer in the session object acting as async I/O. This is in stark contrast with OpenSSL which uses BIO objects to pass information back and forth, and only have callbacks for debug or very specialized cases.

We had to implement callbacks and specialize our case, but it could really be just done with BIOs between the ring buffer and the context, but we'd have to change a lot of code outside of the TLS implementation to add that.

Reads and Writes

Reading and writing in MbedTLS returns a positive value for success (number of bytes written) or a negative value for error (pre-defined error codes) including WANTS_READ and WANTS_WRITE.

In OpenSSL, those methods return 1 for success and 0 or -1 for errors (depending on the version), with all errors, including WANTS_READ and WANTS_WRITE accessible through SSL_get_error. This imposes a number of hacks needed to mimic the MbedTLS implementation, including:

  • Multiple #defines with common error messages in tls.h
  • Having to negate the error code to match
  • Multiple checks to SSL_want_read and SSL_want_write

Error Handling

As discussed above, the error handling is slightly different and promotes verbose code in OpenSSL's side.