openssl之ASN1系列_第1頁(yè)
openssl之ASN1系列_第2頁(yè)
openssl之ASN1系列_第3頁(yè)
openssl之ASN1系列_第4頁(yè)
openssl之ASN1系列_第5頁(yè)
已閱讀5頁(yè),還剩22頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、.openssl之ASN.1系列之1-引言和ASN.1概述作者:DragonKing(Eric Wang)Mail: wzhah發(fā)布于:OpenSSL版本:openssl-0.9.7版權(quán)聲明:未經(jīng)作者授權(quán),本文不能在任何商業(yè)性質(zhì)的出版物或網(wǎng)站上進(jìn)行轉(zhuǎn)載【引言】ASN.1 全稱(chēng)為Abstract Syntax Notation One,是一種描述數(shù)字對(duì)象的方法和標(biāo)準(zhǔn)。openssl的編碼方法就是基于該標(biāo)準(zhǔn)的,目前,很多其他軟件的編碼方法也是基于該標(biāo)準(zhǔn)。對(duì)于直接使用 openssl的API或者應(yīng)用程序來(lái)說(shuō),可能對(duì)ASN.1的了解并不需要很清楚,但是為了使大家對(duì)后續(xù)介紹的各個(gè)API有一個(gè)更深刻的編碼

2、知識(shí)基礎(chǔ),所以對(duì)該ASN.1以及openssl相應(yīng)提供的API處理函數(shù)作介紹?!続SN.1概述】ASN.1 作為一個(gè)數(shù)字對(duì)象描述標(biāo)準(zhǔn),包括了兩部分,分別為數(shù)據(jù)描述語(yǔ)言(ISO8824)和數(shù)據(jù)編碼規(guī)則(ISO8825)。ASN.1的數(shù)據(jù)描述語(yǔ)言標(biāo)準(zhǔn)允許用戶自定義基本數(shù)據(jù)類(lèi)型,并可以通過(guò)簡(jiǎn)單的數(shù)據(jù)類(lèi)型組成更復(fù)雜的數(shù)據(jù)類(lèi)型。比如一個(gè)復(fù)雜的數(shù)據(jù)對(duì)象,如X509證書(shū),就是在其它一些數(shù)據(jù)類(lèi)型上定義的,而其它數(shù)據(jù)類(lèi)型又是在更基本的數(shù)據(jù)類(lèi)型上建立的,直到回溯到定義的最基本的數(shù)據(jù)類(lèi)型。比如ASN.1定義的X509證書(shū)的一個(gè)子域Validity(證書(shū)有效期)就定義如下:Validity := SEQUENCE &

3、#160; notBefore            UTCTIME,  notAfter             UTCTIME其意義就是定義Validity為一個(gè)有序序列,由兩個(gè)個(gè)UTCTIME類(lèi)型的數(shù)據(jù)notBefore和notAfter組成。然后,就需要找出UTCTIME是怎么定義的,當(dāng)然,事實(shí)上UTCTIME是ASN.

4、1定義的一個(gè)基本的時(shí)間數(shù)據(jù)類(lèi)型。在上述數(shù)據(jù)定義的基礎(chǔ)上,ASN.1定義了一組編碼規(guī)則,以規(guī)定怎么將上述描述的對(duì)象轉(zhuǎn)換成應(yīng)用程序能夠處理和進(jìn)行傳輸?shù)亩M(jìn)制編碼形式。ASN.1定義了多種編碼方法,包括了BER, DER, PER, 和XER等,不過(guò),雖然最基本最常用的編碼方式是BER(Basic Encoding Rules),但是由于該編碼方法可能對(duì)一個(gè)相同的對(duì)象有幾種不同的合法二進(jìn)制編碼,所以在openssl里面使用的是BER的子集DER (Distinguished Encoding Rules),使用DER編碼方法,對(duì)于每一個(gè)ASN.1對(duì)象,其相應(yīng)的二進(jìn)制編碼是唯一的。ASN.1里定義的每

5、個(gè)基本對(duì)象都有一個(gè)對(duì)應(yīng)的數(shù)字標(biāo)識(shí)tag,在進(jìn)行二進(jìn)制編碼的時(shí)候需要使用該標(biāo)志?!続SN.1定義的基本數(shù)據(jù)類(lèi)型】下面列出ASN.1定義的部分基本數(shù)據(jù)類(lèi)型,其各字段的意義如下:數(shù)據(jù)類(lèi)型數(shù)據(jù)說(shuō)明Tag(16進(jìn)制)BOOLEAN有兩個(gè)值:false或true01INTEGER整型值02BIT STRING0位或多位03OCTET STRING0字節(jié)或多字節(jié)04NULLNULL值05OBJECT IDENTIFIER相應(yīng)于一個(gè)對(duì)象的獨(dú)特標(biāo)識(shí)數(shù)字06OBJECT DESCRIPTOR一個(gè)對(duì)象的簡(jiǎn)稱(chēng)07EXTERNALASN.1沒(méi)有定義的數(shù)據(jù)類(lèi)型08REAL實(shí)數(shù)值09ENUMERATED數(shù)值列表,這些數(shù)據(jù)每

6、個(gè)都有獨(dú)特的標(biāo)識(shí)符,作為ASN.1定義數(shù)據(jù)類(lèi)型的一部分0aSEQUENCE和SEQUENCE OF有序數(shù)列,SEQUENCE里面的每個(gè)數(shù)值都可以是不同類(lèi)型的,而SEQUENCE OF里是0個(gè)或多個(gè)類(lèi)型相同的數(shù)據(jù)10SET和SET OF無(wú)序數(shù)列,SET里面的每個(gè)數(shù)值都可以是不同類(lèi)型的,而SET OF里是0個(gè)或多個(gè)類(lèi)型相同的數(shù)據(jù)11NumericString09以及空格12PrintableStringA-Z、a-z、0-9、空格以及符號(hào) ()+,-./:=?13UTCTime統(tǒng)一全球時(shí)間格式17除了上述基本類(lèi)型,ASN.1還定義了另外一些專(zhuān)用的數(shù)據(jù)類(lèi)型,這里不再一一敘述。openssl之ASN.

