Reference Code

F.4 Reference Code

The following code implements the calculations of H(A1), H(A2), request-digest, and response-digest, from RFC 2617. It uses the MD5 implementation from RFC 1321.

F.4.1 File " digcalc .h"

  #define HASHLEN 16  
  typedef char HASH[HASHLEN];  
  #define HASHHEXLEN 32  
  typedef char HASHHEX[HASHHEXLEN+1];  
  #define IN  
  #define OUT  
  /* calculate H(A1) as per HTTP Digest spec */  
  void DigestCalcHA1(  
  IN char * pszAlg,  
  IN char * pszUserName,  
  IN char * pszRealm,  
  IN char * pszPassword,  
  IN char * pszNonce,  
   IN char * pszCNonce, 
 OUT HASHHEX SessionKey 
 ); 
 
 /* calculate request-digest/response-digest as per HTTP Digest spec */ 
 void DigestCalcResponse( 
 IN HASHHEX HA1, /* H(A1) */ 
 IN char * pszNonce, /* nonce from server */ 
 IN char * pszNonceCount, /* 8 hex digits */ 
 IN char * pszCNonce, /* client nonce */ 
 IN char * pszQop, /* qop-value: "", "auth", "auth-int" */ 
 IN char * pszMethod, /* method from the request */ 
 IN char * pszDigestUri, /* requested URL */ 
 IN HASHHEX HEntity, /* H(entity body) if qop="auth-int" */ 
 OUT HASHHEX Response /* request-digest or response-digest */ 
 ); 

