
[13] [DFN[Opportunistic Security for HTTP/2]] は、
[CODE(URI)@en[http:]] [[URL]] によって表され、本来なら[[素のHTTP]]で行われるべき
[[HTTP]] アクセスを、 [[HTTPS]] ([[HTTP/2]] over [[TLS]]) [[転送路]]を使って行うものです。

;; [14] [[プロトコル]]としては同じ [[HTTPS]] であっても、
[CODE(URI)@en[https:]] [[URL]] によって表される [[HTTPS]]
アクセスとは、異なるものです。本手法を使っても、 ([CODE(URI)@en[https:]]
[[URL]] によって表される [[HTTPS]] アクセスで防げる) すべての攻撃を防げるわけではありません。

* 代替

[18] [[HTTPS]] を使うべきです。

* 仕様書

[REFS[
- [12] [CITE@en[RFC 8164 - Opportunistic Security for HTTP/2]] ([TIME[2017-05-11 15:47:35 +09:00]]) <https://tools.ietf.org/html/rfc8164>
]REFS]

* プロトコル

[29] 本機能は [[HTTP]] の[[代替サービス]]を使っています。

;; 一般的な事項は[[代替サービス]]参照。

** 代替サービス広告

[19] [[起源サーバー]]は、
プロトコルの識別子を[[代替サービス]]として[[広告]]します。
ここで、[[プロトコル]]は、 [[TLS]] を使うもの (例えば [CODE[h2][HTTP/2]]) とします。
[[プロトコル]]は、[[資源]]の [[scheme][URL scheme]] を明示的に示すものでなければ[MUST[なりません]]。 [SRC[>>12]]

;; [20] [[HTTP/1.1]] は[[要求対象]]に[[絶対URL]]を指定することを認めてはいますが、
([[プロキシサーバー]]ではなく) [[起源サーバー]]に対して指定することは認めていませんので、
該当しません [SRC[>>12]]。

;; [27] [[代替サービス]]のプロトコルの識別子は、 [[ALPN]] の識別子です。
原則として [[TLS]] 上の[[プロトコル]]を表していますが、
[CODE[h2c]] のようにそうでないものもあり、ここでの条件に合致しないことになります。
[CODE[ftp]] のように [[URL]] を指定できない[[プロトコル]]も、
[[scheme][URL scheme]] を明示するとの条件に合致しません。

[21] [[クライアント]]は、そのような[[代替サービス]]の[[広告]]を受信したら、
以後その[[起源]]への[[要求]]を指定された[[代替サービス]]経由で送信して構いません。
[SRC[>>12]]

[23] [[クライアント]]は、[[代替サービス]]の接続の準備が完了するまで、
[[要求]]の送信を遅延させることができます。その場合、接続に失敗したら、
通常の[[平文]]の接続で送信することになります。 [SRC[>>12]]

;; [28] [[代替サービス]]の接続の失敗は [[downgrade attack]] 
の可能性もあり、注意するべきことが[[代替サービス]]の仕様で注意喚起されています。
[[代替サービス]]参照。

[22] [[クライアント]]は、まず [CODE[OPTIONS]] 
[[要求]]のような繊細な情報が少ない[[要求]]を送信して、
[[代替サービス]]が無いか確認することもできます。 [SRC[>>12]]

[24] [[クライアント]]は、既知の[[代替サービス]]の[[満期]]が近い時、
[CODE[OPTIONS]] [[要求]]のようなものを予め送信しておき、
[[代替サービス]]情報を更新することもできます。 [SRC[>>12]]

-*-*-

[51] [[代替サービス]]の[[広告]]は[[素のHTTP]]で送受信されますから、改竄の可能性があります。
例えば [CODE[Alt-Svc:]] [[ヘッダー]]を削除することで、 [[downgrade attack]]
が可能です [SRC[>>12]]。

** TLS ハンドシェイク

[25] [[クライアント証明書]]は、意味を持ちません。
[[クライアント]]は、
[[クライアント証明書]]を指定しては[MUST[なりません]]。 [SRC[>>12]]

[26] [[サーバー]]は、同じ[[ポート]]で [CODE(URI)@en[https:]] も提供する場合に、
[[証明書要求]]することができます。
しかし、[[クライアント]]が[[証明書]]を提供しない場合にも、
[[ハンドシェイク][TLSハンドシェイク]]を[RUBYB[中断]@en[abort]]しては[MUST[なりません]]。 [SRC[>>12]]