7、1系列之2-ASN.1編碼方法簡(jiǎn)介作者:DragonKing(Eric Wang)Mail: wzhah版權(quán)聲明:未經(jīng)作者授權(quán),本文不能在任何商業(yè)性質(zhì)的出版物或網(wǎng)站上進(jìn)行轉(zhuǎn)載發(fā)布網(wǎng)站:OpenSSL版本:openssl-0.9.7參考資料:“Computer Network”,“A Layman s Guide to a Subset of ASN.1, BER, and DER”ASN.1對(duì)象的編碼是ASN.1標(biāo)準(zhǔn)的重要部分,目前,通常采用的是BER,而DER則是其一個(gè)子集。本文將對(duì)該編碼方法作簡(jiǎn)單的介紹。一個(gè)標(biāo)準(zhǔn)的ASN.1編碼對(duì)象有四個(gè)域:對(duì)象標(biāo)識(shí)域、數(shù)據(jù)長(zhǎng)度域、數(shù)據(jù)域以及結(jié)束標(biāo)志(可選

8、,在長(zhǎng)度不可知情況下需要,openssl中沒(méi)有該標(biāo)志)。【對(duì)象標(biāo)識(shí)域】對(duì)象標(biāo)識(shí)域有兩種形式,低Tag數(shù)字(Tag值在0到30)和高Tag數(shù)字(Tag值大于30)形式。低Tag 數(shù)字形式只有一個(gè)字節(jié),包含三部分,從低位為1開(kāi)始編號(hào),8和7位是Tag類(lèi)型,共有四種,分別是universal(0 0)、application(0 1)、context-specific(1 0)和private(1 1);第6位是0,表明編碼類(lèi)型是基本類(lèi)型,第5-1位是Tag值。 高Tag數(shù)字形式可以有兩個(gè)或多個(gè)字節(jié),第一個(gè)字節(jié)跟低Tag數(shù)字形式一樣,但低5位值全為1,而在后續(xù)的第二個(gè)和其后的字節(jié)中給出Tag值,這些

9、字節(jié)都只使用了低7位為數(shù)據(jù)位,最高位都設(shè)為0,但最后一個(gè)字節(jié)的最高位設(shè)為1,采用高位優(yōu)先,經(jīng)可能少的數(shù)字原則。【數(shù)據(jù)長(zhǎng)度域】數(shù)據(jù)長(zhǎng)度域也有兩種形式,短形式和長(zhǎng)形式。短形式的數(shù)據(jù)長(zhǎng)度域只有一個(gè)字節(jié),第8位為0,其它低7位給出數(shù)據(jù)長(zhǎng)度。長(zhǎng)形式的數(shù)據(jù)長(zhǎng)度域有2到127個(gè)字節(jié)。第一個(gè)字節(jié)的第8位為1,其它低7位給出后面該域使用的字節(jié)的數(shù)量,從該域第二個(gè)字節(jié)開(kāi)始給出數(shù)據(jù)的長(zhǎng)度,基于256,高位優(yōu)先。【數(shù)據(jù)域】數(shù)據(jù)域給出了具體的數(shù)據(jù)值。該域的編碼對(duì)不同的數(shù)據(jù)類(lèi)型不一樣,這里就不在一一詳述了,有興趣的可以參看參考資料?!疽粋€(gè)編碼例子】下面是SSLDocument給出的對(duì)一個(gè)對(duì)象進(jìn)行DER編碼的例子,更多的例

10、子可以參看本文給出的參考資料。例子使用的對(duì)象是ASN.1定義的BIT STRING類(lèi)型的對(duì)象,其編碼的步驟如下:1.對(duì)位串使用"0"進(jìn)行填補(bǔ),使其長(zhǎng)度為8的整數(shù)倍(如果已經(jīng)是整數(shù)倍,則不需要進(jìn)行填補(bǔ));2.計(jì)算填補(bǔ)的位數(shù)并寫(xiě)下來(lái),成為數(shù)據(jù)內(nèi)容的第一個(gè)字節(jié);3.寫(xiě)入填補(bǔ)后的位串,高位字節(jié)優(yōu)先。這些數(shù)據(jù)跟前面的一個(gè)字節(jié)組成數(shù)據(jù)內(nèi)容的全部字節(jié);4.在這些數(shù)據(jù)前面加上一個(gè)頭字節(jié),這個(gè)字節(jié)定義如下(編號(hào)是從低位為1開(kāi)始): 第8、7位:00(universal類(lèi)型) 第 6 位 :0(表明是基本類(lèi)型,有限長(zhǎng)度的編碼) 第51位:0x03(表明是BIT S

11、TRING)這個(gè)字節(jié)定義了對(duì)象標(biāo)識(shí)域;5.然后在對(duì)象標(biāo)識(shí)域字節(jié)和數(shù)據(jù)字節(jié)之間加入下面計(jì)算的定義的字節(jié): 計(jì)算有多少字節(jié)的數(shù)據(jù)內(nèi)容(對(duì)象標(biāo)識(shí)域數(shù)據(jù)除外),如果少于127字節(jié),那么就定義一個(gè)字節(jié)如下:  第8位:0  第71位:數(shù)據(jù)內(nèi)容的字節(jié)數(shù)量 如果數(shù)據(jù)內(nèi)容的字節(jié)數(shù)量大于127,就需要定義兩個(gè)或多個(gè)字節(jié),其中,第一個(gè)字節(jié)的定義如下:  第8位:1  第71位:該域后面還有多少字節(jié)  其后的字節(jié)是數(shù)據(jù)內(nèi)容的字節(jié)數(shù)量,每字節(jié)基于256,高位優(yōu)先下面是一個(gè)實(shí)際的數(shù)據(jù)例子:位串: 01

