openssl ans1分析

https://www.jianshu.com/p/f97d72d52d4f

感谢上面兄弟的分享,对分析流程有很大的帮助。但是上面文档没有交代清楚流程的来龙去脉。

X509_new分析
ASN1_INTEGER_new分析

 比如自定一个一个结构体

typedef  struct X509V4_VALID_st
{
    ASN1_GENERALIZEDTIME *notBefore;
    ASN1_GENERALIZEDTIME *notAfter;
} X509V4_VALID;
DECLARE_ASN1_FUNCTIONS(X509V4_VALID)

ASN1_SEQUENCE(X509V4_VALID) =
{
    ASN1_SIMPLE(X509V4_VALID, notBefore, ASN1_GENERALIZEDTIME),
    ASN1_SIMPLE(X509V4_VALID, notAfter, ASN1_GENERALIZEDTIME)
} 
ASN1_SEQUENCE_END(X509V4_VALID)
IMPLEMENT_ASN1_FUNCTIONS(X509V4_VALID)

展开后
static const ASN1_TEMPLATE X509V4_VALID_seq_tt[] = 
{
    { 0, 0, offsetof(X509V4_VALID, notBefore), notBefore, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME) },
    { 0, 0, offsetof(X509V4_VALID, notAfter), notAfter, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME) }
};
const ASN1_ITEM X509V4_VALID_it = {
    ASN1_ITYPE_SEQUENCE,\
    V_ASN1_SEQUENCE,\
    X509V4_VALID_seq_tt,\
    sizeof(X509V4_VALID_seq_tt) / sizeof(ASN1_TEMPLATE),\
    NULL,\
    sizeof(X509V4_VALID,),\
    X509V4_VALID \
};

