Subject: [core] Benjamin Kaduk's No Objection on draft-ietf-core-echo-request-tag-12: (with COMMENT)

From: Benjamin Kaduk via Datatracker <[email-masked]>
Date: Wed, 17 Feb 2021 20:15:20 -0800

Benjamin Kaduk has entered the following ballot position for
draft-ietf-core-echo-request-tag-12: No Objection

When responding, please keep the subject line intact and reply to all
email addresses included in the To and CC lines. (Feel free to cut this
introductory paragraph, however.)

Please refer to https://www.ietf.org/iesg/statement/discuss-criteria.html
for more information about IESG DISCUSS and COMMENT positions.

The document, along with other ballot positions, can be found here:
https://datatracker.ietf.org/doc/draft-ietf-core-echo-request-tag/

----------------------------------------------------------------------
COMMENT:
----------------------------------------------------------------------

Thank you for working on this document; these mechanisms are important
and will help fill some long-standing gaps in CoAP operation.  That
said, I do have some fairly substantive comments that might result in
significant text changes.

While I recognize that there is going to be a spectrum of requirements
for determining freshness, I would have expected the far extreme of that
spectrum to include a strongly time-limited single-use cryptographic
nonce (akin to what the ACME protocol of RFC 8555 uses but with time
limit), as well as discussion of some points on the spectrum and which
ones might be more or less appropriate in various cases.  I do see some
discussion of different use cases, but not much about the tradeoffs
along the spectrum, and no discussion at all about the strongest
properties that it is possible to obtain with this mechanism.

In several places we mention that the Echo option enables a server to
"synchronize state", which to me is a confusing or misleading
characterization -- as I understand it, both additional (application)
protocol mechanism and constraints are required in order for state
synchronization to occur.  Specifically, the client has to be the
authority for the state in question, and the application protocol needs
to specifically indicate under what conditions and which state is to be
synchronized.  In essence, the Echo option provides a mechanism for
ensuring request freshness, and that mechanism is leveraged by the
application protocol to make a synchronzed transfer of state from client
to server.  But AFAICT it is not a generic state synchronization
mechanism, the state to be synchronized is not conveyed in the option
body, etc.  My preference would be to take "synchronize state" out of
the primary list of what is possible and mention it in a separate
sentence as something that can be constructed using the functionality
that the Echo option provides.

There are a couple places where we recommend (implicitly or explicitly)
a sequential counter in contexts that might otherwise use a randomized
value.  I think I mention them all in my section-by-section comments,
but in general the sequential counter might be placing too strong a
requirement on the value, and the considerations of
draft-gont-numeric-ids-sec-considerations seem relevant.

I think it would also be enlightening to have a comparison between the
anti-replay/freshness properties provided by the optional DTLS replay
protection mechanism and the Echo option.  I know they have differences,
but I think there is also some commonality, and giving readers guidance
on whether one vs the other suffices or both are needed could be useful.

Section 2.3

   Upon receiving a 4.01 Unauthorized response with the Echo option, the
   client SHOULD resend the original request with the addition of an
   Echo option with the received Echo option value.  [...]

[just noting that IIUC the revised requirements on token generation made
later in this document are needed in order for this "resend the original
request" to be safe" ... I am not sure if it needs to be called out here
specifically, though.]

> The cache values MUST be different for all practical purposes.

Since we're at least advocating using crypto to enforce this property, I
think that "execpt with negligible probability" would be a more
conventional expression than "for all practical purposes".

I don't think the example of this in Figure 3 meets the requirements,
though, since the echo option value is just a counter that is easily
spoofable.

   [...] When used to demonstrate
   reachability at a claimed network address, the Echo option SHOULD
   contain the client's network address, but MAY be unprotected.