12、000100111011 1.補(bǔ)齊兩個(gè)0在后面,成為8的整數(shù)倍,得到 0100010011101100 ;2. 02 作為第一個(gè)數(shù)據(jù)內(nèi)容的字節(jié);3. 44 ec 作為其余的數(shù)據(jù)內(nèi)容的字節(jié);4. 03 作為前面的對(duì)象標(biāo)識(shí)字節(jié);5.因?yàn)锽IT STRING的tag值3<=127,所以只有一個(gè)字節(jié)的長(zhǎng)度域 03 ;那么得到的這個(gè)位串的DER編碼就是03 03 02 44 ec,其中,第一個(gè)字節(jié)是對(duì)象標(biāo)識(shí)域,第二個(gè)字節(jié)是數(shù)據(jù)長(zhǎng)度域,其他為數(shù)據(jù)域。openssl之ASN.1系列之3-ASN.1函數(shù)概述和結(jié)構(gòu)作者:DragonKing(Eric Wang)Mail: wzhah版權(quán)聲明:未經(jīng)作者授權(quán)

13、,本文不能在任何商業(yè)性質(zhì)的出版物或網(wǎng)站上進(jìn)行轉(zhuǎn)載發(fā)布網(wǎng)站:OpenSSL版本:openssl-0.9.7【ASN.1函數(shù)庫(kù)概述】因?yàn)閄509相關(guān)的協(xié)議都是基于ASN.1和DER編碼的,所以openssl提供了一組函數(shù),這些函數(shù)可以讀取DER編碼的對(duì)象,并將它們轉(zhuǎn)換成 openssl能夠處理的內(nèi)部格式;這些函數(shù)也可以將openssl里定義的C格式的對(duì)象結(jié)構(gòu)轉(zhuǎn)換成DER編碼的對(duì)象。此外,該系列還提供了一些對(duì)這些對(duì)象進(jìn)行比較、讀取和設(shè)定指定值的函數(shù)。該系列函數(shù)還包括了一些簽名函數(shù),這是因?yàn)樵诤灻?,有些?duì)象需要進(jìn)行DER編碼。下面對(duì)ASN.1函數(shù)庫(kù)中重要的數(shù)據(jù)結(jié)構(gòu)做簡(jiǎn)單的介紹?!続SN1_CTX】

14、該結(jié)構(gòu)用來(lái)在ASN1處理過(guò)程中維護(hù)跟蹤各種相關(guān)變量,其定義如下:typedef struct asn1_ctx_st unsigned char *p; int eos; int error; int inf;  int tag;  int xclass;  long slen;  unsigned char *max;  unsigned char *q;   unsigned char *pp; int line;

15、0; ASN1_CTX;· 參數(shù)p是工作字符指針,其最大長(zhǎng)度由參數(shù)max指定; · eos是indefinite編碼模式的結(jié)束標(biāo)識(shí)標(biāo)志; · error是錯(cuò)誤代碼; · inf值為 0x20代表constructd模式, 為0x21代表indefinite模式; · tag是最后取得的對(duì)象的tag值; · xclass是最后取得的對(duì)象的類(lèi)型; · slen是最后取得的對(duì)象的長(zhǎng)度; · line變量在出錯(cuò)處理的時(shí)候使用。【ASN1_OBJECT】該結(jié)構(gòu)用來(lái)保存一個(gè)ASN1對(duì)象,其定義如下:typedef struct

16、 asn1_object_st        char *sn,*ln;        int nid;        int length;        unsigned char *data;       

17、; int flags;ASN1_OBJECT;· nid是openssl內(nèi)部定義的每個(gè)數(shù)字對(duì)象的獨(dú)特標(biāo)識(shí)碼; · sn是對(duì)象的簡(jiǎn)稱(chēng); · ln是對(duì)象的長(zhǎng)名或小寫(xiě)名; · data是相應(yīng)對(duì)象的數(shù)據(jù), · length是該data字段的長(zhǎng)度, · flags是一個(gè)釋放標(biāo)志。【ASN1_STRING】該結(jié)構(gòu)是openssl里一個(gè)很基本的ASN.1對(duì)象結(jié)構(gòu),Openssl里定義的很多類(lèi)型的對(duì)象都是采用該結(jié)構(gòu)的,他們包括ASN1_INTEGER、 ASN1_BIT_STRING、ASN1_OCTET_STRING、ASN1_PRIN

18、TABLESTRING、ASN1_T61STRING、 ASN1_IA5STRING、ASN1_UTCTIME、ASN1_GENERALIZEDTIME、ASN1_GENERALSTRING、 ASN1_UNIVERSALSTRING和ASN1_BMPSTRING。該結(jié)構(gòu)的定義如下:typedef struct asn1_string_st       int length;       int type;       uns

19、igned char *data; long flags; ASN1_STRING;· type參數(shù)指明對(duì)象的類(lèi)型; · data參數(shù)是對(duì)象的數(shù)據(jù), · length指定了其長(zhǎng)度; · flags值跟type有關(guān),一般來(lái)說(shuō),在BIT_STRING對(duì)象中使用?!続SN1_TYPE】該結(jié)構(gòu)可以保存任意類(lèi)型的ASN.1對(duì)象,其定義如下:typedef struct asn1_type_st        int type;    &

