Pol  Rev 533
clib/MD5.cpp
Go to the documentation of this file.
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 }