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.
我有一台服务器可以使用OpenSSL监听HTTPS。为此,我必须提供使用证书。但是,当前实现使用文件名提供给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?
有可能吗?如果是这样,我如何使用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
}
3 个解决方案
#1
12
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);
#2
5
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:
其他代码段只会加载一个证书。包含许多不同证书的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
#3
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);
Don't forget &
before cert_data
and pkey_data
- and note that OpenSSL modifies these pointers.
不要忘记&之前的cert_data和pkey_data - 并注意OpenSSL修改这些指针。
#1
12
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);
#2
5
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:
其他代码段只会加载一个证书。包含许多不同证书的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
#3
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);
Don't forget &
before cert_data
and pkey_data
- and note that OpenSSL modifies these pointers.
不要忘记&之前的cert_data和pkey_data - 并注意OpenSSL修改这些指针。