LINUX.ORG.RU

Библиотека для парсинга ASN.1 С++

 ,


0

4

Всем привет!

У меня есть файл, подписанный цифровой подписью, я его открываю, например, вот в таком онлайн парсере https://lapo.it/asn1js/, и получаю структуру ASN.1.

Я хочу вытащить из такого файла поле - data. Подскажите, пожалуйста, какую-нибудь легкую библиотеку С++ только для чтения файла (как я понял этот формат называется «BER (DER, CER) ASN.1 binary data»). ASN компилятор мне не нужен, ничего генерировать я не собираюсь.

Я уже нашел парочку:

  1. https://github.com/Samuel-Tyler/fast_ber (собрал к ней abseil, и даже ее какие-то либы, но так и не понял, как она должна работать)
  2. https://github.com/YuryStrozhevsky/C-plus-plus-ASN.1-2008-coder-decoder (странная зависимость от xml msxml6.dll, что будет работать только под виндой)

напиши свой парсек. один раз парсь der, второй - дерево асн тегов. у меня этот код работает в микроконтроллере.

anonymous ()

этот формат лютый ад, обаладающий всем набором гемороя как и XML, возьми OpenSSL, там должен быть интерфейс для работы непосредственно с ASN

sparks ★★★ ()

Ты только для начала определись, тебе нужно парсить сам бинарник, или его asn.1 структуру? В OpenSSL есть примитивы для чтения отдельных полей бинарного файла, но сам разбор файликов структуры там сделан через страшный страх на перле и ещё какой-то матери.

Если бы я думал как подойти к такой задаче, я бы начал с обзора подобных инструментов.

pon4ik ★★★★★ ()
Последнее исправление: pon4ik (всего исправлений: 1)
Ответ на: комментарий от pon4ik

Хорошая ссылка, почитаю. Как-то раз я писал snmp-клиента, и столкнулся с этим ASN.1. Возможно, мне это только сейчас кажется наивно не сложным. Там же, вроде, каждый объект имеет свое смещение, а мне, собственно, так и надо - докатиться до нужного блока, скопировать его, и усё. А вот сборки, действительно, лютые бывают, как будто всё это готовилось на космодром.

Парсить надо ASN структуру, чтобы понять, в какой блок я попал, а потом выдрать бинарные данные из него octedstring

Tumyq ()
Последнее исправление: Tumyq (всего исправлений: 1)
Ответ на: комментарий от eve

спасибо, посмотрю. Эх.. жаль, что там ни итераторов, ни токенов.

Tumyq ()
Ответ на: комментарий от anonymous

не, я пока еще не дошел до такого уровня абстракции, и меня повесят, если я на это время потрачу)

Tumyq ()
Ответ на: комментарий от Tumyq

Как минимум OIDы и строки могут быть переменной длинны. Т.е. нужен именно разбор структуры, а вот эту структуру использовать как «карту» бинарника ведя контекст прохождения по нему.

Я делал подобное, но для более простых протоколов, видел реализации для более сложных протоколов. Не ракетная наука, но и не на 5 минут дел.

Для частного случая, если нет полей переменной длины, скорее всего можно и правда просто фиксированное смещение брать, тогда придётся только der разобрать.

pon4ik ★★★★★ ()
Ответ на: комментарий от anonymous

угу, попросили парсер asn.1 + der, ты выдал очередной peg. Который, до кучи ещё и скорее всего в очередной раз не умеет в потоковый разбор(хотя автору это может быть и не нужно, почти все подобные поделки страдают подобным и несут некислые накладные расходы для чувствительных приложений).

Лорвей, сразу видно регистранта со стажем.

P.S.: ещё и переписать аккуратно всю спеку автору придётся, чтобы оно заработало.

pon4ik ★★★★★ ()
Последнее исправление: pon4ik (всего исправлений: 1)
Ответ на: комментарий от eve

Просто чтобы не смущать автора(моим предыдущим высказыванием про страхи не перле), в openssl есть те же примитивы, а он шире распространён как ни крути. Плюс есть пример использования.

pon4ik ★★★★★ ()
Ответ на: комментарий от pon4ik

привет! ты, наверное, автор тех самых говняных асн парсеров, которые я выкинул из-за их ущербности. как там в 80х? память до сих пор освбождаешь оператором delete?

anonymous ()
Ответ на: комментарий от anonymous

Мы в 80ых не выделяем память на куче, у нас всё на стеке отрабатывает за пару-другую сотен наносекундочек, для захардкоженных mtu 100g сетевушек. Ваш хаскель будет портить там кэш даже если просто установлен будет :)

pon4ik ★★★★★ ()
Ответ на: комментарий от pon4ik

