2 * HTTPDIGEST - MD5 challenge/response authentication (RFC 2617)
5 * write challenge: nonce method uri
6 * read response: 2*MD5dlen hex digits
15 digest(char *user, char *realm, char *passwd,
16 char *nonce, char *method, char *uri,
22 char *realm, *passwd, *user, *f[4], *s, resp[MD5dlen*2+1];
29 c->state = "keylookup";
30 k = keyfetch(c, "%A", c->attr);
34 user = strfindattr(k->attr, "user");
35 realm = strfindattr(k->attr, "realm");
36 passwd = strfindattr(k->attr, "!password");
38 if(convreadm(c, &s) < 0)
40 if(tokenize(s, f, 4) != 3){
41 werrstr("bad challenge -- want nonce method uri");
45 digest(user, realm, passwd, f[0], f[1], f[2], resp);
46 convwrite(c, resp, strlen(resp));
59 *s = tolower((uchar)*s);
65 digest(char *user, char *realm, char *passwd,
66 char *nonce, char *method, char *uri,
70 char ha1[MD5dlen*2+1];
71 char ha2[MD5dlen*2+1];
75 * H(A1) = MD5(uid + ":" + realm ":" + passwd)
77 s = md5((uchar*)user, strlen(user), nil, nil);
78 md5((uchar*)":", 1, nil, s);
79 md5((uchar*)realm, strlen(realm), nil, s);
80 md5((uchar*)":", 1, nil, s);
81 md5((uchar*)passwd, strlen(passwd), b, s);
82 enc16(ha1, sizeof(ha1), b, MD5dlen);
86 * H(A2) = MD5(method + ":" + uri)
88 s = md5((uchar*)method, strlen(method), nil, nil);
89 md5((uchar*)":", 1, nil, s);
90 md5((uchar*)uri, strlen(uri), b, s);
91 enc16(ha2, sizeof(ha2), b, MD5dlen);
95 * digest = MD5(H(A1) + ":" + nonce + ":" + H(A2))
97 s = md5((uchar*)ha1, MD5dlen*2, nil, nil);
98 md5((uchar*)":", 1, nil, s);
99 md5((uchar*)nonce, strlen(nonce), nil, s);
100 md5((uchar*)":", 1, nil, s);
101 md5((uchar*)ha2, MD5dlen*2, b, s);
102 enc16(dig, MD5dlen*2+1, b, MD5dlen);
106 static Role hdroles[] =
116 "user? realm? !password?",