cryptolib.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2019 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. #include "jutil.hpp"
  14. #include "jexcept.hpp"
  15. #include "digisign.hpp"
  16. #include "ske.hpp"
  17. #include <openssl/pem.h>
  18. #include <openssl/err.h>
  19. #include <openssl/rand.h>
  20. #include <string>
  21. #include <unordered_map>
  22. #include "cryptolib.hpp"
  23. using namespace std;
  24. #define CRYPTOLIB_VERSION "CRYPTOLIB 1.0.00"
  25. using namespace cryptohelper;
  26. static const char * EclDefinition = nullptr;//Definitions specified in lib_cryptolib.ecllib
  27. CRYPTOLIB_API bool getECLPluginDefinition(ECLPluginDefinitionBlock *pb)
  28. {
  29. // Warning: This function may be called without the plugin being loaded fully.
  30. // It should not make any library calls or assume that dependent modules
  31. // have been loaded or that it has been initialized.
  32. //
  33. // Specifically: "The system does not call DllMain for process and thread
  34. // initialization and termination. Also, the system does not load
  35. // additional executable modules that are referenced by the specified module."
  36. if (pb->size != sizeof(ECLPluginDefinitionBlock))
  37. return false;
  38. pb->magicVersion = PLUGIN_VERSION;
  39. pb->version = CRYPTOLIB_VERSION;
  40. pb->moduleName = "lib_cryptolib";
  41. pb->ECL = EclDefinition;
  42. pb->flags = PLUGIN_IMPLICIT_MODULE;
  43. pb->description = "CryptoLib cryptography services library";
  44. return true;
  45. }
  46. namespace nsCryptolib {
  47. IPluginContext * parentCtx = nullptr;
  48. }
  49. using namespace nsCryptolib;
  50. CRYPTOLIB_API void setPluginContext(IPluginContext * _ctx) { parentCtx = _ctx; }
  51. //-------------------------------------------------------------------------------------------------------------------------------------------
  52. // C++ to ECL helpers
  53. //-------------------------------------------------------------------------------------------------------------------------------------------
  54. size32_t addToECLSetOfString(void * set, const char * str)
  55. {
  56. size32_t len = strlen(str);
  57. if (len)
  58. {
  59. memcpy(set, &len, sizeof(len));//copy 4 byte length. String Set memory buffer should already be allocated within the context
  60. memcpy((char *)set + sizeof(len), str, strlen(str));//followed by string
  61. }
  62. return len + sizeof(len);//return length copied to memory buffer
  63. }
  64. void stringArrayToECLSetOfString(const StringArray & arr, void * * set, size32_t * len)
  65. {
  66. //STRING is a variable length string stored as a 4 byte length, followed by the string. A set of strings has
  67. //the strings in this format repeated, and the total size returned in the __lenResult parameter. The __result value should be allocated
  68. //on the heap.
  69. size32_t currLen = 0;
  70. for (aindex_t idx = 0; idx < arr.length(); idx++)
  71. currLen += strlen(arr.item(idx)) + sizeof(size32_t);
  72. void * pSet = CTXMALLOC(parentCtx, currLen);
  73. assertex(set);
  74. *len = currLen;
  75. *set = pSet;
  76. currLen = 0;
  77. for (aindex_t idx = 0; idx < arr.length(); idx++)
  78. currLen += addToECLSetOfString((char*)pSet + currLen, arr.item(idx));
  79. }
  80. //-------------------------------------------------------------------------------------------------------------------------------------------
  81. // CIPHER SYMMETRIC SUPPORT
  82. //-------------------------------------------------------------------------------------------------------------------------------------------
  83. //NB: It should be noted that we count on the cryptohelper library to call OpenSSL_add_all_algorithms() at init time
  84. void my_clAlgorithmsCallback(const OBJ_NAME * _obj, void * _pRes)
  85. {
  86. ((StringArray*)_pRes)->append((const char*)_obj->name);//add this digest to string array
  87. }
  88. //NB: CRYPTOLIB call signatures can be gleaned from the generated workunit CPP file
  89. //Symmetric block/stream digest algorithms
  90. CRYPTOLIB_API void CRYPTOLIB_CALL clInstalledSymmetricCipherAlgorithms(bool & __isAllResult, size32_t & __lenResult, void * & __result)
  91. {
  92. __isAllResult = false;
  93. StringArray algorithms;
  94. OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, my_clAlgorithmsCallback, (void*)&algorithms);
  95. stringArrayToECLSetOfString(algorithms, &__result, &__lenResult);
  96. }
  97. CRYPTOLIB_API void CRYPTOLIB_CALL clSupportedSymmetricCipherAlgorithms(bool & __isAllResult, size32_t & __lenResult, void * & __result)
  98. {
  99. __isAllResult = false;
  100. StringArray algorithms;
  101. algorithms.appendList("aes-256-cbc,aes-192-cbc,aes-128-cbc", ",");//make sure this list matches loadEVP_Cipher()
  102. stringArrayToECLSetOfString(algorithms, &__result, &__lenResult);
  103. }
  104. //-------------------------------------------------------------------------------------------------------------------------------------------
  105. //Helpers to build the DATA buffer returned from clSymmetricEncrypt, and sent to clSymmetricDecrypt
  106. //Buffer is structured as:
  107. // (size32_t)lenIV, IV excluding NULL, (size32_t)LenPlainText excluding NULL, (size32_t)LenCipher, Cipher
  108. static void symmDeserialize(const void * pBuffer, StringBuffer & sbIV, StringBuffer & sbCipher, size32_t * lenPlainText)
  109. {
  110. size32_t len;
  111. const char * finger = (const char *)pBuffer;
  112. memcpy(&len, finger, sizeof(size32_t));//extract IV
  113. finger += sizeof(size32_t);
  114. sbIV.append(len, finger);
  115. finger += len;
  116. memcpy(lenPlainText, finger, sizeof(size32_t));//extract length of plain text
  117. finger += sizeof(size32_t);
  118. memcpy(&len, finger, sizeof(size32_t));//extract cipher
  119. finger += sizeof(size32_t);
  120. sbCipher.append(len, finger);
  121. }
  122. static void symmSerialize(void * & result, size32_t & lenResult, const char * pIV, size32_t lenIV, size32_t lenPlainText, size32_t lenCipherBuff, const void * pCipherBuff)
  123. {
  124. //Allocate return DATA buffer
  125. lenResult = sizeof(size32_t) + lenIV + sizeof(size32_t) + sizeof(size32_t) + lenCipherBuff;
  126. result = CTXMALLOC(parentCtx, lenResult);
  127. //build result DATA buffer in the form:
  128. char * pRes = (char *)result;
  129. memcpy(pRes, &lenIV, sizeof(size32_t));//copy size of IV
  130. pRes += sizeof(size32_t);
  131. memcpy(pRes, pIV, lenIV);//copy the IV
  132. pRes += lenIV;
  133. memcpy(pRes, &lenPlainText, sizeof(size32_t));
  134. pRes += sizeof(size32_t);
  135. memcpy(pRes, &lenCipherBuff, sizeof(size32_t));
  136. pRes += sizeof(size32_t);
  137. memcpy(pRes, pCipherBuff, lenCipherBuff);
  138. }
  139. //-------------------------------------------------------------------------------------------------------------------------------------------
  140. void verifySymmetricAlgorithm(const char * algorithm, size32_t len)
  141. {
  142. if (strieq(algorithm, "aes-128-cbc"))
  143. {
  144. if (len != 16)
  145. throw MakeStringException(-1, "Invalid Key Length %d specified for algorithm %s, try 16", len, algorithm);
  146. }
  147. else if (strieq(algorithm, "aes-192-cbc"))
  148. {
  149. if (len != 24)
  150. throw MakeStringException(-1, "Invalid Key Length %d specified for algorithm %s, try 24", len, algorithm);
  151. }
  152. else if (strieq(algorithm, "aes-256-cbc"))
  153. {
  154. if (len != 32)
  155. throw MakeStringException(-1, "Invalid Key Length %d specified for algorithm %s, try 32", len, algorithm);
  156. }
  157. else
  158. throw MakeStringException(-1, "Unsupported symmetric algorithm (%s) specified", algorithm);
  159. }
  160. CRYPTOLIB_API void CRYPTOLIB_CALL clSymmetricEncrypt(size32_t & __lenResult, void * & __result,
  161. const char * algorithm,
  162. const char * key,
  163. size32_t lenInputdata,const void * inputdata)
  164. {
  165. verifySymmetricAlgorithm(algorithm, strlen(key) );
  166. //Create a unique Initialization Vector
  167. unsigned char iv[EVP_MAX_IV_LENGTH];
  168. RAND_bytes(iv, EVP_MAX_IV_LENGTH);
  169. //temporary buffer for result
  170. MemoryBuffer out;
  171. aesEncrypt(out, lenInputdata, inputdata, strlen(key), key, (const char *)iv);
  172. //build result DATA buffer in the form:
  173. // (size32_t)EVP_MAX_IV_LENGTH, IV, (size32_t)LenPlainText excluding NULL, (size32_t)LenCipher, Cipher
  174. symmSerialize(__result, __lenResult, (const char *)iv, sizeof(iv), lenInputdata, out.length(), (const void *)out.bufferBase());
  175. }
  176. CRYPTOLIB_API void CRYPTOLIB_CALL clSymmetricDecrypt(size32_t & __lenResult,void * & __result,
  177. const char * algorithm,
  178. const char * key,
  179. size32_t lenEncrypteddata,const void * encrypteddata)
  180. {
  181. verifySymmetricAlgorithm(algorithm, strlen(key));
  182. //Decompose DATA buffer
  183. StringBuffer sbIV;
  184. StringBuffer sbCipher;
  185. size32_t lenPlainText;
  186. symmDeserialize(encrypteddata, sbIV, sbCipher, &lenPlainText);
  187. __result = (char *)CTXMALLOC(parentCtx, lenPlainText);
  188. __lenResult = lenPlainText;
  189. MemoryBuffer decrypted;
  190. size32_t len = aesDecrypt(decrypted, sbCipher.length(), sbCipher.str(), strlen(key), key, sbIV.str());
  191. memcpy(__result, decrypted.toByteArray(), __lenResult);
  192. }
  193. //-------------------------------------------------------------------------------------------------------------------------------------------
  194. // HASH SUPPORT
  195. //-------------------------------------------------------------------------------------------------------------------------------------------
  196. CRYPTOLIB_API void CRYPTOLIB_CALL clInstalledHashAlgorithms(bool & __isAllResult, size32_t & __lenResult, void * & __result)
  197. {
  198. __isAllResult = false;
  199. StringArray algorithms;
  200. OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, my_clAlgorithmsCallback, (void*)&algorithms);
  201. stringArrayToECLSetOfString(algorithms, &__result, &__lenResult);
  202. }
  203. CRYPTOLIB_API void CRYPTOLIB_CALL clSupportedHashAlgorithms(bool & __isAllResult, size32_t & __lenResult, void * & __result)
  204. {
  205. __isAllResult = false;
  206. StringArray algorithms;
  207. algorithms.appendList("SHA1,SHA224,SHA256,SHA384,SHA512", ",");//make sure these match algorithms in clHash()
  208. stringArrayToECLSetOfString(algorithms, &__result, &__lenResult);
  209. }
  210. void throwHashError(const char * str)
  211. {
  212. unsigned long err = ERR_get_error();
  213. char errStr[1024];
  214. ERR_error_string_n(err, errStr, sizeof(errStr));
  215. throw MakeStringException(-1, "%s : ERROR %ld (0x%lX) : %s", str, err, err, errStr);
  216. }
  217. CRYPTOLIB_API void CRYPTOLIB_CALL clHash(size32_t & __lenResult, void * & __result,
  218. const char * algorithm,
  219. size32_t lenInputData, const void * inputData)
  220. {
  221. //Make sure each algorithm is included in clHashAlgorithms()
  222. if (strieq("SHA1", algorithm))
  223. {
  224. SHA_CTX context;
  225. if (!SHA1_Init(&context))
  226. throwHashError("OpenSSL ERROR calling SHA1_Init");
  227. if (!SHA1_Update(&context, (unsigned char*)inputData, lenInputData))
  228. throwHashError("OpenSSL ERROR calling SHA1_Update");
  229. __lenResult = SHA_DIGEST_LENGTH;//20 bytes
  230. __result = CTXMALLOC(parentCtx, __lenResult);
  231. if (!SHA1_Final((unsigned char *)__result, &context))
  232. {
  233. free(__result);
  234. throwHashError("OpenSSL ERROR calling SHA1_Final");
  235. }
  236. }
  237. else if (strieq("SHA224", algorithm))
  238. {
  239. SHA256_CTX context;//SHA224 uses the SHA256 context
  240. if (!SHA224_Init(&context))
  241. throwHashError("OpenSSL ERROR calling SHA224_Init");
  242. if (!SHA224_Update(&context, (unsigned char*)inputData, lenInputData))
  243. throwHashError("OpenSSL ERROR calling SHA224_Update");
  244. __lenResult = SHA224_DIGEST_LENGTH;//28 bytes
  245. __result = CTXMALLOC(parentCtx, __lenResult);
  246. if (!SHA224_Final((unsigned char *)__result, &context))
  247. {
  248. free(__result);
  249. throwHashError("OpenSSL ERROR calling SHA224_Final");
  250. }
  251. }
  252. else if (strieq("SHA256", algorithm))
  253. {
  254. SHA256_CTX context;
  255. if (!SHA256_Init(&context))
  256. throwHashError("OpenSSL ERROR calling SHA256_Init");
  257. if (!SHA256_Update(&context, (unsigned char*)inputData, lenInputData))
  258. throwHashError("OpenSSL ERROR calling SHA256_Update");
  259. __lenResult = SHA256_DIGEST_LENGTH;//32 bytes
  260. __result = CTXMALLOC(parentCtx, __lenResult);
  261. if (!SHA256_Final((unsigned char *)__result, &context))
  262. {
  263. free(__result);
  264. throwHashError("OpenSSL ERROR calling SHA256_Final");
  265. }
  266. }
  267. else if (strieq("SHA384", algorithm))
  268. {
  269. SHA512_CTX context;//SHA384 uses the SHA512 context
  270. if (!SHA384_Init(&context))
  271. throwHashError("OpenSSL ERROR calling SHA384_Init");
  272. if (!SHA384_Update(&context, (unsigned char*)inputData, lenInputData))
  273. throwHashError("OpenSSL ERROR calling SHA384_Update");
  274. __lenResult = SHA384_DIGEST_LENGTH;//48 bytes
  275. __result = CTXMALLOC(parentCtx, __lenResult);
  276. if (!SHA384_Final((unsigned char *)__result, &context))
  277. {
  278. free(__result);
  279. throwHashError("OpenSSL ERROR calling SHA384_Final");
  280. }
  281. }
  282. else if (strieq("SHA512", algorithm))
  283. {
  284. SHA512_CTX context;
  285. if (!SHA512_Init(&context))
  286. throwHashError("OpenSSL ERROR calling SHA512_Init");
  287. if (!SHA512_Update(&context, (unsigned char*)inputData, lenInputData))
  288. throwHashError("OpenSSL ERROR calling SHA512_Update");
  289. __lenResult = SHA512_DIGEST_LENGTH;//64 bytes
  290. __result = CTXMALLOC(parentCtx, __lenResult);
  291. if (!SHA512_Final((unsigned char *)__result, &context))
  292. {
  293. free(__result);
  294. throwHashError("OpenSSL ERROR calling SHA512_Final");
  295. }
  296. }
  297. else
  298. {
  299. throw MakeStringException(-1, "Unsupported hash algorithm '%s' specified", algorithm);
  300. }
  301. }
  302. //-------------------------------------------------------------------------------------------------------------------------------------------
  303. // PUBLIC KEY SUPPORT
  304. //-------------------------------------------------------------------------------------------------------------------------------------------
  305. CRYPTOLIB_API void CRYPTOLIB_CALL clInstalledPublicKeyAlgorithms(bool & __isAllResult, size32_t & __lenResult, void * & __result)
  306. {
  307. __isAllResult = false;
  308. StringArray algorithms;
  309. OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_PKEY_METH, my_clAlgorithmsCallback, (void*)&algorithms);
  310. stringArrayToECLSetOfString(algorithms, &__result, &__lenResult);
  311. }
  312. CRYPTOLIB_API void CRYPTOLIB_CALL clSupportedPublicKeyAlgorithms(bool & __isAllResult, size32_t & __lenResult, void * & __result)
  313. {
  314. __isAllResult = false;
  315. StringArray algorithms;
  316. algorithms.appendList("SHA256", ",");
  317. stringArrayToECLSetOfString(algorithms, &__result, &__lenResult);
  318. }
  319. //signature helper function
  320. void doPKISign(size32_t & __lenResult, void * & __result,
  321. IDigitalSignatureManager * pDSM,
  322. size32_t lenInputdata, const void * inputdata)
  323. {
  324. StringBuffer sbSig;
  325. if (pDSM->digiSign(sbSig, lenInputdata, inputdata))
  326. {
  327. __result = CTXMALLOC(parentCtx, sbSig.length());
  328. __lenResult = sbSig.length();
  329. memcpy(__result, sbSig.str(), __lenResult);
  330. }
  331. else
  332. {
  333. throw MakeStringException(-1, "Unable to create Digital Signature");
  334. }
  335. }
  336. void verifyPKIAlgorithm(const char * pkAlgorithm)
  337. {
  338. if (!strieq(pkAlgorithm, "SHA256"))
  339. throw MakeStringException(-1, "Unsupported PKI algorithm (%s) specified", pkAlgorithm);
  340. }
  341. //-----------------------------------------------------------------
  342. // Simple cache for instances of Digital Signature Managers
  343. //-----------------------------------------------------------------
  344. class CDSMCache
  345. {
  346. private:
  347. CriticalSection csDSMCache;//guards modifications to the cache map
  348. typedef std::unordered_map<string, Owned<IDigitalSignatureManager>> DSMCache;
  349. DSMCache dsmCache;
  350. public:
  351. IDigitalSignatureManager * getInstance(const char * algo, const char * pubKeyFS, const char * pubKeyBuff, const char * privKeyFS, const char * privKeyBuff, const char * passphrase)
  352. {
  353. VStringBuffer searchKey("%s_%s_%s_%s_%s_%s", algo, isEmptyString(pubKeyFS) ? "" : pubKeyFS, isEmptyString(pubKeyBuff) ? "" : pubKeyBuff,
  354. isEmptyString(privKeyFS) ? "" : privKeyFS, isEmptyString(privKeyBuff) ? "" : privKeyBuff, passphrase);
  355. CriticalBlock block(csDSMCache);
  356. DSMCache::iterator it = dsmCache.find(searchKey.str());
  357. IDigitalSignatureManager * ret = nullptr;
  358. if (it != dsmCache.end())//exists in cache
  359. {
  360. ret = (*it).second;
  361. }
  362. else
  363. {
  364. IDigitalSignatureManager * pDSM = nullptr;
  365. if (!isEmptyString(pubKeyFS) && !isEmptyString(privKeyFS))
  366. pDSM = createDigitalSignatureManagerInstanceFromFiles(pubKeyFS, privKeyFS, passphrase);
  367. else
  368. pDSM = createDigitalSignatureManagerInstanceFromKeys(pubKeyBuff, privKeyBuff, passphrase);
  369. dsmCache.insert(pair<string, IDigitalSignatureManager*>(searchKey.str(), pDSM));
  370. ret = pDSM;
  371. }
  372. return LINK(ret);
  373. }
  374. };
  375. static CDSMCache g_DSMCache;
  376. //Sign given data using private key
  377. CRYPTOLIB_API void CRYPTOLIB_CALL clPKISign(size32_t & __lenResult,void * & __result,
  378. const char * pkalgorithm,
  379. const char * privatekeyfile,
  380. const char * passphrase,
  381. size32_t lenInputdata,const void * inputdata)
  382. {
  383. verifyPKIAlgorithm(pkalgorithm);//TODO extend cryptohelper to support more algorithms
  384. Owned<IDigitalSignatureManager> pDSM = g_DSMCache.getInstance(pkalgorithm, nullptr, nullptr, privatekeyfile, nullptr, passphrase);
  385. if (pDSM)
  386. {
  387. doPKISign(__lenResult, __result, pDSM, lenInputdata, inputdata);
  388. }
  389. else
  390. {
  391. throw MakeStringException(-1, "Unable to create Digital Signature Manager");
  392. }
  393. }
  394. CRYPTOLIB_API void CRYPTOLIB_CALL clPKISignBuff(size32_t & __lenResult, void * & __result,
  395. const char * pkalgorithm,
  396. const char * privatekeybuff,
  397. const char * passphrase,
  398. size32_t lenInputdata, const void * inputdata)
  399. {
  400. verifyPKIAlgorithm(pkalgorithm);
  401. Owned<IDigitalSignatureManager> pDSM = g_DSMCache.getInstance(pkalgorithm, nullptr, nullptr, nullptr, privatekeybuff, passphrase);
  402. if (pDSM)
  403. {
  404. doPKISign(__lenResult, __result, pDSM, lenInputdata, inputdata);
  405. }
  406. else
  407. {
  408. throw MakeStringException(-1, "Unable to create Digital Signature Manager");
  409. }
  410. }
  411. CRYPTOLIB_API bool CRYPTOLIB_CALL clPKIVerifySignature(const char * pkalgorithm,
  412. const char * publickeyfile,
  413. const char * passphrase,
  414. size32_t lenSignature,const void * signature,
  415. size32_t lenSigneddata,const void * signeddata)
  416. {
  417. verifyPKIAlgorithm(pkalgorithm);
  418. Owned<IDigitalSignatureManager> pDSM = g_DSMCache.getInstance(pkalgorithm, publickeyfile, nullptr, nullptr, nullptr, passphrase);
  419. if (pDSM)
  420. {
  421. StringBuffer sbSig(lenSignature, (const char *)signature);
  422. bool rc = pDSM->digiVerify(sbSig.str(), lenSigneddata, signeddata);
  423. return rc;
  424. }
  425. else
  426. {
  427. throw MakeStringException(-1, "Unable to create Digital Signature Manager");
  428. }
  429. }
  430. CRYPTOLIB_API bool CRYPTOLIB_CALL clPKIVerifySignatureBuff(const char * pkalgorithm,
  431. const char * publicKeyBuff,
  432. const char * passphrase,
  433. size32_t lenSignature, const void * signature,
  434. size32_t lenSigneddata, const void * signeddata)
  435. {
  436. verifyPKIAlgorithm(pkalgorithm);
  437. Owned<IDigitalSignatureManager> pDSM = g_DSMCache.getInstance(pkalgorithm, nullptr, publicKeyBuff, nullptr, nullptr, passphrase);
  438. if (pDSM)
  439. {
  440. StringBuffer sbSig(lenSignature, (const char *)signature);
  441. bool rc = pDSM->digiVerify(sbSig.str(), lenSigneddata, signeddata);
  442. return rc;
  443. }
  444. else
  445. {
  446. throw MakeStringException(-1, "Unable to create Digital Signature Manager");
  447. }
  448. }
  449. //------------------------------------
  450. //Encryption helper
  451. //------------------------------------
  452. static void doPKIEncrypt(size32_t & __lenResult,void * & __result,
  453. CLoadedKey * publicKey,
  454. size32_t lenInputdata,const void * inputdata)
  455. {
  456. MemoryBuffer pkeMb;
  457. __lenResult = publicKeyEncrypt(pkeMb, lenInputdata, inputdata, *publicKey);
  458. if (__lenResult)
  459. {
  460. __result = CTXMALLOC(parentCtx, __lenResult);
  461. memcpy(__result, pkeMb.bytes(), __lenResult);
  462. }
  463. }
  464. //------------------------------------
  465. //Decryption helper
  466. //------------------------------------
  467. static void doPKIDecrypt(size32_t & __lenResult,void * & __result,
  468. CLoadedKey * privateKey,
  469. size32_t lenInputdata,const void * inputdata)
  470. {
  471. MemoryBuffer pkeMb;
  472. __lenResult = privateKeyDecrypt(pkeMb, lenInputdata, inputdata, *privateKey);
  473. if (__lenResult)
  474. {
  475. __result = CTXMALLOC(parentCtx, __lenResult);
  476. memcpy(__result, pkeMb.bytes(), __lenResult);
  477. }
  478. }
  479. //encryption functions that take filespecs of key files
  480. CRYPTOLIB_API void CRYPTOLIB_CALL clPKIEncrypt(size32_t & __lenResult,void * & __result,
  481. const char * pkalgorithm,
  482. const char * publickeyfile,
  483. const char * passphrase,
  484. size32_t lenInputdata,const void * inputdata)
  485. {
  486. verifyPKIAlgorithm(pkalgorithm);
  487. Owned<CLoadedKey> publicKey = loadPublicKeyFromFile(publickeyfile, passphrase);
  488. doPKIEncrypt(__lenResult, __result, publicKey, lenInputdata, inputdata);
  489. }
  490. CRYPTOLIB_API void CRYPTOLIB_CALL clPKIDecrypt(size32_t & __lenResult,void * & __result,
  491. const char * pkalgorithm,
  492. const char * privatekeyfile,
  493. const char * passphrase,
  494. size32_t lenEncrypteddata,const void * encrypteddata)
  495. {
  496. verifyPKIAlgorithm(pkalgorithm);
  497. Owned<CLoadedKey> privateKey = loadPrivateKeyFromFile(privatekeyfile, passphrase);
  498. doPKIDecrypt(__lenResult, __result, privateKey, lenEncrypteddata, encrypteddata);
  499. }
  500. //encryption functions that take keys in a buffer
  501. CRYPTOLIB_API void CRYPTOLIB_CALL clPKIEncryptBuff(size32_t & __lenResult,void * & __result,
  502. const char * pkalgorithm,
  503. const char * publickeybuff,
  504. const char * passphrase,
  505. size32_t lenInputdata,const void * inputdata)
  506. {
  507. verifyPKIAlgorithm(pkalgorithm);
  508. Owned<CLoadedKey> publicKey = loadPublicKeyFromMemory(publickeybuff, passphrase);
  509. doPKIEncrypt(__lenResult, __result, publicKey, lenInputdata, inputdata);
  510. }
  511. CRYPTOLIB_API void CRYPTOLIB_CALL clPKIDecryptBuff(size32_t & __lenResult,void * & __result,
  512. const char * pkalgorithm,
  513. const char * privatekeybuff,
  514. const char * passphrase,
  515. size32_t lenEncrypteddata,const void * encrypteddata)
  516. {
  517. verifyPKIAlgorithm(pkalgorithm);
  518. Owned<CLoadedKey> privateKey = loadPrivateKeyFromMemory(privatekeybuff, passphrase);
  519. doPKIDecrypt(__lenResult, __result, privateKey, lenEncrypteddata, encrypteddata);
  520. }