20、#160;   union                    char *ptr;  ASN1_BOOLEAN  boolean;                ASN1_ST

21、RING *           asn1_string;                ASN1_OBJECT *           object;       &#

22、160;        ASN1_INTEGER *          integer;  ASN1_ENUMERATED * enumerated;                ASN1_BIT_STRING * &

23、#160;     bit_string;                ASN1_OCTET_STRING *     octet_string;                ASN1_PRINT

24、ABLESTRING *  printablestring;                ASN1_T61STRING *        t61string;               

25、 ASN1_IA5STRING *        ia5string;                ASN1_GENERALSTRING *    generalstring;           

26、     ASN1_BMPSTRING *        bmpstring;                ASN1_UNIVERSALSTRING *  universalstring;        &#

27、160;       ASN1_UTCTIME *          utctime;                ASN1_GENERALIZEDTIME *  generalizedtime;  ASN1_VISIBLEST

28、RING * visiblestring;  ASN1_UTF8STRING * utf8string;                ASN1_STRING *           set;         

29、       ASN1_STRING *           sequence;  value; ASN1_TYPE;其中,參數(shù)type指定了對(duì)象的類(lèi)型?!続SN1_METHOD】該結(jié)構(gòu)包含了指向一組函數(shù)的指針,這些函數(shù)定義了在openssl內(nèi)部結(jié)構(gòu)和DER編碼對(duì)象之間進(jìn)行格式轉(zhuǎn)換的功能,還定義了分配和釋放一個(gè)結(jié)構(gòu)的功能。其定義如下:typedef struct asn1_method_st  &

30、#160;     int (*i2d)();        char *(*d2i)();        char *(*create)();        void (*destroy)(); ASN1_METHOD;· i2d指向的函數(shù)將內(nèi)部格式轉(zhuǎn)換成DER編碼格式; · d2i指向

31、的函數(shù)將DER編碼的對(duì)象轉(zhuǎn)換成內(nèi)部結(jié)構(gòu); · create指向的函數(shù)給新對(duì)象分配內(nèi)存; · destroy指向的函數(shù)釋放對(duì)象的內(nèi)存。例如,在文件x_x509.c里,X509對(duì)象的METHOD結(jié)構(gòu)初始化如下:static ASN1_METHOD meth=        (int (*)()  i2d_X509,        (char *(*)()d2i_X509,  

32、60;     (char *(*)()X509_new,        (void (*)() X509_free;ASN1_METHOD *X509_asn1_meth()        return(&meth);【ASN1_HEADER】該結(jié)構(gòu)只在Netscape格式的證書(shū)里使用了(參考apps/x509.c文件),其定義如下:typedef struct asn1_he

33、ader_st        ASN1_OCTET_STRING *header;        char *data;        ASN1_METHOD *meth; ASN1_HEADER;除了上述介紹的基本結(jié)構(gòu)外,ASN.1相關(guān)的結(jié)構(gòu)還有幾個(gè),但這些因?yàn)椴皇翘貏e通用,在這里不再作介紹,有興趣可以看文件x509.h。openssl之ASN.1系列之4

34、-ASN.1對(duì)象的構(gòu)造和釋放作者:DragonKing(Eric Wang)Mail: wzhah版權(quán)聲明:未經(jīng)作者授權(quán),本文不能在任何商業(yè)性質(zhì)的出版物或網(wǎng)站上進(jìn)行轉(zhuǎn)載發(fā)布網(wǎng)站:OpenSSL版本:openssl-0.9.7因?yàn)槊糠NASN.1對(duì)象都有相應(yīng)的數(shù)據(jù)結(jié)構(gòu),所以openssl也提供了一系列創(chuàng)建和釋放這些對(duì)象的函數(shù)。事實(shí)上,基本的函數(shù)并不多,很多函數(shù)是在基本的函數(shù)上提供的宏定義,主要是為了方便用戶使用?;镜膶?duì)象構(gòu)造和釋放函數(shù)定義如下(cryptoasn1asn1.h):ASN1_OBJECT * ASN1_OBJECT_new(void );void  A

35、SN1_OBJECT_free(ASN1_OBJECT *a);ASN1_OBJECT * ASN1_OBJECT_create(int nid, unsigned char *data,int len,const char *sn, const char *ln);ASN1_STRING * ASN1_STRING_new(void);void  ASN1_STRING_free(ASN1_STRING *a);ASN1_STRING * ASN1_STRING_type_new(int type );ASN1_HEADER * A

36、SN1_HEADER_new(void );void   ASN1_HEADER_free(ASN1_HEADER *a);ASN1_VALUE * ASN1_item_new(const ASN1_ITEM *it);void   ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it);【ASN1_OBJECT】該系列的new和free函數(shù)分別完成了ASN1_OBJECT對(duì)象的創(chuàng)建和釋放。在創(chuàng)建ASN1_OBJECT對(duì)象的時(shí)候,該函數(shù)給對(duì)象分配內(nèi)存空間,并將結(jié)構(gòu)內(nèi)所有指針類(lèi)型的變量值都設(shè)為NU

