TLS 1.3 Alert Protocol

TLS provides the alert content type to indicate closure information and errors. As with other messages, alert messages are encrypted according to the current connection state.

Alert messages convey a description of the alert and a legacy field that, in earlier versions of TLS, conveyed the message severity level. Alerts fall into two categories: closure alerts and error alerts. In TLS 1.3, the severity of an error is implied by the type of alert being sent, and the “level” field can be safely ignored. The “close_notify” alert is used to indicate that an orderly shutdown of the connection has begun in one direction. After receiving such an alert, a TLS implementation should indicate end-of-data to the application.

Error alerts indicate that connection termination is abortive (see Section 6.2). After receiving an error alert, a TLS implementation should indicate an error to the application, and no further data may be sent or received on the connection. The Server and Client must forget the secret values and keys established in the failed connection, except for PSKs associated with session tickets, which should be discarded if possible.

All alerts listed in Section 6.2 must be sent with AlertLevel = fatal, and must be treated as error alerts when received, regardless of the AlertLevel in the message. Unknown alert types must all be treated as error alerts.

Note: TLS defines two generic alerts (see Section 6) for use when message parsing fails. A peer that receives a message whose syntax cannot be parsed (for example, a message with a length that extends beyond the message boundary or that contains an out-of-range length) must terminate the connection with a “decode_error” alert. A peer that receives a syntactically correct but semantically invalid message (for example, a DHE share of p-1 or an invalid enumeration value) must terminate the connection with an “illegal_parameter” alert.

      enum { warning(1), fatal(2), (255) } AlertLevel;

      enum {
          close_notify(0),
          unexpected_message(10),
          bad_record_mac(20),
          record_overflow(22),
          handshake_failure(40),
          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),
          protocol_version(70),
          insufficient_security(71),
          internal_error(80),
          inappropriate_fallback(86),
          user_canceled(90),
          missing_extension(109),
          unsupported_extension(110),
          unrecognized_name(112),
          bad_certificate_status_response(113),
          unknown_psk_identity(115),
          certificate_required(116),
          no_application_protocol(120),
          (255)
      } AlertDescription;

      struct {
          AlertLevel level;
          AlertDescription description;
      } Alert;

I. Closure Alerts

The Client and Server must share the connection-termination state to prevent truncation attacks.

  • close_notify: This alert notifies the recipient that the sender will not send any more messages on this connection. Any data received after a closure alert has been received MUST be ignored.

  • user_canceled: This alert notifies the recipient that the sender is canceling the handshake for some reason unrelated to a protocol failure. If the user cancels an operation after the handshake has completed, it is more appropriate to close the connection by sending “close_notify”. This warning follows “close_notify”. This alert typically has AlertLevel = warning.

Either party may initiate closure of its write side of the connection by sending a “close_notify” alert. Any data received after a closure alert has been received MUST be ignored. If a transport-level close is received before “close_notify”, the receiving side cannot know that it has received all data that was sent.

Each party MUST send a “close_notify” alert before closing its write side of the connection, unless it has already sent some error alert. This has no effect on the read side of the connection. Note that this is a change from versions of TLS prior to TLS 1.3, where implementations were required to react to “close_notify” by discarding pending writes and immediately sending their own “close_notify” alert. The previous requirement could cause truncation on the read side. Neither side is required to wait to receive a “close_notify” alert before closing the read side of the connection, but doing so introduces the possibility of truncation.

If an application protocol using TLS specifies that any data may be carried over the underlying transport after the TLS connection is closed, then the TLS implementation MUST receive a “close_notify” alert before indicating the end of data to the application layer. No part of this standard should be taken to prescribe how TLS usage profiles manage their data transfer, including when connections are opened or closed.

Note: This assumes that any pending data can still be sent reliably after the write side of the connection is closed and before the transport is destroyed.

II. Error Alerts

Error handling in TLS is very simple. When an error is detected, the detecting party sends a message to its peer. Upon sending or receiving a fatal alert message, both parties MUST immediately close the connection.

Whenever an implementation encounters a fatal error condition, it SHOULD send an appropriate fatal alert and MUST close the connection without sending or receiving any additional data. In the remainder of this specification, when the phrases “terminate the connection” and “abort the handshake” are used without a specific alert, this means that the implementation SHOULD send the alert indicated by the descriptions below. The phrases “terminate the connection with alert X” and “abort the handshake with alert X” mean that if any alert is sent, the implementation MUST send alert X. Starting with TLS 1.3, all alerts defined below in this section, as well as all unknown alerts, are considered fatal (see Section 6). Implementations SHOULD provide a convenient way to log sent and received alerts.

