7.1. Change Cipher Spec プロトコル EnglishTLS は、3 つのサブプロトコルをもつ。これは、ピアがレコード層用のセキュリティパラメータについて合意できるようにするため、ピア自体を認証(authenticate)できるようにするため、交渉されたセキュリティパラメータを開始するため、そして、エラー条件を相互に報告するために使われる。
ハンドシェイクプロトコルは、下記の要素から成るセッションの交渉を担う。:
セッション識別子(session identifier) 活動中の(active)もしくは再利用可能なセッション状態を識別するために、サーバによって選択された任意のバイト列( byte sequence)。
ピア証明書(peer certificate) そのピアの X509v3 [PKIX] 証明書。その状態の、この要素は、null である可能性がある。
圧縮手法(compression method) データを 暗号化の前に圧縮するために使われるアルゴリズム。
cipher spec 鍵とする素材を生成するために使われる PRF(pseudorandom function)。バルクデータ暗号化アルゴリズム(例: null、AES 等)および MAC アルゴリズム(例: HMAC-SHA1)を規定する。これは、mac_length のような暗号技術的属性も規定する。(公式な定義については Appendix A.6 を参照。)
master secret クライアントとサーバ間で共有される 48 byte の secret。
is resumable 「そのセッションは、新しいコネクションを開始するために使えるか否か?」を示すフラグ。
そして、これらの要素は、アプリケーションデータを防護するとき、レコード層によって用されるセキュリティパラメータを作るために使われる。多くのコネクションは、TLS ハンドシェイクプロトコルの失敗の再開を通じて同一セッションを使って具体化される可能性がある。
7.2. アラートプロトコル EnglishChange cipher Spec プロトコルは、暗号(ciphering)戦略における変更(transition)を知らせるために存在する。このプロトコルは、現在の(pending ではない)コネクション状態のもとで暗号化され、圧縮された単一のメッセージから成る。このメッセージは、値が 1 の 1byte から成る。
struct { enum { change_cipher_spec(1), (255) } type; } ChangeCipherSpec;ChangeCipherSpec メッセージは、そのクライアントおよびサーバの両方によって、その受信者に「以降のレコードは、新しく交渉される CipherSpec および鍵のもとで保護されること」を通知するために送られる。このメッセージの受領は、その受信者に、レコード層に read pending の状態を read 現在の状態に、ただちにコピーすることを指図することをもたらす。このメッセージを送った直後に、その送信者は、レコード層に write pending 状態を write active 状態にすることを指図しなければならない(MUST)。(6.1 節を参照。) TChangeCipherSpec メッセージは、そのセキュリティパラメータが合意された後、そのハンドシェイクの間に(ただし、その verifying Finished メッセージが送られる前に)送られる。
注:
再ハンドシェイクが、データがあるコネクション上を流れている過程で起きる場合、その通信を行う主体は、その古い CipherSpec を使ってデータを送り続ける可能性がある。しかし、ひとたび、その ChangeCipherSpec が送られるたら、その新しい CipherSpec が使われなければならない(MUST) 。ChangeCipherSpec を最初に送る側は、「他方の側は、新しい鍵とする素材の計算を完了したこと」を知らない(例: それが、時間を費やす公開鍵の操作を行う必要がある場合)。それゆえ、その受信者がデータを貯めなければならない間の短時間、存在する可能性がある(MAY)。現代のマシンを使う実務において、この間隔は、概ね短い可能性が高い。
7.2.1. Closure アラート EnglishTLS レコード層によってサポートされるコンテンツ種別のひとつは、アラートタイプである。アラートメッセージは、そのメッセージの深刻さ(severity)(warning もしくは fatal)および、そのアラートについての記述を運ぶ。fatal レベルのアラートメッセージは、そのコネクションの中断( immediate termination)をもたらす。この場合、そのセッションに対応する他のコネクションは、続く可能性があるが、そのセッション識別子は、無効とし、その失敗したセッションを、新しいコネクションを確立するために使われることから防がなければならない(MUST)。他のメッセージと同様に、アラートメッセージは、現在のコネクション状態によって規定されているように暗号化され、圧縮される。
enum { warning(1), fatal(2), (255) } AlertLevel;enum { close_notify(0), unexpected_message(10), bad_record_mac(20), decryption_failed_RESERVED(21), record_overflow(22), decompression_failure(30), handshake_failure(40), no_certificate_RESERVED(41), bad_certificate(42), unsupported_certificate(43), certificate_revoked(44), certificate_expired(45), certificate_unknown(46), illegal_parameter(47), unknown_ca(48), access_denied(49), decode_error(50), decrypt_error(51), export_restriction_RESERVED(60), protocol_version(70), insufficient_security(71), internal_error(80), user_canceled(90), no_renegotiation(100), unsupported_extension(110), (255) } AlertDescription;struct { AlertLevel level; AlertDescription description; } Alert;
7.2.2. エラーアラート Englishクライアントおよびそのサーバは、「そのコネクションは、truncation 攻撃を避けるために終了する」という知識を共有しなければならない。いずれの主体も、closing メッセージの交換を開始する可能性がある。
close_notify このメッセージは、「その送信者は、これ以上、このコネクション上のメッセージを送らないこと」 を、その受信者宛に通知する。 「TLS 1.1 においては、 コネクションを正しく閉じることの失敗は、もはや、セッションが中断(resume)されないことを要求しないこと」に注意。これは、広範な実装実践を確保するための TLS 1.0 からの変更点である。
両者は、close_notify アラートを送ることによって閉鎖を開始する可能性がある。closure アラートの後、受け取られた、いかなるデータ も、無視される。
何らかの他の fatal アラートが転送されていない限り、各主体には、close_notify アラートを、そのコネクションの write 側を閉じる前に送ることが要求される。他方の主体は、自身の close_notify アラートで応答し、(あらゆる pending writes を棄却して、)そのコネクションをただちに閉じなければならない(MUST)。その close の開始者には、そのコネクションの read side を閉じる前に対応する close_notify アラートを待つことは、要求されない。
TLS を使っているアプリケーションプロトコルについて、TLS コネクションが閉じた後に、あらゆるデータが下層のトランスポート上を運ばれる可能性があるとする場合、TLS 実装は、アプリケーション層宛に「その TLS コネクションは、終端したこと」を示す前に、対応する close_notify アラート を受け取らなければならない。そのアプリケーションプロトコルが、いかなる追加的なデータも転送しないが、その下層のトランスポート コネクションを閉じるのみの場合、その実装は、対応する close_notify を待つこと無しに、そのトランスポートを閉じることを選択する可能性がある(MAY)。この標準には、(「いつ、コネクションは、開けられるか、あるいは、閉じられるか?」を含めて) TLS についての用法プロファイルがそのデータのトランスポートを管理するような作法を命令していると受け止める必要がある箇所は無い。
注: 「トランスポートを壊す(destroying)前に、pending データを信頼性をもって配信するコネクションを閉じること」が想定されている。
7.3. ハンドシェイクプロトコル概要 EnglishTLS ハンドシェイクプロトコルにおけるエラーハンドリングは、とてもシンプルである。あるエラーが検知されたとき、検知者は、メッセージを他方宛に送る。
fatal アラートメッセージの転送(transmission)もしくは受領(receipt)の際、両者は、すぐに、そのコネクションを閉じる。サーバおよびクライアントは、いかなるセッション識別子、鍵、および、failed コネクションに関連する secret も忘れなければならない(MUST)。それゆえ、fatal アラートによって終了された、いかなるコネクションも、中断(resume)されてはならない(MUST NOT)。ある実装が fatal アラートとして定義されている条件に遭遇するときはいつも、それは、適切なアラートを、そのコネクションを閉じる前に送らなければならない(MUST)。アラートレベルが明示的に規定されていない、すべてのエラーについて、送信者は、その自由裁量において、「これを fatal エラーとして扱うか否か?」を判定する可能性がある(MAY)。その実装が、アラートを送るが、その後、ただちにコネクションを閉じることを意図することを選択する場合、それは、そのアラートを fatal アラートレベルとして送らなければならない(MUST)。
警告(warning)レベルのアラートが送受信される場合、一般に、そのコネクションは、普通に続行できる。その受信者が、そのコネクションについては続けないと判断する場合 (例: 受容することを望んでいない再交渉(renegotiation)アラートを受信しなかった後)、それは、そのコネクションを切断するために、fatal アラートを送る必要がある(SHOULD)。これが与えられると、その送信者は、一般に、「どのように、その受信者は、ふるまうか?」を知ることができない。それゆえ、警告アラートは、その送信者が、そのコネクションを続けることを望むとき、さほど有用ではなく、それゆえ、しばしば省略される。例えば、あるピアが、(おそらく、これを、そのユーザと共に確認した後)期限が切れた証明書を許容することを判断し、そのコネクションを継続することを望む場合、これは、一般的には、certificate_expired アラートを送らない。
下記のエラーアラートが定義されている。:
unexpected_message 不適切なメッセージが受信された。このアラートは、常に、fatal であり、決して正規の実装間の通信において観察されないようにする必要がある。
bad_record_mac このアラートは、ある record が誤った MAC と共に受信される場合、返される。このアラートは、TLSCiphertext が不適(invalid)な様に復号されたことに起因してアラートが送られる場合にも返されなければならない(MUST)。:(これがそのブロック長の倍数でさえなかったか、あるいは、チェックされるとき、その padding 値は不正であったか、のいずれか。)このメッセージは、常に fatal であり、(メッセージが、そのネットワークにおいて壊されていたときを除いて)正しい実装間の通信において、決して観測されないようにする必要がある。
decryption_failed_RESERVED このアラートは、TLS のいくつかの以前のバーションにおいて使われてきた。そして、CBC mode [CBCATT] に対する特定の攻撃許容していた可能性がある。これは、準拠実装によって送られてはならない(MUST NOT)。
record_overflow TLSCiphertext レコードが、受信され、それが 2^14+2048 byte より長い長さをもつ。あるいは、あるレコードが 2^14+1024 byte より長い長さをもつ TLSCompressed レコードに復号された。このメッセージは、常に fatal であり、正しい実装間の通信において(メッセージがネットワーク中で壊されたときを除いて)決して観察されないようにする必要がある。
decompression_failure 解凍(decompression)関数が、不正な input を受信した(例: 過剰な長さに拡張するデータ )。このメッセージは、常に fatal であり、正規の(proper)実装間の通信において決して観測されないようにする必要がある。
handshake_failure handshake_failure アラートメッセージの受領は、「その送信者は、オプションが利用可能としたら、許容可能なセキュリティパラメータの集合を交渉できなかったこと」を示す。これは、fatal エラーである。
no_証明書_RESERVED このアラートは、SSLv3 において使われていたが、いかなるバーションの TLS においても使われていない。これは、準拠実装によって送られてはならない(MUST NOT)。
bad_certificate 証明書が壊れていた、正しく検証しなかった署名を収めていた等。
unsupported_certificate 証明書は、サポートされていない種別のものであった。
certificate_revoked 証明書は、その署名者によって失効された。
certificate_expired 証明書は、有効期限切れとなったか、あるいは、現在、有効ではない。
certificate_unknown 何らかの他の(規定されていない)問題が証明書処理において発生し、それを受容不能と見なす。
illegal_parameter そのハンドシェイク中のフィールドは、範囲外であったか、あるいは、他のフィールドと不整合であった。このメッセージは、常に fatal である。
unknown_ca 有効な証明書チェーンもしくは部分のチェーンが受け取られたが、その証明書は、その CA 証明書が 配置(locate)できなかった、あるいは、既知の信頼できる(trusted)CA と一致しえなかったので受容されなかった。このメッセージは、常に fatal である。
access_denied 有効な証明書が受信されたが、アクセス制御が適用されたとき、その送信者は、交渉を進めないことを決断した。このメッセージは、常に fatal である。
decode_error あるメッセージが、decode できなかった。なぜならば、フィールドには規定された範囲外のものがあったから、あるいは、そのメッセージの長さが不正であったからである。このメッセージは、常に fatal であり、決して正しい実装間の通信中で観察されないようにする必要がある。(メッセージがネットワークにおいて壊れたときを除く)
decrypt_error 署名を正しく検証できないか、あるいは、Finished メッセージを検証できないことを含むハンドシェイクの暗号技術的操作のフィールド。このメッセージは、常に、fatal である。
export_restriction_RESERVED このアラートは、TLS の以前のいくつかのバーションにおいて使われた。これは、準拠実装によって送られてはならない(MUST NOT)。
protocol_version クライアントが交渉する試みたプロトコルバーションは、認識されたが、サポートされていない。(例えば、古いプロトコルバーションは、セキュリティの理由で避けられる可能性がある。)このメッセージは、常に fatal である。
insufficient_security そのサーバがクライアントによってサポートされている cypher よりもセキュアなものを要求することに起因して、具体的に交渉が失敗したとき、handshake_failure の代わりに返される。このメッセージは、常に fatal である。
internal_error ピア、もしくは、プロトコルの正しさと無関連な内部エラー(例: memory allocation failure)は、継続することを不可能にする。このメッセージは、常に fatal である。
user_canceled このハンドシェイクは、プロトコル failure とは関係無い、いくつかの理由(reason)用にキャッシュされる。そのユーザが、ハンドシェイクが完了した後の操作をキャンセルする場合、close_notify を送信することによって、単にそのコネクションを閉じることが、より適切である。このアラートは、close_notify を伴う必要がある。このメッセージは、一般に warning である。
no_renegotiation hello リクエストに応じてクライアントによって送られるか、あるいは、最初の handshaking 後にクライアント hello に応じてサーバによって送られる。これらのいずれも、通常、renegotiation をもたらす。; 不適切なとき、その受信者は、このアラートで応答する必要がある。その時点で、当初の要求者(requester)は、「そのコネクションを続行するか否か?」を判断できる。これが適切となる場合のひとつの事例は、サーバがあるリクエストを満たすためにプロセスを量産した場合である。; その過程は、開始時にセキュリティパラメータ (鍵長、認証等)を受信する可能性があり、以降のこれらのパラメータに対する変更点を通信することは、困難である可能性がある。このメッセージは、常に warning である。
unsupported_extension 「それらは、対応するクライアント hello を入れていなかった」という拡張を含む extended サーバ hello を受信するクライアントによって送られる。このメッセージは、常に fatal である。
新しいアラート値が、12 節に記述されているように IANA によって割り当てられた。
7.4. ハンドシェイクプロトコル Englishセッション状態の暗号技術的パラメータは、TLS ハンドシェイクプロトコルによって作り出される。これは、TLS レコード層の最上部で動作する。TLS のクライアントおよびサーバが、まず、通信を開始するとき、それらは、プロトコルバーションに合意し、暗号アルゴリズムを選択し、オプションとして相互に認証(authenticate)し、shared secrets を生成するために公開鍵暗号化テクニックを使う。
TLS ハンドシェイクプロトコルは、下記のステップを含む。:
hello メッセージを、アルゴリズムについて合意するために交換し、random 値を交換し、セッション resumption についてチェックする。
- そのクライアントとサーバが premaster secret について合意できるようにするために必要不可欠な暗号技術的パラメータを交換する。
- そのクライアントおよびサーバが自身を認証できるようにする証明書および暗号技術的情報を交換する。
- aster secret を、その premaster secret および交換された random 値から生成する。
- セキュリティパラメータを レコード層宛に提供する。
- クライアントおよびサーバに「それらのペアは、同一のセキュリティパラメータを計算したこと」と、「そのハンドシェイクは、攻撃者による tampering 無しに起きたこと」を検証することを許容する。
「上位層は、TLS が常に 2 つのピア間で可能性在る最強のコネクションを交渉するか否かに、過度に依存しては、いけないこと 」に注意。中間者攻撃(man-in-the-middle 攻撃)の攻撃者が 2 つの主体をサポートしている最低のセキュア手法にまで落とすことを試みることができる数多くの方法がある。このプロトコルは、このリスクを最小化するように設計されたが、いまだに攻撃法がある。: 例えば、攻撃者は、セキュアサービスが動作しているポート宛のアクセスを妨害(block)する可能性、あるいは、認証されていない(unauthenticated)コネクションを交渉するためにペアを得ることを試みる可能性がある。基礎的なルールは、「高位のレベルは、それらのセキュリティ要件は何であるかを認識可能であり、決して、彼らが要求する情報を、よりセキュアでないチャネル上を転送してはならないこと」である。TLS プロトコルは、あらゆる cipher suite が約束された(promised)レベルのセキュリティを提供するのでセキュアである。: あなたが 3DES と 1024 bit RSA 鍵交換について、証明書を検証したホストと交渉する場合、あなたは、そのセキュリティの程度にあると期待できる。
これらの目標は、ハンドシェイクプロトコルによって達成され、これは、下記のように要約できる。: そのクライアントは、そのサーバが ServerHello メッセージで応答しなければならない相手宛に ClientHello メッセージを送るか、あるいは、fatal エラーが起こり、そのコネクションは、失敗する。ClientHello および ServerHello は、クライアントとサーバ間にセキュリティ拡張機能(capabilities)を確立するために使われる。ClientHello および ServerHello は、下記の属性(attributes)を確立する。: プロトコルバージョン、セッション ID、Cipher Suite および圧縮手法。さらに、ふたつの random な値が生成され、交換される。: ClientHello.random および ServerHello.random。
実際の鍵交換は、4 つまでのメッセージを使う。: ServerCertificate、ServerKeyExchange、ClientCertificate および ClientKeyExchange。
新しい鍵交換手法が、これらのメッセージについてフォーマットを規定すること、および、クライアントとサーバが shared secret について合意することを許容するメッセージの利用を定義することによって作成される可能性がある。この secret は、極めて長くなければならない(MUST)。; 現在、定義されている鍵交換手法は、46 byte 以上の幅がある secret を交換する。その hello メッセージにしたがって、そのサーバは、それが認証されるべき場合、Certificate メッセージ内で、その証明書を送る。さらに、それが要求される場合(例:そのサーバが証明書をもたない場合、あるいは、その証明書が署名専用の場合)、ServerKeyExchange メッセージが送られる可能性がある。そのサーバが認証される場合、これは、選択された cipher suite に適切である場合、証明書をそのクライアントから要求する可能性がある。次に、そのサーバは、「そのハンドシェイクの hello メッセージフェイズは、完了したこと」を示しながら ServerHelloDone メッセージを送る。そして、そのサーバは、クライアント応答を待つ。そのサーバが CertificateRequest メッセージを送っていた場合、そのクライアントは、その Certificate メッセージを送らなければならない(MUST)。ClientKeyExchange メッセージは、今や送られ、そのメッセージの内容は、ClientHello と ServerHello 間で選択された公開鍵アルゴリズムに依存する。そのクライアントが証明書を署名する能力をもって送信した場合、ディジタル的に署名された CertificateVerify メッセージは、その証明書中のプライベート鍵の保持を明示的に検証するために送られる。
この時点で、ChangeCipherSpec メッセージは、そのクライアントによって送信され、そのクライアントは、pending Cipher Spec を current Cipher Spec にコピーする。そして、そのクライアントは、ただちに、その新しいアルゴリズム、鍵および secrets のもとで Finished メッセージを送る。そのサーバは、応答として、自身の ChangeCipherSpec メッセージを送り、現在の Cipher Spec の保留(pending)を転送し、その新しい Cipher Spec のもとで、その Finished メッセージを送る。この時点で、そのハンドシェイクは完成し、そのクライアントおよびサーバは、アプリケーション層データの交換を開始できる。(下記のフローチャートを参照。)アプリケーションデータは、最初のハンドシェイクの完了前に(TLS_NULL_WITH_NULL_NULL 以外の cipher suite が確立される前に)送られてはならない(MUST NOT)。
クライアント サーバClientHello --------> ServerHello Certificate* ServerKeyExchange* CertificateRequest* <-------- ServerHelloDone Certificate* ClientKeyExchange CertificateVerify* [ChangeCipherSpec] Finished --------> [ChangeCipherSpec] <-------- Finished Application Data <-------> Application Data図 1. ハンドシェイク全体についてのメッセージフロー* Indicates optional or situation-dependent メッセージs that are not always sent。
注:pipeline stalls の回避を支援するために、ChangeCipherSpec は、独立した TLS プロトコルコンテンツ種別であり、実際には TLS ハンドシェイクメッセージではない。
そのクライアントおよびサーバが 、以前のセッションを中断すること、あるいは、(新しいセキュリティパラメータを交渉する代わりに)既存セッションを複成することを判断するとき、そのメッセージフローは、下記のようになる。:
そのクライアントは、ClientHello を、回復(resume)されるべきセッションのセッション ID を使って送る。次に、そのサーバは、そのセッションのキャッシュ内に一致するものがないかについてチェックする。一致が発見され、かつ、そのサーバが特定されたセッション状態の下で、そのコネクションを再確立することを望んでいる場合、それは、ServerHello を同一のセッション ID 値と共に送る。この点において、クライアントとサーバの両方は、ChangeCipherSpec メッセージを送り、直接、Finished メッセージに進まなければならない(MUST)。ひとたび、その再確立が完了すると、そのクライアントとサーバは、アプリケーション層データを交換することを開始する可能性がある(MAY)。(下記のフローチャートを参照。)セッション ID が一致が見つからない場合、そのサーバは、新しいセッション ID を生成し、その TLS クライアントおよびサーバは、ハンドシェイク全部を行う。
クライアント サーバClientHello --------> ServerHello [ChangeCipherSpec] <-------- Finished [ChangeCipherSpec] Finished --------> Application Data <-------> Application Data図 2. 省略されたハンドシェイクについてのメッセージフロー各メッセージの内容および顕著な点(significance)は、下記の節において詳細に提供される。
7.4.1. Hello メッセージ EnglishTLS ハンドシェイクプロトコルは、TLS Record プロトコルの定義された高位レベルクライアントのひとつである。このプロトコルは、セッションの secure attributes を交渉するために使われる。ハンドシェイクメッセージは、TLS レコード層宛に供給される。ここで、それらは、ひとつ、もしくは、複数の TLSPlaintext 構造体内で カプセル化される。これは、現在の active セッション状態によって規定されているように処理され、転送される。
enum { hello_request(0), client_hello(1), server_hello(2), certificate(11), server_key_exchange (12), certificate_request(13), server_hello_done(14), certificate_verify(15), client_key_exchange(16), finished(20), (255) } HandshakeType;struct { HandshakeType msg_type; /* handshake type */ uint24 length; /* bytes in メッセージ */ select (HandshakeType) { case hello_request: HelloRequest; case client_hello: ClientHello; case server_hello: ServerHello; case certificate: Certificate; case server_key_exchange: ServerKeyExchange; case certificate_request: CertificateRequest; case server_hello_done: ServerHelloDone; case certificate_verify: CertificateVerify; case client_key_exchange: ClientKeyExchange; case finished: Finished; } body; } Handshake;ハンドシェイクプロトコルメッセージは、それらが送られなければならない(MUST)順に下記に表現されている。; ハンドシェイクメッセージの予期しない順序の送信は、fatal error をもたらす。しかし、必要とされない(unneeded)ハンドシェイクメッセージは、省略できる。順序(ordering)についてのひとつの例外に注意。: Certificate メッセージは、そのハンドシェイクにおいて 2回((まず)サーバからクライアント宛、次にクライアントからサーバ宛)使われ、その最初の場所にのみ記述される。これらの順序のルールによって制約されていないメッセージとは、HelloRequest メッセージである。これは、いつでも送られる可能性があるが、これは、ハンドシェイクの途中で到達する場合、そのクライアントによって無視される必要がある(SHOULD)。
12 節に記述したように、新しいハンドシェイク メッセージ種別が、IANA によって割り当てられる。
7.4.1.1. Hello リクエスト Englishhello メッセージは、セキュリティ拡張(enhancement)能力(capabilitiy)をクライアントとサーバの間で交換するために使われる。新しいセッションが始まるとき、そのレコード層のコネクション状態暗号化、ハッシュアルゴリズムおよび圧縮アルゴリズムは、null に初期化される。現在のコネクション状態は、renegotiation メッセージ用に使われる。
7.4.1.2. クライアント Hello Englishいつこのメッセージが送られるか?:
HelloRequest メッセージは、そのサーバによって、いつでも送られる可能性がある(MAY)。
このメッセージの意味:
HelloRequest は、「そのクライアントは、交渉過程を新たに開始する必要がある」というシンプルな通知である。応答において、そのクライアントは、都合のよい(convenient)とき、ClientHello メッセージを送る必要がある。このメッセージは、「いずれの側が、クライアントもしくはサーバか?」を確立することを意図したものではなく、ただ新しい交渉を開始するものである。サーバは、クライアントの当初コネクションにおいて、ただちに HelloRequest を送ってはいけない(SHOULD NOT)。その時点における ClientHello の送信は、そのクライアントの仕事です。
このメッセージは、そのクライアントがセッションを交渉している最中の場合、そのクライアントによって無視される。このメッセージは、セッションを交渉することを望まない場合、そのクライアントによって無視される可能性がある(MAY)。あるいは、そのクライアントが望む場合、no_renegotiation アラートで応答する可能性がある。ハンドシェイクメッセージは、アプリケーションデータよりも転送の優先権をもつこと意図されているので、「その交渉は、ごく少数のレコードがクライアントから受信される前に始まること」が期待されている。そのサーバが HelloRequest を送るが、応答において ClientHello を受け取らない場合、これは、fatal アラートと共に、そのコネクションを閉じる可能性がある。
HelloRequest の送信後、サーバは、そのリクエストを、以降のハンドシェイク交渉が完了するまで繰り返してはいけない(SHOULD NOT) 。
このメッセージの構造体:
struct { } HelloRequest;
このメッセージは、ハンドシェイクを通じて維持管理されており、Finished メッセージおよび証明書検証メッセージにおいて使われている、管理されているメッセージ hashes 中に含まれてはならない(MUST NOT)。
7.4.1.3. サーバ Hello Englishいつこのメッセージが送られるか?:
クライアントが最初に、あるサーバに接続するとき、ClientHello を、その最初のメッセージとして送ることが要求される。そのクライアントは、HelloRequest に応答して、あるいは、存在しているコネクション中のセキュリティパラメータを再交渉するために率先して ClientHello を送ることもできる。
このメッセージの構造体:
ClientHello メッセージは、このプロトコルにおける後方で使われる random 構造体を含む。
struct { uint32 gmt_unix_time; opaque random_bytes[28]; } Random;
gmt_unix_time 送信者の当初の時計による標準 UNIX 32 bit フォーマットの現在日時 (うるう秒を無視して、1970年 1月 1日の深夜(UTC)から起算する秒)。時計には、基本的な TLS プロトコルによって正しく設定されることは、要求されない。; higher-レベルのプロトコル、あるいはアプリケーションプロトコルは、追加的な要件を定義する可能性がある。「経緯的な理由によって、データ要素は、GMT(現在の世界的標準時 UTC の前身)によって命名されていること」に注意。
random_bytes セキュアな擬似乱数生成器によって生成された 28 byte。
ClientHello メッセージは、可変長のセッション識別子を含む。空でない場合、その値は、同一のクライアントと サーバ間のセッションを識別する。そのセキュリティパラメータは、そのクライアントが再利用することを望むものである。そのセッション識別子は、以前のコネクションからのもの、このコネクションからのもの、あるいは、現在、生きている他方のコネクションからのものである可能性がある(MAY)。2 番目のオプションは、そのクライアントが、その random 構造体、および、取得されたコネクションの値を更新することのみを望む場合、有用である。そして、3 番目のオプションは、その full ハンドシェイクプロトコルを繰り返すこと無しに、いくつかの独立したセキュアなコネクションを確立することを可能にする。これらの独立したコネクションは、逐次(sequential)あるいは同時(simultaneous)に発生する可能性がある。; セッションID は、それを交渉するハンドシェイクが Finished メッセージの交換で完了するときに有効になり、経年に起因して、あるいは、fatal エラーがそのセッションと関連するコネクションに発生したことによって削除されるまで固執(persist)する。その SessionID の実際の内容は、そのサーバによって定義される。
opaque SessionID<0..32>;警告: SessionID は、暗号化もしくは immediate MAC による防護無しで転送されるので、サーバは、セッション識別子中に confidential 情報を配置したり、あるいは、偽の(fake)セッション識別子の内容が、いかなるセキュリティの侵害ももたらしたりしてはならない(MUST NOT)。(「SessionID を含むハンドシェイク全体としての内容は、そのハンドシェイクの最後において交換された Finished メッセージによって防護されていること」に注意。)
クライアントからサーバ宛に ClientHello メッセージ中で渡される cipher suite リストは、クライアントの選好(好まれる選択肢が最初)の順に、そのクライアントによってサポートされる暗号アルゴリズムの組み合わせを含む。各 cipher suite は、鍵交換アルゴリズム、バルク暗号化アルゴリズム(including secret 鍵長)、MAC アルゴリズムおよび PRF を定義する。そのサーバは、ある cipher suite を選択する。あるいは、受容可能な選択肢が提供されなかった場合、ハンドシェイク失敗アラートを返して、そのコネクションを閉じる。そのリストが、サーバが認識・サポート・利用しようとしない cipher suites を含む場合、そのサーバは、それらの cipher suites を無視し、通常どおり、残りのものを処理しなければならない(MUST)。
uint8 CipherSuite[2]; /* Cryptographic suite selector */ClientHello は、クライアントの選好に従って並べられた、そのクライアントによってサポートされる圧縮アルゴリズムのリストを含む。
enum { null(0), (255) } CompressionMethod;struct { ProtocolVersion client_version; Random random; SessionID session_id; CipherSuite cipher_suites<2..2^16-2>; CompressionMethod compression_methods<1..2^8-1>; select (extensions_present) { case false: struct {}; case true: Extension extensions<0..2^16-1>; }; } ClientHello;TLS は、ある拡張ブロック中の compression_methods フィールドに続く拡張を許容する。拡張の存在は、「ClientHello の最後にある compression_methods に追随するバイト列が存在するか否か?」を判定することによって検出できる。「オプションとしてのデータを検知する、この手法は、可変長フィールドをもつ通常の TLS 手法と区別するが、これは、拡張が定義される前に TLS との互換性用に使われること」に注意。
client_version by which the クライアント wishes to communicate during このセッション
TLS プロトコルのバージョン。これは、クライアントによってサポートされている最新バージョンである必要がある(SHOULD)。このバーションの仕様について、そのバーションは、3.3 となる。(下位互換性の詳細については、Appendix E 参照。)
random クライアント-生成された random 構造体。
session_id クライアントがこのコネクション用に使うことを望むセッションのID。このフィールドは、session_id が利用不能な場合、あるいは、クライアントが新しいセキュリティパラメータを生成することを望む場合、空である。
cipher_suites これは、クライアントによってサポートされている暗号技術的なオプションのリストであり、そのクライアントの最初の選好を最初に伴う。session_id フィールドが空でない(implying a セッション resumption リクエスト)場合、この vector は、少なくとも、そのセッションからの cipher_suite を含まなければならない(MUST)。値は、Appendix A.5 に定義されている。
compression_methods これは、クライアントによってサポートされている圧縮手法のリストであり、クライアント preference によってソートされる。session_id フィールドが 空でない(セッション回復(resumption)リクエストを意味する)場合、それは、そのセッションから compression_method を含まなければならない(MUST)。この vector は、含まなければならない(MUST)。そして、すべての実装は、 CompressionMethod.null をサポートしなければならない(MUST)。それゆえ、クライアントおよびサーバは、常に、圧縮手法に合意できる。
extensions クライアントは、サーバから、拡張 フィールド中のデータを送ることによって拡張された機能を要求する可能性がある(MAY)。実際の "Extension"フォーマットは、7.4.1.4 節中に定義されている。 クライアントが、拡張を使う追加的な機能を要求し、かつ、この機能がそのサーバによってサポートされていない場合、そのクライアントは、そのハンドシェイクを abort する可能性がある(MAY)。サーバは、この拡張 フィールドをもつ ClientHello メッセージと、もたない ClientHello メッセージの両方を受容しなければならない(MUST)。そして、(他のすべてのメッセージと同様に)それは、「そのメッセージ中のデータの量が、これらのフォーマットのひとつと正確に一致すること」をチェックしなければならない(MUST)。;
not
場合、それは、fatal "decode_error" アラートを送らなければならない(MUST)。ClientHello メッセージを送った後、そのクライアントは、ServerHello メッセージを待つ。HelloRequest を除く、そのサーバによって返される、あらゆるハンドシェイクメッセージは、fatal エラーとして扱われる。
7.4.1.4. Hello 拡張 Englishいつこのメッセージが送られるか?:
サーバは、許容可能なアルゴリズムの集合をを見つけることが可能であったとき、ClientHello メッセージに応じて、このメッセージを送る。それが、そのような一致を発見できない場合、これは、ハンドシェイク失敗アラートで応答する。
このメッセージの構造体:
struct { ProtocolVersion server_version; Random random; SessionID session_id; CipherSuite cipher_suite; CompressionMethod compression_method; select (extensions_present) { case false: struct {}; case true: Extension extensions<0..2^16-1>; }; } ServerHello;拡張の存在は、「ServerHello の終端に compression_method フィールドに追随するバイト列が存在するか否か?」を判定することによって検出されうる。
server_version このフィールドは、クライアント hello 中のクライアントによって示唆されたものの低い方、および、サーバによってサポートされた最も高いものを含む。このバーションの仕様について、そのバーションは、3.3 である。(下位互換性の詳細については Appendix Eを参照。)
random この構造体は、サーバによって生成され、ClientHello.random から独立して生成されなければならない(MUST)。
session_id これは、このコネクションに対応する セッションの ID である。ClientHello.session_id が空でなかった場合、そのサーバは、そのセッションキャッシュ内に一致がないかを調べる。一致するものが見つかり、かつ、そのサーバが規定されたセッション状態を使って新しいコネクションを確立することを望む場合、そのサーバは、そのクライアントによってサポートされたものと同一の値で応答する。これは、中断されたセッションを示し、「それらの主体は、Finished メッセージに直接、進めなければならない」と命令する。さもなければ、このフィールドは、新しいセッションを識別する異なる値を含む。そのサーバは、「そのセッションは、キャッシュされず、それゆえ、中断されえないこと 」を示すために空の session_id を返す可能性がある。あるセッションが中断(resume)される場合、これは、当初、交渉されたのと同一の cipher suite を使って、中断されなければならない。「そのサーバは、たとえ、めったに session_id を提供されたことがなかった場合でも、あらゆるセッションを中断するという要件は無いこと」に注意。クライアントは、交渉全体(full negotiation)(新しいcipher suites を交渉することを含む)を、あらゆりハンドシェイクにおいて行うことに備えなければならない(MUST)。
cipher_suite ClientHello.cipher_suites 中のリストからサーバによって選択された単一の cipher suite。esumed セッションについて、このフィールドは、そのセッションが中断された状態からの値である。
compression_手法 ClientHello.compression_methods 中のリストからサーバによって選択された単一の圧縮アルゴリズム。中断されたセッションについて、このフィールドは、resumed セッション状態からの値である。
extensions 拡張のリスト。 「そのクライアントによって提供された拡張のみが、そのサーバのリスト中に存在できること」に注意。
7.4.1.4.1. 署名アルゴリズム English拡張フォーマットは、下記のとおり。:
struct { ExtensionType extension_type; opaque extension_data<0..2^16-1>; } Extension;enum { signature_algorithms(13), (65535) } ExtensionType;ここでは:
"extension_type" は、特定の拡張種別を識別する。
"extension_data" は、特定の拡張種別に特有な情報を収める。
拡張の初期設定は、副読本 [TLSEXT] 中に定義されている。拡張種別のリストは、12 節に記述されているように、IANA によって維持管理される。
拡張種別は、同一の拡張種別が対応する ClientHello 中に現れない限り ServerHello 中に現れなければならない(MUST NOT)。クライアントが関連する ClientHello において要求しなかった ServerHello 中の拡張種別を受け取る場合、それは、そのハンドシェイクを unsupported_extension fatal アラートで中断(abort)しなければならない(MUST)。
それにもかかわらず、"server-oriented" 拡張は、将来、このフレームワーク内で提供される可能性がある。このような拡張(例: type x のもの)は、そのクライアントに、まず、「これは、その拡張種別をサポートすること」を示す空の extension_data を伴う ClientHello 中に type x の拡張を送ることを要求する。この場合、クライアントは、その拡張種別を理解する能力を提供しており、そのサーバは、その提供に基づいてクライアントを得ている。
異なる種別の複数の拡張が ClientHello もしくは ServerHello メッセージ中に存在するとき、その拡張は、あらゆる順序で現れる可能性がある(MAY)。同一の種別のひとつより多くの拡張が存在してはならない(MUST NOT)。
最後に、「拡張は、新しいセッションを開始するとき、および、セッション回復(resumption)を要求するときの両方、送信される可能性があること」に注意。まさに、セッション resumption を要求するクライアントは、一般に、「そのサーバは、この リクエストを受領するか否か?」を知らない。それゆえ、それは、回復を試みなかった場合に送られたであろうものと同一の拡張を送る必要がある(SHOULD)。
一般に、各拡張種別の規定は、full ハンドシェイクと、セッション再開(resumption)の両方において、その拡張の影響を記述することを必要とする。大部分の現在の TLS 拡張は、セッションが開始されたときにのみ関連する。: より古いセッションが中断されたとき、そのサーバは、クライアント Hello 中のこれらの拡張を処理せず、サーバ Hello 中のものを含まない。しかし、拡張には、セッション再開(resumption)において、異なるふるまいを規定する可能性があるものがある。
新しい機能と既存の機能の間でこのプロトコル中に起きる可能性がある適切(および不適切)な相互作用か存在する。これは、全体のセキュリティの顕著な低下をもたらす可能性がある。下記の考慮事項が、新しい拡張を設計するとき、考慮される必要がある。:
サーバが、ある拡張に合意しない場合はエラー条件であり、いくつかは、単に特定の機能をサポートすることの拒否である 。一般に、エラーアラートは、前者用に使われる必要があり、サーバ拡張 response 中のフィールドは、後者用に使われる必要がある。
- 拡張は、可能な限り、ハンドシェイク メッセージの改変によって、特定の機能の利用(もしくは放置)を強要する、いかなる攻撃も予防するように設計される必要がある。この原則は、「その失敗がセキュリティ問題をもたらすと信じられているか否か?」に関わらず追随される必要がある。
しばしば、「その拡張フィールドは、Finished メッセージのハッシュへの input 中に含められている」という事実は、十分であろうが、その拡張が ハンドシェイクフェイズにおいて送られるメッセージの意味を変更するとき、特段の注意が必要とされる。設計者および実装者は、「ハンドシェイクが認証される(authenticated)まで、活発な攻撃者は、メッセージを改変し、拡張を挿入、削除または置換する可能性がある」という事実を認識しておく必要がある。
- TLS の設計の主要な観点を変更するために拡張を使うことは、技術的に可能である。(例:cipher suite 交渉の設計)これは、推奨されない。; 新しいバーションの TLS を規定することが、より望ましい。(特に、TLS ハンドシェイクアルゴリズムは、バーション番号に基づくバーション rollback 攻撃に対する特定の(specific)防護をもつので。)そして、バーション後退(rollback)の可能性は、あらゆる主要な設計変更において、顕著な考慮事項である必要がある。
7.4.2. サーバ証明書 Englishクライアントは、そのサーバ宛に「どの署名/ハッシュアルゴリズムのペアがディジタル署名において使われる可能性があるか?」示すために "signature_algorithms" 拡張を使う。この拡張の "extension_data" フィールドは、"supported_signature_algorithms" 値を含む。
enum { none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5), sha512(6), (255) } HashAlgorithm;enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) } SignatureAlgorithm;struct { HashAlgorithm hash; SignatureAlgorithm signature; } SignatureAndHashAlgorithm;SignatureAndHashAlgorithm supported_signature_algorithms<2..2^16-2>;各 SignatureAndHashAlgorithm 値は、そのクライアントが 検証することを望んでいる単一のハッシュと署名のペアを掲げる。その値は、選好される降順に示される。
注: すべての署名アルゴリズムおよびハッシュアルゴリズムが、ある実装によって受容される可能性があるわけではない(例:DSA with SHA-1, ただし SHA-256ではない)ので、ここにアルゴリズムは、ペアで掲げられる。
hash > このフィールドは、使われる可能性があるハッシュアルゴリズムを示す。この値は、順に、unhashed データ、MD5 [MD5]、SHA-1、SHA-224、SHA-256、SHA-384 および SHA-512 [SHS] についてのサポートを示す。"none" という値は、署名する前にハッシュ化することを要求しない署名アルゴリズムの場合、将来の拡張可能性のために提供される。
signature このフィールドは、使われる可能性がある署名アルゴリズムを示す。その値は、順に、anonymous 署名、RSASSA-PKCS1-v1_5 [PKCS1]、DSA [DSS] および ECDSA [ECDSA] を示すものを含む。その "anonymous" 値は、この文脈において無意味ではあるが、7.4.3 節 において使われる。これは、この拡張中に現れてはならない(MUST NOT)。
この拡張の semantics は、その cipher suite がハッシュアルゴリズムではなく許可可能な(permissible)署名アルゴリズムを示すので、何となく複雑になっている。7.4.2 節 と 7.4.3 節 では、適切なルールを記述している。
クライアントが(この節中に掲げられている)デフォルトのハッシュアルゴリズムおよび署名アルゴリズムのみをサポートする場合、それは、signature_algorithms 拡張を省略する可能性がある(MAY)。そのクライアントが、そのデフォルトアルゴリズムをサポートしない場合、あるいは、他のハッシュと署名のアルゴリズムをサポートする場合、(そして、そのサーバによって送られたメッセージ(すなわち、サーバ証明書およびサーバ鍵交換)を検証するために、それらを使うことを望んでいる場合、)それは、受領することを望んでいるアルゴリズムを掲げている signature_algorithms 拡張を送らなければならない(MUST)。
クライアントが signature_algorithms 拡張を送らない場合、サーバは、下記の事項を行わなければならない(MUST)。:
交渉された鍵交換アルゴリズムが (RSA, DHE_RSA, DH_RSA, RSA_PSK, ECDH_RSA, ECDHE_RSA) のひとつである場合、クライアントは、値 {sha1,rsa} を送信したかのようにふるまう。
- 交渉された鍵交換アルゴリズムが (DHE_DSS, DH_DSS) のひとつである場合、そのクライアントは、値 {sha1,dsa} を送信したかのようにふるまう。
- 渉された鍵交換アルゴリズムが (ECDH_ECDSA, ECDHE_ECDSA) のひとつである場合、そのクライアントは、値 {sha1,ecdsa} を送信したかのようにふるまう。
注: これは、明示的なルールが無い TLS 1.1からの変更点であるが、実際問題として、人は、「そのペアは、MD5 および SHA-1 をサポートする」と想定できる。
注: この拡張は、1.2 より前のバージョンの TLS 用には有意でない。クライアントは、それらが以前のバーションを提供している場合、それを提供しなければならない(MUST NOT)。しかし、たとえクライアントがこれを提供する場合でも、[TLSEXT] 中に規定されたルールは、サーバが理解できない拡張を無視することを要する。
サーバは、この拡張を送らなければならない(MUST NOT)。TLS サーバは、この拡張の受信をサポートしなければならない(MUST)。
セッション回復(resumption)を行うとき、この拡張は、サーバ Hello 含まれていない。そして、そのサーバは、クライアント Hello(があれば、その)中の、その拡張を無視する。
7.4.3. サーバ鍵交換メッセージ Englishいつこのメッセージが送られるか?:
サーバは、合意された鍵交換手法が証明書を authentication 用(これは、DH_anon を除く本書中に規定されているすべての鍵交換手法を含む)
に使うかぎり、証明書メッセージを送らなければならない(MUST)。このメッセージは、常に、ServerHello メッセージの直後に追随する。このメッセージの意味:
このメッセージは、サーバの証明書チェーンを、そのクライアント宛に運ぶ。
その証明書は、交渉された cipher suite の鍵交換アルゴリズム、および、あらゆる交渉された拡張 にとって適切でなければならない(MUST)。
このメッセージの構造体:
opaque ASN.1Cert<1..2^24-1>;struct { ASN.1Cert certificate_list<0..2^24-1>; } Certificate;
certificatelist これは、一連(チェーン)の証明書である。送信者の証明書は、リスト中の最初にこなければならない(MUST)。追随する各証明書は、直接、先行するものを認定(certify)しなければならない(MUST)。証明書検証は、「root 鍵が独立して配布されること」を要求するので、 その root CA を規定する自己署名証明書は、「遠隔の終端は、いかなるときにもそれを検証するために、既に保持していなければならない」という想定のもとで、そのチェーンから省略される可能性がある(MAY)。
同一のメッセージ種別および構造体が、証明書リクエストメッセージに対するクライアントの response 用に使われる。「クライアントは、サーバの認証(authentication)リクエストに応じて送る適切な証明書をもたない場合、証明書を送らない可能性がある(MAY)こと」に注意。
注: PKCS #7 [PKCS7] は、証明書 vector用のフォーマットとして使われない。なぜならば、PKCS #6 [PKCS6] extended 証明書は、使われていないからである。また、PKCS #7 は、SEQUENCE ではなく SET を定義し、そのリストを構文解析する(parsing)タスクをより困難にする。
下記のルールが、そのサーバによって送られた証明書に適用される。:
その証明書種別は、明示的に別途(例:[TLSPGP])交渉されない限り、X.509v3 でなければならない(MUST)。
end 主体証明書の公開鍵(および関連する制約)は、選択された鍵交換アルゴリズムと互換性がなければならない(MUST)。
鍵交換アルゴリズム 証明書鍵種別 RSA
RSA_PSKRSA 公開鍵。その証明書は、暗号化に使われるべき鍵を許容しなければならない(MUST)。(keyEncipherment bit は、鍵用途拡張が在る場合、セットされなければならない(MUST)。)
注: RSA_PSK は、[TLSPSK] 中に定義されている。
DHE_RSA
ECDHE_RSARSA 公開鍵。その証明書は、サーバ鍵交換メッセージ中に採用される署名スキームおよびハッシュアルゴリズムと共に署名用に使われるべき鍵を許容しなければならない(MUST)。(digitalSignature bit は、鍵用途拡張が在る場合、セットされなければならない(MUST)。)
注:ECDHE_RSA は、[TLSECC] 中に定義されている。
DHE_DSS DSA 公開鍵。その証明書は、その鍵がサーバ鍵交換メッセージにおいて採用されるハッシュアルゴリズムと共に署名用に使えるようにしなければならない(MUST)。
DH_DSS
DH_RSADiffie-Hellman 公開鍵。その keyAgreement bit は、鍵用途拡張が在る場合、セットされなければならない(MUST)。
ECDH_ECDSA
ECDH_RSAECDH-capable 公開鍵。その公開鍵は、[TLSECC] に記述さているように、クライアントによってサポートされる curve および point format を使わなければならない(MUST)。
ECDHE_ECDSA ECDSA-capable 公開鍵。その証明書は、サーバ鍵交換 メッセージ中に採用されるハッシュアルゴリズムと共に署名用に使われるべき鍵を許容しなければならない(MUST)。その公開鍵は、[TLSECC] に記述さているように、クライアントによってサポートされる curve および point format を使わなければならない(MUST)。
- "server_name" および "trusted_ca_keys" 拡張 [TLSEXT] は、証明書選択(selection)を導くために使われる。
そのクライアントが "signature_algorithms" 拡張を提供した場合、そのサーバによって提供された、すべての証明書は、その拡張中に現れるハッシュ/署名アルゴリズムのペアによって署名されなければならない(MUST)。「これは、『ある署名アルゴリズム用の鍵を含む証明書は、異なる署名アルゴリズム(例: DSA 鍵で署名された RSA 鍵)を使って署名されること』を意味する可能性がある(MAY)こと」に注意。これは、TLS 1.1 から始まったことであり、「それらのアルゴリズムが同一であること」を要求する。「これは、DH_DSS, DH_RSA, ECDH_ECDSA および ECDH_RSA 鍵交換アルゴリズムは、その証明書に署名するのに使われるアルゴリズムを制限しないことも意味すること」に注意。Fixed DH 証明書は、その拡張中に現れるあらゆるハッシュ/署名アルゴリズムのペアによって署名される可能性がある(MAY)。DH_DSS, DH_RSA, ECDH_ECDSA および ECDH_RSA という名前は、経緯に由来するもの(historical)である。
そのサーバが複数の証明書をもつ場合、それは、上術のクライテリアに基づくもののひとつ(他のクライテリアに加えて、トランスポート層の終点(endpoint)、ローカル設定および性能、等)を選択する。そのサーバが単一の証明書をもつ場合、それは、「これらのクライテリアに合致すること」を検証することを試みる必要がある(SHOULD)。
「現在 TLS と共には使えないアルゴリズム、かつ/または、アルゴリズムの組み合わせを使う証明書が存在すること 」に注意。例えば、RSASSA-PSS 署名鍵 (id-RSASSA-PSS OID in SubjectPublicKeyInfo) をもつ証明書は、TLS が対応する署名アルゴリズムを定義していないので、使えない。
新しい鍵交換手法を規定する cipher suites は、TLS プロトコル用に規定されているので、それらは、証明書フォーマット、および、要求された符号化がされた鍵とする情報を意味する。
7.4.4. 証明書リクエスト Englishいつこのメッセージが送られるか?:
このメッセージは、サーバ証明書メッセージ(もしくは、これが匿名交渉である場合、ServerHello メッセージ)の直後に送られる可能性がある。
ServerKeyExchange メッセージは、サーバ Certificate メッセージが(送られた場合)クライアントが premaster secret を交換することを許容するのに十分なデータを含まないときのみ、そのサーバによって送られる。これは、下記の鍵交換手法について真である。:
DHE_DSS
DHE_RSA
DH_anon下記の鍵交換手法のために ServerKeyExchange メッセージを送ることは、不正である。:
RSA
DH_DSS
DH_RSA
[TLSECC] 中に規定されているもののような他の鍵交換アルゴリズムは、「ServerKeyExchange メッセージが送られたか否か?」を規定しなければならない(MUST)。; そして、そのメッセージが送られる場合、その内容を(規定しなければならない(MUST))。
このメッセージの意味:
このメッセージは、クライアントが premaster secret 通信することを許容するために暗号技術的情報を運ぶ。: Diffie-Hellman 公開鍵、もしくは、何らかの他のアルゴリズム用の公開鍵。これらを使って、(premaster secret となる結果と共に)そのクライアントは、鍵交換を完了させることができる。
このメッセージの構造体:
enum { dhe_dss, dhe_rsa, dh_anon, rsa, dh_dss, dh_rsa /* 拡張される可能性がある。(例:ECDH について [TLSECC] 参照)*/ } KeyExchangeAlgorithm;struct { opaque dh_p<1..2^16-1>; opaque dh_g<1..2^16-1>; opaque dh_Ys<1..2^16-1>; } ServerDHParams; /* 超短期(Ephemeral)DH パラメータ */dh_p The prime modulus used for the Diffie-Hellman 処理。dh_g The generator used for the Diffie-Hellman 処理。dh_Ys サーバの Diffie-Hellman 公開値 (g^X mod p)。struct { select (KeyExchangeAlgorithm) { case dh_anon: ServerDHParams params; case dhe_dss: case dhe_rsa: ServerDHParams params; digitally-signed struct { opaque client_random[32]; opaque server_random[32]; ServerDHParams params; } signed_params; case rsa: case dh_dss: case dh_rsa: struct {} ; /* メッセージは、rsa、dh_dss について省略される。*/
/* そして、dh_rsa は、拡張される可能性がある。(例:ECDH について [TLSECC] 参照) */ }; } ServerKeyExchange;params そのサーバの鍵交換パラメータ。signed_params 非匿名鍵交換用に、サーバの鍵交換パラメータ上の署名。そのクライアントが"signature_algorithms" 拡張を提示した場合、その署名アルゴリズムおよびハッシュアルゴリズムは、その拡張中に掲げられたペアでなければならない(MUST)。「ここに不整合の可能性があること 」に注意。例えば、そのクライアントが DHE_DSS 鍵交換を提示しても、あらゆる DSA ペアを、その "signature_algorithms" 拡張から省略する可能性がある。正しく交渉するようにするため、そのサーバは、あらゆる cipher suites 候補を選択する前に、その "signature_algorithms" 拡張に照らしてチェックしなければならない(MUST)。これは、いささか inelegant であるが、当初の cipher suite 設計への変更を最小化するために設計された妥協案である。
さらに、そのハッシュアルゴリズムおよび署名アルゴリズムは、そのサーバのエンド主体(end-entity)証明書中の鍵と互換性がなければならない(MUST)。RSA 鍵は、あらゆる許容されるハッシュアルゴリズムと共に使われ、証明書中に制約(restriction)(がある場合、制約)の対象となる可能性がある(MAY)。
DSA 署名は、ハッシュアルゴリズムの、いかなる secure indication も含まないので、複数のハッシュが、あらゆる鍵と共に使われる可能性がある場合、ハッシュ substitution のリスクがある。現在、DSA [DSS] は、SHA-1 と共にのみ使われる可能性がある。将来、改訂される DSS [DSS-3] は、他のダイジェストアルゴリズムを DSA と共に利用することを許容することが期待されると共に、「どのダイジェストアルゴリズムが各鍵長と共に使われる必要があるか?」に関するガイダンスが期待される 。さらに、将来の [PKIX] の改訂は、「どのダイジェストアルゴリズムが DSA と共に使われるべきものであるか?」を示すため、証明書用のメカニズムを規定する可能性がある。
追加的な cipher suites は、新しい鍵交換アルゴリズムを含む TLS 用に定義されるので、そのサーバ鍵交換メッセージは、その鍵交換アルゴリズムと関連づけられた証明書種別が、そのクライアントが premaster secret を交換するために十分な情報を提供しない場合のみ、送られる。
7.4.5. サーバ Hello Done Englishいつこのメッセージが送られるか?:
非匿名サーバは、選択された cipher suite について適切である場合、証明書を、そのクライアントからオプションとして要求できる。このメッセージが送られた場合、ServerKeyExchange メッセージ直後に追随する。(さもなければ、これが送られた場合、このメッセージは、そのサーバの Certificate メッセージに追随する。)
このメッセージの構造体:
enum { rsa_sign(1), dss_sign(2), rsa_fixed_dh(3), dss_fixed_dh(4), rsa_ephemeral_dh_RESERVED(5), dss_ephemeral_dh_RESERVED(6), fortezza_dms_RESERVED(20), (255) } ClientCertificateType;opaque DistinguishedName<1..2^16-1>;struct { ClientCertificateType certificate_types<1..2^8-1>; SignatureAndHashAlgorithm supported_signature_algorithms<2^16-1>; DistinguishedName certificate_authorities<0..2^16-1>; } CertificateRequest;
certificate_types クライアントが提供する可能性がある証明書種別のリスト。
rsa_sign RSA 鍵を含む証明書 dss_sign DSA 鍵を含む証明書 rsa_fixed_dh 無期の(static)DH 鍵を含む証明書 dss_fixed_dh 無期の(static)DH 鍵を含む証明書
supported_signature_algorithms 選好の降順に掲げられている、そのサーバが喧噪できるハッシュ/署名アルゴリズムペアのリスト。
certificate_authorities 許容可能な certificate_authorities の DN [X501] のリストで、DER-encoded format で表現されたもの。これらの DN は、 root CA 用、もしくは subordinate CA 用に渇望される DN を規定する可能性がある。; それゆえ、このメッセージは、渇望される認可(authorization)space と同様に、既知の roots を記述するために使える。その certificate_authorities リストが空である場合、そのクライアントは、逆に、何らかの外部との調整(arrangement) がないかぎり、適切な ClientCertificateType の、あらゆる証明書を送る可能性がある(MAY)。
certificate_types および supported_signature_algorithms フィールドの相互作用は、何とも複雑である。certificate_types は、SSLv3 以来、TLS 中に存在していたが、なぜか規定されなかった。その機能の一致は、supported_signature_algorithms によって、取って代えられた。下記のルールが適用される。:
- そのクライアントによって提供されたあらゆる証明書は、supported_signature_algorithms 中にあるハッシュアルゴリズム/署名アルゴリズムのペアを使って署名されなければならない(MUST)。
- そのクライアントによって提供された end-entity 証明書は、certificate_types と互換性がある鍵を含まなければならない(MUST)。その鍵が署名鍵である場合、それは、supported_signature_algorithms 中の何らかのハッシュアルゴリズム/署名アルゴリズムのペアと共に利用可能でなければならない(MUST)。
- あるいは、経緯上の理由により、クライアント証明書種別の名前には、証明書に署名するために使われるアルゴリズムを含むものがある。例えば、TLS の初期のバーションにおいて、rsa_fixed_dh は、RSA で署名され、ひとつの static DH 鍵を含む証明書を意味した。TLS 1.2 において、この機能は、supported_signature_algorithms によって廃止され、その証明書種別は、もはや、その証明書に署名するために使われるアルゴリズムを制限しない。例えば、そのサーバは、dss_fixed_dh 証明書種別と {{sha1, dsa}, {sha1, rsa}} 署名種別を送る場合、そのクライアントは、RSA-SHA1 で署名された、ひとつの無期の(static)DH 鍵を含む証明書と共に応答する可能性がある(MAY) 。
新しい ClientCertificateType 値が 12 章に記述されているように IANA によって割り当てられた。
注: RESERVED として掲げられている値は、使われない可能性がある。それらは、SSLv3において使われていた。
注:クライアント認証を要求することは、匿名(anonymous)サーバにとっては fatal handshake_failure アラートである。
7.4.6. クライアント証明書 Englishいつこのメッセージが送られるか?:
ServerHelloDone メッセージは、ServerHello および関連するメッセージの終りを示すために、そのサーバによって送られる。このメッセージを送った後、そのサーバは、クライアントからの応答(response)を待つ。
このメッセージの意味:
このメッセージは、「そのサーバは、鍵交換をサポートするためにメッセージを送信し終え、そのクライアントは、その鍵交換のフェイズを処理できること」を意味する。
ServerHelloDone メッセージの受信に際して、そのクライアントは、「そのサーバは、(要求される場合)有効な証明書を提供したか?」を検証し、「そのサーバ hello パラメータは、受容可能であること」をチェックする必要がある(SHOULD)。
このメッセージの構造体:
struct { } ServerHelloDone;
7.4.7. クライアント鍵交換 メッセージ Englishいつこのメッセージが送られるか?:
これは、そのクライアントが ServerHelloDone メッセージを受け取った後、送信できる最初のメッセージである。このメッセージは、そのサーバが証明書を要求する場合にのみ送られる。適切な証明書で利用可能でない場合、そのクライアントは、証明書を何も含まない証明書メッセージを送らなければならない(MUST)。すなわち、certificate_list 構造体の長さは、ゼロである。そのクライアントが、いかなる証明書も送らない場合、そのサーバは、その裁量で、そのハンドシェイクをクライアント認証無しに続けるか、あるいは、 fatal handshake_failure アラートで応答するか、のいずれかの可能性がある(MAY)。また、その証明書チェーンの観点に適用できなかったものがある場合(例:これは、既知の信頼できる CA によって署名されたものではない)、そのサーバには、その裁量で、そのハンドシェイク(そのクライアントが認証されていない(unauthenticated)ことを考慮して)を続けるか、あるいは、fatal アラートを送るか、のいずれの可能性もある(MAY)。
クライアント証明書は、7.4.2 節に定義されている証明書の構造体を使って送られる。
このメッセージの意味:
このメッセージは、クライアントの証明書チェーンを、そのサーバ宛に運ぶ。; そのサーバは、 それを CertificateVerify メッセージを検証するとき(そのクライアント認証が署名(signing)に基づいているとき)、あるいは、その premaster secret (非超短期(ephemeral)Diffie-Hellman 用)を計算するとき、使う。その証明書は、交渉された cipher suite の鍵交換アルゴリズム、および、あらゆる交渉された拡張について、適切でなければならない(MUST)。
特記:
証明書種別は、明示的に別途、交渉されない限り(例:[TLSPGP])、X.509v3 でなければならない(MUST)。
end-entity 証明書の公開鍵(および関連する制約(restrictions))は、CertificateRequest 中に掲げられた証明書種別と互換性をもつ必要がある。:
クライアント証明書種別 証明書鍵種別
rsa_sign RSA 公開鍵。その証明書は、その鍵が 証明書検証メッセージ中に採用される署名スキームおよびハッシュアルゴリズムと共に署名用に使われることを許容しなければならない(MUST)。
dss_sign DSA 公開鍵。その証明書は、その鍵が証明書検証メッセージ中で採用されるハッシュアルゴリズムと共に署名用に使われることを許容しなければならない(MUST)。
ecdsa_sign ECDSA-capable 公開鍵。その証明書は、その鍵が証明書検証メッセージにおいて採用されるハッシュアルゴリズムで署名するために使えるようにしなければならない(MUST)。; その公開鍵は、そのサーバによってサポートされている curve と point のフォーマットを使わなければならない(MUST)。
rsa_fixed_dh
dss_fixed_dh
Diffie-Hellman 公開鍵。サーバの鍵と同一のパラメータを使わなければならない(MUST)。
rsa_fixed_ecdh
ecdsa_fixed_ecdhECDH-capable 公開鍵。サーバの鍵と同一の curve を使わなければならない(MUST)。そして、そのサーバによってサポートされる point フォーマットを使わなければならない(MUST)。
証明書リクエストメッセージ中の certificate_authorities リストが空でない場合、その証明書チェーン中の証明書のひとつは、掲げられた CA のひとつによって発行される必要がある(SHOULD)。
証明書は、7.4.4 節に記述されているように、受容可能なハッシュ/署名アルゴリズムのペアを使って署名されなければならない(MUST)。「これは、以前のバーションの TLS にみられる証明書署名アルゴリズムについての制約を緩和すること」に注意。
「サーバ証明書と同様に、TLS と共には現在、使えないアルゴリズム/アルゴリズムの組み合わせを使う証明書があること」に注意。
7.4.7.1. RSA-Encrypted Premaster Secret メッセージ Englishいつこのメッセージが送られるか?:
このメッセージは、常にクライアントによって送られる。これは、送られる場合、そのクライアント証明書メッセージの直後に追随しなければならない(MUST)。さもなければ、これは、クライアントが ServerHelloDone メッセージを受け取った後に、そのクライアントによって 送られた最初のメッセージでなければならない(MUST)。
このメッセージの意味:
このメッセージによって、premaster secret は、RSA で暗号化された secret の直接転送か、あるいは、各側が同一の premaster secret について合意することを許容する Diffie-Hellman パラメータの転送のいずれかによってセットされる。
そのクライアントが超短期(ephemeral)Diffie-Hellman exponent を使っているとき、このメッセージは、そのクライアントの Diffie-Hellman public 値を含む。そのクライアントが定数 DH exponent を収めている証明書を送っている(すなわち、それは、fixed_dh クライアント認証を行っている)場合、 このメッセージは、送られなければならない(MUST)が、空でなければならない(MUST)。
このメッセージの構造体:
メッセージの選択は、「どの鍵交換手法が選択されたか?」に依存する。KeyExchangeAlgorithm 定義については 7.4.3 節を参照。
struct { select (KeyExchangeAlgorithm) { case rsa: EncryptedPreMasterSecret; case dhe_dss: case dhe_rsa: case dh_dss: case dh_rsa: case dh_anon: ClientDiffieHellmanPublic; } exchange_keys; } ClientKeyExchange;
7.4.7.2. クライアント Diffie-Hellman 公開値 Englishこのメッセージの意味:
RSA が鍵 agreement および認証(authentication)用に使われている場合、そのクライアントは、48 byte の premaster secret を生成し、そのサーバの証明書からの公開鍵を使ってそれを暗号化し、その結果を暗号化された premaster secret メッセージの中で送る。この構造体は、ClientKeyExchange メッセージの流派であり、メッセージ自体ではない。
このメッセージの構造体:
struct { ProtocolVersion client_version; opaque random[46]; } PreMasterSecret;client_versionそのクライアントによってサポートされた最新バーション。これは、バーションロールバック攻撃を検知するために使われる。
random46 セキュアに生成された random バイト列。
struct { public-key-encrypted PreMasterSecret pre_master_secret; } EncryptedPreMasterSecret;pre_master_secretこの random 値は、そのクライアントによって生成され、8.1 節中に規定されているように master secret を生成するために使われる。
注: PreMasterSecret 中のバーション番号は、ClientHello.client_version 中に、そのクライアントによって提供されるバーションであり、そのコネクション用に交渉されたバーションではない。この機能は、rollback 攻撃を防ぐために設計された。残念ながら、古い実装には、代わりに、その交渉された バーションを使うものがあり、それゆえ、バーション番号をチェックすることは、このような誤った(incorrect)クライアント実装と相互運用することに失敗をもたらす可能性がある。
クライアント実装は、常に PreMasterSecret 中の正しいバーション番号を送らなければならない(MUST)。ClientHello.client_version が TLS 1.1 以降である場合、サーバ実装は、下記の注の中に記述したように、そのバーション番号をチェックしなければならない(MUST)。そのバーション番号が TLS 1.0 以前である場合、サーバ実装は、そのバーション番号をチェックする必要がある(SHOULD)が、 そのチェックを不能にする設定オプションをもつ可能性がある(MAY)。「そのチェックが失敗する場合、PreMasterSecret は、下記のように乱雑化される必要がある(SHOULD)」に注意。
注: Bleichenbacher [BLEI] および Klima ら [KPR03] によって発見された攻撃は、「特定のメッセージが(復号されるとき)正しく PKCS#1 フォーマット化されているか否か?」、「妥当な PreMasterSecret 構造体を含むか否か?」あるいは「正しいバーション番号をもっているか否か?」を明かす TLS サーバを攻撃するために使える。
Klima [KPR03] によって記述されたように、これらの脆弱性は、不正に(incorrectly)フォーマットされたメッセージブロック、かつ/または、一致しないバーション番号を、正しくフォーマットされた RSA ブロックと区別できない作法で扱うことによって避けることができる。換言する。:
46 random byte の string R を生成する
その plaintext M を復元するために、そのメッセージを復号する
- PKCS#1 padding が不正、
あるいはメッセージ M の長さが明示的に 48 byte ではない場合:
pre_master_secret = ClientHello.client_version || R
else If ClientHello.client_version <= TLS 1.0 かつバージョン番号チェックが明示的に不能とされている:
pre_master_secret = M
else:
pre_master_secret = ClientHello.client_version || M[2..47]「そのクライアントが当初の pre_master_secret において誤ったバーションを送った場合、ClientHello.client_version で pre_master_secret を明示的に構築することは、不適な(invalid)master_secret を作り出すこと」に注意。
代替アプローチのひとつは、バーション番号の不一致を PKCS-1 formatting エラーとして扱い、その premaster secret を完全に乱雑化することである。:
48 random byte の string R を生成する
そのメッセージを plaintext M を復元するために復号する
PKCS#1 padding が不正であるか、あるいは、メッセージ M の長さが明示的に 48 byte ではない場合:
pre_master_secret = R
else If ClientHello.client_version <= TLS 1.0 かつバージョン番号チェックが明示的に不能とされている:
premaster secret = M
else If M[0..1] != ClientHello.client_version:
premaster secret = R
else:
premaster secret = Mこの construction に対する実践的な攻撃は、知られていないが、Klima ら [KPR03] は、いくつかの論理的な攻撃を記述している。それゆえ、記述された最初の construction が、推奨される(RECOMMENDED)。
いずれにせよ、TLS サーバは、RSA で暗号化された premaster secret メッセージが失敗するのを処理する場合、あるいは、そのバーション番号が期待したものではない場合、アラートを生成してはならない(MUST NOT)。代わりに、ランダムに生成された premaster secret と共にそのハンドシェイクを続けなければならない(MUST)。トラブルシューティング目的用に失敗の真の原因(real cause)を記録する(log)ことは、有用である可能性がある。; しかし、その情報を(例えば、タイミング、ログファイルもしくは他のチャネルを通じて)攻撃者に洩らすことを避ける注意をはらう必要がある。
[PKCS1] に定義された RSAES-OAEP 暗号化スキームは、Bleichenbacher 攻撃に対して、よりセキュアである。しかし、以前のバーションの TLS との最大限の互換性のために、この仕様は、RSAES-PKCS1-v1_5 スキームを使う。Bleichenbacher 攻撃の流派(variant)の存在は、上記の推奨事項に従っているとしたら、知られていない。
実装上の注意: Public-key-encrypted データは、opaque ベクトル <0..2^16-1> (4.7 節を参照)として表現される。それゆえ、ClientKeyExchange 中の RSA-encrypted PreMasterSecret は、2 length bytes によって先行される。こららの bytes は、RSA の場合、EncryptedPreMasterSecret は、ClientKeyExchange 中の唯一のデータであり、それゆえ、その長さは、明白に(unambiguously)決定される可能性があるので、冗長となる。SSL v3 仕様は、public-key-encrypted データの符号化について、明確でなかった。それゆえ、多くの SSLv3 実装は、その長さの bytes を含まない。(それらは、その RSA-encrypted データを、直接、ClientKeyExchange メッセージ中に符号化する。)
この仕様は、長さのバイトで完成する EncryptedPreMasterSecret の正しい符号化を要する。結果としての PDU は、多くの SSLv3 実装と互換性が無い。SSLv3 からアップグレードする実装者は、正しい encoding を生成し、受領するように、自身の実装を改変しなければならない(MUST)。SSLv3 および TLS の両方と互換性があることを望む実装者は、彼らの実装のふるまいを、そのプロトコルバーションに依拠するようにする必要がある。
実装上の注意: 「TLS 上の remote timing-based 攻撃は、少なくとも、そのクライアントおよびサーバが同一の LAN 上に在るとき、可能であること」が知られている。したがって、static RSA 鍵を使う実装は、[TIMING] に記述されているように、RSA blinding もしくは何らかの他の anti-timing テクニックを使わなければならない(MUST)。
7.4.8. 証明書 Verify Englishこのメッセージの意味:
この構造体は、これが既にクライアントの証明書中に含まれていなかった場合、そのクライアントの Diffie-Hellman public 値 (Yc) を運ぶ。Yc 用に使われる符号化は、挙げられた PublicValueEncoding によって判定される。この構造体は、クライアント鍵交換メッセージの流派(variant)であり、それ自体の中のメッセージではない。
このメッセージの構造体:
enum { implicit, explicit } PublicValueEncoding;
implicitそのクライアントが、適切な Diffie-Hellman 鍵(fixed_dh クライアント認証用)を含む証明書を送った場合、Yc は、implicit であり、再送されることを必要としない。この場合、クライアント鍵交換メッセージは、送られるが、それは、空でなければならない(MUST)。
explicitYc が送られる必要がある。
struct { select (PublicValueEncoding) { case implicit: struct { }; case explicit: opaque dh_Yc<1..2^16-1>; } dh_public; } ClientDiffieHellmanPublic;dh_Ycそのクライアントの Diffie-Hellman public 値 (Yc)。
7.4.9. Finished Englishいつこのメッセージが送られるか?:
このメッセージは、明示的なクライアント証明書の検証を提供するために使われる。このメッセージは、署名能力をもつクライアント証明書に従ってのみ送られる。(すなわち、すべての証明書が定数の Diffie-Hellman パラメータを納めるものと期待する。)送られるとき、これは、ただちに、そのクライアント鍵交換メッセージに追随しなければならない(MUST)。
このメッセージの構造体:
struct { digitally-signed struct { opaque handshake_messages[handshake_messages_length]; } } CertificateVerify;ここで、handshake_messages は、クライアント hello から始まって、このメッセージを含まない直前までに送受信されるすべてのハンドシェイクメッセージを言い、ハンドシェイクメッセージの種別と長さのフィールドが含まれる。これは、(7.4 節中に規定されているように)それまでに交換された、すべてのハンドシェイク構造体の連結である。「これは、そのメッセージをバッファするか、あるいは、CertificateVerify 計算の時間までの、すべての潜在的なハッシュアルゴリズムについて、動作するハッシュを計算するか、の両面を要すること」に注意。サーバは、CertificateRequest メッセージ中にダイジェストアルゴリズムの限定された集合を提供することによって、この計算費用を最小化できる。
署名において使われるハッシュアルゴリズムおよび署名アルゴリズムは、CertificateRequest メッセージの supported_signature_algorithms フィールド中にあるもののひとつでなければならない(MUST)。さらに、そのハッシュアルゴリズムおよび署名アルゴリズムは、クライアントのエンド主体証明書中の鍵と互換性がなければならない(MUST)。RSA 鍵は、証明書中の制約(かあれば、それ)の対象となり、あらゆる許容されるハッシュアルゴリズムと共に使われる可能性がある(MAY)。
DSA 署名は、ハッシュアルゴリズムの、いかなる secure indication も含まないので、複数のハッシュが、あらゆる鍵と共に使われる可能性がある場合、ハッシュ substitution のリスクが存在する。現在、DSA [DSS] は、SHA-1 と共にのみ使われる可能性がある。将来のバージョンの DSS [DSS-3] には、DSS と共に他のダイジェストアルゴリズムの利用を許可することが期待されると共に、「どのダイジェストアルゴリズムが、各鍵長と共に使われる必要があるか?」に関するガイダンスが期待される。さらに、将来のバージョンの [PKIX] は、「どのダイジェストアルゴリズムが DSA と共に使われるものであるか?」を示すための証明書についてのメカニズムを規定する可能性がある。
いつこのメッセージが送られるか?:
Finished メッセージは、常に、「その鍵交換と認証(authentication)プロセスが成功したこと」を検証するために、change cipher spec メッセージの直後に送られる。「change cipher spec メッセージが他方のハンドシェイクメッセージと Finished メッセージの間で受信されること」が肝要である。
このメッセージの意味:
Finished メッセージは、交渉されたばかりのアルゴリズム、鍵および secrets で防護された最初のものである。Finished メッセージの受信者は、「そのコンテンツは、正しいこと」を検証しなければならない(MUST)。ひとたび、一方がその Finished メッセージを送信し、Finished メッセージをその相方から受信し検証すると、これは、アプリケーションデータを、そのコネクション越しに送受信することを開始する可能性がある。
このメッセージの構造体:
struct { opaque verify_data[verify_data_length]; } Finished;verify_data PRF(master_secret, finished_label, Hash(handshake_messages)) [0..verify_data_length-1];finished_labelクライアントによって送られた Finished メッセージ用には "client finished" という文字列。サーバによって送信された Finished メッセージ用には、"server finished"という文字列。
ハッシュは、ハンドシェイク メッセージ のハッシュを言う。5 章中に規定されている PRF について、そのハッシュは、その PRF についての基礎として使われたハッシュでなければならない(MUST)。異なる PRF を規定しているあらゆる cipher suite は、また、Finished 計算において利用するハッシュを定義しなければならない(MUST)。
以前のバーションの TLS において、verify_data の長さは、常に 12 octet であった。現在のバーションの TLS において、これは、その cipher suite に依存する。verify_data_length を明示的に規定しないあらゆる cipher suite は、12 と等しい verify_data_length をもつ。これは、すべての 存在する cipher suites を含む。「この表現は、以前のバーションと同一の符号化がなされていること」に注意。将来の cipher suites は、他の長さを規定する可能性がある(MAY)が、このような長さは、少なくとも 12 byte なければならない(MUST)。
ハンドシェイク_メッセージ
このハンドシェイク(いかなる HelloRequest メッセージを含まない)中のすべてのメッセージから、このメッセージまで(ただし、これを含まない)のすべてのデータ。これは、ハンドシェイク層において見ることができる唯一のデータであり、レコード層ヘッダを含まない。これは、7.4 節, 中に定義されているように、 これまでに交換されたすべてのハンドシェイク構造体の連結(concatenation)である。
これは、Finished メッセージが、そのハンドシェイクにおける適切な時点において、ChangeCipherSpec メッセージによって先行されない場合、fatal エラーである。
handshake_messages という値は、ClientHello に始まり、すべてのハンドシェイクメッセージまで含むが、この Finished メッセージは含まない。これは、7.4.8 節 中の handshake_messages とは異なる可能性がある。なぜならば、これは、CertificateVerify メッセージ(が送られた場合、これ)を含むからである。また、 クライアントによって送られた Finished メッセージ用の handshake_messages は、サーバによって送信される Finished メッセージ 用のものとは異なる。なぜならば、2 番目に送られたものは、以前のものを含むからである。
注: ChangeCipherSpec メッセージ、アラートおよび、いかなる他のレコード種別は、ハンドシェイクメッセージではなく、そのハッシュ計算には含まれない。また、HelloRequest メッセージは、ハンドシェイクハッシュから省略される。