#include <freeradius-devel/ident.h>
RCSID("$Id$")
#include <freeradius-devel/radiusd.h>
#include <freeradius-devel/modules.h>
#include <freeradius-devel/rad_assert.h>
#include <freeradius-devel/md5.h>
#include <freeradius-devel/sha1.h>
#include <ctype.h>
#include "smbdes.h"
void mschap_ntpwdhash (uint8_t *szHash, const char *szPassword)
{
char szUnicodePass[513];
int nPasswordLen;
int i;
nPasswordLen = strlen(szPassword);
for (i = 0; i < nPasswordLen; i++) {
szUnicodePass[i << 1] = szPassword[i];
szUnicodePass[(i << 1) + 1] = 0;
}
fr_md4_calc(szHash, (uint8_t *) szUnicodePass, (nPasswordLen<<1) );
}
void mschap_challenge_hash( const uint8_t *peer_challenge,
const uint8_t *auth_challenge,
const char *user_name, uint8_t *challenge )
{
fr_SHA1_CTX Context;
uint8_t hash[20];
fr_SHA1Init(&Context);
fr_SHA1Update(&Context, peer_challenge, 16);
fr_SHA1Update(&Context, auth_challenge, 16);
fr_SHA1Update(&Context, (const uint8_t *) user_name,
strlen(user_name));
fr_SHA1Final(hash, &Context);
memcpy(challenge, hash, 8);
}
void mschap_auth_response(const char *username,
const uint8_t *nt_hash_hash,
uint8_t *ntresponse,
uint8_t *peer_challenge, uint8_t *auth_challenge,
char *response)
{
fr_SHA1_CTX Context;
static const uint8_t magic1[39] =
{0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76,
0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65,
0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67,
0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74};
static const uint8_t magic2[41] =
{0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B,
0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F,
0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E,
0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F,
0x6E};
static const char hex[16] = "0123456789ABCDEF";
size_t i;
uint8_t challenge[8];
uint8_t digest[20];
fr_SHA1Init(&Context);
fr_SHA1Update(&Context, nt_hash_hash, 16);
fr_SHA1Update(&Context, ntresponse, 24);
fr_SHA1Update(&Context, magic1, 39);
fr_SHA1Final(digest, &Context);
mschap_challenge_hash(peer_challenge, auth_challenge, username, challenge);
fr_SHA1Init(&Context);
fr_SHA1Update(&Context, digest, 20);
fr_SHA1Update(&Context, challenge, 8);
fr_SHA1Update(&Context, magic2, 41);
fr_SHA1Final(digest, &Context);
response[0] = 'S';
response[1] = '=';
for (i = 0; i < sizeof(digest); i++) {
response[2 + (i * 2)] = hex[(digest[i] >> 4) & 0x0f];
response[3 + (i * 2)] = hex[digest[i] & 0x0f];
}
}