ASN.1

Матеріал з Вікі ЦДУ
Версія від 22:47, 18 грудня 2011; Aleksey (обговореннявнесок)

(різн.) ← Попередня версія • Поточна версія (різн.) • Новіша версія → (різн.)
Перейти до: навігація, пошук

Загальна інформація

Однією з найбільш складних систем сьогодні є відкриті системи зв'язку OSI (Open System Interconnection). OSI являє собою досить формалізовану стандартну архітектуру управління межкомпьютерними комунікаціями. Для опису цієї системи був розроблений абстрактний синтаксис нотацій ASN.1 (Abstract Syntax Notation; cм. A Layman's Guide to a Subset of ASN.1, BER, and DER. Burton S. Kaliski Jr., RSA Data Security, Inc. Redwood City , CA, 1991). ASN.1 є формальною мовою, яка володіє двома основними рисами.

ASN.1 являє собою мову опису типів даних та їх значень. У загальному вигляді такий опис має вигляд:

data type value name | data type identifier:: = data value або {data type identifier (data value)}

Комі того, ASN.1 є мовою програмування. Ця мова служить для опису MIB і може використовуватися для модифікації існуючої або створення нової бази даних MIB для SNMP. Список найбільш поширених ключових слів ASN.1 для опису MIB SNMP включає в себе: BEGIN, IDENTIFIER, END, OCTETS, STRING, SEQUENCE, INTEGER, STRING, OBJECT, OF, NULL, DEFINITIONS DESCRIPTION.

Макроси OBJECT-TYPE

Об'єкти MIB створюються макросами ASN.1. Макрос OBJECT-TYPE має формат:

data type value name OBJECT-TYPE

SYNTAX data type identifier

UNITS

ACCESS

STATUS

DESCRIPTION

REFERENCE

INDEX

DEFVAL

:: = {Data value}

  • SYNTAX - визначає тип даних (простий, структурований і т.д)
  • ACCESS - задає рівень доступу до об'єкта (read only, read & write)
  • STATUS - визначає статус опису об'єкта (поточний, застарілий і пр.)
  • DESCRIPTION - описує роль або функцію керованого об'єкта і способи його застосування
  • REFERENCE - опціональний опис, характеризує наслідування об'єкта (вказує на батьківський об'єкт)
  • INDEX - працює у випадку, коли об'єкт містить список або таблицю і дозволяє вказати позицію в списку або таблиці
  • DEFVAL - опціонна характеристика, яка вказує значення об'єкта за замовчуванням

Використовувана в документах нотація легко читається і зрозуміла, а в компактному кодовому поданні інформація може використовуватися комунікаційними протоколами. Невід'ємною частиною ASN.1 є базові правила кодування BER (Basic Encoding Rules), які дозволяють визначити велику різноманітність типів даних. BER описує те, як представити або закодувати будь-яку величину в рамках стандарту ASN.1. або всі величини тут представляються у вигляді послідовності 8-бітних октетів. Восьмий біт октету завжди вважається найстаршим. BER дозволяє закодувати величину більш ніж одним способом. Є також піднабір правил кодування DER (Distinguished Encoding Rules, описані в документі Х.509), які визначають однозначні способи кодування величин ASN.1.

Базові правила позначень метасинтаксису ASN.1

Нижче наведено базові правила позначень метасинтаксису ASN.1.

n (полужирний курсив) означає змінну
[] (квадратні дужки, полужирним шрифтом) терм є опціональним
{} (фігурні дужки, полужирним шрифтом) групування в родинні терми
| (вертикальна риска, полужирним шрифтом) виділяє альтернативні значення
... (три крапки, полужирним шрифтом) означає повторення
= (знак рівності, полужирним шрифтом) описує терм, як субтерм

ASN.1 має чотири різновиди типів: прості типи, що не мають компонент, структурні типи, що мають компоненти, помічені (tagged) типи, які виходять з інших типів, а також інші типи, які включають в себе типи CHOICE і ANY. Типами та значенням можуть присвоюватися імена за допомогою оператора (::=). Ці імена в подальшому можуть використовуватися для визначення інших типів і величин.

Всі типи ASN.1 крім CHOICE і ANY мають мітки, які складаються з класу і невід'ємного коду мітки. Типи ASN.1 тотожні, якщо їх числові мітки збігаються. Існує чотири класи міток.