[30] [[代替サービス]]における「[[十分な保証]]」は、[[HTTPSサーバー認証]]を使うことによります。
[[クライアント]]は、
[[HTTPSサーバー認証]]により[[サーバー証明書]]が[[要求]]の[[起源]]について妥当である場合を除き、
当該接続で[[要求]]を送信しては[MUST[なりません]]。 [SRC[>>12]]

;; [52] [[TLS]] で定められた[[サーバー証明書]]の検証や[[HTTPSサーバー認証]]を正しく行わないと、
正しい相手と通信しているかを確認できません。
例えば[[平文]]で送信された[[代替サービス]]の[[広告]]が改竄されている場合、
悪意ある第三者のサーバーに接続してしまっても気づけません。

** 最初の要求

[31] [[クライアント]]は、
まず[[要求]]の[[起源]]に関して[[妥当な「[CODE[http-opportunistic]]」応答]]を得なければ[MUST[なりません]]。
[SRC[>>12]]

[35] [[起源]]について[DFN[[RUBYB[妥当な「[CODE[http-opportunistic]]」応答を持つ]@en[have a valid "[CODE[http-opportunistic]]" response]]]]とは、
次の条件を満たすことをいいます。 [SRC[>>12]]

[FIG(list)[
- [36] 認証を経た接続で、
[[クライアント]]が [DFN[[CODE[/.well-known/http-opportunistic]]]]
に[[要求]]を送信し、
- [37] それに対する[[応答]]の[F[状態][状態符号]]が [CODE[200]] であり、
- [38] その[[応答]]が[[新鮮]]であり (必要なら[[再検証]]可)、
- [39] その[[応答]]の[[MIME型]]が [CODE(MIME)@en[application/json]] であり、
- [40] その[[応答]]の [[payload]] が [[RFC 7159]] [[JSON]] であり、
- [41] その [[JSON]] の[[根]]が[[配列]]であり、
- [42] その[[配列]]に、[[起源]]の [[RFC 6454]] [[Unicode直列化]]と[[大文字・小文字不区別]]で一致する[[文字列]]が含まれる
]FIG]

;; [43] [[大文字・小文字不区別]]が具体的にどのような[[比較]]によるものかは不明です。

[44] ([[配列]]に?) 含まれる値が[[文字列]]でない時、[[非妥当]]として構いません。 [SRC[>>12]]

