2011-04-07 88 views
3

我正嘗試在C(OpenSSL)中創建一個代理證書(ProxyCertInfo擴展RFC3820)的X509請求,但我無法弄清楚應該如何定義ProxyCertInfo的數據結構。該RFC定義了語言ASN.1如下:X.509v3 ASN.1到C數據結構

PKIXproxy88 { iso(1) identified-organization(3) dod(6) 
    internet(1) security(5) mechanisms(5) pkix(7) id-mod(0) 
    proxy-cert-extns(25) } 

DEFINITIONS EXPLICIT TAGS ::= 

BEGIN 

-- EXPORTS ALL -- 

-- IMPORTS NONE -- 

-- PKIX specific OIDs 

id-pkix OBJECT IDENTIFIER ::= 
     { iso(1) identified-organization(3) 
      dod(6) internet(1) security(5) mechanisms(5) pkix(7) } 

-- private certificate extensions 
id-pe OBJECT IDENTIFIER ::= { id-pkix 1 } 

-- Locally defined OIDs 

-- The proxy certificate extension 
id-pe-proxyCertInfo OBJECT IDENTIFIER ::= { id-pe 14 } 

-- Proxy certificate policy languages 
id-ppl OBJECT IDENTIFIER ::= { id-pkix 21 } 

-- Proxy certificate policies languages defined in 
id-ppl-anyLanguage  OBJECT IDENTIFIER ::= { id-ppl 0 } 
id-ppl-inheritAll  OBJECT IDENTIFIER ::= { id-ppl 1 } 
id-ppl-independent  OBJECT IDENTIFIER ::= { id-ppl 2 } 

-- The ProxyCertInfo Extension 
ProxyCertInfoExtension ::= SEQUENCE { 
    pCPathLenConstraint  ProxyCertPathLengthConstraint OPTIONAL, 
    proxyPolicy    ProxyPolicy 
} 

ProxyCertPathLengthConstraint ::= INTEGER 
ProxyPolicy ::= SEQUENCE { 
    policyLanguage   OBJECT IDENTIFIER, 
    policy     OCTET STRING OPTIONAL 
} 

END 

我看過的OpenSSL的非常有限的文件,不能找出如何解析這個到C的數據結構。我還讀了http://www.openssl.org/docs/apps/asn1parse.html#,因爲它解釋瞭如何使用命令行工具的解析器,但不知道如何將它包含在自己的源代碼中。

我已經設法將其他擴展包含到X509請求中,所以我相對確定我唯一的問題是這個特定擴展的數據結構的格式。

回答

5

我認爲你的問題是「我如何將數據格式化爲ProxyCertInfoExtension?」如果這在不正確的,請讓我知道。

如果你想知道一些理論,我發現的最佳參考是A Layman's Guide to a Subset of ASN.1, BER, and DER

您問題中的代碼部分描述了ProxyCertInfoExtension的數據是如何編碼的。將編碼描述看作可以由解析器生成器處理的語法,就像yacc將語法作爲輸入並輸出C代碼一樣。實際上,至少存在一個ASN.1解析器生成器ASN1C

ASN.1編碼可能具有不同的大小。數據從outtermost或頂級ASN.1編碼開始。每個ASN.1編碼本身可能包含一個或多個ASN.1編碼。這樣ASN.1是遞歸的。

ASN.1編碼由頭部,長度,可選內容和可選結尾組成。

ASN.1 encoding { Header length [content] [end] } 

頭部由類型,原始/構造位和標記號組成。如果標籤號大​​於63,則標籤號將跨越多個字節。這意味着根據標籤號的值,標題可以是一個字節長或多個字節長。標題是字節對齊的,意思是總是有一些字節長。

ASN.1 header { ClassType Primitive/Constructed Tag-number } 

根據長度值的不同,長度也可能是一個字節到很多字節。長度也是字節對齊的。

類的類型和標記號告訴你在內容中編碼的內容。

outtermost編碼通常是一個序列或集合,它們是複合基本類型。在您的編碼中,outtermost編碼是ProxyCertInfoExtension,它是可選的ProxyCertPathLengthConstraint和ProxyPolicy的序列。您的編碼看起來是這樣的:

ProxyCertInfoExtension { [ProxyCertPathLengthConstraint] ProxyPolicy } 

回首編碼規則,ProxyCertPathLengthConstraint僅僅是一個整數,所以你的編碼是真的:

ProxyCertInfoExtension { [Integer] ProxyPolicy } 

的編碼規則定義ProxyPolicy作爲一個序列policyLanguage和一個可選策略。因此,我們可以更新編碼表示看起來像這樣:

ProxyCertInfoExtension { [Integer] { policyLanguage [policy] } } 

的編碼規則規定政策字節串(只是一些字節數)。所以firther簡化生產:

