2023年1月28日土曜日

【ASN.1】ASN.1の型とPERのデコード

 ※注意! 本内容は独学で得た知識のため、内容に誤りがある場合があります。
      予め誤りがある前提でご覧ください。 

■ASN.1で良く用いられる型(代表的なもの)

デコードを前提に記載すると、代表的な型はだいたい8種類あります。

説明
BOOLEAN1ビットを使用してTRUEかFALSEの論理値を表す
INTEGER

(a..b)の範囲の整数値を表す
サイズが9Bits以上の場合、自動的に8Bitsの整数倍のサイズとなる。
BIT STRINGSIZE(a) or SIZE(a..b)でビット列を表す
OCTET STRINGSIZE(a) or SIZE(a..b)でオクテット列を表す
ENUMERATED各要素の中から1つを選択する
SEQUENCE全要素を順番に処理する
SEQUENCE OFSIZE(a) or SIZE(a..b)の回数分SEQUENCE型で処理する
CHOICE各要素の中から1つを選択し、選択された処理をする

■BOOLEAN型

1Bitを使用し、TRUE(1) or FLASE(0)を判定します。

使われ方としてはSEQUENCE型やCHOICE型の中で記載されることが多く、以下のように表現されます。

Data ::= SEQUENCE {
	trueOrFalse	BOOLEAN
}

仮に'80'Hのデータが転送されてきたとした場合は

HEX |Bits|Contents                      |Value|Parameter|Link
----+-----------------------------------|-----+---------+------
  80|1___|trueOrFalse BOOLEAN Data      |    1|     true|
    |_000|Padding                       |     |         |
    |0000|                              |     |         |

となり、1BitでTRUE or FALSEを判定します。結果

Data
	trueOrFalse = true

という結果が返ります。


■INTEGER型

整数値を返します。

値範囲が定義される場合(INTEGER(1..8))と定義されない場合(INTEGER(5))があり、値範囲が定義されている場合はINTEGER(a..b)というように表現されます。

この時、値が0の場合はaとなるため、値+aが戻り値となります。

また値が範囲で定義されているので値を表現するためにb-a分のBit数が必要となります。
ex.)INTEGER(1..8)の場合、初期値が0ではなく1なので8('1000'B)を表現する4Bitsではなく、8-1=7('111'B)を表現できる3Bitsが必要となります。

仮に'80'Hのデータが転送されてきたとした場合、ASN.1の情報として

Data ::= SEQUENCE {
	value	Value
}

Value ::= INTEGER(1..10)

となっていた場合、

HEX |Bits|Contents                      |Value|Parameter|Link
----+-----------------------------------|-----+---------+------
    |    |Data SEQUENCE Data            |     |value    |Value
  80|100_|Value INTEGER Data            |    4|    4+1=5|
    |___0|Padding                       |     |         |
    |0000|                              |     |         |

となり、

Data
	value = 5

という結果が返ります。

また、

Data ::= SEQUENCE {
	value	INTEGER(1..10)
}

という記載や

Data ::= SEQUENCE {
	value	INTEGER(1..maxValue)
}

maxValue INTEGER ::= 5

という記載がされる場合がありますが、SEQUENCE型の外にINTEGER型を置くかどうか、値の範囲を変数で持つか、の違いであり、結果は全て

Data
	value = 5

となります。


ちなみに

Data ::= SEQUENCE {
	value	INTEGER(5)
}

のように固定値の場合は1Bitも使用せずに

HEX |Bits|Contents                      |Value|Parameter|Link
----+-----------------------------------|-----+---------+------
    |    |Data SEQUENCE Data            |     |value    |value
    |    |Value INTEGER Data            |     |        5|
  80|1000|Padding                       |     |         |
    |0000|                              |     |         |

となり

Data
	value = 5

という結果が返ります。


■BIT STRING型

ビット列を返します。

SIZEで表現するBit数を定義しますが、SIZE(a..b)のように可変長の場合はb-a分のDataLengthが必要となります。

仮に'80'Hのデータが転送されてきたとした場合、ASN.1の情報として

Data ::= SEQUENCE {
	bits	BIT STRING(SIZE(3))
}

となっていた場合、