37、LL,nid和長(zhǎng)度都初始化為0,并將flags設(shè)置為ASN1_OBJECT_FLAG_DYNAMIC,返回創(chuàng)建的對(duì)象的指針,如果失敗,返回NULL。對(duì)象釋放的時(shí)候,free函數(shù)將所有對(duì)象成員的內(nèi)存和自身的內(nèi)存釋放,并將lenght設(shè)置為0。除了使用ASN1_OBJECT_new創(chuàng)建ASN1_OBJECT對(duì)象,還可以使用ASN1_OBJECT_create函數(shù)創(chuàng)建對(duì)象,該函數(shù)根據(jù)給定的參數(shù)創(chuàng)建一個(gè)ASN1_OBJECT對(duì)象。其中,nid是對(duì)象的獨(dú)特標(biāo)識(shí)NID;data為對(duì)象的數(shù)據(jù),len指定了data有效數(shù)據(jù)的長(zhǎng)度;sn是對(duì)象的簡(jiǎn)稱(chēng);ln是對(duì)象的完整名字或小寫(xiě)名字;該函數(shù)將falgs標(biāo)志設(shè)為 A

38、SN1_OBJECT_FLAG_DYNAMIC|ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|ASN1_OBJECT_FLAG_DYNAMIC_DATA。 該函數(shù)返回一個(gè)對(duì)象結(jié)構(gòu)體,而不是指針?!続SN1_STRING】ASN1_STRING_type_new函數(shù)根據(jù)給定的參數(shù) type創(chuàng)建并返回一個(gè)ASN1_STRING對(duì)象指針。事實(shí)上,該函數(shù)不管type是什么,都是創(chuàng)建一個(gè)ASN1_STRING對(duì)象,然后將成員 data初始化為NULL,flags和length初始化為0。唯一有區(qū)別的就是令成員變量type的值為參數(shù)type的值,目前支持的type值如下:V_ASN1_

39、BIT_STRINGV_ASN1_INTEGERV_ASN1_ENUMERATEDV_ASN1_OCTET_STRINGV_ASN1_T61STRINGV_ASN1_PRINTABLESTRINGV_ASN1_VISIBLESTRINGV_ASN1_IA5STRINGV_ASN1_UTCTIMEV_ASN1_GENERALIZEDTIMEV_ASN1_GENERALSTRINGV_ASN1_UNIVERSALSTRINGV_ASN1_BMPSTRINGV_ASN1_UTF8STRINGASN1_STRING_new 函數(shù)是調(diào)用返回了ASN1_STRING_type_new函數(shù)實(shí)現(xiàn)的,其type

40、參數(shù)為V_ASN1_OCTET_STRING。上述兩個(gè)函數(shù)成功執(zhí)行 返回一個(gè)ASN1_STRING的指針,否則返回NULL。ASN1_STRING_free函數(shù)釋放了用上述兩個(gè)函數(shù)創(chuàng)建ASN1_STRING對(duì)象,沒(méi)有返回值?!続SN1_HEADER】這兩個(gè)函數(shù)用于處理Netscape格式的證書(shū)和私鑰對(duì)象。事實(shí)上,new函數(shù)創(chuàng)建了一個(gè) ASN1_HEADER對(duì)象,并調(diào)用了ASN1_STRING_type_new函數(shù),使用type參數(shù)為V_ASN1_OCTET_STRING對(duì)該對(duì)象的header成員變量進(jìn)行初始化,并將meth和data設(shè)置為NULL,返回ASN1_HEADER對(duì)象的指針。free

41、函數(shù)釋放該類(lèi)型對(duì)象,沒(méi)有返回值。【ASN1_VALUE】這兩個(gè)函數(shù)一般已經(jīng)不在使用,只是為了兼容以前的版本而保留了下來(lái)。這里不再作介紹?!净谏鲜龌竞瘮?shù)的宏定義函數(shù)】基于上述的基本函數(shù),尤其是ASN1_STRING_type_new函數(shù),openssl提供了很多為了方便用戶使用的宏定義,這些宏定義的形式是如下述形式:構(gòu)造函數(shù):M_對(duì)象名_new()釋放函數(shù):M_對(duì)象名_free(a)由于函數(shù)較多,具體可以參考asn1.h文件,這里不再一一列出了。openssl之ASN.1系列之5-編碼轉(zhuǎn)換函數(shù)i2d和d2i(一)作者:DragonKing(Eric Wang)Mail: wzhah版權(quán)聲明:

42、未經(jīng)作者授權(quán),本文不能在任何商業(yè)性質(zhì)的出版物或網(wǎng)站上進(jìn)行轉(zhuǎn)載發(fā)布網(wǎng)站:OpenSSL版本:openssl-0.9.7為了實(shí)現(xiàn)在Openssl內(nèi)部對(duì)象結(jié)構(gòu)和標(biāo)準(zhǔn)的DER編碼對(duì)象之間格式的轉(zhuǎn)換,OpenSSL定義了一組完成該功能的函數(shù),這些函數(shù)基本上是以i2d(內(nèi)部 ->DER)和d2i(DER->內(nèi)部)開(kāi)頭的。跟其他各個(gè)系列的函數(shù)一樣,OpenSSL雖然提供了針對(duì)各種對(duì)象類(lèi)型的函數(shù),但是其基本的函數(shù)不多,而其他都是在這個(gè)基礎(chǔ)上實(shí)現(xiàn)的宏定義。這些基本函數(shù)如下(cryptoasn1asn1.h):int  i2d_ASN1_OBJECT(ASN1_OBJECT *a,

43、unsigned char *pp);ASN1_OBJECT * d2i_ASN1_OBJECT(ASN1_OBJECT *a,unsigned char *pp,long length);int  i2d_ASN1_BOOLEAN(int a,unsigned char *pp);int   d2i_ASN1_BOOLEAN(int *a,unsigned char *pp,long length);int   i2d_ASN1_bytes(ASN1_STRING *a, unsigned char *pp, int ta

44、g, int xclass);ASN1_STRING * d2i_ASN1_bytes(ASN1_STRING *a, unsigned char *pp,long length, int Ptag, int Pclass);ASN1_STRING * d2i_ASN1_type_bytes(ASN1_STRING *a,unsigned char *pp,long length,int type);int  i2d_ASN1_SET(STACK *a, unsigned char *pp,int (*func)(), int ex_tag, int e

45、x_class, int is_set);STACK * d2i_ASN1_SET(STACK *a, unsigned char *pp, long length,char *(*func)(), void (*free_func)(void *),int ex_tag, int ex_class);【i2d系列函數(shù)總體介紹】i2d 系列函數(shù)將一個(gè)內(nèi)部的結(jié)構(gòu)(c語(yǔ)言結(jié)構(gòu)體)轉(zhuǎn)換成DER編碼的對(duì)象。參數(shù)a是一個(gè)指向一個(gè)結(jié)構(gòu)體的指針,參數(shù)pp是一個(gè)指向并創(chuàng)建的DER編碼字符串對(duì)象指針的指針。調(diào)用成功完成后,pp指針將被指向新生成的DER字符串的結(jié)束位置,并返回該字符串的長(zhǎng)度。所以參數(shù)p

