target = "https://tools.ietf.org/rfc/rfc8446#section-4.2.10"

# 4.2.10.  Early Data Indication
#
# When a PSK is used and early data is allowed for that PSK, the client
# can send Application Data in its first flight of messages.  If the
# client opts to do so, it MUST supply both the "pre_shared_key" and
# "early_data" extensions.
# 
# The "extension_data" field of this extension contains an
# "EarlyDataIndication" value.
# 
#    struct {} Empty;
# 
#    struct {
#        select (Handshake.msg_type) {
#            case new_session_ticket:   uint32 max_early_data_size;
#            case client_hello:         Empty;
#            case encrypted_extensions: Empty;
#        };
#    } EarlyDataIndication;
# 
# See Section 4.6.1 for details regarding the use of the
# max_early_data_size field.
# 
# The parameters for the 0-RTT data (version, symmetric cipher suite,
# Application-Layer Protocol Negotiation (ALPN) [RFC7301] protocol,
# etc.) are those associated with the PSK in use.  For externally
# provisioned PSKs, the associated values are those provisioned along
# with the key.  For PSKs established via a NewSessionTicket message,
# the associated values are those which were negotiated in the
# connection which established the PSK.  The PSK used to encrypt the
# early data MUST be the first PSK listed in the client's
# "pre_shared_key" extension.
# 
# For PSKs provisioned via NewSessionTicket, a server MUST validate
# that the ticket age for the selected PSK identity (computed by
# subtracting ticket_age_add from PskIdentity.obfuscated_ticket_age
# modulo 2^32) is within a small tolerance of the time since the ticket
# was issued (see Section 8).  If it is not, the server SHOULD proceed
# with the handshake but reject 0-RTT, and SHOULD NOT take any other
# action that assumes that this ClientHello is fresh.
# 
# 0-RTT messages sent in the first flight have the same (encrypted)
# content types as messages of the same type sent in other flights
# (handshake and application_data) but are protected under different
# keys.  After receiving the server's Finished message, if the server
# has accepted early data, an EndOfEarlyData message will be sent to
# indicate the key change.  This message will be encrypted with the
# 0-RTT traffic keys.
# 
# A server which receives an "early_data" extension MUST behave in one
# of three ways:
# 
# -  Ignore the extension and return a regular 1-RTT response.  The
#    server then skips past early data by attempting to deprotect
#    received records using the handshake traffic key, discarding
#    records which fail deprotection (up to the configured
#    max_early_data_size).  Once a record is deprotected successfully,
#    it is treated as the start of the client's second flight and the
#    server proceeds as with an ordinary 1-RTT handshake.
# 
# -  Request that the client send another ClientHello by responding
#    with a HelloRetryRequest.  A client MUST NOT include the
#    "early_data" extension in its followup ClientHello.  The server
#    then ignores early data by skipping all records with an external
#    content type of "application_data" (indicating that they are
#    encrypted), up to the configured max_early_data_size.
# 
# -  Return its own "early_data" extension in EncryptedExtensions,
#    indicating that it intends to process the early data.  It is not
#    possible for the server to accept only a subset of the early data
#    messages.  Even though the server sends a message accepting early
#    data, the actual early data itself may already be in flight by the
#    time the server generates this message.
# 
# In order to accept early data, the server MUST have accepted a PSK
# cipher suite and selected the first key offered in the client's
# "pre_shared_key" extension.  In addition, it MUST verify that the
# following values are the same as those associated with the
# selected PSK:
# 
# -  The TLS version number
# 
# -  The selected cipher suite
# 
# -  The selected ALPN [RFC7301] protocol, if any
# 
# These requirements are a superset of those needed to perform a 1-RTT
# handshake using the PSK in question.  For externally established
# PSKs, the associated values are those provisioned along with the key.
# For PSKs established via a NewSessionTicket message, the associated
# values are those negotiated in the connection during which the ticket
# was established.
# 
# Future extensions MUST define their interaction with 0-RTT.
# 
# If any of these checks fail, the server MUST NOT respond with the
# extension and must discard all the first-flight data using one of the
# first two mechanisms listed above (thus falling back to 1-RTT or
# 2-RTT).  If the client attempts a 0-RTT handshake but the server
# rejects it, the server will generally not have the 0-RTT record
# protection keys and must instead use trial decryption (either with
# the 1-RTT handshake keys or by looking for a cleartext ClientHello in
# the case of a HelloRetryRequest) to find the first non-0-RTT message.
# 
# If the server chooses to accept the "early_data" extension, then it
# MUST comply with the same error-handling requirements specified for
# all records when processing early data records.  Specifically, if the
# server fails to decrypt a 0-RTT record following an accepted
# "early_data" extension, it MUST terminate the connection with a
# "bad_record_mac" alert as per Section 5.2.
# 
# If the server rejects the "early_data" extension, the client
# application MAY opt to retransmit the Application Data previously
# sent in early data once the handshake has been completed.  Note that
# automatic retransmission of early data could result in incorrect
# assumptions regarding the status of the connection.  For instance,
# when the negotiated connection selects a different ALPN protocol from
# what was used for the early data, an application might need to
# construct different messages.  Similarly, if early data assumes
# anything about the connection state, it might be sent in error after
# the handshake completes.
# 
# A TLS implementation SHOULD NOT automatically resend early data;
# applications are in a better position to decide when retransmission
# is appropriate.  A TLS implementation MUST NOT automatically resend
# early data unless the negotiated connection selects the same ALPN
# protocol.

