Subject: [OAUTH-WG] MAC: more comments on draft-hammer-oauth-v2-mac-token-02

From: "Manger, James H" <[email-masked]>
Date: Fri, 4 Feb 2011 16:22:54 +1100

Comments on draft-hammer-oauth-v2-mac-token-02
<http://tools.ietf.org/html/draft-hammer-oauth-v2-mac-token-02>

This draft is a good improvement.

(continuing numbering from my previous comments)

11. The "access token" field would be better labelled "id". The MAC scheme
only needs this field to identify the MAC secret. The MAC scheme itself
doesn't need to care whether this id also represents a scope, duration,
assertion etc.

Though it may slightly complicated the use of the MAC scheme with OAuth2,
I would seriously consider supporting two identifiers:
* An authentication id -- to identify the key used to verify the MAC; and
* An authorization id -- to identify the scope/account/permissions/duration...
 that the client want to act under.
The SASL framework has these two concepts
[RFC4422 Simple Authentication and Security Layer (SASL)].
Any modern SASL authentication mechanism will be expected to support both ids.
The authorization id is a good match for an OAuth2 token or other sort of 
assertion.
The OAuth2-to-MAC binding could define a 'keyid' parameter to accompany the 
'secret'.
The 'keyid' value would map to the authentication id field in the MAC scheme,
and the 'access_token' would map to the authorization id field.

12. Which bytes does the body hash apply to? Is it the "message-body" or
"payload body" (in HTTPbis parlance)? I assume any Transfer-Encoding (eg
chunked) is removed before calculating the body hash, but any Content-Encoding
(eg gzip) is not removed. The spec should explicitly state this. [c.f. wording
as for the "Content-MD5" header in draft-ietf-httpbis-p3-payload-12, section
6.8]

13. The MAC algorithm should be explicitly indicated in the request, instead
of being implied by the access-token/id. I suggest including an "algorithm"
parameter in the "Authorization" request header. I also suggest including an
"algorithms" parameter in the "WWW-Authenticate" response header that is a
(comma-separated?) list of MAC algorithms that the server supports.

14. Explicitly state in section 3.3.2 (and 3.3.3) that SHA-1 (and SHA-256) are
used to calculate the body hash when using the hmac-sha-1 (and hmac-sha-256)
algorithm.

15. 3.3.2 (and 3.3.3) shouldn't mention the OAuth-specific "authorization
server" (when defining their "key" field).

