cpprestsdk
cpprestsdk copied to clipboard
Support for client certificates
Years ago(!) there already was a discussion on Casablanca supporting client certificates for mutual SSL connections. See here: client side certificates
Unfortunately this seems not to have changed meanwhile, Apparently Casablanca still doesn't support client certificates! :-/ AT least I can see no code inside that acts upon ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED and sets some certificate context via WINHTTP_OPTION_CLIENT_CERT_CONTEXT in the Windows flavour (dunno how to do that on POSIX but never mind).
Is there any plan to implement that any time soon or will we never see it? For my current application this is a real showstopper, as the customer demands client side certificates and mutual SSL. I could of course try to patch in something but I would feel much more comfortable if things are build in!
I agree that this should be better supported by cpprest. In the meantime, there is a rather simple way to do that using web::http::client::http_client_config::set_nativehandle_options()
. We use this in a productive application successfully since a while.
I didn't compile the below code, please just take it as a guideline. Also this (obviously) only works on windows. For macOS/Linux you need to do a similar trick with the ::native_handle
treated as a boost::asio::ssl::context
. This provides a bit higher-level ::use_certificate()
and ::use_private_key()
methods.
#include <Wincrypt.h>
std::vector<uint8_t> pkcs12_data; // "... your client certificate PKCS#12 with private key goes here ...";
utility::string_t password = "pkcs12_password";
web::http::client::http_client_config cfg;
cfg.set_nativehandle_options([=] (web::http::client::native_handle h) {
CRYPT_DATA_BLOB data;
data.cbData = pkcs12_data.size();
data.pbData = reinterpret_cast<BYTE *>(pkcs12_data.data());
HCERTSTORE hCertStore = PFXImportCertStore(&data, password.c_str(), 0);
PCCERT_CONTEXT hContext = CertFindCertificateInStore(
hCertStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_ANY,
NULL, NULL);
WinHttpSetOption(h, WINHTTP_OPTION_CLIENT_CERT_CONTEXT,
(LPVOID)hContext, sizeof(CERT_CONTEXT));
});
web::http::client::http_client http_client(PS("https://secure.com"), cfg);
THX for replying and sorry for commenting late!
This sounds like a good approach, I will test this ASAP (but will take some time, my schedule as usual is full). The Windows-Only point is currently not an issue for me, I'm also on Windows. So if I get this working this will be OK for me and could avoid me a lot of work/research. Thums up.
Cf. #199
Any news on this ? Would love to see this happen...
Has there been any progress on this, please? I'd like to be able to have my cpprestsdk REST server authenticate a client. Any way to use the example given by @reneme in Linux? I didn't quite get the method described here.
I would like to know how did you achieve that ? I am in the same situation. cpprestsdk does not support HTTPS seems