2010-09-28 57 views
10

我有一台服务器可以使用OpenSSL在HTTPS上侦听。为此,我必须提供使用的证书。但是,当前的实现使用一个文件名来提供给OpenSSL API。使用OpenSSL从内存中读取证书文件而不是文件

我希望从内存中读取证书信息,这样我就不必发运证书文件。我试图谷歌,但我没有拿出任何选择。

可以吗?如果是这样,我如何从内存中读取证书文件而不是使用OpenSSL的文件?


编辑:下面是从评论的问题移动。

// 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 
} 
+0

“我希望从内存中读取证书信息,以便我不必装运证书文件” - 您能澄清一下吗?不确定你在这里的意思。代码在哪里首先得到证书? – 2010-09-28 06:01:51

+0

我现在有了我的证书文件。服务器必须使用它们。通常的做法是向OpenSSL提供证书文件的文件名。 OpenSSL会在内部处理剩下的事情。但我无法直接发送证书文件。我必须将它们硬编码到源代码中。这是要求。所以,我正在考虑在内存缓冲区中拥有证书的选项,并以某种方式使OpenSSL使用该证书信息。 – Karthik 2010-09-28 06:25:14

+0

你可以用一些示例代码来指定你在做什么吗?证书SSL上下文可以从内存中创建,但如果您可以通过一些代码分享您想要实现的内容,这将会很有帮助。 – 2010-09-28 07:00:48

回答

4
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); 

cert_datapkey_data此之前不要忘& - 并注意OpenSSL的修改这些指针。

11

下面的代码做的工作对我来说:


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); 
+1

您不应该忘记相应地释放分配的缓冲区。 – anselm 2015-02-02 13:41:17

4

其他片段将只加载一个证书。包含许多不同证书的文件(如http://curl.haxx.se/ca/cacert.pem)的内容需要一种新方法。这是从openssl 1.0.1p(主要是openssl-1.0.1p \ crypto \ x509 \ by_file.c,char * buf包含一个* .pem文件的内容,ctx是一个boost :: asio :: ssl :: context ),请自行添加错误处理:

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 
+0

非常感谢你@ oliver-zendel它完美地完成了这项工作:)但是,后来我发现了一个错误,所以我将“BIO_free(cbio)”,“最后。我在curl的CURLOPT_SSL_CTX_FUNCTION回调中使用你的代码来读取一个带有2个证书的PEM文件。 – Kervala 2016-03-01 12:02:28

+0

感谢Kervala,我改变了代码片断以确保;) – 2016-04-18 14:03:24

+0

不客气:) – Kervala 2016-04-20 10:59:48

相关问题