本结构用来表示通用名称,它定义在crypto/x509v3/x509v3.h中,如下:
typedef struct GENERAL_NAME_st
{
#define GEN_OTHERNAME0
#define GEN_EMAIL 1
#define GEN_DNS 2
#define GEN_X400 3
#define GEN_DIRNAME 4
#define GEN_EDIPARTY 5
#define GEN_URI 6
#define GEN_IPADD 7
#define GEN_RID 8
int type;
union {
char *ptr;
OTHERNAME *otherName; /* 其他名称 */
ASN1_IA5STRING *rfc822Name; /* 符合rfc822标准的名称 */
ASN1_IA5STRING *dNSName; /* DNS名称 */
ASN1_TYPE *x400Address;
X509_NAME *directoryName; /* 目录名 */
EDIPARTYNAME *ediPartyName;
ASN1_IA5STRING *uniformResourceIdentifier; /* URI名称 */
ASN1_OCTET_STRING *iPAddress; /* IP地址名称 */
ASN1_OBJECT *registeredID;
/* Old names */
ASN1_OCTET_STRING *ip;
X509_NAME *dirn;
ASN1_IA5STRING *ia5;
ASN1_OBJECT *rid; /* registeredID */
ASN1_TYPE *other; /* x400Address */
} d;
} GENERAL_NAME;
typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES;
GENERAL_NAMES为GENERAL_NAME堆栈。
GENERAL_NAME可以包含各种各样的名称。type用来表示该结构采用了什么样的名称,从0~8分别对应otherName、rfc822Name、dNSName、x400Address、directoryName、ediPartyName、uniformResourceIdentifier、iPAddress和registeredID。ptr用来存放通用的各种名称的地址。当type为某一类型时,数据存放在d中对应的项。比如,当type为GEN_DIRNAME时,数据存放在directoryName中。openssl中最常用的是X509_NAME。
上述两种结构的DER编码在crypto/x509v3/v3_genn.c中由宏实现,实现了new、free、i2d和d2i四个函数。
编程示例:
#include <openssl/x509v3.h>
int main()
{
GENERAL_NAME*gn;
GENERAL_NAMES *gns;
char *buf,*p;
int len;
FILE *fp;
gns=sk_GENERAL_NAME_new_null();
/* new 函数 */
gn=GENERAL_NAME_new();
/* 设置gn的值为一个rfc822Name */
gn->type=GEN_EMAIL;
gn->d.rfc822Name=ASN1_STRING_new();
ASN1_STRING_set(gn->d.rfc822Name,"forxy@126.com",13);
len=i2d_GENERAL_NAME(gn,NULL);
p=buf=malloc(len);
len=i2d_GENERAL_NAME(gn,&p);
/* 生成的gn1.cer并不是一个完整的DER编码文件,不能用ASN1view工具查看 */
fp=fopen("gn1.cer","wb");
fwrite(buf,1,len,fp);
fclose(fp);
free(buf);
sk_GENERAL_NAME_push(gns,gn);
/* new 函数 */
gn=GENERAL_NAME_new();
/* 设置gn的值为一个GEN_DIRNAME */
gn->type=GEN_DIRNAME;
gn->d.directoryName=X509_NAME_new();
X509_NAME_add_entry_by_txt(gn->d.directoryName,LN_commonName,V_ASN1_UTF8STRING,"forxy",5,0,-1);
/* i2d 函数 */
len=i2d_GENERAL_NAME(gn,NULL);
p=buf=malloc(len);
len=i2d_GENERAL_NAME(gn,&p);
/* 生成的gn2.cer并不是一个完整的DER编码文件,不能用ASN1view工具查看 */
fp=fopen("gn2.cer","wb");
fwrite(buf,1,len,fp);
fclose(fp);
free(buf);
sk_GENERAL_NAME_push(gns,gn);
/* GENERAL_NAMES 的i2d函数 */
len=i2d_GENERAL_NAMES(gns,NULL);
p=buf=malloc(len);
len=i2d_GENERAL_NAMES(gns,&p);
/* 生成完整的DER编码文件 */
fp=fopen("gns.cer","wb");
fwrite(buf,1,len,fp);
fclose(fp);
free(buf);
sk_GENERAL_NAME_pop_free(gns,GENERAL_NAME_free);
return 0;
}