HEX |Bits|Contents                      |Value|Parameter|Link
----+-----------------------------------|-----+---------+------
    |    |Data SEQUENCE Data            |     |bits     |bits
  80|100_|bits BIT STRING Data          |  100|   '100'B|
    |___0|Padding                       |     |         |
    |0000|                              |     |         |

となり

Data
	bits = '100'B

という結果が返ります。


また

Data ::= SEQUENCE {
	bits	BIT STRING(SIZE(1..5))
}

のように可変長で設定された場合は

HEX |Bits|Contents                      |Value|Parameter|Link
----+-----------------------------------|-----+---------+------
    |    |Data SEQUENCE Data            |     |bits     |bits
  80|100_|bits BIT STRING DataLength    |    4|    4+1=5|
    |___0|bits BIT STRING Data          |00000| '00000'B|
    |0000|                              |     |         |

となり

Data
	bits = '00000'B

という結果が返ります。


■OCTET STRING型

オクテット列を返します。

BIT STRING同様、SIZEで表現するOct数を定義しますが、SIZE(a..b)のように可変長の場合はb-a分のDataLengthが必要となります。

仮に'10 00 00 00'Hのデータが転送されてきたとした場合、ASN.1の情報として

Data ::= SEQUENCE {
	octets	OCTET STRING(SIZE(3))
}

となっていた場合、

HEX |Bits|Contents                      |Value |Parameter|Link
----+-----------------------------------|------+---------+------
    |    |Data SEQUENCE Data            |      |octets   |octets
  10|0001|octets OCTET STRING Data      |010000|'010000'H|
    |0000|                              |      |         |
  00|0000|                              |      |         |
    |0000|                              |      |         |
  00|0000|                              |      |         |
    |0000|                              |      |         |
  00|0000|Padding                       |      |         |
    |0000|                              |      |         |

となり

Data
	octets = '010000'H

という結果が返ります。

また

Data ::= SEQUENCE {
	octets	OCTET STRING(SIZE(1..10))
}

のように可変長で設定された場合は

HEX |Bits|Contents                      |Value |Parameter|Link
----+-----------------------------------|------+---------+------
    |    |Data SEQUENCE Data            |      |octets   |octets
  10|0001|octets OCTET STRING DataLength|  0001|    1+1=2|
    |0000|octets OCTET STRING Data      |  0000|  '0000'H|
  00|0000|                              |      |         |
    |0000|                              |      |         |
  00|0000|                              |      |         |
    |0000|Padding                       |      |         |
  00|0000|                              |      |         |
    |0000|                              |      |         |

となり

Data
	octets = '0000'H

という結果が返ります。


■ENUMERATED型

用意された要素の1つを返します。

0が初期値となりますので、要素数-1のBit数が必要となります。

例えば、月を判断するために以下のようなASN.1の情報があり

Data ::= SEQUENCE {
	months	Months
}

Months ::= ENUMERATED {
	january,	--'Value = 0'
	february,	--'Value = 1'
	march,		--'Value = 2'
	april,		--'Value = 3'
	may,		--'Value = 4'
	june,		--'Value = 5'
	july,		--'Value = 6'
	august,		--'Value = 7'
	september,	--'Value = 8'
	october,	--'Value = 9'
	november,	--'Value = 10'
	december	--'Value = 11'
}

そこに'80'Hのデータが転送されて来たとき、

HEX |Bits|Contents                      |Value|Parameter|Link
----+-----------------------------------|-----+---------+------
    |    |Data SEQUENCE Data            |     |months   |Months
  80|1000|Months ENUMERATED Data        |    4|may      |
    |0000|Padding                       |     |         |

となり

Data
    months
        may

という結果が返ります。


■SEQUENCE型

順番に処理をしていきます。

Extensionbit、OptionalBitmap、DefaultBitmapが無い場合は1Bitも使用しません。

例えば以下のようなASN.1の情報があったとして、

Data ::= SEQUENCE {
	sex	Sex,
	age	Age
}

Sex ::= ENUMERATED {
	male,
	female
}

Age ::= INTEGER(0..128)

そこに'80 00'Hのデータが転送されて来たとき、