universal для типів, значення яких є незмінним для всіх додатків. Ці типи визначені в документі Х.208.
application для типів зі значенням, специфічним для додатків, таких як служба каталогів Х.500. Типи двох різних програм можуть мати одну і ту ж мітку і різні значення.
private для типів, які є специфічними для даного підприємства.
content-specific для типів зі значенням, специфічним для даного структурного типу.

Типи та їх мітки

Тип Коментарій Цифрова мітка (шістнадцяткова)
INTEGER Будь-яке ціле число 02
BIT STRING Будь-який рядок біт 03
OCTET STRING Будь-яка послідовність октетів 04
NULL 0 05
OBJECT IDENTIFIER Послідовність цілих компонент, що ідентифікують об'єкт 06
SEQUENCE and SEQUENCE OF 10
SET and SET OF 11
PrintableString Последовательность печатных символов 13
IA5String Произвольная строка символов IA5 (ASCII) 16
UTCTime Універсальний час(по Гринвічу; GMT) 17

ASN.1 типи і значення виражаються в нотації, близької до тої що використовується в мовах програмування. Множинні пробіли і розриви рядків розглядаються як один пропуск. Коментарі виділяються парами дефісів або парою дефісів і переведенням рядка. Ідентифікатори (імена значень і полів) і імена типів складаються з літер, цифр та пробілів. Ідентифікатори починаються з малої літери, а імена типів - з великої.

У SMI (Structure of Management Information) не використовується повний набір типів об'єктів, передбачений в ASN.1, дозволені тільки такі типи примітивів: INTEGER, OCTET STRING, OBJECT IDENTIFIER і NULL.

Стандарт ASN.1 визначає форму подання інформації та імен. Для малих типів може бути введено обмеження на максимальний розмір. В ASN.1 визначено чотири структуровані типи.

Структуровані типи рядків

  • SEQUENCE - упорядкований набір з одного або більше типів.
  • SEQUENCE OF - упорядкований набір з нуля або більше представників даного типу.
  • SET - невпорядкований набір з одного або більше типів.
  • SET OF - невпорядкований набір з нуля або більше представників даного типу.

Структуровані типи можуть мати опціонні компоненти, в тому числі зі значеннями за замовчуванням.

Існують типи помічені явно і неявно. Неявно помічені типи виходять з інших типів шляхом зміни мітки. Для неявної позначки використовується ключове слово IMPLICIT. Явно помічені типи виходять з інших типів шляхом додавання зовнішньої мітки. Позначений явно тип - це структурований тип, що складається з одного компонента основного типу. Для явної позначки використовується ключове слово EXPLICIT. Позначка (тегування) дуже зручна для відмінності типів в межах однієї програми.

Тип CHOICE позначає об'єднання одного або більше альтернатив. Тип ANY служить для позначення довільної величини для довільного типу.

Правила BER

Правила BER визначають один або більше способів представити будь-яку величину у вигляді рядка октетів. Існує три методи кодування величин (в рамках BER): примітивний з відомою довжиною; конструктивний при відомій довжині і конструктивний при невідомій довжині. Вибір методу залежить від типу величини і від того, чи відома довжина перетворюваної величини. Для простих не рядкових типів використовується примітивний метод кодування. У кожному методі BER-кодування має три або чотири частини:

  • Identifier octets - визначає клас і числову позначку значення, а також вказує, чи є метод примітивним або конструктивним.
  • Length octets - для методів кодування з відомою довжиною визначає число октетів вмісту.
  • Contents octets - для примітивних методів із заданою довжиною дає конкретний вираз значення.
  • End-of-contents octets - Для конструктивних методів з невизначеною довжиною вказує на кінець вмісту.

Примітивний метод кодування із заданою довжиною

Цей метод можна застосовувати для простих типів і типів отриманих з простих типів шляхом неявного позначення. Тут необхідно, щоб довжина величини була відома заздалегідь. Октети ідентифікатора мають два формати: для числових міток від 0 до 31, і для числових міток більше 31. У першому випадку біти 7 і 8 визначають клас, біт 6 дорівнює нулю, вказуючи на те, що метод кодування primitive. Решта бітів використовуються для запису коду числової мітки. У другому випадку використовується два або більше октетів. У першому октеті кодування аналогічне першому варіанту за винятком того, що біти 1-5 містять одиниці.

Коди класів:

