24.openssl編程——通用數據結構


24.1 通用數據結構
本文中數據結構主要指的是證書相關各個數據結構。他們主要用在數字證書申請、數字證書和CRL中。
*X509_ALGOR
X509算法
*X509_VAL
X509有效時間
*X509_PUBKEY
X509公鑰
*X509_SIG
X509摘要或者簽名值
*X509_NAME_ENTRY
X509中的一項名臣
*X509_NAME
X509名稱集合
*X509_EXTENSION
X509擴展項
*X509_ATTRIBUTE
X509屬性
*GENRAL_NAME
通用名稱
通過openssl提供的ASN1庫,這些數據結構都是可以進行DER編解碼的。用戶主要需要了解他們各項意義、對他們的編解碼以及他們的set和get操作。
24.2 X509_ALOGOR
該數據結構用來表示算法,他定義在crypto/x509/x509.h
struct X509_algor_st
{
ASN1_OBJECT *algorithm;
ASN1_TYPE *parameter;
}
包含兩項:
algorithm:ASN1_OBJECT類型,表明了是何種算法
parameter:ASN1_TYPE類型,代表該算法需要的參數。
該結構的DER編解碼接口crypto/asn1/x_algor.c中由ASN1宏來實現,其中parameter是可選的。該結構相關的函數為new(生成數據結構)\free(釋放數據結構)\i2d(將他轉換為DER編碼)\d2i(由DER編碼轉換為該結構)和dup(拷貝)
24.3 X509_VAL
該數據結構用來表示有效時間,定義在crypto/x509/x509.h
typedef struct X509_val_st
{
ASN1_TIME *notBefore;
ASN1_TIME *notAfter;
} X509_VAL;
包含兩項
notBefore:生效日期
notAfter:失效日期
24.4 X509_SIG
該結構用來存放摘要或者簽名值,定義crypto/x509/x509.h
typedef struct X509_sig_st
{
X509_ALGOR *algor;
ASN1_OCTET_STRING *digest;
} X509_SIG;
其中algor為算法,digest用於存放摘要或者簽名值。對數據進行簽名時,要先對數據摘要,摘要的結果要通過本結構進行DER編碼,然后才能用私鑰進行計算,此時digest中存放的就是摘要值。
24.5 X509_NAME_ENTRY
typedef struct X509_name_entry_st
{
ASN1_OBJECT *object;
ASN1_STRING *value;
int set;
int size;
} X509_NAME_ENTRY;
每個X509_NAME_ENTRY對應於一個證書中C\OU和O等實體名稱,其中object表明了實體的類型是C還是OU等;value表明了改實體的內容,這兩項用於DER編解碼。該結構的DER編解碼在crtypto/asn1/x_name.c中實現,包括new\free\i2d\d2i和dup函數。
24.6 X509_NAME
該結構是一個名稱集合,在crypto/x509/x509.h
struct X509_name_st
{
STACK_OF(X509_NAME_ENTRTY) *entries;
int modified;
#ifndef OPENSSL_NO_BUFFER
BUF_MEM *bytes;
#else
char *bytes;
#endif
unsinged long hash;
}
a. int X509_NAME_add_entry(X509_NAME *name, X509_ENTRY *ne, int loc, int set)
將一個X509_NAME_ENTRY放入X509_NAME的堆棧中,在堆棧中的位置由loc制定。
b.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_OBEJCT(OBJ_nid2obj函數)
c.X509_NAME_add_entry_by_OBJ
與b類似,知識要添加的項由ASN1_OBJECT來表示
d.X509_NAME_add_entry_by_txt
與b類似,只是要添加的項由字符串來表示,根據txt能獲取ASN1_OBJECT
e.X509_NAME_ENTRY X509_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類型
f.X509_NAME_ENTRY_create_by_OBJ
生成項由ASN1_OBJECT來表示
g.X509_NAME_ENTRY_create_by_txt
生成的項有字符串表示
h.int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, cahr *buf, int len)
根據NID來獲取值,結果存放在buf中
i.X509_NAME_get_text_by_OBJ
根據ASN1_OBJECT來獲取值
j.int X509_NAME_get_index_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int lastpos)
根據ASN1_OBJECT獲取NAME_ENTRY在堆棧中的位置
k.X509_NAME_get_index_by_NID
根據NID獲取X509_NAME_ENTRY在堆棧中的位置
l.X509_NAME_cmp
名字比較
m.X509_NAME_delete_entry
從堆棧中刪除一個指定位置的X509_NAME_ENTRY,並將他返回。
n.X509_NAME_digest
根據指定的算法,對X509_NAME坐摘要計算
o.X509_NAME_dup
名字拷貝
p.X509_NAME_entry_count
獲取X509_NAME的X509_NAME_ENTRY堆棧中元素個數
q.X509_NAME_ENTRY_dup
X509_NAME_ENTRY拷貝
r.X509_NAME_ENTRY_get/set_data
獲取/設置一項名稱的值;set函數還需要指明值的ASN1類型。
s.X509_NAME_ENTRY_get_entry
根據制定堆棧位置獲取一個X509_NAME_ENTRY;
t.X509_NAME_hash
摘要計算,該結果是對MD5的結果處理后的值
將a表示的名字變成:/OU=z/CN=形式放在buf中,返回buf首地址。
u.X509_NAME_print/X509_NAME_print_ex
打印X509_NAME到bio中
v.X509_NAME_print_ex_fp
打印X509_NAME到FILE中
w.int X509_NAME_set(X509_NAME**xn, X509_NAME *name)
通過dup函數,設置*xn的為name.
24.7 X509_ENTENSION
本結構用於存放各種擴展項信息
a.結構定義
數據證書擴展項,定義在crypto/x509/x509.h中
typedef struct X509_extension_st
{
ASN1_OBJECT *object;
ASN1_BOOLEAN cirtical; 關鍵擴展項
ASN1_OCTET_STRING value; DER編碼的具體擴展項的值
}
b. 通過X509V3_EXT_METHOD進行DER編解碼
openssl通過X509V3_EXT_METHOD來實現對擴展項的編解碼。
struct v3_ext_method
{
int ext_nid;
int ext_flags;
ASN1_ITEM_EXP *it;
X509V3_EXT_NEW ext_new;
X509V3_EXT_FREE ext_free;
X509V3_EXT_D2I d2i;
X509V3_EXT_I2D i2d;
X509V3_EXT_I2S i2s;
X509V3_EXT_S2I s2i;
X509V3_EXT_I2V i2v;
X509V3_EXT_V2I v2i;
X509V3_EXT_I2R i2r;
X509V3_EXT_R2I r2i;
void *usr_data;
}
該結構以ext_nid表示是何種擴展項,以it\d2i和i2d函數來指明來他的DER編解碼函數。
文件架構
功能
v3_akey.c
權威密鑰標識,實現了AUTHORITY_KEYID的DER編解碼和
X509V3_EXT_METHOD;
v3_alt.c
頒發者別名,實現了GENERAL_NAMES的509V3_EXT_METHOD.
v3_bcons.c
基本約束,實現了BASIC_CONSTRAINTS的DER編解碼和509V3_EXT_METHOD;
v3_cpols.c
證書策略,實現了CERTIFICATEROLICIES的DER編解碼和509V3_EXT_METHOD
v3_crld.c
CRL發布點,實現了CRL_DIST_POINTS的DER編解碼和509V3_EXT_METHOD;
v3_enum.c
證書撤銷原因,實現了其509V3_EXT_METHOD
v3_extku.c
擴展密鑰用法,實現了EXTENDED_KEY_USAGE的DER編解碼
擴展密鑰和ocsp_accresp的509V3_EXT_METHOD
v3_info.c
權威信息獲取,實現了AUTHORITY_INFO_ACCESS的DER編解碼
v3_sinfo兩個509V3_EXT_METHOD
v3_ncons.c
名字約束,實現了NAME_CONSTRAINTS的編解碼和他的509V3_EXT_METHOD
v3_ocsp.c
實現了OCSP相關的多個擴展項的509V3_EXT_METHOD
v3_pci.c
實現了OCSP相關的多個擴展項的509V3_EXT_METHOD
v3_pcons.c
策略約束,實現了POLICY_CONSTRAINTS的DER編解碼和509V3_EXT_METHOD
v3_pku.c
密鑰有效期,是心啊了PEKY_USAGE_PERIOD的DER編解碼
它的509V3_EXT_METHOD
v3_pmaps.c
策略映射,實現了POLICY_MAPPINGS的DER編解碼和他的509V3_EXT_METHOD
v3_skey.c
主題密鑰標識,實現了改擴展項的509V3_EXT_METHOD
v3_sxnet.c
實現了SXNET的DER編解碼和他的509V3_EXT_METHOD
從X509_EXTENSION中提取具體擴展項的數據結構可以采用如下函數
void *X509V3_EXT_d2i(X509_EXTENSION *ext)
該函數首先根據X509_EXTENSION來獲取是那種擴展項,並查找X509V3_EXT_METHOD表,然后根據對應的d2i函數解碼X509_extension->value中的DER編碼數據,生成具體的擴展項數據結構並返回。
上述兩個函數是具體擴展項和X509_EXTENSION相互轉化最基本的函數,很多函數都基於他們。
函數
功能
X509_EXT_add
在擴展X509V3_EXT_METHOD表ext_list中添加一個方法
X509V3_EXT_get_nid
根據nid來查找X509V3_EXT_METHOD
X509V3_EXT_get
根據擴展項來查找X509V3_EXTG_METHOD,
他調用了X509V3_EXT_METHOD有不同的擴展項X509V3_EXT_get_nid
X509V3_EXT_add_alias
添加一個X509V3_EXT_METHOD,
使具有相同方法的X509V3_EXT_METHOD有不同的擴展項nid
X509V3_EXT_print
打印單個擴展項
X509V3_add1_i2d
往擴展堆棧中添加一個具體的擴展項value,
該具體的擴展項是其數據結構地址,添加擴展項時,
輸入參數flags可以處理擴展項沖突。flags可以的值定義在x509ve:h中
#define X509V3_ADD_DEFAULT 0L
#define X509V3_ADD_APPEND 1L
#define X509V3_ADD_REPLACE 2L
#define X509V3_ADD_REPLACE_EXISTING 3L
#define X509V3_KEEP_EXISTING 4L
#define X509V3_ADD_DELETE 5L
#define X509V3_ADD_SILENT 0X10
24.8  X509_ATTRIBUTE
typedef struct x509_attributes_st
{
ASN1_OBJECT *object;
STACK_OF(ASN1_TYPE) *set;
}
主要函數:
a.int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr)
獲取屬性中ASN1_TYPE的個數
b.X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value)
生成一個屬性。id用來生成ASN1_OBJECT,指明是哪種屬性,atrtype為ASN1類型,value為值,用來設置set堆棧
c.X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **atr, const ASN1_OBJECT *obj, int atrytpe, const void *data, int len)
生成一個屬性,obj指明了屬性類型,atrtype為ASN1類型,data和len指明了需要設置的值。
d.X509_ATTRIBUTE_create_by_NID
同上,屬性類型有nid指定
e.X509_ATTRIBUTE_create_by_txt
屬性類型有ASN1_OBJECT的名字指定
f.X509_ATTRIBUTE_dup
拷貝函數
g. ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx)
獲取屬性中由堆棧位置idx指定的ASN1_TYPE, 如果屬性不是set集合則返回value,single.
h.void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx)
由idx_he ASN1類型atrtype來獲取value.ptr.
i.X509_ATTRIBUTE_get0_object
獲取屬性類型信息
j.X509_ATTRIBUTE_set1_data
設置屬性信息
k.X509_ATTRIBUTE_set1_object
設置屬性類型
l.STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTTRIBUTE) **x, X509_ATTRIBUTE *attr)
堆棧中添加一個屬性,返回屬性最站;如果*x為NULL, 則聲稱一個新的堆棧
m. X509at_add1_attr_by_OBJ
屬性類型由ASN1_OBJECT指定。
n.X509at_add1_attr_by_txt
屬性類型由屬性名指定。
24.9 GENERAL_NAME
本結構用來表示通用名稱x509v3.h中
typedef struct GENERAL_NAME_st {
#define GEN_OTHERNAME 0
#define GEN_EMAIL 1
#define GEN_DNS 2
#define GEN_X400 3
#define GEN_DIRNAME 4
#define GEN_EDIPRART 5
#define GEN_URI 6
#define GEN_IPADD 7
#define GEN_RID 8
int type;
union {
char *ptr;
OTHERNAME *otherName;
ASN1_IA5STRING *rfc822Name;
ASN1_IA5STRING *dNSName;
ASN1_TYPE *x400Address;
X509_NAME *directoryName;
EDIPARTYNAME *ediPartyName;
ASN1_IA5STRING *uniformResourceIdentifier;
ASN1_OCTET_STRING *iPAddress;
ASN1_OBJECT *registeredID;
ASN1_OCTET_STRING *ip;
X509_NAME *dirn;
ASN1_IA5STRING *ia5;
ASN1_OBJECT *rid;
ASN1_TYPE *other;
} d;
} GENERAL_NAME;
GENERAL_NAME可以包含各種各樣的名稱。type用來表示該結構采用了0~8分別對應otherName\rfc822Name、dNSName、x4000Address、directoryName\ediPartyName、uniformResourceIdentifier\iPAddress和registeredID.ptr用來存放通用的各種名稱的地址。當type為某一個類型時,數據存放在d中對應的想。比如,當type為GEN_DIRNAME,數據存放在directoryName中。openssl中最常用的是X509_NAME.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM