You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

lua_rsa.c 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867
  1. /*-
  2. * Copyright 2016 Vsevolod Stakhov
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /**
  17. * @file lua_rsa.c
  18. * This module exports routines to load rsa keys, check inline or external
  19. * rsa signatures. It assumes sha256 based signatures.
  20. */
  21. #include "lua_common.h"
  22. #include "unix-std.h"
  23. #include <openssl/err.h>
  24. #include <openssl/pem.h>
  25. #include <openssl/sha.h>
  26. #include <openssl/rsa.h>
  27. LUA_FUNCTION_DEF(rsa_pubkey, load);
  28. LUA_FUNCTION_DEF(rsa_pubkey, create);
  29. LUA_FUNCTION_DEF(rsa_pubkey, gc);
  30. LUA_FUNCTION_DEF(rsa_pubkey, tostring);
  31. LUA_FUNCTION_DEF(rsa_privkey, load_file);
  32. LUA_FUNCTION_DEF(rsa_privkey, load_pem);
  33. LUA_FUNCTION_DEF(rsa_privkey, load_raw);
  34. LUA_FUNCTION_DEF(rsa_privkey, load_base64);
  35. LUA_FUNCTION_DEF(rsa_privkey, create);
  36. LUA_FUNCTION_DEF(rsa_privkey, gc);
  37. LUA_FUNCTION_DEF(rsa_privkey, save);
  38. LUA_FUNCTION_DEF(rsa_signature, create);
  39. LUA_FUNCTION_DEF(rsa_signature, load);
  40. LUA_FUNCTION_DEF(rsa_signature, save);
  41. LUA_FUNCTION_DEF(rsa_signature, base64);
  42. LUA_FUNCTION_DEF(rsa_signature, gc);
  43. LUA_FUNCTION_DEF(rsa, verify_memory);
  44. LUA_FUNCTION_DEF(rsa, sign_memory);
  45. LUA_FUNCTION_DEF(rsa, keypair);
  46. static const struct luaL_reg rsalib_f[] = {
  47. LUA_INTERFACE_DEF(rsa, verify_memory),
  48. LUA_INTERFACE_DEF(rsa, sign_memory),
  49. LUA_INTERFACE_DEF(rsa, keypair),
  50. {NULL, NULL}};
  51. static const struct luaL_reg rsapubkeylib_f[] = {
  52. LUA_INTERFACE_DEF(rsa_pubkey, load),
  53. LUA_INTERFACE_DEF(rsa_pubkey, create),
  54. {NULL, NULL}};
  55. static const struct luaL_reg rsapubkeylib_m[] = {
  56. {"__tostring", lua_rsa_pubkey_tostring},
  57. {"__gc", lua_rsa_pubkey_gc},
  58. {NULL, NULL}};
  59. static const struct luaL_reg rsaprivkeylib_f[] = {
  60. LUA_INTERFACE_DEF(rsa_privkey, load_file),
  61. LUA_INTERFACE_DEF(rsa_privkey, load_pem),
  62. LUA_INTERFACE_DEF(rsa_privkey, load_raw),
  63. LUA_INTERFACE_DEF(rsa_privkey, load_base64),
  64. LUA_INTERFACE_DEF(rsa_privkey, create),
  65. {NULL, NULL}};
  66. static const struct luaL_reg rsaprivkeylib_m[] = {
  67. {"__tostring", rspamd_lua_class_tostring},
  68. {"__gc", lua_rsa_privkey_gc},
  69. LUA_INTERFACE_DEF(rsa_privkey, save),
  70. {NULL, NULL}};
  71. static const struct luaL_reg rsasignlib_f[] = {
  72. LUA_INTERFACE_DEF(rsa_signature, load),
  73. LUA_INTERFACE_DEF(rsa_signature, create),
  74. {NULL, NULL}};
  75. static const struct luaL_reg rsasignlib_m[] = {
  76. LUA_INTERFACE_DEF(rsa_signature, save),
  77. LUA_INTERFACE_DEF(rsa_signature, base64),
  78. {"__tostring", rspamd_lua_class_tostring},
  79. {"__gc", lua_rsa_signature_gc},
  80. {NULL, NULL}};
  81. static RSA *
  82. lua_check_rsa_pubkey(lua_State *L, int pos)
  83. {
  84. void *ud = rspamd_lua_check_udata(L, pos, rspamd_rsa_pubkey_classname);
  85. luaL_argcheck(L, ud != NULL, 1, "'rsa_pubkey' expected");
  86. return ud ? *((RSA **) ud) : NULL;
  87. }
  88. static RSA *
  89. lua_check_rsa_privkey(lua_State *L, int pos)
  90. {
  91. void *ud = rspamd_lua_check_udata(L, pos, rspamd_rsa_privkey_classname);
  92. luaL_argcheck(L, ud != NULL, 1, "'rsa_privkey' expected");
  93. return ud ? *((RSA **) ud) : NULL;
  94. }
  95. static rspamd_fstring_t *
  96. lua_check_rsa_sign(lua_State *L, int pos)
  97. {
  98. void *ud = rspamd_lua_check_udata(L, pos, rspamd_rsa_signature_classname);
  99. luaL_argcheck(L, ud != NULL, 1, "'rsa_signature' expected");
  100. return ud ? *((rspamd_fstring_t **) ud) : NULL;
  101. }
  102. static int
  103. lua_rsa_pubkey_load(lua_State *L)
  104. {
  105. RSA *rsa = NULL, **prsa;
  106. const char *filename;
  107. FILE *f;
  108. filename = luaL_checkstring(L, 1);
  109. if (filename != NULL) {
  110. f = fopen(filename, "r");
  111. if (f == NULL) {
  112. msg_err("cannot open pubkey from file: %s, %s",
  113. filename,
  114. strerror(errno));
  115. lua_pushnil(L);
  116. }
  117. else {
  118. if (!PEM_read_RSA_PUBKEY(f, &rsa, NULL, NULL)) {
  119. msg_err("cannot open pubkey from file: %s, %s", filename,
  120. ERR_error_string(ERR_get_error(), NULL));
  121. lua_pushnil(L);
  122. }
  123. else {
  124. prsa = lua_newuserdata(L, sizeof(RSA *));
  125. rspamd_lua_setclass(L, rspamd_rsa_pubkey_classname, -1);
  126. *prsa = rsa;
  127. }
  128. fclose(f);
  129. }
  130. }
  131. else {
  132. lua_pushnil(L);
  133. }
  134. return 1;
  135. }
  136. static int
  137. lua_rsa_privkey_save(lua_State *L)
  138. {
  139. const char *filename;
  140. const char *type = "pem";
  141. FILE *f;
  142. int ret;
  143. RSA *rsa = lua_check_rsa_privkey(L, 1);
  144. filename = luaL_checkstring(L, 2);
  145. if (lua_gettop(L) > 2) {
  146. type = luaL_checkstring(L, 3);
  147. }
  148. if (rsa != NULL && filename != NULL) {
  149. if (strcmp(filename, "-") == 0) {
  150. f = stdout;
  151. }
  152. else {
  153. f = fopen(filename, "wb");
  154. }
  155. if (f == NULL) {
  156. msg_err("cannot save privkey to file: %s, %s",
  157. filename,
  158. strerror(errno));
  159. lua_pushboolean(L, FALSE);
  160. }
  161. else {
  162. if (f != stdout) {
  163. /* Set secure permissions for the private key file */
  164. chmod(filename, S_IRUSR | S_IWUSR);
  165. }
  166. if (strcmp(type, "der") == 0) {
  167. ret = i2d_RSAPrivateKey_fp(f, rsa);
  168. }
  169. else {
  170. ret = PEM_write_RSAPrivateKey(f, rsa, NULL, NULL, 0, NULL, NULL);
  171. }
  172. if (!ret) {
  173. msg_err("cannot save privkey to file: %s, %s", filename,
  174. ERR_error_string(ERR_get_error(), NULL));
  175. lua_pushboolean(L, FALSE);
  176. }
  177. else {
  178. lua_pushboolean(L, TRUE);
  179. }
  180. if (f != stdout) {
  181. fclose(f);
  182. }
  183. else {
  184. fflush(f);
  185. }
  186. }
  187. }
  188. else {
  189. lua_pushboolean(L, FALSE);
  190. }
  191. return 1;
  192. }
  193. static int
  194. lua_rsa_pubkey_create(lua_State *L)
  195. {
  196. RSA *rsa = NULL, **prsa;
  197. const char *buf;
  198. BIO *bp;
  199. buf = luaL_checkstring(L, 1);
  200. if (buf != NULL) {
  201. bp = BIO_new_mem_buf((void *) buf, -1);
  202. if (!PEM_read_bio_RSA_PUBKEY(bp, &rsa, NULL, NULL)) {
  203. msg_err("cannot parse pubkey: %s",
  204. ERR_error_string(ERR_get_error(), NULL));
  205. lua_pushnil(L);
  206. }
  207. else {
  208. prsa = lua_newuserdata(L, sizeof(RSA *));
  209. rspamd_lua_setclass(L, rspamd_rsa_pubkey_classname, -1);
  210. *prsa = rsa;
  211. }
  212. BIO_free(bp);
  213. }
  214. else {
  215. lua_pushnil(L);
  216. }
  217. return 1;
  218. }
  219. static int
  220. lua_rsa_pubkey_gc(lua_State *L)
  221. {
  222. RSA *rsa = lua_check_rsa_pubkey(L, 1);
  223. if (rsa != NULL) {
  224. RSA_free(rsa);
  225. }
  226. return 0;
  227. }
  228. static int
  229. lua_rsa_pubkey_tostring(lua_State *L)
  230. {
  231. RSA *rsa = lua_check_rsa_pubkey(L, 1);
  232. if (rsa != NULL) {
  233. BIO *pubout = BIO_new(BIO_s_mem());
  234. const char *pubdata;
  235. gsize publen;
  236. int rc = i2d_RSA_PUBKEY_bio(pubout, rsa);
  237. if (rc != 1) {
  238. BIO_free(pubout);
  239. return luaL_error(L, "i2d_RSA_PUBKEY_bio failed");
  240. }
  241. publen = BIO_get_mem_data(pubout, &pubdata);
  242. lua_pushlstring(L, pubdata, publen);
  243. BIO_free(pubout);
  244. }
  245. else {
  246. return luaL_error(L, "invalid arguments");
  247. }
  248. return 1;
  249. }
  250. static int
  251. lua_rsa_privkey_load_file(lua_State *L)
  252. {
  253. RSA *rsa = NULL, **prsa;
  254. const char *filename;
  255. FILE *f;
  256. filename = luaL_checkstring(L, 1);
  257. if (filename != NULL) {
  258. f = fopen(filename, "r");
  259. if (f == NULL) {
  260. msg_err("cannot open private key from file: %s, %s",
  261. filename,
  262. strerror(errno));
  263. lua_pushnil(L);
  264. }
  265. else {
  266. if (!PEM_read_RSAPrivateKey(f, &rsa, NULL, NULL)) {
  267. msg_err("cannot open private key from file: %s, %s", filename,
  268. ERR_error_string(ERR_get_error(), NULL));
  269. lua_pushnil(L);
  270. }
  271. else {
  272. prsa = lua_newuserdata(L, sizeof(RSA *));
  273. rspamd_lua_setclass(L, rspamd_rsa_privkey_classname, -1);
  274. *prsa = rsa;
  275. }
  276. fclose(f);
  277. }
  278. }
  279. else {
  280. lua_pushnil(L);
  281. }
  282. return 1;
  283. }
  284. static int
  285. lua_rsa_privkey_load_pem(lua_State *L)
  286. {
  287. RSA *rsa = NULL, **prsa;
  288. BIO *b;
  289. struct rspamd_lua_text *t;
  290. const char *data;
  291. gsize len;
  292. if (lua_isuserdata(L, 1)) {
  293. t = lua_check_text(L, 1);
  294. if (!t) {
  295. return luaL_error(L, "invalid arguments");
  296. }
  297. data = t->start;
  298. len = t->len;
  299. }
  300. else {
  301. data = luaL_checklstring(L, 1, &len);
  302. }
  303. if (data != NULL) {
  304. b = BIO_new_mem_buf(data, len);
  305. if (!PEM_read_bio_RSAPrivateKey(b, &rsa, NULL, NULL)) {
  306. msg_err("cannot open private key from data, %s",
  307. ERR_error_string(ERR_get_error(), NULL));
  308. lua_pushnil(L);
  309. }
  310. else {
  311. prsa = lua_newuserdata(L, sizeof(RSA *));
  312. rspamd_lua_setclass(L, rspamd_rsa_privkey_classname, -1);
  313. *prsa = rsa;
  314. }
  315. BIO_free(b);
  316. }
  317. else {
  318. return luaL_error(L, "invalid arguments");
  319. }
  320. return 1;
  321. }
  322. static int
  323. lua_rsa_privkey_load_raw(lua_State *L)
  324. {
  325. RSA *rsa = NULL, **prsa;
  326. BIO *b;
  327. struct rspamd_lua_text *t;
  328. const char *data;
  329. gsize len;
  330. if (lua_isuserdata(L, 1)) {
  331. t = lua_check_text(L, 1);
  332. if (!t) {
  333. return luaL_error(L, "invalid arguments");
  334. }
  335. data = t->start;
  336. len = t->len;
  337. }
  338. else {
  339. data = luaL_checklstring(L, 1, &len);
  340. }
  341. if (data != NULL) {
  342. b = BIO_new_mem_buf(data, len);
  343. rsa = d2i_RSAPrivateKey_bio(b, NULL);
  344. if (rsa == NULL) {
  345. msg_err("cannot open private key from data, %s",
  346. ERR_error_string(ERR_get_error(), NULL));
  347. lua_pushnil(L);
  348. }
  349. else {
  350. prsa = lua_newuserdata(L, sizeof(RSA *));
  351. rspamd_lua_setclass(L, rspamd_rsa_privkey_classname, -1);
  352. *prsa = rsa;
  353. }
  354. BIO_free(b);
  355. }
  356. else {
  357. return luaL_error(L, "invalid arguments");
  358. }
  359. return 1;
  360. }
  361. static int
  362. lua_rsa_privkey_load_base64(lua_State *L)
  363. {
  364. RSA *rsa = NULL, **prsa;
  365. BIO *b;
  366. EVP_PKEY *evp = NULL;
  367. struct rspamd_lua_text *t;
  368. const char *data;
  369. unsigned char *decoded;
  370. gsize len, dec_len;
  371. if (lua_isuserdata(L, 1)) {
  372. t = lua_check_text(L, 1);
  373. if (!t) {
  374. return luaL_error(L, "invalid arguments");
  375. }
  376. data = t->start;
  377. len = t->len;
  378. }
  379. else {
  380. data = luaL_checklstring(L, 1, &len);
  381. }
  382. if (data != NULL) {
  383. decoded = g_malloc(len);
  384. if (!rspamd_cryptobox_base64_decode(data, len, decoded, &dec_len)) {
  385. g_free(decoded);
  386. return luaL_error(L, "invalid base64 encoding");
  387. }
  388. b = BIO_new_mem_buf(decoded, dec_len);
  389. if (d2i_PrivateKey_bio(b, &evp) != NULL) {
  390. rsa = EVP_PKEY_get1_RSA(evp);
  391. if (rsa == NULL) {
  392. msg_err("cannot open RSA private key from data, %s",
  393. ERR_error_string(ERR_get_error(), NULL));
  394. lua_pushnil(L);
  395. }
  396. else {
  397. prsa = lua_newuserdata(L, sizeof(RSA *));
  398. rspamd_lua_setclass(L, rspamd_rsa_privkey_classname, -1);
  399. *prsa = rsa;
  400. }
  401. EVP_PKEY_free(evp);
  402. }
  403. else {
  404. msg_err("cannot open EVP private key from data, %s",
  405. ERR_error_string(ERR_get_error(), NULL));
  406. lua_pushnil(L);
  407. }
  408. BIO_free(b);
  409. g_free(decoded);
  410. }
  411. else {
  412. return luaL_error(L, "invalid arguments");
  413. }
  414. return 1;
  415. }
  416. static int
  417. lua_rsa_privkey_create(lua_State *L)
  418. {
  419. RSA *rsa = NULL, **prsa;
  420. const char *buf;
  421. BIO *bp;
  422. buf = luaL_checkstring(L, 1);
  423. if (buf != NULL) {
  424. bp = BIO_new_mem_buf((void *) buf, -1);
  425. if (!PEM_read_bio_RSAPrivateKey(bp, &rsa, NULL, NULL)) {
  426. msg_err("cannot parse private key: %s",
  427. ERR_error_string(ERR_get_error(), NULL));
  428. lua_pushnil(L);
  429. }
  430. else {
  431. prsa = lua_newuserdata(L, sizeof(RSA *));
  432. rspamd_lua_setclass(L, rspamd_rsa_privkey_classname, -1);
  433. *prsa = rsa;
  434. }
  435. BIO_free(bp);
  436. }
  437. else {
  438. lua_pushnil(L);
  439. }
  440. return 1;
  441. }
  442. static int
  443. lua_rsa_privkey_gc(lua_State *L)
  444. {
  445. RSA *rsa = lua_check_rsa_privkey(L, 1);
  446. if (rsa != NULL) {
  447. RSA_free(rsa);
  448. }
  449. return 0;
  450. }
  451. static int
  452. lua_rsa_signature_load(lua_State *L)
  453. {
  454. rspamd_fstring_t *sig, **psig;
  455. const char *filename;
  456. gpointer data;
  457. int fd;
  458. struct stat st;
  459. filename = luaL_checkstring(L, 1);
  460. if (filename != NULL) {
  461. fd = open(filename, O_RDONLY);
  462. if (fd == -1) {
  463. msg_err("cannot open signature file: %s, %s", filename,
  464. strerror(errno));
  465. lua_pushnil(L);
  466. }
  467. else {
  468. if (fstat(fd, &st) == -1 ||
  469. (data =
  470. mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) {
  471. msg_err("cannot mmap file %s: %s", filename, strerror(errno));
  472. lua_pushnil(L);
  473. }
  474. else {
  475. sig = rspamd_fstring_new_init(data, st.st_size);
  476. psig = lua_newuserdata(L, sizeof(rspamd_fstring_t *));
  477. rspamd_lua_setclass(L, rspamd_rsa_signature_classname, -1);
  478. *psig = sig;
  479. munmap(data, st.st_size);
  480. }
  481. close(fd);
  482. }
  483. }
  484. else {
  485. lua_pushnil(L);
  486. }
  487. return 1;
  488. }
  489. static int
  490. lua_rsa_signature_save(lua_State *L)
  491. {
  492. rspamd_fstring_t *sig;
  493. int fd, flags;
  494. const char *filename;
  495. gboolean forced = FALSE, res = TRUE;
  496. sig = lua_check_rsa_sign(L, 1);
  497. filename = luaL_checkstring(L, 2);
  498. if (lua_gettop(L) > 2) {
  499. forced = lua_toboolean(L, 3);
  500. }
  501. if (sig != NULL && filename != NULL) {
  502. flags = O_WRONLY | O_CREAT;
  503. if (forced) {
  504. flags |= O_TRUNC;
  505. }
  506. else {
  507. flags |= O_EXCL;
  508. }
  509. fd = open(filename, flags, 00644);
  510. if (fd == -1) {
  511. msg_err("cannot create a signature file: %s, %s",
  512. filename,
  513. strerror(errno));
  514. lua_pushboolean(L, FALSE);
  515. }
  516. else {
  517. while (write(fd, sig->str, sig->len) == -1) {
  518. if (errno == EINTR) {
  519. continue;
  520. }
  521. msg_err("cannot write to a signature file: %s, %s",
  522. filename,
  523. strerror(errno));
  524. res = FALSE;
  525. break;
  526. }
  527. lua_pushboolean(L, res);
  528. close(fd);
  529. }
  530. }
  531. else {
  532. lua_pushboolean(L, FALSE);
  533. }
  534. return 1;
  535. }
  536. static int
  537. lua_rsa_signature_create(lua_State *L)
  538. {
  539. rspamd_fstring_t *sig, **psig;
  540. const char *data;
  541. gsize dlen;
  542. data = luaL_checklstring(L, 1, &dlen);
  543. if (data != NULL) {
  544. sig = rspamd_fstring_new_init(data, dlen);
  545. psig = lua_newuserdata(L, sizeof(rspamd_fstring_t *));
  546. rspamd_lua_setclass(L, rspamd_rsa_signature_classname, -1);
  547. *psig = sig;
  548. }
  549. return 1;
  550. }
  551. static int
  552. lua_rsa_signature_gc(lua_State *L)
  553. {
  554. rspamd_fstring_t *sig = lua_check_rsa_sign(L, 1);
  555. rspamd_fstring_free(sig);
  556. return 0;
  557. }
  558. static int
  559. lua_rsa_signature_base64(lua_State *L)
  560. {
  561. rspamd_fstring_t *sig = lua_check_rsa_sign(L, 1);
  562. unsigned int boundary = 0;
  563. char *b64;
  564. gsize outlen;
  565. enum rspamd_newlines_type how = RSPAMD_TASK_NEWLINES_CRLF;
  566. if (lua_isnumber(L, 2)) {
  567. boundary = lua_tonumber(L, 2);
  568. }
  569. if (lua_isstring(L, 3)) {
  570. const char *how_str = lua_tostring(L, 3);
  571. if (strcmp(how_str, "cr") == 0) {
  572. how = RSPAMD_TASK_NEWLINES_CR;
  573. }
  574. else if (strcmp(how_str, "lf") == 0) {
  575. how = RSPAMD_TASK_NEWLINES_LF;
  576. }
  577. else {
  578. how = RSPAMD_TASK_NEWLINES_CRLF;
  579. }
  580. }
  581. b64 = rspamd_encode_base64_fold(sig->str, sig->len, boundary, &outlen, how);
  582. if (b64) {
  583. lua_pushlstring(L, b64, outlen);
  584. g_free(b64);
  585. }
  586. else {
  587. lua_pushnil(L);
  588. }
  589. return 1;
  590. }
  591. /**
  592. * Check memory using specified rsa key and signature
  593. *
  594. * arguments:
  595. * (rsa_pubkey, rsa_signature, string)
  596. *
  597. * returns:
  598. * true - if string match rsa signature
  599. * false - otherwise
  600. */
  601. static int
  602. lua_rsa_verify_memory(lua_State *L)
  603. {
  604. RSA *rsa;
  605. rspamd_fstring_t *signature;
  606. const char *data;
  607. gsize sz;
  608. int ret;
  609. rsa = lua_check_rsa_pubkey(L, 1);
  610. signature = lua_check_rsa_sign(L, 2);
  611. data = luaL_checklstring(L, 3, &sz);
  612. if (rsa != NULL && signature != NULL && data != NULL) {
  613. ret = RSA_verify(NID_sha256, data, sz,
  614. signature->str, signature->len, rsa);
  615. if (ret == 0) {
  616. lua_pushboolean(L, FALSE);
  617. lua_pushstring(L, ERR_error_string(ERR_get_error(), NULL));
  618. return 2;
  619. }
  620. else {
  621. lua_pushboolean(L, TRUE);
  622. }
  623. }
  624. else {
  625. lua_pushnil(L);
  626. }
  627. return 1;
  628. }
  629. /**
  630. * Sign memory using specified rsa key and signature
  631. *
  632. * arguments:
  633. * (rsa_privkey, string)
  634. *
  635. * returns:
  636. * rspamd_signature object
  637. * nil - otherwise
  638. */
  639. static int
  640. lua_rsa_sign_memory(lua_State *L)
  641. {
  642. RSA *rsa;
  643. rspamd_fstring_t *signature, **psig;
  644. const char *data;
  645. gsize sz;
  646. int ret;
  647. rsa = lua_check_rsa_privkey(L, 1);
  648. data = luaL_checklstring(L, 2, &sz);
  649. if (rsa != NULL && data != NULL) {
  650. signature = rspamd_fstring_sized_new(RSA_size(rsa));
  651. unsigned int siglen = signature->len;
  652. ret = RSA_sign(NID_sha256, data, sz,
  653. signature->str, &siglen, rsa);
  654. if (ret != 1) {
  655. rspamd_fstring_free(signature);
  656. return luaL_error(L, "cannot sign: %s",
  657. ERR_error_string(ERR_get_error(), NULL));
  658. }
  659. else {
  660. signature->len = siglen;
  661. psig = lua_newuserdata(L, sizeof(rspamd_fstring_t *));
  662. rspamd_lua_setclass(L, rspamd_rsa_signature_classname, -1);
  663. *psig = signature;
  664. }
  665. }
  666. else {
  667. return luaL_error(L, "invalid arguments");
  668. }
  669. return 1;
  670. }
  671. static int
  672. lua_rsa_keypair(lua_State *L)
  673. {
  674. BIGNUM *e;
  675. RSA *rsa, *pub_rsa, *priv_rsa, **prsa;
  676. int bits = lua_gettop(L) > 0 ? lua_tointeger(L, 1) : 1024;
  677. if (bits > 4096 || bits < 512) {
  678. return luaL_error(L, "invalid bits count");
  679. }
  680. e = BN_new();
  681. rsa = RSA_new();
  682. g_assert(BN_set_word(e, RSA_F4) == 1);
  683. g_assert(RSA_generate_key_ex(rsa, bits, e, NULL) == 1);
  684. priv_rsa = RSAPrivateKey_dup(rsa);
  685. prsa = lua_newuserdata(L, sizeof(RSA *));
  686. rspamd_lua_setclass(L, rspamd_rsa_privkey_classname, -1);
  687. *prsa = priv_rsa;
  688. pub_rsa = RSAPublicKey_dup(rsa);
  689. prsa = lua_newuserdata(L, sizeof(RSA *));
  690. rspamd_lua_setclass(L, rspamd_rsa_pubkey_classname, -1);
  691. *prsa = pub_rsa;
  692. RSA_free(rsa);
  693. BN_free(e);
  694. return 2;
  695. }
  696. static int
  697. lua_load_pubkey(lua_State *L)
  698. {
  699. lua_newtable(L);
  700. luaL_register(L, NULL, rsapubkeylib_f);
  701. return 1;
  702. }
  703. static int
  704. lua_load_privkey(lua_State *L)
  705. {
  706. lua_newtable(L);
  707. luaL_register(L, NULL, rsaprivkeylib_f);
  708. return 1;
  709. }
  710. static int
  711. lua_load_signature(lua_State *L)
  712. {
  713. lua_newtable(L);
  714. luaL_register(L, NULL, rsasignlib_f);
  715. return 1;
  716. }
  717. static int
  718. lua_load_rsa(lua_State *L)
  719. {
  720. lua_newtable(L);
  721. luaL_register(L, NULL, rsalib_f);
  722. return 1;
  723. }
  724. void luaopen_rsa(lua_State *L)
  725. {
  726. rspamd_lua_new_class(L, rspamd_rsa_pubkey_classname, rsapubkeylib_m);
  727. lua_pop(L, 1);
  728. rspamd_lua_add_preload(L, "rspamd_rsa_pubkey", lua_load_pubkey);
  729. rspamd_lua_new_class(L, rspamd_rsa_privkey_classname, rsaprivkeylib_m);
  730. lua_pop(L, 1);
  731. rspamd_lua_add_preload(L, "rspamd_rsa_privkey", lua_load_privkey);
  732. rspamd_lua_new_class(L, rspamd_rsa_signature_classname, rsasignlib_m);
  733. lua_pop(L, 1);
  734. rspamd_lua_add_preload(L, "rspamd_rsa_signature", lua_load_signature);
  735. rspamd_lua_add_preload(L, "rspamd_rsa", lua_load_rsa);
  736. lua_settop(L, 0);
  737. }