I'd like to store my CAs in a string inside my binary instead of loading it in via SSL_CTX_load_verify_locations, which takes in file paths and folder paths.
However, I can't find a method that lets me take in a string.
I don't know of a documented way to do this. The only way I know of is to roll your own verification, e.g. create a store using X509_STORE_CTX_new, add the trusted CAs with X509_STORE_CTX_trusted_stack, add the certificate with X509_STORE_CTX_set_cert add some other chain certificates and CRLs with similar function and finally call X509_verify_cert on the X509_STORE_CTX.
OK I figured out how to do it. OpenSSL has a bunch of ways to deal with loading certs, and many of them add the certs to the non-trusted chain. You must use SSL_CTX_get_cert_store and X509_STORE_add_cert in conjunction. These two functions take in X509 pointers, which can be created from a raw c string. Since the documentation is pretty much non-existent for these two functions, so I figured I'd share the code here:
Edit: this is basically Steffen Ulrich's method except using X509_STORE_add_cert.
#include <openssl/ssl.h>
#include <openssl/bio.h>
#include <openssl/x509.h>
void read_cert_into_ctx(istream &some_stream, SSL_CTX *ctx) {
// Add a stream of PEM formatted certificate strings to the trusted store
// of the ctx.
string line;
string buffer;
while(getline(some_stream, line)) {
buffer.append(line);
buffer.append("\n");
if(line == "-----END CERTIFICATE-----") {
BIO *bio;
X509 *certificate;
bio = BIO_new(BIO_s_mem());
BIO_puts(bio, buffer.c_str());
certificate = PEM_read_bio_X509(bio, NULL, 0, NULL);
if(certificate == NULL)
throw std::runtime_error("could not add certificate to trusted\
CAs");
X509_STORE* store = SSL_CTX_get_cert_store(ctx);
int result = X509_STORE_add_cert(store, certificate);
BIO_free(bio);
buffer = "";
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With