Документация OpenSSL довольно ограничена, когда речь идет о функциональности ASN.1. Лучший способ узнать об этом - просмотреть соответствующие заголовочные файлы asn1.h
и asn1t.h
, которые являются общедоступными. Они определяют набор макросов, которые позволяют вам создавать свои собственные типы ASN.1. Опять же, просмотр исходного кода - лучший способ понять, как они используются, например, в ts_asn1.c
. Элементарное объяснение дано в ASN1_ITEM () . Веселитесь!
К счастью, ваш пример Rocket
типа прост. Его определение типа ASN.1 с вспомогательными функциями может быть создано следующим образом:
/* 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 и DER. Дополнительную информацию о функциях 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"