Интерпретация кодировки неопределенной длины ASN.1 с несколькими инкапсулированными цепочками октетов
У меня есть структура BER, как это...
$ openssl asn1parse -inform der -in test.der -i -dump
????:d=4 hl=2 l=inf cons: cont [ 0 ]
????:d=5 hl=3 l= 240 prim: OCTET STRING
0000 - AABBCCDD
????:d=5 hl=2 l= 8 prim: OCTET STRING
0000 - EEFF
????:d=5 hl=2 l= 0 prim: EOC
... или в стиле der2ascii...
[0] `80`
OCTET_STRING { `AABBCCDD` }
OCTET_STRING { `EEFF` }
`0000`
Что я знаю: кодирование неопределенной длины должно содержать составной тип, потому что примитивные типы могут вводить неоднозначности, например, когда содержат 0x0000. Что я хочу знать: как должен вести себя декодер при разборе этой структуры BER? Включены ли в кодировку байты заголовка обеих строк OCTET? Если да, то как закодированы байтовые данные неопределенной длины? Как приложение интерпретирует значение поля TLV с тегом [0], когда вторая строка OCTET является, например, INTEGER?
Я задаю этот вопрос, потому что в стандарте CMS поле определяется как одна строка OCTET STRING, но в большинстве кодировок BER я всегда вижу два из них. Это только из-за кодирования неопределенной длины? Я что-то пропустил?
Из МСЭ-T X.690:
8.1.4 Содержание октетов
Октеты содержимого должны состоять из нуля, одного или нескольких октетов и должны кодировать значение данных, как указано в последующих пунктах.
ПРИМЕЧАНИЕ. - Октеты содержимого зависят от типа значения данных; последующие пункты следуют той же последовательности, что и определение типов в ASN.1.
Означает ли это, что я могу поместить каждый созданный тип, и приложение должно интерпретировать только часть значения в созданной структуре TLV?
1 ответ
Когда вы кодируете примитив OCTET STRING в режиме неопределенной длины, кодер должен:
- разделите значение на куски меньших ОКТЕТНЫХ СТРОК
- кодировать каждый блок в режиме определенной длины, чтобы каждый имел свой собственный TLV (с длиной!)
- вся последовательность кодированных примитивов OCTET STRING определенной длины должна быть оформлена одним "контейнером" OCTET STRING с кодированной неопределенной длиной, имеющим собственный TLV (без длины, но с указанием конца октета)
На другом конце декодер извлекает V-часть из внутренних фрагментов OCTET STRING определенной длины (отбрасывая их заголовки TL). Затем соединяет / использует V вместе в порядке прибытия, отбрасывая часть TL внешнего кадра.
Обратите внимание, что идея метода кодирования с неопределенной длиной заключается в том, что и кодер, и декодер могут излучать / потреблять неполные, возможно, слишком большие данные.
Размер порции выбирается кодером / приложением на основе доступности данных, ситуации с памятью и, возможно, оценки возможностей буферизации декодера. Я думаю, что это упоминается где-то в документах X.280/X.680.
Кодировщику не разрешается помещать порции разных типов ASN.1 в какой-либо один закодированный контейнер неопределенной длины. Другими словами, все куски должны быть того же типа, что и внешний контейнер.
Следует надеяться, что это объясняет, почему вы можете видеть несколько (в зависимости от размера фрагмента) СТРОК OCTET в закодированном потоке BER/CER неопределенной длины, где ожидается только одна СТРОКА OCTET.
DER запрещает кодирование с неопределенной длиной на том основании, что сериализованное представление одних и тех же данных может измениться при перекодировании (из-за потенциально изменяющегося размера фрагмента).