16. OAuth2 can provide a "secret" as a Unicode string. MAC algorithms such as
HMAC use a key that is a byte array. Section 2 of the MAC spec says 'secret'
can only include printable ASCII chars (except " and /). This is not quite
right.
The MAC scheme should expect 'secret' to be a byte array (ie not limit its
chars). A 'secret' string from an OAuth2 response should be UTF-8 encoded to
produce the byte array the MAC scheme uses.

17. This MAC scheme should be compared to the SCRAM SASL mechanism [RFC 5802].
SCRAM is the latest-and-greatest authentication mechanism based on a shared 
secret
(without using the brilliant, but patent-troubled, zero-knowledge proof 
techniques).
It has quite a few features that MAC is missing: two ids (auth & authz);
credentials at the server are not sufficient to impersonate the client
(not a "password-equivalent"); mutual authentication; channel binding
(to an underlying TLS secure tunnel).
I don't think MAC can achieve all these properties. The MAC scheme almost 
certainly
wants to avoid multiple exchanges at the HTTP layer. I expect the wider IETF
community to judge MAC by comparing it negatively to SCRAM unless the document
is quite clear about its constraints (eg sign an HTTP request without any
interactivity with the server; suitable for shared secret keys, but not for
shared passwords...).

--
James Manger

-----Original Message-----
From: [email-masked] [mailto:[email-masked]] On Behalf Of
Manger, James H
Sent: Tuesday, 11 January 2011 5:05 PM
To: OAuth WG
Subject: [OAUTH-WG] MAC: comments on draft-hammer-oauth-v2-mac-token-00

Comments on draft-hammer-oauth-v2-mac-token-00
<http://tools.ietf.org/html/draft-hammer-oauth-v2-mac-token-00>

1. The connection of this MAC scheme to OAuth is secondary. The primary
function of the MAC scheme is to secure the authenticity of parts of an HTTP
request using a shared secret. Section 2 "Issuing MAC-Type Access Tokens"
would be better at the end, ideally as an Annex, along with most of the OAuth
talk from the introduction (and title).

2. Include a \n after the final query string parameter.
It makes the format simply lines of text, instead of making the last line
special (and only special if there are query params). It is awkward to
manually edit sample files, debug files etc without a final newline character.
Adding a final \n would just make it more consistent.

3. The Authorization header example in 1.1 uses single quotes around values.
It should use double quotes. The ABNF in 3.1 for timestamp, for instance,
explicitly uses <">.

4. The quoted-string production only supports a subset of ASCII. Better add a
sentence stating that the 'token' is assumed to only use this subset so no
escaping is defined. May be worth adding that only double-quote and backslash
need escaping in quoted-string, but neither of those are allowed in any of
this specs parameters so no escaping in quoted-string values shall occur.

5. Don't list the new line characters as separate numbered items in section
3.2.1 "Normalized Request String". Better to say it is a line-based format.
Each line ends with a single new line character (U+000A). Then list the 7
lines (as points 1 to 7), followed by point 8 saying there is 1 extra line for
each query string parameter.

6. I18N. Is the Normalised Request String UTF-8, or does it happen to be just
ASCII? Host, path, and query strings can contain non-ASCII characters -- but I
guess that the ASCII-only escaping used to create an HTTP Host header and URI
are assumed to have occurred before this spec uses these values. Would be
worth an explicit statement, and definitely an example.

7. I suggest swapping steps 2 (sort) & 3 (combine escaped name and value) in
section 3.2.1.1. "Parameters Normalization".
The current 2-layer sort is not ideal (sort on %-escaped name, then on
%-escaped value if the names are equal). It needs a special comparator
function etc, instead of using a programming language's standard
sort-a-list-of-strings function. It is tempting to concatenate %-escaped
name=value pairs and sort those -- but it doesn't always give the same result.
Eg a1=X and a11=Y should sort in that order according to the spec, but "1" <
"=" in an ASCII string comparison of the pairs.
A programmer probably has a map/dictionary/assoc-array of unescaped names to
values. The normalisation rules require a separate map of escaped names to
escaped values plus a custom comparator that considers names and values.
A nicer alternative would be to construct escaped name=value pairs then sort
that list (not map).
It would be worth adding another parameter to the example (eg a22=A) to
illustrate this (regardless of whether or not the steps are swapped).

8. HMAC operates on bytes, not strings. The 'text' and 'key' HMAC inputs (in
3.2.2 and 3.2.3) should be specified as the UTF-8-encoding of the Normalized
Request String and access token shared secret respectively. Might be able to
say ASCII-encoding, but only if we are sure that an OAuth token response
(which might be a UTF-8 JSON blob) can never return non-ASCII chars in a
'secret' field.

9. The 'secret' parameter is registered twice (7.1 & 7.2). I guess one of
these should be registering the 'algorithm' parameter instead.

10. I would like a "WWW-Authenticate: MAC algorithm=..." response header
defined. It would provide a nice illustration of how a complete HTTP auth
scheme is mapped to OAuth2. That is, how the scheme name "MAC" and parameters
from the "WWW-Authenticate: MAC ..." response header can be mapped to fields
in an OAuth2 token response (where they are accompanied by an actual secret
key).

--
James Manger

---

From: Eran Hammer-Lahav <[email-masked]>
Date: Thu, 3 Feb 2011 23:02:00 -0700

Thanks James.

> From: [email-masked] [mailto:[email-masked]] On Behalf
> Of Manger, James H
> Sent: Thursday, February 03, 2011 9:23 PM
> To: [email-masked]
> Subject: [OAUTH-WG] MAC: more comments on draft-hammer-oauth-v2-
> mac-token-02
> 
> The OAuth2-to-MAC binding could define a 'keyid' parameter to accompany
> the 'secret'.
> The 'keyid' value would map to the authentication id field in the MAC
> scheme, and the 'access_token' would map to the authorization id field.

I don't see the value of this, but I do see how it complicates both the specification and its usage with OAuth. The token can be constructed using these two identifiers if needed, outside its use with OAuth, but my instinctive reaction is that if you need something that much more specific, you will be better off using something else.

> chunked) is removed before calculating the body hash, but any Content-
> Encoding (eg gzip) is not removed. The spec should explicitly state this. [c.f.
> wording as for the "Content-MD5" header in draft-ietf-httpbis-p3-payload-
> 12, section 6.8]

