如何解析ASN.1选择OpenSSL C API

发布于 2025-02-14 00:46:49 字数 2750 浏览 0 评论 0原文

我正在使用openssl 1.1.1g的c API处理ASN.1数据,但是D2I_TYPE函数无法将二进制选择数据转换为结构,这是结构

typedef struct Obj_s {
  ASN1_PRINTABLESTRING *type;
  ASN1_OCTET_STRING *value;
} Obj_t;

DECLARE_ASN1_FUNCTIONS(Obj_t)
DEFINE_STACK_OF(Obj_t)

typedef struct Choice_s {
  int type;
  union {
    STACK_OF(ASN1_OCTET_STRING) *string;
    STACK_OF(Obj_t) *obj;
  } d;
} Choice_t;

DECLARE_ASN1_FUNCTIONS(Choice_t)

和实现的

ASN1_SEQUENCE(Obj_t) = {
    ASN1_SIMPLE(Obj_t, type, ASN1_PRINTABLESTRING),
    ASN1_SIMPLE(Obj_t, value, ASN1_OCTET_STRING)
}ASN1_SEQUENCE_END(Obj_t)

IMPLEMENT_ASN1_FUNCTIONS(Obj_t)

ASN1_CHOICE(Choice_t) = {
    ASN1_SEQUENCE_OF(Choice_t, d.string, ASN1_OCTET_STRING),
    ASN1_SEQUENCE_OF(Choice_t, d.obj, Obj_t)
}ASN1_CHOICE_END(Choice_t)

IMPLEMENT_ASN1_FUNCTIONS(Choice_t)

定义,我

Choice_t *choice = Choice_t_new();

int stack_count = 0;
int test_switch; //0 or 1
switch(test_switch) {
    case 0: {
        choice->type = 0;
        choice->d.string = (STACK_OF(ASN1_OCTET_STRING) *) sk_ASN1_STRING_new_null();
        ASN1_STRING *string = ASN1_STRING_new();
        ASN1_STRING_set(string, /*some string*/, /*length of string*/);
        stack_count = sk_ASN1_STRING_push((STACK_OF(ASN1_STRING) *) choice->d.string, string); // count 1
        stack_count = sk_ASN1_STRING_push((STACK_OF(ASN1_STRING) *) choice->d.string, string); // count 2
        break;
    }
    case 1: {
        choice->type = 1;
        choice->d.obj = sk_Obj_t_new_null();
        
        Obj_t *obj = Obj_t_new();
        ASN1_STRING_set((ASN1_STRING *)obj->type, /*some string*/, /*length of string*/);
        ASN1_STRING_set((ASN1_STRING *)obj->value, /*some value*/, /*length of value*/);
        stack_count = sk_Obj_t_push(choice->d.obj, obj); // count 1
        stack_count = sk_Obj_t_push(choice->d.obj, obj); // count 2
        break;
    }
    default:return;
}

int write_choice_len = i2d_Choice_t(choice, nullptr);
std::vector<unsigned char> write_choice_buf(write_choice_len + 1, 0);
unsigned char *p_write_choice_buf = &write_choice_buf[0];
write_choice_len = i2d_Choice_t(choice, &p_write_choice_buf);
write_choice_buf.resize(write_choice_len);
Utility::WriteFile("file name", "wb+", &write_choice_buf[0], write_choice_len);

std::vector<unsigned char> read_choice_buf(Utility::ReadFile("file name", "rb+"));
const unsigned char *p_read_choice_buf = &read_choice_buf[0];
Choice_t *test_choice = d2i_Choice_t(nullptr, &p_read_choice_buf, (long)read_choice_buf.size());

在test_switch = 0时写了一些测试代码,一切都可以。 ,但是当test_switch = 1时,d2i_choice_t返回null。我怎么了?

当我更改工会成员的顺序时,我发现当type = 1时,d2i_type函数总是返回null

I am using c api of OpenSSL 1.1.1g to process asn.1 data, but d2i_type function cannot convert binary choice data to a structure, this is the definition of structure

typedef struct Obj_s {
  ASN1_PRINTABLESTRING *type;
  ASN1_OCTET_STRING *value;
} Obj_t;

DECLARE_ASN1_FUNCTIONS(Obj_t)
DEFINE_STACK_OF(Obj_t)

typedef struct Choice_s {
  int type;
  union {
    STACK_OF(ASN1_OCTET_STRING) *string;
    STACK_OF(Obj_t) *obj;
  } d;
} Choice_t;

DECLARE_ASN1_FUNCTIONS(Choice_t)

and implementation

ASN1_SEQUENCE(Obj_t) = {
    ASN1_SIMPLE(Obj_t, type, ASN1_PRINTABLESTRING),
    ASN1_SIMPLE(Obj_t, value, ASN1_OCTET_STRING)
}ASN1_SEQUENCE_END(Obj_t)

IMPLEMENT_ASN1_FUNCTIONS(Obj_t)

ASN1_CHOICE(Choice_t) = {
    ASN1_SEQUENCE_OF(Choice_t, d.string, ASN1_OCTET_STRING),
    ASN1_SEQUENCE_OF(Choice_t, d.obj, Obj_t)
}ASN1_CHOICE_END(Choice_t)

IMPLEMENT_ASN1_FUNCTIONS(Choice_t)

I wrote some test code

Choice_t *choice = Choice_t_new();

int stack_count = 0;
int test_switch; //0 or 1
switch(test_switch) {
    case 0: {
        choice->type = 0;
        choice->d.string = (STACK_OF(ASN1_OCTET_STRING) *) sk_ASN1_STRING_new_null();
        ASN1_STRING *string = ASN1_STRING_new();
        ASN1_STRING_set(string, /*some string*/, /*length of string*/);
        stack_count = sk_ASN1_STRING_push((STACK_OF(ASN1_STRING) *) choice->d.string, string); // count 1
        stack_count = sk_ASN1_STRING_push((STACK_OF(ASN1_STRING) *) choice->d.string, string); // count 2
        break;
    }
    case 1: {
        choice->type = 1;
        choice->d.obj = sk_Obj_t_new_null();
        
        Obj_t *obj = Obj_t_new();
        ASN1_STRING_set((ASN1_STRING *)obj->type, /*some string*/, /*length of string*/);
        ASN1_STRING_set((ASN1_STRING *)obj->value, /*some value*/, /*length of value*/);
        stack_count = sk_Obj_t_push(choice->d.obj, obj); // count 1
        stack_count = sk_Obj_t_push(choice->d.obj, obj); // count 2
        break;
    }
    default:return;
}

int write_choice_len = i2d_Choice_t(choice, nullptr);
std::vector<unsigned char> write_choice_buf(write_choice_len + 1, 0);
unsigned char *p_write_choice_buf = &write_choice_buf[0];
write_choice_len = i2d_Choice_t(choice, &p_write_choice_buf);
write_choice_buf.resize(write_choice_len);
Utility::WriteFile("file name", "wb+", &write_choice_buf[0], write_choice_len);

std::vector<unsigned char> read_choice_buf(Utility::ReadFile("file name", "rb+"));
const unsigned char *p_read_choice_buf = &read_choice_buf[0];
Choice_t *test_choice = d2i_Choice_t(nullptr, &p_read_choice_buf, (long)read_choice_buf.size());

When test_switch = 0, everything is ok, but when test_switch = 1, d2i_choice_t return null. What's wrong with me?

When I change the order of the union members, I find that when type=1, the d2i_type function always returns null

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文