Клас Біт 8 Біт 7
Універсальний 0 0
Прикладний 0 1
Контекстно-орієнтований 1 0
Приватний 1 1

Для октетів довжини примітивного методу є два формати: короткий (один октет для довжин 0-127) і довгий (2-127 октетів). Для короткої форми восьмий біт октету завжди дорівнює нулю. Для довгої форми восьмий біт першого октету завжди дорівнює 1, біти 1-7 містять код числа додаткових октетів довжини. Старша цифра записується першою.

Конструктивний метод із заданою довжиною

Цей метод використовується для простих малих і структурованих типів, типів, похідних від простих рядкових типів, та деяких інших. Тут октети ідентифікатора і октети довжини мають формат, ідентичний використовуваному примітивним методом, за винятком того, що біт 6 першого октету ідентифікатора дорівнює 1.

Конструктивний метод кодування з незаданою довжиною

Метод використовується для простих рядкових типів, структурованих типів і типів, отриманих із простих і структурованих типів за допомогою неявного позначення. Октети ідентифікатора ідентичні попереднім. Октет довжини містить код 80. Два октету кінця змістовної частини містять 00 00.

Нотація типів, позначених неявно, має вигляд:

[[Class] number] IMPLICIT Type

class = UNIVERSAL | APPLICATION | PRIVITE

де Type - тип, class - опціональне ім'я класу і number - цифрова мітка (невід'ємне ціле число).

Якщо ім'я класу відсутнє, тоді мітка є контекстно-орієнтованою. Такі мітки можуть з'являтися тільки в структурних компонентах або в типі CHOICE. Наприклад:

PrivateKeyInfo:: = {SEQUENCE version Version, privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, privateKey PrivateKey, attributes [0] IMPLICIT Attributes OPTIONAL}

Тут вихідним (що породжує) типом є Attributes, клас відсутній (тобто контекстно-орієнтований), а числова мітка дорівнює нулю. Кодування компоненти attributes величини PrivateKeyInfo здійснюється наступним чином.

Октети ідентифікатора рівні 80, якщо значення величини Attributes має конструктивне BER-кодування. Октети довжини та вмісту строго відповідають октетам величини Attributes.

Безпосередня (явна) позначка використовується для опціональних компонент SEQUENCE c породжуючим типом ANY і для компонент version типу Certificate (X.509 і RFC-1114). Нотація типів, позначених явно, має формат:

[[Class] number] EXPLICIT Type

class = UNIVERSAL | APPLICATION | PRIVATE

де Type - тип, class - опціоне ім'я класу, а number - числова мітка в межах класу (невід'ємне ціле число). Приклад:

ContentInfo:: = {SEQUENCE ContebtType ContentType, Content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL}

Тип ContentInfo має опціональну компоненту content з явною контекстно-орієнтованою міткою.

Іншим прикладом може бути тип Certificate [X.509], що має компоненту з явною контекстно-орієнтованою міткою (ключове слово EXPLICIT опущено).

Certificate:: = ... Version [0] Version DEFAULT v1988, ...

BER-кодування величин, позначених явно, є завжди конструктивним. Октети вмісту ідентичні відповідним октетам породжуючої величини.

Тип ANY

Тип ANY позначає довільну величину довільного типу, де довільний тип можливо визначений при реєстрації ідентифікатора об'єкта або є цілочисельним індексом. Нотація типу ANY має формат:

ANY [DEINED BY identifier]

де identifier - опціонний ідентифікатор. Форма ANY DEINED BY identifier може з'явитися тільки в компоненті типу SEQUNCE або SET, для якої identifier визначає якусь іншу компоненту і ця компонента має тип INTEGER або OBJECT IDENTIFIER. У цій формі істинний тип задається величиною цієї іншої частини. Наприклад, тип AlgorithmIdentifier [X.509] має компоненту типу ANY:

AlgorithmIdentifier:: = {SEQUENCE algorithm OBJECT IDENTIFIER, parameter ANY DEFINED BY algorithm OPTIONAL}

Тут справжній тип компоненти parameter залежить від величини компоненти algorithm. Істинний тип буде визначений при реєстрації об'єкта величини ідентифікатора для компоненти algorithm.

Бітові рядки

Тип BIT STRING позначає довільні бітові послідовності довільної довжини (включаючи нуль). Тип BIT STRING використовується для цифрових сигнатур типу ExtendedCertificate або Certificate [X.509].