I'll make this clear.
 
> (comma-separated?) list of MAC algorithms that the server supports.

Why? The client does not get a choice which algorithm to use. There is no negotiation here.

> used to calculate the body hash when using the hmac-sha-1 (and hmac-sha-
> 256) algorithm.

Why isn't 3.2 enough? That's where body hash is discussed.

> server" (when defining their "key" field).

Ok.

> 16. OAuth2 can provide a "secret" as a Unicode string. MAC algorithms such
> as HMAC use a key that is a byte array. Section 2 of the MAC spec says
> 'secret'
> can only include printable ASCII chars (except " and /). This is not quite right.
> chars). A 'secret' string from an OAuth2 response should be UTF-8 encoded
> to produce the byte array the MAC scheme uses.

What about when the secret is returned in the HTTP fragment? What is the value of making this use UTF-8.

> SCRAM is the latest-and-greatest authentication mechanism based on a
> shared secret (without using the brilliant, but patent-troubled, zero-
> knowledge proof techniques).
> credentials at the server are not sufficient to impersonate the client (not a
> "password-equivalent"); mutual authentication; channel binding (to an
> underlying TLS secure tunnel).
> certainly wants to avoid multiple exchanges at the HTTP layer. I expect the
> wider IETF community to judge MAC by comparing it negatively to SCRAM
> unless the document is quite clear about its constraints (eg sign an HTTP
> request without any interactivity with the server; suitable for shared secret
> keys, but not for shared passwords...).

I'll make this comparison clear in the introduction.

EHL

> From: [email-masked] [mailto:[email-masked]] On Behalf
> Of Manger, James H
> would be better at the end, ideally as an Annex, along with most of the
> OAuth talk from the introduction (and title).
> 
> It makes the format simply lines of text, instead of making the last line special
> (and only special if there are query params). It is awkward to manually edit
> sample files, debug files etc without a final newline character.
> escaping is defined. May be worth adding that only double-quote and
> backslash need escaping in quoted-string, but neither of those are allowed in
> any of this specs parameters so no escaping in quoted-string values shall
> occur.
> 
> Each line ends with a single new line character (U+000A). Then list the 7 lines
> (as points 1 to 7), followed by point 8 saying there is 1 extra line for each
> query string parameter.
> 
> guess that the ASCII-only escaping used to create an HTTP Host header and
> URI are assumed to have occurred before this spec uses these values. Would
> be worth an explicit statement, and definitely an example.
> 
> The current 2-layer sort is not ideal (sort on %-escaped name, then on %-
> escaped value if the names are equal). It needs a special comparator function
> etc, instead of using a programming language's standard sort-a-list-of-strings
> function. It is tempting to concatenate %-escaped name=value pairs and sort
> those -- but it doesn't always give the same result.
> A programmer probably has a map/dictionary/assoc-array of unescaped
> names to values. The normalisation rules require a separate map of escaped
> names to escaped values plus a custom comparator that considers names
> and values.
> A nicer alternative would be to construct escaped name=value pairs then
> sort that list (not map).
> 9. The 'secret' parameter is registered twice (7.1 & 7.2). I guess one of these
> should be registering the 'algorithm' parameter instead.
> 
> scheme is mapped to OAuth2. That is, how the scheme name "MAC" and
> parameters from the "WWW-Authenticate: MAC ..." response header can be
> mapped to fields in an OAuth2 token response (where they are accompanied
> by an actual secret key).
> 
> --
> James Manger

