reSIProcate/stack  9694
digcalc.hxx
Go to the documentation of this file.
00001 #ifndef digcalc_hxx
00002 #define digcalc_hxx
00003 
00004 
00005 #include "rutil/vmd5.hxx"
00006 #include <string.h>
00007 #include <iostream>
00008 #include "rutil/Data.hxx"
00009 
00010 #define HASHLEN 16
00011 typedef char HASH[HASHLEN];
00012 #define HASHHEXLEN 32
00013 typedef char HASHHEX[HASHHEXLEN+1];
00014 #define IN const
00015 #define OUT
00016 
00017 
00018 using namespace std;
00019 
00020 namespace resip
00021 {
00022 
00023 typedef MD5Context MD5_CTX;
00024 
00025 
00026 void
00027 MD5_Update(struct MD5Context *ctx, char const *buf, unsigned len)
00028 {
00029    MD5Update(ctx, (unsigned char*)(buf), len);
00030 }
00031 
00032 void
00033 MD5_Final(char digest[16], struct MD5Context *ctx)
00034 {
00035    MD5Final((unsigned char*)digest, ctx);
00036 }
00037 
00038 /* calculate H(A1) as per HTTP Digest spec */
00039 void DigestCalcHA1(
00040     IN char * pszAlg,
00041     IN char * pszUserName,
00042     IN char * pszRealm,
00043     IN char * pszPassword,
00044     IN char * pszNonce,
00045     IN char * pszCNonce,
00046     OUT HASHHEX SessionKey
00047     );
00048 
00049 /* calculate request-digest/response-digest as per HTTP Digest spec */
00050 void DigestCalcResponse(
00051     IN HASHHEX HA1,           /* H(A1) */
00052     IN char * pszNonce,       /* nonce from server */
00053     IN char * pszNonceCount,  /* 8 hex digits */
00054     IN char * pszCNonce,      /* client nonce */
00055     IN char * pszQop,         /* qop-value: "", "auth", "auth-int" */
00056     IN char * pszMethod,      /* method from the request */
00057     IN char * pszDigestUri,   /* requested URL */
00058     IN HASHHEX HEntity,       /* H(entity body) if qop="auth-int" */
00059     OUT HASHHEX Response      /* request-digest or response-digest */
00060     );
00061 
00062 void CvtHex(
00063     IN HASH Bin,
00064     OUT HASHHEX Hex
00065     )
00066 {
00067     unsigned short i;
00068     unsigned char j;
00069 
00070     for (i = 0; i < HASHLEN; i++) {
00071         j = (Bin[i] >> 4) & 0xf;
00072         if (j <= 9)
00073             Hex[i*2] = (j + '0');
00074          else
00075             Hex[i*2] = (j + 'a' - 10);
00076         j = Bin[i] & 0xf;
00077         if (j <= 9)
00078             Hex[i*2+1] = (j + '0');
00079          else
00080             Hex[i*2+1] = (j + 'a' - 10);
00081     };
00082     Hex[HASHHEXLEN] = '\0';
00083 };
00084 
00085 /* calculate H(A1) as per spec */
00086 void DigestCalcHA1(
00087     IN char * pszAlg,
00088     IN char * pszUserName,
00089     IN char * pszRealm,
00090     IN char * pszPassword,
00091     IN char * pszNonce,
00092     IN char * pszCNonce,
00093     OUT HASHHEX SessionKey
00094     )
00095 {
00096       MD5_CTX Md5Ctx;
00097       HASH HA1;
00098 
00099       MD5Init(&Md5Ctx);
00100       MD5_Update(&Md5Ctx, pszUserName, strlen(pszUserName));
00101       MD5_Update(&Md5Ctx, ":", 1);
00102       MD5_Update(&Md5Ctx, pszRealm, strlen(pszRealm));
00103       MD5_Update(&Md5Ctx, ":", 1);
00104       MD5_Update(&Md5Ctx, pszPassword, strlen(pszPassword));
00105       MD5_Final(HA1, &Md5Ctx);
00106       if (strcasecmp(pszAlg, "md5-sess") == 0) {
00107             MD5Init(&Md5Ctx);
00108             MD5_Update(&Md5Ctx, HA1, HASHLEN);
00109             MD5_Update(&Md5Ctx, ":", 1);
00110             MD5_Update(&Md5Ctx, pszNonce, strlen(pszNonce));
00111             MD5_Update(&Md5Ctx, ":", 1);
00112             MD5_Update(&Md5Ctx, pszCNonce, strlen(pszCNonce));
00113             MD5_Final(HA1, &Md5Ctx);
00114       };
00115       CvtHex(HA1, SessionKey);
00116 };
00117 
00118 /* calculate request-digest/response-digest as per HTTP Digest spec */
00119 void DigestCalcResponse(
00120     IN HASHHEX HA1,           /* H(A1) */
00121     IN char * pszNonce,       /* nonce from server */
00122     IN char * pszNonceCount,  /* 8 hex digits */
00123     IN char * pszCNonce,      /* client nonce */
00124     IN char * pszQop,         /* qop-value: "", "auth", "auth-int" */
00125     IN char * pszMethod,      /* method from the request */
00126     IN char * pszDigestUri,   /* requested URL */
00127     IN HASHHEX HEntity,       /* H(entity body) if qop="auth-int" */
00128     OUT HASHHEX Response      /* request-digest or response-digest */
00129     )
00130 {
00131       MD5_CTX Md5Ctx;
00132       HASH HA2;
00133       HASH RespHash;
00134        HASHHEX HA2Hex;
00135 
00136       // calculate H(A2)
00137       MD5Init(&Md5Ctx);
00138       MD5_Update(&Md5Ctx, pszMethod, strlen(pszMethod));
00139       MD5_Update(&Md5Ctx, ":", 1);
00140       MD5_Update(&Md5Ctx, pszDigestUri, strlen(pszDigestUri));
00141       if (strcasecmp(pszQop, "auth-int") == 0) {
00142             MD5_Update(&Md5Ctx, ":", 1);
00143             MD5_Update(&Md5Ctx, HEntity, HASHHEXLEN);
00144       };
00145       MD5_Final(HA2, &Md5Ctx);
00146        CvtHex(HA2, HA2Hex);
00147 
00148 
00149       // calculate response
00150       MD5Init(&Md5Ctx);
00151       MD5_Update(&Md5Ctx, HA1, HASHHEXLEN);
00152       MD5_Update(&Md5Ctx, ":", 1);
00153       MD5_Update(&Md5Ctx, pszNonce, strlen(pszNonce));
00154       MD5_Update(&Md5Ctx, ":", 1);
00155       if (*pszQop) {
00156           MD5_Update(&Md5Ctx, pszNonceCount, strlen(pszNonceCount));
00157           MD5_Update(&Md5Ctx, ":", 1);
00158           MD5_Update(&Md5Ctx, pszCNonce, strlen(pszCNonce));
00159           MD5_Update(&Md5Ctx, ":", 1);
00160           MD5_Update(&Md5Ctx, pszQop, strlen(pszQop));
00161           MD5_Update(&Md5Ctx, ":", 1);
00162       };
00163       MD5_Update(&Md5Ctx, HA2Hex, HASHHEXLEN);
00164       MD5_Final(RespHash, &Md5Ctx);
00165       CvtHex(RespHash, Response);
00166 };
00167 
00168  
00169 }
00170 
00171 
00172 #endif
00173 /* ====================================================================
00174  * The Vovida Software License, Version 1.0 
00175  * 
00176  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
00177  * 
00178  * Redistribution and use in source and binary forms, with or without
00179  * modification, are permitted provided that the following conditions
00180  * are met:
00181  * 
00182  * 1. Redistributions of source code must retain the above copyright
00183  *    notice, this list of conditions and the following disclaimer.
00184  * 
00185  * 2. Redistributions in binary form must reproduce the above copyright
00186  *    notice, this list of conditions and the following disclaimer in
00187  *    the documentation and/or other materials provided with the
00188  *    distribution.
00189  * 
00190  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00191  *    and "Vovida Open Communication Application Library (VOCAL)" must
00192  *    not be used to endorse or promote products derived from this
00193  *    software without prior written permission. For written
00194  *    permission, please contact vocal@vovida.org.
00195  *
00196  * 4. Products derived from this software may not be called "VOCAL", nor
00197  *    may "VOCAL" appear in their name, without prior written
00198  *    permission of Vovida Networks, Inc.
00199  * 
00200  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00201  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00202  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00203  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00204  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00205  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00206  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00207  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00208  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00209  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00210  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00211  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00212  * DAMAGE.
00213  * 
00214  * ====================================================================
00215  * 
00216  * This software consists of voluntary contributions made by Vovida
00217  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00218  * Inc.  For more information on Vovida Networks, Inc., please see
00219  * <http://www.vovida.org/>.
00220  *
00221  */