Получение строк эмитента ASN.1 из файлов PEM?
Вопрос
Недавно я столкнулся с проблемой с Windows 2003 (по-видимому, она также существует и в других версиях), когда, если сервер SSL / TLS запрашивает аутентификацию по сертификату клиента и у него более 16 КБ доверенного DNS-сертификата, Internet Explorer (или любое другое приложение, которое использует schannel.dll ) не удается завершить SSL-квитирование.(В двух словах, сервер разбивает сообщение на фрагменты по 2 ^ 14 байт, согласно RFC 2246 sec.6.2.1, но Schannel не был написан для поддержки этого.Я получил подтверждение от службы поддержки Microsoft, что это недостаток Schannel и что они рассматривают возможность исправления этого в будущей версии.)
Итак, я пытаюсь найти способ легко проанализировать мои доверенные сертификаты (я использую Apache в качестве своего сервера, поэтому все они в формате PEM), чтобы получить общую длину DNS в формате ASN.1 (именно так они отправляются по проводам во время квитирования) и, таким образом, посмотреть, не слишком ли я близок к пределу.Однако я пока не смог найти способ сделать это:функция OpenSSL asn1parse подходит близко, но, похоже, она не предоставляет способа получить последовательность ASN.1 только для имени эмитента, что мне и нужно.
Есть какие-нибудь предложения?
Решение
Поскольку ASN.1 описывает себя сам, написать анализатор ASN.1 довольно легко.Как вы, вероятно, знаете, данные ASN.1 содержат дерево значений, где каждый тип значения идентифицируется глобально присвоенным OID (идентификатор объекта).Вы можете найти бесплатный декодер ASN.1 с исходным кодом по адресу: http://www.geocities.co.jp/SiliconValley-SanJose/3377/asn1JS.html.Он написан на javascript, так что вы можете играть с ним прямо в вашем браузере.
Что касается вашего точного вопроса - я бы:
- Используйте прилагаемый синтаксический анализатор, найдите другой или напишите мой собственный
- Найдите OID доверенного DNs (проверьте спецификацию или просто расшифруйте сертификат, используя прилагаемую страницу декодера ASN.1)
- Объедините два вышеперечисленных параметра, чтобы извлечь размер доверенного DNS внутри сертификата.
Другие советы
openssl asn1parse сделает это, но вам нужно будет выполнить некоторый ручной синтаксический анализ, чтобы выяснить, где начинается последовательность отправителя.Согласно RFC 5280, это 4-й элемент в последовательности TBSCertificate (потенциально 3-й, если это сертификат v1), сразу после алгоритма подписи.В следующем примере:
0:d=0 hl=4 l= 621 cons: SEQUENCE
4:d=1 hl=4 l= 470 cons: SEQUENCE
8:d=2 hl=2 l= 3 cons: cont [ 0 ]
10:d=3 hl=2 l= 1 prim: INTEGER :02
13:d=2 hl=2 l= 1 prim: INTEGER :02
16:d=2 hl=2 l= 13 cons: SEQUENCE
18:d=3 hl=2 l= 9 prim: OBJECT :sha1WithRSAEncryption
29:d=3 hl=2 l= 0 prim: NULL
31:d=2 hl=2 l= 64 cons: SEQUENCE
33:d=3 hl=2 l= 11 cons: SET
35:d=4 hl=2 l= 9 cons: SEQUENCE
37:d=5 hl=2 l= 3 prim: OBJECT :countryName
42:d=5 hl=2 l= 2 prim: PRINTABLESTRING :US
46:d=3 hl=2 l= 26 cons: SET
48:d=4 hl=2 l= 24 cons: SEQUENCE
50:d=5 hl=2 l= 3 prim: OBJECT :organizationName
55:d=5 hl=2 l= 17 prim: PRINTABLESTRING :Test Certificates
74:d=3 hl=2 l= 21 cons: SET
76:d=4 hl=2 l= 19 cons: SEQUENCE
78:d=5 hl=2 l= 3 prim: OBJECT :commonName
83:d=5 hl=2 l= 12 prim: PRINTABLESTRING :Trust Anchor
97:d=2 hl=2 l= 30 cons: SEQUENCE
99:d=3 hl=2 l= 13 prim: UTCTIME :010419145720Z
114:d=3 hl=2 l= 13 prim: UTCTIME :110419145720Z
129:d=2 hl=2 l= 59 cons: SEQUENCE
DN отправителя начинается со смещения 31 и имеет длину заголовка, равную двум, и длину значения, равную 64, общей длиной 66 байт.Конечно, написать сценарий не так-то просто...