使用openssl解析自定义asn1数据失败
我现有一段asn1结构体数据如下:
现在我用openssl自定义了对应的结构体,并用代码去解析但是返回了错误:
//对应的结构定义
typedef struct Data_st
{
ASN1_OBJECT* type;
ASN1_BOOLEAN* critical;
ASN1_OCTET_STRING* extnValue;
}Data;
DECLARE_ASN1_FUNCTIONS(Data)
ASN1_SEQUENCE(Data) = {
ASN1_SIMPLE(Data, type, ASN1_OBJECT),
ASN1_SIMPLE(Data, critical, ASN1_BOOLEAN),
ASN1_SIMPLE(Data, extnValue, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(Data)
IMPLEMENT_ASN1_FUNCTIONS(Data)
typedef struct Datas_st
{
STACK_OF(Data)* list;
} Datas;
DECLARE_ASN1_FUNCTIONS(Datas)
ASN1_SEQUENCE(Datas) = {
ASN1_SEQUENCE_OF(Datas, list, Data)
} ASN1_SEQUENCE_END(Datas)
IMPLEMENT_ASN1_FUNCTIONS(Datas)
//解析的代码:
void func()
{
unsigned char* ucData = NULL;
int nDataLen = 0;
FILE* pf = fopen("Datas", "rb");
if (pf)
{
fseek(pf, 0, SEEK_END);
nDataLen = ftell(pf);
fseek(pf, 0, SEEK_SET);
ucData = new unsigned char[nDataLen];
fread(ucData, 1, nDataLen, pf);
fclose(pf);
}
else
{
std::cout << "read err\n";
return;
}
const unsigned char* ucDataTmp = ucData;
Datas* p = d2i_Datas(NULL, &ucDataTmp, nDataLen);
if (p)
{
}
else
{
unsigned long ul = ERR_get_error();
std::cout << ERR_error_string(ul, NULL) << std::endl;
std::cout << "parse err\n";
delete[] ucData ;
return;
}
delete[] ucData ;
}
因为Data对象可能有多个,所以用了STACK_OF
以上代码解析会走到parse err,得到的openssl错误信息是:
error:0D0680A8:asn1 encoding routines:asn1_check_tlen:wrong tag
请帮忙看看是哪里弄错了
有没有高手能帮帮我...
引用 皆我百晓生 小程序回复内容作答:
根据您提供的代码和错误信息,问题可能出在以下几个方面:
ASN1结构体定义不正确:在ASN1_SEQUENCE(Datas)
宏中,应该使用ASN1_SEQUENCE_OF(Datas, list, Data)
来表示list
是由Data
对象组成的。所以您需要修改为ASN1_SEQUENCE_OF(Datas, list, Data)
。
ASN1结构体成员类型不正确:在Data
结构体中,critical
应该是ASN1_BOOLEAN
类型的指针而不是对象。所以您需要修改为ASN1_BOOLEAN* critical
。
请尝试更正上述问题,然后重新编译和运行代码,看看能否解析成功。如果问题仍然存在,请提供更多的相关信息和代码,以便我们能够更好地帮助您。
【以下回答由 GPT 生成】
根据您提供的代码和错误信息,问题出在ASN1_SEQUENCE定义上。由于ASN1_SEQUENCE使用ASN1_SIMPLE宏定义Data结构体的成员,所以需要将这些成员指针定义成指向指针的形式,而不是普通指针。代码应该如下所示:
typedef struct Data_st
{
ASN1_OBJECT* type;
ASN1_BOOLEAN* critical;
ASN1_OCTET_STRING** extnValue;
}Data;
然后,您还需要更新ASN1_SEQUENCE宏以正确解析extnValue成员:
ASN1_SEQUENCE(Data) = {
ASN1_SIMPLE(Data, type, ASN1_OBJECT),
ASN1_SIMPLE(Data, critical, ASN1_BOOLEAN),
ASN1_EXP_OPT(Data, extnValue, ASN1_OCTET_STRING, 0)
} ASN1_SEQUENCE_END(Data)
更新后的代码应该能够正确解析asn1数据。