s/qmail 4.4.12
Next generation secure email transport
Loading...
Searching...
No Matches
digest_md5.c
Go to the documentation of this file.
1/*
2 * digest_md5.c taken for Manvendra's Indimail
3 * adjusted for use with s/qmail by permission
4 *
5 * Note: DIGEST-MD5 appeared in RFC 2831 and is historic now (RFC 6331).
6 * Though it originates from M$ and the year 2000, it already
7 * looks like an AI slop, pretending to be better than CRAM-MD5
8 *
9 */
10#include "global.h"
11#include "md5.h"
12#include "str.h"
13#include "stralloc.h"
14
15static char hextab[] = "0123456789abcdef";
16
17int digest_md5(unsigned char *digestmd5,stralloc *user,stralloc *realm,stralloc *pass,
18 char *authzid,stralloc *nonce,stralloc *digesturi,
19 char *cnonce,const char *nc,const char *qop)
20{
21 int j;
22 unsigned char digest[20], ea1[33], ea2[33];
23 MD5_CTX md5;
24
25 if (user->len < 2) return 0;
26 if (pass->len < 2) return 0;
27 if (realm->len < 2) return 0;
28 if (nonce->len < 2) return 0;
29 if (digesturi->len < 2) return 0;
30 if (!cnonce || !nc || !qop) return 0;
31
32 MD5Init(&md5);
33 MD5Update(&md5,(unsigned char *)user->s,user->len);
34 MD5Update(&md5,(unsigned char *)":",1);
35 MD5Update(&md5,(unsigned char *)realm->s,realm->len);
36 MD5Update(&md5,(unsigned char *)":",1);
37 MD5Update(&md5,(unsigned char *)pass->s,pass->len);
38 MD5Final(digest,&md5);
39
40 MD5Init(&md5);
41 MD5Update(&md5,digest,16); /* md5(user+realm+pass) */
42 MD5Update(&md5,(unsigned char *)":",1);
43 MD5Update(&md5,(unsigned char *)nonce->s,nonce->len);
44 MD5Update(&md5,(unsigned char *)":",1);
45 MD5Update(&md5,(unsigned char *)cnonce,32);
46 if (authzid && *authzid) { /* warning: not tested with authzid! */
47 MD5Update(&md5,(unsigned char *)":",1);
48 MD5Update(&md5,(unsigned char *)authzid,str_len(authzid));
49 }
50 MD5Final(digest,&md5);
51 for (j = 0; j < 16; j++) {
52 ea1[j] = hextab[digest[j] / 16];
53 ea1[j + 1] = hextab[digest[j] % 16];
54 }
55 ea1[32] = 0; /* ea1 = ready */
56
57 MD5Init(&md5);
58 MD5Update(&md5,(unsigned char *)"AUTHENTICATE:",13);
59 MD5Update(&md5,(unsigned char *)digesturi->s,digesturi->len);
60 if (str_len(qop) > 4) /* for auth-* type */
61 MD5Update(&md5,(unsigned char *)":00000000000000000000000000000000",32);
62 MD5Final(digest,&md5);
63
64 for (j = 0; j < 16; j++) {
65 ea2[j] = hextab[digest[j] / 16];
66 ea2[j + 1] = hextab[digest[j] % 16];
67 }
68 ea2[32] = 0; /* ea2 = ready */
69
70 /* digestmd5 = hex(a1) + nonce + nc + cnonce + qop + hex(a2) */
71
72 MD5Init(&md5);
73 MD5Update(&md5,ea1,32);
74 MD5Update(&md5,(unsigned char *)":",1);
75 MD5Update(&md5,(unsigned char *)nonce->s,nonce->len);
76 MD5Update(&md5,(unsigned char *)":",1);
77 MD5Update(&md5,(unsigned char *)nc,str_len(nc));
78 MD5Update(&md5,(unsigned char *) ":",1);
79 MD5Update(&md5,(unsigned char *)cnonce, 32);
80 MD5Update(&md5,(unsigned char *) ":",1);
81 MD5Update(&md5,(unsigned char *)qop, str_len(qop));
82 MD5Update(&md5,(unsigned char *)":",1);
83 MD5Update(&md5,ea2, 32);
84 MD5Final(digest,&md5);
85
86 for (j = 0; j < 16; j++) {
87 digestmd5[j] = hextab[digest[j] / 16];
88 digestmd5[j + 1] = hextab[digest[j] % 16];
89 }
90 digestmd5[32] = 0; /* done */
91
92 return 1;
93}
int digest_md5(unsigned char *digestmd5, stralloc *user, stralloc *realm, stralloc *pass, char *authzid, stralloc *nonce, stralloc *digesturi, char *cnonce, const char *nc, const char *qop)
Definition: digest_md5.c:17
void MD5Init(MD5_CTX *)
Definition: md5c.c:95
void MD5Final(unsigned char[16], MD5_CTX *)
Definition: md5c.c:144
void MD5Update(MD5_CTX *, unsigned char *, unsigned int)
stralloc user
stralloc pass
Definition: qmail-remote.c:679
int j
Definition: qmail-send.c:926
Definition: md5.h:31