⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mschapv2.c

📁 linux 下通过802.1认证的安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
/**
 * EAPMSCHAPv2 Function implementations
 *
 * Licensed under a dual GPL/BSD license.  (See LICENSE file for more info.)
 *
 * \file mschapv2.c
 *
 * \author chris@open1x.org
 *
 * $Id: mschapv2.c,v 1.16.2.16 2007/07/02 22:36:33 chessing Exp $
 * $Date: 2007/07/02 22:36:33 $
 **/

// This code was taken from the pseudo code in RFC 2759.

#include <openssl/ssl.h>
#include <openssl/des.h>
#include <string.h>

#ifndef WINDOWS
#include <strings.h>
#include <stdint.h>
#endif

#include <ctype.h>

#include "../../../lib/libxsupconfig/xsupconfig_structs.h"
#include "../../xsup_common.h"
#include "../../../lib/libxsupconfig/xsupconfig.h"
#include "../../xsup_err.h"
#include "../../context.h"
#include "../../xsup_debug.h"
#include "../../ipc_events.h"
#include "../../ipc_events_index.h"

#ifdef USE_EFENCE
#include <efence.h>
#endif

void ChallengeHash(char *PeerChallenge, char *AuthenticatorChallenge,
		   char *UserName, char *Challenge)
{
  EVP_MD_CTX cntx;
  char Digest[30];
  int retLen = 0;

  if (!xsup_assert((PeerChallenge != NULL), "PeerChallenge != NULL", FALSE))
    return;

  if (!xsup_assert((AuthenticatorChallenge != NULL), 
		   "AuthenticatorChallenge != NULL", FALSE))
    return;

  if (!xsup_assert((UserName != NULL), "UserName != NULL", FALSE))
    return;

  if (!xsup_assert((Challenge != NULL), "Challenge != NULL", FALSE))
    return;

  memset(Digest, 0x00, 30);
  EVP_DigestInit(&cntx, EVP_sha1());
  EVP_DigestUpdate(&cntx, PeerChallenge, 16);
  EVP_DigestUpdate(&cntx, AuthenticatorChallenge, 16);
  EVP_DigestUpdate(&cntx, UserName, strlen(UserName));
  EVP_DigestFinal(&cntx, (uint8_t *)&Digest, (unsigned int *) &retLen);

  memcpy(Challenge, Digest, 8);
}

char *to_unicode(char *non_uni)
{
  char *retUni;
  int i;

  if (!xsup_assert((non_uni != NULL), "non_uni != NULL", FALSE))
    return NULL;

  retUni = (char *)Malloc((strlen(non_uni)+1)*2);
  if (retUni == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Error with MALLOC in to_unicode()!\n");
	  ipc_events_malloc_failed(NULL);
      return NULL;
    }

  for (i=0; i<strlen(non_uni); i++)
    {
      retUni[(2*i)] = non_uni[i];
    }
  return retUni;
}

void NtPasswordHash(char *Password, char *PasswordHash)
{
  EVP_MD_CTX cntx;
  char retVal[20];
  int i, len;
  char *uniPassword;

  if (!xsup_assert((Password != NULL), "Password != NULL", FALSE))
    return;

  if (!xsup_assert((PasswordHash != NULL), "PasswordHash != NULL", FALSE))
    return;

  memset(retVal, 0x00, 20);
  uniPassword = to_unicode(Password);
  len = (strlen(Password))*2;

  EVP_DigestInit(&cntx, EVP_md4());
  EVP_DigestUpdate(&cntx, uniPassword, len);
  EVP_DigestFinal(&cntx, (uint8_t *)&retVal, (unsigned int *)&i);
  memcpy(PasswordHash, &retVal, 16);
  FREE(uniPassword);
}

void HashNtPasswordHash(char *PasswordHash, char *PasswordHashHash)
{
  EVP_MD_CTX cntx;
  int i;

  if (!xsup_assert((PasswordHash != NULL), "PasswordHash != NULL", FALSE))
    return;

  if (!xsup_assert((PasswordHashHash != NULL), "PasswordHashHash != NULL",
		   FALSE)) return;

  EVP_DigestInit(&cntx, EVP_md4());
  EVP_DigestUpdate(&cntx, PasswordHash, 16);
  EVP_DigestFinal(&cntx, (uint8_t *) PasswordHashHash, (unsigned int *) &i);
}