ProxyCertInfoExtension { [Integer] { policyLanguage [Octet String] } } 

根據對象標識符,編碼是以下之一:

ProxyCertInfoExtension { [Integer] { id-ppl-anyLanguage [Octet String] } } 
ProxyCertInfoExtension { [Integer] { id-ppl-inheritAll [Octet String] } } 
ProxyCertInfoExtension { [Integer] { id-ppl-independent [Octet String] } } 

我會嘗試一個未測試例如 ProxyCertPathLengthConstraint = 64 policyLanguage = ID-PPL -anyLanguage policy =「test」 我會從頭開始策略長度是04 這是一個可打印的字符串,因此class = 00(universal)primitive/construct = 0(primitive)和標籤編號= 0×13 頭字節是0×13 長度= 4,所以長度是0x04 「測試」 在ASCII是0x74 0x65 0x73 0x74 政策的編碼是0×13 0×04 0x74 0x65 0x73 0x74

ID- ppl-anyLanguage是對象標識符,所以class = 00(通用)基元/構造= 0(基元)和標籤號= 0x06 頭字節是0x06 id-ppl-anyLanguage的值是「1.3.6.1.5.5 .7.21.0「 長度= 18,所以長度字節是0x12 」1.3.6.1.5.5.7.21。0" = 0×11 0x0E的0x03時爲0x0E 0x16 0x0E的爲0x11 0x0E的爲0x15 0x0E的爲0x15 0x0E的0×17 0x0E的0×12 0×11 0x0E的0x10的 編碼爲policyLanguage是 0×06 0×12 0×11爲0x0E×03 0x0E的0x16 0x0E的爲0x11 0x0E的爲0x15 0x0E的爲0x15 0x0E的0×17 0x0E的0×12 0×11 0x0E的0x10的

proxyPolicy是一個這樣的序列:class = 00(universal)primitive/constructed = 0(primitive)and tag-number = 0x10 頭字節爲0x10 length =(policyLanguage)+ lengthof(policy) =(lengthof (策略語言頭文件)+長度(策略語言內容))+(長度(策略頭)+長度(策略內容)) =(2 + 4)+(2 + 18) = 6 + 20 = 26 長度=長度字節是0x1A 含量policyLanguage接着政策= 0×06 0×12 0×11爲0x0E×03 0x0E的0x16 0x0E的爲0x11 0x0E的爲0x15 0x0E的爲0x15 0x0E的0×17 0x0E的0×12 0×11 0x0E的0x10的0×13 0×04 0x74 0x65 0x73 0x74 的用於proxyPolicy編碼是 爲0x10 0x1A的0×06 0×12 0×11 0x0E的0x03時0x0E的0x16 0x0E的爲0x11 0x0E的爲0x15 0x0E的爲0x15 0x0E的0×17 0x0E的0×12 0×11 0x0E的0x10的0×13 0×04 0x74 0x65 0x73 0x74

ProxyCertPathLengthConstraint是一個整數,從而類= 00(通用)原語/構造= 0(原始)和標籤的數量= 0×02 頭字節爲0x02 長度= 0x01 內容= 0x40 編碼爲0x02 0x01 0x40

ProxyCertInfoExtension是一個序列,以便類= 00(通用)原語/構造= 0(原始)和標籤的數量= 0×10 頭字節是0x10的 長度= lengthof(pCPathLenConstraint)+ lengthof(proxyPolicy) = lengthof(內容= pCPathLenConstraint頭)+ lengthof(pCPathLenConstraint內容))+(lengthof(proxyPolicy頭)+ lengthof(proxyPolicy內容)) =(2 + 1)+(2 + 26)= 3 + 28 = 31 = 0x1F content =其次是proxyPolicy = 0x02 0x01 0x40 0x10 0x1A 0x06 0x12 0x11 0x0E 0x03 0x0E 0x15 0x11 0x00 0x15 0x0E 0x12 0x11 0x0E 0x10 0x13 0x04 0x74 0x65 0x73 0x74 編碼爲0x10 0x1F 0x02 0x01 0x40 0x10 0x1A 0x06 0x12 0x11 0x0E 0x03 0x0E 0x16 0x0E 0x11 0x0E 0x15 0x0E 0x1 5 0x0E 0x17 0x0E 0x12 0x11 0x0E 0x10 0x13 0x04 0x74 0x65 0x73 0x74

+0

感謝這個詳細的答案,並對遲到的反饋感到抱歉(項目繼續進行,現在只能回到這個部分)。 正如我後來瞭解的那樣,這裏的問題可以以不同的方式查看,因爲OpenSSL提供了從內部結構轉換爲DER(i2d函數)的函數,但是現在我的問題是i2d函數似乎只能用於其他擴展ProxyCertInfoExtension。稍後我會修改問題以堅持這一點。 – efr4k 2011-05-25 15:52:01