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

# 8.2.  Client Hello Recording
#
# An alternative form of anti-replay is to record a unique value
# derived from the ClientHello (generally either the random value or
# the PSK binder) and reject duplicates.  Recording all ClientHellos
# causes state to grow without bound, but a server can instead record
# ClientHellos within a given time window and use the
# "obfuscated_ticket_age" to ensure that tickets aren't reused outside
# that window.
# 
# In order to implement this, when a ClientHello is received, the
# server first verifies the PSK binder as described in Section 4.2.11.
# It then computes the expected_arrival_time as described in the next
# section and rejects 0-RTT if it is outside the recording window,
# falling back to the 1-RTT handshake.
# 
# If the expected_arrival_time is in the window, then the server checks
# to see if it has recorded a matching ClientHello.  If one is found,
# it either aborts the handshake with an "illegal_parameter" alert or
# accepts the PSK but rejects 0-RTT.  If no matching ClientHello is
# found, then it accepts 0-RTT and then stores the ClientHello for as
# long as the expected_arrival_time is inside the window.  Servers MAY
# also implement data stores with false positives, such as Bloom
# filters, in which case they MUST respond to apparent replay by
# rejecting 0-RTT but MUST NOT abort the handshake.
# 
# The server MUST derive the storage key only from validated sections
# of the ClientHello.  If the ClientHello contains multiple PSK
# identities, then an attacker can create multiple ClientHellos with
# different binder values for the less-preferred identity on the
# assumption that the server will not verify it (as recommended by
# Section 4.2.11).  I.e., if the client sends PSKs A and B but the
# server prefers A, then the attacker can change the binder for B
# without affecting the binder for A.  If the binder for B is part of
# the storage key, then this ClientHello will not appear as a
# duplicate, which will cause the ClientHello to be accepted, and may
# cause side effects such as replay cache pollution, although any 0-RTT
# data will not be decryptable because it will use different keys.  If
# the validated binder or the ClientHello.random is used as the storage
# key, then this attack is not possible.
# 
# Because this mechanism does not require storing all outstanding
# tickets, it may be easier to implement in distributed systems with
# high rates of resumption and 0-RTT, at the cost of potentially weaker
# anti-replay defense because of the difficulty of reliably storing and
# retrieving the received ClientHello messages.  In many such systems,
# it is impractical to have globally consistent storage of all the
# received ClientHellos.  In this case, the best anti-replay protection
# is provided by having a single storage zone be authoritative for a
# given ticket and refusing 0-RTT for that ticket in any other zone.
# This approach prevents simple replay by the attacker because only one
# zone will accept 0-RTT data.  A weaker design is to implement
# separate storage for each zone but allow 0-RTT in any zone.  This
# approach limits the number of replays to once per zone.  Application
# message duplication of course remains possible with either design.
# 
# When implementations are freshly started, they SHOULD reject 0-RTT as
# long as any portion of their recording window overlaps the startup
# time.  Otherwise, they run the risk of accepting replays which were
# originally sent during that period.
# 
# Note: If the client's clock is running much faster than the server's,
# then a ClientHello may be received that is outside the window in the
# future, in which case it might be accepted for 1-RTT, causing a
# client retry, and then acceptable later for 0-RTT.  This is another
# variant of the second form of attack described in Section 8.

[[spec]]
level = "MUST"
quote = '''
Servers MAY
also implement data stores with false positives, such as Bloom
filters, in which case they MUST respond to apparent replay by
rejecting 0-RTT but MUST NOT abort the handshake.
'''

[[spec]]
level = "MUST"
quote = '''
Servers MAY
also implement data stores with false positives, such as Bloom
filters, in which case they MUST respond to apparent replay by
rejecting 0-RTT but MUST NOT abort the handshake.
'''

[[spec]]
level = "MUST"
quote = '''
The server MUST derive the storage key only from validated sections
of the ClientHello.
'''

[[spec]]
level = "SHOULD"
quote = '''
When implementations are freshly started, they SHOULD reject 0-RTT as
long as any portion of their recording window overlaps the startup
time.
'''