// Shamelessly take from the hostap code written by Jouni Malinen
void des_encrypt(uint8_t *clear, uint8_t *key, uint8_t *cypher)
{
  uint8_t pkey[8], next, tmp;
  int i;
  DES_key_schedule ks;

  if (!xsup_assert((clear != NULL), "clear != NULL", FALSE))
    return;

  if (!xsup_assert((key != NULL), "key != NULL", FALSE))
    return;

  if (!xsup_assert((cypher != NULL), "cypher != NULL", FALSE))
    return;

  /* Add parity bits to key */
  next = 0;
  for (i=0; i<7; i++)
    {
      tmp = key[i];
      pkey[i] = (tmp >> i) | next | 1;
      next = tmp << (7-i);
    }
  pkey[i] = next | 1;

  DES_set_key(&pkey, &ks);
  DES_ecb_encrypt((DES_cblock *) clear, (DES_cblock *) cypher, &ks,
		  DES_ENCRYPT);
}

char ctonibble(char cnib)
{
  char retVal=0x00;
  char testval=0x00;

  if ((cnib>='0') && (cnib<='9'))
    {
      retVal = cnib - '0';
    } else {
      testval = toupper(cnib);
      if ((testval>='A') && (testval<='F'))
	{
	  retVal = ((testval - 'A') +10);
	} else {
	  debug_printf(DEBUG_NORMAL, "Error in conversion!  (Check ctonibble()) -- %02x\n",testval);
	}
    }
  return retVal;
}

// Convert an ASCII hex string to it's binary version.
void process_hex(char *instr, int size, char *outstr)
{
  int i;

  if (!xsup_assert((instr != NULL), "instr != NULL", FALSE))
    return;

  if (!xsup_assert((outstr != NULL), "outstr != NULL", FALSE))
    return;

  // Make sure we don't try to convert something that isn't byte aligned.
  if ((size % 2) != 0)
    {
      debug_printf(DEBUG_NORMAL, "Hex string isn't an even number of chars!!!"
		   "\n");
      return;
    }

  for (i=0;i<(size/2);i++)
    {
      if (instr[i*2] != 0x00)
	{
	  outstr[i] = (ctonibble(instr[i*2]) << 4) + ctonibble(instr[(i*2)+1]);
	}
    }
}

void GenerateAuthenticatorResponse(char *Password, char *NTResponse,
				   char *PeerChallenge, 
				   char *AuthenticatorChallenge, char *UserName,
				   char *AuthenticatorResponse, int nthash)
{
  char PasswordHash[16];
  char PasswordHashHash[16];
  EVP_MD_CTX context;
  int Digest_len;
  char Digest[20];
  char Challenge[8];

  char 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};

  char 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};

  if (!xsup_assert((Password != NULL), "Password != NULL", FALSE))
    return;

  if (!xsup_assert((NTResponse != NULL), "NTResponse != NULL", FALSE))
    return;

  if (!xsup_assert((PeerChallenge != NULL), "PeerChallenge != NULL", FALSE))
    return;

  if (!xsup_assert((AuthenticatorChallenge != NULL),
		   "AuthenticatorChallenge != NULL", FALSE))
    return;

  if (!xsup_assert((UserName != NULL), "UserName != NULL", FALSE))
    return;

  if (!xsup_assert((AuthenticatorResponse != NULL), 
		   "AuthenticatorResponse != NULL", FALSE))
    return;

  if (nthash == 0)
    {
      NtPasswordHash(Password, (char *)&PasswordHash);
    } else {
      process_hex(Password, strlen(Password), (char *)&PasswordHash);
    }

  HashNtPasswordHash((char *)&PasswordHash, (char *)&PasswordHashHash);

  EVP_DigestInit(&context, EVP_sha1());
  EVP_DigestUpdate(&context, &PasswordHashHash, 16);
  EVP_DigestUpdate(&context, NTResponse, 24);
  EVP_DigestUpdate(&context, Magic1, 39);
  EVP_DigestFinal(&context, (uint8_t *)&Digest, (unsigned int *) &Digest_len);

  ChallengeHash(PeerChallenge, AuthenticatorChallenge, UserName, Challenge);

  EVP_DigestInit(&context, EVP_sha1());
  EVP_DigestUpdate(&context, &Digest, 20);
  EVP_DigestUpdate(&context, &Challenge, 8);
  EVP_DigestUpdate(&context, Magic2, 41);
  EVP_DigestFinal(&context, (uint8_t *)&Digest, (unsigned int *) &Digest_len);

  memcpy(AuthenticatorResponse, &Digest, Digest_len);
}



void CheckAuthenticatorResponse(char *Password, char *NtResponse,
				char *PeerChallenge, 
				char *AuthenticatorChallenge, char *UserName,
				char *ReceivedResponse, int *ResponseOK,
				int nthash)
{
  char MyResponse[20], procResp[20];
  char *stripped;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -