概述
众所周知,使用OpenSSL建立连接,需要加载密钥、证书、证书链、根证书等,这些接口从文件中加载很方便,但有些使用场景使我们必须从内存加载,以下是保姆级介绍OpenSSL从内存中加载密钥、证书、证书链、根证书的具体实现方法。
加载密钥
加载私钥主要通过SSL_CTX_use_PrivateKey
函数实现。
/* 获取并加载私钥 */
pKey = (unsigned char *)malloc(KEY_MAXSIZE);
if (NULL == pKey)
{
return -1;
}
memset(pKey,0,KEY_MAXSIZE);
// 获取私钥内容方式省略。。。
// pKey为私钥内容,pKeylen为私钥长度
BIO * pkeybio = BIO_new_mem_buf(pKey, pKeylen);
if (NULL == pkeybio)
{
free(pKey);
return -1;
}
EVP_PKEY* evpkey = PEM_read_bio_PrivateKey(pkeybio, NULL, NULL, NULL);
if (NULL == evpkey)
{
free(pKey);
BIO_free(pkeybio);
return -1;
}
if (!SSL_CTX_use_PrivateKey(ctx,evpkey))
{
free(pKey);
BIO_free(pkeybio);
EVP_PKEY_free(evpkey);
return -1;
}
/* 输入私钥密码 */
if (pin != NULL)
{
SSL_CTX_set_default_passwd_cb_userdata(ctx, pin);
}
加载端证书
加载端证书主要通过SSL_CTX_use_certificate
函数实现。
pKey = (unsigned char *)malloc(CERT_MAXSIZE);
if (NULL == Cert)
{
return -1;
}
memset(Cert,0,CERT_MAXSIZE);
// 获取证书内容方式省略。。。
// Cert为证书内容,Certlen为私钥长度
BIO * certbio = BIO_new_mem_buf(Cert, Certlen);
if (NULL == certbio)
{
return -1;
}
X509 * cert_x509 = PEM_read_bio_X509(certbio, NULL, 0, NULL);
if (NULL == cert_x509)
{
BIO_free(certbio);
return -1;
}
if (!SSL_CTX_use_certificate(ctx, cert_x509))
{
BIO_free(certbio);
X509_free(cert_x509);
return -1;
}
加载证书链
有些时候使用的通讯证书为证书链,这时我们必须依次按顺序加载其中证书,我在这里封成了一个函数。文章来源:https://www.toymoban.com/news/detail-738684.html
int SSL_CTX_use_certificate_chain_mem(SSL_CTX *ctx, void *data, int data_len)
{
int alRet = 0;
ERR_clear_error(); // 清空错误队列
/* 从内存中读取证书链 */
BIO * certbio = BIO_new_mem_buf(data, data_len);
if (NULL == certbio)
{
return -1;
}
/* 读取并加载端证书 */
X509 * cert_x509 = PEM_read_bio_X509_AUX(certbio, NULL, NULL, NULL);
if (NULL == cert_x509)
{
BIO_free(certbio);
return -1;
}
if (!SSL_CTX_use_certificate(ctx, cert_x509))
{
BIO_free(certbio);
X509_free(cert_x509);
return -1;
}
/* 读取并加载额外sub证书 */
alRet = SSL_CTX_clear_extra_chain_certs(ctx); // 清空额外证书
while (alRet)
{
cert_x509 = PEM_read_bio_X509(certbio, NULL, NULL, NULL);
if (!cert_x509)
{
/* 加载到文件结束,成功退出 */
BIO_free(certbio);
X509_free(cert_x509);
ERR_clear_error();
return OK;
}
/* 加载额外证书 */
alRet = SSL_CTX_add_extra_chain_cert(ctx, cert_x509);
if (!alRet)
{
BIO_free(certbio);
X509_free(cert_x509);
return -1;
}
}
}
加载根证书
加载根证书比加载私钥和端证书复杂些,需要修改cert_store来实现。文章来源地址https://www.toymoban.com/news/detail-738684.html
/* 获取并加载根证书 */
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
caCert = (unsigned char *)malloc(CACERT_MAXSIZE);
if (NULL == caCert)
{
return NTS_ERR_MALLOC;
}
memset(caCert,0,CACERT_MAXSIZE);
// 获取根证书内容方式省略。。。
// caCert为证书内容,caCertlen为私钥长度
X509_STORE *ca_store = X509_STORE_new();
ca_store = SSL_CTX_get_cert_store(ctx);
if (NULL == ca_store)
{
free(caCert);
return -1;
}
BIO * cabio = BIO_new_mem_buf(caCert, caCertlen);
if (NULL == cabio)
{
free(caCert);
X509_STORE_free(ca_store);
return -1;
}
X509 * cacert_x509 = PEM_read_bio_X509(cabio, NULL, 0, NULL);
if (NULL == cacert_x509)
{
free(caCert);
X509_STORE_free(ca_store);
BIO_free(cabio);
return -1;
}
if ( !X509_STORE_add_cert(ca_store, cacert_x509) )
{
free(caCert);
X509_STORE_free(ca_store);
BIO_free(cabio);
X509_free(cacert_x509);
return -1;
}
free(caCert);
BIO_free(cabio);
X509_free(cacert_x509);
到了这里,关于OpenSSL从内存中加载密钥、证书、证书链、根证书的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!