[2] [DFN[[[closure alert]]]] は、 [[TLS]] の[[接続]]を閉じることを表す[[メッセージ]]です。
[CODE[[[AlertDescription]]]] の値 [DFN[[CODE[[[close_notify]]]]]] ([CODE[[[0]]]]) は、
[[closure alert]] を表します。

* 仕様書

[REFS[
- [1] [CITE@en[RFC 5246 - The Transport Layer Security (TLS) Protocol Version 1.2]] ([TIME[2015-02-19 08:58:15 +09:00]] 版) <http://tools.ietf.org/html/rfc5246#section-7.2.1>
]REFS]

* プロトコル

[3] [[クライアント]]と[[鯖]]は、[[truncation attack]] の防止のため、
[[接続]]を終える旨を共有しなければなりません [SRC[>>1]]。
[[closure alert]] ([CODE[[[AlertDescription]]]] = [CODE[[[close_notify]]]] ([CODE[[[0]]]])
の[[メッセージ]]) をこれに用います。他の [[fatal alert]]
を転送した場合を除き、[[クライアント]]や[[鯖]]は、[[接続]]の書き込み側を閉じる前に
[CODE[[[close_notify]]]] [[alert]] を送信する必要があります [SRC[>>1]]。

[6] [CODE[[[close_notify]]]] [[alert]] は、送信者が当該[[接続]]においてそれ以上は[[メッセージ]]を送らないことを意味します
[SRC[>>1]]。[[クライアント]]と[[鯖]]のどちらから送信しても構いません
[SRC[>>1]]。

[5] [[closure alert]] より後に受信したデータは、無視します [SRC[>>1]]。

[7] [[closure alert]] を受信したら、 [CODE[[[close_notity]]]] [[alert]]
を返送すると共に、直ちに[[接続]]を閉じ、書き残したものがあれば捨てなければ[['''なりません''']] [SRC[>>1]]。

[8] [CODE[[[close_notify]]]] を先に送った側は、返送の到着を待たずに[[接続]]の読み込み側を閉じて構いません [SRC[>>1]]。
[[TLS]] を使う[[応用プロトコル]]が [[TLS]] が閉じられた後に下位の[[輸送路]]を使ってデータを転送する場合には、
[[TLS]] の[[接続]]が閉じられたと[[応用プロトコル]]側に通知するのは
[CODE[[[close_notify]]]] [[alert]] が返送された後としなければなりません [SRC[>>1]]。
[[応用プロトコル]]がそれ以上データを転送せずに下位の[[輸送路]]を閉じるだけの場合には、
[CODE[[[close_notify]]]] [[alert]] の返送を待たずとも構いません [SRC[>>1]]。

[4] [[接続]]を正しく閉じることに失敗しても、[[TLSセッション]]を[[再開]]することを妨げるものではありません [SRC[>>1]]。

;; [12] これは [[TLS/1.0]] から [[TLS/1.1]] での仕様変更 [SRC[>>1]] ですが、
それ以前から既にそのような実装がなされていた [SRC[>>1]] ようです。

;; [13] [[error alert]] の場合は、[[TLSセッション]]の[[再開]]は禁止されています。

[11] [[alert level]] は [[closure alert]] では無視されるようです。

* 応用

[9] [[アプリケーション層プロトコル]]は、 [[TLS]] を使う場合に [[closure alert]]
との関係 (どのタイミングで [[closure alert]] を送信するのか、 [[closure alert]]
を受信した場合に[[アプリケーション層プロトコル]]側でどうエラー処理するのか、
[[TLS]] より下の層の[[プロトコル]]の[[接続]]を閉じるタイミングなど)
を規定する必要があります。

;; [10] 例えば [[RFC 2818]] は [[HTTPS]] における取り扱いを規定しています。

[FIG(quote)[
[FIGCAPTION[
[14] [CITE[Issue 244260 - chromium - Security: TLS Truncation attack on HTTP headers, including cookie flags - An open-source project to help move the web forward. - Google Project Hosting]]
([TIME[2015-07-04 16:53:26 +09:00]] 版)
<https://code.google.com/p/chromium/issues/detail?id=244260>
]FIGCAPTION]

> Requiring close_notify isn't possible because so many sites don't send it

]FIG]


