2016-12-15 16 views
6

Tôi muốn mã hóa cấu trúc X509 thành các byte DER. Sau dụ mã nguồn từ openssl (phiên bản> 0.9.7) man page tôi cần phải làm (nếu tôi sẽ i2d_X509 để cấp phát bộ nhớ trên riêng của mình):Cách chính xác để bộ đệm đầu ra miễn phí sau khi cuộc gọi đến openssl :: i2d_X509 là gì?

int len; 
unsigned char *buf; 

buf = NULL; 

len = i2d_X509(x, &buf); 

if (len < 0) 
    /* error */ 

Tuy nhiên, nó không phải là hoàn toàn rõ ràng (nhưng tôi giả định nó là cần thiết để gọi OPENSSL_free) từ tài liệu hướng dẫn đúng cách để giải phóng bộ nhớ sau khi tôi được thực hiện với buf là gì.

Cách chính xác để miễn phí buf là gì?

+0

Assuption của bạn có vẻ đúng với tôi. –

+0

@MichaelWalz, hy vọng như vậy. Nhưng hành vi không được xác định, ví dụ: nó có thể xảy ra rằng nó sẽ là cần thiết để buf miễn phí ngay cả khi lỗi xảy ra. – tysonite

Trả lời

1

Trả lời ngắn: OPENSSL_free phải được sử dụng miễn phí buf.

Câu trả lời dài: IMPLEMENT_ASN1_FUNCTIONS macro được mở rộng thành định nghĩa của hàm i2d_X509. Ví dụ dưới đây cho thấy rằng, đặt mã nguồn sau vào một source.c:

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

Sau khi thực hiện các gcc -E source.c vĩ mô được mở rộng để:

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

các địa điểm ưa thích là định nghĩa của i2d_X509, lần lượt mà gọi hàm ASN1_item_i2d. Theo mã nguồn của openssl, ASN1_item_i2d là một chức năng được xác định trong tasn_enc.c file:

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

Nhánh if (out && !*out) được sử dụng trong một trường hợp được mô tả trong câu hỏi ban đầu (bufNULL). Vì vậy, nội bộ, openssl phân bổ bộ nhớ cho buf sử dụng OPENSSL_malloc và kết quả là OPENSSL_free phải được sử dụng để deallocate bộ nhớ.

Lưu ý: Tôi đã xem mã nguồn của openssl khả dụng trên GH vào thời điểm hiện tại.

Các vấn đề liên quan