What does "contain" mean, here?  Plaintext?  That seems potentially
problematic; using it as an input to the MAC that is not transmitted (as
I mention later) is more conventional, in my understanding.

                             The CoAP client side of HTTP-to-CoAP
   proxies SHOULD respond to Echo challenges themselves if they know
   from the recent establishing of the connection that the HTTP request
   is fresh.  Otherwise, they SHOULD respond with 503 Service
   Unavailable, Retry-After: 0 and terminate any underlying Keep-Alive
   connection.  If the HTTP request arrived in Early Data, the proxy
   SHOULD use a 425 Too Early response instead (see [RFC8470]).  They
   MAY also use other mechanisms to establish freshness of the HTTP
   request that are not specified here.

Where is the MUST-level requirement to actually ensure freshness (by
whatever mechanism is available/appropriate)?

Section 2.4

       *  The same Echo value may be used for multiple actuation
          requests to the same server, as long as the total round-trip
          time since the Echo option value was generated is below the
          freshness threshold.

The "round-trip" in "total round-trip time" is a bit confusing to me,
since what's being described doesn't really seem like a round-trip
operation, rather a "get a thing, do some stuff, do some more stuff,
keep sending the echo option, send a particular request to the server
that we are talking about checking the freshness of", with the final
request not very correlated to the issuance event.

   2.  A server may use the Echo option to synchronize properties (such
       as state or time) with a requesting client.  A server MUST NOT
       synchronize a property with a client which is not the authority
       of the property being synchronized.  E.g. if access to a server
       resource is dependent on time, then server MUST NOT synchronize
       time with a client requesting access unless it is time authority
       for the server.

Also, disambiguating the final "it" seems like it would be worthwhile,
just in case, since this is rather important to get right.

       *  If a server reboots during operation it may need to
          synchronize state or time before continuing the interaction.
          For example, with OSCORE it is possible to reuse a partly
          persistently stored security context by synchronizing the
          Partial IV (sequence number) using the Echo option, see
          Section 7.5 of [RFC8613].

In light of my toplevel comment, I'd suggest rewording this to clarify
that the protocol specified in RFC 8613 includes a mechanism for
resynchronizing the partial IV state, that uses the Echo option in a
specific controlled protocol interaction.

(A similar consideration would apply to the group communication example,
though it might be a little harder to write clearly.)

   3.  A server that sends large responses to unauthenticated peers
       SHOULD mitigate amplification attacks such as described in
       Section 11.3 of [RFC7252] (where an attacker would put a victim's
       address in the source address of a CoAP request).  The
       RECOMMENDED way to do this is to ask a client to Echo its request
       to verify its source address.  [...]

(editorial) this usage of "ask a client to Echo its request" seems
rather divorced from the actual mechanicis of the Echo option...in the
rest of the document (bar one other instance noted below) we restrain
ourselves to saying that the Echo option is what is echoed, divorced
from the containing request/response.

                                      This needs to be done only once
       per peer [...]

How is the "peer" identified in this case?  Is it tied to a single
(security) association, or the identity (if any) associated with that
security association, or IP address (and port?), or something else?
How long can/should the reachability information be cached for?

          reachability as described in Section 2.3.  The proxy MAY
          forward idempotent requests immediately to have a cached
          result available when the client's Echoed request arrives.

(The "Echoed request" phrasing again.)

Section 3.1

                                           In order for a security
   protocol to support CoAP operations over unreliable transports, it
   must allow out-of-order delivery of messages using e.g. a sliding
   replay window such as described in Section 4.1.2.6 of DTLS
   ([RFC6347]).

My understanding is that the requirement is only to allow out-of-order
delivery of messages (not necessarily including replay detection), so
the clause about the sliding window is not needed. here.

Section 3.2

   In essence, it is an implementation of the "proxy-safe elective
   option" used just to "vary the cache key" as suggested in [RFC7959]
   Section 2.4.

The referenced section of RFC 7959 covers Block2 operation, but my
understanding is that the Block1 operation (covered in Section 2.5 of
that same document) would be a more applicable reference.

Section 3.3

                                         Also, a client that lost
   interest in an old operation but wants to start over can overwrite
   the server's old state with a new initial (num=0) Block1 request and
   the same Request-Tag under some circumstances.  Likewise, that
   results in the new message not being part of the old operation.

Where are those "some circumstances" enumerated?

