zcrypt.cpp 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #ifdef _WIN32
  14. #pragma warning(disable: 4996)
  15. #endif
  16. #include "zcrypt.ipp"
  17. #include "aes.hpp"
  18. #include "base64.ipp"
  19. #include "zip.h"
  20. #include "jexcept.hpp"
  21. #include <math.h>
  22. #ifdef WIN32
  23. #define USEWIN32IOAPI
  24. #include "iowin32.h"
  25. #endif
  26. IZBuffer::~IZBuffer()
  27. {
  28. }
  29. IZEncryptor::~IZEncryptor()
  30. {
  31. }
  32. IZDecryptor::~IZDecryptor()
  33. {
  34. }
  35. IZZIPor::~IZZIPor()
  36. {
  37. }
  38. RSAZCryptor::RSAZCryptor(unsigned traceLevel)
  39. {
  40. setTraceLevel(traceLevel);
  41. init();
  42. }
  43. RSAZCryptor::RSAZCryptor(const char* publickeyBuff, unsigned traceLevel)
  44. {
  45. setTraceLevel(traceLevel);
  46. init();
  47. setPublicKey(publickeyBuff);
  48. }
  49. RSAZCryptor::RSAZCryptor(const char* privatekeyBuff, const char* passphrase, unsigned traceLevel)
  50. {
  51. setTraceLevel(traceLevel);
  52. init();
  53. setPrivateKey(privatekeyBuff, passphrase);
  54. }
  55. void RSAZCryptor::init()
  56. {
  57. m_encoding = true;
  58. bio_err = NULL;
  59. priv_mem = NULL;
  60. pub_mem = NULL;
  61. privkey = NULL;
  62. pubkey = NULL;
  63. priv_rsa = NULL;
  64. pub_rsa = NULL;
  65. priv_size = 0;
  66. pub_size = 0;
  67. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
  68. bio_err=BIO_new_fp(stderr, BIO_NOCLOSE);
  69. #if defined(_WIN32) || defined(__linux__)
  70. OpenSSL_add_all_ciphers();
  71. #else
  72. SSL_library_init();
  73. #endif
  74. ERR_load_crypto_strings ();
  75. seed_prng();
  76. m_keycache = new ZKeyCache();
  77. m_filesToBeZIP = NULL;
  78. }
  79. int RSAZCryptor::setPublicKey(const char* publickeyBuff)
  80. {
  81. if(!publickeyBuff || !*publickeyBuff)
  82. {
  83. if(m_trace_level > 0)
  84. printf("Warning: publickeyBuff is empty\n");
  85. return -1;
  86. }
  87. if(pubkey)
  88. {
  89. EVP_PKEY_free(pubkey);
  90. pubkey = NULL;
  91. }
  92. if(pub_mem)
  93. {
  94. BIO_free(pub_mem);
  95. pub_mem = NULL;
  96. }
  97. if(pub_rsa)
  98. {
  99. RSA_free(pub_rsa);
  100. pub_rsa = NULL;
  101. }
  102. pub_size = 0;
  103. pub_mem = BIO_new(BIO_s_mem());
  104. BIO_puts(pub_mem, publickeyBuff);
  105. if (!(pubkey = PEM_read_bio_PUBKEY(pub_mem, NULL, NULL, NULL)))
  106. {
  107. throw_error();
  108. }
  109. if(!(pub_rsa = EVP_PKEY_get1_RSA(pubkey)))
  110. {
  111. throw_error();
  112. }
  113. pub_size = RSA_size(pub_rsa);
  114. generate_key(32, m_sessionkey);
  115. ZBuffer ekeybuf;
  116. publickey_encrypt(m_sessionkey.length(), m_sessionkey.buffer(), ekeybuf);
  117. base64_encode(ekeybuf.length(), ekeybuf.buffer(), m_encrypted_sessionkey);
  118. return 0;
  119. }
  120. int RSAZCryptor::setPrivateKey(const char* privatekeyBuff, const char* passphrase)
  121. {
  122. if(!privatekeyBuff || !*privatekeyBuff)
  123. {
  124. if(m_trace_level > 0)
  125. printf("Warning: privatekeyBuff is empty\n");
  126. return -1;
  127. }
  128. if(privkey)
  129. {
  130. EVP_PKEY_free(privkey);
  131. privkey = NULL;
  132. }
  133. if(priv_mem)
  134. {
  135. BIO_free(priv_mem);
  136. priv_mem = NULL;
  137. }
  138. if(priv_rsa)
  139. {
  140. RSA_free(priv_rsa);
  141. priv_rsa = NULL;
  142. }
  143. priv_size = 0;
  144. priv_mem = BIO_new(BIO_s_mem());
  145. BIO_puts(priv_mem, privatekeyBuff);
  146. if (!(privkey = PEM_read_bio_PrivateKey (priv_mem, NULL, NULL, (void*)passphrase)))
  147. {
  148. throw_error();
  149. }
  150. if(!(priv_rsa = EVP_PKEY_get1_RSA(privkey)))
  151. {
  152. throw_error();
  153. }
  154. priv_size = RSA_size(priv_rsa);
  155. return 0;
  156. }
  157. RSAZCryptor::~RSAZCryptor()
  158. {
  159. if(m_keycache)
  160. delete m_keycache;
  161. if(bio_err)
  162. {
  163. CRYPTO_mem_leaks(bio_err);
  164. BIO_free(bio_err);
  165. }
  166. if(privkey)
  167. EVP_PKEY_free(privkey);
  168. if(pubkey)
  169. EVP_PKEY_free(pubkey);
  170. if(priv_mem)
  171. BIO_free(priv_mem);
  172. if(pub_mem)
  173. BIO_free(pub_mem);
  174. if(priv_rsa)
  175. RSA_free(priv_rsa);
  176. if(pub_rsa)
  177. RSA_free(pub_rsa);
  178. EVP_cleanup();
  179. }
  180. void RSAZCryptor::throw_error()
  181. {
  182. char errbuf[512];
  183. ERR_error_string_n(ERR_get_error(), errbuf, 512);
  184. if(m_trace_level > 0)
  185. printf("Error: %s\n", errbuf);
  186. throw string(errbuf);
  187. }
  188. void RSAZCryptor::setTraceLevel(unsigned trace_level)
  189. {
  190. m_trace_level = trace_level;
  191. }
  192. int RSAZCryptor::gzipToFile(unsigned in_len, void const *in, const char* tempFile)
  193. {
  194. if (in_len < 1)
  195. return -1;
  196. if (!in)
  197. return -2;
  198. if (!tempFile || !*tempFile)
  199. return -3;
  200. gzFile fp = gzopen(tempFile, "wb");
  201. if (!fp)
  202. return -4;
  203. gzwrite(fp, in, in_len);
  204. gzclose(fp);
  205. return 0;
  206. }
  207. //a caller should be responsible for releasing memory for
  208. //the 'content' after the zipToFile function is called.
  209. int RSAZCryptor::addContentToZIP(unsigned contentLength, void *content, char* fileName, bool append)
  210. {
  211. time_t simple;
  212. time(&simple);
  213. return addContentToZIP(contentLength, content, fileName, simple, append);
  214. }
  215. //a caller should be responsible for releasing memory for
  216. //the 'content' after the zipToFile function is called.
  217. int RSAZCryptor::addContentToZIP(unsigned contentLength, void *content, char* fileName, time_t fileTM, bool append)
  218. {
  219. if (!append && m_filesToBeZIP)
  220. {
  221. cleanFileList(m_filesToBeZIP);
  222. m_filesToBeZIP = NULL;
  223. }
  224. linkedlist_filetozip* pFile = new linkedlist_filetozip();
  225. pFile->next_filetozip = NULL;
  226. pFile->file_name = NULL;
  227. if (fileName && *fileName)
  228. {
  229. int len = strlen(fileName);
  230. pFile->file_name = (char*)malloc(len+1);
  231. strcpy(pFile->file_name, fileName);
  232. }
  233. pFile->file_content = content;
  234. pFile->content_length = contentLength;
  235. pFile->file_time = fileTM;
  236. if (!m_filesToBeZIP)
  237. m_filesToBeZIP = pFile;
  238. else
  239. {
  240. linkedlist_filetozip* ppFile = m_filesToBeZIP;
  241. while (ppFile->next_filetozip)
  242. {
  243. ppFile = ppFile->next_filetozip;
  244. }
  245. ppFile->next_filetozip = pFile;
  246. }
  247. return 0;
  248. }
  249. void RSAZCryptor::cleanFileList(linkedlist_filetozip* pFileList)
  250. {
  251. if (!pFileList) //nothing to clean
  252. return;
  253. if (pFileList->next_filetozip)
  254. {
  255. cleanFileList(pFileList->next_filetozip);
  256. }
  257. if (pFileList->file_name)
  258. free(pFileList->file_name);
  259. delete pFileList;
  260. pFileList = NULL;
  261. }
  262. int RSAZCryptor::zipToFile(const char* zipFileName, bool cleanFileListAfterUsed)
  263. {
  264. unsigned len=(int)strlen(zipFileName);
  265. char* filename_try = (char*)malloc(len+16);
  266. if (filename_try==NULL)
  267. {
  268. return ZIP_INTERNALERROR;
  269. }
  270. strcpy(filename_try, zipFileName);
  271. bool dot_found = false;
  272. for (unsigned i=0; i<len; i++)
  273. {
  274. if (filename_try[i]=='.')
  275. {
  276. dot_found=true;
  277. break;
  278. }
  279. }
  280. if (!dot_found)
  281. strcat(filename_try,".zip");
  282. zipFile zf;
  283. int opt_overwrite=0; //?1
  284. #ifdef USEWIN32IOAPI
  285. zlib_filefunc_def ffunc;
  286. fill_win32_filefunc(&ffunc);
  287. zf = zipOpen2(filename_try,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc);
  288. #else
  289. zf = zipOpen(filename_try,(opt_overwrite==2) ? 2 : 0);
  290. #endif
  291. int err=0;
  292. if (zf == NULL)
  293. {
  294. printf("error opening %s\n",filename_try);
  295. err= ZIP_ERRNO;
  296. }
  297. unsigned count = 0;
  298. linkedlist_filetozip* pFileList = m_filesToBeZIP;
  299. while (pFileList && (err==ZIP_OK))
  300. {
  301. count++;
  302. unsigned contentLength = pFileList->content_length;
  303. void const *content = pFileList->file_content;
  304. char* fileName = NULL;
  305. char fileName0[16];
  306. if (pFileList->file_name)
  307. fileName = pFileList->file_name;
  308. else
  309. {
  310. sprintf(fileName0, "file%d", count);
  311. fileName = fileName0;
  312. }
  313. struct tm * ts = gmtime(&pFileList->file_time);
  314. zip_fileinfo zi;
  315. zi.tmz_date.tm_sec = ts->tm_sec;
  316. zi.tmz_date.tm_min = ts->tm_min;
  317. zi.tmz_date.tm_hour = ts->tm_hour;
  318. zi.tmz_date.tm_mday = ts->tm_mday;
  319. zi.tmz_date.tm_mon = ts->tm_mon;
  320. zi.tmz_date.tm_year = ts->tm_year;
  321. zi.dosDate = 0;
  322. zi.internal_fa = 0;
  323. zi.external_fa = 0;
  324. err = zipOpenNewFileInZip3(zf,fileName,&zi,
  325. NULL,0,NULL,0,NULL /* comment*/,
  326. Z_DEFLATED,
  327. Z_DEFAULT_COMPRESSION,0,
  328. /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */
  329. -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
  330. NULL, 0);
  331. if (err != ZIP_OK)
  332. printf("error in opening %s in zipfile\n",fileName);
  333. if (contentLength>0)
  334. {
  335. err = zipWriteInFileInZip (zf,content,contentLength);
  336. if (err<0)
  337. {
  338. printf("error in writing %s in the zipfile\n", fileName);
  339. }
  340. }
  341. if (err<0)
  342. err=ZIP_ERRNO;
  343. else
  344. {
  345. err = zipCloseFileInZip(zf);
  346. if (err!=ZIP_OK)
  347. printf("error in closing %s in the zipfile\n", fileName);
  348. }
  349. pFileList = pFileList->next_filetozip;
  350. }
  351. if (zipClose(zf,NULL) != ZIP_OK)
  352. printf("error in closing %s\n",filename_try);
  353. free(filename_try);
  354. if (cleanFileListAfterUsed)
  355. {
  356. cleanFileList(m_filesToBeZIP);
  357. m_filesToBeZIP = NULL;
  358. }
  359. return 0;
  360. }
  361. int RSAZCryptor::zipToFile(unsigned contentLength, void const *content, const char* fileToBeZipped, const char* fileOut)
  362. {
  363. unsigned len=(int)strlen(fileOut);
  364. char* filename_try = (char*)malloc(len+16);
  365. if (filename_try==NULL)
  366. {
  367. return ZIP_INTERNALERROR;
  368. }
  369. strcpy(filename_try, fileOut);
  370. bool dot_found = false;
  371. for (unsigned i=0; i<len; i++)
  372. {
  373. if (filename_try[i]=='.')
  374. {
  375. dot_found=true;
  376. break;
  377. }
  378. }
  379. if (!dot_found)
  380. strcat(filename_try,".zip");
  381. zipFile zf;
  382. int opt_overwrite=0; //?1
  383. #ifdef USEWIN32IOAPI
  384. zlib_filefunc_def ffunc;
  385. fill_win32_filefunc(&ffunc);
  386. zf = zipOpen2(filename_try,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc);
  387. #else
  388. zf = zipOpen(filename_try,(opt_overwrite==2) ? 2 : 0);
  389. #endif
  390. int err=0;
  391. if (zf == NULL)
  392. {
  393. printf("error opening %s\n",filename_try);
  394. err= ZIP_ERRNO;
  395. }
  396. zip_fileinfo zi;
  397. zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
  398. zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
  399. zi.dosDate = 0;
  400. zi.internal_fa = 0;
  401. zi.external_fa = 0;
  402. err = zipOpenNewFileInZip3(zf,fileToBeZipped,&zi,
  403. NULL,0,NULL,0,NULL /* comment*/,
  404. Z_DEFLATED,
  405. Z_DEFAULT_COMPRESSION,0,
  406. /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */
  407. -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
  408. NULL, 0);
  409. if (err != ZIP_OK)
  410. printf("error in opening %s in zipfile\n",fileToBeZipped);
  411. if (contentLength>0)
  412. {
  413. err = zipWriteInFileInZip (zf,content,contentLength);
  414. if (err<0)
  415. {
  416. printf("error in writing %s in the zipfile\n", fileToBeZipped);
  417. }
  418. }
  419. if (err<0)
  420. err=ZIP_ERRNO;
  421. else
  422. {
  423. err = zipCloseFileInZip(zf);
  424. if (err!=ZIP_OK)
  425. printf("error in closing %s in the zipfile\n", fileToBeZipped);
  426. }
  427. if (zipClose(zf,NULL) != ZIP_OK)
  428. printf("error in closing %s\n",filename_try);
  429. free(filename_try);
  430. return 0;
  431. }
  432. int RSAZCryptor::zip(int in_len, unsigned char* in, ZBuffer& outbuf)
  433. {
  434. if(in_len <= 0 || !in || !*in)
  435. {
  436. if(m_trace_level > 0)
  437. printf("Warning: input to zip() is empty\n");
  438. return Z_DATA_ERROR;
  439. }
  440. int ret;
  441. unsigned have;
  442. z_stream strm;
  443. int buflen = in_len / 10;
  444. if(buflen <= 1)
  445. buflen = 1;
  446. /* allocate deflate state */
  447. strm.zalloc = Z_NULL;
  448. strm.zfree = Z_NULL;
  449. strm.opaque = Z_NULL;
  450. ret = deflateInit(&strm, Z_DEFAULT_COMPRESSION);
  451. if (ret != Z_OK)
  452. {
  453. if(m_trace_level > 0)
  454. printf("Warning: deflateInit returned %d\n", ret);
  455. return ret;
  456. }
  457. strm.avail_in = in_len;
  458. strm.next_in = in;
  459. ZBuffer onebuf(buflen);
  460. do
  461. {
  462. strm.avail_out = buflen;
  463. strm.next_out = onebuf.buffer();
  464. ret = deflate(&strm, Z_FINISH); /* no bad return value */
  465. if(ret == Z_STREAM_ERROR)
  466. {
  467. if(m_trace_level > 0)
  468. printf("Warning: deflate() returned Z_STREAM_ERROR\n");
  469. return ret;
  470. }
  471. have = buflen - strm.avail_out;
  472. if(have > 0)
  473. outbuf.append(have, onebuf.buffer());
  474. }
  475. while (strm.avail_out == 0);
  476. (void)deflateEnd(&strm);
  477. return Z_OK;
  478. }
  479. int RSAZCryptor::unzip(int in_len, unsigned char* in, ZBuffer& outbuf)
  480. {
  481. if(in_len <= 0 || !in || !*in)
  482. {
  483. if(m_trace_level > 0)
  484. printf("Warning: input to unzip() is empty\n");
  485. return Z_DATA_ERROR;
  486. }
  487. int ret;
  488. unsigned have;
  489. z_stream strm;
  490. /* allocate inflate state */
  491. strm.zalloc = Z_NULL;
  492. strm.zfree = Z_NULL;
  493. strm.opaque = Z_NULL;
  494. strm.avail_in = 0;
  495. strm.next_in = Z_NULL;
  496. ret = inflateInit(&strm);
  497. if (ret != Z_OK)
  498. {
  499. if(m_trace_level > 0)
  500. printf("Warning: inflateInit returned %d\n", ret);
  501. return ret;
  502. }
  503. strm.avail_in = in_len;
  504. strm.next_in = in;
  505. int buflen = in_len * 2;
  506. ZBuffer onebuf(buflen);
  507. /* run inflate() on input until output buffer not full */
  508. do
  509. {
  510. strm.avail_out = buflen;
  511. strm.next_out = onebuf.buffer();
  512. ret = inflate(&strm, Z_NO_FLUSH);
  513. if(ret == Z_STREAM_ERROR)
  514. {
  515. if(m_trace_level > 0)
  516. printf("Warning: deflate() returned Z_STREAM_ERROR\n");
  517. return ret;
  518. }
  519. switch (ret)
  520. {
  521. case Z_NEED_DICT:
  522. ret = Z_DATA_ERROR; /* and fall through */
  523. case Z_DATA_ERROR:
  524. case Z_MEM_ERROR:
  525. if(m_trace_level > 0)
  526. printf("Warning: deflate() returned %d\n", ret);
  527. (void)inflateEnd(&strm);
  528. return ret;
  529. }
  530. have = buflen - strm.avail_out;
  531. if(have > 0)
  532. {
  533. outbuf.append(have, onebuf.buffer());
  534. }
  535. }
  536. while (strm.avail_out == 0);
  537. /* clean up and return */
  538. (void)inflateEnd(&strm);
  539. return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
  540. }
  541. void RSAZCryptor::setEncoding(bool yes)
  542. {
  543. m_encoding = yes;
  544. }
  545. void RSAZCryptor::seed_prng()
  546. {
  547. #ifdef _WIN32
  548. __int64 curtime = __rdtsc();//read timestamp count
  549. void* ptr = (void*)&curtime;
  550. RAND_seed(ptr, 8);
  551. #else
  552. RAND_load_file("/dev/urandom", 1024);
  553. #endif
  554. }
  555. ZBuffer& RSAZCryptor::publickey_encrypt(int in_len, unsigned char* in, ZBuffer& result)
  556. {
  557. if(in_len <= 0)
  558. {
  559. if(m_trace_level > 0)
  560. printf("Warning: input to publickey_encrypt is empty\n");
  561. return result;
  562. }
  563. ZBuffer onebuf(pub_size);
  564. int onelen = 0;
  565. int inc = pub_size - 42;
  566. int resultlen = (in_len/inc + (((in_len%inc) == 0)?0:1)) * pub_size;
  567. result.reserve(resultlen);
  568. int curpos = 0;
  569. unsigned char* resultptr = result.buffer();
  570. while(curpos < in_len)
  571. {
  572. int cur_inc = (in_len - curpos > inc)?inc:(in_len - curpos);
  573. onelen = RSA_public_encrypt(cur_inc, in + curpos, onebuf.buffer(), pub_rsa, RSA_PKCS1_OAEP_PADDING);
  574. if(onelen < 0)
  575. {
  576. throw_error();
  577. }
  578. memcpy(resultptr, onebuf.buffer(), onelen);
  579. curpos += cur_inc;
  580. resultptr += onelen;
  581. }
  582. return result;
  583. }
  584. ZBuffer& RSAZCryptor::privatekey_decrypt(int in_len, unsigned char* in, ZBuffer& result)
  585. {
  586. if(in_len <= 0)
  587. {
  588. if(m_trace_level > 0)
  589. printf("Warning: input to privatekey_decrypt is empty\n");
  590. return result;
  591. }
  592. ZBuffer onebuf(priv_size);
  593. int onelen = 0;
  594. int inc = priv_size;
  595. int est_len = (in_len/priv_size + (((in_len%priv_size)==0)?0:1)) * (priv_size - 42);
  596. result.reserve(est_len);
  597. unsigned char* resultptr = result.buffer();
  598. unsigned resultlen = 0;
  599. int curpos = 0;
  600. while(curpos < in_len)
  601. {
  602. int cur_inc = (in_len - curpos > inc)?inc:(in_len - curpos);
  603. onelen = RSA_private_decrypt(cur_inc, in + curpos, onebuf.buffer(), priv_rsa, RSA_PKCS1_OAEP_PADDING);
  604. if(onelen < 0)
  605. {
  606. throw_error();
  607. }
  608. memcpy(resultptr + resultlen, onebuf.buffer(), onelen);
  609. resultlen += onelen;
  610. curpos += cur_inc;
  611. }
  612. resultptr[resultlen] = '\0';
  613. result.setLength(resultlen);
  614. return result;
  615. }
  616. ZBuffer& RSAZCryptor::generate_key(int len, ZBuffer& keybuf)
  617. {
  618. if(len <= 0)
  619. return keybuf;
  620. if(m_trace_level > 5)
  621. printf("Info: generating a %d byte session key\n", len);
  622. keybuf.reserve(len);
  623. RAND_bytes(keybuf.buffer(), len);
  624. /*
  625. for(int i = 0; i < len - 1; i++)
  626. {
  627. printf("%02X", keybuf.buffer()[i]);
  628. }
  629. printf("%02X\n", keybuf.buffer()[len - 1]);
  630. */
  631. return keybuf;
  632. }
  633. int RSAZCryptor::encrypt(int in_len, unsigned char* in, IZBuffer*& session_key, IZBuffer*& encrypted_data)
  634. {
  635. if(in_len <= 0 || !in || !*in)
  636. {
  637. if(m_trace_level > 0)
  638. printf("Warning: input to encrypt is empty\n");
  639. return 0;
  640. }
  641. if(m_trace_level > 10)
  642. printf("Info: encrypt input: \n%s\n", in);
  643. session_key = new ZBuffer;
  644. ((ZBuffer*)session_key)->append(m_encrypted_sessionkey.length(), m_encrypted_sessionkey.buffer());
  645. ZBuffer zippedbuf;
  646. int ret = zip(in_len, in, zippedbuf);
  647. int zippedlen = zippedbuf.length();
  648. if(ret != Z_OK || zippedlen <= 0)
  649. return -1;
  650. if(m_trace_level > 5)
  651. printf("Info: length before zipping: %d, length after zipping: %d, compression ratio: %6.2f:1\n", in_len, zippedlen, in_len*1.0/zippedlen);
  652. ZBuffer outbuf;
  653. aes_encrypt(m_sessionkey.buffer(), m_sessionkey.length(), zippedbuf.buffer(), zippedbuf.length(), outbuf);
  654. if(m_trace_level > 5)
  655. printf("Info: length after encryption: %d\n", outbuf.length());
  656. // base64 encode
  657. encrypted_data = new ZBuffer();
  658. if(m_encoding)
  659. {
  660. base64_encode(outbuf.length(), outbuf.buffer(), *(ZBuffer*)encrypted_data);
  661. if(m_trace_level > 5)
  662. {
  663. printf("Info: length after base64 encoding: %d\n", encrypted_data->length());
  664. if(m_trace_level > 10)
  665. printf("Info: zip/encryption/base64-encoding result:\n%s\n", encrypted_data->buffer());
  666. }
  667. }
  668. else
  669. {
  670. int result_len = outbuf.length();
  671. ((ZBuffer*)encrypted_data)->setBuffer(result_len, outbuf.detach());
  672. }
  673. return 0;
  674. }
  675. IZBuffer* RSAZCryptor::decrypt(int key_len, unsigned char* keybuf, int in_len, unsigned char* inbuf)
  676. {
  677. if(key_len <= 0 || !keybuf)
  678. {
  679. if(m_trace_level > 0)
  680. printf("Warning: Please specify a key for decryption.\n");
  681. return NULL;
  682. }
  683. if(in_len <= 0 || !inbuf)
  684. {
  685. return NULL;
  686. }
  687. if(m_trace_level > 5)
  688. {
  689. printf("Info: length of keybuf %d\n", key_len);
  690. printf("Info: length of inbuf %d\n", in_len);
  691. }
  692. if(m_trace_level > 10)
  693. {
  694. printf("Info: key for decryption: \n%s\n", keybuf);
  695. }
  696. ZBuffer* dkeybuf = m_keycache->getCachedKey(this, key_len, keybuf);
  697. if(!dkeybuf)
  698. {
  699. return NULL;
  700. }
  701. // Base64 decode first
  702. ZBuffer dbuf;
  703. int dlen = in_len;
  704. unsigned char* dptr = inbuf;
  705. if(m_encoding)
  706. {
  707. base64_decode(in_len, (const char*)inbuf, dbuf);
  708. if(m_trace_level > 5)
  709. printf("Info: data length after base64 decode: %d\n", dbuf.length());
  710. dlen = dbuf.length();
  711. dptr = dbuf.buffer();
  712. }
  713. ZBuffer buf;
  714. aes_decrypt(dkeybuf->buffer(), dkeybuf->length(), dptr, dlen, buf);
  715. if(m_trace_level > 5)
  716. printf("Info: data length after aes_decryption: %d\n", buf.length());
  717. ZBuffer* outbuf = new ZBuffer();
  718. int ret = unzip(buf.length(), buf.buffer(), *outbuf);
  719. if(ret != Z_OK || outbuf->length() <= 0)
  720. return NULL;
  721. if(m_trace_level > 5)
  722. printf("Info: data length after base64-decode/decryption/unzip: %d\n", outbuf->length());
  723. if(m_trace_level > 10)
  724. printf("info: base64-decode/decryption/unzip result:\n%s\n", outbuf->buffer());
  725. return outbuf;
  726. }
  727. IZBuffer* RSAZCryptor::decrypt(unsigned char* keybuf, unsigned char* inbuf)
  728. {
  729. if(!keybuf || !inbuf)
  730. {
  731. if(m_trace_level > 0)
  732. printf("Warning: Please specify key and input for decryption.\n");
  733. return NULL;
  734. }
  735. return decrypt(strlen((const char*)keybuf), keybuf, strlen((const char*)inbuf), inbuf);
  736. }
  737. ZBuffer* ZKeyCache::getCachedKey(RSAZCryptor* zc, int elen, unsigned char* ekey)
  738. {
  739. if(!elen || !ekey)
  740. return NULL;
  741. zsynchronized block(m_mutex);
  742. int start = simpleHash(elen, ekey) % ZKEYCACHESIZE;
  743. int ind = start;
  744. int oldest = start;
  745. do
  746. {
  747. ZKeyEntry* entry = m_cache[ind];
  748. if(!entry)
  749. break;
  750. ZBuffer* cur_ekey = entry->getEKey();
  751. if(!cur_ekey)
  752. {
  753. delete entry;
  754. m_cache[ind] = NULL;
  755. break;
  756. }
  757. if(cur_ekey->equal(elen, ekey))
  758. return entry->getKey();
  759. if(entry->getTimestamp() < m_cache[oldest]->getTimestamp())
  760. oldest = ind;
  761. ind = (ind+1) % ZKEYCACHESIZE;
  762. }
  763. while(ind != start);
  764. if(m_cache[ind] != NULL)
  765. {
  766. if(m_cache[oldest] != NULL)
  767. {
  768. delete m_cache[oldest];
  769. m_cache[oldest] = NULL;
  770. }
  771. ind = oldest;
  772. }
  773. ZBuffer buf;
  774. base64_decode(elen, (char*)ekey, buf);
  775. ZBuffer keybuf;
  776. zc->privatekey_decrypt(buf.length(), buf.buffer(), keybuf);
  777. m_cache[ind] = new ZKeyEntry(elen, ekey, keybuf.length(), keybuf.buffer());
  778. return m_cache[ind]->getKey();
  779. return NULL;
  780. }
  781. extern "C" {
  782. ZCRYPT_API IZEncryptor* createZEncryptor(const char* publickey)
  783. {
  784. return new RSAZCryptor(publickey);
  785. }
  786. ZCRYPT_API IZDecryptor* createZDecryptor(const char* privatekey, const char* passphrase)
  787. {
  788. return new RSAZCryptor(privatekey, passphrase);
  789. }
  790. ZCRYPT_API IZZIPor* createZZIPor()
  791. {
  792. return new RSAZCryptor();
  793. }
  794. ZCRYPT_API void releaseIZ(IZInterface* iz)
  795. {
  796. if(iz)
  797. delete iz;
  798. }
  799. }
  800. inline const char *getZlibHeaderTypeName(ZlibCompressionType zltype)
  801. {
  802. if (zltype==ZlibCompressionType::GZIP)
  803. return "gzip";
  804. if (zltype==ZlibCompressionType::ZLIB_DEFLATE)
  805. return "zlib_deflate";
  806. //DEFLATE, no header
  807. return "deflate";
  808. }
  809. static void throwZlibException(const char* operation, int errorCode, ZlibCompressionType zltype)
  810. {
  811. const char* errorMsg;
  812. switch (errorCode)
  813. {
  814. case Z_ERRNO:
  815. errorMsg = "Error occured while reading file";
  816. break;
  817. case Z_STREAM_ERROR:
  818. errorMsg = "The stream state was inconsistent";
  819. break;
  820. case Z_DATA_ERROR:
  821. errorMsg = "The deflate data was invalid or incomplete";
  822. break;
  823. case Z_MEM_ERROR:
  824. errorMsg = "Memory could not be allocated for processing";
  825. break;
  826. case Z_BUF_ERROR:
  827. errorMsg = "Insufficient output buffer";
  828. break;
  829. case Z_VERSION_ERROR:
  830. errorMsg = "The version mismatch between zlib.h and the library linked";
  831. break;
  832. default:
  833. errorMsg = "Unknown exception";
  834. break;
  835. }
  836. throw MakeStringException(500, "Exception in %s %s: %s.", getZlibHeaderTypeName(zltype), operation, errorMsg);
  837. }
  838. inline int getWindowBits(ZlibCompressionType zltype)
  839. {
  840. if (zltype==ZlibCompressionType::GZIP)
  841. return 15+16;
  842. if (zltype==ZlibCompressionType::ZLIB_DEFLATE)
  843. return 15;
  844. //DEFLATE, no header
  845. return -15;
  846. }
  847. // Compress a character buffer using zlib in gzip/zlib_deflate format with given compression level
  848. //
  849. void zlib_deflate(MemoryBuffer &mb, const char* inputBuffer, unsigned int inputSize, int compressionLevel, ZlibCompressionType zltype)
  850. {
  851. if (inputBuffer == NULL || inputSize == 0)
  852. throw MakeStringException(500, "%s failed: input buffer is empty!", getZlibHeaderTypeName(zltype));
  853. /* Before we can begin compressing (aka "deflating") data using the zlib
  854. functions, we must initialize zlib. Normally this is done by calling the
  855. deflateInit() function; in this case, however, we'll use deflateInit2() so
  856. that the compressed data will have gzip headers if requested. This will make
  857. it easy to decompress the data later using a tool like gunzip, WinZip, etc.
  858. deflateInit2() accepts many parameters, the first of which is a C struct of
  859. type "z_stream" defined in zlib.h. The properties of this struct are used to
  860. control how the compression algorithms work. z_stream is also used to
  861. maintain pointers to the "input" and "output" byte buffers (next_in/out) as
  862. well as information about how many bytes have been processed, how many are
  863. left to process, etc. */
  864. z_stream zs; // z_stream is zlib's control structure
  865. zs.zalloc = Z_NULL; // Set zalloc, zfree, and opaque to Z_NULL so
  866. zs.zfree = Z_NULL; // that when we call deflateInit2 they will be
  867. zs.opaque = Z_NULL; // updated to use default allocation functions.
  868. zs.total_out = 0; // Total number of output bytes produced so far
  869. /* Initialize the zlib deflation (i.e. compression) internals with deflateInit2().
  870. The parameters are as follows:
  871. z_streamp strm - Pointer to a zstream struct
  872. int level - Compression level. Must be Z_DEFAULT_COMPRESSION, or between
  873. 0 and 9: 1 gives best speed, 9 gives best compression, 0 gives
  874. no compression.
  875. int method - Compression method. Only method supported is "Z_DEFLATED".
  876. int windowBits - Base two logarithm of the maximum window size (the size of
  877. the history buffer). It should be in the range 8..15. Add
  878. 16 to windowBits to write a simple gzip header and trailer
  879. around the compressed data instead of a zlib wrapper. The
  880. gzip header will have no file name, no extra data, no comment,
  881. no modification time (set to zero), no header crc, and the
  882. operating system will be set to 255 (unknown).
  883. int memLevel - Amount of memory allocated for internal compression state.
  884. 1 uses minimum memory but is slow and reduces compression
  885. ratio; 9 uses maximum memory for optimal speed. Default value
  886. is 8.
  887. int strategy - Used to tune the compression algorithm. Use the value
  888. Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data
  889. produced by a filter (or predictor), or Z_HUFFMAN_ONLY to
  890. force Huffman encoding only (no string match) */
  891. int ret = deflateInit2(&zs, compressionLevel, Z_DEFLATED, getWindowBits(zltype), 8, Z_DEFAULT_STRATEGY);
  892. if (ret != Z_OK)
  893. throwZlibException("initialization", ret, zltype);
  894. // set the z_stream's input
  895. zs.next_in = (Bytef*)inputBuffer;
  896. zs.avail_in = inputSize;
  897. // Create output memory buffer for compressed data. The zlib documentation states that
  898. // destination buffer size must be at least 0.1% larger than avail_in plus 12 bytes.
  899. const unsigned long outsize = (unsigned long) inputSize + inputSize / 1000 + 13;
  900. Bytef* outbuf = (Bytef*) mb.reserveTruncate(outsize);
  901. do
  902. {
  903. // Store location where next byte should be put in next_out
  904. zs.next_out = outbuf + zs.total_out;
  905. // Calculate the amount of remaining free space in the output buffer
  906. // by subtracting the number of bytes that have been written so far
  907. // from the buffer's total capacity
  908. zs.avail_out = outsize - zs.total_out;
  909. /* deflate() compresses as much data as possible, and stops/returns when
  910. the input buffer becomes empty or the output buffer becomes full. If
  911. deflate() returns Z_OK, it means that there are more bytes left to
  912. compress in the input buffer but the output buffer is full; the output
  913. buffer should be expanded and deflate should be called again (i.e., the
  914. loop should continue to rune). If deflate() returns Z_STREAM_END, the
  915. end of the input stream was reached (i.e.g, all of the data has been
  916. compressed) and the loop should stop. */
  917. ret = deflate(&zs, Z_FINISH);
  918. } while (ret == Z_OK);
  919. // Free data structures that were dynamically created for the stream.
  920. deflateEnd(&zs);
  921. if (ret != Z_STREAM_END) // an error occurred that was not EOS
  922. {
  923. mb.clear();
  924. throwZlibException("compression", ret, zltype);
  925. }
  926. mb.setLength(zs.total_out);
  927. }
  928. // Compress a character buffer using zlib in gzip format with given compression level
  929. //
  930. void gzip(MemoryBuffer &mb, const char* inputBuffer, unsigned int inputSize, int compressionLevel)
  931. {
  932. zlib_deflate(mb, inputBuffer, inputSize, compressionLevel, ZlibCompressionType::GZIP);
  933. }
  934. bool zlib_inflate(const byte* compressed, unsigned int comprLen, StringBuffer& sOutput, ZlibCompressionType zltype, bool inflateException)
  935. {
  936. if (comprLen == 0)
  937. return true;
  938. const int CHUNK_OUT = 16384;
  939. z_stream d_stream; // decompression stream
  940. memset( &d_stream, 0, sizeof(z_stream));
  941. d_stream.next_in = (byte*) compressed;
  942. d_stream.avail_in = comprLen;
  943. int ret = inflateInit2(&d_stream, getWindowBits(zltype));
  944. if (ret != Z_OK)
  945. throwZlibException("initialization", ret, zltype); //don't ignore this
  946. unsigned int outLen = 0;
  947. do
  948. {
  949. sOutput.ensureCapacity( outLen + CHUNK_OUT );
  950. d_stream.avail_out = CHUNK_OUT; //free space in the output buffer
  951. d_stream.next_out = (byte*)sOutput.str() + outLen;
  952. ret = inflate(&d_stream, Z_NO_FLUSH);
  953. if (ret < Z_OK)
  954. break;
  955. outLen += CHUNK_OUT - d_stream.avail_out;
  956. sOutput.setLength( outLen );
  957. } while (d_stream.avail_out == 0 || ret != Z_STREAM_END);
  958. inflateEnd(&d_stream);
  959. if (ret != Z_STREAM_END)
  960. {
  961. sOutput.clear();
  962. if (!inflateException)
  963. return false;
  964. throwZlibException("decompression", ret, zltype);
  965. }
  966. return true;
  967. }
  968. void gunzip(const byte* compressed, unsigned int comprLen, StringBuffer& sOutput)
  969. {
  970. zlib_inflate(compressed, comprLen, sOutput, ZlibCompressionType::GZIP, true);
  971. }
  972. void httpInflate(const byte* compressed, unsigned int comprLen, StringBuffer& sOutput, bool use_gzip)
  973. {
  974. if (use_gzip)
  975. {
  976. zlib_inflate(compressed, comprLen, sOutput, ZlibCompressionType::GZIP, true);
  977. }
  978. else if (!zlib_inflate(compressed, comprLen, sOutput, ZlibCompressionType::ZLIB_DEFLATE, false)) //this is why gzip is preferred, deflate can mean 2 things
  979. {
  980. zlib_inflate(compressed, comprLen, sOutput, ZlibCompressionType::DEFLATE, true);
  981. }
  982. }
  983. bool isgzipped(const byte * content, size_t length)
  984. {
  985. if (length < 2)
  986. return false;
  987. return (content[0] == 0x1f) && (content[1] == 0x8b);
  988. }
  989. void removeZipExtension(StringBuffer & target, const char * source)
  990. {
  991. target.set(source);
  992. const char * extension = strrchr(target.str(), '.');
  993. if (extension && streq(extension, ".gz"))
  994. target.remove(extension-target.str(), 3);
  995. }