Интерпретация кодировки неопределенной длины 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 запрещает кодирование с неопределенной длиной на том основании, что сериализованное представление одних и тех же данных может измениться при перекодировании (из-за потенциально изменяющегося размера фрагмента).

Другие вопросы по тегам