Наприклад, тип SubjectPublicKeyInfo має компоненту типу BIT STRING:

SubjectPublicKeyInfo:: = {SEQUENCE Algorithm AlgorithmIdentifier, PublicKey BIT STRING}

BER-кодування величини BIT STRING може бути примітивним або конструктивним. При примітивному кодуванні перший октет має в собі довжину бітової рядки в октетах. У наступних октетах записується сама бітова послідовність. Процедура кодування може включати в себе додаток бітового рядка до цілого числа октетів нулями (якщо це необхідно). Рядок ділиться на октети.

При конструктивному кодуванні октети вмісту представляють собою з'єднання послідовності субрядків, тільки остання з яких містить код довжини, виражений в октетах. Наприклад, при BER-кодуванні значення BIT STRING "0111 1101 1001 1111 11" може бути представлене ​​в одному з наступних видів, залежно від вибору схеми додатку до цілого числа октетів, від формату октетів довжини і від методу кодування примітивний / конструктивний).

Тип CHOICE

Цей тип служить для об'єднання однієї або більше альтернатив. Нотація типу CHOICE має формат.

CHOICE { [Identifier1] Type1, ..., [IdentifierN] Typen}

де identifier1, ..., identifierN є опціональним ідентифікаторами альтернатив, а типи Type1, ..., TypeN - альтернативи. Ідентифікатори потрібні для документування і не грають якоїсь ролі при кодуванні. Типи повинні мати певні позначки. Розглянемо приклад типу ExtendedCertificateOrCertificate, який відноситься до типу CHOICE.

ExtendedCertificateOrCertificate:: = {CHOICE certificate Certificate, - X.509 certificate extendedCertificate [0] IMPLICIT ExtendedCertificate}

Тут ідентифікаторами для альтернатив є certificate і extendedCertificate, а самі альтернативи представлені типами Certificate і [0] IMPLICIT ExtendedCertificate. BER-кодування для типу CHOICE зводиться до кодування альтернатив. При цьому октети ідентифікатора для розглянутого прикладу містять код 30, якщо вибрана альтернатива certificate, і A0 - у разі ExtendedCertificate.

Рядки IA5

Тип IA5String представляє будь послідовності IA5-символів (міжнародний алфавіт 5 - еквівалентно ASCII). Довжина рядка може бути будь-хто, включаючи нуль. Цей тип використовується для адрес електронної пошти та неструктурованих імен.

BER-кодування величини IA5String може бути примітивним або структурованим. При примітивному кодуванні октети вмісту являють собою символи IA5 в ASCII-кодів. При конструктивному кодуванні октети вмісту представляють собою з'єднання ряду IA5-субрядків.

DER-кодування

DER-кодування є завжди примітивним, октети вмісту ідентичні випадку BER-кодування.

Тип INTEGER

Тип INTEGER представляє будь-які цілі числа (позитивні, негативні або 0). Тип INTEGER використовується для номерів версій, криптографічних параметрів (показників, модулів) і типів RSAPublicKey, RSAPrivatKey, DHParameter PBEParameter. Нотація типу INTEGER має формат:

INTEGER [{identifier1 (value1) ... identifiern (valuen)}]

де identifier1 ... identifierN є опціональними ідентифікаторами, а value1 ... valueN - jgwsjyfkmys цілі значення. Наприклад, Version RFC-1114 відноситься до цілого типу зі значенням:

Version:: = INTEGER {1988 (0)}

Ідентифікатору v1988 поставлено у відповідність значення 0. Тип Certificate RFC-1114 використовує ідентифікатор v1988 для присвоєння значення за замовчуванням компоненту version:

Certificate version Version DEFAULT v1988, ...

BER-кодування значення INTEGER є завжди примітивним. Октети вмісту представляють значення цілого по модулю 256 в формі доповнення за модулем 2. Старша цифра є першою. Значення нуль кодується одним октетом 00. Приклади BER-кодування (збігається в даному випадку з DER-кодуванням) представлені в таблиці:

Значення цілого BER-код
0 02 01 00
127 02 02 00 7F
128 02 02 00 80
256 02 02 01 00
-128 02 01 80
-129 02 02 FF 7F

NULL

Тип NULL позначає нульову величину.

