zcrypt.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167
  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. #pragma warning(disable: 4996)
  14. #include "zcrypt.ipp"
  15. #include "aes.hpp"
  16. #include "base64.ipp"
  17. #include "zip.h"
  18. #include "jexcept.hpp"
  19. #include <math.h>
  20. #ifdef WIN32
  21. #define USEWIN32IOAPI
  22. #include "iowin32.h"
  23. #endif
  24. IZBuffer::~IZBuffer()
  25. {
  26. }
  27. IZEncryptor::~IZEncryptor()
  28. {
  29. }
  30. IZDecryptor::~IZDecryptor()
  31. {
  32. }
  33. IZZIPor::~IZZIPor()
  34. {
  35. }
  36. RSAZCryptor::RSAZCryptor()
  37. {
  38. init();
  39. }
  40. RSAZCryptor::RSAZCryptor(const char* publickey)
  41. {
  42. init();
  43. setPublicKey(publickey);
  44. }
  45. RSAZCryptor::RSAZCryptor(const char* privatekey, const char* passphrase)
  46. {
  47. init();
  48. setPrivateKey(privatekey, passphrase);
  49. }
  50. void RSAZCryptor::init()
  51. {
  52. m_trace_level = 0;
  53. m_encoding = true;
  54. bio_err = NULL;
  55. priv_mem = NULL;
  56. pub_mem = NULL;
  57. privkey = NULL;
  58. pubkey = NULL;
  59. priv_rsa = NULL;
  60. pub_rsa = NULL;
  61. priv_size = 0;
  62. pub_size = 0;
  63. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
  64. bio_err=BIO_new_fp(stderr, BIO_NOCLOSE);
  65. #if defined(_WIN32) || defined(__linux__)
  66. OpenSSL_add_all_ciphers();
  67. #else
  68. SSL_library_init();
  69. #endif
  70. ERR_load_crypto_strings ();
  71. seed_prng();
  72. m_keycache = new ZKeyCache();
  73. m_filesToBeZIP = NULL;
  74. }
  75. int RSAZCryptor::setPublicKey(const char* publickey)
  76. {
  77. if(!publickey || !*publickey)
  78. {
  79. if(m_trace_level > 0)
  80. printf("Warning: publickey is empty\n");
  81. return -1;
  82. }
  83. if(m_trace_level > 10)
  84. printf("setting publickey:\n%s\n", publickey);
  85. if(pubkey)
  86. {
  87. EVP_PKEY_free(pubkey);
  88. pubkey = NULL;
  89. }
  90. if(pub_mem)
  91. {
  92. BIO_free(pub_mem);
  93. pub_mem = NULL;
  94. }
  95. if(pub_rsa)
  96. {
  97. RSA_free(pub_rsa);
  98. pub_rsa = NULL;
  99. }
  100. pub_size = 0;
  101. pub_mem = BIO_new(BIO_s_mem());
  102. BIO_puts(pub_mem, publickey);
  103. if (!(pubkey = PEM_read_bio_PUBKEY(pub_mem, NULL, NULL, NULL)))
  104. {
  105. throw_error();
  106. }
  107. if(!(pub_rsa = EVP_PKEY_get1_RSA(pubkey)))
  108. {
  109. throw_error();
  110. }
  111. pub_size = RSA_size(pub_rsa);
  112. generate_key(32, m_sessionkey);
  113. ZBuffer ekeybuf;
  114. publickey_encrypt(m_sessionkey.length(), m_sessionkey.buffer(), ekeybuf);
  115. base64_encode(ekeybuf.length(), ekeybuf.buffer(), m_encrypted_sessionkey);
  116. return 0;
  117. }
  118. int RSAZCryptor::setPrivateKey(const char* privatekey, const char* passphrase)
  119. {
  120. if(!privatekey || !*privatekey)
  121. {
  122. if(m_trace_level > 0)
  123. printf("Warning: privatekey is empty\n");
  124. return -1;
  125. }
  126. if(m_trace_level > 10)
  127. printf("setting privatekey:\n%s\n", privatekey);
  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, privatekey);
  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. static void throwGZipException(const char* operation, int errorCode)
  801. {
  802. const char* errorMsg;
  803. switch (errorCode)
  804. {
  805. case Z_ERRNO:
  806. errorMsg = "Error occured while reading file";
  807. break;
  808. case Z_STREAM_ERROR:
  809. errorMsg = "The stream state was inconsistent";
  810. break;
  811. case Z_DATA_ERROR:
  812. errorMsg = "The deflate data was invalid or incomplete";
  813. break;
  814. case Z_MEM_ERROR:
  815. errorMsg = "Memory could not be allocated for processing";
  816. break;
  817. case Z_BUF_ERROR:
  818. errorMsg = "Insufficient output buffer";
  819. break;
  820. case Z_VERSION_ERROR:
  821. errorMsg = "The version mismatch between zlib.h and the library linked";
  822. break;
  823. default:
  824. errorMsg = "Unknown exception";
  825. break;
  826. }
  827. throw MakeStringException(500, "Exception in gzip %s: %s.", operation, errorMsg);
  828. }
  829. // Compress a character buffer using zlib in gzip format with given compression level
  830. //
  831. char* gzip( const char* inputBuffer, unsigned int inputSize, unsigned int* outlen, int compressionLevel)
  832. {
  833. if (inputBuffer == NULL || inputSize == 0)
  834. throw MakeStringException(500, "gzip failed: input buffer is empty!");
  835. /* Before we can begin compressing (aka "deflating") data using the zlib
  836. functions, we must initialize zlib. Normally this is done by calling the
  837. deflateInit() function; in this case, however, we'll use deflateInit2() so
  838. that the compressed data will have gzip headers. This will make it easy to
  839. decompress the data later using a tool like gunzip, WinZip, etc.
  840. deflateInit2() accepts many parameters, the first of which is a C struct of
  841. type "z_stream" defined in zlib.h. The properties of this struct are used to
  842. control how the compression algorithms work. z_stream is also used to
  843. maintain pointers to the "input" and "output" byte buffers (next_in/out) as
  844. well as information about how many bytes have been processed, how many are
  845. left to process, etc. */
  846. z_stream zs; // z_stream is zlib's control structure
  847. zs.zalloc = Z_NULL; // Set zalloc, zfree, and opaque to Z_NULL so
  848. zs.zfree = Z_NULL; // that when we call deflateInit2 they will be
  849. zs.opaque = Z_NULL; // updated to use default allocation functions.
  850. zs.total_out = 0; // Total number of output bytes produced so far
  851. /* Initialize the zlib deflation (i.e. compression) internals with deflateInit2().
  852. The parameters are as follows:
  853. z_streamp strm - Pointer to a zstream struct
  854. int level - Compression level. Must be Z_DEFAULT_COMPRESSION, or between
  855. 0 and 9: 1 gives best speed, 9 gives best compression, 0 gives
  856. no compression.
  857. int method - Compression method. Only method supported is "Z_DEFLATED".
  858. int windowBits - Base two logarithm of the maximum window size (the size of
  859. the history buffer). It should be in the range 8..15. Add
  860. 16 to windowBits to write a simple gzip header and trailer
  861. around the compressed data instead of a zlib wrapper. The
  862. gzip header will have no file name, no extra data, no comment,
  863. no modification time (set to zero), no header crc, and the
  864. operating system will be set to 255 (unknown).
  865. int memLevel - Amount of memory allocated for internal compression state.
  866. 1 uses minimum memory but is slow and reduces compression
  867. ratio; 9 uses maximum memory for optimal speed. Default value
  868. is 8.
  869. int strategy - Used to tune the compression algorithm. Use the value
  870. Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data
  871. produced by a filter (or predictor), or Z_HUFFMAN_ONLY to
  872. force Huffman encoding only (no string match) */
  873. int ret = deflateInit2(&zs, compressionLevel, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY);
  874. if (ret != Z_OK)
  875. throwGZipException("initialization", ret);
  876. // set the z_stream's input
  877. zs.next_in = (Bytef*)inputBuffer;
  878. zs.avail_in = inputSize;
  879. // Create output memory buffer for compressed data. The zlib documentation states that
  880. // destination buffer size must be at least 0.1% larger than avail_in plus 12 bytes.
  881. const unsigned long outsize = (unsigned long)floorf((float)inputSize * 1.01f) + 12;
  882. Bytef* outbuf = new Bytef[outsize];
  883. do
  884. {
  885. // Store location where next byte should be put in next_out
  886. zs.next_out = outbuf + zs.total_out;
  887. // Calculate the amount of remaining free space in the output buffer
  888. // by subtracting the number of bytes that have been written so far
  889. // from the buffer's total capacity
  890. zs.avail_out = outsize - zs.total_out;
  891. /* deflate() compresses as much data as possible, and stops/returns when
  892. the input buffer becomes empty or the output buffer becomes full. If
  893. deflate() returns Z_OK, it means that there are more bytes left to
  894. compress in the input buffer but the output buffer is full; the output
  895. buffer should be expanded and deflate should be called again (i.e., the
  896. loop should continue to rune). If deflate() returns Z_STREAM_END, the
  897. end of the input stream was reached (i.e.g, all of the data has been
  898. compressed) and the loop should stop. */
  899. ret = deflate(&zs, Z_FINISH);
  900. } while (ret == Z_OK);
  901. if (ret != Z_STREAM_END) // an error occurred that was not EOS
  902. {
  903. // Free data structures that were dynamically created for the stream.
  904. deflateEnd(&zs);
  905. delete[] outbuf;
  906. *outlen = 0;
  907. throwGZipException("compression", ret);
  908. }
  909. // Free data structures that were dynamically created for the stream.
  910. deflateEnd(&zs);
  911. *outlen = zs.total_out;
  912. return (char*) outbuf;
  913. }
  914. void gunzip(const byte* compressed, unsigned int comprLen, StringBuffer& sOutput)
  915. {
  916. if (comprLen == 0)
  917. return;
  918. const int CHUNK_OUT = 16384;
  919. z_stream d_stream; // decompression stream
  920. memset( &d_stream, 0, sizeof(z_stream));
  921. d_stream.next_in = (byte*) compressed;
  922. d_stream.avail_in = comprLen;
  923. int ret = inflateInit2(&d_stream, (15+16));
  924. if (ret != Z_OK)
  925. throwGZipException("initialization", ret);
  926. unsigned int outLen = 0;
  927. do
  928. {
  929. sOutput.ensureCapacity( outLen + CHUNK_OUT );
  930. d_stream.avail_out = CHUNK_OUT; //free space in the output buffer
  931. d_stream.next_out = (byte*)sOutput.str() + outLen;
  932. ret = inflate(&d_stream, Z_NO_FLUSH);
  933. if (ret < Z_OK)
  934. break;
  935. outLen += CHUNK_OUT - d_stream.avail_out;
  936. sOutput.setLength( outLen );
  937. } while (d_stream.avail_out == 0 || ret != Z_STREAM_END);
  938. inflateEnd(&d_stream);
  939. if (ret != Z_STREAM_END)
  940. {
  941. sOutput.clear();
  942. throwGZipException("decompression", ret);
  943. }
  944. }