首先是几个结构体的定义
struct ASN1_TLC_st{ char valid; /* Values below are valid */ int ret; /* return value */ long plen; /* length */ int ptag; /* class value */ int pclass; /* class value */ int hdrlen; /* header length */ };
struct ASN1_ITEM_st { char itype; /* The item type, primitive, SEQUENCE, CHOICE or extern */ long utype; /* underlying type */ const ASN1_TEMPLATE *templates; /* If SEQUENCE or CHOICE this contains the contents */ long tcount; /* Number of templates if SEQUENCE or CHOICE */ const void *funcs; /* functions that handle this type */ long size; /* Structure size (usually)*/ #ifndef NO_ASN1_FIELD_NAMES const char *sname; /* Structure name */ #endif };
struct ASN1_TEMPLATE_st { unsigned long flags; /* Various flags */ long tag; /* tag, not used if no tagging */ unsigned long offset; /* Offset of this field in structure */ #ifndef NO_ASN1_FIELD_NAMES char *field_name; /* Field name */ #endif ASN1_ITEM_EXP *item; /* Relevant ASN1_ITEM or ASN1_ADB */ };
上次说到d2i_x509的实现最终是通过调用ASN1_item_d2i来实现的。所以我们现在进入到ASN1_item_d2i来看看究竟。
ASN1_item_d2i一共有4个参数,前三个参数都是由d2i_x509传进来,第4个参数it是通过ASN1_ITEM_rptr(X509)这样的宏转换而来。ASN1_ITEM_rptr的定义是#define ASN1_ITEM_rptr(ref) (&(ref##_it)),由此我们得知这个参数实际上扩展为&X509_it. 那么这个X509_it是如何定义的呢?这个问题着实困扰了我好一阵,始终没能search到,最后是通过dump编译好的obj文件里面找到其类型为local_it来实现,于是在code里面搜索local_it,总算发现了源头。
在文件asn1t.h的line102,有这样的2个宏。
#define ASN1_ITEM_start(itname) / const ASN1_ITEM * itname##_it(void) / { / static const ASN1_ITEM local_it = { /
#define ASN1_ITEM_end(itname) / }; / return &local_it; / }
在x_x509.c的line119中,有如下宏
ASN1_SEQUENCE_ref(X509, x509_cb, CRYPTO_LOCK_X509) = { ASN1_SIMPLE(X509, cert_info, X509_CINF), ASN1_SIMPLE(X509, sig_alg, X509_ALGOR), ASN1_SIMPLE(X509, signature, ASN1_BIT_STRING) } ASN1_SEQUENCE_END_ref(X509, X509)
最后的ASN1_SEQUENCE_END_ref(X509, X509)又会通过ASN1_ITEM_start来最终定义X509_it函数。X509_it函数将返回一个local_it的静态变量指针,ASN_ITEM的各个域则在宏ASN1_SEQUENCE_END_ref里面定义。
至此,函数的参数总算是齐了,下次在深入到ASN1_item_ex_d2i函数里面。