молодец, признался! а я вот думаю, чего у меня с виртексов и артиксов данные по езернету плохо идут, то пакеты теряются, то таймауты, в целых пару сотен наносекунд. драйвер на сетевуху ты писал наверное.

и это, вы бы там с пиков на атмеги перешли бы хотя бы, или денег нет?

anonymous ()
Ответ на: комментарий от pon4ik

А, понятно. денег нет, понимаю. ну держитесь там, хорошего настроения!

anonymous ()
Ответ на: комментарий от pon4ik

Я имел в виду, парсинг структуры и смещение относительно его объектов, они ведь в ASN как-то так лежат, что там заголовок переменной и т.д.

Tumyq ()
Ответ на: комментарий от anonymous

с json проблем нет никаких, и много легко подключаемых либ. Буквально недавно одну из них использовал. проблема с ber.

Tumyq ()
Ответ на: комментарий от pon4ik

мне все больше нравится идея с openssl но, честно говоря, о страхах на перле я знаю не понаслышке. никогда не получалось собрать с ним что-нибудь эдакое. поэтому если мне придется собрать openssl c ним, знайте, я был коммунистом )

Tumyq ()
Последнее исправление: Tumyq (всего исправлений: 1)
Ответ на: комментарий от Tumyq

Да там они как-то кодируются, я деталей не помню, но в первых битах значений переменной длины кодируется собственно длина поля. Там по-моему ещё был нюанс с размерами чиселок, по спеке они бесконечной длины, но тот же OpenSSL вписывает их в какой-то из целочисленных типов, мотивируя это тем, что в спеках нигде значения большей длины не используются, а так гораздо эффективней(хотя реализация BIGNUM у них тоже есть:)). Если формат более менее стандартный и связан с криптографией, скорее всего выбор API из криптографических фреймворков аля OpenSSL или MbedTLS будет как минимум самым быстрым решением кроме хаков уровня считать что-то по смещению и т.п.

pon4ik ★★★★★ ()

ASN компилятор мне не нужен

Комрилятор нужен, чтобы сгенерить из asn.1 декодер (в том числе для C++). Если не ошибаюсь, бесплатных их для C(++) полтора калеки.

Из общедоступного только Erlang умеет в полноценный asn.1

Тот же openssl, ЕНМНИП умеет только ту малую часть, что необходима для парзинга PEM. Но может быть этого хватит.

Распарсить «ручками» там ничего страшного нет. Делается на коленке под пиво за полтора дня. Интересное начинается при крос-рефененции asn.1 сообщений. Вот там уже нужны «компиляторы».

beastie ★★★★★ ()
Последнее исправление: beastie (всего исправлений: 2)

ASN компилятор мне не нужен, ничего генерировать я не собираюсь.

А, ты мазохизмом интересуешься, тогда я пас

annulen ★★★★★ ()
Ответ на: комментарий от annulen

Я понимаю так, что компилятор нужен, чтобы генерировать подобные asn-сруктуры. То есть, непосредственно такой дамп памяти с описанной на проприетарном языке структурой asn. И если мне нужно только распарсить уже существующую, такую как файл (например, DER), то - для чего он нужен, что ему собирать?

http://lionet.info/asn1c/

тоже видел, не понял, как его под винду собирать, может, просто воткнуть все файлы в проект.. у них написано, что это надо с Cygwin проворачивать, таки я пробовал - когда запустил make 3.81, он мне фигу показал, хотя их Makefile.am вполне себе что-то содержит

Tumyq ()
Последнее исправление: Tumyq (всего исправлений: 2)
Ответ на: комментарий от anonymous

Через анафорические лямбды, я надеюсь?

слабаки на волге. ничему не научились, кроме грести на галерах.

anonymous ()
Ответ на: комментарий от beastie

Я не с функциональной точки зрения говорю, идея стандартного DSL для описания и сериализации структур данных огонь, но с гибкостью приходят проблемы машинной обработки такой логики и кучей уязвимостей разных реализаций этих парсеров

sparks ★★★ ()
Ответ на: комментарий от Tumyq

Я понимаю так, что компилятор нужен, чтобы генерировать подобные asn-сруктуры.

Не совсем. В принципе Protobufs слизали полностью (с некоторыми упрощениями) с ASN.1 – теже яйца, вид в профиль только без глобального OID namespace.

Т.е. у тебя есть некоторые файл/файлы с описанием структуры данных. Из низ уже компилятор генерирует тебе сериализатор/десериализатор для языка твоего выбора.

beastie ★★★★★ ()
Последнее исправление: beastie (всего исправлений: 1)
Ответ на: комментарий от beastie

