core: fix another bunch of 'no real prototype' warnings, add doxygen docs
[sip-router] / modules_s / uac / auth_alg.c
1 /*
2  * $Id$
3  *
4  * Copyright (C) 2005 Voice Sistem SRL
5  *
6  * This file is part of SIP Express Router.
7  *
8  * UAC SER-module is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * UAC SER-module is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * For any questions about this software and its license, please contact
23  * Voice Sistem at following e-mail address:
24  *         office@voice-sistem.ro
25  *
26  *
27  * History:
28  * ---------
29  *  2005-01-31  first version (ramona)
30  */
31
32
33 #include "../../md5.h"
34
35 #include "auth_alg.h"
36
37
38 static inline void cvt_hex(HASH bin, HASHHEX hex)
39 {
40         unsigned short i;
41         unsigned char j;
42
43         for (i = 0; i<HASHLEN; i++)
44         {
45                 j = (bin[i] >> 4) & 0xf;
46                 if (j <= 9)
47                 {
48                         hex[i * 2] = (j + '0');
49                 } else {
50                         hex[i * 2] = (j + 'a' - 10);
51                 }
52
53                 j = bin[i] & 0xf;
54
55                 if (j <= 9)
56                 {
57                         hex[i * 2 + 1] = (j + '0');
58                 } else {
59                         hex[i * 2 + 1] = (j + 'a' - 10);
60                 }
61         };
62
63         hex[HASHHEXLEN] = '\0';
64 }
65
66
67
68 /* 
69  * calculate H(A1)
70  */
71 void uac_calc_HA1( struct uac_credential *crd,
72                 struct authenticate_body *auth,
73                 str* cnonce,
74                 HASHHEX sess_key)
75 {
76         MD5_CTX Md5Ctx;
77         HASH HA1;
78
79         MD5Init(&Md5Ctx);
80         MD5Update(&Md5Ctx, crd->user.s, crd->user.len);
81         MD5Update(&Md5Ctx, ":", 1);
82         MD5Update(&Md5Ctx, crd->realm.s, crd->realm.len);
83         MD5Update(&Md5Ctx, ":", 1);
84         MD5Update(&Md5Ctx, crd->passwd.s, crd->passwd.len);
85         MD5Final(HA1, &Md5Ctx);
86
87         if ( auth->flags& AUTHENTICATE_MD5SESS )
88         {
89                 MD5Init(&Md5Ctx);
90                 MD5Update(&Md5Ctx, HA1, HASHLEN);
91                 MD5Update(&Md5Ctx, ":", 1);
92                 MD5Update(&Md5Ctx, auth->nonce.s, auth->nonce.len);
93                 MD5Update(&Md5Ctx, ":", 1);
94                 MD5Update(&Md5Ctx, cnonce->s, cnonce->len);
95                 MD5Final(HA1, &Md5Ctx);
96         };
97
98         cvt_hex(HA1, sess_key);
99 }
100
101
102
103 /* 
104  * calculate H(A2)
105  */
106 void uac_calc_HA2( str *method, str *uri,
107                 struct authenticate_body *auth,
108                 HASHHEX hentity,
109                 HASHHEX HA2Hex )
110 {
111         MD5_CTX Md5Ctx;
112         HASH HA2;
113
114         MD5Init(&Md5Ctx);
115         MD5Update(&Md5Ctx, method->s, method->len);
116         MD5Update(&Md5Ctx, ":", 1);
117         MD5Update(&Md5Ctx, uri->s, uri->len);
118
119         if ( auth->flags&QOP_AUTH_INT)
120         {
121                 MD5Update(&Md5Ctx, ":", 1);
122                 MD5Update(&Md5Ctx, hentity, HASHHEXLEN);
123         };
124
125         MD5Final(HA2, &Md5Ctx);
126         cvt_hex(HA2, HA2Hex);
127 }
128
129
130
131 /* 
132  * calculate request-digest/response-digest as per HTTP Digest spec 
133  */
134 void uac_calc_response( HASHHEX ha1, HASHHEX ha2,
135                 struct authenticate_body *auth,
136                 str* nc, str* cnonce,
137                 HASHHEX response)
138 {
139         MD5_CTX Md5Ctx;
140         HASH RespHash;
141
142         MD5Init(&Md5Ctx);
143         MD5Update(&Md5Ctx, ha1, HASHHEXLEN);
144         MD5Update(&Md5Ctx, ":", 1);
145         MD5Update(&Md5Ctx, auth->nonce.s, auth->nonce.len);
146         MD5Update(&Md5Ctx, ":", 1);
147
148         if ( auth->qop.len)
149         {
150                 MD5Update(&Md5Ctx, nc->s, nc->len);
151                 MD5Update(&Md5Ctx, ":", 1);
152                 MD5Update(&Md5Ctx, cnonce->s, cnonce->len);
153                 MD5Update(&Md5Ctx, ":", 1);
154                 MD5Update(&Md5Ctx, auth->qop.s, auth->qop.len);
155                 MD5Update(&Md5Ctx, ":", 1);
156         };
157         MD5Update(&Md5Ctx, ha2, HASHHEXLEN);
158         MD5Final(RespHash, &Md5Ctx);
159         cvt_hex(RespHash, response);
160 }