[Ace] AD review of draft-ietf-ace-oscore-profile-08
Benjamin Kaduk <kaduk@mit.edu> Tue, 07 January 2020 16:40 UTC
Return-Path: <kaduk@mit.edu>
X-Original-To: ace@ietfa.amsl.com
Delivered-To: ace@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 0553512095E; Tue, 7 Jan 2020 08:40:11 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -4.2
X-Spam-Level:
X-Spam-Status: No, score=-4.2 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id hqozIfN-gWu1; Tue, 7 Jan 2020 08:40:04 -0800 (PST)
Received: from outgoing.mit.edu (outgoing-auth-1.mit.edu [18.9.28.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 8819F120052; Tue, 7 Jan 2020 08:38:56 -0800 (PST)
Received: from kduck.mit.edu ([24.16.140.251]) (authenticated bits=56) (User authenticated as kaduk@ATHENA.MIT.EDU) by outgoing.mit.edu (8.14.7/8.12.4) with ESMTP id 007Gcq85029119 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 7 Jan 2020 11:38:54 -0500
Date: Tue, 07 Jan 2020 08:38:51 -0800
From: Benjamin Kaduk <kaduk@mit.edu>
To: draft-ietf-ace-oscore-profile.all@ietf.org
Cc: ace@ietf.org
Message-ID: <20200107163851.GV57294@kduck.mit.edu>
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Disposition: inline
User-Agent: Mutt/1.12.1 (2019-06-15)
Archived-At: <https://mailarchive.ietf.org/arch/msg/ace/rgVfs3dzcWQnNlXn331DdpQfwwQ>
Subject: [Ace] AD review of draft-ietf-ace-oscore-profile-08
X-BeenThere: ace@ietf.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: "Authentication and Authorization for Constrained Environments \(ace\)" <ace.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/ace>, <mailto:ace-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/ace/>
List-Post: <mailto:ace@ietf.org>
List-Help: <mailto:ace-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/ace>, <mailto:ace-request@ietf.org?subject=subscribe>
X-List-Received-Date: Tue, 07 Jan 2020 16:40:12 -0000
Hi all, Some high-level points before the section-by-section commentary: I'm a little confused by the registry we are creating in Section 9.2. While it's clear that we need something to specify the CBOR map key labels to encode the structure for transit, it's not clear that we need easy extensibility vs. a fixed table. A registry implies expectations of future additions, but draft-ietf-core-object-security did not feel a need to make a registry for future extensions; what has changed in the past few months that makes extensibility needed now? Why is this document the right place to create the registry as opposed to that one? We are in some sense defining a new substructure within "kid" values (a CBOR-encoded array of one or two elements) for usage by things using this profile. That's probably not problematic, as the "kid" can be an arbitrary bstr and its interpretation is up to the recipient -- any recipient that implements this profile will know to handle the substructure, but it does feel a little unusual and perhaps worth an early note. (IIUC, we also need to be careful about actually providing the bstr framing in our examples.) I'm concerned about the usage of "cnonce" to carry both N1 and N2, neither of which correspond to the "cnonce" behavior in the core framework; I think we should pick a different parameter name for the differeng semantic usage. Specifically, the core-framework "cnonce" is a tool to give RSes some modicum of replay protection -- it verifies that the client's authorization in the token is "fresh", since the token includes the random nonce generated by the RS and conveyd to the AS via the client. This document uses a parameter named "cnonce" in two ways: (1) to convey the client-generated nonce N1 to the RS in the authz-info request; this is giving the client contributory behavior to the ephemeral randomness input to the Security Context computation but does not provide any sort of replay-protection in and of itself (2) to convey the RS-generated nonce N2 back to the client in the authz-info response; this does serve as replay protection in some sense, but in that it serves to cause repeated posting of the same token (as might occur in a replay attack) to generate a different OSCORE context (due to the RSes contributory nature) so that the resulting key material will be unique for a given association, as opposed to detecting and blocking replay outright. I think all three uses should have distinct parameter names, based on my current understanding. We mention several times about getting protection from AEAD nonce/key reuse, but to some extent leave it to the reader to figure out how that works. Specifically, the only guidance we give on nonce selection is for our N1 and N2 that go into the Master Salt; we don't say how varying the Master Salt like that will cause the generated keys and (common) IVs to differ across runs, thus by construction preventing the collision of (key, nonce) pairs. (Implementation carelessness that just reuses key+nonce for a given Security Context is still possible, of course.) In a related vein, we do not get into full detail about the cryptographic role played by N1 and N2, so as to make the reader confident that our 64-bit recommendation does provide full Internet-grade security (as opposed to a weakened "IoT" variant). I'm not specifically concerned, but we may get some reviewers asking for more detail. I am, however, concerned about the exposure to an RFC 3552-style attacker for unprotected authz-info responses. There are two main aspects I'm concerned about: identifier selection and nonce selection. Letting the server override the client's idea of its own identity (even when the AS has given the client an identifier!) seems to increase the risk of a client being tricked into impersonating a different client, and the stated justification (letting the RS preserve uniqueness) doesn't seem to hold up in our one-AS-per-RS stated scope, where the AS can equally well do so. Based on what I know right now, it doesn't feel like we're at the right point on the cost/benefit curve. For the nonce selection, this comes into play due to the lack of injectivity for the mapping of initial AS-generated salt, N1, and N2 into the Master Salt. Specifically, if a client chooses an N1 that's a prefix of some other N1 that was used, then the attacker can send an "N2" that contains the tail end of that other N1 plus the actual N2 picked by the server in that other exchange, causing a full nonce collision and having the AS-generated portion be the only difference in Master Salt between security contexts. Using a length prefix for the fields being concatenated provides injectivity and thwarts this type of attack. There are a few places where I'm not entirely sure how the protocol flow works for the case where the RS is (re)assigning the clientId; I've tried to note them in the section-by-section comments. On to the section-by-section notes: Section 1 I'd suggest noting that this is a symmetric-crypto-based scheme in some manner (e.g., that the AS is assigning a shared symmetric key used as the OSCORE master secret), and/or that asymmetric PoP semantics are not possible with this mechanism (or OSCORE in general). I'd also suggest noting that proof of possession is not done by a dedicated protocol element, but rather occurs implicitly based on knowledge of the OSCORE Security Context. (This is essentially analogous to Kerberos, but a reference is not strictly needed.) We do have a good treatment in toplevel Section 4, but it might be worth saying earlier. Section 2 [I-D.ietf-ace-oauth-authz]. The access token request and response MUST be confidentiality-protected and ensure authenticity. This profile RECOMMENDS the use of OSCORE between client and AS, but TLS or DTLS MAY be used additionally or instead. Since the client/AS and client/RS profile are supposed to be completely severable, I don't think we should use "MAY" here; perhaps "but other protocols (such as TLS or DTLS) can be used as well". Once the client has retrieved the access token, it generates a nonce N1 and posts both the token and N1 to the RS using the authz-info endpoint and mechanisms specified in section 5.8 of [I-D.ietf-ace-oauth-authz] and Content-Format = application/ace+cbor. Do we want to say explicitly that there is no cryptographic protection applied for this POST to authz-info? which contains a nonce N2 in a CBOR map. Moreover, the server concatenates N1 with N2 and appends the result to the Master Salt in the Security Context (see section 3 of [I-D.ietf-core-object-security]). The RS then derives the complete Security Context associated with the received token from it plus the parameters received in the AS, following section 3.2 of [I-D.ietf-core-object-security]. This passage feels strange to me, probably because it seems to use "Master Salt" to both the portion with and without N1+N2, and also because it does not introduce "the Master Salt" as a term or some other object that deserves the definite article. Would it be equivalent to say "Moreover, the server concatenates the input salt, N1, and N2 to obtain the Master Salt of the OSCORE Security Context (see section 3 of [I-D.ietf-core-object-security]" instead? (Though the details may yet change based on later comments...) Is "from it" the resulting Master Salt? There seems to be a word or two missing in "the parameters received in the AS". (Presumably these parameters are contained in the token?) After receiving the nonce N2, the client concatenates it with N1 and appends the result to the Master Salt in its Security Context (see section 3 of [I-D.ietf-core-object-security]). The client then derives the complete Security Context from the nonces plus the parameters received from the AS. Similarly, IIUC we should be able to word this so that the "Master Salt" is unique (and includes the nonces), as opposed to having it apparently refer to both the pre- and post-nonce-includion strings. Are these "parameters" received from the AS in the token response? Finally, the client sends a request protected with OSCORE to the RS. If the request verifies, then this Security Context is stored in the server, and used in the response, and in further communications with the client, until token expiration. This Security Context is discarded if the same token is re-used to successfully derive a new Security Context. The conditional on storing the Security Context only if the request verifies reads oddly to me, as the RS seems to have needed to store some amount of security context information for the period betweeen receiving the token and receiving the authenticated request, as a prerequisite to being able to verify the request. Also, is this security context discarded if a new token from the same client is successfully used? The use of random nonces during the exchange prevents the reuse of AEAD nonces and keys with different messages, in case of re- derivation of the Security Context both for Clients and Resource Servers from an old non-expired access token, e.g. in case of re-boot of either the client or RS. In fact, by using random nonces as part This sentence is pretty long and a little hard to parse. I'd suggest something more like: % The use of random nonces during the exchange prevents the reuse of % an AEAD nonces/key pair for two different messages. This situation % might occur when client and RS derive a new Security Context from an % existing (non-expired) access token, as might occur when either party % has just rebooted. [...] I'd also consider s/In fact/Instead/ since we are contrasting the previously described hypothetical (bad) scenario with what actually happens. of the Master Salt, the request to the authz-info endpoint posting the same token results in a different Security Context, since Master Secret, Sender ID and Recipient ID are the same but Master Salt is different. Therefore, the main requirement for the nonces is that nit: [more usage of "Master Salt" for pre- and post-nonce forms] I'd also suggest to s/since/since even though the/ (and the s/but/the/ needed to fix up the end of the sentence). I also want to check my understanding: this "different Security Context" is still going to use the same identifiers for the endpoints, and will just have different keys/IVs/etc? This would tie in to the (later) recommendation to have such a new Security Context completely replace the old one, since otherwise we'd have to resort to trial decryption to determine which Security Context to use for processing a given message. they have a good amount of randomness. If random nonces were not used, a node re-using a non-expired old token would be susceptible to on-path attackers provoking the creation of OSCORE messages using old AEAD keys and nonces. I guess the focus on "good amount of randomness" is trying to emphasize that we merely need to avoid a single node accidentally producing the same value, as opposed to a stricter property of unguessability by an on-path attacker? Or is unguessability also needed when the attacker can delay traffic? Section 3 Section 3.2 of [I-D.ietf-core-object-security] defines how to derive a Security Context based on a shared master secret and a set of other parameters, established between client and server, which the client receives from the AS in this exchange. The proof-of-possession key We say that the client gets the OSCORE parameters from the AS in the token response; where do we say how the RS gets the OSCORE parameters from the AS? Section 3.1 The client MUST send this POST request to the token endpoint over a secure channel that guarantees authentication, message integrity and confidentiality (see Section 5). (The framework already requires this, so we may not need the "MUST" keyword again, though I'm not proposing to remove all mention of the need for these properties.) An example of such a request, in CBOR diagnostic notation without the tag and value abbreviations is reported in Figure 2 nit: only the payload is using CBOR diagnostic notation; the headers are using CoAP notation. If the client wants to update its access rights without changing an existing OSCORE Security Context, it MUST include in its POST request to the token endpoint a req_cnf object. The req_cnf MUST include a kid field carrying a CBOR array object containing the client's identifier (assigned in section Section 3.2) and optionally the context identifier (if assigned in section Section 3.2). The CBOR I'm not sure the best way to write a clear description that includes the "bstr" framing for "kid". Also, nit: the "assigned" language in the parentheticals feels weird to me, here. What's the workflow when the RS has overridden the AS's idea of the clientId? Does the client have to remember the original AS-assigned clientId and use it here instead of the RS-assigned one? These identifiers can be used by the AS to determine the shared secret to construct the proof-of-possession token and therefore MUST identify a symmetric key that was previously generated by the AS as a shared secret for the communication between the client and the RS. nit: I suggest s/shared secret to construct/shared secret bound to/ Also, I think the AS will need to use some of the other token request parameters (e.g., req_aud) in order to determine the client and RS for which it needs to retrieve the shared PoP key. We might want to mention that as well. The AS MUST verify that the received value identifies a proof-of- possession key and token that have previously been issued to the requesting client. If that is not the case, the Client-to-AS request nit: It's not clear that we need it to identify a specific token, just a key. (And in fact for multiple successive access-rights updates, there will be more than one previous token.) The "kid" "req_cnf" member in Figure 4's example does not include the bstr wrapper that draft-ietf-ace-cwt-proof-of-possession suggests is required. Section 3.2 Moreover, the AS MUST provision the following data: It's frequently the case in IETF documents that "provision" is a euphimism for "out-of-band configuration", so if we mean "include in the token response" it's probably better to say that directly. Additionally, the AS MAY provision the following data, in the same response. When the AS does not do so, how are these parameters determined? The OSCORE_Security_Context is a CBOR map object, defined in Section 3.2.1. The master secret MUST be communicated as the 'ms' field in the OSCORE_Security_Context in the 'cnf' parameter of the access token response as defined in Section 3.2 of [I-D.ietf-ace-oauth-params]. The AEAD algorithm MAY be included as nit: s/in the OSCORE_Security_Context/in the OSCORE_Security_Context field/, I think? the 'alg' parameter in the OSCORE_Security_Context; the HKDF algorithm MAY be included as the 'hkdf' parameter of the OSCORE_Security_Context, a salt MAY be included as the 'salt' parameter of the OSCORE_Security_Context, and the replay window type and size MAY be included as the 'rpl' of the OSCORE_Security_Context, as defined in Section 3.2.1. I think we want to reword all of these, as I understand what we're doing to be defining the parameters in which these values are conveyed, if they are conveyed at all. Just saying "<X> MAY be conveyed in <Y>" has the connotation that <X> might alternatively be conveyed in some other <Z> that is not mentioned. The relevant MAY for our purposes is the one above the list -- "the AS MAY provision the following data". The same parameters MUST be included as metadata of the access token. This profile RECOMMENDS the use of CBOR web token (CWT) as specified in [RFC8392]. If the token is a CWT, the same OSCORE_Security_Context structure defined above MUST be placed in the 'cnf' claim of this token. nit: "metadata of the access token" sounds like it's trying to be a term of art, but it is not presently used as such. s/metadata/attributes/ would, IIUC, be more in keeping with OAuth 2.0 tradition. not-nit: the second sentence seems redundant with the second sentence of the previous paragraph. The AS MUST also assign an identifier to the RS (serverId), MAY assign an identifier to the client (clientId), and MAY assign an identifier to the context (contextId). These identifiers are then used as Sender ID, Recipient ID and ID Context in the OSCORE context as described in section 3.1 of [I-D.ietf-core-object-security]. The couple (client identifier, context identifier) MUST be unique in the set of all clients on a single RS. Moreover, when assigned, serverId, clientId and contextId MUST be included in the OSCORE_Security_Context, as defined in Section 3.2.1. [Any time we're assigning identities we have to say something about the privacy properties thereof, or a bunch of reviewers will complain.] Is the Recipient ID expected to be stable/persistent for a given RS as seen by all clients? nit: "all clients on a single RS" reads oddly to me; maybe s/on/of/? nit: I'd suggest to replace "couple" with "tuple" or "pair". nit: serverId is always assigned by the AS, so the "when assigned" doesn't quite bind properly, grammar-wise. While the clientId is "always assigned" by the time of the Master Secret derivation, this is just discussing the AS token response, so we can't necessarily assume it's assigned here, at least with the current protocol spec. OSCORE requires a Sender ID and Recipient ID, but we only have it as optional for the AS to assign the clientId -- what does OSCORE use as the Sender/Recipient ID when the AS does not assign a clientId? When certain fields are optional, we typically have to ask whether it's possible for the two parties to disagree about whether the field is present. IIUC, the OSCORE context derivation procedure includes enough information to prevent that possibility, but it would be good if someone would confirm that. We assume in this document that a resource is associated to one single AS, which makes it possible to assume unique identifiers for each client requesting a particular resource to a RS. If this is not I feel like this might be more clear if we can frame it in terms of the AS enforcing the uniqueness of client identifiers (or, if you will, that we delegate the enforcement thereof to the AS...) the case, collisions of identifiers may appear in the RS, in which case the RS needs to have a mechanism in place to disambiguate identifiers or mitigate their effect. nit: s/appear in/occur at/ nit: s/mitigate their effect/mitigate the effect of the collisions/ Note that in Section 4.3 C sets the Sender ID of its Security Context to the clientId value received and the Recipient ID to the serverId value, and RS does the opposite. (The way this is written implicitly assumes that both clientId and serverId are received from the AS.) Figure 5 shows an example of such an AS response, in CBOR diagnostic notation without the tag and value abbreviations. I'd suggest s/such an AS response/an AS token response/ "access_token" : h'a5037674656d7053656e73 ...' (remainder of access token omitted for brevity)', In addition to the invalid-CBOR-diagnostic-notation-syntax comment, we also have unbalanced quotes. "profile" : "coap_oscore", "expires_in" : "3600", "cnf" : { "OSCORE_Security_Context" : { "alg" : "AES-CCM-16-64-128", "clientId" : b64'qA', "serverId" : b64'Qg', Any reason to prefer b64'qA' over h'a8' which is shorter? If the client has requested an update to its access rights using the same OSCORE Security Context, which is valid and authorized, the AS MUST omit the 'cnf' parameter in the response, and MUST carry the client identifier and optionally the context identifier in the 'kid' field in the 'cnf' parameter of the token, with the same structure I think we should be careful about referring to this as "optionally the context identifier" -- the choice for whether there is a context identifier is made once (at initial issuance), and subsequent usage depends on whether one has been allocated or not. It's not like the AS can decide at runtime "I gave you a context identifier for your original security context, but I don't feel like giving it to you again" -- the derived keys won't match up and it won't be reusable as the same security context. Also, I'm not sure this is fully defined for the case when the RS overrides the AS's clientId assignment, as the kid array in the token needs to be the value the RS will know, but the kid in req_cnf needs to be the one the AS knows, and we don't really define a mechanism for the AS to be able to do translation from one to the other. defined in Figure 3. These identifiers need to be provisioned, in order for the RS to identify the previously generated Security Context. nits: there's only one (not "these") identifier in the token, and nothing in the token response; and a similar remark about "provisioned" as was made above. Figure 9 shows an example CWT, containing the necessary OSCORE parameters in the 'cnf' claim for update of access rights, in CBOR diagnostic notation without tag and value abbreviations. { "aud" : "tempSensorInLivingRoom", "iat" : "1360189224", "exp" : "1360289224", "scope" : "temperature_h", "cnf" : { "kid" : b64'qA' I don't think this "kid" is a valid CBOR bstr wrapping the one- or two-element array. Section 3.2.1 [I-D.ietf-core-object-security]). The OSCORE_Security_Context object can either be encoded as JSON object or as CBOR map. In both cases, nits "a JSON object", "a CBOR map". defined below. All parameters are optional. Table 1 provides a summary of the OSCORE_Security_Context parameters defined in this section. They're optional to appear in the OSCORE_Security_Context object that's included in a "cnf" value, but not necessarily optional for OSCORE to be usable. What do we do for OSCORE when any given parameter is not present in this structure? (Also, doesn't the AS always have to provide things like 'ms' and 'serverId'?) | hkdf | 4 | bstr / int | COSE | OSCORE HKDF | | | | | Algorithm | value | | | | | Values | | | | | | (HMAC-based) | | Should be tstr, not bstr, right? Also, why do we need the string form of either hkdf or alg? More possibilities makes the decoder more complicated and increases the attack surface. | rpl | 8 | bstr / int | | OSCORE Replay | | | | | | Window Type | | | | | | and Size | Should just be bstr (not int), right? hkdf: This parameter identifies the OSCORE HKDF Algorithm. For more information about this field, see section 3.1 of [I-D.ietf-core-object-security]. The values used MUST be registered in the IANA "COSE Algorithms" registry and MUST be HMAC-based HKDF algorithms. The value can either be the integer It's a little unfortunate that we basically are relying on "I know it when I see it" for determining which algorithms are HKDF algorithms. Also, "HKDF" expands to "HMAC-based Extract-and-Expand Key Derivation Function", i.e., is definitionally HMAC-based. So this should be reworded to reflect the actual intent. alg: This parameter identifies the OSCORE AEAD Algorithm. For more information about this field, see section 3.1 of [I-D.ietf-core-object-security] The values used MUST be registered in the IANA "COSE Algorithms" registry and MUST be AEAD algorithms. The value can either be the integer or the text Similarly, this seems to be "I know it when I see it". contextId: This parameter identifies the security context as a byte string. This identifier is used as OSCORE ID Context. For more information about this field, see section 3.1 of [I-D.ietf-core-object-security]. In JSON, the "contextID" value is a Base64 encoded byte string. In CBOR, the "contextID" type is bstr, and has label 7. Do we need to forbid present-but-empty contextIds in order to avoid cryptographic collision with absent-contextId? rpl: This parameter is used to carry the OSCORE value, encoded as a bstr. This parameter identifies the OSCORE Replay Window Size and Type value, which is a byte string. For more information about this field, see section 3.1 of [I-D.ietf-core-object-security]. In JSON, the "rpl" value is a Base64 encoded byte string. In CBOR, the "rpl" type is bstr, and has label 8. I tried to follow the reference, but I couldn't really find a description of the encoding for this as a byte string (especially noteworthy since we claim that it represents both size and type). (Relatedly, I'm not sure why it's allowed to be either bstr or int.) Section 4 Can we get some CDDL or similar for both C-to-RS and RS-to-C (in the respective subsections)? I'd naively expect a section titled "Client-RS Communication" to include some discussion of normal protected OSCORE request/response pairs once the security context is fully established, but this initial section basically only talks about the authz-info interaction and disclaims that the subsections will cover anything else. The following subsections describe the details of the POST request and response to the authz-info endpoint between client and RS. The client generates a nonce N1 and posts it together with the token that includes the materials provisioned by the AS to the RS. The RS then derives a nonce N2 and use Section 3.2 of nits: "provisioned" again, and the RS is going to be generating a nonce from scratch, not deriving one from ... anything else, really. [I-D.ietf-core-object-security] to derive a security context based on a shared master secret and the two nonces, established between client and server. (The shared master secret is part of what the AS provisions^Wgives to the RS, right?) Note that the proof-of-possession required to bind the access token to the client is implicitly performed by generating the shared OSCORE Security Context using the pop-key as master secret, for both client and RS. An attacker using a stolen token will not be able to generate a valid OSCORE context and thus not be able to prove possession of the pop-key. It may be worth saying something roughly equating "proof of possesion performed by the RS" and "the RS authenticating itself to the client", since there is not an external action for server authentication. Also, ISTR getting some pushback on a different document that talked about an attacker with a "stolen token", as something that can steal a token from the client's local storage might also steal the associated key. I forget if we ended up changing to some other phrasing or not, though :( Section 4.1 The client MUST generate a nonce N1 very unlikely to have been previously used with the same input keying material. This profile RECOMMENDS to use a 64-bit long random number as nonce. The client Why 64 instead of 128? I know that 128 is enough without having to think about it; for 64 we have to be clear about what role the nonce is serving. Note that the use of the payload and the Content-Format is different from what described in section 5.8.1 of [I-D.ietf-ace-oauth-authz], which only transports the token without any CBOR wrapping. In this profile, the client MUST wrap the token and N1 in a CBOR map. The client MUST use the Content-Format "application/ace+cbor" defined in section 8.14 of [I-D.ietf-ace-oauth-authz]. The client MUST include the access token using the correct CBOR label (e.g., "cwt" for CWT, "jwt" for JWT) and N1 using the 'cnonce' parameter defined in section 5.1.2 of [I-D.ietf-ace-oauth-authz]. That's not what the 'cnonce' parameter is for -- 'cnonce' is protecting the RS against replay, but N1 is protecting the client. I think we need to use a different name (and maybe define some integer map label values?) for this authz-info POST body. The access token MUST be encrypted, since it is transferred from the client to the RS over an unprotected channel. This is probably worth stating in Section 3.2 as well, where we discuss the AS-to-C token response in more detail. Note that a client may be required to re-POST the access token, since an RS may delete a stored access token, due to lack of memory. I'd suggest using the phrase "at any time" and noting that the client will detect this by receiving an AS Request Creation Hints message since the RS treated the request as an Unauthorized Resource Request, perhaps: % Note that a client may be required to re-POST the access token in % order to complete a request, since an RS may delete a stored access % token at any time, for example due to all storage space being % consumed. This situation is detected by the client when it receives % an AS Request Creation Hints response. Payload: { "access_token": h'a5037674656d7053656e73 ...' (remainder of access token omitted for brevity)', "cnonce": h'018a278f7faab55a' } This does not appear to be using either a "cwt" label or "jwt" label, as the second paragraph of the section would have us using. Section 4.2 token. If the token is valid, the RS MUST respond to the POST request with 2.01 (Created). If the token is valid but is associated We probably don't need to repeat the normative requirements from the core framework with normative keywords again. to claims that the RS cannot process (e.g., an unknown scope), or if any of the expected parameters in the OSCORE_Security_Context is Hmm, "associated to claims that the RS cannot process" sounds like we're telling the RS to abort if the token includes any unrecognized claims, which IIUC is at odds with the OAuth 2.0 philosophy of ignoring unrecognized parameters. (Hopefully someone will correct me if I'm misremembering that.) missing (e.g. any of the mandatory parameters from the AS), or if any nit: comma after "e.g.". Additionally, the RS MUST generate a nonce N2 very unlikely to have been previously used with the same input keying material, and send it within the 2.01 (Created) response. The payload of the 2.01 (Created) response MUST be a CBOR map containing the 'cnonce' parameter defined in section 5.1.2 of [I-D.ietf-ace-oauth-authz], set to N2. This profile RECOMMENDS to use a 64-bit long random number as nonce. Moreover, if the OSCORE_Security_Context in the token did not As above, we need to use a different name than 'cnonce', as it's performing a different role (this time, contributing entropy to the master secret). (Also, if we change our recommendation about nonce length above we should do so here as well, of course.) contain a 'clientId' parameter, the RS MUST generate an identifier, unique in the set of all its existing client identifiers, and send it in a 'clientId' parameter in the CBOR map as a CBOR bstr. The RS MAY generate and send a 'ClientId' identifier even though the OSCORE_Security_Context contained such a parameter, in order to guarantee the uniqueness of the client identifier. The RS MUST use I'm not sure I understand the case where the AS wouldn't be able to guarantee uniqueness of ClientId, and wonder if we could simplify by always having the AS make ID assignment. Is there some more background/usage scenarios here that I'm missing? When receiving an updated access token with updated authorization information from the client (see section Section 3.1), it is RECOMMENDED that the RS overwrites the previous token, that is only the latest authorization information in the token received by the RS is valid. This simplifies for the RS to keep track of authorization information for a given client. [this same recommendation is already in the core framework] Section 4.3 the 'clientId' in the CBOR map in the payload of the response. Then, the client MUST set the Master Salt of the Security Context created to communicate with the RS to the concatenation of salt, N1, and N2, in this order: Master Salt = salt | N1 | N2, where | denotes byte string concatenation, and where salt was received from the AS in Section 3.2. The client MUST set the Master Secret and Recipient ID I think it's general best practice to use an injective mapping of the inputs to the Master Salt value (i.e., length-prefixes for the various fields, since there are no reserved octet values). from the parameters received from the AS in Section 3.2. The client MUST set the AEAD Algorithm, ID Context, HKDF, and Replay Window from the parameters received from the AS in Section 3.2, if present. In case these parameters are omitted, the default values are used as described in section 3.2 of [I-D.ietf-core-object-security]. The Ah, okay; I'd asked about default values earlier. That said, if stock OSCORE ever changes the defaults we'd have to come up with a compatibility story for communication between old/new nodes. client MUST set the Sender ID from the 'clientId in the 2.01 (Created) response, if present; otherwise, the client MUST set the Sender ID from the parameters received from the AS in Section 3.2. [As written, this has the clientId from the RS take precedence over the one from the AS when both are present. I understand that the claimed justification is for the RS to be able to enforce clientId uniqueness, but it still feels risky, since the value from the RS is unauthenticated.] If any of the expected parameters is missing (e.g. any of the mandatory parameters from the AS, or the 'clientId', either received from the AS or in the 2.01 (Created) response from the RS), the client MUST stop the exchange, and MUST NOT derive the Security Context. The client MAY restart the exchange, to get the correct security material. I think this means "restart at the AS" but it's probably worth being very explicit about it. Also, is there anything to be said about rate-limiting/backoff for persistent missing parameters? After sending the 2.01 (Created) response, the RS MUST set the Master Salt of the Security Context created to communicate with the client to the concatenation of salt, N1, and N2, in this order: Master Salt = salt | N1 | N2, where | denotes byte string concatenation, and [It might be worth breaking this computation off into a standalone piece of text that applies to both C and RS, including the edits for injectivity.] where salt was received from the AS in Section 4.2. The RS MUST set the Master Secret, Sender ID and Recipient ID from the parameters, received from the client in the access token in Section 4.1 after nit: I'd place the emphasis more on "in the access token" or even "from the AS" rather than "from the client" -- the RS/AS preestablished relationship is what authenticates these values. validation of the token as specified in Section 4.2. The RS MUST set Does Section 4.2 really say much about validation other than "RS MUST verify the validity of the token"? [I-D.ietf-core-object-security]. After that, the RS MUST derive the complete Security Context following section 3.2.1 of [I-D.ietf-core-object-security], and MUST associate this Security Context with the authorization information from the access token. side note: it's sometimes useful as a rhetorical device to have a discussion of the abstract data model the RS uses -- in this case, that it maintains a collection of Security Contexts with associated authorization information, for all the clients that it's currently communicating with, and that the authorization information is policy that's used as input to processing requests from those clients. Otherwise, this text about "MUST associate" can be a bit vague to the reader. The RS then uses this Security Context to verify the request and send responses to C using OSCORE. If OSCORE verification fails, error (nit?) what is "the request"? I don't think we've talked about a specific OSCORE request yet, so this would probably be better if talking about generic incoming requests from a given client. responses are used, as specified in section 8 of [I-D.ietf-core-object-security]. Additionally, if OSCORE verification succeeds, the verification of access rights is performed as described in section Section 4.4. The RS MUST NOT use the Security Context after the related token has expired, and MUST respond with a unprotected 4.01 (Unauthorized) error message. nit: I suggest "MUST respond with an unprotected [...] error message to requests received that correspond to a security context with an expired token" to tie it back to which requests are affected. If the exchange was an update of access rights, i.e. a new Security nit: comma after "i.e.". Context was derived from a client that already had a Security Context in place, the is RECOMMENDED to delete the old Security Context after OSCORE verification and verification of access rights succeed. The RS MUST delete the Security Context if it deletes the access token associated to it. I'm not sure I understand what the workflow is, here -- I assume that the deletion of the old security context occurs after a successful update via the authz-info endpoint (as opposed to some particular OSCORE-protected request), but I don't know what "verification of access rights" could be performed at that time. Aren't access rights mostly tied to a specific operation, or is this just supposed to be a more generic audience/scope check? Section 4.4 The RS MUST follow the procedures defined in section 5.8.2 of [I-D.ietf-ace-oauth-authz]: if an RS receives an OSCORE-protected request from a client, then the RS processes it according to [I-D.ietf-core-object-security]. If OSCORE verification succeeds, and the target resource requires authorization, the RS retrieves the nit(?): is it appropriate to say "requires additional authorization" (over the implicit authorization given to any authenticated client)? I'm not sure if that would be confusing or not. authorization information from the access token associated to the Security Context. The RS then MUST verify that the authorization information covers the resource and the action requested. In the vein of my previous note about an abstract data model, we may not want to be overly prescriptive about "retrieves [...] from the access token". Per-request introspection is allowed, as is caching the authorization information in a non-token local datastore. I'd also consider rephrasing to "MUST verify that the resource and action requested are authorized", since "covers" is perhaps a little vague. The response code MUST be 4.01 (Unauthorized) in case the client has not used the Security Context associated with the access token, or if RS has no valid access token for the client. If RS has an access The causality here seems a bit weird; how would the RS know what token was intended just from an OSCORE request that's using a random or different security context? token for the client but not for the resource that was requested, RS MUST reject the request with a 4.03 (Forbidden). If RS has an access I'd suggest rephrasing this to be in terms of authorization rather than "token for X", perhaps as "if the RS has an access token for the client but no actions are authorized on the target resource" token for the client but it does not cover the action that was requested on the resource, RS MUST reject the request with a 4.05 (Method Not Allowed). Similarly, perhaps "but the requested action is not authorized". Also, don't both of these descriptions have high overlap with Section 5.8.2 of the core framework? Is it necessary to reiterate those behavior specifications? Section 5 Thank you for clearly stating that the OSCORE security contexts between RS/AS and C/AS must be established independently of any of the mechanisms defined in this document, and that the protocols used for the C/RS, C/AS, and RS/AS steps can be selected independently. Furthermore the requesting entity and the AS communicate using OSCORE ([I-D.ietf-core-object-security]) through the introspection endpoint as specified in section 5.7 of [I-D.ietf-ace-oauth-authz] and through the token endpoint as specified in section 5.6 of [I-D.ietf-ace-oauth-authz]. I'm not entirely sure what this sentence is trying to say -- it comes across a little bit as saying that when this document is in use, the indicated interactions also use OSCORE, but that of course can't be what's actually intended. Perhaps just saying that the behavior of the introspection endpoing is specified in section 5.7 of [framework] and that of the token endpoint is specified in section 5.6 of [framework] would suffice? Section 6 o the client receives a number of 4.01 Unauthorized responses to OSCORE requests using the same security context. The exact number needs to be specified by the application. Is this a global counter or does it get reset by a successful OSCORE response? o the client receives a new nonce in the 2.01 (Created) response (see Section 4.2) to a POST request to the authz-info endpoint, when re-posting a non-expired token associated to the existing context. Why is "non-expired" specifically relevant? The RS MUST discard the current security context associated with a client when: o Sequence Number space ends. o Access token associated with the context expires. nit: we should make the grammar of the list elements parallel to the client's list, so "the Sequence Number space ends." and "the access token associated with the context expires". Section 7 We talk about both nonces as needing to be "very unlikely to have been previously used", and it might be worth trying to quantify that (e.g., "chance of inadvertent collision less than 2^-32"). As alluded to in my high-level point, we should have more discussion of the consequences of the authz-info exchange being completely unprotected. a secure binding between the request and the response(s). Thus the basic OSCORE protocol is not intended for use in point-to-multipoint communication (e.g. multicast, publish-subscribe). Implementers of nit: comma after "e.g.". provoke re-use. If that is not guaranteed, nodes are still susceptible to re-using AEAD nonces and keys, in case the Security Context is lost, and on-path attacker replay messages. This text is talking about AEAD nonces, but the nonces (and 64-bit recommendation) previously discussed are the nonces used in the Master Salt (and thus Master Secret) calculation; we don't really talk about AEAD nonces specifically anywhere in the document, other than to point out the risk of (nonce, key) reuse. IIUC, vulnerable nodes would need to reuse both the N1 or N2 values defined in this spec as well as the OSCORE partial IV in order to collide the AEAD (nonce, key) pair (noting that both key and common IV are influenced by the Master Salt). That said, if the N1 generation is flawed it seems quite plausible that PIV generation is similarly flawed, so we are right to document the concern. Also, the grammar here is a little bit weird, so perhaps a rewording to: % provoke re-use. If that is not guaranteed, nodes are % susceptible to re-use of AEAD (nonces, keys) pairs, especially since an on-path % attacker can cause the client to use an arbitrary nonce for Security % Context establishment. Even partial loss of Security Context information % can allow an on-path attacker to replay messages. though I'm not entirely sure I understand which replay scenarios you had in mind. This profiles recommends that the RS maintains a single access token nit: "This profile" singular. Also, tokens may contradict each other which may lead the server to enforce wrong permissions. If one of the access tokens expires Could you give me an example of the contradiction scenarios? I see the "common" case as being roughly "Token T1 gives access to the set X of resources and token T2 gives access to a partially disjoint set Y of resources", but I don't know that such a scenario would be considered a "conflict". To get a conflict I'd expect more like "token T1 indicates that access to X is to be denied, but token T2 indicates that access to X is to be allowed" with some sort of explicit negative ACL, but I don't think OAuth really has a concept of negative ACL. Section 8 There might be a few more privacy considerations worth mentioning: - the token is sent in the clear to the authz-info endpoint, so if a single token is used with multiple audiences or RSes, a client that uses the same token from multiple locations can be tracked/correlated by the access token's value. - the nonces exchanged in the authz-info exchange are also sent in the clear, so using random nonces is best for privacy (as opposed to, e.g., a counter, that might leak some information). - the identifiers clientId/serverId that are created/assigned for this protocol have some privacy considerations; they overlap a lot with the core OSCORE considerations in terms of the potential privacy consequences but there might be a little more to say about guidelines for how the identifiers are generated. If I'm reading OSCORE correctly, for the uses specified in this document only the clientId will actually go on the wire? - similarly, there may be considerations for the ID context values. Section 9.1 o Profile Description: Profile for using OSCORE to secure communication between constrained nodes using the Authentication and Authorization for Constrained Environments framework. This is the registry for ACE profiles; "using the Authentication and Authorization for Constrained Envirornments framework" feels redundant. There's also perhaps something to say about defining "coap_oscore" for all three interaction flows even though the procedures for two of the three are essentially just "out of the scope of this specification", though having *some* identifier for "use OSCORE" is probably still useful. Section 9.2 name The JSON name requested (e.g., "ms"). Because a core goal of this specification is for the resulting representations to be compact, it is RECOMMENDED that the name be short. This name is case sensitive. Names may not match other registered names in a case-insensitive manner unless the Designated Experts state that there is a compelling reason to allow an exception. The name is nit: I'd suggest s/state/determine/ CBOR label The value to be used to identify this algorithm. Key map labels MUST be unique. The label can be a positive integer, a nit: s/Key map/Map key/ negative integer or a string. Integer values between 0 and 255 and strings of length 1 are designated as Standards Track Document required. Integer values from 256 to 65535 and strings of length 2 are designated as Specification Required. Integer values of greater than 65535 and strings of length greater than 2 are designated as expert review. Integer values less than -65536 are marked as private use. So use of negative integers from -65535 to -1 and positive integers greater than or equal to 65536 is not defined? I'd also consider listing [I-D.ietf-core-object-security] as an additional reference for the initial entries, since that specifies the actual semantics of the fields in question. Section 9.3 "OSCORE_Security_Context" feels like a somewhat long name in light of the previous commentary about shorter names being preferred. :) o Confirmation Method Description: OSCORE_Security_Context carrying the OSCORE Security Context parameters I'd suggest rewording the description to "parameters for using OSCORE per-message security with implicit key confirmation" Section 9.4 [same suggested rewording] Section 9.5 Thank you for indicating in which direction the various considerations should sway the experts' decisions, as opposed to just what the experts should consider. :) The IANA registry established in this document is defined as expert review. This section gives some general guidelines for what the nit: I suggest "defined to use the Expert Review registration policy". The zones tagged as private use are intended for testing purposes and closed environments, code points in other ranges should not be assigned for testing. nit: comma splice o Specifications are required for the standards track range of point assignment. Specifications should exist for specification required ranges, but early assignment before a specification is available is considered to be permissible. Specifications are side note: this is a little awkward, as RFC 7120 formally does not allow "early allocations" for the "Expert Review" policy, so there is not a formal procedure in place to review and expire early allocations that end up not being needed. It might be worth something to chat with the IANA table about in Vancouver. Section 10.2 We might get some sticklers asking for the terminology references to be made normative, but I'm not concerned about it one way or the other for now. Appendix A Thank you for assembling this in list form for me. Do we expect to keep this content in the final RFC? If we do, we should resynchronize to the current list in Appendix C of the framework :) o how/if the authz-info endpoint is protected: Security protocol above I thought authz-info was fully unprotected, per Section 4.1's "The authz-info endpoint is not protected, nor are the responses from this resource." Thanks, Ben
- [Ace] AD review of draft-ietf-ace-oscore-profile-… Benjamin Kaduk
- Re: [Ace] AD review of draft-ietf-ace-oscore-prof… Francesca Palombini
- Re: [Ace] AD review of draft-ietf-ace-oscore-prof… Jim Schaad
- Re: [Ace] AD review of draft-ietf-ace-oscore-prof… Benjamin Kaduk
- Re: [Ace] AD review of draft-ietf-ace-oscore-prof… Benjamin Kaduk
- Re: [Ace] AD review of draft-ietf-ace-oscore-prof… Francesca Palombini
- Re: [Ace] AD review of draft-ietf-ace-oscore-prof… Benjamin Kaduk
- Re: [Ace] AD review of draft-ietf-ace-oscore-prof… Francesca Palombini