[FIG(quote)[
[FIGCAPTION[
[15] [CITE[Issue 244260 - chromium - Security: TLS Truncation attack on HTTP headers, including cookie flags - An open-source project to help move the web forward. - Google Project Hosting]]
([TIME[2015-07-04 16:55:54 +09:00]] 版)
<https://code.google.com/p/chromium/issues/detail?id=244260>
]FIGCAPTION]

> However, like all other browsers, it doesn't implement the mandatory TLS closure alert enforcement from TLS 1.1 to prevent truncation attacks at the transport layer.

]FIG]


[FIG(quote)[
[FIGCAPTION[
[16] [CITE[SSL / TLS: Is a server always required to respond to a close notify? - Information Security Stack Exchange]]
([TIME[2015-09-07 11:27:14 +09:00]] 版)
<http://security.stackexchange.com/questions/82028/ssl-tls-is-a-server-always-required-to-respond-to-a-close-notify>
]FIGCAPTION]

> For example, https://www.oracle.com sends the close notify as I expect it, but https://www.google.com does not - it just closes the connection after my app sends the close notify.

]FIG]


[FIG(quote)[
[FIGCAPTION[
[17] [CITE[SSL / TLS: Is a server always required to respond to a close notify? - Information Security Stack Exchange]]
([TIME[2015-09-07 11:27:14 +09:00]] 版)
<http://security.stackexchange.com/questions/82028/ssl-tls-is-a-server-always-required-to-respond-to-a-close-notify>
]FIGCAPTION]

> OpenSSL, and thus implementations based on OpenSSL (clients and server), tend to no longer send close_notify messages; they just drop the connection. The main reason is that in existing Web servers and clients, connections are managed in a pool that closes them after some inactivity delay; that pool manages low-level sockets and has no notion of what SSL could be; thus, the SSL layer has no way to send (or wait for) an explicit close_notify.

]FIG]

[18] [[Chrome]] と [[IE]] は、正常時も異常時も、 alert を送らないで [[TCP接続]]を閉じるようです。 [TIME[2015-09-07T04:31:50.900Z]]

[19] [[Firefox]] は正常時は [CODE[[[close_notify]]]]、異常時は適当なエラーの alert
を送って閉じるようです。
相手の [[TLS]] alert は待たずに[[TCP]]を閉じるようです。 [TIME[2015-09-07T04:32:27.700Z]]


[FIG(quote)[
[FIGCAPTION[
[20] [CITE[tls - how can i bypass close_notify in ssl in firefox? - Information Security Stack Exchange]]
([TIME[2015-09-26 23:02:22 +09:00]] 版)
<http://security.stackexchange.com/questions/63719/how-can-i-bypass-close-notify-in-ssl-in-firefox>
]FIGCAPTION]

> Both GnuTLS and CDSA (Adium's SSL plugin) check whether a TLS connection has been closed properly by checking if the server sent a  close_notify alert first. '''['''https://bugzilla.mozilla.org/show_bug.cgi?id=508698 NSS doesn't''']'''. If that alert wasn't sent, GnuTLS and CDSA consider it a fatal error, which for the HTTPS handler means the response is completely discarded. That's what's happening here with Yahoo: their HTTPS server closes the connection without sending close_notify first.

]FIG]


[21] [CITE@en[508698 – SSL_SecureRecv returns 0 rather than an error if the peer closes the TCP connection without sending an SSL close_notify alert]]
([TIME[2015-09-26 23:05:57 +09:00]] 版)
<https://bugzilla.mozilla.org/show_bug.cgi?id=508698>

[22] [CITE@en[/docs/manmaster/man3/SSL_CTX_set_quiet_shutdown.html]]
([[OpenSSL Foundation, Inc.]]著, [TIME[2018-09-30 23:53:59 +09:00]])
<https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_quiet_shutdown.html>