Кодування для типу NULL є завжди примітивним, октети вмісту порожні. Наприклад, BER-представлення значення NULL може мати одну з наведених нижче форм (залежить від використовуваного представлення октетів довжини.

05 00 05 81 00

DER-кодування типу NULL є також примітивним і збігається з першим рядком наведеного вище прикладу.

Об'єктні ідентифікатори

Тип OBJECT IDENTIFIER служить для позначення ідентіфікаторов, які представляють собою послідовність цілочисельних компонент, які ідентифікують такі об'єкти, як алгоритм або атрибут імені каталогу. Значення OBJECT IDENTIFIER може містити будь-яке число невід'ємних компонентів. Значення OBJECT IDENTIFIER присвоюються при реєстрації.

Тип OBJECT IDENTIFIER використовується для ідентифікації вмісту ContentInfo, алгоритмів в X.509 (AlgorithmIdentifier) і атрибутів Attribute і AttributeValueAssertion (X.501).

Нотація величини OBJECT IDENTIFIER має вигляд:

{[Identifier] component1 ... componentN} componenti = identifieri | identifieri (valuei) | valuei

де identifier, identifier1, ... identifierN є ідентифікаторами, а value1 ..., valueN - опціональні цілі числа. Ідентифікатори без цілих значень можуть зустрітися тільки для об'єктів, описаних в Х.208.

Наприклад, наведені нижче величини об'єктних ідентифікаторів присвоєні RSA DATA Security, Inc.

{Iso (1) member-body (2) 840 113 549} {1 2 840 113549}

У наступній таблиці представлені деякі об'єктні ідентифікатори та їх значення:

Величина об'єктного ідентифікатора Призначення
{ 1 2 } Члени ISO
{ 1 2 840 } US (ANSI)
{ 1 2 840 113549} RSA Data Security, Inc.
{ 1 2 840 113549 } RSA Data Security, Inc. PKCS (Public Key Cryptography Standard)
{ 2 5 } Служба каталогів (X.500)
{ 2 5 8 } Служба каталогів - алгоритми

BER-кодування OBJECT IDENTIFIER є завжди примітивним. Октети вмісту представляють собою об'єднання n-1 рядка октетів, де n число компонент об'єктного ідентифікатора. Кожни октетний рядок несе в собі ціле число по модулю 128 (старша частина перша). Восьмий біт кожного октету, крім останнього, дорівнює 1. Нехай value1, ..., valueN цілі значення компонентів об'єктного ідентифікатора. Тоді n-1 субідентіфікаторов, з яких формується октетное рядок, будуть мати наступний вигляд:

1. Перший субідентіфікатор дорівнює 40value1 + value2. (Значення value1 лежить в межах 0-2 включно, а value2 в інтервалі 0-39, коли value1 дорівнює 0 або 1.

2. i-ий субідентіфікатор дорівнює value(i+1); де i - належить проміжку від 2 до n-1.

Наприклад, субідентіфікатори об'єктного ідентифікатора RSA Data Security, Inc. дорівнюють 42 = 40x1 + 2, 840, 113 549 і 1. У шістнадцятковому представленні BER-код цього об'єктного ідентифікатора має вигляд:

06 07 2A 86 48 86 F7 0D 01

DER-кодування в даному випадку співпадає з BER.

Рядки октетів

Тип OCTET STRING служить для представлення довільних послідовностей октетів. Значення OCTET STRING може мати будь-яку довжину, включаючи нуль. OCTET STRING використовується для подання повідомлень, включаючи зашифровані, а також для типу PBEParameter. Нотація типу OCTET STRING має формат.

OCTET STRING [SIZE ({size | size1 .. size2})]

де size, size1 і size2 опціональні обмеження розміру. У формі OCTET STRING SIZE (size) рядок октетів повинен мати октети size. У форматі OCTET STRING SIZE (size1 .. size2) рядок повинен містити число октетів між size1 і size2. Наприклад, тип PBEParameter має компоненту типу OCTET STRING:

PBEParameter:: = {SEQUENCE salt OCTET STRING SIZE (8), iterationCount INTEGER}

Тут розмір компоненти salt завжди дорівнює 8 октетам. BER-кодування типу OCTET STRING може бути примітивним або конструктивним. При примітивному кодуванні октети вмісту несуть в собі октети рядки з першого по останній. При конструктивному кодуванні вміст октетів являє собою послідовне об'єднання субрядків значення OCTET STRING.