📄 auth.c
字号:
sprintf(result, "%s,opaque=\"%s\"",result,opaque); } return 1;}/*"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";*/static int base64_val(char x)\{ switch(x){ case '=': return -1; case 'A': return 0; case 'B': return 1; case 'C': return 2; case 'D': return 3; case 'E': return 4; case 'F': return 5; case 'G': return 6; case 'H': return 7; case 'I': return 8; case 'J': return 9; case 'K': return 10; case 'L': return 11; case 'M': return 12; case 'N': return 13; case 'O': return 14; case 'P': return 15; case 'Q': return 16; case 'R': return 17; case 'S': return 18; case 'T': return 19; case 'U': return 20; case 'V': return 21; case 'W': return 22; case 'X': return 23; case 'Y': return 24; case 'Z': return 25; case 'a': return 26; case 'b': return 27; case 'c': return 28; case 'd': return 29; case 'e': return 30; case 'f': return 31; case 'g': return 32; case 'h': return 33; case 'i': return 34; case 'j': return 35; case 'k': return 36; case 'l': return 37; case 'm': return 38; case 'n': return 39; case 'o': return 40; case 'p': return 41; case 'q': return 42; case 'r': return 43; case 's': return 44; case 't': return 45; case 'u': return 46; case 'v': return 47; case 'w': return 48; case 'x': return 49; case 'y': return 50; case 'z': return 51; case '0': return 52; case '1': return 53; case '2': return 54; case '3': return 55; case '4': return 56; case '5': return 57; case '6': return 58; case '7': return 59; case '8': return 60; case '9': return 61; case '+': return 62; case '/': return 63; } return 0;}char * base64_decode_string( const char *buf, unsigned int len, int *newlen ){ int i,j,x1,x2,x3,x4; char *out; out = (char *)malloc( ( len * 3/4 ) + 8 ); for(i=0,j=0;i+3<len;i+=4){ x1=base64_val(buf[i]); x2=base64_val(buf[i+1]); x3=base64_val(buf[i+2]); x4=base64_val(buf[i+3]); out[j++]=(x1<<2) | ((x2 & 0x30)>>4); out[j++]=((x2 & 0x0F)<<4) | ((x3 & 0x3C)>>2); out[j++]=((x3 & 0x03)<<6) | (x4 & 0x3F); } if (i<len) { x1 = base64_val(buf[i]); if (i+1<len) x2=base64_val(buf[i+1]); else x2=-1; if (i+2<len) x3=base64_val(buf[i+2]); else x3=-1; if(i+3<len) x4=base64_val(buf[i+3]); else x4=-1; if (x2!=-1) { out[j++]=(x1<<2) | ((x2 & 0x30)>>4); if (x3==-1) { out[j++]=((x2 & 0x0F)<<4) | ((x3 & 0x3C)>>2); if (x4==-1) { out[j++]=((x3 & 0x03)<<6) | (x4 & 0x3F); } } } } out[j++] = 0; *newlen=j; return out;}char base64[64]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";char * base64_encode_string( const char *buf, unsigned int len, int *newlen ){ int i,k; int triplets,rest; char *out,*ptr; triplets = len/3; rest = len%3; out = (char *)malloc( ( triplets * 4 ) + 8 ); ptr = out; for(i=0;i<triplets*3;i+=3){ k = (((unsigned char) buf[i])&0xFC)>>2; *ptr=base64[k];ptr++; k = (((unsigned char) buf[i])&0x03)<<4; k |=(((unsigned char) buf[i+1])&0xF0)>>4; *ptr=base64[k];ptr++; k = (((unsigned char) buf[i+1])&0x0F)<<2; k |=(((unsigned char) buf[i+2])&0xC0)>>6; *ptr=base64[k];ptr++; k = (((unsigned char) buf[i+2])&0x3F); *ptr=base64[k];ptr++; } i=triplets*3; switch(rest){ case 0: break; case 1: k = (((unsigned char) buf[i])&0xFC)>>2; *ptr=base64[k];ptr++; k = (((unsigned char) buf[i])&0x03)<<4; *ptr=base64[k];ptr++; *ptr='=';ptr++; *ptr='=';ptr++; break; case 2: k = (((unsigned char) buf[i])&0xFC)>>2; *ptr=base64[k];ptr++; k = (((unsigned char) buf[i])&0x03)<<4; k |=(((unsigned char) buf[i+1])&0xF0)>>4; *ptr=base64[k];ptr++; k = (((unsigned char) buf[i+1])&0x0F)<<2; *ptr=base64[k];ptr++; *ptr='=';ptr++; break; } // fprintf(stderr,"base64=%.*s >> %d\n",ptr-out,out,ptr-out); *newlen = ptr-out; return out;}char hexa[16]="0123456789abcdef";int createAuthHeaderAKAv1MD5(char * user, char * aka_OP, char * aka_AMF, char * aka_K, char * method, char * uri, char * msgbody, char * auth, char *algo, char * result) { char tmp[MAX_HEADER_LEN], authtype[16], cnonce[32], nc[32], opaque[64]; char *start, *end; static unsigned int mync = 1; int has_auts = 0, resuf = 1; int has_opaque = 0; char *nonce64, *nonce; int noncelen; RESHEX resp_hex; AMF amf; OP op; RAND rnd; AUTN autn; AUTS auts_bin; AUTS64 auts_hex; MAC mac,xmac; SQN sqn, sqnxoraka, sqn_ms; K k; RES res; CK ck; IK ik; AK ak; int i,j; // Extract the Nonce if ((start = stristr(auth, "nonce=")) == NULL) { sprintf(result, "createAuthHeaderAKAv1MD5: couldn't parse nonce"); return 0; } start = start + strlen("nonce="); if (*start == '"') { start++; } end = start + strcspn(start, " ,\"\r\n"); strncpy(tmp, start, end - start); tmp[end - start] ='\0'; /* Compute the AKA RES */ resp_hex[0]=0; nonce64 = tmp; nonce = base64_decode_string(nonce64,end-start,&noncelen); if (noncelen<RANDLEN+AUTNLEN) { sprintf(result,"createAuthHeaderAKAv1MD5 : Nonce is too short %d < %d expected \n", noncelen,RANDLEN+AUTNLEN); return 0; } memcpy(rnd,nonce,RANDLEN); memcpy(sqnxoraka,nonce+RANDLEN,SQNLEN); memcpy(mac,nonce+RANDLEN+SQNLEN+AMFLEN,MACLEN); memcpy(k,aka_K,KLEN); memcpy(amf,aka_AMF,AMFLEN); memcpy(op,aka_OP,OPLEN); /* Compute the AK, response and keys CK IK */ f2345(k,rnd,res,ck,ik,ak,op); res[RESLEN]='\0'; /* Compute sqn encoded in AUTN */ for (i=0; i < SQNLEN; i++) sqn[i] = sqnxoraka[i] ^ ak[i]; /* compute XMAC */ f1(k,rnd,sqn,aka_AMF,xmac,op); if (memcmp(mac,xmac,MACLEN)!=0) { sprintf(result,"createAuthHeaderAKAv1MD5 : MAC != eXpectedMAC -> Server might not know the secret (man-in-the-middle attack?) \n"); //return 0; } /* Check SQN, compute AUTS if needed and authorization parameter */ /* the condition below is wrong. * Should trigger synchronization when sqn_ms>>3!=sqn_he>>3 for example. * Also, we need to store the SQN per user or put it as auth parameter. */ if (1/*sqn[5] > sqn_he[5]*/) { sqn_he[5] = sqn[5]; has_auts = 0; /* RES has to be used as password to compute response */ for(i=0;i<RESLEN;i++){ resp_hex[2*i]=hexa[(res[i]&0xF0)>>4]; resp_hex[2*i+1]=hexa[res[i]&0x0F]; } resp_hex[RESLEN*2]=0; resuf = createAuthHeaderMD5(user, resp_hex, method, uri, msgbody, auth, algo, result); } else { sqn_ms[5] = sqn_he[5] + 1; f5star(k, rnd, ak, op); for(i=0; i<SQNLEN; i++) auts_bin[i]=sqn_ms[i]^ak[i]; f1star(k, rnd, sqn_ms, amf, auts_bin+SQNLEN, op); has_auts = 1; /* When re-synchronisation occurs an empty password has to be used */ /* to compute MD5 response (Cf. rfc 3310 section 3.2) */ resuf=createAuthHeaderMD5(user,"",method,uri,msgbody,auth,algo,result); } if (has_auts) { /* Format data for output in the SIP message */ for(i=0;i<AUTSLEN;i++){ auts_hex[2*i]=hexa[(auts_bin[i]&0xF0)>>4]; auts_hex[2*i+1]=hexa[auts_bin[i]&0x0F]; } auts_hex[AUTS64LEN-1]=0; sprintf(result, "%s,auts=\"%s\"",result,auts_hex); } return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -