3 <- index ->5
4. 表現言語 English

本書は、外部表現(external representation)において、データの formatting を扱う。下記の、非常に基本的かつ何となくカジュアルに定義された表現構文が使われる。その構文は、その構造において、いくつかの源泉から描く。これは、C 言語と、その構文と意図の両面で、構文と XDR [XDR] において似通っているが、あまりに多くの類似例を書くにはリスクがある。この表現(presentation)言語の目的は、TLS のみを文書化することにある。; これは、その特定の目標を越えて一般的なアプリケーションをもたない。

4.1. Basic Block Size English

すべてのデータ項目の表現は、明示的に規定される。基本データのブロック長は、1 byte(すなわち、8 bit)である。複数バイトのデータ項目は、左から右へ、上から下への byte の連結である。その byte ストリームから、複数バイトの項目(例中の numeric)は、(C notation を使うと)下記によって形成される。:

 value = (byte[0] << 8*(n-1)) | (byte[1] << 8*(n-2)) |
     ... | byte[n-1];

この複数バイト値についてのバイトの並びは、平凡な(commonplace)ネットワークバイト順もしくはビッグエンディアンフォーマットである。

4.2. その他 English

コメントは、"/*" で始まり、"*/"で終わる。

オプションとしてのコンポーネントは、それらを "[[ ]]" 二重の引用符(bracket)中に囲むことによって表される。

解釈されていない(uninterpreted)データを収めている単一バイト主体は、opaque 型のものである。

4.3. ベクトル English

あるベクトル(single-dimensioned array)は、同室の(homogeneous)データ要素のストリームである。そのベクトルの大きさは、documentation 時刻に規定されるか、あるいは、実行時(runtime)まで規定されないまま残される可能性がある。いずれの場合においても、その長さは、そのベクトル中の要素の数ではなく、バイト数を宣言する。type T の固定長ベクトルである新しい型 T' を規定するための構文は、下記のとおり。

 T T'[n];

ここで、T' は、n が T の長さの倍数であるとき、そのデータストリーム中の n byte を占める。そのベクトルの長さは、その符号化されたストリーム中に含まれない。

下記の例において、Datum は、そのプロトコルが解釈しない 3 consecutive byte として定義される一方、Data は、総計 9 byte を費やす 3 つの consecutive Datum である。

 opaque Datum[3];  /* 解釈されない 3 byte */
 Datum Data[9]; /* 3 consecutive 3 byte ベクトルs */

可変長ベクトルは、notation <floor..ceiling> を使って、包含的に(inclusively)正規の(legal)長さの subrange を規定することによって定義される。これらが符号化されるとき、その実際の長さは、その byte ストリーム中のベクトルの contents に先行する。その長さは、そのベクトルの規定された最大(ceiling)長を保持するために要求されるのと同量のバイト数を費やす数の形態となる。実際の length フィールドとしてゼロをもつ可変長ベクトルは、空のベクトルとして言及される。

 T T'<floor..ceiling>;

下例において、必須なのは、300 から 400 byte 間の type opaque を含まなければならないベクトルである。これは、空ではありえない。実際の length フィールドは、2 byte, a uint16 を費やす。これは、値 400 という値(4.4 節を参照)を表現するために、十分である。他方、長い方は、800 byte のデータ、もしくは 400 uint16 要素までを表現するする可能性があり、それは、空である可能性がある。その符号化は、そのベクトルに先行する 2 byte の実長フィールドを含む。符号化されたベクトルの長さは、単一要素の長さの複数倍でなければならない。(例えば、uint16 の 17 byte ベクトルは、不正となる。)

 opaque mandatory<300..400>;
    /* length フィールドは、2 byteであり、空であってはいけない。 */
 uint16 longer<0..800>;
    /* ゼロから 400 までの 16 bit の unsigned 整数。 */
4.4. Numbers English

basic numeric データ型は、unsigned byte (uint8) である。すべての larger numeric データ型は、 4.1 節 に記述されたように連結された固定長の一連の bytes から形成され、符号無しでもある。下記の numeric 種別は、事前に定義される。

  uint8 uint16[2];
uint8 uint24[3];
uint8 uint32[4];
uint8 uint64[8];

この仕様のここと、他のすべてに渡って、すべての値は、ネットワークバイト順(ビッグエンディアン)に保管される。; hex byte 01 02 03 04 によって表現される uint32 は、その decimal 値 16909060 と等価である。

「場合によっては整数を opaque ベクトルとして表現することが必要不可欠であること(例: DH parameters) 」に注意。このような場合において、それらは、unsigned 整数として表現される。(すなわち、先行する zero octets は、たとえ最も顕著なビットがセットされている場合でも要求されない。)

