调用 openssl::i2d_X509 后释放输出缓冲区的正确方法是什么?

问题描述 投票:0回答:1

我想将X509结构编码为DER字节。以下来自 openssl(版本> 0.9.7)手册页的源代码示例我需要做(如果我愿意

i2d_X509
自己分配内存):

int len;
unsigned char *buf;

buf = NULL;

len = i2d_X509(x, &buf);

if (len < 0)
    /* error */

但是,从文档中并不完全清楚(但我认为需要调用

OPENSSL_free
),在我完成
buf
后释放内存的正确方法是什么。

正确的释放方法是什么

buf

c memory-management openssl x509
1个回答
5
投票

简短回答:必须使用

OPENSSL_free
来释放
buf

长答案

IMPLEMENT_ASN1_FUNCTIONS
宏扩展为
i2d_X509
函数的定义。下面的例子演示了,将以下源代码放入
source.c

#include <openssl/asn1t.h>
IMPLEMENT_ASN1_FUNCTIONS(X509)

执行

gcc -E source.c
后,宏扩展为:

X509 *d2i_X509(X509 **a, const unsigned char **in, long len) { return (X509 *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, (&(X509_it))); }
int i2d_X509(X509 *a, unsigned char **out) { return ASN1_item_i2d((ASN1_VALUE *)a, out, (&(X509_it))); }
X509 *X509_new(void) { return (X509 *)ASN1_item_new((&(X509_it))); } 
void X509_free(X509 *a) { ASN1_item_free((ASN1_VALUE *)a, (&(X509_it))); }

感兴趣的点是

i2d_X509
的定义,进而该函数调用
ASN1_item_i2d
。根据openssl的源代码,
ASN1_item_i2d
是在
tasn_enc.c
文件中定义的函数:

static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
                               const ASN1_ITEM *it, int flags)
{
    if (out && !*out) {
        unsigned char *p, *buf;
        int len;
        len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags);
        if (len <= 0)
            return len;
        buf = OPENSSL_malloc(len);
        if (buf == NULL)
            return -1;
        p = buf;
        ASN1_item_ex_i2d(&val, &p, it, -1, flags);
        *out = buf;
        return len;
    }

    return ASN1_item_ex_i2d(&val, out, it, -1, flags);
}

分支

if (out && !*out)
用于原始问题中描述的情况(
buf
NULL
)。因此,在内部,openssl 使用
buf
OPENSSL_malloc
分配内存,因此必须使用
OPENSSL_free
来释放内存。

注意:我查看了当前 GH 上可用的 openssl 的源代码。

© www.soinside.com 2019 - 2024. All rights reserved.