djarek / certify

Boost.ASIO-based TLS certificate verification library
https://djarek.github.io/certify/
Boost Software License 1.0
76 stars 40 forks source link

How to use certify with Async SSL #58

Open benstadin opened 4 years ago

benstadin commented 4 years ago

I'm trying get certify working for a Async SSL Client (I have to use Async because I need to set a timeout). The stream is declared as:

beast::ssl_stream stream_;

I don't find the matching function for setting host name and sni:

    boost::certify::set_server_hostname(beast::get_lowest_layer(stream_).socket(), host);
    boost::certify::sni_hostname(beast::get_lowest_layer(stream_), host);

Does certify work in async mode?

Edit: Sorry, the title should read Async SSL instead.

benstadin commented 4 years ago

I got it working by replacing set_server_name with the detail implementation call (as a workaround for now):

    boost::system::error_code ec;
    boost::certify::detail::set_server_hostname(stream_.native_handle(), host, ec);
    if (ec)
        boost::throw_exception(boost::system::system_error{ec});
djarek commented 4 years ago

Unfortunately, the ssl stream in Beast doesn't seem to have an API that exposes the underlying SSL socket. As a sidenote: I'm no longer working on this library, due to fundemental implemntation issues when working with OpenSSL (and especially when working with ASIO's wrapper on top OpenSSL).

The primary issue is that OpenSSL doesn't expose a way of doing asynchronous operations in the verification callback (something that, IIRC, BoringSSL does allow), which means that doing things like OCSP lookup (which involes doing a simplified HTTP reques) can't be done in a non-blocking way.

While this is not an issue for synchronous programs, it may be an issue for programs that do async operations. At this point I'd probably recommend doing what the mobile app folks have been doing all along - if their native code uses OpenSSL, bundle certs with the app, keep the app updated. This does not give the full verification functionality (no OCSP), but it's better than no verification at all on Windows or MacOS/iOS.

What would be a proper solution? Hard to say. Probably replacing asio::ssl with something that uses the native TLS capabilities (because they do the proper verification on their own). But that's a massive project in itself even though it doesn't involve writing TLS impl itself, just wrapping platform-specific TLS API.s

benstadin commented 4 years ago

Thanks @djarek that all makes sense. The Java folks also have their own Java keystore (could be accessed using JNI in theory), and tools like Hashicorp's Vault might fill that gap.

Thanks again for your thorough feedback. I'll reconsider my software design.