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