Digest cnonce, Nonce Count , and the channel binding directive value


2/10/2012 update: The post below is old. Its good for learning – but ask questions that appear unanswered. One should know that the questions were answered. In short, the extending hash process we didn’t understand at the time turns out to have been extended by microsoft in a VERY obvious (and natural) way.  Someone sent me a comment telling how to do it (and working my own examples to show the math does then work).

—————-

 

Lets try to comprehend the fields of the www authorization request header, when using the Digest scheme.

Authorization: Digest username=”pwilliams”,realm=”rapnt”, nonce=”+Upgraded+v171d455c90b2989903a515dc157e97d1d8040826816c6ca01826531613f86188a13e8a0ff7b1bf03153945ceba317d5cb1a1c60e8892a17e5″, uri=”/foafdotme.aspx”, cnonce=”+Upgraded+v11b4ed068bd089ef5b3dbb7ff66aac0a75c65a5fb5423d2b64061b15d19ede27d”, nc=00000001, algorithm=MD5-sess, response=”b5c493e17d724853117d0fa97185bf46″,  qop=”auth”, charset=utf-8, hashed-dirs=”service-name,channel-binding”, service-name=”HTTP/3SJCHK1.rapnt.com”, channel-binding=”4dc109bd16b5f8cbde3093baf7246121″

Channel Binding for Digest

In draft-santesson-digestbind-01, folks describe the format of the digest cnonce:

“If the client decides to send channel binding information, it includes the same “+UpGrAdEd+v1” prefix string at the beginning of the cnonce it generates. The MD5 ASCII hex of the unquoted service-name and channel-bindings directive values follows the upgraded prefix.”

Given a cnonce value from a www-auth message, let’s apply the rule to it.

cnonce is

“+Upgraded+v11b4ed068bd089ef5b3dbb7ff66aac0a75c65a5fb5423d2b64061b15d19ede27d”

From this cnonce value, remove the prefix “+Upgraded+v1” leaving

“1b4ed068bd089ef5b3dbb7ff66aac0a75c65a5fb5423d2b64061b15d19ede27d”

  • The first 32 hex chars are
    • “1b4ed068bd089ef5b3dbb7ff66aac0a7”
  • leaving 32 hex chars
    • “5c65a5fb5423d2b64061b15d19ede27d”

Trying MD5

We now tabulate the MD5 function

cnonce  “MD5 ASCII hex” value string Md5(value) http://www.adamek.biz/md5-generator.php 
1b4ed068bd089ef5b3dbb7ff66aac0a7 HTTP/3SJCHK1.rapnt.com bf512273efcee45475652907afc91a94
5c65a5fb5423d2b64061b15d19ede27d 4dc109bd16b5f8cbde3093baf7246121 7dc5a048ef1d6124f9bd083f09e928ae

The table shows that the md5(string) does not equal the cnonce value component’s value. Evidently, the term ”MD5 ASCII hex” is merely a lexical definition. It’s name does not imply that the value is the result of the MD5 hash function.

Trying MD5-Session

To support the integrity and data origin authentication security services, rfc2831 defines the keyed hash function KD():

Let KD(k, s) be H({k, “:”, s}), i.e., the 16 octet hash of the string k, a colon and the string s

where H() is MD5().