46、p可以被相同的函數(shù)多次調(diào)用,以處理多個(gè)對(duì)象,并將這些對(duì)象存儲(chǔ)成一個(gè)長(zhǎng)DER編碼的字符串。如果參數(shù)pp為NULL,則僅僅返回有效數(shù)據(jù)的長(zhǎng)度。這種性質(zhì)可以在首次調(diào)用的時(shí)候用來(lái)決定要分配的字符串空間的長(zhǎng)度,例如下面的例子:len=i2d_my_favorite_type(a,NULL);if (string=(char *)malloc(len) = NULL) complain.i2d_my_favorite_type(a,&string);如果a為NULL,則返回0?!綿2i系列函數(shù)總體介紹】d2i 系列函數(shù)將一個(gè)DER編碼的對(duì)象轉(zhuǎn)換為一個(gè)內(nèi)部的結(jié)構(gòu)(c語(yǔ)言結(jié)構(gòu)體)。參數(shù)a是一個(gè)指向一個(gè)

47、結(jié)構(gòu)體指針的指針,用來(lái)存放轉(zhuǎn)換好的內(nèi)部結(jié)構(gòu)對(duì)象;參數(shù)pp 是一個(gè)指向DER編碼字符串對(duì)象指針的指針,參數(shù)length是*pp里面有效數(shù)據(jù)的長(zhǎng)度。如果a為NULL,則僅僅將內(nèi)部結(jié)構(gòu)對(duì)象作為返回值返回;如果 a不為NULL而*a為NULL,則將為*a分配內(nèi)存并存儲(chǔ)生成的內(nèi)部結(jié)構(gòu)對(duì)象。如果調(diào)用失敗,返回NULL。調(diào)用成功完成后,*pp將被重置到*pp+ length的位置,并返回生成的內(nèi)部結(jié)構(gòu)對(duì)象的地址。所以pp可以被d2i函數(shù)多次調(diào)用,以處理多個(gè)DER編碼的對(duì)象。出錯(cuò)返回NULL,如果*a不為 NULL,那么它指向的結(jié)構(gòu)會(huì)被釋放。一般來(lái)說(shuō),只有在內(nèi)存分配失敗或者DER編碼數(shù)據(jù)有誤的情況下才會(huì)出錯(cuò)。

48、【ASN1_OBJECT】i2d_ASN1_OBJECT 函數(shù)將一個(gè)內(nèi)部結(jié)構(gòu)ASN1_OBJECT的對(duì)象a轉(zhuǎn)換成DER編碼的對(duì)象;d2i_ASN1_OBJECT函數(shù)則是將參數(shù)pp里DER編碼的對(duì)象數(shù)據(jù)轉(zhuǎn)換成一個(gè)ASN1_OBJECT結(jié)構(gòu)的對(duì)象。其參數(shù)a,pp和length跟上面介紹的是一樣意義的?!続SN1_BOOLEAN】i2d_ASN1_BOOLEAN 函數(shù)將一個(gè)內(nèi)部結(jié)構(gòu)ASN1_BOOLEAN的對(duì)象a轉(zhuǎn)換成DER編碼的對(duì)象;d2i_ASN1_BOOLEAN函數(shù)則是將參數(shù)pp里DER編碼的對(duì)象數(shù)據(jù)轉(zhuǎn)換成一個(gè)ASN1_BOOLEAN結(jié)構(gòu)的對(duì)象。其參數(shù)a,pp和length跟上面介紹的是一樣意

49、義的。openssl之ASN.1系列之6-編碼轉(zhuǎn)換函數(shù)i2d和d2i(二)作者:DragonKing(Eric Wang)Mail: wzhah版權(quán)聲明:未經(jīng)作者授權(quán),本文不能在任何商業(yè)性質(zhì)的出版物或網(wǎng)站上進(jìn)行轉(zhuǎn)載發(fā)布網(wǎng)站:OpenSSL版本:openssl-0.9.7【ASN1_bytes】int   i2d_ASN1_bytes(ASN1_STRING *a, unsigned char *pp, int tag, int xclass);ASN1_STRING * d2i_ASN1_bytes(ASN1_STRING *a, unsigned char *p

50、p,long length, int Ptag, int Pclass);這兩個(gè)函數(shù)其實(shí)是相對(duì)來(lái)說(shuō)比較底層的函數(shù),一般不直接使用他們,而是使用基于他們的宏定義函數(shù)。可以看到,跟其他i2d和d2i函數(shù)一樣,這兩個(gè)函數(shù)也有參數(shù)a和pp,其含義跟前面介紹是相同的。i2d_ASN1_bytes函數(shù)中的參數(shù)tag是定義的對(duì)象的tag值,可能的值包括在下面:#define V_ASN1_UNDEF   -1#define V_ASN1_EOC   0#define V_ASN1_BOOLEAN   1 #d

