Subject: Re: Digest-MD5 to Historic

From: "Frank Ellermann" <[email-masked]>
Date: Wed, 5 Mar 2008 01:43:55 +0100

> it should be "algorithm" instead of "alg"

Plus s/authz/authzid/g, and a bunch of parameters I have
forgotten, <charset>, <stale>, <cipher>, <maxbuf>, maybe
more.  I also forgot to add a 2617-version of the example
in RFC 5034.

It is probably more straightforward to focus on one issue,
RFC 2617 and 2831 md5-sess are incompatible, see below for
a fresh and far shorter attempt.

Apparently DIGEST-MD5 is also used for BEEP.  How sure are
you that deprecating RFC 2831 is okay ?  Should RFC 2617
with its different md5-sess idea added to the registry of
SASL mechanisms under another name ?  

 Frank

-----------------------------------------------------------------
Omitting plausibility checks and parameter parsing, as well as
all details of  XURI = <method> ":" <uri> [":" <hash>]  the code
(here using REXX) for DIGEST-MD5 could be something like this:

   parse arg USER, PASS, REALM, NONCE, CNONCE, NC, QOP, XURI, ALG
   ALG = translate( ALG )        /* algorithm is case insensitive */

   HA1 = MD5(  USER || ':' || REALM || ':' || PASS )
   if ALG = 'MD5-SESS'  then  do
      HA1 = x2c( HA1 ) || ':' || NONCE || ':' || CNONCE
      if arg( 10, 'e' ) then  HA1 = HA1 || ':' || arg( 10 )
      HA1 = MD5( HA1 )           /* optional 10th arg.: AUTHZID   */
   end

   HA2 = MD5( XURI )             /* XURI incl. hash for auth-int  */
   TMP = NONCE                   /* 2069 compatibility (= no qop) */
   if ALG = 'MD5-SESS' | QOP <> ''  then  do
      TMP = translate( d2x( NC, 8 ), 'abcdef', 'ABCDEF' )
      TMP = NONCE || ':' || TMP || ':' || CNONCE || ':' || QOP
   end

   return MD5( HA1 || ':' || TMP || ':' || HA2 )

Here MD5( x ) is a subroutine returning 32 lower case hex. digits
of the MD5 [RFC 1321].  Ideally this code should also work for an
HTTP Auth Digest [RFC 2617].  Unfortunately this is not the case
for 'MD5-SESS':  [RFC 2831] adopted the [RFC 2617] algorithms "as
is" before the 'MD5-SESS' erratum was reported.  One line in the
example code shown above has to be modified:

      HA1 = HA1 || ':' || NONCE || ':' || CNONCE

The difference is x2c( HA1 ) vs. HA1.  In other words [RFC 2831]
uses a binary MD5 where [RFC 2617] plus erratum uses a hex. MD5
string.  See the expired [I-D.smith-sipping-auth-01] for correct
2069-fallback and 'MD5-SESS' examples.

New "fixed" [RFC 2617] 'MD5-SESS' results for examples published
in [RFC 2831], [RFC 4643], and [RFC 5034] are shown below:

1: user   = "chris" (see RFC 2831)
   pass   = "secret"
   realm  = "elwood.innosoft.com"
   method = "AUTHENTICATE"
   uri    = "imap/elwood.innosoft.com"
   nonce  = "OA6MG9tEQGm2hh"
   qop    = "auth"
   cnonce = "OA6MHXh6VqTrRk"
   nc     = 1
   alg    = "md5-sess"

   RFC 2831 digest  = "d388dad90d4bbd760a152321f2143af7"
   RFC 2831 rspauth = "ea40f60335c427b5527b84dbabcdfffd"

   RFC 2617 digest  = "26ef1190b643a36e879673066098379c"
   RFC 2617 rspauth = "c316c87a595a2cbfb4405784db016e34"