---

From: "Manger, James H" <[email-masked]>
Date: Fri, 4 Feb 2011 17:32:41 +1100

> Why isn't 3.2 enough? That's where body hash is discussed.

3.2 says the "body hash algorithm is determined by the access token algorithm" so it makes sense to state the former where you define the latter (in 3.3.2 & 3.3.3).
If someone ever wants to specify another algorithm the obvious thing to do is start with the text in 3.3.2 "hmac-sha-1" and modify it for the new algorithm -- but that would miss the extra detail that an algorithm spec needs (indicating a body hash alg).
Anyway, this is a basically a minor editorial issue.

--
James Manger

---

From: "Manger, James H" <[email-masked]>
Date: Mon, 7 Feb 2011 00:43:12 +1100

Eran,

>> "algorithms" parameter in the "WWW-Authenticate" response header that is
>> a (comma-separated?) list of MAC algorithms that the server supports.

> Why? The client does not get a choice which algorithm to use. There is no negotiation here.

Pretty much every standardised crypto message indicates the algorithm used to protect it in the message itself. Why be different?

Consider hashing the body. You don't need the secret key to do this, but you do need to know the hash algorithm. With an algorithm parameter, a front-end web server can use that to confirm the body-hash parameter is correct before passing the message to a middle tier where the secret key is available to verify the MAC.

An algorithm parameter offers some ability to migrate to stronger MAC algorithms if, say, (more) weaknesses in SHA-1 are found. Without it you need to issue new credentials to migrate.

If you have a environment of heterogeneous servers (legacy, new, vendor A, vendor B...) they might support different algorithms, but it would handy if clients could use a single credential.

Secret keys are generally handled separately in software than support for crypto algorithms. For instance, you can store a secret key in a Java Key Store, but I don't think there is an associated spot to specify a MAC algorithm.

--
James Manger

---

From: "Manger, James H" <[email-masked]>
Date: Mon, 7 Feb 2011 01:16:11 +1100

Eran,

> What about when the secret is returned in the HTTP fragment?

A fragment is part of a URI which is a string. Presumably you: (1) unescape any %xx sequences in the fragment (assuming UTF-8) to get a string of any Unicode characters; (2) encode the string to bytes using some character encoding; (3) pass the bytes as the secret key to the MAC algorithm.
The spec should explicitly the state what the character encoding is at step (2).

> What is the value of making this use UTF-8.

It was one reasonable choice -- once I convince you that a string-to-bytes encoding needs to be explicitly stated. Other options are ASCII or hex or base64url.

--
James Manger

---

From: Skylar Woodward <[email-masked]>
Date: Mon, 7 Feb 2011 17:56:51 +0100

comments below...

> and the 'access_token' would map to the authorization id field.

While I don't see much need for two IDs (they could be combined in the token, if necessary, as Eran mentions) I do favor using a term other than token, merely for the sake of clarity when this is used outside of OAuth. Consistent naming with other similar conventions (AWS, SASL?, etc.) seems like a logical decision maker. I had suggested "assertion" as each token seems to be asserting some identity, permission, etc.  However, "id" is perhaps just as good if only to remove the implication that this is to be used primarily with OAuth or that the value of "token" is always a value so-named coming from an OAuth server.

> (comma-separated?) list of MAC algorithms that the server supports.

After seeing James' follow-up on this, I see the value to implementors and tiered architectures to adding this parameter. On the other-hand, this could be yet another element forced into "token" (as with client_id) if it was critical for providers to detect at the header. This seems to be a tension between minimalism and convention.

One argument for not including it is that providers should not be tempted to validate a token based on the signature method supplied by the client. That is, if "algorithm" was included, the provider MUST validate at the lower level that it matches that of the token issued. By not having it in the header, providers are required to do the look-up. As Eran said, it's not negotiable.