Openssl 的 ASN.1 宏
Openssl 中的 ASN.1 宏用来定义某种内部数据结构以及这种结构如何编码,部分宏
定义说明如下:
- DECLARE_ASN1_FUNCTIONS
用于声明一个内部数据结构的四个基本函数,一般可以在头文件中定义。 - IMPLEMENT_ASN1_FUNCTIONS
用于实现一个数据结构的四个基本函数。
3) ASN1_SEQUENCE
用于 SEQUENCE,表明下面的编码是一个 SEQUENCE。 - ASN1_CHOICE
表明下面的编码是选择其中一项,为 CHOICE 类型。
5) ASN1_SIMPLE
用于简单类型或结构类型,并且是必须项。 - ASN1_OPT
用于可选项,表明 asn.1 语法中,本项是可选的。 - ASN1_EXP_OPT
用于显示标记,表明 asn.1 语法中,本项是显示类型,并且是可选的; - ASN1_EXP
用于显示标记,表明 asn.1 语法中,本项是显示标记。
9) ASN1_IMP_SEQUENCE_OF_OPT
用于隐示标记,表明 asn.1 语法中,本项是一个 SEQUENCE 序列,为隐
示类型,并且是可选的。 - ASN1_IMP_OPT
用于隐示标记,表明 asn.1 语法中,本项是隐示类型,并且是可选的。 - ASN1_IMP
用于隐示标记,表明 asn.1 语法中,本项是隐示类型。 - ASN1_SEQUENCE_END
用于 SEQUENCE 结束。 - ASN1_CHOICE_END
用于结束 CHOICE 类型。
步骤:
当采用 Openssl 的 ASN.1 库编码一个 asn.1 定义的结构的时候,需要采用如下步骤:
-
用 ASN.1 语法定义内部数据结构,并声明函数;
所谓内部数据结构, 指的是 Openssl 中用基本的数据类型按照 ASN.1 语法定义的其他的数据结构,这种数据结构可以方便的用于编解码。
以 x509v4 中的证书有效期为例,证书有效期定义如下:AttCertValidityPeriod ::= SEQUENCE
{
notBeforeTime GeneralizedTime,
notAfterTime GeneralizedTime
}
所以我们可以定义相应的内部数据结构,如下:
typedef struct X509V4_VALID_st
{
ASN1_GENERALIZEDTIME *notBefore;
ASN1_GENERALIZEDTIME *notAfter;
}X509V4_VALID;
DECLARE_ASN1_FUNCTIONS(X509V4_VALID)
其中最后一行用于定义四个函数:
X509V4_VALID *X509V4_VALID_new(void);
void *X509V4_VALID_free(X509V4_VALID *a);
X509V4_VALID *d2i_ASN1_INTEGER(X509V4_VALID **a,unsigned char
**in,long len);
int i2d_ X509V4_VALID (X509V4_VALID *a,unsigned char **out);
-
实现内部数据结构的四个基本函数
实现内部数据结构的基本函数,是通过一系列的宏来实现的。定义的模式如下,以
属性证书有效期为例,如下/* X509V4_VALID */
ASN1_SEQUENCE(X509V4_VALID) =
{
ASN1_SIMPLE(X509V4_VALID, notBefore, ASN1_GENERALIZEDTIME),
ASN1_SIMPLE(X509V4_VALID, notAfter, ASN1_GENERALIZEDTIME)
} ASN1_SEQUENCE_END(X509V4_VALID)
IMPLEMENT_ASN1_FUNCTIONS(X509V4_VALID)
这样通过宏就实现了一个 asn.1 定义结构的最基本的四个函数。
本例有五个宏,采用什么样的宏,与数据结构的 asn.1 定义相关。
测试代码:
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/conf.h>
#include <string.h>
typedef struct X509V4_VALID_st
{
ASN1_GENERALIZEDTIME *notBefore;
ASN1_GENERALIZEDTIME *notAfter;
}X509V4_VALID;
DECLARE_ASN1_FUNCTIONS(X509V4_VALID)
ASN1_SEQUENCE(X509V4_VALID) = {
ASN1_SIMPLE(X509V4_VALID, notBefore, ASN1_GENERALIZEDTIME),
ASN1_SIMPLE(X509V4_VALID, notAfter, ASN1_GENERALIZEDTIME)
} ASN1_SEQUENCE_END(X509V4_VALID)
IMPLEMENT_ASN1_FUNCTIONS(X509V4_VALID)
int main(int argc, char const *argv[])
{
int len=0;
char *der;char *p;
unsigned char buf[50] = "abcd";
FILE *fp;
//ASN1_GENERALIZEDTIME *t = ASN1_GENERALIZEDTIME_new();
ASN1_GENERALIZEDTIME t;
t.type = V_ASN1_GENERALIZEDTIME;
t.length = strlen(buf);
t.data = (unsigned char *)buf;
X509V4_VALID *v4 = X509V4_VALID_new();
v4->notAfter = &t;
v4->notBefore = &t;
len= i2d_X509V4_VALID(v4,NULL);
der=(char *)malloc(len);
p = der;
len=i2d_X509V4_VALID(v4,(unsigned char **)&p);
fp=fopen("v4.cer","rw");
fwrite(der,1,len,fp);
fclose(fp);
//X509V4_VALID_free(v4);
free(der);
return 0;
}