F.4.2 File "digcalc.c"

 #include <global.h> 
 #include <md5.h> 
 #include <string.h> 
 #include "digcalc.h" 
 
 void CvtHex( 
 IN HASH Bin, 
 OUT HASHHEX Hex 
 ) 
 { 
 unsigned short i; 
 unsigned char j; 
 for (i = 0; i < HASHLEN; i++) { 
 j = (Bin[i] >> 4) & 0xf; 
 if (j <= 9) 
 Hex[i*2] = (j + '0'); 
 else 
 Hex[i*2] = (j + 'a' - 10); 
 j = Bin[i] & 0xf; 
 if (j <= 9) 
 Hex[i*2+1] = (j + '0'); 
 else 
 Hex[i*2+1] = (j + 'a' - 10); 
 }; 
 Hex[HASHHEXLEN] = ' 
 Hex[HASHHEXLEN] = '\0'; 
';
 }; 
 
 /* calculate H(A1) as per spec */ 
 void DigestCalcHA1( 
 IN char * pszAlg, 
 IN char * pszUserName, 
 IN char * pszRealm, 
 IN char * pszPassword, 
 IN char * pszNonce, 
 IN char * pszCNonce, 
 OUT HASHHEX SessionKey 
 ) 
 { 
 MD5_CTX Md5Ctx; 
 HASH HA1; 
 MD5Init(&Md5Ctx); 
 MD5Update(&Md5Ctx, pszUserName, strlen(pszUserName)); 
 MD5Update(&Md5Ctx, ":", 1); 
 MD5Update(&Md5Ctx, pszRealm, strlen(pszRealm)); 
 MD5Update(&Md5Ctx, ":", 1); 
 MD5Update(&Md5Ctx, pszPassword, strlen(pszPassword)); 
 MD5Final(HA1, &Md5Ctx); 
 if (stricmp(pszAlg, "md5-sess") == 0) { 
 MD5Init(&Md5Ctx); 
 MD5Update(&Md5Ctx, HA1, HASHLEN); 
 MD5Update(&Md5Ctx, ":", 1); 
 MD5Update(&Md5Ctx, pszNonce, strlen(pszNonce)); 
 MD5Update(&Md5Ctx, ":", 1); 
 MD5Update(&Md5Ctx, pszCNonce, strlen(pszCNonce)); 
 MD5Final(HA1, &Md5Ctx); 
 }; 
 CvtHex(HA1, SessionKey); 
 }; 
 /* calculate request-digest/response-digest as per HTTP Digest spec */ 
 void DigestCalcResponse( 
 IN HASHHEX HA1, /* H(A1) */ 
 IN char * pszNonce, /* nonce from server */ 
 IN char * pszNonceCount, /* 8 hex digits */ 
 IN char * pszCNonce, /* client nonce */ 
 IN char * pszQop, /* qop-value: "", "auth", "auth-int" */ 
 IN char * pszMethod, /* method from the request */ 
 IN char * pszDigestUri, /* requested URL */ 
 IN HASHHEX HEntity, /* H(entity body) if qop="auth-int" */ 
 OUT HASHHEX Response /* request-digest or response-digest */ 
 ) 
 { 
 MD5_CTX Md5Ctx; 
 HASH HA2; 
 HASH RespHash; 
 HASHHEX HA2Hex; 
 // calculate H(A2) 
 MD5Init(&Md5Ctx); 
 MD5Update(&Md5Ctx, pszMethod, strlen(pszMethod)); 
 MD5Update(&Md5Ctx, ":", 1); 
 MD5Update(&Md5Ctx, pszDigestUri, strlen(pszDigestUri)); 
 if (stricmp(pszQop, "auth-int") == 0) { 
 MD5Update(&Md5Ctx, ":", 1); 
 MD5Update(&Md5Ctx, HEntity, HASHHEXLEN); 
 }; 
 MD5Final(HA2, &Md5Ctx); 
 CvtHex(HA2, HA2Hex); 
 // calculate response 
 MD5Init(&Md5Ctx); 
 MD5Update(&Md5Ctx, HA1, HASHHEXLEN); 
 MD5Update(&Md5Ctx, ":", 1); 
 MD5Update(&Md5Ctx, pszNonce, strlen(pszNonce)); 
 MD5Update(&Md5Ctx, ":", 1); 
 if (*pszQop) { 
 MD5Update(&Md5Ctx, pszNonceCount, strlen(pszNonceCount)); 
 MD5Update(&Md5Ctx, ":", 1); 
 MD5Update(&Md5Ctx, pszCNonce, strlen(pszCNonce)); 
 MD5Update(&Md5Ctx, ":", 1); 
 MD5Update(&Md5Ctx, pszQop, strlen(pszQop)); 
 MD5Update(&Md5Ctx, ":", 1); 
 }; 
 MD5Update(&Md5Ctx, HA2Hex, HASHHEXLEN); 
 MD5Final(RespHash, &Md5Ctx); 
 CvtHex(RespHash, Response); 
 }; 

F.4.3 File "digtest.c"

 #include <stdio.h> 
 #include "digcalc.h" 
 
 void main(int argc, char ** argv) { 
 char * pszNonce = "dcd98b7102dd2f0e8b11d0f600bfb0c093"; 
 char * pszCNonce = "0a4f113b"; 
 char * pszUser = "Mufasa"; 
 char * pszRealm = "testrealm@host.com"; 
 char * pszPass = "Circle Of Life"; 
 char * pszAlg = "md5"; 
 char szNonceCount[9] = "00000001"; 
 char * pszMethod = "GET"; 
 char * pszQop = "auth"; 
 char * pszURI = "/dir/index.html"; 
 HASHHEX HA1; 
 HASHHEX HA2 = ""; 
 HASHHEX Response; 
 DigestCalcHA1(pszAlg, pszUser, pszRealm, pszPass, 
 pszNonce, pszCNonce, HA1); 
 DigestCalcResponse(HA1, pszNonce, szNonceCount, pszCNonce, pszQop, 
 pszMethod, pszURI, HA2, Response); 
 printf("Response = %s\n", Response); 
 }; 



HTTP. The Definitive Guide
HTTP: The Definitive Guide
ISBN: 1565925092
EAN: 2147483647
Year: 2001
Pages: 294

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net