4.5. enum English

追加的な sparse データ種別は、利用可能であり、enum と呼ばれる。type enum のフィールドは、定義において宣言された値と見なすことのみができる。各定義は、異なる種別である。同種の enumerateds のみが、割り当てられたり、あるいは、比較されたりする可能性がある。挙げられたすべての要素は、下例中に実証したように、値を割り当てられなければならない。挙げられた要素は、順に並べられていないので、それらは、割り当てられた、いかなる固有の値であれ、あらゆる順序である可能性がある。

  enum { e1(v1), e2(v2), ... , en(vn) [[, (n)]] } Te;

enum とされたものは、そのバイトストリーム中に、その最大(maximal)として定義された当初の値となるだけのスペースを占める。下記の定義は、type Color のフィールドを運ぶために使われるべき 1byte をもたらす。

  enum { red(3), blue(5), white(7) } Color;

オプションとして、余分な(superfluous)要素を定義することなしに、 width 定義を強制するために、その関連するタグ無しに、値を規定するものいる可能性がある。下例において、Taste は、そのデータ ストリームにおいて 2 byte を費やすが、値 1, 2 もしくは 4 のみを想定する可能性がある。

  enum { sweet(1), sour(2), bitter(4), (32000) } Taste;

an enumeration の要素の名前は、その定義された種別の範囲内とされる。最初の例において、the enumeration の 2nd 要素宛の fully qualified 参照は、Color.blue となる。このような qualification は、割り当て(assignment)の標的が、よく規定されている場合、要求されない。

 Color color = Color.blue; /* overspecified, legal */
 Color color = blue; /* correct, type implicit */

決して外部的表現には変換されない enum について、その numerical 情報は、省略される可能性がある。

  enum { low, medium, high } Amount;
4.6. Constructed 種別 English

構造体型は、便宜上、primitive 種別から構築される可能性がある。各仕様は、新しく固有(unique)な種別を宣言する。定義についての構文は、C 言語のものとよく似ている。

 
struct {
    T1 f1;
    T2 f2;
    ...
    Tn fn;
} [[T]];

構造体内のフィールドは、その種別の名前を enumerateds 用に利用可能なものと、ほぼ同様の構文と共に使って、適格とされる可能性がある。例えば、T.f2 は、以前の宣言の 2 番目のフィールドを参照する。構造体定義は、embed される可能性がある。

4.6.1. Variants English

定義された構造体は、その環境内で利用可能な何らかの知識に基づく流派(variants)をもつ可能性がある。その選択器(selector)は、その構造体が定義する可能性在る流派を定義する enum 種別でなければならない。その select において宣言された enumeration のすべての要素について、case arm が存在しなければならない。Case arm は、限られた fall-through をもつ。: ふたつの case arm を直後(no fields in between)に伴う場合、それら両方は、同一のフィールドを含む。それゆえ、下例において、"orange" と "banana" の両方は、V2 を含む。「これは、TLS 1.2 における新しい構文の piece であること」に注意。

その流派(variant)の構造体の body は、参照のためのラベルを与えられる可能性がある。その流派が実行時(runtime)に選択されるメカニズムは、その表現言語によって規定されるものではない。

 
   struct {
       T1 f1;
       T2 f2;
       ....
       Tn fn;
        select (E) {
            case e1: Te1;
            case e2: Te2;
            case e3: case e4: Te3;
            ....
            case en: Ten;
        } [[fv]];
   } [[Tv]];

For example:

   enum { apple, orange, banana } VariantTag;

   struct {
       uint16 number;
       opaque string<0..10>; /* variable length */
   } V1;
   
   struct {
       uint32 number;
       opaque string[10];    /* fixed length */
   } V2;

   struct {
       select (VariantTag) { /* value of selector is implicit */
           case apple:
             V1;   /* VariantBody, tag = apple */
           case orange:
           case banana:
             V2;   /* VariantBody, tag = orange or banana */
       } variant_body;       /* optional label on variant */
   } VariantRecord;
4.7. 暗号技術的属性 English

5 つの暗号技術的操作(ディジタル署名、ストリーム暗号による暗号化、ブロック暗号による暗号化、追加的データを伴う公開鍵暗号化(AEAD)および認証された暗号化)は、ディジタル的に署名され、順に、ストリーム暗号化、ブロック暗号化、aead 暗号化、公開鍵暗号化されるように設計されている。あるフィールドの暗号技術的処理は、そのフィールドの種別規定前の適切なキーワード指定(designation)を防ぐことによって規定される。暗号鍵は、現在のセッション状態(6.1 節を参照)によって意味される。

