[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

AW: Proposed Resolution to Issue 230: RFC 4590bis Last Call Comments



I agree with the resolution proposed by Bernard.

Bernard, I'll send you a corrected version of the examples.

The values in the examples were created with a Python script, using 'secret' as
secret. Here is the script (I don't know any more where I stole the HMAC_MD5
part):

"""
HTTP digest authentication

usage: from digauth import *
       digest(p5, '12345678', 'secret')
"""

import md5
import array

def h(x):
    m = md5.new(x)
    return m.digest().encode('hex')

def kd(secret, data):
    return h(secret + ':' + data)

class Params:
    pass

#
# returns Authorization response and Authentication-Info response
#
def digest(p, username, password):
    if p.algorithm == 'MD5' or p.algorithm == None:
	a1 = username + ':' + p.realm + ':' + password
    elif p.algorithm == 'MD5-sess':
	a1 = h(username + ':' + p.realm + ':' + password) \
	    + ':' + p.nonce \
	    + ':' + p.cnonce
    else:
	a1 = ''
    if p.qop == 'auth' or p.qop == 'auth-int':
	if p.qop == 'auth':
	    a2 = p.method +':' + p.uri
	    a2s = ':' + p.uri
	elif p.qop == 'auth-int':
	    a2 = p.method + ':' + p.uri + h(p.body)
	    a2s = ':' + p.uri + h(p.body)
	else:
	    a2 = ''
	    a2s = ''
	    
	return ( kd(h(a1), \
	          p.nonce \
	    + ':' + p.nc \
	    + ':' + p.cnonce \
	    + ':' + p.qop \
	    + ':' + h(a2)), \
	    kd(h(a1), \
	          p.nonce \
	    + ':' + p.nc \
	    + ':' + p.cnonce \
	    + ':' + p.qop \
	    + ':' + h(a2s)))
    elif p.qop == None:
	a2 = p.method +':' + p.uri
	a2s = ':' + p.uri
	return ( kd( h(a1), p.nonce + ':' + h(a2) ), \
		kd (h(a1), p.nonce + ':' + h(a2s) ) )

class HMAC_MD5:
    # keyed MD5 message authentication
    def __init__(self, key):
	if len(key) > 64:
	    key = md5.new(key).digest()
	ipad = array.array("B", [0x36] * 64)
	opad = array.array("B", [0x5C] * 64)
	for i in range(len(key)):
	    ipad[i] = ipad[i] ^ ord(key[i])
	    opad[i] = opad[i] ^ ord(key[i])
	self.ipad = md5.md5(ipad.tostring())
	self.opad = md5.md5(opad.tostring())
    def digest(self, data):
	ipad = self.ipad.copy()
	opad = self.opad.copy()
	ipad.update(data)
	opad.update(ipad.digest())
	return opad.digest()

#
# RfC 4590bis, example 1
# user = '12345678' password = 'secret'
#
# digest(p5, '12345678', 'secret')
#
p5 = Params()
p5.algorithm = 'MD5'
p5.qop = 'auth'
p5.method = 'INVITE'
p5.uri = 'sip:97226491335@example.com'
p5.realm = 'example.com'
p5.nonce = '3bada1a0'
p5.cnonce = '56593a78'
p5.nc = '00000001'

#
# RfC 4590bis, example 2
# user = '12345678' password = 'secret'
#
# digest(p6, '12345678', 'secret')
#
p6 = Params()
p6.algorithm = 'MD5'
p6.qop = 'auth'
p6.method = 'GET'
p6.uri = '/index.html'
p6.realm = 'example.com'
p6.nonce = '3bada1a0'
p6.cnonce = '56593a78'
p6.nc = '00000001'

-----Ursprüngliche Nachricht-----
Von: Bernard Aboba [mailto:bernard_aboba@hotmail.com] 
Gesendet: Donnerstag, 28. Juni 2007 03:20
An: radiusext@ops.ietf.org
Betreff: Proposed Resolution to Issue 230: RFC 4590bis Last Call Comments


 
Issue 230 (RFC 4590bis Last Call Comments) is enclosed below. 
 
The length of the Digest-Nonce-Count attribute has to include the Type and Length fields, so that it is indeed 10, not 8. 
 
Here is what RFC 2617 Section 3.2.2 says about nonce-count:
 
   nonce-count
     This MUST be specified if a qop directive is sent (see above), and
     MUST NOT be specified if the server did not send a qop directive in
     the WWW-Authenticate header field.  The nc-value is the hexadecimal
     count of the number of requests (including the current request)
     that the client has sent with the nonce value in this request.  For
     example, in the first request sent in response to a given nonce
     value, the client sends "nc=00000001".  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.   See the description
     below of the construction of the request-digest value.

So all the examples (not just the first) in Section 6 do indeed appear to be illegal. 
 
Also, the examples should supply the password so as to allow for verification of the calculations.  
 
Handling of internationalization within RADIUS is covered in RFC 4282, so that I don't believe that this draft needs to reinvent that wheel. 
 
 

--
to unsubscribe send a message to radiusext-request@ops.ietf.org with
the word 'unsubscribe' in a single line as the message text body.
archive: <http://psg.com/lists/radiusext/>