Таки и я об этом, что мне не надо генерировать сериализаторы, так как у меня нет заранее известной структуры, да и она мне не нужна. мне нужен только парсер, который сможет пройтись по файлу DER.

Tumyq ()
Ответ на: комментарий от pon4ik

Собрал сегодня 1.1.1.i с тем самым perl. Удивительно, но даже strawberry не ругнулось. nasm положил, nmake даже тесты прошёл. В проект все закинул, собирается, акромя того, что получилось без дебага, и некоторые функции не проходят, но тут, видимо, надо разбираться с правильностью использования.

Tumyq ()
Ответ на: комментарий от Tumyq

Это да, с документацией по использованию API там довольно скудно, рекомендую изучить пример того же asn1parse, дебаг там как-то не очень сложно заводится, вроде опция -d на этапе конфигурации.

pon4ik ★★★★★ ()
Ответ на: комментарий от Tumyq

Я понимаю так, что компилятор нужен, чтобы генерировать подобные asn-сруктуры.

Конечно же, нет. Компилятор может генерировать как энкодер, так и декодер.

И если мне нужно только распарсить уже существующую, такую как файл (например, DER), то - для чего он нужен, что ему собирать?

Собирать декодер и получать готовый парсер из DER в сишные структуры

тоже видел, не понял, как его под винду собирать, может, просто воткнуть все файлы в проект.. у них написано, что это надо с Cygwin проворачивать, таки я пробовал - когда запустил make 3.81, он мне фигу показал, хотя их Makefile.am вполне себе что-то содержит

Там бинарники для винды выложены. Сгенерированный код от компилятора не зависит.

annulen ★★★★★ ()
Ответ на: комментарий от Tumyq

у меня нет заранее известной структуры

Эмм, а ты уверен, что asn1 тогда тебе нужен? Одно дело с xml или json такое ваять, и совсем другое - брать формат, изначально заточенный под сериализацию

annulen ★★★★★ ()
Ответ на: комментарий от Tumyq

мне все больше нравится идея с openssl но, честно говоря, о страхах на перле я знаю не понаслышке

Там нет ничего страшного, к тому же openssl есть в conan

annulen ★★★★★ ()
Ответ на: комментарий от pon4ik

Там в самом openssl при сборке нужно выставлять параметр, чтобы дебаг был, а потом позняк. Я пока насобирался уже его, поэтому попробую примерчики в релизе посмотреть, мало ли, какого зверя там ещё надо было дружить.

Tumyq ()
Ответ на: комментарий от annulen

Бинарники не заметил, попробую с ними тоже. По поводу заранее структуры: я нашёл такой вот парсер, и он вполне это делает https://lapo.it/asn1js/

Tumyq ()
Последнее исправление: Tumyq (всего исправлений: 1)
Ответ на: комментарий от pon4ik

Попробовал парсер openssl, запустил как утилиту для наглядности. Парсер работает, однако, теперь надо понять, как работает функция парсинга, и затащить в свое приложение. Радует, что есть те самые данные заголовков:


+-------------------+---------------+-----------------+
| Identifier octets | Length octets | Contents octets |
| (Type)            | (Length)      | (Value)         |
+-------------------+---------------+-----------------+


C:\WINDOWS\system32>openssl asn1parse -inform der -in C:\Users\asadu\Desktop\Document1.pdf
    0:d=0  hl=4 l=39364 cons: SEQUENCE
    4:d=1  hl=2 l=   9 prim: OBJECT            :pkcs7-signedData
   15:d=1  hl=4 l=39349 cons: cont [ 0 ]
   19:d=2  hl=4 l=39345 cons: SEQUENCE
   23:d=3  hl=2 l=   1 prim: INTEGER           :01
   26:d=3  hl=2 l=  14 cons: SET
   28:d=4  hl=2 l=  12 cons: SEQUENCE
   30:d=5  hl=2 l=   8 prim: OBJECT            :1.2.643.7.1.1.2.2
   40:d=5  hl=2 l=   0 prim: NULL
   42:d=3  hl=4 l=33451 cons: SEQUENCE
   46:d=4  hl=2 l=   9 prim: OBJECT            :pkcs7-data
   57:d=4  hl=4 l=33436 cons: cont [ 0 ]
   61:d=5  hl=4 l=33432 prim: OCTET STRING      [HEX DUMP]:255044462D312E ...

… и есть смещения, есть шанс, что все получится. Так же собрал https://github.com/ARMmbed/mbedtls, и мне понравилось, что все компилится прям в vs в маленькую статичную либу. Хочу попробовать. В плане использования, она была бы легче

Tumyq ()
Ограничение на отправку комментариев: только для зарегистрированных пользователей