2016-12-15 12 views
6

X509構造体をDERバイトにエンコードしたい。 opensslのからソースコードの例を、以下の(バージョン> 0.9.7)man page(私はi2d_X509が独自にメモリを割り当てるかどう)私は実行する必要があります。しかしopenssl :: i2d_X509の呼び出し後に出力バッファを解放する正しい方法は何ですか?

int len; 
unsigned char *buf; 

buf = NULL; 

len = i2d_X509(x, &buf); 

if (len < 0) 
    /* error */ 

、それは完全に明確ではありません(私は仮定しますbufで完了したらメモリを解放する正しい方法は何かをドキュメントからOPENSSL_freeと呼ぶ必要があります)。

bufを無料にする正しい方法は何ですか?

+0

私の考えは正しいです。 –

+0

@MichaelWalz、そうそう。しかし、その動作は定義されていません。エラーが発生してもbufを解放する必要が生じることがあります。 – tysonite

答えて

1

短い回答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

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)は(bufNULLある)元の質問に記載された場合に使用されている:のOpenSSLのソースコードに従って、ASN1_item_i2dtasn_enc.cファイルで定義された関数です。したがって、内部的には、bufのメモリはOPENSSL_mallocを使用してopensslに割り当てられます。その結果、メモリの割り当てを解除するにはOPENSSL_freeを使用する必要があります。

メモ:現時点でGHで利用可能なソースコードopensslを見ました。

関連する問題