challenge.c
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:4k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: challenge.c,v $
  4.  * PRODUCTION Revision 1000.0  2003/10/29 20:34:28  gouriano
  5.  * PRODUCTION PRODUCTION: IMPORTED [ORIGINAL] Dev-tree R1.1
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
  10.  * Copyright (C) 1998-1999  Brian Bruns
  11.  *
  12.  * This library is free software; you can redistribute it and/or
  13.  * modify it under the terms of the GNU Library General Public
  14.  * License as published by the Free Software Foundation; either
  15.  * version 2 of the License, or (at your option) any later version.
  16.  *
  17.  * This library is distributed in the hope that it will be useful,
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  20.  * Library General Public License for more details.
  21.  *
  22.  * You should have received a copy of the GNU Library General Public
  23.  * License along with this library; if not, write to the
  24.  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  25.  * Boston, MA 02111-1307, USA.
  26.  */
  27. #include <tds_config.h>
  28. #include "tds.h"
  29. #ifdef HAVE_SSL
  30. #include <openssl/des.h>
  31. #include <openssl/md4.h>
  32. #ifdef DMALLOC
  33. #include <dmalloc.h>
  34. #endif
  35. /*
  36.  * The following code is based on some psuedo-C code from ronald@innovation.ch
  37.  */
  38. static void tds_encrypt_answer(unsigned char *hash, unsigned char *challenge, unsigned char *answer);
  39. static void tds_convert_key(unsigned char *key_56, des_key_schedule ks);
  40. #define MAX_PW_SZ 14
  41. void tds_answer_challenge(char *passwd, char *challenge, TDSANSWER* answer)
  42. {
  43. int   len;
  44. int i;
  45. static const_des_cblock magic = { 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
  46. des_key_schedule ks;
  47. unsigned char hash[24];
  48. unsigned char passwd_up[MAX_PW_SZ];
  49. unsigned char nt_pw[256];
  50. MD4_CTX context;
  51. memset(answer,0,sizeof(TDSANSWER));
  52. /* convert password to upper and pad to 14 chars */
  53. memset(passwd_up, 0, MAX_PW_SZ);
  54. len = strlen(passwd);
  55. if (len>MAX_PW_SZ) len=MAX_PW_SZ;
  56. for (i=0; i<len; i++)
  57. passwd_up[i] = toupper(passwd[i]);
  58. /* hash the first 7 characters */
  59. tds_convert_key(passwd_up, ks);
  60. des_ecb_encrypt(&magic, (des_cblock*)(hash+0), ks, DES_ENCRYPT);
  61. /* hash the second 7 characters */
  62. tds_convert_key(passwd_up+7, ks);
  63. des_ecb_encrypt(&magic, (des_cblock*)(hash+8), ks, DES_ENCRYPT);
  64. memset(hash+16, 0, 5);
  65. tds_encrypt_answer(hash, challenge, answer->lm_resp);
  66. /* NT resp */
  67. len = strlen(passwd);
  68. if (len > 128) len = 128;
  69. for(i=0;i<len;++i)
  70. {
  71. nt_pw[2*i] = passwd[i];
  72. nt_pw[2*i+1] = 0;
  73. }
  74. MD4_Init(&context);
  75. MD4_Update(&context, nt_pw, len*2);
  76. MD4_Final(hash,&context);
  77. memset(hash+16, 0, 5);
  78. tds_encrypt_answer(hash, challenge, answer->nt_resp);
  79. /* with security is best be pedantic */
  80. memset(&ks,0,sizeof(ks));
  81. memset(hash,0,sizeof(hash));
  82. memset(passwd_up,0,sizeof(passwd_up));
  83. memset(nt_pw,0,sizeof(nt_pw));
  84. memset(&context,0,sizeof(context));
  85. }
  86. /*
  87. * takes a 21 byte array and treats it as 3 56-bit DES keys. The
  88. * 8 byte plaintext is encrypted with each key and the resulting 24
  89. * bytes are stored in the results array.
  90. */
  91. static void tds_encrypt_answer(unsigned char *hash, unsigned char *challenge, unsigned char *answer)
  92. {
  93. des_key_schedule ks;
  94. tds_convert_key(hash, ks);
  95. des_ecb_encrypt((des_cblock*) challenge, (des_cblock*) answer, ks, DES_ENCRYPT);
  96. tds_convert_key(&hash[7], ks);
  97. des_ecb_encrypt((des_cblock*) challenge, (des_cblock*) (&answer[8]), ks, DES_ENCRYPT);
  98. tds_convert_key(&hash[14], ks);
  99. des_ecb_encrypt((des_cblock*) challenge, (des_cblock*) (&answer[16]), ks, DES_ENCRYPT);
  100. memset(&ks,0,sizeof(ks));
  101. }
  102. /*
  103. * turns a 56 bit key into the 64 bit, odd parity key and sets the key.
  104. * The key schedule ks is also set.
  105. */
  106. static void tds_convert_key(unsigned char *key_56, des_key_schedule ks)
  107. {
  108. des_cblock key;
  109. key[0] = key_56[0];
  110. key[1] = ((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1);
  111. key[2] = ((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2);
  112. key[3] = ((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3);
  113. key[4] = ((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4);
  114. key[5] = ((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5);
  115. key[6] = ((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6);
  116. key[7] =  (key_56[6] << 1) & 0xFF;
  117. des_set_odd_parity(&key);
  118. des_set_key(&key, ks);
  119. memset(&key, 0, sizeof(key));
  120. }
  121. #endif /* HAVE_SSL */