[[spec]]
level = "MUST"
quote = '''
If the
client opts to do so, it MUST supply both the "pre_shared_key" and
"early_data" extensions.
'''

[[spec]]
level = "MUST"
quote = '''
The PSK used to encrypt the
early data MUST be the first PSK listed in the client's
"pre_shared_key" extension.
'''

[[spec]]
level = "MUST"
quote = '''
For PSKs provisioned via NewSessionTicket, a server MUST validate
that the ticket age for the selected PSK identity (computed by
subtracting ticket_age_add from PskIdentity.obfuscated_ticket_age
modulo 2^32) is within a small tolerance of the time since the ticket
was issued (see Section 8).
'''

[[spec]]
level = "SHOULD"
quote = '''
If it is not, the server SHOULD proceed
with the handshake but reject 0-RTT, and SHOULD NOT take any other
action that assumes that this ClientHello is fresh.
'''

[[spec]]
level = "SHOULD"
quote = '''
If it is not, the server SHOULD proceed
with the handshake but reject 0-RTT, and SHOULD NOT take any other
action that assumes that this ClientHello is fresh.
'''

[[spec]]
level = "MUST"
quote = '''
A server which receives an "early_data" extension MUST behave in one
of three ways:
'''

[[spec]]
level = "MUST"
quote = '''
A client MUST NOT include the
"early_data" extension in its followup ClientHello.
'''

[[spec]]
level = "MUST"
quote = '''
In order to accept early data, the server MUST have accepted a PSK
cipher suite and selected the first key offered in the client's
"pre_shared_key" extension.
'''

[[spec]]
level = "MUST"
quote = '''
In addition, it MUST verify that the
following values are the same as those associated with the
selected PSK:
'''

[[spec]]
level = "MUST"
quote = '''
Future extensions MUST define their interaction with 0-RTT.
'''

[[spec]]
level = "MUST"
quote = '''
If any of these checks fail, the server MUST NOT respond with the
extension and must discard all the first-flight data using one of the
first two mechanisms listed above (thus falling back to 1-RTT or
2-RTT).
'''

[[spec]]
level = "MUST"
quote = '''
If the server chooses to accept the "early_data" extension, then it
MUST comply with the same error-handling requirements specified for
all records when processing early data records.
'''

[[spec]]
level = "MUST"
quote = '''
Specifically, if the
server fails to decrypt a 0-RTT record following an accepted
"early_data" extension, it MUST terminate the connection with a
"bad_record_mac" alert as per Section 5.2.
'''

[[spec]]
level = "MAY"
quote = '''
If the server rejects the "early_data" extension, the client
application MAY opt to retransmit the Application Data previously
sent in early data once the handshake has been completed.
'''

[[spec]]
level = "SHOULD"
quote = '''
A TLS implementation SHOULD NOT automatically resend early data;
applications are in a better position to decide when retransmission
is appropriate.
'''

[[spec]]
level = "MUST"
quote = '''
A TLS implementation MUST NOT automatically resend
early data unless the negotiated connection selects the same ALPN
protocol.
'''