51、efine V_ASN1_INTEGER   2#define V_ASN1_NEG_INTEGER  (2 | V_ASN1_NEG)#define V_ASN1_BIT_STRING  3#define V_ASN1_OCTET_STRING  4#define V_ASN1_NULL   5#define V_ASN1_OBJECT   6#define V_ASN1_OBJECT_DESCRIPTOR 7#define V_AS

52、N1_EXTERNAL   8#define V_ASN1_REAL   9#define V_ASN1_ENUMERATED  10#define V_ASN1_NEG_ENUMERATED  (10 | V_ASN1_NEG)#define V_ASN1_UTF8STRING  12#define V_ASN1_SEQUENCE   16#define V_ASN1_SET   17#define V_ASN1_

53、NUMERICSTRING  18 #define V_ASN1_PRINTABLESTRING  19#define V_ASN1_T61STRING  20#define V_ASN1_TELETEXSTRING  20 #define V_ASN1_VIDEOTEXSTRING  21 #define V_ASN1_IA5STRING  22#define V_ASN1_UTCTIME   23#define

54、V_ASN1_GENERALIZEDTIME  24 #define V_ASN1_GRAPHICSTRING  25 #define V_ASN1_ISO64STRING  26 #define V_ASN1_VISIBLESTRING  26 #define V_ASN1_GENERALSTRING  27 #define V_ASN1_UNIVERSALSTRING  28 #define V_ASN1_BMP

55、STRING  30參數(shù)xclass可能的值如下:#define V_ASN1_UNIVERSAL  0x00#define V_ASN1_APPLICATION  0x40#define V_ASN1_CONTEXT_SPECIFIC  0x80#define V_ASN1_PRIVATE   0xc0這兩個(gè)參數(shù)的信息用來(lái)填寫(xiě)DER編碼的標(biāo)識(shí)字節(jié),沒(méi)有這些信息,函數(shù)就會(huì)只是對(duì)ASN1_STRING對(duì)象進(jìn)行沒(méi)有意義或錯(cuò)誤的編碼。比如你如果不給ASN1_INTEGER類(lèi)型對(duì)象一個(gè)tag值

56、,那么返回的編碼就是一堆沒(méi)有意義的垃圾代碼。d2i_ASN1_bytes 函數(shù)比其他d2i函數(shù)也多兩個(gè)參數(shù),Ptag和Pxclass,是兩個(gè)指針,分別是用來(lái)存放從標(biāo)識(shí)字節(jié)讀出的上述tag和class值。沒(méi)有這兩個(gè)值,函數(shù)就只是將DER對(duì)象作為ASN1_STRING對(duì)象進(jìn)行處理,確定不了類(lèi)型。該函數(shù)返回一個(gè)ASN1_STRING對(duì)象?!続SN1_type_bytes】ASN1_STRING * d2i_ASN1_type_bytes(ASN1_STRING *a,unsigned char *pp,long length,int type);本函數(shù)也是一個(gè)底層的函數(shù)。相比于其他d2i函

57、數(shù),本函數(shù)多了一個(gè)參數(shù)type,該參數(shù)有效的值如下:#define B_ASN1_NUMERICSTRING 0x0001#define B_ASN1_PRINTABLESTRING 0x0002#define B_ASN1_T61STRING 0x0004#define B_ASN1_TELETEXSTRING 0x0008#define B_ASN1_VIDEOTEXSTRING 0x0008#define B_ASN1_IA5STRING 0x0010#define B_ASN1_GRAPHICSTRING 0x002

58、0#define B_ASN1_ISO64STRING 0x0040#define B_ASN1_VISIBLESTRING 0x0040#define B_ASN1_GENERALSTRING 0x0080#define B_ASN1_UNIVERSALSTRING 0x0100#define B_ASN1_OCTET_STRING 0x0200#define B_ASN1_BIT_STRING 0x0400#define B_ASN1_BMPSTRING 0x0800#define B_ASN1_UNKNOWN 

59、; 0x1000#define B_ASN1_UTF8STRING 0x2000#define B_ASN1_UTCTIME  0x4000#define B_ASN1_GENERALIZEDTIME 0x8000該函數(shù)完成的功能跟d2i_ASN1_bytes函數(shù)是一樣的,不過(guò),如果從DER對(duì)象解碼得到的對(duì)象類(lèi)型跟type參數(shù)給定的類(lèi)型不一致,那么,就會(huì)出錯(cuò)返回NULL。如果沒(méi)有這個(gè)參數(shù),就不能確定得到對(duì)象的類(lèi)型,只是返回一個(gè)ASN1_STRING的指針。openssl之ASN.1系列之7-編碼轉(zhuǎn)換函數(shù)i2d和d2i(三)作者:DragonKi

60、ng(Eric Wang)Mail: wzhah版權(quán)聲明:未經(jīng)作者授權(quán),本文不能在任何商業(yè)性質(zhì)的出版物或網(wǎng)站上進(jìn)行轉(zhuǎn)載發(fā)布網(wǎng)站:OpenSSL版本:openssl-0.9.7【ASN1_SET】int  i2d_ASN1_SET(STACK *a, unsigned char *pp,int (*func)(), int ex_tag, int ex_class, int is_set);STACK * d2i_ASN1_SET(STACK *a, unsigned char *pp, long length,char *(*func)(), void (*fre

61、e_func)(void *),int ex_tag, int ex_class);這兩個(gè)函數(shù)對(duì)ASN1_SET和ASN1_SEQUENCE類(lèi)型的對(duì)象進(jìn)行內(nèi)部對(duì)象和DER編碼之間的轉(zhuǎn)換。1.i2d_ASN1_SET函數(shù)參數(shù)a和pp是跟前面介紹的意義是一樣的。參數(shù)ex_tag的值可能如如下:V_ASN1_SETV_ASN1_SEQUENCE參數(shù)ex_class的值可能如下:V_ASN1_UNIVERSALV_ASN1_CONTEXT_SPECIFIC參數(shù)func指向一個(gè)i2d_*形式的函數(shù)指針,它用來(lái)對(duì)參數(shù)a的STACK中的每一個(gè)元素進(jìn)行內(nèi)部結(jié)構(gòu)向DER編碼轉(zhuǎn)換的操作。這個(gè)STACK包括了將要組

