From a838bdd2fc80ac89bd251eea4d80a119c5869939 Mon Sep 17 00:00:00 2001 From: "Jean-Marc Pigeon (Delson)" Date: Sun, 6 Jul 2025 00:31:31 -0400 Subject: [PATCH] At last able to compute DIGEST-MD5 sequence --- lib/lvleml.c | 2 +- lib/subcnv.c | 7 ++-- lib/subcnv.h | 2 +- lib/unidig.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++--- lib/unidig.h | 8 +++-- tools/digmd5.c | 4 ++- 6 files changed, 99 insertions(+), 15 deletions(-) diff --git a/lib/lvleml.c b/lib/lvleml.c index 931a7ce..1b49f6a 100644 --- a/lib/lvleml.c +++ b/lib/lvleml.c @@ -438,7 +438,7 @@ while (proceed==true) { char *hexa; local=dig_cryptmd5(passwd,(unsigned char *)challenge); - hexa=cnv_tohexa(local); + hexa=cnv_tohexa(local,strlen(local)); //(void) rou_alert(0,"%s anwr=<%s>",OPEP,answer); //(void) rou_alert(0,"%s hexa=<%s>",OPEP,hexa); if (strcmp(hexa,answer)!=0) diff --git a/lib/subcnv.c b/lib/subcnv.c index c4e167f..17c8204 100644 --- a/lib/subcnv.c +++ b/lib/subcnv.c @@ -174,16 +174,13 @@ return coded; /* an hexadecimale string sequence */ /* */ /********************************************************/ -PUBLIC char *cnv_tohexa(const char *str) +PUBLIC char *cnv_tohexa(const char *str,int taille) { char *hexa; hexa=(char *)0; -if ((str!=(char *)0)&&(strlen(str)>0)) { - unsigned int taille; - - taille=strlen(str); +if ((str!=(char *)0)&&(taille>0)) { hexa=(char *)calloc((taille*2)+1,sizeof(char)); for (int i=0;i #include +#include #include #include "subrou.h" @@ -31,7 +32,7 @@ static char *voc[]={ "digest-uri", "nc", "nonce", - "qpop", + "qop", "realm", "response", "username", @@ -76,9 +77,9 @@ if (strlen(entry)>0) { resp->nonce=rou_freestr(resp->nonce); resp->nonce=strdup(ptr); break; - case 5 : //qpop - resp->qpop=rou_freestr(resp->qpop); - resp->qpop=strdup(ptr); + case 5 : //qop + resp->qop=rou_freestr(resp->qop); + resp->qop=strdup(ptr); break; case 6 : //realm resp->realm=rou_freestr(resp->realm); @@ -115,7 +116,7 @@ PUBLIC RSPTYP *dig_freeresp(RSPTYP *resp) if (resp!=(RSPTYP *)0) { resp->response=rou_freestr(resp->response); resp->charset=rou_freestr(resp->charset); - resp->qpop=rou_freestr(resp->qpop); + resp->qop=rou_freestr(resp->qop); resp->cnonce=rou_freestr(resp->cnonce); resp->nonce=rou_freestr(resp->nonce); resp->digesturi=rou_freestr(resp->digesturi); @@ -279,3 +280,83 @@ return hashmd5; #undef OPEP } +/* + +*/ +/********************************************************/ +/* */ +/* Procedure to compute local response to challenge*/ +/* and check if the compupted answer is the same as*/ +/* reponse available within RSPTYP record. */ +/* */ +/********************************************************/ +_Bool dig_checkresp(RSPTYP *resp,char *secret) + +{ +_Bool isok; +char *HA1; +char *HA2; +char *HA3; +char seq[400]; +int phase; +_Bool proceed; + + +isok=false; +(void) memset(seq,'\000',sizeof(seq)); +HA1=(char *)0; +HA2=(char *)0; +HA3=(char *)0; +phase=0; +proceed=(resp!=(RSPTYP *)0); +while (proceed==true) { + switch (phase) { + case 0 : { //computing hash HA1 + MD5TYP *A1; + + (void) snprintf(seq,sizeof(seq),"%s:%s:%s",resp->username,resp->realm,secret); + A1=dig_hashmd5((unsigned char *)seq); + //algorithm value is "MD5-sess" + (void) snprintf(seq,sizeof(seq),"%s:%s:%s", + (char *)A1,resp->nonce,resp->cnonce); + (void) free(A1); + A1=dig_hashmd5((unsigned char *)seq); + HA1=cnv_tohexa((char *)A1,sizeof(MD5TYP)); + (void) free(A1); + } + break; + case 1 : { //computing HA2 + MD5TYP *A2; + + (void) snprintf(seq,sizeof(seq),"AUTHENTICATE:%s",resp->digesturi); + A2=dig_hashmd5((unsigned char *)seq); + HA2=cnv_tohexa((char *)A2,sizeof(MD5TYP)); + (void) free(A2); + } + break; + case 2 : { //computing response + MD5TYP *A3; + + (void) snprintf(seq,sizeof(seq),"%s:%s:%08lx:%s:%s:%s", + HA1,resp->nonce,resp->nc, + resp->cnonce,resp->qop,HA2); + A3=dig_hashmd5((unsigned char *)seq); + HA3=cnv_tohexa((char *)A3,sizeof(MD5TYP)); + (void) free(A3); + } + break; + case 3 : //comparing annoced response versus computed response + if (strcmp(HA3,resp->response)==0) + isok=true; + break; + default : //SAFE Guard + proceed=false; + break; + } + phase++; + } +HA3=rou_freestr(HA3); +HA2=rou_freestr(HA2); +HA1=rou_freestr(HA1); +return isok; +} diff --git a/lib/unidig.h b/lib/unidig.h index a43a66e..fa856c4 100644 --- a/lib/unidig.h +++ b/lib/unidig.h @@ -15,13 +15,13 @@ typedef struct { //DIGEST-MD5 challange response structure char *nonce; //server nonce char *cnonce; //client nonce u_long nc; //nonce count - char *qpop; //protection quality (authentication) + char *qop; //protection quality (authentication) char *charset; //used carset char *response; //Challenge md5 response }RSPTYP; //MD5 hashing result -typedef unsigned char MD5TYP[17]; +typedef unsigned char MD5TYP[16]; //procedure to free the response structure extern RSPTYP *dig_freeresp(RSPTYP *resp); @@ -37,4 +37,8 @@ extern MD5TYP *dig_hashmd5(unsigned char *seq); //Procedure to crypt a string with MD5 hash function extern char *dig_cryptmd5(const void *key,unsigned char *seq); +//Procedure to compute local response to challenge and +//check if the remote session is the same +extern _Bool dig_checkresp(RSPTYP *resp,char *secret); + #endif diff --git a/tools/digmd5.c b/tools/digmd5.c index 9674b46..7955c39 100644 --- a/tools/digmd5.c +++ b/tools/digmd5.c @@ -50,6 +50,8 @@ while (proceed==true) { resp=dig_parseresp(cleartext); break; case 1 : //checking + if (dig_checkresp(resp,argv[0])==true) + status=0; break; case 2 : //free memory resp=dig_freeresp(resp); @@ -109,7 +111,7 @@ while (proceed==true) { foreground=true; break; case 3 : //doing main task - (void) chkresponse(params->argc,params->argv); + status=chkresponse(params->argc,params->argv); break; case 4 : //main task completed (void) prc_cleantitle(); -- 2.47.3