Section 3.5.1

      If any future security mechanisms allow a block-wise transfer to
      continue after an endpoint's details (like the IP address) have
      changed, then the client MUST consider messages sent to _any_
      endpoint address using the new operation's security context.

(editorial?) when I read this I feel like it's missing a clause --
consider those messages for the purposes of what operation?

   *  The client MUST NOT regard a block-wise request operation as
      concluded unless all of the messages the client previously sent in
      the operation have been confirmed by the message integrity
      protection mechanism, [...]

nit: confirmed as what?  Delivered?

      Typically, in OSCORE, these confirmations can result either from

nit: I suggest "When security services are provided by OSCORE, these
confirmations typically result from"

      In DTLS, this can only be confirmed if the request message was not
      retransmitted, and was responded to.

Similarly, this would be "When security services are provided by DTLS"
-- DTLS does include a native retransmission layer, but only for DTLS
handshake messages, so this phrasing is needlessly ambiguous as to
whether it is the CoAP request that got retransmitted.

   Authors of other documents (e.g. applications of [RFC8613]) are
   invited to mandate this behavior for clients that execute block-wise
   interactions over secured transports.  In this way, the server can
   rely on a conforming client to set the Request-Tag option when
   required, and thereby conclude on the integrity of the assembled
   body.

Could you clarify which client behavior would be mandated?  The overall
"body integrity based on payload integrity" procedures, or the specific
"typically, in OSCORE" behavior?

Also (nit), the phrasing "conclude on the integrity of" seems unusual to
me; I think the intent is more like "thereby have confidence in the
integrity of".

Section 3.5.2

   For those cases, Request-Tag is the proxy-safe elective option
   suggested in [RFC7959] Section 2.4 last paragraph.

(Per above, Section 2.5?)

Section 3.6

   The Request-Tag option is repeatable because this easily allows
   several cascaded stateless proxies to each put in an origin address.
   They can perform the steps of Section 3.5.3 without the need to
   create an option value that is the concatenation of the received
   option and their own value, and can simply add a new Request-Tag
   option unconditionally.

Thanks for including this!  However, it wasn't clear to me from reading
https://tools.ietf.org/html/rfc7252#section-5.4.5 and this document
whether the order of repeated Request-Tag options was significant.
Some clarification might be helpful.

Section 3.7

   That approach would have been difficult to roll out reliably on DTLS
   where many implementations do not expose sequence numbers, and would
   still not prevent attacks like in [I-D.mattsson-core-coap-actuators]
   Section 2.5.2.

(I agree that DTLS implementations largely don't expose sequence numbers
and that is unlikely to change.  But) I am not sure I fully understand
the scenario referenced in draft-mattsson-core-coap-actuators §2.5.2.
Perhaps it is not what was intended to be conveyed, but it seems like in
a setup that is tracking both sequence and fragment numbers, it would be
pretty easy to enforce that a fragment-0 block will only start a new
request if the sequence number is larger than the sequence number of the
current/previous blockwise request.  IIUC that would reject the
"withheld first block" as being too old.

Section 3.8

                    and MUST NOT use the same ETag value for different
   representations of a resource.

(side note) I was a little surprised that this was not already a
requirement, but I couldn't find an equivalent statement in a quick
review of RFC 7252.  (It's definitely correct that this is required
behavior to get the protection in question.)

Section 4.1

   In HTTPS, this type of binding is always assured by the ordered and
   reliable delivery as well as mandating that the server sends
   responses in the same order that the requests were received.  [...]

I believe this description applies to HTTP/1.1 over TLS, but not to
HTTP/2 or HTTP/3 (both of which provide other mechanisms for reliably
binding requests and responses in the form of stream IDs).

Section 4.2

   One easy way to accomplish this is to implement the Token (or part of
   the Token) as a sequence number starting at zero for each new or
   rekeyed secure connection.  This approach SHOULD be followed.

I note that sequential assignment often has some additional undesirable
properties, as discussed in draft-gont-numeric-ids-sec-considerations.
Would a different method (e.g., one listed in
draft-irtf-pearg-numeric-ids-generation) provide the needed properties
with fewer side effects?
In particular, sequential increment is at odds with the "nontrivial,
randomized token" recommended for clients not using TLS (that is
intended to guard against spoofing of responses).
("use of a sequence number" and "a sequence number approach" also appear
in §5.1, if this is changed.)