62、成整個(gè)SET或SEQUENCE的ASN1結(jié)構(gòu)的有序集合。例如,如果STACK中包含了一些列X509_ATTRIBUTE對(duì)象,那么你可以調(diào)用下面的函數(shù)得到DER編碼的SET對(duì)象:i2d_ASN1_SET(sk,&p,i2d_X509_ATTRIBUTE,V_ASN1_SET,V_ASN1_UNIVERSAL)2.d2i_ASN1_SET函數(shù)改函數(shù)跟其它d2i函數(shù)完成的功能是一樣的,其參數(shù)a、pp、ex_tag和ex_class跟上面的函數(shù)里同名參數(shù)的意義是一樣的。參數(shù)func是 d2i_*形式的函數(shù),用來(lái)對(duì)DER編碼的SET或SEQUENCE對(duì)象中的每個(gè)對(duì)象進(jìn)行DER解碼并創(chuàng)建相應(yīng)的AS

63、N1結(jié)構(gòu),然后將創(chuàng)建的對(duì)象結(jié)構(gòu)存放在STACK參數(shù)a中,返回該對(duì)象的指針。如果出錯(cuò),該函數(shù)返回NULL?!続SN1_STRING相關(guān)的宏定義函數(shù)】前面我們介紹過(guò),OpenSSL里面許多ASN1對(duì)象類(lèi)型的底層其實(shí)是ASN1_STRING類(lèi)型的宏定義,所以O(shè)penSSL提供了一系列宏定義函數(shù)對(duì)這些類(lèi)型相應(yīng)的tag和class進(jìn)行正確的DER編解碼處理,這些函數(shù)的形式一般為:M_i2d_*M_d2i_*他們的參數(shù)也跟前面介紹過(guò)的同名參數(shù)意義一樣。為了方便查找,把這些宏定義函數(shù)列出如下:#define M_i2d_ASN1_OCTET_STRING(a,pp) i2d_ASN1_bytes(ASN1_

64、STRING *)a,pp,V_ASN1_OCTET_STRING,V_ASN1_UNIVERSAL)#define M_i2d_ASN1_PRINTABLE(a,pp) i2d_ASN1_bytes(ASN1_STRING *)a,pp,a->type,V_ASN1_UNIVERSAL)#define M_d2i_ASN1_PRINTABLE(a,pp,l) d2i_ASN1_type_bytes(ASN1_STRING *)a,pp,l, B_ASN1_PRINTABLE)#define M_i2d_DIRECTORYSTRING(a,pp) i2d_ASN1_bytes(ASN1_

65、STRING *)a,pp,a->type,V_ASN1_UNIVERSAL)#define M_d2i_DIRECTORYSTRING(a,pp,l) d2i_ASN1_type_bytes(ASN1_STRING *)a,pp,l, B_ASN1_DIRECTORYSTRING)#define M_i2d_DISPLAYTEXT(a,pp) i2d_ASN1_bytes(ASN1_STRING *)a,pp,a->type,V_ASN1_UNIVERSAL)#define M_d2i_DISPLAYTEXT(a,pp,l) d2i_ASN1_type_bytes(ASN1_ST

66、RING *)a,pp,l,B_ASN1_DISPLAYTEXT)#define M_i2d_ASN1_PRINTABLESTRING(a,pp) i2d_ASN1_bytes(ASN1_STRING *)a,pp,V_ASN1_PRINTABLESTRING,V_ASN1_UNIVERSAL)#define M_d2i_ASN1_PRINTABLESTRING(a,pp,l) (ASN1_PRINTABLESTRING *)d2i_ASN1_type_bytes(ASN1_STRING *)a,pp,l,B_ASN1_PRINTABLESTRING)#define M_i2d_ASN1_T6

67、1STRING(a,pp) i2d_ASN1_bytes(ASN1_STRING *)a,pp,V_ASN1_T61STRING,V_ASN1_UNIVERSAL)#define M_d2i_ASN1_T61STRING(a,pp,l) (ASN1_T61STRING *)d2i_ASN1_type_bytes(ASN1_STRING *)a,pp,l,B_ASN1_T61STRING)#define M_i2d_ASN1_IA5STRING(a,pp) i2d_ASN1_bytes(ASN1_STRING *)a,pp,V_ASN1_IA5STRING,V_ASN1_UNIVERSAL)#d

68、efine M_d2i_ASN1_IA5STRING(a,pp,l) (ASN1_IA5STRING *)d2i_ASN1_type_bytes(ASN1_STRING *)a,pp,l,B_ASN1_IA5STRING)#define M_i2d_ASN1_GENERALSTRING(a,pp) i2d_ASN1_bytes(ASN1_STRING *)a,pp,V_ASN1_GENERALSTRING,V_ASN1_UNIVERSAL)#define M_d2i_ASN1_GENERALSTRING(a,pp,l) (ASN1_GENERALSTRING *)d2i_ASN1_type_bytes(ASN1_STRING *)a,pp,l,B_ASN1_GENERALSTRI

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論