该结构是一个名称集合,在crypto/x509/x509.h中定义如下:
struct X509_name_st
{
STACK_OF(X509_NAME_ENTRY) *entries;
int modified;
#ifndef OPENSSL_NO_BUFFER
BUF_MEM *bytes;
#else
char *bytes;
#endif
unsigned long hash;
}
它主要包含了X509_NAME_ENTRY堆栈信息,bytes用于存放DER编码值,hash为该结构的摘要计算值。该结构的DER编解码在crypto/asn1/x_name.c中由宏实现。
主要函数:
1) int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, int loc,
int set)
将一个X509_NAME_ENTRY放入X509_NAME的堆栈中,在堆栈中的位置由loc指定。
2) int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, unsigned char *bytes, int len, int loc, int set)
根据nid在X509_NAME的X509_NAME_ENTRY堆栈中添加一项;bytes 为要添加项的值,type指明了types的ASN1类型,loc为堆栈中的位置;根据nid能够获取ASN1_OBJECT(OBJ_nid2obj函数)。
3) X509_NAME_add_entry_by_OBJ
与2)类似,只是要添加的项由ASN1_OBJECT来表示。
4) X509_NAME_add_entry_by_txt
与2)类似,只是要添加的项由字符串来表示,根据txt能获取ASN1_OBJECT(OBJ_txt2obj函数)。
3) X509_NAME_ENTRY 509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, int type, unsigned char *bytes, int len)
根据nid来生成一个X509_NAME_ENTRY,bytes 为要添加项的值,type指明了types的ASN1类型。
4) X509_NAME_ENTRY_create_by_OBJ
与5)类似,生成的项由ASN1_OBJECT来表示。
5) X509_NAME_ENTRY_create_by_txt
与5)类似,生成的项有字符串来表示。
6) int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len)
根据NID来获取值,结果存放在buf中。
7) X509_NAME_get_text_by_OBJ
根据ASN1_OBJECT来获取值。
10) int X509_NAME_get_index_by_OBJ(X509_NAME *name,
ASN1_OBJECT *obj, int lastpos)
根据ASN1_OBJECT获取NAME_ENTRY在堆栈中的位置。
11) X509_NAME_get_index_by_NID
根据NID获取X509_NAME_ENTRY在堆栈中的位置。
12)X509_NAME_cmp
名字比较。
13)X509_NAME_delete_entry
从堆栈中删除一个指定位置的X509_NAME_ENTRY,并将它返回。
14)X509_NAME_digest
根据指定的算法,对X509_NAME做摘要计算。
15)X509_NAME_dup
名字拷贝。
16)X509_NAME_entry_count
获取X509_NAME的X509_NAME_ENTRY堆栈中元素个数。
17)X509_NAME_ENTRY_dup
X509_NAME_ENTRY拷贝。
18)X509_NAME_ENTRY_get/set_data
获取/设置一项名称的值;set函数还需指明值的ASN1类型。
19)X509_NAME_ENTRY_get/set_object
获取/设置一项名称的ASN1_OBJECT。
20)X509_NAME_get_entry
根据指定堆栈位置获取一个X509_NAME_ENTRY。
21)X509_NAME_hash
摘要计算,该结果是对MD5的结果处理后的值。
22)char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
将a表示的名字变成:/OU=z/CN=的形式放在buf中,返回buf首地址。
23) X509_NAME_print/ X509_NAME_print_ex
打印X509_NAME到bio中。
24) X509_NAME_print_ex_fp
打印X509_NAME到FILE中。
25) int X509_NAME_set(X509_NAME **xn, X509_NAME *name)
通过dup函数,设置*xn的值为name。
编程示例:
#include <string.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
int main()
{
X509 *x;
BIO *b,*out;
int ret,len,position,count;
unsigned int mdl;
unsigned charmd[20];
char buf[1024],*bufp,bytes[500];
const EVP_MD*type;
X509_NAME *xname,*xn;
unsigned long hv=0;
FILE *fp;
ASN1_OBJECT *obj;
X509_NAME_ENTRY *entry,*c=NULL,*c1;
ASN1_STRING *str;
/* cert.cer为PEM格式的数字证书 */
b=BIO_new_file("b64cert.cer","r");
if(b==NULL)
{
printf("can not open b64cert.cer!\n");
return -1;
}
x=PEM_read_bio_X509(b,NULL,NULL,NULL);
/* X509_NAME 函数 */
/* X509_get_issuer_name,返回指针地址 */
xname=X509_get_issuer_name(x);
/* X509_get_subject_name,返回指针地址 */
xname=X509_get_subject_name(x);
/* X509_NAME_hash,将X509_NAME数据结构中缓存的DER编码值(放在bytes中)MD5,其结果再做运算,注意xname->hash此时的值无意义 */
hv=X509_NAME_hash(xname);
/* X509_NAME_print */
out=BIO_new(BIO_s_file());
BIO_set_fp(out,stdout,BIO_NOCLOSE);
X509_NAME_print(out,xname,0);
printf("\n");
/* X509_NAME_print_ex_fp */
fp=stdout;
X509_NAME_print_ex_fp(fp,xname,0,XN_FLAG_SEP_MULTILINE);
printf("\n\n");
/* X509_NAME_print_ex,XN_FLAG_SEP_MULTILINE表明个值打印时占一行*/
X509_NAME_print_ex(out,xname,0,XN_FLAG_SEP_MULTILINE);
printf("\n");
/* X509_NAME_get_text_by_NID */
len=1024;
ret=X509_NAME_get_text_by_NID(xname,NID_commonName,buf,len);
printf("commonName : %s\n\n",buf);
/* X509_NAME_get_text_by_OBJ */
len=1024;
obj=OBJ_nid2obj(NID_commonName);
memset(buf,0,1024);
ret=X509_NAME_get_text_by_OBJ(xname,obj,buf,len);
printf("commonName : %s\n\n",buf);
/* X509_NAME_get_index_by_NID */
position=X509_NAME_get_index_by_NID(xname,NID_commonName,-1);
entry=X509_NAME_get_entry(xname,position);
printf("entry value : %s\n",entry->value->data);
/* X509_NAME_ENTRY_get_data */
str=X509_NAME_ENTRY_get_data(entry);
/* X509_NAME_ENTRY_get_object */
obj=X509_NAME_ENTRY_get_object(entry);
/* X509_NAME_entry_count */
count=X509_NAME_entry_count(xname);
/* X509_NAME_get_index_by_OBJ */
len=1024;
memset(buf,0,1024);
position=X509_NAME_get_index_by_OBJ(xname,obj,-1);
entry=X509_NAME_get_entry(xname,position);
printf("entry value : %s\n",entry->value->data);
/* X509_NAME_digest */
type=EVP_sha1();
ret=X509_NAME_digest(x->cert_info->subject,type,md,&mdl);
if(ret!=1)
{
printf("X509_NAME_digest err.\n");
BIO_free(b);
X509_free(x);
return -1;
}
/* X509_name_cmp */
ret=X509_name_cmp(x->cert_info->subject,x->cert_info->issuer);
if(ret==0)
{
printf("subject == issuer\n");
}
else
{
printf("subject != issuer\n");
}
/* X509_NAME_oneline */
len=1024;
bufp=X509_NAME_oneline(x->cert_info->subject,buf,len);
if(bufp==NULL)
{
printf("X509_NAME_oneline err\n");
}
else
{
printf("%s\n",buf);
}
/* 构造X509_NAME */
xn=X509_NAME_new();
strcpy(bytes,"openssl");
len=strlen(bytes);
/* X509_NAME_add_entry_by_txt */
ret=X509_NAME_add_entry_by_txt(xn,"commonName",V_ASN1_UTF8STRING,bytes,len,0,-1);
if(ret!=1)
{
printf("X509_NAME_add_entry_by_txt err.\n");
}
/* X509_NAME_add_entry_by_NID */
strcpy(bytes,"china");
len=strlen(bytes);
ret=X509_NAME_add_entry_by_txt(xn,LN_countryName,V_ASN1_UTF8STRING,bytes,len,0,-1);
if(ret!=1)
{
printf("X509_NAME_add_entry_by_txt err.\n");
}
/* X509_NAME_add_entry_by_OBJ */
strcpy(bytes,"myou");
len=strlen(bytes);
obj=OBJ_nid2obj(NID_organizationalUnitName);
ret=X509_NAME_add_entry_by_OBJ(xn,obj,V_ASN1_UTF8STRING,bytes,len,0,-1);
if(ret!=1)
{
printf("X509_NAME_add_entry_by_OBJ err.\n");
}
/* X509_NAME_ENTRY_create_by_NID */
strcpy(bytes,"myo");
len=strlen(bytes);
c=X509_NAME_ENTRY_create_by_NID(&c,NID_organizationName,V_ASN1_UTF8STRING,bytes,len);
/* X509_NAME_add_entry */
ret=X509_NAME_add_entry(xn,c,1,-1);
if(ret!=1)
{
printf("X509_NAME_add_entry_by_OBJ err.\n");
}
/* X509_NAME_ENTRY_set_object */
obj=OBJ_nid2obj(NID_localityName);
c1=X509_NAME_ENTRY_new();
ret=X509_NAME_ENTRY_set_object(c1,obj);
if(ret!=1)
{
printf("X509_NAME_ENTRY_set_object err.\n");
}
strcpy(bytes,"mylocal");
len=strlen(bytes);
/* X509_NAME_ENTRY_set_data */
ret=X509_NAME_ENTRY_set_data(c1,V_ASN1_UTF8STRING,bytes,len);
if(ret!=1)
{
printf("X509_NAME_ENTRY_set_data err.\n");
}
ret=X509_NAME_add_entry(xn,c,2,-1);
if(ret!=1)
{
printf("X509_NAME_add_entry_by_OBJ err.\n");
}
c1=X509_NAME_delete_entry(xn,2);
/* X509_NAME_set */
BIO_free(b);
X509_free(x);
return 0;
}