Search code examples
c++macosboostasiobeast

Using Boost Beast to build Platform specific client-side authentication in SSL connection


I’m working on boost::beast based application on macOS platform, and I wonder how I can provide a client-side certificate to authenticate against the server ?

basically , in macOS the certificates are stored in keychain, and cannot be exported (backed by dedicated hardware called secured-enclave for better security)…

So I wonder if there’s any callback suitable to sign server’s challenge manually with native macOS native code that send the challenge to the keychain/secure-enclave for signing.

basically, I'm looking for a callback that have roughly the following signature :

bool validate_client_side_certificate(const std::string& challenge) 

So basically What I've got right not is the ability to provide the certificate + private key from file


boost::asio::ssl::context ctx_;
std::string client_cert_ = read_pem_file(client_cert_path);
std::string client_cert_private_key_ = read_pem_file(private_key_path);

ctx_.use_certificate(
   boost::asio::buffer(client_cert_.c_str(), client_cert_.length()),
   boost::asio::ssl::context::pem);
ctx_.use_private_key(
   boost::asio::buffer(client_cert_key_.c_str(),                                            client_cert_key_.length()),
   boost::asio::ssl::context::pem);

This flow works perfectly, but if I want to use the certificates that are inside the keychain (macOS storage for crypto data) I cannot get the private key but only a reference (because it's protected).

So in macOS we cannot just provide the private key to ctx_ do that the challenge will be signed automatically. instead, we need to get the callback that occur when client-side authentication is required, along with the challenge... and use macOS native code to sign the challenge inside the keychain hardware, using the key reference.


Solution

  • See set_verify_callback

    There are examples here:

    • asio/example/cpp11/ssl/client.cpp
    • asio/example/cpp03/ssl/client.cpp

    You can see it integrated in Beast's ssl_stream: https://www.boost.org/doc/libs/1_78_0/libs/beast/doc/html/beast/ref/boost__beast__ssl_stream/set_verify_callback/overload2.html