00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "../../md5.h"
00029
00030 #include "auth_alg.h"
00031
00032
00033 static inline void cvt_hex(HASH bin, HASHHEX hex)
00034 {
00035 unsigned short i;
00036 unsigned char j;
00037
00038 for (i = 0; i<HASHLEN; i++)
00039 {
00040 j = (bin[i] >> 4) & 0xf;
00041 if (j <= 9)
00042 {
00043 hex[i * 2] = (j + '0');
00044 } else {
00045 hex[i * 2] = (j + 'a' - 10);
00046 }
00047
00048 j = bin[i] & 0xf;
00049
00050 if (j <= 9)
00051 {
00052 hex[i * 2 + 1] = (j + '0');
00053 } else {
00054 hex[i * 2 + 1] = (j + 'a' - 10);
00055 }
00056 };
00057
00058 hex[HASHHEXLEN] = '\0';
00059 }
00060
00061
00062
00063
00064
00065
00066 void uac_calc_HA1( struct uac_credential *crd,
00067 struct authenticate_body *auth,
00068 str* cnonce,
00069 HASHHEX sess_key)
00070 {
00071 MD5_CTX Md5Ctx;
00072 HASH HA1;
00073
00074 MD5Init(&Md5Ctx);
00075 MD5Update(&Md5Ctx, crd->user.s, crd->user.len);
00076 MD5Update(&Md5Ctx, ":", 1);
00077 MD5Update(&Md5Ctx, crd->realm.s, crd->realm.len);
00078 MD5Update(&Md5Ctx, ":", 1);
00079 MD5Update(&Md5Ctx, crd->passwd.s, crd->passwd.len);
00080 MD5Final(HA1, &Md5Ctx);
00081
00082 if ( auth->flags& AUTHENTICATE_MD5SESS )
00083 {
00084 MD5Init(&Md5Ctx);
00085 MD5Update(&Md5Ctx, HA1, HASHLEN);
00086 MD5Update(&Md5Ctx, ":", 1);
00087 MD5Update(&Md5Ctx, auth->nonce.s, auth->nonce.len);
00088 MD5Update(&Md5Ctx, ":", 1);
00089 MD5Update(&Md5Ctx, cnonce->s, cnonce->len);
00090 MD5Final(HA1, &Md5Ctx);
00091 };
00092
00093 cvt_hex(HA1, sess_key);
00094 }
00095
00096
00097
00098
00099
00100
00101 void uac_calc_HA2( str *method, str *uri,
00102 struct authenticate_body *auth,
00103 HASHHEX hentity,
00104 HASHHEX HA2Hex )
00105 {
00106 MD5_CTX Md5Ctx;
00107 HASH HA2;
00108
00109 MD5Init(&Md5Ctx);
00110 MD5Update(&Md5Ctx, method->s, method->len);
00111 MD5Update(&Md5Ctx, ":", 1);
00112 MD5Update(&Md5Ctx, uri->s, uri->len);
00113
00114 if ( auth->flags&QOP_AUTH_INT)
00115 {
00116 MD5Update(&Md5Ctx, ":", 1);
00117 MD5Update(&Md5Ctx, hentity, HASHHEXLEN);
00118 };
00119
00120 MD5Final(HA2, &Md5Ctx);
00121 cvt_hex(HA2, HA2Hex);
00122 }
00123
00124
00125
00126
00127
00128
00129 void uac_calc_response( HASHHEX ha1, HASHHEX ha2,
00130 struct authenticate_body *auth,
00131 str* nc, str* cnonce,
00132 HASHHEX response)
00133 {
00134 MD5_CTX Md5Ctx;
00135 HASH RespHash;
00136
00137 MD5Init(&Md5Ctx);
00138 MD5Update(&Md5Ctx, ha1, HASHHEXLEN);
00139 MD5Update(&Md5Ctx, ":", 1);
00140 MD5Update(&Md5Ctx, auth->nonce.s, auth->nonce.len);
00141 MD5Update(&Md5Ctx, ":", 1);
00142
00143 if ( auth->qop.len)
00144 {
00145 MD5Update(&Md5Ctx, nc->s, nc->len);
00146 MD5Update(&Md5Ctx, ":", 1);
00147 MD5Update(&Md5Ctx, cnonce->s, cnonce->len);
00148 MD5Update(&Md5Ctx, ":", 1);
00149 MD5Update(&Md5Ctx, auth->qop.s, auth->qop.len);
00150 MD5Update(&Md5Ctx, ":", 1);
00151 };
00152 MD5Update(&Md5Ctx, ha2, HASHHEXLEN);
00153 MD5Final(RespHash, &Md5Ctx);
00154 cvt_hex(RespHash, response);
00155 }