使用openssl解析自定义asn1数据失败

使用openssl解析自定义asn1数据失败
我现有一段asn1结构体数据如下:

img

现在我用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
请帮忙看看是哪里弄错了

有没有高手能帮帮我...

引用 皆我百晓生 小程序回复内容作答:

根据您提供的代码和错误信息,问题可能出在以下几个方面:

  1. ASN1结构体定义不正确:在ASN1_SEQUENCE(Datas)宏中,应该使用ASN1_SEQUENCE_OF(Datas, list, Data)来表示list是由Data对象组成的。所以您需要修改为ASN1_SEQUENCE_OF(Datas, list, Data)

  2. 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数据。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^