Read certificate files from memory instead of a file using OpenSSL Read certificate files from memory instead of a file using OpenSSL c c

Read certificate files from memory instead of a file using OpenSSL


The following code did the job for me:

 SSL_CTX *CTX;X509 *cert = NULL;RSA *rsa = NULL;BIO *cbio, *kbio;const char *cert_buffer = "";const char *key_buffer = "";cbio = BIO_new_mem_buf((void*)cert_buffer, -1);cert = PEM_read_bio_X509(cbio, NULL, 0, NULL);assert(cert != NULL);SSL_CTX_use_certificate(CTX, cert);kbio = BIO_new_mem_buf((void*)key_buffer, -1);rsa = PEM_read_bio_RSAPrivateKey(kbio, NULL, 0, NULL);assert(rsa != NULL);SSL_CTX_use_RSAPrivateKey(CTX, rsa);


The other snippets will only load one certificate. The content of files like http://curl.haxx.se/ca/cacert.pem that contain a lot of different certificates need a new approach. This is adapted from openssl 1.0.1p (mostly openssl-1.0.1p\crypto\x509\by_file.c, char* buf contains the content of a *.pem file, ctx is a boost::asio::ssl::context), add error handling on your own:

BIO *cbio = BIO_new_mem_buf((void*)buf, (int)length);X509_STORE  *cts = SSL_CTX_get_cert_store(ctx.native_handle());if(!cts || !cbio)   return false;X509_INFO *itmp;int i, count = 0, type = X509_FILETYPE_PEM;STACK_OF(X509_INFO) *inf = PEM_X509_INFO_read_bio(cbio, NULL, NULL, NULL);if (!inf){    BIO_free(cbio);//cleanup    return false;}//itterate over all entries from the pem file, add them to the x509_store one by onefor (i = 0; i < sk_X509_INFO_num(inf); i++) {    itmp = sk_X509_INFO_value(inf, i);    if (itmp->x509) {          X509_STORE_add_cert(cts, itmp->x509);          count++;    }    if (itmp->crl) {          X509_STORE_add_crl(cts, itmp->crl);          count++;    }}sk_X509_INFO_pop_free(inf, X509_INFO_free); //cleanupBIO_free(cbio);//cleanup


unsigned char *cert_data = (....);int cert_len = (....);X509 *cert = d2i_X509(NULL, &cert_data, cert_len);SSL_CTX_use_certificate(ctx, cert);unsigned char *pkey_data = /* ... */;int pkey_len = /* ... */;RSA *pkey = d2i_RSAPrivateKey(NULL, &pkey_data, pkey_len);SSL_CTX_use_RSAPrivateKey(ctx, pkey);

Don't forget & before cert_data and pkey_data - and note that OpenSSL modifies these pointers.