;; [45] [CODE[[[https:]]//...[[/.well-known/http-opportunistic]]]] や、
[[配列]]に [CODE(URI)@en[https:]] の[[起源]]が含まれる場合の[[意味]]は、
定義されていません。 [SRC[>>12]]

[46] [[新鮮]]であるとの条件が暗示する通り、[[HTTPキャッシュ]]の利用が認められています。
したがって、すべての[[代替サービス]]が 
[CODE[[[http:]]//...[[/.well-known/http-opportunistic]]]] 
に[[応答]]できる必要があります [SRC[>>12]]。
[[クライアント]]は、当該[[代替サービス]]から
[CODE[[[http:]]//...[[/.well-known/http-opportunistic]]]] 
を取得せずとも ([[キャッシュ][HTTPキャッシュ]]を使って) 
すぐに利用できます [SRC[>>12]]。

[47] [[クライアント]]は、認証されていない接続を使って得た
[CODE[[[http:]]//...[[/.well-known/http-opportunistic]]]] 
の[[キャッシュ][HTTPキャッシュ]]を使っては[MUST[なりません]] [SRC[>>12]]。

;; [48] ということは、[[HTTPキャッシュ]]の[[蓄積された応答]]は[[代替サービス]]経由の[[応答]]かどうかの情報を保持する必要があります。

[49] [[クライアント]]は、認証されていない接続を使って得た
[CODE[[[http:]]//...[[/.well-known/http-opportunistic]]]] 
が[[キャッシュ][HTTPキャッシュ]]にあっても、消去しなければ[MUST[なりません]]。
認証されていない接続の[[応答]]を認証された接続で[[再検証]]したところで、
[[応答]]の[[一貫性]]は保てません。 [SRC[>>12]]

[53] 
[CODE[[[http:]]//...[[/.well-known/http-opportunistic]]]] 
の検査が必要なのは、
従来 [[HTTPS]] でアクセスされた時 [CODE(URI)@en[https:]] のアクセスとみなして[[応答]]を返す運用がなされてきたため、
真に [[Opportunistic HTTP/2 Security]] を意図した[[サーバー]]かどうかを確認するためです
[SRC[>>12]]。

;; [54] 長年そのように運用されてきて本来そのままで問題なかった前提を変えてしまった
[[Opportunistic HTTP/2 Security]] が技術的に筋悪な気がしますが。

** 接続の利用

[32] [[クライアント]]は、
同じ[[接続][HTTP接続]]に異なる[[起源]]の[[要求]]を送信しては[MUST[なりません]]。
[SRC[>>12]]

[EG[
[33] [CODE(URI)@en[http:]] と [CODE(URI)@en[https:]] とで[[接続][HTTP接続]]を共有することはできません
[SRC[>>12]]。
]EG]

[EG[
[34] 接続先[[代替サービス]]が同じだとしても、
異なる[F[ホスト]]の [[URL]] への[[要求]]で[[接続][HTTP接続]]を共有することはできません。
]EG]

* 批判

[16] 中途半端な[[セキュリティー]]しか提供できない本技術は
[[HTTPS]] への移行を遅らせるものだとして、
好ましくないと考える人もいます。

* 利用者インターフェイス

[50] [CODE(URI)@en[http:]] [[URL]] の[[応答]]を [[TLS]] 経由で受け取っても、
[CODE(URI)@en[https:]] のような[[セキュリティー]]の表示を行っては[MUST[なりません]]。 [SRC[>>12]]

* 実装

[15] [[Firefox]] が実装しています。

[17] 他の [[Webブラウザー]]が実装するかどうかは不明です。

* 歴史

[1] [CITE@en[draft-ietf-httpbis-http2-encryption-01 - Opportunistic Security for HTTP]]
([TIME[2015-04-24 04:11:58 +09:00]] 版)
<https://tools.ietf.org/html/draft-ietf-httpbis-http2-encryption-01>

[FIG(quote)[
[FIGCAPTION[
[2] [CITE@en[meetings/04-21-minutes.md at gh-pages · w3ctag/meetings]]
([TIME[2015-05-06 15:35:03 +09:00]] 版)
<https://github.com/w3ctag/meetings/blob/gh-pages/2015/04-sfo/04-21-minutes.md>
]FIGCAPTION]

> Mark: Only Mozilla is implementing Opportunistic Encryption '''['''not shipped it''']'''
> Alex: '''['''We on the Chrome team are adamently against Opportunistic Encryption because it doesn't solve any problems''']'''
> Mark: The IETF is generally enthusiastic about Opportunistic Security
> Mark: The W3C is much less excited about Opportunistic Security

]FIG]


[3] [CITE@en[draft-ietf-httpbis-http2-encryption-04 - Opportunistic Security for HTTP]]
([TIME[2016-03-17 20:22:27 +09:00]] 版)
<https://tools.ietf.org/html/draft-ietf-httpbis-http2-encryption-04>

[4] [CITE@en[draft-ietf-httpbis-http2-encryption-07 - Opportunistic Security for HTTP]]
([TIME[2016-10-26 22:24:53 +09:00]])
<https://tools.ietf.org/html/draft-ietf-httpbis-http2-encryption-07>

[5] [CITE@en[RFC 8164 - Opportunistic Security for HTTP/2]]
([TIME[2017-05-11 14:53:24 +09:00]])
<https://tools.ietf.org/html/rfc8164>

[6] [CITE@en[1301117 - Update Opportunistic Security for HTTP]]
([TIME[2017-05-11 15:54:14 +09:00]])
<https://bugzilla.mozilla.org/show_bug.cgi?id=1301117>

[7] [CITE@en[1003448 - http/2 alt-svc support]]
([TIME[2017-05-11 16:04:15 +09:00]])
<https://bugzilla.mozilla.org/show_bug.cgi?id=1003448>

[8] [CITE@en[1172615 - opportunistic encryption potentially perturbing certificate verification telemetry]]
([TIME[2017-05-11 16:05:57 +09:00]])
<https://bugzilla.mozilla.org/show_bug.cgi?id=1172615>

[9] [CITE@en[1148885 - Opportunistic Encryption does not work with HTTP/2 proxy]]
([TIME[2017-05-11 16:06:42 +09:00]])
<https://bugzilla.mozilla.org/show_bug.cgi?id=1148885>

[10] [CITE@en[742610 - Remove opportunistic caching support from nsHttpChannel]]
([TIME[2017-05-11 16:07:06 +09:00]])
<https://bugzilla.mozilla.org/show_bug.cgi?id=742610>

[11] [CITE@en[1148328 - (CVE-2015-0799) Server certificate verification bypass with Alt-Svc]]
([TIME[2017-05-11 16:07:53 +09:00]])
<https://bugzilla.mozilla.org/show_bug.cgi?id=1148328>