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.
See
set_verify_callback
There are examples here:
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