デジタル的に署名された要素は、構造体 DigitallySigned として符号化される。:

 
struct {
   SignatureAndHashAlgorithm algorithm;
   opaque signature<0..2^16-1>;
} DigitallySigned;

そのアルゴリズムフィールド(このフィールドの定義については 7.4.1.4.1節を参照)は、使われているアルゴリズムを規定する。「アルゴリズムフィールドの導入は、以前のバージョンからの変更点であること」に注意。その署名は、それらのアルゴリズムを、その要素の内容に渡って使うディジタル署名である。その内容自体は、回線上に現れないが、単純に計算される。その署名の長さは、その署名アルゴリズムおよび鍵によって規定される。

RSA 署名において、opaque ベクトルは、[PKCS1] 中に定義されている RSASSA-PKCS1-v1_5 署名スキームを使って生成された署名を含む。[PKCS1] において検討されたように、DigestInfo は、DER で符号化 [X680][X690] されなければならない(MUST)。(SHA-1 を含む)パラメータをもたないハッシュアルゴリズムについて、DigestInfo.AlgorithmIdentifier.parameters フィールドは、NULL でなければならない(MUST)が、実装は、parameters をもたないものと NULL パラメータをもつものの両方を受容しなければならない(MUST)。「早期のバージョンの TLS は、DigestInfo 符号化を含んでいなかった、異なる RSA 署名スキームを使っていたこと」に注意。

DSA において、20 byte の SHA-1 ハッシュは、Digital Signing Algorithm を通じて、追加的なハッシュ化無しで直接、動作する。これは、ふたつの値( r および s)を作り出す。DSA 署名は、上記のように、opaque ベクトルであり、これは DER 符号化されたものの内容となる。:

 
Dss-Sig-Value ::= SEQUENCE {
    r INTEGER,
    s INTEGER
}

注: 現在の用語表において、DSA は Digital Signature Algorithm を言い、DSS は NIST の標準を言う。当初の SSL 仕様および TLS 仕様において、"DSS" は、通常、使われた。本書は、"DSA" を、そのアルゴリズムを言うため、"DSS" を、その標準を言うために使い、これは、"DSS"経緯的(historical)継続性(continuity)のために、その code point 定義において使う。

ストリーム暗号による暗号化において、その plaintext は、暗号技術的にセキュアな keyed 擬似乱数生成器から生成された、ちょうど等量の output と排他的論理和がとられる。block cipher 暗号化において、plaintext の、すべてのブロックは、ciphertext のブロックに暗号化する。すべてのブロック暗号の暗号化は、CBC (Cipher Block Chaining) モードで行われ、ブロック暗号化されたすべての要素は、その cipher ブロック長の、ちょうど倍数となる。

AEAD 暗号化において、その plaintext は、同時に暗号化され、インテグリティが保護される。その input は、あらゆる長さをとる可能性があり、aead で暗号化された output は、一般に、インテグリティチェック値を調達するために、その input より大きい。

公開鍵暗号化において、公開鍵アルゴリズムが、データを一致するプライベート鍵で復号できるような方法で暗号化するために使われている。公開鍵暗号化された要素は、opaque ベクトル <0..2^16-1> のように符号化される。ここで、長さは、その暗号化アルゴリズムおよび鍵によって規定される。

RSA 暗号化は、[PKCS1] に定義されている RSAES-PKCS1-v1_5 暗号化スキームを使って行われる。

下例において

 
stream-ciphered struct {
    uint8 field1;
    uint8 field2;
    digitally-signed opaque {
      uint8 field3<0..255>;
      uint8 field4;
    };
} UserType;

内部の構造体(field3 および field4)の内容は、その署名/ハッシュアルゴリズムのための input として使われる。そして、その構造体の全体は、ストリーム暗号で暗号化される。この構造体の長さは(byte 単位で)、(field1 と field2 用の 2 byte)+(その署名アルゴリズムおよびハッシュアルゴリズム用の 2 byte)+(その署名の長さ用の 2 byte)+(署名アルゴリズムの output の長さ)と等しくなる。その署名用に使われるアルゴリズムと鍵は、この構造体を符号化もしくは decoding する前に知られているので、その署名の長さは、知られている。

4.8. 制約 English

Typed 制約は、その要望された種別のシンボルと、 それに割り当てられた値を宣言することによって仕様の目的用に定義される可能性がある。

Under-specified 種別(オペ行く、可変長ベクトルおよび opaque を含む構造体)は、割り当てられた値ではありえない。複数の要素構造体もしくはベクトルのフィールドには、省略されたものは無い可能性がある。

例:

 
struct {
    uint8 f1;
    uint8 f2;
} Example1;

Example1 ex1 = {1, 4}; /* assigns f1 = 1, f2 = 4 */

 


3 <- index -> 5