PageRenderTime 41ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/Miranda IM - CK Release/Miranda/Plugins/CryptoPP/src/cpp_svcs.cpp

http://miranda-dev.googlecode.com/
C++ | 345 lines | 257 code | 69 blank | 19 comment | 43 complexity | d2042439ba532bf33ba521446e636d66 MD5 | raw file
Possible License(s): GPL-2.0, MPL-2.0-no-copyleft-exception, LGPL-3.0, AGPL-1.0, BSD-3-Clause, LGPL-2.1
  1. #include "commonheaders.h"
  2. const unsigned char IV[] = "SIMhell@MIRANDA!";
  3. // encrypt string using KeyX, return encoded string as ASCII or NULL
  4. LPSTR __cdecl cpp_encrypt(pCNTX ptr, LPCSTR szPlainMsg) {
  5. ptr->error = ERROR_NONE;
  6. pSIMDATA p = (pSIMDATA) ptr->pdata;
  7. BYTE dataflag = 0;
  8. int clen,slen;
  9. slen = strlen(szPlainMsg);
  10. LPSTR szMsg;
  11. if(ptr->features & FEATURES_GZIP) {
  12. szMsg = (LPSTR) cpp_gzip((BYTE*)szPlainMsg,slen,clen);
  13. if(clen>=slen) {
  14. free(szMsg);
  15. szMsg = _strdup(szPlainMsg);
  16. }
  17. else {
  18. slen = clen;
  19. dataflag |= DATA_GZIP;
  20. }
  21. }
  22. else
  23. szMsg = _strdup(szPlainMsg);
  24. string ciphered;
  25. CBC_Mode<AES>::Encryption enc(p->KeyX,Tiger::DIGESTSIZE,IV);
  26. StreamTransformationFilter cbcEncryptor(enc,new StringSink(ciphered));
  27. cbcEncryptor.Put((PBYTE)szMsg, slen);
  28. cbcEncryptor.MessageEnd();
  29. free(szMsg);
  30. clen = (int) ciphered.length();
  31. if(ptr->features & FEATURES_CRC32) {
  32. BYTE crc32[CRC32::DIGESTSIZE];
  33. memset(crc32,0,sizeof(crc32));
  34. CRC32().CalculateDigest(crc32, (BYTE*)ciphered.data(), clen);
  35. ciphered.insert(0,(LPSTR)&crc32,CRC32::DIGESTSIZE);
  36. ciphered.insert(0,(LPSTR)&clen,2);
  37. }
  38. if(ptr->features & FEATURES_GZIP) {
  39. ciphered.insert(0,(LPSTR)&dataflag,1);
  40. }
  41. clen = (int) ciphered.length();
  42. SAFE_FREE(ptr->tmp);
  43. if(ptr->features & FEATURES_BASE64) {
  44. ptr->tmp = base64encode(ciphered.data(),clen);
  45. }
  46. else {
  47. ptr->tmp = base16encode(ciphered.data(),clen);
  48. }
  49. return ptr->tmp;
  50. }
  51. // decrypt string using KeyX, return decoded string as ASCII or NULL
  52. LPSTR __cdecl cpp_decrypt(pCNTX ptr, LPCSTR szEncMsg) {
  53. LPSTR ciphered = NULL;
  54. try {
  55. ptr->error = ERROR_SEH;
  56. pSIMDATA p = (pSIMDATA) ptr->pdata;
  57. int clen = strlen(szEncMsg);
  58. if(ptr->features & FEATURES_BASE64)
  59. ciphered = base64decode(szEncMsg,&clen);
  60. else
  61. ciphered = base16decode(szEncMsg,&clen);
  62. LPSTR bciphered = ciphered;
  63. BYTE dataflag=0;
  64. if(ptr->features & FEATURES_GZIP) {
  65. dataflag = *ciphered;
  66. bciphered++; clen--; // cut GZIP flag
  67. }
  68. if(ptr->features & FEATURES_CRC32) {
  69. int len;
  70. __asm {
  71. mov esi,[bciphered];
  72. xor eax,eax;
  73. mov ax,word ptr [esi];
  74. mov [len], eax;
  75. }
  76. bciphered+=2; clen-=2; // cut CRC32 length
  77. if(clen-CRC32::DIGESTSIZE<len) { // mesage not full
  78. #if defined(_DEBUG) || defined(NETLIB_LOG)
  79. Sent_NetLog("cpp_decrypt: error bad_len");
  80. #endif
  81. free(ciphered);
  82. ptr->error = ERROR_BAD_LEN;
  83. return NULL;
  84. }
  85. BYTE crc32[CRC32::DIGESTSIZE];
  86. memset(crc32,0,sizeof(crc32));
  87. CRC32().CalculateDigest(crc32, (PBYTE)(bciphered+CRC32::DIGESTSIZE), len);
  88. if(memcmp(crc32,bciphered,CRC32::DIGESTSIZE)) { // message is bad crc
  89. #if defined(_DEBUG) || defined(NETLIB_LOG)
  90. Sent_NetLog("cpp_decrypt: error bad_crc");
  91. #endif
  92. free(ciphered);
  93. ptr->error = ERROR_BAD_CRC;
  94. return NULL;
  95. }
  96. bciphered+=CRC32::DIGESTSIZE; // cut CRC32 digest
  97. clen=len;
  98. }
  99. string unciphered;
  100. CBC_Mode<AES>::Decryption dec(p->KeyX,Tiger::DIGESTSIZE,IV);
  101. StreamTransformationFilter cbcDecryptor(dec,new StringSink(unciphered));
  102. cbcDecryptor.Put((PBYTE)bciphered,clen);
  103. cbcDecryptor.MessageEnd();
  104. free(ciphered);
  105. SAFE_FREE(ptr->tmp);
  106. if(dataflag & DATA_GZIP) {
  107. ptr->tmp = (LPSTR) cpp_gunzip((PBYTE)unciphered.data(),unciphered.length(),clen);
  108. ptr->tmp[clen] = 0;
  109. }
  110. else {
  111. ptr->tmp = (LPSTR) strdup(unciphered.c_str());
  112. }
  113. ptr->error = ERROR_NONE;
  114. return ptr->tmp;
  115. }
  116. catch (...) {
  117. #if defined(_DEBUG) || defined(NETLIB_LOG)
  118. Sent_NetLog("cpp_decrypt: error seh");
  119. #endif
  120. free(ciphered);
  121. SAFE_FREE(ptr->tmp);
  122. return NULL;
  123. }
  124. }
  125. // encode message from ANSI into UTF8 if need
  126. LPSTR __cdecl cpp_encodeA(HANDLE context, LPCSTR msg) {
  127. pCNTX ptr = get_context_on_id(context);
  128. if(!ptr) return NULL;
  129. cpp_alloc_pdata(ptr); pSIMDATA p = (pSIMDATA) ptr->pdata;
  130. if(!p->KeyX) { ptr->error = ERROR_NO_KEYX; return NULL; }
  131. LPSTR szNewMsg = NULL;
  132. LPSTR szOldMsg = (LPSTR) msg;
  133. if(ptr->features & FEATURES_UTF8) {
  134. // ansi message: convert to unicode->utf-8 and encrypt.
  135. int slen = strlen(szOldMsg)+1;
  136. LPWSTR wstring = (LPWSTR) alloca(slen*sizeof(WCHAR));
  137. MultiByteToWideChar(CP_ACP, 0, szOldMsg, -1, wstring, slen*sizeof(WCHAR));
  138. // encrypt
  139. szNewMsg = cpp_encrypt(ptr, utf8encode(wstring));
  140. }
  141. else {
  142. // ansi message: encrypt.
  143. szNewMsg = cpp_encrypt(ptr, szOldMsg);
  144. }
  145. return szNewMsg;
  146. }
  147. // encode message from UTF8
  148. LPSTR __cdecl cpp_encodeU(HANDLE context, LPCSTR msg) {
  149. pCNTX ptr = get_context_on_id(context);
  150. if(!ptr) return NULL;
  151. cpp_alloc_pdata(ptr); pSIMDATA p = (pSIMDATA) ptr->pdata;
  152. if(!p->KeyX) { ptr->error = ERROR_NO_KEYX; return NULL; }
  153. LPSTR szNewMsg = NULL;
  154. LPSTR szOldMsg = (LPSTR) msg;
  155. if(ptr->features & FEATURES_UTF8) {
  156. // utf8 message: encrypt.
  157. szNewMsg = cpp_encrypt(ptr, szOldMsg);
  158. }
  159. else {
  160. // utf8 message: convert to ansi and encrypt.
  161. LPWSTR wstring = utf8decode(szOldMsg);
  162. int wlen = wcslen(wstring)+1;
  163. LPSTR astring = (LPSTR) alloca(wlen);
  164. WideCharToMultiByte(CP_ACP, 0, (LPWSTR)szOldMsg, -1, astring, wlen, 0, 0);
  165. szNewMsg = cpp_encrypt(ptr, astring);
  166. }
  167. return szNewMsg;
  168. }
  169. // encode message from UNICODE into UTF8 if need
  170. LPSTR __cdecl cpp_encodeW(HANDLE context, LPWSTR msg) {
  171. pCNTX ptr = get_context_on_id(context);
  172. if(!ptr) return NULL;
  173. cpp_alloc_pdata(ptr); pSIMDATA p = (pSIMDATA) ptr->pdata;
  174. if(!p->KeyX) { ptr->error = ERROR_NO_KEYX; return NULL; }
  175. LPSTR szNewMsg = NULL;
  176. LPSTR szOldMsg = (LPSTR) msg;
  177. if(ptr->features & FEATURES_UTF8) {
  178. // unicode message: convert to utf-8 and encrypt.
  179. szNewMsg = cpp_encrypt(ptr, utf8encode((LPWSTR)szOldMsg));
  180. }
  181. else {
  182. // unicode message: convert to ansi and encrypt.
  183. int wlen = wcslen((LPWSTR)szOldMsg)+1;
  184. LPSTR astring = (LPSTR) alloca(wlen);
  185. WideCharToMultiByte(CP_ACP, 0, (LPWSTR)szOldMsg, -1, astring, wlen, 0, 0);
  186. szNewMsg = cpp_encrypt(ptr, astring);
  187. }
  188. return szNewMsg;
  189. }
  190. // decode message from UTF8 if need, return ANSIzUCS2z
  191. LPSTR __cdecl cpp_decode(HANDLE context, LPCSTR szEncMsg) {
  192. pCNTX ptr = get_context_on_id(context);
  193. if(!ptr) return NULL;
  194. cpp_alloc_pdata(ptr); pSIMDATA p = (pSIMDATA) ptr->pdata;
  195. if(!p->KeyX) { ptr->error = ERROR_NO_KEYX; return NULL; }
  196. LPSTR szNewMsg = NULL;
  197. LPSTR szOldMsg = cpp_decrypt(ptr, szEncMsg);
  198. if(szOldMsg) {
  199. if(ptr->features & FEATURES_UTF8) {
  200. // utf8 message: convert to unicode -> ansii
  201. LPWSTR wstring = utf8decode(szOldMsg);
  202. int wlen = wcslen(wstring)+1;
  203. szNewMsg = (LPSTR) malloc(wlen*(sizeof(WCHAR)+2)); // work.zy@gmail.com
  204. WideCharToMultiByte(CP_ACP, 0, wstring, -1, szNewMsg, wlen, 0, 0);
  205. memcpy(szNewMsg+strlen(szNewMsg)+1, wstring, wlen*sizeof(WCHAR)); // work.zy@gmail.com
  206. }
  207. else {
  208. // ansi message: convert to unicode
  209. int slen = strlen(szOldMsg)+1;
  210. szNewMsg = (LPSTR) malloc(slen*(sizeof(WCHAR)+1));
  211. memcpy(szNewMsg,szOldMsg,slen);
  212. WCHAR* wstring = (LPWSTR) alloca(slen*sizeof(WCHAR));
  213. MultiByteToWideChar(CP_ACP, 0, szOldMsg, -1, wstring, slen*sizeof(WCHAR));
  214. memcpy(szNewMsg+slen,wstring,slen*sizeof(WCHAR));
  215. }
  216. }
  217. SAFE_FREE(ptr->tmp);
  218. ptr->tmp = szNewMsg;
  219. return szNewMsg;
  220. }
  221. // decode message return UTF8z
  222. LPSTR __cdecl cpp_decodeU(HANDLE context, LPCSTR szEncMsg) {
  223. pCNTX ptr = get_context_on_id(context);
  224. if(!ptr) return NULL;
  225. cpp_alloc_pdata(ptr); pSIMDATA p = (pSIMDATA) ptr->pdata;
  226. if(!p->KeyX) { ptr->error = ERROR_NO_KEYX; return NULL; }
  227. LPSTR szNewMsg = NULL;
  228. LPSTR szOldMsg = cpp_decrypt(ptr, szEncMsg);
  229. if(szOldMsg) {
  230. if(ptr->features & FEATURES_UTF8) {
  231. // utf8 message: copy
  232. szNewMsg = _strdup(szOldMsg);
  233. }
  234. else {
  235. // ansi message: convert to utf8
  236. int slen = strlen(szOldMsg)+1;
  237. LPWSTR wstring = (LPWSTR) alloca(slen*sizeof(WCHAR));
  238. MultiByteToWideChar(CP_ACP, 0, szOldMsg, -1, wstring, slen*sizeof(WCHAR));
  239. szNewMsg = _strdup(utf8encode(wstring));
  240. }
  241. }
  242. SAFE_FREE(ptr->tmp);
  243. ptr->tmp = szNewMsg;
  244. return szNewMsg;
  245. }
  246. int __cdecl cpp_encrypt_file(HANDLE context,LPCSTR file_in,LPCSTR file_out) {
  247. pCNTX ptr = get_context_on_id(context);
  248. if(!ptr) return 0;
  249. cpp_alloc_pdata(ptr); pSIMDATA p = (pSIMDATA) ptr->pdata;
  250. if(!p->KeyX) return 0;
  251. try{
  252. CBC_Mode<AES>::Encryption enc(p->KeyX,Tiger::DIGESTSIZE,IV);
  253. FileSource *f = new FileSource(file_in,true,new StreamTransformationFilter (enc,new FileSink(file_out)));
  254. delete f;
  255. }
  256. catch (...) {
  257. return 0;
  258. }
  259. return 1;
  260. }
  261. int __cdecl cpp_decrypt_file(HANDLE context,LPCSTR file_in,LPCSTR file_out) {
  262. pCNTX ptr = get_context_on_id(context);
  263. if(!ptr) return 0;
  264. cpp_alloc_pdata(ptr); pSIMDATA p = (pSIMDATA) ptr->pdata;
  265. if(!p->KeyX) return 0;
  266. try{
  267. CBC_Mode<AES>::Decryption dec(p->KeyX,Tiger::DIGESTSIZE,IV);
  268. FileSource *f = new FileSource(file_in,true,new StreamTransformationFilter (dec,new FileSink(file_out)));
  269. delete f;
  270. }
  271. catch (...) {
  272. return 0;
  273. }
  274. return 1;
  275. }
  276. // EOF