Draft: draft-ietf-ace-mqtt-tls-profile

Commentary: Some changes that I propose having read the -13 and diff from -12 to -13 in light of my first AD evaluation . Many of these are definitely not editorial and will require some discussion .
The Broker connection acknowledgment.  CONNACK packets contain
return codes indicating either a success or an error state in
response to a Client's CONNECT packet and any subsequent AUTH
packets.
The Broker connection acknowledgment.  CONNACK packets contain
return codes indicating either a success or an error state in
response to a Client's CONNECT packet.
TLS:Anon,MQTT:ace: The token is transported inside the CONNECT
packet and MUST be validated using one of the methods described in
app-authzinfo.  This option also supports a tokenless connection
request for AS discovery.
TLS:Known(RPK/PSK),MQTT:none: This specification supports client
authentication with TLS with Raw Public Keys (RPK) RFC7250 and
with Pre-Shared Keys (PSK).  For the RPK, the Client MUST have
published the token to the "authz-info" topic.  For the PSK, the
token MAY be, alternatively, provided as a "PSK identity" (e.g.
"identity" in the "identities" field in the client's
"pre_shared_key" extension in TLS 1.3).
TLS:Anon,MQTT:ace: The token is transported inside the CONNECT
packet and MUST be validated using one of the methods described in
app-authzinfo.  This option also supports a tokenless connection
request for AS discovery.  As per I-D.ietf-ace-oauth-authz, a
separate step is needed to determine whether the discovered AS URI
is authorized to act as an AS.
TLS:Known(RPK/PSK),MQTT:none: This specification supports client
authentication with TLS with Raw Public Keys (RPK) RFC7250 and
with Pre-Shared Keys (PSK).  For the RPK, the Client MUST have
published the token to the "authz-info" topic.  For the PSK, the
token MAY be published to the "authz-info" topic, or MAY be,
alternatively, provided as a "PSK identity" (e.g. "identity" in
the "identities" field in the client's "pre_shared_key" extension
in TLS 1.3).
The Broker stores and indexes all tokens received to the "authz-info"
topic in its key store (similar to I-D.ietf-ace-dtls-authorize).
This profile follows the recommendation of Section 5.10.1 of the I-
D.ietf-ace-oauth-authz, and expects that the Broker stores only one
token per proof-of-possession key, and any other token linked to the
same key overwrites an existing token.
The Broker stores and indexes all tokens received to the "authz-info"
topic in its key store (similar to the I-D.ietf-ace-dtls-authorize).
This profile follows the recommendation of Section 5.10.1 of the I-
D.ietf-ace-oauth-authz, and expects that the Broker stores only one
token per proof-of-possession key, and any other token linked to the
same key overwrites an existing token.
The Broker MUST verify the validity of the token (i.e., through local
validation or introspection, if the token is a reference) as
described in token_validation.  If the token is not valid, the Broker
MUST discard the token.  Depending on the QoS level of the PUBLISH
packet, the Broker returns the error response as a PUBACK or a
DISCONNECT packet as explained below.
The Broker MUST verify the validity of the token (i.e., through local
validation or introspection, if the token is a reference) as
described in token_validation.  If the token is not valid, the Broker
MUST discard the token.  Depending on the QoS level of the PUBLISH
packet, the Broker returns the error response as a PUBACK, PUBREC, or
DISCONNECT packet as explained below.
If the QoS level of the PUBLISH packet is greater than or equal to 1,
and the token is invalid, or the claims cannot be obtained in the
case of an introspected token, the Broker MUST send the reason code
0x87 ('Not authorized') in the PUBACK.  If the PUBLISH payload does
not parse to a token, the PUBACK reason code is '0x99 (Payload format
invalid)'.
If the QoS level of the PUBLISH packet is greater than or equal to 1,
and the token is invalid, or the claims cannot be obtained in the
case of an introspected token, the Broker MUST send the reason code
0x87 ('Not authorized') in the PUBACK or PUBREC.  If the PUBLISH
payload does not parse to a token, the PUBACK/PUBREC reason code is
'0x99 (Payload format invalid)'.
The TLS session setup is similar to the one described in the I-
D.ietf-ace-dtls-authorize, and if TLS 1.2 is used, RFC7925 describes
how TLS can be used for constrained devices, alongside recommended
cipher suites.  Additionally, TLS 1.2 implementations SHOULD use
"Extended Master Secret" RFC7627 to include parts of the handshake
transcript into the master secret, and SNI (Server Name Indication)
RFC6066 and APLN (Application-Layer Protocol Negotiation) RFC7301
extensions.
The TLS session setup is similar to the one described in the I-
D.ietf-ace-dtls-authorize, and if TLS 1.2 is used, RFC7925 describes
how TLS can be used for constrained devices, alongside recommended
cipher suites.  Additionally, TLS 1.2 implementations SHOULD use
"Extended Master Secret" RFC7627 to include handshake transcript into
the master secret (RFC 7627 describes alternative conditions that
must be met to defend against the same attacks without the
extension).  TLS implementations SHOULD use the SNI (Server Name
Indication) RFC6066 and APLN (Application-Layer Protocol Negotiation)
RFC7301 extensions.
In the RPK mode, the Client proves that it can use the RPK bound to
the token, and the Broker shows that it can use a certain RPK.  The
Broker needs access to the token to complete this exchange.
Therefore, for the RPK mode, the client must upload the access token
to the Broker as specified in app-authzinfo before initiating the
handshake.  The client MUST use its correct public key in the TLS
handshake and MUST specify this public key in the
SubjectPublicKeyInfo structure of the TLS handshake as described in
RFC7250.  The handshake only finishes if the Client and the Broker
are able to use their respective keying material.
An implementation that supports the RPK mode of this profile MUST at
least support the cipher suite TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
RFC7250.  Implementations of this profile MUST implement support for
curve25519 RFC7748.
In the RPK mode, the Client proves that it can use the RPK bound to
the token, and the Broker shows that it can use a certain RPK.  The
Broker needs access to the token to complete this exchange.
Therefore, for the RPK mode, the client must upload the access token
to the Broker as specified in app-authzinfo before initiating the
handshake.  The client MUST use its correct public key in the TLS
handshake and MUST specify this public key in the
SubjectPublicKeyInfo structure of the TLS handshake as described in
RFC7250.  The handshake only finishes if the Client and the Broker
are able to use their respective keying material.  While RFC 7250
allows independent negotiation of client and server use of raw public
keys, this document assumes that if RPK is used, it is negotiated to
be used by both parties.
An implementation that supports the RPK mode of this profile MUST at
least support the cipher suite TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
RFC7251.  Implementations of this profile MUST implement support for
the x25519 key-exchange group RFC8422,RFC8446.
To use TLS with pre-shared keys, the Client follows the PSK key
extension specified in RFC8446 using the key conveyed in the "cnf"
parameter of the AS response.  The same key is bound to the access
token in the "rs_cnf" claim.  The Client can upload the access as
specified in app-authzinfo before initiating the handshake.  The
token MAY be, alternatively, provided as an "identity" in the
"identities" field in the client's "pre_shared_key" extension.
To use TLS 1.3 with pre-shared keys, the Client follows the PSK key
extension specified in RFC8446 using the key conveyed in the "cnf"
parameter of the AS response.  The same key is bound to the access
token in the "cnf" claim.  The Client can upload the access as
specified in app-authzinfo before initiating the handshake.  The
token MAY be, alternatively, provided as an "identity" in the
"identities" field in the client's "pre_shared_key" extension.
If the scope is empty, the Broker records no permissions for the
client for any topic.  In this case, the Client is not able to
publish or subscribe to any protected topics.  The non-empty scope
used to authorize the Will Topic, if provided, in the CONNECT packet,
during connection setup, and if the connection request succeeds, the
Topic Names or Topic Filters requested in the future PUBLISH and
SUBSCRIBE packets.  For the authorization to succeed, the Broker MUST
verify that the topic name or filter in question is either an an
exact match to or a subset of at least one 'topic_filter' in the
scope.
If the scope is empty, the Broker records no permissions for the
client for any topic.  In this case, the Client is not able to
publish or subscribe to any protected topics.  The non-empty scope is
used to authorize the Will Topic, if provided, in the CONNECT packet,
during connection setup, and if the connection request succeeds, the
Topic Names or Topic Filters requested in the future PUBLISH and
SUBSCRIBE packets.  For the authorization to succeed, the Broker MUST
verify that the topic name or filter in question is either an an
exact match to or a subset of at least one 'topic_filter' in the
scope.
The Broker MAY also trigger AS discovery and include a User Property
(identified as property type 38 (0x26)) in the CONNACK for the AS
Request Creation Hints.  The User Property is a UTF-8 string pair,
composed of a name and a value.  The name of the User Property MUST
be set to "ace_as_hint".  The value of the user property is a UTF-8
encoded JSON string containing the mandatory "AS" parameter, and the
optional parameters "audience", "kid", "cnonce", and "scope" as
defined in Section 5.3 of the I-D.ietf-ace-oauth-authz.
The Broker MAY also trigger AS discovery and include a User Property
(identified as property type 38 (0x26)) in the CONNACK for the AS
Request Creation Hints.  The User Property is a UTF-8 string pair,
composed of a name and a value.  The name of the User Property MUST
be set to "ace_as_hint".  The value of the user property is a UTF-8
encoded JSON object containing the mandatory "AS" parameter, and the
optional parameters "audience", "kid", "cnonce", and "scope" as
defined in Section 5.3 of the I-D.ietf-ace-oauth-authz.
Accepting the connection, the Broker MUST be prepared to store the
token during the connection and after disconnection for future use.
If the token is not self-contained and the Broker uses token
introspection, it MAY cache the validation result to authorize the
subsequent PUBLISH and SUBSCRIBE packets.  PUBLISH and SUBSCRIBE
packets, which are sent after a connection setup, do not contain
access tokens.  If the introspection result is not cached, the Broker
needs to introspect the saved token for each request.  The Broker
SHOULD also use a cache timeout to introspect tokens regularly.  The
timeout value is application-specific and SHOULD be chosen to reduce
the risk of using stale introspection responses.
Having accepted the connection, the Broker MUST be prepared to store
the token during the connection and after disconnection for future
use.  If the token is not self-contained and the Broker uses token
introspection, it MAY cache the validation result to authorize the
subsequent PUBLISH and SUBSCRIBE packets.  PUBLISH and SUBSCRIBE
packets, which are sent after a connection setup, do not contain
access tokens.  If the introspection result is not cached, the Broker
needs to introspect the saved token for each request.  The Broker
SHOULD also use a cache timeout to introspect tokens regularly.  The
timeout value is application-specific and SHOULD be chosen to reduce
the risk of using stale introspection responses.
The Client MAY reauthenticate as a response to the PUBACK and SUBACK
that signal loss of authorization.  The Clients MAY also proactively
update their tokens, i.e., before they receive a packet with a "Not
authorized" return code.  To start reauthentication, the Client MUST
send an AUTH packet with the reason code "0x19 (Re-authentication)".
The Client MUST set the Authentication Method as "ace" and transport
the new token in the Authentication Data.  To re-authenticate, the
Client MUST NOT use Proof-of-Possession using a challenge from the
TLS session during the same TLS session to avoid re-using the same
challenge value from the TLS-Exporter.  For re-authentications in the
same TLS-session, the Client MUST use the challenge-response PoP as
defined in pop_challenge.  The Broker accepts reauthentication
requests if the Client has already submitted a token (may be
expired), for which it performed proof-of-possession.  Otherwise, the
Broker MUST deny the request.  If the reauthentication fails, the
Broker MUST send a DISCONNECT with the reason code "0x87 (Not
Authorized)".
The Client MAY reauthenticate as a response to the PUBACK and SUBACK
that signal loss of authorization.  The Clients MAY also proactively
update their tokens, i.e., before they receive a packet with a "Not
authorized" return code.  To start reauthentication, the Client MUST
send an AUTH packet with the reason code "0x19 (Re-authentication)".
The Client MUST set the Authentication Method as "ace" and transport
the new token in the Authentication Data.  To re-authenticate, the
Client MUST NOT use Proof-of-Possession using a challenge from the
TLS session during the same TLS session to avoid re-using the same
challenge value from the TLS-Exporter.  Note that this means that
servers will either need to record in the session ticket or database
entry whether the TLS-Exporter-derived challenge was used, or always
deny use of the TLS-Exporter-derived challenge for resumed sessions.
In TLS 1.3, the resumed connection would have a new exporter value,
but the requirement is phrased this way for simplicity.  For re-
authentications in the same TLS-session, the Client MUST use the
challenge-response PoP as defined in pop_challenge.  The Broker
accepts reauthentication requests if the Client has already submitted
a token (may be expired), for which it performed proof-of-possession.
Otherwise, the Broker MUST deny the request.  If the reauthentication
fails, the Broker MUST send a DISCONNECT with the reason code "0x87
(Not Authorized)".
As in MQTT v5.0, the token MAY either be transported before, by
publishing to the "authz-info" topic or inside the CONNECT packet.
If the Client provided the token via the "authz-info" topic and will
not update the token in the CONNECT packet, it MUST authenticate over
TLS.  The Broker SHOULD still be prepared to store the Client access
token for future use (regardless of the method of transport).
As in MQTT v5.0, the token MAY either be transported before, by
publishing to the "authz-info" topic, or inside the CONNECT packet.
If the Client provided the token via the "authz-info" topic and will
not update the token in the CONNECT packet, it MUST authenticate over
TLS.  The Broker SHOULD still be prepared to store the Client access
token for future use (regardless of the method of transport).