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

# 4.2.8.  Key Share
#
# The "key_share" extension contains the endpoint's cryptographic
# parameters.
# 
# Clients MAY send an empty client_shares vector in order to request
# group selection from the server, at the cost of an additional round
# trip (see Section 4.1.4).
# 
#    struct {
#        NamedGroup group;
#        opaque key_exchange<1..2^16-1>;
#    } KeyShareEntry;
# 
# group:  The named group for the key being exchanged.
# 
# key_exchange:  Key exchange information.  The contents of this field
#    are determined by the specified group and its corresponding
#    definition.  Finite Field Diffie-Hellman [DH76] parameters are
#    described in Section 4.2.8.1; Elliptic Curve Diffie-Hellman
#    parameters are described in Section 4.2.8.2.
# 
# In the ClientHello message, the "extension_data" field of this
# extension contains a "KeyShareClientHello" value:
# 
#    struct {
#        KeyShareEntry client_shares<0..2^16-1>;
#    } KeyShareClientHello;
# 
# client_shares:  A list of offered KeyShareEntry values in descending
#    order of client preference.
# 
# This vector MAY be empty if the client is requesting a
# HelloRetryRequest.  Each KeyShareEntry value MUST correspond to a
# group offered in the "supported_groups" extension and MUST appear in
# the same order.  However, the values MAY be a non-contiguous subset
# of the "supported_groups" extension and MAY omit the most preferred
# groups.  Such a situation could arise if the most preferred groups
# are new and unlikely to be supported in enough places to make
# pregenerating key shares for them efficient.
# 
# Clients can offer as many KeyShareEntry values as the number of
# supported groups it is offering, each representing a single set of
# key exchange parameters.  For instance, a client might offer shares
# for several elliptic curves or multiple FFDHE groups.  The
# key_exchange values for each KeyShareEntry MUST be generated
# independently.  Clients MUST NOT offer multiple KeyShareEntry values
# for the same group.  Clients MUST NOT offer any KeyShareEntry values
# for groups not listed in the client's "supported_groups" extension.
# Servers MAY check for violations of these rules and abort the
# handshake with an "illegal_parameter" alert if one is violated.
# 
# In a HelloRetryRequest message, the "extension_data" field of this
# extension contains a KeyShareHelloRetryRequest value:
# 
#    struct {
#        NamedGroup selected_group;
#    } KeyShareHelloRetryRequest;
# 
# selected_group:  The mutually supported group the server intends to
#    negotiate and is requesting a retried ClientHello/KeyShare for.
# 
# Upon receipt of this extension in a HelloRetryRequest, the client
# MUST verify that (1) the selected_group field corresponds to a group
# which was provided in the "supported_groups" extension in the
# original ClientHello and (2) the selected_group field does not
# correspond to a group which was provided in the "key_share" extension
# in the original ClientHello.  If either of these checks fails, then
# the client MUST abort the handshake with an "illegal_parameter"
# alert.  Otherwise, when sending the new ClientHello, the client MUST
# 
# replace the original "key_share" extension with one containing only a
# new KeyShareEntry for the group indicated in the selected_group field
# of the triggering HelloRetryRequest.
# 
# In a ServerHello message, the "extension_data" field of this
# extension contains a KeyShareServerHello value:
# 
#    struct {
#        KeyShareEntry server_share;
#    } KeyShareServerHello;
# 
# server_share:  A single KeyShareEntry value that is in the same group
#    as one of the client's shares.
# 
# If using (EC)DHE key establishment, servers offer exactly one
# KeyShareEntry in the ServerHello.  This value MUST be in the same
# group as the KeyShareEntry value offered by the client that the
# server has selected for the negotiated key exchange.  Servers
# MUST NOT send a KeyShareEntry for any group not indicated in the
# client's "supported_groups" extension and MUST NOT send a
# KeyShareEntry when using the "psk_ke" PskKeyExchangeMode.  If using
# (EC)DHE key establishment and a HelloRetryRequest containing a
# "key_share" extension was received by the client, the client MUST
# verify that the selected NamedGroup in the ServerHello is the same as
# that in the HelloRetryRequest.  If this check fails, the client MUST
# abort the handshake with an "illegal_parameter" alert.

[[spec]]
level = "MAY"
quote = '''
Clients MAY send an empty client_shares vector in order to request
group selection from the server, at the cost of an additional round
trip (see Section 4.1.4).
'''

[[spec]]
level = "MAY"
quote = '''
This vector MAY be empty if the client is requesting a
HelloRetryRequest.
'''

[[spec]]
level = "MUST"
quote = '''
Each KeyShareEntry value MUST correspond to a
group offered in the "supported_groups" extension and MUST appear in
the same order.
'''

[[spec]]
level = "MUST"
quote = '''
Each KeyShareEntry value MUST correspond to a
group offered in the "supported_groups" extension and MUST appear in
the same order.
'''

[[spec]]
level = "MAY"
quote = '''
However, the values MAY be a non-contiguous subset
of the "supported_groups" extension and MAY omit the most preferred
groups.
'''

[[spec]]
level = "MAY"
quote = '''
However, the values MAY be a non-contiguous subset
of the "supported_groups" extension and MAY omit the most preferred
groups.
'''

[[spec]]
level = "MUST"
quote = '''
The
key_exchange values for each KeyShareEntry MUST be generated
independently.
'''

[[spec]]
level = "MUST"
quote = '''
Clients MUST NOT offer multiple KeyShareEntry values
for the same group.
'''

[[spec]]
level = "MUST"
quote = '''
Clients MUST NOT offer any KeyShareEntry values
for groups not listed in the client's "supported_groups" extension.
'''

[[spec]]
level = "MAY"
quote = '''
Servers MAY check for violations of these rules and abort the
handshake with an "illegal_parameter" alert if one is violated.
'''

[[spec]]
level = "MUST"
quote = '''
Upon receipt of this extension in a HelloRetryRequest, the client
MUST verify that (1) the selected_group field corresponds to a group
which was provided in the "supported_groups" extension in the
original ClientHello and (2) the selected_group field does not
correspond to a group which was provided in the "key_share" extension
in the original ClientHello.
'''

[[spec]]
level = "MUST"
quote = '''
If either of these checks fails, then
the client MUST abort the handshake with an "illegal_parameter"
alert.
'''

[[spec]]
level = "MUST"
quote = '''
Otherwise, when sending the new ClientHello, the client MUST
'''

[[spec]]
level = "MUST"
quote = '''
This value MUST be in the same
group as the KeyShareEntry value offered by the client that the
server has selected for the negotiated key exchange.
'''

[[spec]]
level = "MUST"
quote = '''
Servers
MUST NOT send a KeyShareEntry for any group not indicated in the
client's "supported_groups" extension and MUST NOT send a
KeyShareEntry when using the "psk_ke" PskKeyExchangeMode.
'''

[[spec]]
level = "MUST"
quote = '''
Servers
MUST NOT send a KeyShareEntry for any group not indicated in the
client's "supported_groups" extension and MUST NOT send a
KeyShareEntry when using the "psk_ke" PskKeyExchangeMode.
'''

[[spec]]
level = "MUST"
quote = '''
If using
(EC)DHE key establishment and a HelloRetryRequest containing a
"key_share" extension was received by the client, the client MUST
verify that the selected NamedGroup in the ServerHello is the same as
that in the HelloRetryRequest.
'''

[[spec]]
level = "MUST"
quote = '''
If this check fails, the client MUST
abort the handshake with an "illegal_parameter" alert.
'''

