当谈到ASN.1功能时,OpenSSL文档是相当有限的。了解它的最好方法是检查关联的头文件
asn1.h
和
asn1t.h
,这是公开的。它们定义了一组宏,允许您创建自己的ASN.1类型。同样,查看源代码是理解如何使用它们的最好方法,例如
ts_asn1.c
. 基本解释见
ASN1_ITEM()
. 玩得高兴!
幸运的是,你的例子
Rocket
类型很简单。它的asn.1类型定义和helper函数可以创建如下:
/* Rocket.h */
#include <openssl/asn1.h>
typedef struct Rocket_st {
ASN1_IA5STRING *name;
ASN1_IA5STRING *type;
} ROCKET;
DECLARE_ASN1_FUNCTIONS(ROCKET)
结构是手工编码的,
DECLARE_ASN1_FUNCTIONS
宏展开为一组助手函数,这些函数按以下方式实现:
/* Rocket.c */
#include "Rocket.h"
#include <openssl/asn1t.h>
ASN1_SEQUENCE(ROCKET) = {
ASN1_SIMPLE(ROCKET, name, ASN1_IA5STRING),
ASN1_SIMPLE(ROCKET, type, ASN1_IA5STRING),
} ASN1_SEQUENCE_END(ROCKET)
IMPLEMENT_ASN1_FUNCTIONS(ROCKET)
编译后,符号表如下所示(我使用的是Mac):
$ objdump -t Rocket.o
Rocket.o: file format Mach-O 64-bit x86-64
SYMBOL TABLE:
00000000000000d0 l __DATA,__const _ROCKET_seq_tt
00000000000000a0 g F __TEXT,__text _ROCKET_free
0000000000000120 g __DATA,__const _ROCKET_it
0000000000000080 g F __TEXT,__text _ROCKET_new
0000000000000000 g F __TEXT,__text _d2i_ROCKET
0000000000000040 g F __TEXT,__text _i2d_ROCKET
0000000000000000 *UND* _ASN1_IA5STRING_it
0000000000000000 *UND* _ASN1_item_d2i
0000000000000000 *UND* _ASN1_item_free
0000000000000000 *UND* _ASN1_item_i2d
0000000000000000 *UND* _ASN1_item_new
未定义的符号由openssl提供
crypto
图书馆。您可以使用
ROCKET
以它们的名义在C结构和顺序序列化数据之间进行来回转换。关于
d2i
和
i2d
函数可以在openssl文档页面中找到
d2i_X509
. 您的应用程序代码可能类似于以下内容:
ROCKET *rocket;
ROCKET *rocket2;
unsigned char *rocketString;
const unsigned char *ptr;
int len;
rocket = ROCKET_new();
rocket->name = ASN1_IA5STRING_new();
ASN1_STRING_set(rocket->name, "Falcon", -1);
rocket->type = ASN1_IA5STRING_new();
ASN1_STRING_set(rocket->type, "Boo", -1);
len = i2d_ROCKET(rocket, &rocketString);
printf("DER-encoded Rocket has length %d\n", len);
ptr = rocketString;
rocket2 = d2i_ROCKET(NULL, &ptr, len);
printf("rocket2 fields are:\n name = \"%s\"\n type = \"%s\"\n",
ASN1_STRING_get0_data(rocket2->name),
ASN1_STRING_get0_data(rocket2->type));
结果是:
$ ./main
DER-encoded Rocket has length 15
rocket2 fields are:
name = "Falcon"
type = "Boo"