|
Pol
Rev 533
|
00001 /* 00002 History 00003 ======= 00004 2003/06/29 Dave: MD5_Encrypt(), changed the order. the "safe" method was also really slow, so do it only if the "fast" method fails. 00005 also, store provider handle for further speed improvements 00006 00007 Notes 00008 ======= 00009 00010 */ 00011 00012 #include "stl_inc.h" 00013 00014 #include "stlutil.h" 00015 #include "MD5.h" 00016 00017 #ifdef _WIN32 00018 #define _WIN32_WINNT 0x0400 // need this for wincrypt.h to be even looked at 00019 #include <windows.h> 00020 #include <wincrypt.h> 00021 #undef _WIN32_WINNT 00022 00023 HCRYPTPROV hProv = NULL; 00024 00025 bool MD5_Encrypt(const string& in, string& out) 00026 { 00027 //bool bResult = true; 00028 00029 //HCRYPTKEY hKey = NULL; 00030 //HCRYPTKEY hXchgKey = NULL; 00031 HCRYPTHASH hHash = NULL; 00032 00033 if(!hProv) 00034 { 00035 if (! CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) 00036 { 00037 if (! CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0)) 00038 { 00039 cerr << "Error " << GetLastError() << " acquiring crypt context" << std::endl; 00040 return false; 00041 } 00042 } 00043 } 00044 00045 if (! CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) 00046 { 00047 cerr << "Error " << GetLastError() << " creating hash" << std::endl; 00048 return false; 00049 } 00050 00051 // Hash password string. 00052 if (!CryptHashData(hHash, (const unsigned char*)(in.data()), static_cast<unsigned long>(in.length()), 0)) 00053 { 00054 cerr << "Error " << GetLastError() << " adding data to hash" << std::endl; 00055 return false; 00056 } 00057 unsigned long len = 16; 00058 unsigned char buf[16]; 00059 if (! CryptGetHashParam(hHash, HP_HASHVAL, buf, &len, 0)) 00060 { 00061 cerr << "Error " << GetLastError() << " getting hash value" << std::endl; 00062 return false; 00063 } 00064 00065 ostringstream os; 00066 for(unsigned int i=0; i<len; i++) 00067 { 00068 os << std::setfill('0') << std::setw(2) << hex << (int)buf[i]; 00069 } 00070 out = os.str(); 00071 00072 CryptDestroyHash(hHash); 00073 return true; 00074 } 00075 00076 void MD5_Cleanup() 00077 { 00078 CryptReleaseContext(hProv, 0); 00079 } 00080 00081 #elif defined(HAVE_OPENSSL) 00082 00083 #include <openssl/md5.h> 00084 00085 bool MD5_Encrypt(const string& in, string& out) 00086 { 00087 unsigned char sum[16]; 00088 00089 MD5( reinterpret_cast<const unsigned char*>(in.c_str()), in.length(), sum ); 00090 00091 ostringstream os; 00092 for(unsigned int i=0; i<sizeof(sum); i++) 00093 { 00094 os << std::setfill('0') << std::setw(2) << hex << (int)sum[i]; 00095 } 00096 out = os.str(); 00097 00098 return true; 00099 } 00100 void MD5_Cleanup() 00101 { 00102 //OpenSSL cleanup, if any 00103 } 00104 00105 #else 00106 extern "C"{ 00107 #include "MD5.h" 00108 } 00109 00110 bool MD5_Encrypt(const string& in, string& out) 00111 { 00112 struct md5_ctx ctx; 00113 unsigned char sum[16]; 00114 00115 __md5_init_ctx (&ctx); 00116 __md5_process_bytes (in.c_str(), in.length(), &ctx); 00117 __md5_finish_ctx (&ctx, sum); 00118 00119 ostringstream os; 00120 for(unsigned int i=0; i<sizeof(sum); i++) 00121 { 00122 os << std::setfill('0') << std::setw(2) << hex << (int)sum[i]; 00123 } 00124 out = os.str(); 00125 00126 return true; 00127 } 00128 00129 void MD5_Cleanup() 00130 { 00131 //MD5 cleanup, if any. Consider storing ctx until server shutdown. 00132 } 00133 00134 #endif 00135 00136 bool MD5_Compare(const string& a, const string& b) 00137 { 00138 bool ret = false; 00139 if( stringicmp(a,b) == 0) 00140 ret = true; 00141 00142 return ret; 00143 }