Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read certificate files from memory instead of a file using OpenSSL

I have a server which would listen on HTTPS using OpenSSL. For this, I have to provide the certificate to use. However, the current implementation uses a filename to be provided to the OpenSSL API.

I want the certificate information to be read from memory, so that I don't have to ship the certificate file opening. I tried to google, but I didn't come up with any options.

Is is possible? If so, how do I read certificate files from memory instead of a file using OpenSSL?


EDIT: The following was moved from the comments to the question.

// CURRENT
void start_server()
{
    const char *fileName = "cert_and_key.pem";
    set_server_ssl_file(fileName);
}
set_server_ssl_file(const char *fileName)
{
    //initialize context
    SSL_CTX_use_certificate_file(CTX, pem, SSL_FILETYPE_PEM); 
    SSL_CTX_use_PrivateKey_file(CTX, pem, SSL_FILETYPE_PEM);
}

//REQUIRED
void start_server()
{
    const char *cert = "--BEGIN CERTIFICATE--............";
    const char *key = "--BEGIN RSA PRIVATE KEY--.......";
    set_server_ssl_options(cert, key);
}
set_server_ssl_options(const char *cert, const char *key)
{
    //IMPLEMENTATION REQUIRED
}
like image 459
Karthik Avatar asked Sep 28 '10 05:09

Karthik


People also ask

How do I read a cert file?

To view certificates for the current user, open the command console, and then type certmgr. msc. The Certificate Manager tool for the current user appears. To view your certificates, under Certificates - Current User in the left pane, expand the directory for the type of certificate you want to view.

Where are OpenSSL certificates stored?

The directory for all OpenSSL certificates is /var/ssl/. All commands and paths in this document are issued from this directory, it is not mandatory but it will help the examples. OpenSSL by default looks for a configuration file in /usr/lib/ssl/openssl.

How do I find the certificate file path?

Open the Start menu and click inside the “Search Programs and Files” box. Type “certmgr. msc” (without quotes) in the box and press “Enter” to open the Certificate Manager.


2 Answers

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);
like image 186
Karthik Avatar answered Oct 01 '22 01:10

Karthik


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 one
for (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); //cleanup
BIO_free(cbio);//cleanup
like image 42
Oliver Zendel Avatar answered Sep 30 '22 23:09

Oliver Zendel