This is used to calculate response-value (where the result of KD is then written out using the HEX() function.

response-value  =
         HEX( KD ( HEX(H(A1)),
                 { nonce-value, ":" nc-value, ":",
                   cnonce-value, ":", qop-value, ":", HEX(H(A2)) }))

The key thing to note is that both the keyed hash function’s key is a function of cnonce, as is the text to be hashed. (See definitions of A1 and A2, in the reference.)

Data

Let’s write out the values of a first authentication handshake involving multiple exchanges. (A single handshake has a common server nonce value, and unlike the SASL flow, there is no final, “server generated handshake message” aiming to authenticate the server’s own binding token tied to the client cert). Then, let’s analyze the values.

Challenge Response data

In response to a challenge from the server, the browser mints a new cnonce. This is the first time a message is sent with this nonce, so the NC value is 1. The response mac is b5c493e17d724853117d0fa97185bf46 (which is a function of cnonce). Cnonce is 1b… computed (somehow) from the server’s GSSAPI name, and 5c… from the SSL certificate.

nonce +Upgraded+v171d455c90b2989903a515dc157e97d1d8040826816c6ca01826531613f86188a13e8a0ff7b1bf03153945ceba317d5cb1a1c60e8892a17e5
cnonce +Upgraded+v1 1b4ed068bd089ef5b3dbb7ff66aac0a7
5c65a5fb5423d2b64061b15d19ede27d”
nc 00000001
binding 4dc109bd16b5f8cbde3093baf7246121
response b5c493e17d724853117d0fa97185bf46

Integrity protected #1 data

For the same server nonce, the browser mints a new cnonce (note the f2fdc935e348bcf496fc9d86f054789b in the cnonce field). This is the first time the IDP’s message is sent with this cnonce, so the NC value is 1. The response value is changed from the challenge response, implying that its calculation does indeed involve cnonce.  The binding value is the same as the channel response,yet the (keyed) hash of the value in the cnonce is different. This supports the notion that the cnonce’s (keyed) hashed binding token is indeed keyed. Semantically, the only value that changed was the URI (that now bears the authentication token).

nonce +Upgraded+v171d455c90b2989903a515dc157e97d1d99460d7216c6ca01492ee4c44f51df663cab3651d4835054b20c25a0b20b1504ed154f18b31e5a2a
cnonce +Upgraded+v1
1b4ed068bd089ef5b3dbb7ff66aac0a7
f2fdc935e348bcf496fc9d86f054789b
nc 00000001
binding 4dc109bd16b5f8cbde3093baf7246121
response ce070611cfcb6ca5c42cc0e513252e62

Integrity protected #2 data

We use F5 on the browser to replay the previous data (#1). The cnonce does not change from the previous message. This means that replay does not change the (keyed) hash of the binding token. However, the NC values increments (appropriately), which induces a change in response value. This suggests that nc is not used in the formation of the key in the (keyed) has of the binding token put in cnonce. The combination of cnonce change and NC value change induces the change in response value. That the value of cnonce element for the hashed channel token is constant between replays does lend some support to the suggestion that it is a function of the URI field.

nonce +Upgraded+v171d455c90b2989903a515dc157e97d1d99460d7216c6ca01492ee4c44f51df663cab3651d4835054b20c25a0b20b1504ed154f18b31e5a2a
cnonce +Upgraded+v1
1b4ed068bd089ef5b3dbb7ff66aac0a7
f2fdc935e348bcf496fc9d86f054789b
nc 00000002
binding 4dc109bd16b5f8cbde3093baf7246121
response f385823a6fc819684fbe470c4230fd3d

Meaning of NC

The purpose of this directive is to allow the server to detect request replays by maintaining its own copy of this count – if the same nc-value is seen twice, then the request is a replay.

Clearly, only if the NC varies for the same cnonce values is there “a replay”. This definition is relevant to our application of NC for the purpose of detecting the nth use of an authentication token from the IDP. We have seen from the data trace that over TLS the cnonce will change between the request for access, and the request that (first) presents the authentication token.  Detection that the NC value changes upon assertion presentation from the NC value used in the request is only valid in the case that the request itself presented a cnonce with NC=1.

Definition of A1 and A2 – a key generator

A1 = { H( { username-value, “:”, realm-value, “:”, passwd } ), “:”, nonce-value, “:”, cnonce-value, “:”, authzid-value }

If we assumed that the keyed hash for cnonce’s hashed binding token is based on the same parameters as the calculation of response, this would mean that A1 is the generator of the key for the keyed hash function.

However ifA1 is used to calculate a value for cnonce, and cnonce is used in the definition of A1, this would imply that a “previous” value of cnonce is available (and used.)

Since the the “qop” directive’s value is “auth”, then

A2 = { “AUTHENTICATE:”, digest-uri-value }

where digest-uri-value is the IDP’s assertion in the case of HTTP Digest, noting that in contrast it is the GSSAPI sevice descriptor in the case of SASL. However, the (keyed?) hash of the service descriptor is present in the cnonce,where the service name directive carries the text of the GSSAPI service descriptor.

Could it be that the generator for the keyed hash of the directive values found in cnonce might be A2,whose change would be reflected in A1 (depending on cnonce) and thus reflected in response?

The case of the Integrity protected #2 data supports this. There, the cnonce hashed directive for the binding token does not change, suggesting the generator is based on the same values as the case #1 run. Yet, the response value changes, since NC changes. One can observer that the digest-URI does not change ( consistent with the semantic of F5 at a browser), and A2 is a simple function of that URI (which bears the assertion in the foafssl.org design,and which bears the audience controls, request/response tying, and (assertion) replay detection in the improved method).

Confirming the Guess

If its true that A2 is the generator, we can tabulate the values (since all the inputs to A2 are known.)

field value Md5(value) http://www.adamek.biz/md5-generator.php 
URI /foafdotme.aspx
input to A AUTHENTICATE:/foafdotme.aspx d0518caf4d8772cc75c394e846c96ce8

since the constant challen token value is4dc109bd16b5f8cbde3093baf7246121, then

KD = MD5(“d0518caf4d8772cc75c394e846c96ce8:4dc109bd16b5f8cbde3093baf7246121”) (unquoted argument)

which is 65e11e7abeda6c0d20e86e90fbf0c28c which != 5c65a5fb5423d2b64061b15d19ede27d.

Of course, things like case of hex digits make a difference when digesting; yet the values are already lower case per the lexical definition. could the URI require a UTF8 8 header bytes, perhaps?

Getting more Technical Information

Searching around the web identified the micosoft Digest Protocol Extensions on the mechanism we are discussing, also stored in skydrive. Lets study it, and hope it answers 2 questions:

  1. how is the binding token calculated , given its supposed to be the output of SHA-256 (a 32 byte, 64 hexchar value)?
  2. how is the element of cnonce calculated (given the answer to the previous question)?

So, after a quick reading, it doesn’t. It simply references the material we have already consulted. Sigh.

Browsing around Microsoft sources did identify group policy support. This enables one to make registry settings that set the enforcement requirements of the service name and TLS channel binding tokens. It also identified an good introductory article on the mechanism for using channel bindings to delegate responsibilities between security layers (e.g. https to SSL).

There was also a suggestion in a grid community posting that the client’s (TLS) CBT would be the finished message of the half channel, and that said value would be “sealed” under the current session key. It would make some sense that the current “session” key derived from the digest handshake would be ‘sealing” the CBT computed as a SHA-256 hash of the server cert – and that said sealing would be an instance of KD(k,s) – which of course is MD5. This MIGHT explain why the “sealed” binding token is 16 bytes long.

About home_pw

Computer Programmer who often does network administration with focus on security servers. Sometimes plays at slot machine programming.
This entry was posted in FOAF+SSL. Bookmark the permalink.

Leave a comment