在OpenSSL documentation中它说:
所有这些功能都以宏的形式实现。包含1的那些增加了提供的证书或链的引用计数,因此必须在操作后的某个时刻释放它。包含0的那些不会增加引用计数,并且在操作之后不得释放提供的证书或链。
但是当我试着查看一些案例的例子时,我应该使用哪一个案件。
首先 OpenSSL :
它在SSL_add0_chain_cert
SSL_CTX_use_certificate_chain_file
函数中使用ssl_rsa.c
。 Here是来源:
static int use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file) {
if (ctx)
ret = SSL_CTX_use_certificate(ctx, x);
else
ret = SSL_use_certificate(ssl, x);
......
while ((ca = PEM_read_bio_X509(in, NULL, passwd_callback,
passwd_callback_userdata))
!= NULL) {
if (ctx)
r = SSL_CTX_add0_chain_cert(ctx, ca);
else
r = SSL_add0_chain_cert(ssl, ca);
......
}
我看到的第二种用法是 OpenResty Lua :
它以一种设置证书(SSL_add0_chain_cert
)的方式使用ngx_http_lua_ffi_ssl_set_der_certificate
,请参阅here:
int ngx_http_lua_ffi_ssl_set_der_certificate(ngx_http_request_t *r,
const char *data, size_t len, char **err) {
......
if (SSL_use_certificate(ssl_conn, x509) == 0) {
*err = "SSL_use_certificate() failed";
goto failed;
}
......
while (!BIO_eof(bio)) {
x509 = d2i_X509_bio(bio, NULL);
if (x509 == NULL) {
*err = "d2i_X509_bio() failed";
goto failed;
}
if (SSL_add0_chain_cert(ssl_conn, x509) == 0) {
*err = "SSL_add0_chain_cert() failed";
goto failed;
}
}
BIO_free(bio);
*err = NULL;
return NGX_OK;
failed:
.......
}
然而以另一种方式使用SSL_add1_chain_cert
(ngx_http_lua_ffi_set_cert
),请参阅here:
int ngx_http_lua_ffi_set_cert(ngx_http_request_t *r,
void *cdata, char **err) {
......
if (SSL_use_certificate(ssl_conn, x509) == 0) {
*err = "SSL_use_certificate() failed";
goto failed;
}
x509 = NULL;
/* read rest of the chain */
for (i = 1; i < sk_X509_num(chain); i++) {
x509 = sk_X509_value(chain, i);
if (x509 == NULL) {
*err = "sk_X509_value() failed";
goto failed;
}
if (SSL_add1_chain_cert(ssl_conn, x509) == 0) {
*err = "SSL_add1_chain_cert() failed";
goto failed;
}
}
*err = NULL;
return NGX_OK; /* No free of x509 here */
failed:
......
}
然而,当我在 Lua 中调用这两个时,我看不出有什么变化的明显区别,并且它看起来不像证书X509,当设置成功时,会被释放在任一情况下。根据我对OpenSSL文档的理解,我希望X509_free(x509)
在调用x509 SSL_add1_chain_cert
后调用ssl_cert_add1_chain_cert
。这是正确的理解吗?
最后,SSL_add1_chain_cert
的 Openssl implementation(从ssl_cert_add0_chain_cert
宏向下归结)确实表明它只是{int ssl_cert_add1_chain_cert(SSL *s, SSL_CTX *ctx, X509 *x)
{
if (!ssl_cert_add0_chain_cert(s, ctx, x))
return 0;
X509_up_ref(x);
return 1;
}
的包装。 {1}}引用计数在证书上递增,但是如何在调用进程中反映出来?
SSL_CTX_add_extra_chain_cert
现在 Nginx 仅处理另一个函数SSL_add0_chain_cert
,这会留下这种选择的负担,因为它不处理每个SSL连接的切换证书。在我的情况下,我需要使用此功能修补Nginx,为每个连接切换证书(但不使用Lua)。
所以我不确定我应该使用哪一个,SSL_add1_chain_cert
或class Program
{
static void Main(string[] args)
{
Template.Render();
Template2.Render();
Console.WriteLine(ReferenceEquals(Template.Factory, Template2.Factory));
}
}
public class BaseTemplate<T> where T : new()
{
static BaseTemplate()
{
Console.WriteLine("BaseTemplate() " + typeof(T).Name);
}
public static object Factory = new object();
public static void Render()
{
Console.WriteLine("Render() from " + typeof(T).Name);
}
}
public class Template : BaseTemplate<Template>
{
static Template()
{
Console.WriteLine("Static ctor()");
}
}
public class Template2 : BaseTemplate<Template2>
{
static Template2()
{
Console.WriteLine("Static ctor() 2");
}
}
?那里的解放实践是什么?