The following error alerts are defined:

  1. unexpected_message:
    An inappropriate message was received (for example, an incorrect handshake message, premature application data, etc.). This alert should never occur in communication between correct implementations.

  2. bad_record_mac:
    This alert is returned if a record is received that cannot be unprotected. Because AEAD algorithms combine decryption and verification and also avoid side-channel attacks, this alert is used for all deprotection failures. This alert should never occur in communication between correct implementations unless the message was corrupted in the network.

  3. record_overflow:
    A TLSCiphertext record was received with a length greater than 2 ^ 14 + 256 bytes, or a record decrypted to a TLSPlaintext record with a length greater than 2 ^ 14 bytes (or some other negotiated limit). This alert should never occur in communication between correct implementations unless the message was corrupted in the network.

  4. handshake_failure:
    Receipt of a “handshake_failure” alert message indicates that the sender was unable to negotiate an acceptable set of security parameters given the available options.

  5. bad_certificate:
    The certificate was corrupt, including signatures that could not be verified correctly, etc.

  6. unsupported_certificate:
    The type of the certificate is not supported.

  7. certificate_revoked:
    The certificate has been revoked by its signer.

  8. certificate_expired:
    The certificate has expired or is not currently valid.

  9. certificate_unknown:
    Some other (unspecified) issue occurred while processing the certificate, making it unacceptable.

  10. illegal_parameter:
    A field in the handshake was incorrect or inconsistent with other fields. This alert is used for errors that conform to the formal protocol syntax but are otherwise incorrect.

  11. unknown_ca:
    A valid certificate chain or partial chain was received, but the certificate was not accepted because the CA certificate could not be found or could not be matched to a known trust anchor.

  12. access_denied:
    A valid certificate or PSK was received, but when applying access control, the sender decided not to continue negotiation.

  13. decode_error:
    A message could not be decoded because some field was outside the specified range or the message length was incorrect. This alert is used for errors where the message does not conform to the formal protocol syntax. This alert should never occur in communication between correct implementations unless the message was corrupted in the network.

  14. decrypt_error:
    A handshake (rather than record-layer) cryptographic operation failed, including failure to correctly verify a signature, verify a Finished message, or verify a PSK binder.

  15. protocol_version:
    The protocol version that the peer attempted to negotiate was recognized but is not supported (see Appendix D).

  16. insufficient_security:
    “insufficient_security” is returned instead of “handshake_failure” when negotiation fails because the Server requires parameters more secure than those supported by the Client.

  17. internal_error:
    An internal error unrelated to the peer or to the correctness of the protocol (for example, memory allocation failure) made it impossible to continue the connection.

  18. applicable_fallback:
    Sent by the Server in response to a retry from the Client with an invalid connection (see [RFC7507]).

  19. missing_extension:
    Sent by an endpoint that receives a handshake message that does not contain an extension that must be sent for the offered TLS version, or that does not contain an extension required by other negotiated parameters.

  20. unsupported_extension:
    Sent by an endpoint that receives any handshake message containing an extension known to be prohibited in the given handshake message, or containing an extension in ServerHello or Certificate that was not first offered in the corresponding ClientHello or CertificateRequest.

  21. unrecognized_name:
    When the name provided by the Client via the “server_name” extension does not correspond to any Server identified by that name, the Server sends an “unrecognized_name” alert message (see [RFC6066]).

  22. bad_certificate_status_response:
    When the Server provides an invalid or unacceptable OCSP response via the “status_request” extension, the Client sends “bad_certificate_status_response” (see [RFC6066]).

  23. unknown_psk_identity:
    When PSK key establishment is required but the Client cannot provide an acceptable PSK identity, the Server sends “unknown_psk_identity”. Sending this alert is optional; the Server may instead choose to send a “decrypt_error” alert, indicating only an invalid PSK identity.

  24. certificate_required:
    When a Client certificate is required but the Client does not provide any certificate, the Server sends “certificate_required”.

  25. no_application_protocol:
    When the Server does not support any of the protocols in the Client’s “application_layer_protocol_negotiation” extension, the Server sends “no_application_protocol” (see [RFC7301]).

New alert values are assigned by IANA, as described in Section 11.


Reference:

RFC 8446

GitHub Repo: Halfrost-Field

Follow: halfrost · GitHub

Source: https://halfrost.com/TLS_1.3_Alert_Protocol/