X.509v3 ASN.1 к C датаструктам - PullRequest
       93

X.509v3 ASN.1 к C датаструктам

3 голосов
/ 07 апреля 2011

Я пытаюсь создать запрос X509 на получение сертификата прокси (расширение ProxyCertInfo RFC3820 ) в C (OpenSSL), но не могу понять, как следует определять структуры данных ProxyCertInfo. RFC определяет язык ASN.1 следующим образом:

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, поэтому я относительно уверен, что моя единственная проблема - с форматированием структур данных для этого конкретного расширения.

1 Ответ

5 голосов
/ 21 апреля 2011

Я думаю, что ваш вопрос «Как мне отформатировать данные как ProxyCertInfoExtension?» Если это неправильно, пожалуйста, дайте мне знать.

Если вы хотите узнать какую-то теорию, лучшая ссылка, которую я нашел, это Руководство для неспециалистов по подмножеству ASN.1, BER и DER .

Раздел кода в вашем вопросе является описанием того, как кодируются данные для ProxyCertInfoExtension. Думайте о кодировке как о грамматике, которая может быть обработана генератором синтаксического анализатора, подобно тому, как yacc принимает грамматику в качестве входных данных и выводит C-код. На самом деле существует хотя бы один генератор синтаксического анализатора ASN.1 ASN1C

Кодировки ASN.1 могут иметь переменный размер. Данные начинаются с кодировки ASN.1 внешнего уровня или верхнего уровня. Каждая кодировка ASN.1 может содержать внутри себя одну или несколько кодировок ASN.1. Таким образом, ASN.1 является рекурсивным.

Кодировка ASN.1 состоит из заголовка, длины, необязательного содержимого и необязательного конца.

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

Заголовок состоит из типа Class, примитивного / составного бита и номера тега. Если номер тега больше 63, тогда номер тега будет занимать несколько байтов. Это означает, что заголовок может быть длиной в один байт или длиной в несколько байтов в зависимости от значения номера тега. Заголовок выровнен по байту, что означает, что он всегда имеет длину в несколько байтов.

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

Длина также может составлять от одного байта до многих байтов в зависимости от значения длины. Снова длина выравнивается по байту.

Тип класса и номер тега сообщают вам, что закодировано в Контенте.

Самым внешним кодированием обычно является последовательность или набор, которые являются составными базовыми типами. В вашей кодировке самая внешняя кодировка - это ProxyCertInfoExtension, которая является последовательностью необязательного ProxyCertPathLengthConstraint и ProxyPolicy. Ваша кодировка выглядит так:

ProxyCertInfoExtension { [ProxyCertPathLengthConstraint] ProxyPolicy }

Оглядываясь назад на правила кодирования, ProxyCertPathLengthConstraint - это просто целое число, поэтому ваша кодировка действительно:

ProxyCertInfoExtension { [Integer] ProxyPolicy }

Правила кодирования определяют ProxyPolicy как последовательность policyLanguage и необязательной политики. Таким образом, мы можем обновить представление кодировки, чтобы оно выглядело так:

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

Правила кодирования определяют политику в виде строки октетов (всего несколько байтов). Итак, еще одно упрощение дает:

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 политика = «тест» Я буду работать наизнанку, начиная с политики длиной 04 это строка для печати, поэтому class = 00 (универсальный) примитив / построенный = 0 (примитив) и номер тега = 0x13 байт заголовка 0x13 длина = 4, поэтому длина байта равна 0x04 "тест" в ascii 0x74 0x65 0x73 0x74 кодировка для политики 0x13 0x04 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» = 0x11 0x0E 0x03 0x0E 0x16 0x0E 0x11 0x0E 0x15 0x0E 0x15 0x0E 0x17 0x0E 0x12 0x11 0x0E 0x10 кодировка для policyLanguage 0x06 0x12 0x11 0x0E 0x03 0x0E 0x16 0x0E 0x11 0x0E 0x15 0x0E 0x15 0x0E 0x17 0x0E 0x12 0x11 0x0E 0x10

proxyPolicy является последовательностью, поэтому class = 00 (универсальный) примитив / построенный = 0 (примитив) и номер тега = 0x10 байт заголовка 0x10 длина = длина (политика) + длина (политика) = (lengthof (заголовки policyLanguage) + lengthof (содержимое policyLanguage)) + + (lengthof (заголовки policy) + lengthof (содержимое policy)) = (2 + 4) + (2 + 18) = 6 + 20 = 26 длина = 26, поэтому длина байта равна 0x1A содержимое - policyLanguage, за которым следует policy = 0x06 0x12 0x11 0x0E 0x03 0x0E 0x16 0x0E 0x11 0x0E 0x15 0x0E 0x15 0x0E 0x17 0x0E 0x12 0x11 0x0E 0x10 0x13 0x04 0x74 0x65 0x73 0x74 кодировка для proxyPolicy является0x10 0x1A 0x06 0x12 0x11 0x0E 0x03 0x0E 0x16 0x0E 0x11 0x0E 0x15 0x0E 0x15 0x0E 0x17 0x0E 0x12 0x11 0x0E 0x10 0x13 0x04 0x74 0x65 0x73 0x5 045 * 10 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * * 0 * * * 0 * * * 0 * *(примитив) и номер тега = 0x02 байт заголовка равен 0x02, длина = 0x01, содержимое = 0x40, кодировка 0x02 0x01 0x40

ProxyCertInfoExtension - это SEQUENCE, поэтому class = 00 (универсальный) примитив / построенный = 0(примитив) и tag-number = 0x10 байт заголовка равен 0x10 длина = lengthof (pCPathLenConstraint) + lengthof (proxyPolicy) = lengthof (заголовки pCPathLenConstraint) + lengthof (содержимое pCPathLenConstraint)) + (lengthof (заголовки proxyPolicy) + lengthof (proxyPPolol)содержание)) = (2 + 1) + (2 + 26) = 3 + 28 = 31 = 0x1F содержание = pCPathLenConstraint с последующим proxyPolicy = 0x02 0x01 0x40 0x10 0x1A 0x06 0x12 0x11 0x0E 0x03 0x0E 0x16 0x0E 0x11 0x0E 0x15 0x0E 0x15 0x0E0x17 0x0E 0x12 0x11 0x0E 0x10 0x13 0x04 0x74 0x65 0x73 0x74 кодировка 0x10 0x1F 0x02 0x01 0x40 0x10 0x06 0x12 0x1A 0x11 0x0E 0x03 0x0E 0x16 0x0E 0x11 0x0E 0x15 0x0E 0x15 0x0E 0x17 0x0E 0x12 0x11 0x10 0x13 0x0E 0x04 0x74 0x65 0x73 0x74

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...