HEX |Bits|Contents                      |Value|Parameter|Link
----+-----------------------------------|-----+---------+------
    |    |Data SEQUENCE Data            |     |sex      |Sex
  80|1___|Sex ENUMERATED Data           |    1|female   |
    |    |Data SEQUENCE Data            |     |age      |Age
    |_000|Age INTEGER Data              |   20|       20|
    |1000|                              |     |         |
  00|0___|                              |     |         |
    |_000|Padding                       |     |         |

となるので

Data
    sex
        female
    age = 20

という結果が返ります。

このように、SEQUENCE型自体は1Bitも使用せずに他の型でBitsを使い結果を返すことになります。


■SEQUENCE OF型

同じ処理(SEQUENCE)を繰り返します。

SIZEで処理回数を定義しますが、SIZE(4)のように固定長である場合はDataLengthは不要ですがSIZE(a..b)のように可変長である場合はb-aのDataLengthが必要になります。

例えば複数人の男女を表現する場合、'80'Hのデータが転送されてきたとき、麻雀のように4人固定である場合は

Majang ::= SEQUENCE(SIZE(4)) OF Sex

Sex ::= ENUMERATED {
	male,
	female
}

とすることで

HEX |Bits|Contents                      |Value|Parameter|Link
----+-----------------------------------|-----+---------+------
    |    |Data SEQUENCE OF DataLength   |    4|         |
    |    |Data SEQUENCE OF Data         |     |Sex      |Sex
  80|1___|Sex ENUMERATED Data           |    1|female   |
    |    |Data SEQUENCE Data            |     |Sex      |Sex
    |_0__|Sex ENUMERATED Data           |    0|male     |
    |    |Data SEQUENCE Data            |     |Sex      |Sex
    |__0_|Sex ENUMERATED Data           |    0|male     |
    |    |Data SEQUENCE Data            |     |Sex      |Sex
    |___0|Sex ENUMERATED Data           |    0|male     |
    |0000|Padding                       |     |         |

となり

Majang
    Sex
        female
    Sex
        male
    Sex
        male
    Sex
        male

という結果になります。

しかし家族のように可変の複数人である場合は

Family ::= SEQUENCE(SIZE(1..5)) OF Sex

Sex ::= ENUMERATED {
	male,
	female
}

となるので

HEX |Bits|Contents                      |Value|Parameter|Link
----+-----------------------------------|-----+---------+------
  80|100_|Data SEQUENCE OF DataLength   |    4|4+1=5    |
    |    |Data SEQUENCE Data            |     |Sex      |Sex
    |___0|Sex ENUMERATED Data           |    0|male     |
    |    |Data SEQUENCE Data            |     |Sex      |Sex
    |0___|Sex ENUMERATED Data           |    0|male     |
    |    |Data SEQUENCE Data            |     |Sex      |Sex
    |_0__|Sex ENUMERATED Data           |    0|male     |
    |    |Data SEQUENCE Data            |     |Sex      |Sex
    |__0_|Sex ENUMERATED Data           |    0|male     |
    |    |Data SEQUENCE Data            |     |Sex      |Sex
    |___0|Sex ENUMERATED Data           |    0|male     |

となり、

Family
    Sex
        male
    Sex
        male
    Sex
        male
    Sex
        male
    Sex
        male

という結果が返ります。


■CHOICE型

複数の要素から一つを選択し処理します。

ENUMERATED型と同様に0が初期値となりますので、要素数-1のBit数が必要となります。

例えば以下のようなASN.1の情報があったとして、

Legs ::= CHOICE {
	insect	INTEEGR(6),	--'Value = 0'
	octopus	INTEGER(8),	--'Value = 1'
	squid	INTEGER(10)	--'Value = 2'
}

そこに'80'Hのデータが転送されて来たとき、

HEX |Bits|Contents                      |Value|Parameter|Link
----+-----------------------------------|-----+---------+------
  80|10__|Legs CHOICE Data              |    2|        2|squid
    |    |squid INTEGER Data            |   10|       10|
    |__00|Padding                       |     |         |
    |0000|                              |     |         |

となり

Legs
	squid = 10

という結果が返ります。


他にもIA5STRINGやSET等、ASN.1の型はいろいろありますので確認してみてください。


↓よろしければクリックをお願いします!

TOPページに戻る


■関連ページ

【ASN.1】ASN.1(Abstract Syntax Notation One)とは

【ASN.1】PER(Packed Encoding Rules)コーディングとは


0 件のコメント:

コメントを投稿