Section 5

   The freshness assertion of the Echo option comes from the client
   reproducing the same value of the Echo option in a request as in a
   previous response.  [...]

nit/editorial: I suggest s/as in/as it received in/

                              However, this may not be an issue if the
   communication is integrity protected against third parties and the
   client is trusted not misusing this capability.  [...]

nit: s/trusted not misusing/trusted to not misuse/

                        See ([RFC8613], Appendix B.1.1) for issues and
   solution approaches for writing to nonvolatile memory.

nit: redundant word in "solution approaches"?

   For the purpose of generating timestamps for Echo a server MAY set a
   timer at reboot and use the time since reboot, in a unit such that
   different requests arrive at different times.  [...]

Something about this sentence confuses me, possibly around "in a unit".

Section 5.1

   Tokens that cannot be reused need to be handled appropriately.  This
   could be solved by increasing the Token as soon as the currently used
   Token cannot be reused, or by keeping a list of all blacklisted
   Tokens.

editorial: perhaps "unsafe to reuse" is more clear than "blacklisted"?

Section 6

This seems to be the first (and only) place where we use the term
"preemptive Echo values"; it might be worth a bit more exposition that
these are ones piggybacked on non-4.01 responses (assuming that's
correct, of course).

Section 8.1

I note that DTLS 1.3 is in IETF Last Call.  I did not notice anything in
this document that's specific to a DTLS version, which suggests that it
woudl be safe to change the reference according to relative publication
order of these documents.  It would be good for the authors to confirm
that at their leisure, so as to not be rushed into a decision if/when
the RFC Editor asks during their processing.

Section 8.2

I note that draft-mattsson-core-coap-actuators is referenced from
several locations (for useful additional discussion, to be clear), but
it is only an individual draft that expired almost two years ago.  Is
there any likelihood that it will ever progress to an RFC?

One might argue that "SHOULD use a 425 Too Early response" is enough to
promote RFC 8470 to being a normative reference (see
https://www.ietf.org/about/groups/iesg/statements/normative-informative-references/).

Section A

   2.  Integrity Protected Timestamp.  The Echo option value is an
   integrity protected timestamp.  The timestamp can have different
   resolution and range.  A 32-bit timestamp can e.g. give a resolution
   of 1 second with a range of 136 years.  The (pseudo-)random secret
   key is generated by the server and not shared with any other party.
   The use of truncated HMAC-SHA-256 is RECOMMENDED.  With a 32-bit
   timestamp and a 64-bit MAC, the size of the Echo option value is 12
   bytes and the Server state is small and constant.  The security
   against an attacker guessing echo values is given by the MAC length.
   If the server loses time continuity, e.g. due to reboot, the old key
   MUST be deleted and replaced by a new random secret key.  Note that
   the privacy considerations in Section 6 may apply to the timestamp.
   Therefore, it might be important to encrypt it.  Depending on the
   choice of encryption algorithms, this may require a nonce to be
   included in the Echo option value.

I note that a MAC construction allows additional information to be
covered under the MAC that is not sent alongside it, e.g., identity
information about the client to which the Echo option value is being
associated.  Are there common situations in which including such
additional contextual information under the MAC would be valuable (to
prevent an echo option value received on one connection from being
usable on a different one)?

   3.  Persistent Counter.  This is an event-based freshness method
   usable for state synchronization (for example after volatile state
   has been lost), and cannot be used for client aliveness.  It requires
   that the client can be trusted to not spuriously produce Echo values.

I have severe qualms about specifying a protocol mechcanism that relies
on trusting a client to this extent.  It seems to expose a lot of latent
risk; even if we think there should be mechanisms in place to protect
against that risk, they might fail, or the mechanism might get used
outside its intended context, etc.; if there are other mechanisms
available for similar cost that provide the needed properties it seems
more robust to suggest their use in place of the persistent counter.