You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
239 lines
7.3 KiB
239 lines
7.3 KiB
#include "stdafx.h"
|
|
#include "auth.h"
|
|
#include "md5.h"
|
|
|
|
|
|
const CHAR g_cszADVAPI32DllName[] = "ADVAPI32.DLL";
|
|
|
|
const CHAR g_cszCryptAcquireContextA[] = "CryptAcquireContextA";
|
|
|
|
const CHAR g_cszCryptCreateHash[] = "CryptCreateHash";
|
|
const CHAR g_cszCryptHashData[] = "CryptHashData";
|
|
const CHAR g_cszCryptGetHashParam[] = "CryptGetHashParam";
|
|
const CHAR g_cszCryptDestroyHash[] = "CryptDestroyHash";
|
|
const CHAR g_cszCryptReleaseContext[] = "CryptReleaseContext";
|
|
|
|
const CHAR g_rgchHexNumMap[] =
|
|
{
|
|
'0', '1', '2', '3', '4', '5', '6', '7',
|
|
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
|
|
};
|
|
|
|
const int MD5_HASH_LEN = 16;
|
|
|
|
void
|
|
hmac_md5(
|
|
unsigned char* text, /* pointer to data stream */
|
|
int text_len, /* length of data stream */
|
|
unsigned char* key, /* pointer to authentication key */
|
|
int key_len, /* length of authentication key */
|
|
BYTE digest[16]) /* caller digest to be filled in */
|
|
|
|
{
|
|
MD5_CTX context;
|
|
memset(&context, 0, sizeof(context));
|
|
|
|
unsigned char k_ipad[65]; /* inner padding -
|
|
* key XORd with ipad
|
|
*/
|
|
unsigned char k_opad[65]; /* outer padding -
|
|
* key XORd with opad
|
|
*/
|
|
int i;
|
|
/* if key is longer than 64 bytes reset it to key=MD5(key) */
|
|
if (key_len > 64) {
|
|
|
|
MD5_CTX tctx;
|
|
memset(&tctx, 0, sizeof(tctx));
|
|
|
|
MD5Init(&tctx);
|
|
MD5Update(&tctx, key, key_len);
|
|
MD5Final(&tctx);
|
|
|
|
key = tctx.digest;
|
|
key_len = 16;
|
|
}
|
|
|
|
/*
|
|
* the HMAC_MD5 transform looks like:
|
|
*
|
|
* MD5(K XOR opad, MD5(K XOR ipad, text))
|
|
*
|
|
* where K is an n byte key
|
|
* ipad is the byte 0x36 repeated 64 times
|
|
|
|
* opad is the byte 0x5c repeated 64 times
|
|
* and text is the data being protected
|
|
*/
|
|
|
|
/* start out by storing key in pads */
|
|
ZeroMemory( k_ipad, sizeof k_ipad);
|
|
ZeroMemory( k_opad, sizeof k_opad);
|
|
CopyMemory( k_ipad, key, key_len);
|
|
CopyMemory( k_opad, key, key_len);
|
|
|
|
/* XOR key with ipad and opad values */
|
|
for (i=0; i<64; i++) {
|
|
k_ipad[i] ^= 0x36;
|
|
k_opad[i] ^= 0x5c;
|
|
}
|
|
/*
|
|
* perform inner MD5
|
|
*/
|
|
MD5Init(&context); /* init context for 1st
|
|
* pass */
|
|
MD5Update(&context, k_ipad, 64); /* start with inner pad */
|
|
MD5Update(&context, text, text_len); /* then text of datagram */
|
|
MD5Final(&context); /* finish up 1st pass */
|
|
|
|
CopyMemory(digest, context.digest, 16);
|
|
|
|
/*
|
|
* perform outer MD5
|
|
*/
|
|
MD5Init(&context); /* init context for 2nd
|
|
* pass */
|
|
MD5Update(&context, k_opad, 64); /* start with outer pad */
|
|
MD5Update(&context, digest, 16); /* then results of 1st
|
|
* hash */
|
|
MD5Final(&context); /* finish up 2nd pass */
|
|
CopyMemory(digest, context.digest, 16);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------------
|
|
//
|
|
// Initialize the static class members.
|
|
//
|
|
//------------------------------------------------------------------------------------
|
|
CAuthentication* CAuthentication::m_spAuthentication = NULL;
|
|
|
|
PSTR CAuthentication::GetHMACMD5Result(PSTR pszChallengeInfo, PSTR pszPassword)
|
|
{
|
|
MD5_CTX MD5Buffer;
|
|
memset(&MD5Buffer, 0, sizeof(MD5Buffer));
|
|
|
|
MD5Init(&MD5Buffer);
|
|
MD5Update(&MD5Buffer, (const unsigned char*)pszPassword, lstrlenA(pszPassword));
|
|
MD5Final(&MD5Buffer);
|
|
|
|
BYTE pbHash[16];
|
|
|
|
PBYTE pbHexHash = NULL; // The MD5 result in hex string format
|
|
pbHexHash = new BYTE[MD5DIGESTLEN * 2 + 1];
|
|
if (pbHexHash)
|
|
{
|
|
hmac_md5((unsigned char *) pszChallengeInfo, lstrlenA(pszChallengeInfo), MD5Buffer.digest, sizeof(MD5Buffer.digest), pbHash);
|
|
|
|
PBYTE pCurrent = pbHexHash;
|
|
|
|
// Convert the hash data to hex string.
|
|
for (int i = 0; i < MD5DIGESTLEN; i++)
|
|
{
|
|
*pCurrent++ = g_rgchHexNumMap[pbHash[i]/16];
|
|
*pCurrent++ = g_rgchHexNumMap[pbHash[i]%16];
|
|
}
|
|
|
|
*pCurrent = '\0';
|
|
}
|
|
|
|
return (PSTR) pbHexHash;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------------
|
|
//
|
|
// Method: CAuthentication::GetMD5Key()
|
|
//
|
|
// Synopsis: Construct the MD5 hash key based on the ChallengeInfo and password.
|
|
//
|
|
// Append the password to the ChallengeInfo.
|
|
//
|
|
//------------------------------------------------------------------------------------
|
|
PSTR
|
|
CAuthentication::GetMD5Key(PSTR pszChallengeInfo, PSTR pszPassword)
|
|
{
|
|
int cbChallengeInfo = lstrlenA(pszChallengeInfo);
|
|
int cbPassword = lstrlenA(pszPassword);
|
|
|
|
PBYTE pbData = new BYTE[cbChallengeInfo + cbPassword + 1];
|
|
|
|
if (!pbData)
|
|
{
|
|
//WARNING_OUT(("CAuthentication::GetMD5Key> Out of memory"));
|
|
return NULL;
|
|
}
|
|
|
|
PBYTE pCurrent = pbData;
|
|
|
|
::CopyMemory(pCurrent, pszChallengeInfo, cbChallengeInfo);
|
|
pCurrent += cbChallengeInfo;
|
|
::CopyMemory(pCurrent, pszPassword, cbPassword);
|
|
pCurrent += cbPassword;
|
|
*pCurrent = '\0';
|
|
|
|
return (PSTR)pbData;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------------
|
|
//
|
|
// Method: CAuthentication::GetMD5Result()
|
|
//
|
|
// Synposis: Compute the MD5 hash result based on the clear text.
|
|
//
|
|
//------------------------------------------------------------------------------------
|
|
PSTR
|
|
CAuthentication::GetMD5Result(PCSTR pszClearText)
|
|
{
|
|
PBYTE pbHexHash = NULL;
|
|
if (pszClearText)
|
|
{
|
|
MD5_CTX MD5Buffer;
|
|
MD5Init(&MD5Buffer);
|
|
MD5Update(&MD5Buffer, (const unsigned char*)pszClearText, lstrlenA(pszClearText));
|
|
MD5Final(&MD5Buffer);
|
|
|
|
PBYTE pbHash = MD5Buffer.digest;
|
|
|
|
pbHexHash = new BYTE[MD5DIGESTLEN * 2 + 1];
|
|
if (pbHexHash)
|
|
{
|
|
PBYTE pCurrent = pbHexHash;
|
|
|
|
// Convert the hash data to hex string.
|
|
for (int i = 0; i < MD5DIGESTLEN; i++)
|
|
{
|
|
*pCurrent++ = g_rgchHexNumMap[pbHash[i]/16];
|
|
*pCurrent++ = g_rgchHexNumMap[pbHash[i]%16];
|
|
}
|
|
|
|
*pCurrent = '\0';
|
|
}
|
|
else
|
|
{
|
|
//WARNING_OUT(("CAuthentication::GetMD5Result> Out of memory"));
|
|
}
|
|
}
|
|
return (PSTR)pbHexHash;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------------
|
|
//
|
|
// Method: CAuthentication::GetMD5Result()
|
|
//
|
|
// Synopsis: Compute the MD5 hash result based on the ChallengeInfo and password.
|
|
//
|
|
//------------------------------------------------------------------------------------
|
|
PSTR
|
|
CAuthentication::GetMD5Result(PSTR pszChallengeInfo, PSTR pszPassword)
|
|
{
|
|
PSTR pbHexHash = NULL; // The MD5 result in hex string format
|
|
PSTR pMD5Key = GetMD5Key(pszChallengeInfo, pszPassword);
|
|
|
|
pbHexHash = GetMD5Result(pMD5Key);
|
|
delete pMD5Key;
|
|
|
|
return pbHexHash;
|
|
}
|
|
|