/** 我们以基本类型INTEGER为例子,
ASN1声明方法,以ASN1_INTEGER举例 

ASN1_INTEGER *ASN1_INTEGER_new(void); 
void ASN1_INTEGER_free(ASN1_INTEGER *a);
type *d2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **in, long len); 
int i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **out); 
const ASN1_ITEM ASN1_INTEGER_it;

ASN1方法实现,以ASN1_INTEGER举例 ,应该是这样的,

ASN1_INTEGER *ASN1_INTEGER_new(void)
{
    return (ASN1_INTEGER*)ASN1_item_new(&ASN1_INTEGER_it));
}
void ASN1_INTEGER_free(ASN1_INTEGER *a)
{
    ASN1_item_free((ASN1_VALUE *)a, &ASN1_INTEGER_it);
}
ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **in, long len)
{
    return (ASN1_INTEGER*)ASN1_item_d2i((ASN1_VALUE **)a, in, len, &ASN1_INTEGER_it);
}
int i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **out)
{
    return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_INTEGER_it);
}
但是我们通过调试发现他不是这样的

在asn1.h中,对基本数据类型声明了助记函数:
DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER)
DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED)
DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING)
DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING)
DECLARE_ASN1_FUNCTIONS(ASN1_NULL)
DECLARE_ASN1_FUNCTIONS(ASN1_UTCTIME)
DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME)
DECLARE_ASN1_FUNCTIONS(ASN1_TIME)
DECLARE_ASN1_FUNCTIONS(ASN1_UTF8STRING)


实现在哪里?调试就知道了,他的实现在这里。
在crypto/asn1/tasn_typ.c中
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_OCTET_STRING)
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_INTEGER)
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_ENUMERATED)
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_BIT_STRING)
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_UTF8STRING)
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_PRINTABLESTRING)
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_T61STRING)
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_IA5STRING)
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_GENERALSTRING)
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_UTCTIME)
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_GENERALIZEDTIME)
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_VISIBLESTRING)
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_UNIVERSALSTRING)
IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_BMPSTRING)




实现都是调用的ASN1_STRING_NEW

#define IMPLEMENT_ASN1_STRING_FUNCTIONS(sname) \
IMPLEMENT_ASN1_TYPE(sname) \
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(sname, sname, sname) \
sname *sname##_new(void) \
{ \
return ASN1_STRING_type_new(V_##sname); \
} \
void sname##_free(sname *x) \
{ \
ASN1_STRING_free(x); \
}

这里就是给ans1_string分配了内存后,指定了他的类型为整形

下面我们分析下X509,看他是如何创建的。

crypto/x509/x_x509.c:109
 IMPLEMENT_ASN1_FUNCTIONS(X509)
发现这个it是有值的,他是什么时候被赋值的?
ASN1_item_new (it=0x7ffff7dc13c0 <X509_it>) at crypto/asn1/tasn_new.c:28

这里可以使用反汇编的方式进行调试,可以发现他会调用X509_it()方法,

然后在方法中是通过

eax,offset local_it (7A165DF8h) 将local_it变量的地址给到eax然后传入ASN1_item_new 的。

搜索这个变量的定义在ASN1_ITEM_start中。

可以发现有这么多地方调用ASN1_ITEM_start

asn1t.h (include\openssl) line 35 : # define ASN1_ITEM_start(itname) \
asn1t.h (include\openssl) line 51 : # define ASN1_ITEM_start(itname) \
static_ASN1_ITEM_start in asn1t.h (include\openssl) : static ASN1_ITEM_start(itname)
ASN1_ITEM_TEMPLATE_END in asn1t.h (include\openssl) : ASN1_ITEM_start(tname) \
ASN1_SEQUENCE_END_name in asn1t.h (include\openssl) : ASN1_ITEM_start(tname) \
ASN1_NDEF_SEQUENCE_END in asn1t.h (include\openssl) : ASN1_ITEM_start(tname) \
ASN1_SEQUENCE_END_ref in asn1t.h (include\openssl) : ASN1_ITEM_start(tname) \
ASN1_NDEF_SEQUENCE_END_cb in asn1t.h (include\openssl) : ASN1_ITEM_start(tname) \
ASN1_CHOICE_END_selector in asn1t.h (include\openssl) : ASN1_ITEM_start(tname) \
ASN1_CHOICE_END_cb in asn1t.h (include\openssl) : ASN1_ITEM_start(tname) \
IMPLEMENT_ASN1_TYPE_ex in asn1t.h (include\openssl) : ASN1_ITEM_start(itname) \
IMPLEMENT_ASN1_MSTRING in asn1t.h (include\openssl) : ASN1_ITEM_start(itname) \
IMPLEMENT_EXTERN_ASN1 in asn1t.h (include\openssl) : ASN1_ITEM_start(sname) \
x_bignum.c (crypto\asn1) line 57 : ASN1_ITEM_start(BIGNUM)
x_bignum.c (crypto\asn1) line 61 : ASN1_ITEM_start(CBIGNUM)
x_int64.c (crypto\asn1) line 254 : ASN1_ITEM_start(INT32)
x_int64.c (crypto\asn1) line 259 : ASN1_ITEM_start(UINT32)
x_int64.c (crypto\asn1) line 263 : ASN1_ITEM_start(INT64)
x_int64.c (crypto\asn1) line 268 : ASN1_ITEM_start(UINT64)
x_int64.c (crypto\asn1) line 272 : ASN1_ITEM_start(ZINT32)
x_int64.c (crypto\asn1) line 277 : ASN1_ITEM_start(ZUINT32)
x_int64.c (crypto\asn1) line 282 : ASN1_ITEM_start(ZINT64)
x_int64.c (crypto\asn1) line 287 : ASN1_ITEM_start(ZUINT64)
x_long.c (crypto\asn1) line 45 : ASN1_ITEM_start(LONG)
x_long.c (crypto\asn1) line 49 : ASN1_ITEM_start(ZLONG)

 

而X509的定义

ASN1_SEQUENCE_ref(X509, x509_cb) = {
ASN1_EMBED(X509, cert_info, X509_CINF),
ASN1_EMBED(X509, sig_alg, X509_ALGOR),
ASN1_EMBED(X509, signature, ASN1_BIT_STRING)
ASN1_SEQUENCE_END_ref(X509, X509)

# define ASN1_SEQUENCE_ref(tname, cb) \
static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), offsetof(tname, lock), cb, 0}; \
ASN1_SEQUENCE(tname)

# define ASN1_SEQUENCE(tname) \
static const ASN1_TEMPLATE tname##_seq_tt[]

# define ASN1_SEQUENCE_END_ref(stname, tname) \
;\
ASN1_ITEM_start(tname) \
ASN1_ITYPE_SEQUENCE,\
V_ASN1_SEQUENCE,\
tname##_seq_tt,\
sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
&tname##_aux,\
sizeof(stname),\
#tname \
ASN1_ITEM_end(tname)

这里就是定义的local_it

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值