2: user   = "chris" (see RFC 2831)
   pass   = "secret"
   realm  = "elwood.innosoft.com"
   method = "AUTHENTICATE"
   uri    = "acap/elwood.innosoft.com"
   nonce  = "OA9BSXrbuRhWay"
   qop    = "auth"
   cnonce = "OA9BSuZWMSpW8m"
   nc     = 1
   alg    = "md5-sess"

   RFC 2831 digest  = "6084c6db3fede7352c551284490fd0fc"
   RFC 2831 rspauth = "2f0b3d7c3c2e486600ef710726aa2eae"

   RFC 2617 digest  = "90771dc5643a801bb9a9bcbb1ed3cd34"
   RFC 2617 rspauth = "ec0700b2da00dd133bcb0c841f42d341"

3: user   = "test"  (see RFC 4643)
   pass   = "test"
   realm  = "eagle.oceana.com"
   method = "AUTHENTICATE"
   uri    = "nntp/localhost"
   nonce  = "sayAOhCEKGIdPMHC0wtleLqOIcOI2wQYIe4zzeAtuiQ="
   qop    = "auth-conf"
   cnonce = "0Y3JQV2Tg9ScDip+O1SVC0rhVg//+dnOIiGz/7CeNJ8="
   nc     = 1
   alg    = "md5-sess"
   hash   = "00000000000000000000000000000000"

   RFC 2831 digest  = "d43cf66cffa903f9eb0356c08a3db0f2"
   RFC 2831 rspauth = "de2e127e5a81cda53d97acda35cde83a"

   RFC 2617 digest  = "41e814138958b1a0f08ef8b2dbe94ee9"
   RFC 2617 rspauth = "3f4d2b034c67c0c77df650f34ece6127"

4: user   = "chris" (see RFC 5034)
   pass   = "secret"
   realm  = "elwood.innosoft.com"
   method = "AUTHENTICATE"
   uri    = "pop/elwood.innosoft.com"
   nonce  = "OA6MG9tEQGm2hh"
   qop    = "auth"
   cnonce = "OA6MHXh6VqTrRk"
   nc     = 1
   alg    = "md5-sess"

   RFC 2831 digest  = "b0d56d2f054c24b62072322106468db9"
   RFC 2831 rspauth = "0b971462cef5e8f930db9a33b02fc9a0"

   RFC 2617 digest  = "089a19fffd2d75667e9d01583ee0fd58"
   RFC 2617 rspauth = "bb52468bdaadaac994e05c3958c71a09"

---

From: Alexey Melnikov <[email-masked]>
Date: Wed, 12 Mar 2008 12:09:23 +0000

Frank Ellermann wrote:

>Hi, 
>
>here is the proposed text explaining the MD5-SESS Digest-MD5
>problem.  I could transform it into xml2rfc format if needed.
>  
>
Hi Frank,
I think the text you've suggested would be good for an interoperability 
report on an update to DIGEST-MD5 itself.
My "DIGEST-MD5 to historic" draft was never intended as a detailed 
description of all things broken in DIGEST-MD5.

---

From: "Frank Ellermann" <[email-masked]>
Date: Thu, 13 Mar 2008 08:38:19 +0100

Alexey Melnikov wrote:

> I think the text you've suggested would be good for an 
> interoperability report on an update to DIGEST-MD5 itself.

I have just learned that XMPP also uses DIGEST-MD5, and my
MD5 test suite does not yet include the 3920bis example :-(

The complete "deprecate 2831" plan is premature, maybe we
should pick your old 2831bis draft, remove the new features
including "bindings", remove the old "auth" variants as not
unnecessary for current common practice, and publish the
rest as 2831bis "draft standard" with three clear warnings:

- interoperability is non-trivial, and guaranteed to fail
  for MD5-sess wrt RFC 2617 MD5-sess
- all passwords, user names, and realms are supposed to be
  in SASLprep UTF-8
- new intended usage "rare" or whatever the opposite of 
  "common" is (=> update SASL registry), anybody trying to
  replace CRAMMD5 by DIGEST-MD5 is a public danger and in
  need of medical help ;-)

> My "DIGEST-MD5 to historic" draft was never intended as a
> detailed description of all things broken in DIGEST-MD5.

Yes, your 2831bis draft was better for this purpose.  When
you (this WG) decided to deprecate it, did anybody check 
the normative references *to* RFC 2831 ?  Bill created a
nice tool for this job:
 
http://rtg.ietf.org/~fenner/ietf/deps/index.cgi?dep=rfc2831

 Frank