#include "commonheaders.h" const unsigned char IV[] = "SIMhell@MIRANDA!"; // encrypt string using KeyX, return encoded string as ASCII or NULL LPSTR __cdecl cpp_encrypt(pCNTX ptr, LPCSTR szPlainMsg) { ptr->error = ERROR_NONE; pSIMDATA p = (pSIMDATA) ptr->pdata; BYTE dataflag = 0; size_t slen = strlen(szPlainMsg); LPSTR szMsg; if (ptr->features & FEATURES_GZIP) { size_t clen; szMsg = (LPSTR) cpp_gzip((BYTE*)szPlainMsg,slen,clen); if (clen>=slen) { free(szMsg); szMsg = _strdup(szPlainMsg); } else { slen = clen; dataflag |= DATA_GZIP; } } else szMsg = _strdup(szPlainMsg); string ciphered; CBC_Mode::Encryption enc(p->KeyX,Tiger::DIGESTSIZE,IV); StreamTransformationFilter cbcEncryptor(enc,new StringSink(ciphered)); cbcEncryptor.Put((PBYTE)szMsg, slen); cbcEncryptor.MessageEnd(); free(szMsg); unsigned clen = (unsigned)ciphered.length(); if (ptr->features & FEATURES_CRC32) { BYTE crc32[CRC32::DIGESTSIZE]; memset(crc32,0,sizeof(crc32)); CRC32().CalculateDigest(crc32, (BYTE*)ciphered.data(), clen); ciphered.insert(0,(LPSTR)&crc32,CRC32::DIGESTSIZE); ciphered.insert(0,(LPSTR)&clen,2); } if (ptr->features & FEATURES_GZIP) ciphered.insert(0,(LPSTR)&dataflag,1); clen = (unsigned)ciphered.length(); if (ptr->features & FEATURES_BASE64) replaceStr(ptr->tmp, mir_base64_encode((PBYTE)ciphered.data(), clen)); else replaceStr(ptr->tmp, base16encode(ciphered.data(), clen)); return ptr->tmp; } // decrypt string using KeyX, return decoded string as ASCII or NULL LPSTR __cdecl cpp_decrypt(pCNTX ptr, LPCSTR szEncMsg) { ptrA ciphered; try { ptr->error = ERROR_SEH; pSIMDATA p = (pSIMDATA) ptr->pdata; unsigned clen = (unsigned)strlen(szEncMsg); if (ptr->features & FEATURES_BASE64) ciphered = (LPSTR)mir_base64_decode(szEncMsg,&clen); else ciphered = base16decode(szEncMsg,&clen); LPSTR bciphered = ciphered; BYTE dataflag=0; if (ptr->features & FEATURES_GZIP) { dataflag = *ciphered; bciphered++; clen--; // cut GZIP flag } if (ptr->features & FEATURES_CRC32) { int len = *( WORD* )bciphered; bciphered+=2; clen-=2; // cut CRC32 length if ((int)clen - CRC32::DIGESTSIZE < len) { // mesage not full #if defined(_DEBUG) || defined(NETLIB_LOG) Sent_NetLog("cpp_decrypt: error bad_len"); #endif ptr->error = ERROR_BAD_LEN; return NULL; } BYTE crc32[CRC32::DIGESTSIZE]; memset(crc32,0,sizeof(crc32)); CRC32().CalculateDigest(crc32, (PBYTE)(bciphered+CRC32::DIGESTSIZE), len); if (memcmp(crc32,bciphered,CRC32::DIGESTSIZE)) { // message is bad crc #if defined(_DEBUG) || defined(NETLIB_LOG) Sent_NetLog("cpp_decrypt: error bad_crc"); #endif ptr->error = ERROR_BAD_CRC; return NULL; } bciphered += CRC32::DIGESTSIZE; // cut CRC32 digest clen = len; } string unciphered; CBC_Mode::Decryption dec(p->KeyX,Tiger::DIGESTSIZE,IV); StreamTransformationFilter cbcDecryptor(dec,new StringSink(unciphered)); cbcDecryptor.Put((PBYTE)bciphered,clen); cbcDecryptor.MessageEnd(); if (dataflag & DATA_GZIP) { size_t clen2 = clen; LPSTR res = (LPSTR)cpp_gunzip((PBYTE)unciphered.data(),unciphered.length(),clen2); replaceStr(ptr->tmp, mir_strndup(res, clen2)); free(res); } else replaceStr(ptr->tmp, mir_strdup(unciphered.c_str())); ptr->error = ERROR_NONE; return ptr->tmp; } catch (...) { #if defined(_DEBUG) || defined(NETLIB_LOG) Sent_NetLog("cpp_decrypt: error seh"); #endif mir_free(ptr->tmp); ptr->tmp = 0; return NULL; } } // encode message from ANSI into UTF8 if need LPSTR __cdecl cpp_encodeA(HANDLE context, LPCSTR msg) { pCNTX ptr = get_context_on_id(context); if (!ptr) return NULL; cpp_alloc_pdata(ptr); pSIMDATA p = (pSIMDATA) ptr->pdata; if (!p->KeyX) { ptr->error = ERROR_NO_KEYX; return NULL; } LPSTR szNewMsg = NULL; LPSTR szOldMsg = (LPSTR) msg; if (ptr->features & FEATURES_UTF8) { // ansi message: convert to unicode->utf-8 and encrypt. int slen = (int)strlen(szOldMsg)+1; LPWSTR wstring = (LPWSTR) alloca(slen*sizeof(WCHAR)); MultiByteToWideChar(CP_ACP, 0, szOldMsg, -1, wstring, slen*sizeof(WCHAR)); // encrypt szNewMsg = cpp_encrypt(ptr, utf8encode(wstring)); } else { // ansi message: encrypt. szNewMsg = cpp_encrypt(ptr, szOldMsg); } return szNewMsg; } // encode message from UTF8 LPSTR __cdecl cpp_encodeU(HANDLE context, LPCSTR msg) { pCNTX ptr = get_context_on_id(context); if (!ptr) return NULL; cpp_alloc_pdata(ptr); pSIMDATA p = (pSIMDATA) ptr->pdata; if (!p->KeyX) { ptr->error = ERROR_NO_KEYX; return NULL; } LPSTR szNewMsg = NULL; LPSTR szOldMsg = (LPSTR) msg; if (ptr->features & FEATURES_UTF8) { // utf8 message: encrypt. szNewMsg = cpp_encrypt(ptr, szOldMsg); } else { // utf8 message: convert to ansi and encrypt. LPWSTR wstring = utf8decode(szOldMsg); int wlen = (int)wcslen(wstring)+1; LPSTR astring = (LPSTR) alloca(wlen); WideCharToMultiByte(CP_ACP, 0, (LPWSTR)szOldMsg, -1, astring, wlen, 0, 0); szNewMsg = cpp_encrypt(ptr, astring); } return szNewMsg; } // encode message from UNICODE into UTF8 if need LPSTR __cdecl cpp_encodeW(HANDLE context, LPWSTR msg) { pCNTX ptr = get_context_on_id(context); if (!ptr) return NULL; cpp_alloc_pdata(ptr); pSIMDATA p = (pSIMDATA) ptr->pdata; if (!p->KeyX) { ptr->error = ERROR_NO_KEYX; return NULL; } LPSTR szNewMsg = NULL; LPSTR szOldMsg = (LPSTR) msg; if (ptr->features & FEATURES_UTF8) { // unicode message: convert to utf-8 and encrypt. szNewMsg = cpp_encrypt(ptr, utf8encode((LPWSTR)szOldMsg)); } else { // unicode message: convert to ansi and encrypt. int wlen = (int)wcslen((LPWSTR)szOldMsg)+1; LPSTR astring = (LPSTR) alloca(wlen); WideCharToMultiByte(CP_ACP, 0, (LPWSTR)szOldMsg, -1, astring, wlen, 0, 0); szNewMsg = cpp_encrypt(ptr, astring); } return szNewMsg; } // decode message from UTF8 if need, return ANSIzUCS2z LPSTR __cdecl cpp_decode(HANDLE context, LPCSTR szEncMsg) { pCNTX ptr = get_context_on_id(context); if (!ptr) return NULL; cpp_alloc_pdata(ptr); pSIMDATA p = (pSIMDATA) ptr->pdata; if (!p->KeyX) { ptr->error = ERROR_NO_KEYX; return NULL; } LPSTR szNewMsg = NULL; LPSTR szOldMsg = cpp_decrypt(ptr, szEncMsg); if (szOldMsg) { if (ptr->features & FEATURES_UTF8) { // utf8 message: convert to unicode -> ansii LPWSTR wstring = utf8decode(szOldMsg); int wlen = (int)wcslen(wstring)+1; szNewMsg = (LPSTR)mir_alloc(wlen*(sizeof(WCHAR)+2)); // work.zy@gmail.com WideCharToMultiByte(CP_ACP, 0, wstring, -1, szNewMsg, wlen, 0, 0); memcpy(szNewMsg+strlen(szNewMsg)+1, wstring, wlen*sizeof(WCHAR)); // work.zy@gmail.com } else { // ansi message: convert to unicode int slen = (int)strlen(szOldMsg)+1; szNewMsg = (LPSTR)mir_alloc(slen*(sizeof(WCHAR)+1)); memcpy(szNewMsg,szOldMsg,slen); WCHAR* wstring = (LPWSTR) alloca(slen*sizeof(WCHAR)); MultiByteToWideChar(CP_ACP, 0, szOldMsg, -1, wstring, slen*sizeof(WCHAR)); memcpy(szNewMsg+slen,wstring,slen*sizeof(WCHAR)); } } replaceStr(ptr->tmp, szNewMsg); return szNewMsg; } // decode message return UTF8z LPSTR __cdecl cpp_decodeU(HANDLE context, LPCSTR szEncMsg) { pCNTX ptr = get_context_on_id(context); if (!ptr) return NULL; cpp_alloc_pdata(ptr); pSIMDATA p = (pSIMDATA) ptr->pdata; if (!p->KeyX) { ptr->error = ERROR_NO_KEYX; return NULL; } LPSTR szNewMsg = NULL; LPSTR szOldMsg = cpp_decrypt(ptr, szEncMsg); if (szOldMsg) { if (ptr->features & FEATURES_UTF8) { // utf8 message: copy szNewMsg = mir_strdup(szOldMsg); } else { // ansi message: convert to utf8 int slen = (int)strlen(szOldMsg)+1; LPWSTR wstring = (LPWSTR) alloca(slen*sizeof(WCHAR)); MultiByteToWideChar(CP_ACP, 0, szOldMsg, -1, wstring, slen*sizeof(WCHAR)); szNewMsg = mir_strdup(utf8encode(wstring)); } } replaceStr(ptr->tmp, szNewMsg); return szNewMsg; } int __cdecl cpp_encrypt_file(HANDLE context,LPCSTR file_in,LPCSTR file_out) { pCNTX ptr = get_context_on_id(context); if (!ptr) return 0; cpp_alloc_pdata(ptr); pSIMDATA p = (pSIMDATA) ptr->pdata; if (!p->KeyX) return 0; try{ CBC_Mode::Encryption enc(p->KeyX,Tiger::DIGESTSIZE,IV); FileSource *f = new FileSource(file_in,true,new StreamTransformationFilter (enc,new FileSink(file_out))); delete f; } catch (...) { return 0; } return 1; } int __cdecl cpp_decrypt_file(HANDLE context,LPCSTR file_in,LPCSTR file_out) { pCNTX ptr = get_context_on_id(context); if (!ptr) return 0; cpp_alloc_pdata(ptr); pSIMDATA p = (pSIMDATA) ptr->pdata; if (!p->KeyX) return 0; try{ CBC_Mode::Decryption dec(p->KeyX,Tiger::DIGESTSIZE,IV); FileSource *f = new FileSource(file_in,true,new StreamTransformationFilter (dec,new FileSink(file_out))); delete f; } catch (...) { return 0; } return 1; } // EOF