QUIC: Update SSL_shutdown manpage

Fixes https://github.com/openssl/project/issues/138

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/21618)
This commit is contained in:
Hugo Landau 2023-08-01 16:51:16 +01:00
parent 1875642c89
commit 51b2a670c8
3 changed files with 278 additions and 132 deletions

View File

@ -93,6 +93,14 @@ are buffered bytes available for immediate retrieval.
In this case the read function can be called without blocking or actually
receiving new data from the underlying socket.
When used with a QUIC SSL object, calling an I/O function such as SSL_read()
allows internal network event processing to be performed. It is important that
this processing is performed regularly. If an application is not using thread
assisted mode, an application should ensure that an I/O function such as
SSL_read() is called regularly, or alternatively ensure that SSL_handle_events()
is called regularly. See L<openssl-quic(7)> and L<SSL_handle_events(3)> for more
information.
=head1 RETURN VALUES
SSL_read_ex() and SSL_peek_ex() will return 1 for success or 0 for failure.

View File

@ -21,155 +21,284 @@ SSL_shutdown, SSL_shutdown_ex - shut down a TLS/SSL or QUIC connection
=head1 DESCRIPTION
SSL_shutdown() shuts down an active TLS/SSL connection. It sends the
close_notify shutdown alert to the peer.
SSL_shutdown() tries to send the close_notify shutdown alert to the peer.
Whether the operation succeeds or not, the SSL_SENT_SHUTDOWN flag is set and
a currently open session is considered closed and good and will be kept in the
session cache for further reuse.
Note that SSL_shutdown() must not be called if a previous fatal error has
occurred on a connection i.e. if SSL_get_error() has returned SSL_ERROR_SYSCALL
or SSL_ERROR_SSL.
The shutdown procedure consists of two steps: sending of the close_notify
shutdown alert, and reception of the peer's close_notify shutdown alert.
The order of those two steps depends on the application.
It is acceptable for an application to only send its shutdown alert and
then close the underlying connection without waiting for the peer's response.
This way resources can be saved, as the process can already terminate or
serve another connection.
This should only be done when it is known that the other side will not send more
data, otherwise there is a risk of a truncation attack.
When a client only writes and never reads from the connection, and the server
has sent a session ticket to establish a session, the client might not be able
to resume the session because it did not received and process the session ticket
from the server.
In case the application wants to be able to resume the session, it is recommended to
do a complete shutdown procedure (bidirectional close_notify alerts).
When the underlying connection shall be used for more communications, the
complete shutdown procedure must be performed, so that the peers stay
synchronized.
SSL_shutdown() only closes the write direction.
It is not possible to call SSL_write() after calling SSL_shutdown().
The read direction is closed by the peer.
The behaviour of SSL_shutdown() additionally depends on the underlying BIO.
If the underlying BIO is B<blocking>, SSL_shutdown() will only return once the
handshake step has been finished or an error occurred.
If the underlying BIO is B<nonblocking>, SSL_shutdown() will also return
when the underlying BIO could not satisfy the needs of SSL_shutdown()
to continue the handshake. In this case a call to SSL_get_error() with the
return value of SSL_shutdown() will yield B<SSL_ERROR_WANT_READ> or
B<SSL_ERROR_WANT_WRITE>. The calling process then must repeat the call after
taking appropriate action to satisfy the needs of SSL_shutdown().
The action depends on the underlying BIO. When using a nonblocking socket,
nothing is to be done, but select() can be used to check for the required
condition. When using a buffering BIO, like a BIO pair, data must be written
into or retrieved out of the BIO before being able to continue.
After SSL_shutdown() returned 0, it is possible to call SSL_shutdown() again
to wait for the peer's close_notify alert.
SSL_shutdown() will return 1 in that case.
However, it is recommended to wait for it using SSL_read() instead.
SSL_shutdown() can be modified to only set the connection to "shutdown"
state but not actually send the close_notify alert messages,
see L<SSL_CTX_set_quiet_shutdown(3)>.
When "quiet shutdown" is enabled, SSL_shutdown() will always succeed
and return 1.
Note that this is not standard compliant behaviour.
It should only be done when the peer has a way to make sure all
data has been received and doesn't wait for the close_notify alert
message, otherwise an unexpected EOF will be reported.
There are implementations that do not send the required close_notify alert.
If there is a need to communicate with such an implementation, and it's clear
that all data has been received, do not wait for the peer's close_notify alert.
Waiting for the close_notify alert when the peer just closes the connection
will result in an error being generated.
The error can be ignored using the B<SSL_OP_IGNORE_UNEXPECTED_EOF>.
For more information see L<SSL_CTX_set_options(3)>.
SSL_shutdown() shuts down an active connection represented by an SSL object.
SSL_shutdown_ex() is an extended version of SSL_shutdown(). If non-NULL, I<args>
must point to a B<SSL_SHUTDOWN_EX_ARGS> structure and I<args_len> must be set to
C<sizeof(SSL_SHUTDOWN_EX_ARGS)>. The B<SSL_SHUTDOWN_EX_ARGS> structure must be
zero-initialized. If I<args> is NULL, the behaviour is the same as passing a
zero-initialised B<SSL_SHUTDOWN_EX_ARGS> structure. When used with a non-QUIC
SSL object, the arguments are ignored and the call functions identically to
SSL_shutdown().
zero-initialised B<SSL_SHUTDOWN_EX_ARGS> structure. Currently, all extended
arguments relate to usage with QUIC, therefore this call functions identically
to SSL_shutdown() when not being used with QUIC.
When used with a QUIC connection SSL object, SSL_shutdown_ex() initiates a QUIC
immediate close. The I<quic_error_code> field can be used to specify a 62-bit
application error code to be signalled via QUIC. The value specified must be in
the range [0, 2**62-1], else this call fails. I<quic_reason> may optionally
specify a zero-terminated reason string to be signalled to the peer. If a reason
is not specified, a zero-length string is used as the reason. The reason string
is copied and need not remain allocated after the call to the function returns.
Reason strings are bounded by the path MTU and may be silently truncated if they
are too long to fit in a QUIC packet. The arguments are only used on the first
call to SSL_shutdown_ex() for a given QUIC connection SSL object.
While the general operation of SSL_shutdown() is common between protocols, the
exact nature of how a shutdown is performed depends on the underlying protocol
being used. See the section below pertaining to each protocol for more
information.
When using QUIC, how an application uses SSL_shutdown() or SSL_shutdown_ex() has
implications for whether QUIC closes a connection in an RFC-compliant manner.
For discussion of these issues, and for discussion of the I<flags> argument, see
B<QUIC-SPECIFIC SHUTDOWN CONSIDERATIONS> below.
In general, calling SSL_shutdown() in nonblocking mode will initiate the
shutdown process and return 0 to indicate that the shutdown process has not yet
completed. Once the shutdown process has completed, subsequent calls to
SSL_shutdown() will return 1. See the RETURN VALUES section for more
information.
=head2 First to close the connection
SSL_shutdown() should not be called if a previous fatal error has occurred on a
connection; i.e., if L<SSL_get_error(3)> has returned B<SSL_ERROR_SYSCALL> or
B<SSL_ERROR_SSL>.
When the application is the first party to send the close_notify
alert, SSL_shutdown() will only send the alert and then set the
SSL_SENT_SHUTDOWN flag (so that the session is considered good and will
be kept in the cache).
If successful, SSL_shutdown() will return 0.
=head1 TLS AND DTLS-SPECIFIC CONSIDERATIONS
If a unidirectional shutdown is enough (the underlying connection shall be
closed anyway), this first successful call to SSL_shutdown() is sufficient.
Shutdown for SSL/TLS and DTLS is implemented in terms of the SSL/TLS/DTLS
close_notify alert message. The shutdown process for SSL/TLS and DTLS
consists of two steps:
In order to complete the bidirectional shutdown handshake, the peer needs
to send back a close_notify alert.
The SSL_RECEIVED_SHUTDOWN flag will be set after receiving and processing
it.
=over 4
The peer is still allowed to send data after receiving the close_notify
event.
When it is done sending data, it will send the close_notify alert.
SSL_read() should be called until all data is received.
SSL_read() will indicate the end of the peer data by returning <= 0
and SSL_get_error() returning SSL_ERROR_ZERO_RETURN.
=item *
=head2 Peer closes the connection
A close_notify shutdown alert message is sent to the peer.
If the peer already sent the close_notify alert B<and> it was
already processed implicitly inside another function
(L<SSL_read(3)>), the SSL_RECEIVED_SHUTDOWN flag is set.
SSL_read() will return <= 0 in that case, and SSL_get_error() will return
SSL_ERROR_ZERO_RETURN.
SSL_shutdown() will send the close_notify alert, set the SSL_SENT_SHUTDOWN
flag.
If successful, SSL_shutdown() will return 1.
=item *
Whether SSL_RECEIVED_SHUTDOWN is already set can be checked using the
SSL_get_shutdown() (see also L<SSL_set_shutdown(3)> call.
A close_notify shutdown alert message is received from the peer.
=back
These steps can occur in either order depending on whether the connection
shutdown process was first initiated by the local application or by the peer.
=head2 Locally-Initiated Shutdown
Calling SSL_shutdown() on a SSL/TLS or DTLS SSL object initiates the shutdown
process and causes OpenSSL to try to send a close_notify shutdown alert to the
peer. The shutdown process will then be considered completed once the peer
responds in turn with a close_notify shutdown alert message.
Calling SSL_shutdown() only closes the write direction of the connection; the
read direction is closed by the peer. Once SSL_shutdown() is called,
L<SSL_write(3)> can no longer be used, but L<SSL_read(3)> may still be used
until the peer decides to close the connection in turn. The peer might
continue sending data for some period of time before handling the local
application's shutdown indication.
SSL_shutdown() does not affect an underlying network connection such as a TCP
connection, which remains open.
=head2 Remotely-Initiated Shutdown
If the peer was the first to initiate the shutdown process by sending a
close_notify alert message, an application will be notified of this as an EOF
condition when calling
L<SSL_read(3)> (i.e., L<SSL_read(3)> will fail and L<SSL_get_error(3)> will
return B<SSL_ERROR_ZERO_RETURN>), after all application data sent by the peer
prior to initiating the shutdown has been read. An application should handle
this condition by calling SSL_shutdown() to respond with a close_notify alert in
turn, completing the shutdown process, though it may choose to write additional
application data using L<SSL_write(3)> before doing so. If an application does
not call SSL_shutdown() in this case, a close_notify alert will not be sent and
the behaviour will not be fully standards compliant.
=head2 Shutdown Lifecycle
Regardless of whether a shutdown was initiated locally or by the peer, if the
underlying BIO is blocking, a call to SSL_shutdown() will return firstly once a
close_notify alert message is written to the peer (returning 0), and upon a
second and subsequent call, once a corresponding message is received from the
peer (returning 1 and completing the shutdown process). Calls to SSL_shutdown()
with a blocking underlying BIO will also return if an error occurs.
If the underlying BIO is nonblocking and the shutdown process is not yet
complete (for example, because a close_notify alert message has not yet been
received from the peer, or because a close_notify alert message needs to be sent
but would currently block), SSL_shutdown() returns 0 to indicate that the
shutdown process is still ongoing; in this case, a call to L<SSL_get_error(3)>
will yield B<SSL_ERROR_WANT_READ> or B<SSL_ERROR_WANT_WRITE>.
An application can then detect completion of the shutdown process by calling
SSL_shutdown() again repeatedly until it returns 1, indicating that the shutdown
process is complete (with a close_notify alert having both been sent and
received).
However, the preferred method of waiting for the shutdown to complete is to use
L<SSL_read(3)> until L<SSL_get_error(3)> indicates EOF by returning
B<SSL_ERROR_ZERO_RETURN>. This ensures any data received immediately before the
peer's close_notify alert is still provided to the application. It also ensures
any final handshake-layer messages received are processed (for example, messages
issuing new session tickets).
If this approach is not used, the second call to SSL_shutdown() (to complete the
shutdown by confirming receipt of the peer's close_notify message) will fail if
it is called when the application has not read all pending application data
sent by the peer using L<SSL_read(3)>.
When calling SSL_shutdown(), the B<SSL_SENT_SHUTDOWN> flag is set once an
attempt is made to send a close_notify alert, regardless of whether the attempt
was successful. The B<SSL_RECEIVED_SHUTDOWN> flag is set once a close_notify
alert is received, which may occur during any call which processes incoming data
from the network, such as L<SSL_read(3)> or SSL_shutdown(). These flags
may be checked using L<SSL_get_shutdown(3)>.
=head2 Fast Shutdown
Alternatively, it is acceptable for an application to call SSL_shutdown() once
(such that it returns 0) and then close the underlying connection without
waiting for the peer's response. This allows for a more rapid shutdown process
if the application does not wish to wait for the peer.
This alternative "fast shutdown" approach should only be done if it is known
that the peer will not send more data, otherwise there is a risk of an
application exposing itself to a truncation attack. The full SSL_shutdown()
process, in which both parties send close_notify alerts and SSL_shutdown()
returns 1, provides a cryptographically authenticated indication of the end of a
connection.
This approach of a single SSL_shutdown() call without waiting is preferable to
simply calling L<SSL_free(3)> or L<SSL_clear(3)> as calling SSL_shutdown()
beforehand makes an SSL session eligible for subsequent reuse and notifies the
peer of connection shutdown.
The fast shutdown approach can only be used if there is no intention to reuse
the underlying connection (e.g. a TCP connection) for further communication; in
this case, the full shutdown process must be performed to ensure
synchronisation.
=head2 Effects on Session Reuse
Calling SSL_shutdown() sets the SSL_SENT_SHUTDOWN flag (see
L<SSL_set_shutdown(3)>), regardless of whether the transmission of the
close_notify alert was successful or not. This makes the SSL session eligible
for reuse; the SSL session is considered properly closed and can be reused for
future connections.
=head2 Quiet Shutdown
SSL_shutdown() can be modified to set the connection to the "shutdown"
state without actually sending a close_notify alert message; see
L<SSL_CTX_set_quiet_shutdown(3)>. When "quiet shutdown" is enabled,
SSL_shutdown() will always succeed and return 1 immediately.
This is not standards-compliant behaviour. It should only be done when the
application protocol in use enables the peer to ensure that all data has been
received, such that it doesn't need to wait for a close_notify alert, otherwise
application data may be truncated unexpectedly.
=head2 Non-Compliant Peers
There are SSL/TLS implementations that never send the required close_notify
alert message but simply close the underlying transport (e.g. a TCP connection)
instead. This will ordinarily result in an error being generated.
If compatibility with such peers is desired, the option
B<SSL_OP_IGNORE_UNEXPECTED_EOF> can be set. For more information, see
L<SSL_CTX_set_options(3)>.
Note that use of this option means that the EOF condition for application data
does not receive cryptographic protection, and therefore renders an application
potentially vulnerable to truncation attacks. Thus, this option must only be
used in conjunction with an application protocol which indicates unambiguously
when all data has been received.
An alternative approach is to simply avoid calling L<SSL_read(3)> if it is known
that no more data is going to be sent. This requires an application protocol
which indicates unambiguously when all data has been sent.
=head2 Session Ticket Handling
If a client application only writes to a SSL/TLS or DTLS connection and never
reads, OpenSSL may never process new SSL/TLS session tickets sent by the server.
This is because OpenSSL ordinarily processes handshake messages received from a
peer during calls to L<SSL_read(3)> by the application.
Therefore, client applications which only write and do not read but which wish
to benefit from session resumption are advised to perform a complete shutdown
procedure by calling SSL_shutdown() until it returns 1, as described above. This
will ensure there is an opportunity for SSL/TLS session ticket messages to be
received and processed by OpenSSL.
=head1 QUIC-SPECIFIC SHUTDOWN CONSIDERATIONS
When using QUIC, SSL_shutdown() or SSL_shutdown_ex() causes any data written to
a stream which has not yet been sent to the peer to be written before the
shutdown process is considered complete. An exception to this is streams which
terminated in a non-normal fashion, for example due to a stream reset; only
streams which are non-terminated or which terminated in a normal fashion have
their pending send buffers flushed in this manner. This behaviour can be skipped
by setting the B<SSL_SHUTDOWN_FLAG_NO_STREAM_FLUSH> flag; in this case, data
remaining in stream send buffers may not be transmitted to the peer. This flag
may be used when a non-normal application condition has occurred and the
delivery of data written to streams via L<SSL_write(3)> is no longer relevant.
When used with a QUIC connection SSL object, SSL_shutdown() initiates a QUIC
immediate close using QUIC B<CONNECTION_CLOSE> frames.
SSL_shutdown() cannot be used on QUIC stream SSL objects. To conclude a stream
normally, see L<SSL_stream_conclude(3)>; to perform a non-normal stream
termination, see L<SSL_stream_reset(3)>.
SSL_shutdown_ex() may be used instead of SSL_shutdown() by an application to
provide additional information to the peer on the reason why a connection is
being shut down. The information which can be provided is as follows:
=over 4
=item I<quic_error_code>
An optional 62-bit application error code to be signalled to the peer. The value
must be in the range [0, 2**62-1], else the call to SSL_shutdown_ex() fails. If
not provided, an error code of 0 is used by default.
=item I<quic_reason>
An optional zero-terminated (UTF-8) reason string to be signalled to the peer.
The application is responsible for providing a valid UTF-8 string and OpenSSL
will not validate the string. If a reason is not provided, or SSL_shutdown() is
used, a zero-length string is used as the reason. If provided, the reason string
is copied and stored inside the QUIC connection SSL object and need not remain
allocated after the call to SSL_shutdown_ex() returns. Reason strings are
bounded by the path MTU and may be silently truncated if they are too long to
fit in a QUIC packet.
Reason strings are intended for human diagnostic purposes only, and should not
be used for application signalling.
=back
The arguments to SSL_shutdown_ex() are used only on the first call to
SSL_shutdown_ex() (or SSL_shutdown()) for a given QUIC connection SSL object.
These arguments are ignored on subsequent calls.
These functions do not affect an underlying network BIO or the resource it
represents; for example, a UDP datagram provided to a QUIC connection as the
network BIO will remain open.
Note that when using QUIC, an application must call SSL_shutdown() if it wants
to ensure that all transmitted data was received by the peer. This is unlike a
TLS/TCP connection, where reliable transmission of buffered data is the
responsibility of the operating system. If an application calls SSL_free() on a
QUIC connection SSL object or exits before completing the shutdown process using
SSL_shutdown(), data which was written by the application using SSL_write(), but
could not yet be transmitted, or which was sent but lost in the network, may not
be received by the peer.
When using QUIC, calling SSL_shutdown() allows internal network event processing
to be performed. It is important that this processing is performed regularly,
whether during connection usage or during shutdown. If an application is not
using thread assisted mode, an application conducting shutdown should either
ensure that SSL_shutdown() is called regularly, or alternatively ensure that
SSL_handle_events() is called regularly. See L<openssl-quic(7)> and
L<SSL_handle_events(3)> for more information.
=head2 Application Data Drainage Behaviour
When using QUIC, SSL_shutdown() or SSL_shutdown_ex() ordinarily waits until all
data written to a stream by an application has been acknowledged by the peer. In
other words, the shutdown process waits until all data written by the
application has been sent to the peer, and until the receipt of all such data is
acknowledged by the peer. Only once this process is completed is the shutdown
considered complete.
An exception to this is streams which terminated in a non-normal fashion, for
example due to a stream reset; only streams which are non-terminated at the time
SSL_shutdown() is called, or which terminated in a normal fashion, have their
pending send buffers flushed in this manner.
This behaviour of flushing streams during the shutdown process can be skipped by
setting the B<SSL_SHUTDOWN_FLAG_NO_STREAM_FLUSH> flag in a call to
SSL_shutdown_ex(); in this case, data remaining in stream send buffers may not
be transmitted to the peer. This flag may be used when a non-normal application
condition has occurred and the delivery of data written to streams via
L<SSL_write(3)> is no longer relevant.
=head2 Shutdown Mode
Aspects of how QUIC handles connection closure must be taken into account by
applications. Ordinarily, QUIC expects a connection to continue to be serviced
@ -255,7 +384,8 @@ Call L<SSL_get_error(3)> with the return value B<ret> to find out the reason.
It can occur if an action is needed to continue the operation for nonblocking
BIOs.
It can also occur when not all data was read using SSL_read().
It can also occur when not all data was read using SSL_read(), or if called
on a QUIC stream SSL object.
This value is also returned when called on QUIC stream SSL objects.

View File

@ -66,6 +66,14 @@ operation is considered completed. The bytes are sent and a new write call with
a new buffer (with the already sent bytes removed) must be started. A partial
write is performed with the size of a message block, which is 16kB.
When used with a QUIC SSL object, calling an I/O function such as SSL_write()
allows internal network event processing to be performed. It is important that
this processing is performed regularly. If an application is not using thread
assisted mode, an application should ensure that an I/O function such as
SSL_write() is called regularly, or alternatively ensure that SSL_handle_events()
is called regularly. See L<openssl-quic(7)> and L<SSL_handle_events(3)> for more
information.
=head1 WARNINGS
When a write function call has to be repeated because L<SSL_get_error(3)>