1 /*--------------------------------------------------------------------------
2 * LuaSec 1.0.2
3 *
4 * Copyright (C) 2014-2021 Kim Alvefur, Paul Aurich, Tobias Markmann,
5 * Matthew Wild.
6 * Copyright (C) 2006-2021 Bruno Silvestre.
7 *
8 *--------------------------------------------------------------------------*/
9
10 #include <string.h>
11
12 #if defined(WIN32)
13 #include <windows.h>
14 #endif
15
16 #include <openssl/ssl.h>
17 #include <openssl/err.h>
18 #include <openssl/x509.h>
19 #include <openssl/x509v3.h>
20 #include <openssl/dh.h>
21
22 #include <lua.h>
23 #include <lauxlib.h>
24
25 #include "compat.h"
26 #include "context.h"
27 #include "options.h"
28
29 #ifndef OPENSSL_NO_EC
30 #include <openssl/ec.h>
31 #include "ec.h"
32 #endif
33
34 /*--------------------------- Auxiliary Functions ----------------------------*/
35
36 /**
37 * Return the context.
38 */
checkctx(lua_State * L,int idx)39 static p_context checkctx(lua_State *L, int idx)
40 {
41 return (p_context)luaL_checkudata(L, idx, "SSL:Context");
42 }
43
testctx(lua_State * L,int idx)44 static p_context testctx(lua_State *L, int idx)
45 {
46 return (p_context)luaL_testudata(L, idx, "SSL:Context");
47 }
48
49 /**
50 * Prepare the SSL options flag.
51 */
set_option_flag(const char * opt,unsigned long * flag)52 static int set_option_flag(const char *opt, unsigned long *flag)
53 {
54 lsec_ssl_option_t *p;
55 for (p = lsec_get_ssl_options(); p->name; p++) {
56 if (!strcmp(opt, p->name)) {
57 *flag |= p->code;
58 return 1;
59 }
60 }
61 return 0;
62 }
63
64 #ifndef LSEC_API_OPENSSL_1_1_0
65 /**
66 * Find the protocol.
67 */
str2method(const char * method,int * vmin,int * vmax)68 static const SSL_METHOD* str2method(const char *method, int *vmin, int *vmax)
69 {
70 (void)vmin;
71 (void)vmax;
72 if (!strcmp(method, "any")) return SSLv23_method();
73 if (!strcmp(method, "sslv23")) return SSLv23_method(); // deprecated
74 if (!strcmp(method, "tlsv1")) return TLSv1_method();
75 if (!strcmp(method, "tlsv1_1")) return TLSv1_1_method();
76 if (!strcmp(method, "tlsv1_2")) return TLSv1_2_method();
77 return NULL;
78 }
79
80 #else
81
82 /**
83 * Find the protocol.
84 */
str2method(const char * method,int * vmin,int * vmax)85 static const SSL_METHOD* str2method(const char *method, int *vmin, int *vmax)
86 {
87 if (!strcmp(method, "any") || !strcmp(method, "sslv23")) { // 'sslv23' is deprecated
88 *vmin = 0;
89 *vmax = 0;
90 return TLS_method();
91 }
92 else if (!strcmp(method, "tlsv1")) {
93 *vmin = TLS1_VERSION;
94 *vmax = TLS1_VERSION;
95 return TLS_method();
96 }
97 else if (!strcmp(method, "tlsv1_1")) {
98 *vmin = TLS1_1_VERSION;
99 *vmax = TLS1_1_VERSION;
100 return TLS_method();
101 }
102 else if (!strcmp(method, "tlsv1_2")) {
103 *vmin = TLS1_2_VERSION;
104 *vmax = TLS1_2_VERSION;
105 return TLS_method();
106 }
107 #if defined(TLS1_3_VERSION)
108 else if (!strcmp(method, "tlsv1_3")) {
109 *vmin = TLS1_3_VERSION;
110 *vmax = TLS1_3_VERSION;
111 return TLS_method();
112 }
113 #endif
114 return NULL;
115 }
116 #endif
117
118 /**
119 * Prepare the SSL handshake verify flag.
120 */
set_verify_flag(const char * str,int * flag)121 static int set_verify_flag(const char *str, int *flag)
122 {
123 if (!strcmp(str, "none")) {
124 *flag |= SSL_VERIFY_NONE;
125 return 1;
126 }
127 if (!strcmp(str, "peer")) {
128 *flag |= SSL_VERIFY_PEER;
129 return 1;
130 }
131 if (!strcmp(str, "client_once")) {
132 *flag |= SSL_VERIFY_CLIENT_ONCE;
133 return 1;
134 }
135 if (!strcmp(str, "fail_if_no_peer_cert")) {
136 *flag |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
137 return 1;
138 }
139 return 0;
140 }
141
142 /**
143 * Password callback for reading the private key.
144 */
passwd_cb(char * buf,int size,int flag,void * udata)145 static int passwd_cb(char *buf, int size, int flag, void *udata)
146 {
147 lua_State *L = (lua_State*)udata;
148 switch (lua_type(L, 3)) {
149 case LUA_TFUNCTION:
150 lua_pushvalue(L, 3);
151 lua_call(L, 0, 1);
152 if (lua_type(L, -1) != LUA_TSTRING) {
153 lua_pop(L, 1); /* Remove the result from the stack */
154 return 0;
155 }
156 /* fallback */
157 case LUA_TSTRING:
158 strncpy(buf, lua_tostring(L, -1), size);
159 lua_pop(L, 1); /* Remove the result from the stack */
160 buf[size-1] = '\0';
161 return (int)strlen(buf);
162 }
163 return 0;
164 }
165
166 /**
167 * Add an error related to a depth certificate of the chain.
168 */
add_cert_error(lua_State * L,SSL * ssl,int err,int depth)169 static void add_cert_error(lua_State *L, SSL *ssl, int err, int depth)
170 {
171 luaL_getmetatable(L, "SSL:Verify:Registry");
172 lua_pushlightuserdata(L, (void*)ssl);
173 lua_gettable(L, -2);
174 if (lua_isnil(L, -1)) {
175 lua_pop(L, 1);
176 /* Create an error table for this connection */
177 lua_newtable(L);
178 lua_pushlightuserdata(L, (void*)ssl);
179 lua_pushvalue(L, -2); /* keep the table on stack */
180 lua_settable(L, -4);
181 }
182 lua_rawgeti(L, -1, depth+1);
183 /* If the table doesn't exist, create it */
184 if (lua_isnil(L, -1)) {
185 lua_pop(L, 1); /* remove 'nil' from stack */
186 lua_newtable(L);
187 lua_pushvalue(L, -1); /* keep the table on stack */
188 lua_rawseti(L, -3, depth+1);
189 }
190 lua_pushstring(L, X509_verify_cert_error_string(err));
191 lua_rawseti(L, -2, lua_rawlen(L, -2) + 1);
192 /* Clear the stack */
193 lua_pop(L, 3);
194 }
195
196 /**
197 * Call Lua user function to get the DH key.
198 */
dhparam_cb(SSL * ssl,int is_export,int keylength)199 static DH *dhparam_cb(SSL *ssl, int is_export, int keylength)
200 {
201 BIO *bio;
202 lua_State *L;
203 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
204 p_context pctx = (p_context)SSL_CTX_get_app_data(ctx);
205
206 L = pctx->L;
207
208 /* Get the callback */
209 luaL_getmetatable(L, "SSL:DH:Registry");
210 lua_pushlightuserdata(L, (void*)ctx);
211 lua_gettable(L, -2);
212
213 /* Invoke the callback */
214 lua_pushboolean(L, is_export);
215 lua_pushnumber(L, keylength);
216 lua_call(L, 2, 1);
217
218 /* Load parameters from returned value */
219 if (lua_type(L, -1) != LUA_TSTRING) {
220 lua_pop(L, 2); /* Remove values from stack */
221 return NULL;
222 }
223
224 bio = BIO_new_mem_buf((void*)lua_tostring(L, -1), lua_rawlen(L, -1));
225 if (bio) {
226 pctx->dh_param = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
227 BIO_free(bio);
228 }
229
230 lua_pop(L, 2); /* Remove values from stack */
231 return pctx->dh_param;
232 }
233
234 /**
235 * Set the "ignore purpose" before to start verifing the certificate chain.
236 */
cert_verify_cb(X509_STORE_CTX * x509_ctx,void * ptr)237 static int cert_verify_cb(X509_STORE_CTX *x509_ctx, void *ptr)
238 {
239 int verify;
240 lua_State *L;
241 SSL_CTX *ctx = (SSL_CTX*)ptr;
242 p_context pctx = (p_context)SSL_CTX_get_app_data(ctx);
243
244 L = pctx->L;
245
246 /* Get verify flags */
247 luaL_getmetatable(L, "SSL:Verify:Registry");
248 lua_pushlightuserdata(L, (void*)ctx);
249 lua_gettable(L, -2);
250 verify = (int)lua_tonumber(L, -1);
251
252 lua_pop(L, 2); /* Remove values from stack */
253
254 if (verify & LSEC_VERIFY_IGNORE_PURPOSE) {
255 /* Set parameters to ignore the server purpose */
256 X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(x509_ctx);
257 if (param) {
258 X509_VERIFY_PARAM_set_purpose(param, X509_PURPOSE_SSL_SERVER);
259 X509_VERIFY_PARAM_set_trust(param, X509_TRUST_SSL_SERVER);
260 }
261 }
262 /* Call OpenSSL standard verification function */
263 return X509_verify_cert(x509_ctx);
264 }
265
266 /**
267 * This callback implements the "continue on error" flag and log the errors.
268 */
verify_cb(int preverify_ok,X509_STORE_CTX * x509_ctx)269 static int verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
270 {
271 int err;
272 int verify;
273 SSL *ssl;
274 SSL_CTX *ctx;
275 p_context pctx;
276 lua_State *L;
277
278 /* Short-circuit optimization */
279 if (preverify_ok)
280 return 1;
281
282 ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
283 SSL_get_ex_data_X509_STORE_CTX_idx());
284 ctx = SSL_get_SSL_CTX(ssl);
285 pctx = (p_context)SSL_CTX_get_app_data(ctx);
286 L = pctx->L;
287
288 /* Get verify flags */
289 luaL_getmetatable(L, "SSL:Verify:Registry");
290 lua_pushlightuserdata(L, (void*)ctx);
291 lua_gettable(L, -2);
292 verify = (int)lua_tonumber(L, -1);
293
294 lua_pop(L, 2); /* Remove values from stack */
295
296 err = X509_STORE_CTX_get_error(x509_ctx);
297 if (err != X509_V_OK)
298 add_cert_error(L, ssl, err, X509_STORE_CTX_get_error_depth(x509_ctx));
299
300 return (verify & LSEC_VERIFY_CONTINUE ? 1 : preverify_ok);
301 }
302
303 /*------------------------------ Lua Functions -------------------------------*/
304
305 /**
306 * Create a SSL context.
307 */
create(lua_State * L)308 static int create(lua_State *L)
309 {
310 p_context ctx;
311 const char *str_method;
312 const SSL_METHOD *method;
313 int vmin, vmax;
314
315 str_method = luaL_checkstring(L, 1);
316 method = str2method(str_method, &vmin, &vmax);
317 if (!method) {
318 lua_pushnil(L);
319 lua_pushfstring(L, "invalid protocol (%s)", str_method);
320 return 2;
321 }
322 ctx = (p_context) lua_newuserdata(L, sizeof(t_context));
323 if (!ctx) {
324 lua_pushnil(L);
325 lua_pushstring(L, "error creating context");
326 return 2;
327 }
328 memset(ctx, 0, sizeof(t_context));
329 ctx->context = SSL_CTX_new(method);
330 if (!ctx->context) {
331 lua_pushnil(L);
332 lua_pushfstring(L, "error creating context (%s)",
333 ERR_reason_error_string(ERR_get_error()));
334 return 2;
335 }
336 #ifdef LSEC_API_OPENSSL_1_1_0
337 SSL_CTX_set_min_proto_version(ctx->context, vmin);
338 SSL_CTX_set_max_proto_version(ctx->context, vmax);
339 #endif
340 ctx->mode = LSEC_MODE_INVALID;
341 ctx->L = L;
342 luaL_getmetatable(L, "SSL:Context");
343 lua_setmetatable(L, -2);
344
345 /* No session support */
346 SSL_CTX_set_session_cache_mode(ctx->context, SSL_SESS_CACHE_OFF);
347 /* Link LuaSec context with the OpenSSL context */
348 SSL_CTX_set_app_data(ctx->context, ctx);
349
350 return 1;
351 }
352
353 /**
354 * Load the trusting certificates.
355 */
load_locations(lua_State * L)356 static int load_locations(lua_State *L)
357 {
358 SSL_CTX *ctx = lsec_checkcontext(L, 1);
359 const char *cafile = luaL_optstring(L, 2, NULL);
360 const char *capath = luaL_optstring(L, 3, NULL);
361 if (SSL_CTX_load_verify_locations(ctx, cafile, capath) != 1) {
362 lua_pushboolean(L, 0);
363 lua_pushfstring(L, "error loading CA locations (%s)",
364 ERR_reason_error_string(ERR_get_error()));
365 return 2;
366 }
367 lua_pushboolean(L, 1);
368 return 1;
369 }
370
371 /**
372 * Load the certificate file.
373 */
load_cert(lua_State * L)374 static int load_cert(lua_State *L)
375 {
376 SSL_CTX *ctx = lsec_checkcontext(L, 1);
377 const char *filename = luaL_checkstring(L, 2);
378 if (SSL_CTX_use_certificate_chain_file(ctx, filename) != 1) {
379 lua_pushboolean(L, 0);
380 lua_pushfstring(L, "error loading certificate (%s)",
381 ERR_reason_error_string(ERR_get_error()));
382 return 2;
383 }
384 lua_pushboolean(L, 1);
385 return 1;
386 }
387
388 /**
389 * Load the key file -- only in PEM format.
390 */
load_key(lua_State * L)391 static int load_key(lua_State *L)
392 {
393 int ret = 1;
394 SSL_CTX *ctx = lsec_checkcontext(L, 1);
395 const char *filename = luaL_checkstring(L, 2);
396 switch (lua_type(L, 3)) {
397 case LUA_TSTRING:
398 case LUA_TFUNCTION:
399 SSL_CTX_set_default_passwd_cb(ctx, passwd_cb);
400 SSL_CTX_set_default_passwd_cb_userdata(ctx, L);
401 /* fallback */
402 case LUA_TNIL:
403 if (SSL_CTX_use_PrivateKey_file(ctx, filename, SSL_FILETYPE_PEM) == 1)
404 lua_pushboolean(L, 1);
405 else {
406 ret = 2;
407 lua_pushboolean(L, 0);
408 lua_pushfstring(L, "error loading private key (%s)",
409 ERR_reason_error_string(ERR_get_error()));
410 }
411 SSL_CTX_set_default_passwd_cb(ctx, NULL);
412 SSL_CTX_set_default_passwd_cb_userdata(ctx, NULL);
413 break;
414 default:
415 lua_pushstring(L, "invalid callback value");
416 lua_error(L);
417 }
418 return ret;
419 }
420
421 /**
422 * Check that the certificate public key matches the private key
423 */
424
check_key(lua_State * L)425 static int check_key(lua_State *L)
426 {
427 SSL_CTX *ctx = lsec_checkcontext(L, 1);
428 lua_pushboolean(L, SSL_CTX_check_private_key(ctx));
429 return 1;
430 }
431
432 /**
433 * Set the cipher list.
434 */
set_cipher(lua_State * L)435 static int set_cipher(lua_State *L)
436 {
437 SSL_CTX *ctx = lsec_checkcontext(L, 1);
438 const char *list = luaL_checkstring(L, 2);
439 if (SSL_CTX_set_cipher_list(ctx, list) != 1) {
440 lua_pushboolean(L, 0);
441 lua_pushfstring(L, "error setting cipher list (%s)", ERR_reason_error_string(ERR_get_error()));
442 return 2;
443 }
444 lua_pushboolean(L, 1);
445 return 1;
446 }
447
448 /**
449 * Set the cipher suites.
450 */
set_ciphersuites(lua_State * L)451 static int set_ciphersuites(lua_State *L)
452 {
453 #if defined(TLS1_3_VERSION)
454 SSL_CTX *ctx = lsec_checkcontext(L, 1);
455 const char *list = luaL_checkstring(L, 2);
456 if (SSL_CTX_set_ciphersuites(ctx, list) != 1) {
457 lua_pushboolean(L, 0);
458 lua_pushfstring(L, "error setting cipher list (%s)", ERR_reason_error_string(ERR_get_error()));
459 return 2;
460 }
461 #endif
462 lua_pushboolean(L, 1);
463 return 1;
464 }
465
466 /**
467 * Set the depth for certificate checking.
468 */
set_depth(lua_State * L)469 static int set_depth(lua_State *L)
470 {
471 SSL_CTX *ctx = lsec_checkcontext(L, 1);
472 SSL_CTX_set_verify_depth(ctx, (int)luaL_checkinteger(L, 2));
473 lua_pushboolean(L, 1);
474 return 1;
475 }
476
477 /**
478 * Set the handshake verify options.
479 */
set_verify(lua_State * L)480 static int set_verify(lua_State *L)
481 {
482 int i;
483 const char *str;
484 int flag = 0;
485 SSL_CTX *ctx = lsec_checkcontext(L, 1);
486 int max = lua_gettop(L);
487 for (i = 2; i <= max; i++) {
488 str = luaL_checkstring(L, i);
489 if (!set_verify_flag(str, &flag)) {
490 lua_pushboolean(L, 0);
491 lua_pushfstring(L, "invalid verify option (%s)", str);
492 return 2;
493 }
494 }
495 if (flag) SSL_CTX_set_verify(ctx, flag, NULL);
496 lua_pushboolean(L, 1);
497 return 1;
498 }
499
500 /**
501 * Set the protocol options.
502 */
set_options(lua_State * L)503 static int set_options(lua_State *L)
504 {
505 int i;
506 const char *str;
507 unsigned long flag = 0L;
508 SSL_CTX *ctx = lsec_checkcontext(L, 1);
509 int max = lua_gettop(L);
510 /* any option? */
511 if (max > 1) {
512 for (i = 2; i <= max; i++) {
513 str = luaL_checkstring(L, i);
514 if (!set_option_flag(str, &flag)) {
515 lua_pushboolean(L, 0);
516 lua_pushfstring(L, "invalid option (%s)", str);
517 return 2;
518 }
519 }
520 SSL_CTX_set_options(ctx, flag);
521 }
522 lua_pushboolean(L, 1);
523 return 1;
524 }
525
526 /**
527 * Set the context mode.
528 */
set_mode(lua_State * L)529 static int set_mode(lua_State *L)
530 {
531 p_context ctx = checkctx(L, 1);
532 const char *str = luaL_checkstring(L, 2);
533 if (!strcmp("server", str)) {
534 ctx->mode = LSEC_MODE_SERVER;
535 lua_pushboolean(L, 1);
536 return 1;
537 }
538 if (!strcmp("client", str)) {
539 ctx->mode = LSEC_MODE_CLIENT;
540 lua_pushboolean(L, 1);
541 return 1;
542 }
543 lua_pushboolean(L, 0);
544 lua_pushfstring(L, "invalid mode (%s)", str);
545 return 1;
546 }
547
548 /**
549 * Configure DH parameters.
550 */
set_dhparam(lua_State * L)551 static int set_dhparam(lua_State *L)
552 {
553 SSL_CTX *ctx = lsec_checkcontext(L, 1);
554 SSL_CTX_set_tmp_dh_callback(ctx, dhparam_cb);
555
556 /* Save callback */
557 luaL_getmetatable(L, "SSL:DH:Registry");
558 lua_pushlightuserdata(L, (void*)ctx);
559 lua_pushvalue(L, 2);
560 lua_settable(L, -3);
561
562 return 0;
563 }
564
565 #if !defined(OPENSSL_NO_EC)
566 /**
567 * Set elliptic curve.
568 */
set_curve(lua_State * L)569 static int set_curve(lua_State *L)
570 {
571 long ret;
572 EC_KEY *key = NULL;
573 SSL_CTX *ctx = lsec_checkcontext(L, 1);
574 const char *str = luaL_checkstring(L, 2);
575
576 SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE);
577
578 key = lsec_find_ec_key(L, str);
579
580 if (!key) {
581 lua_pushboolean(L, 0);
582 lua_pushfstring(L, "elliptic curve '%s' not supported", str);
583 return 2;
584 }
585
586 ret = SSL_CTX_set_tmp_ecdh(ctx, key);
587 /* SSL_CTX_set_tmp_ecdh takes its own reference */
588 EC_KEY_free(key);
589
590 if (!ret) {
591 lua_pushboolean(L, 0);
592 lua_pushfstring(L, "error setting elliptic curve (%s)",
593 ERR_reason_error_string(ERR_get_error()));
594 return 2;
595 }
596
597 lua_pushboolean(L, 1);
598 return 1;
599 }
600
601 /**
602 * Set elliptic curves list.
603 */
set_curves_list(lua_State * L)604 static int set_curves_list(lua_State *L)
605 {
606 SSL_CTX *ctx = lsec_checkcontext(L, 1);
607 const char *str = luaL_checkstring(L, 2);
608
609 SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE);
610
611 if (SSL_CTX_set1_curves_list(ctx, str) != 1) {
612 lua_pushboolean(L, 0);
613 lua_pushfstring(L, "unknown elliptic curve in \"%s\"", str);
614 return 2;
615 }
616
617 #if defined(LIBRESSL_VERSION_NUMBER) || !defined(LSEC_API_OPENSSL_1_1_0)
618 (void)SSL_CTX_set_ecdh_auto(ctx, 1);
619 #endif
620
621 lua_pushboolean(L, 1);
622 return 1;
623 }
624 #endif
625
626 /**
627 * Set the protocols a client should send for ALPN.
628 */
set_alpn(lua_State * L)629 static int set_alpn(lua_State *L)
630 {
631 long ret;
632 size_t len;
633 p_context ctx = checkctx(L, 1);
634 const char *str = luaL_checklstring(L, 2, &len);
635
636 ret = SSL_CTX_set_alpn_protos(ctx->context, (const unsigned char*)str, len);
637 if (ret) {
638 lua_pushboolean(L, 0);
639 lua_pushfstring(L, "error setting ALPN (%s)", ERR_reason_error_string(ERR_get_error()));
640 return 2;
641 }
642 lua_pushboolean(L, 1);
643 return 1;
644 }
645
646 /**
647 * This standard callback calls the server's callback in Lua sapce.
648 * The server has to return a list in wire-format strings.
649 * This function uses a helper function to match server and client lists.
650 */
alpn_cb(SSL * s,const unsigned char ** out,unsigned char * outlen,const unsigned char * in,unsigned int inlen,void * arg)651 static int alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen,
652 const unsigned char *in, unsigned int inlen, void *arg)
653 {
654 int ret;
655 size_t server_len;
656 const char *server;
657 p_context ctx = (p_context)arg;
658 lua_State *L = ctx->L;
659
660 luaL_getmetatable(L, "SSL:ALPN:Registry");
661 lua_pushlightuserdata(L, (void*)ctx->context);
662 lua_gettable(L, -2);
663
664 lua_pushlstring(L, (const char*)in, inlen);
665
666 lua_call(L, 1, 1);
667
668 if (!lua_isstring(L, -1)) {
669 lua_pop(L, 2);
670 return SSL_TLSEXT_ERR_NOACK;
671 }
672
673 // Protocol list from server in wire-format string
674 server = luaL_checklstring(L, -1, &server_len);
675 ret = SSL_select_next_proto((unsigned char**)out, outlen, (const unsigned char*)server,
676 server_len, in, inlen);
677 if (ret != OPENSSL_NPN_NEGOTIATED) {
678 lua_pop(L, 2);
679 return SSL_TLSEXT_ERR_NOACK;
680 }
681
682 // Copy the result because lua_pop() can collect the pointer
683 ctx->alpn = malloc(*outlen);
684 memcpy(ctx->alpn, (void*)*out, *outlen);
685 *out = (const unsigned char*)ctx->alpn;
686
687 lua_pop(L, 2);
688
689 return SSL_TLSEXT_ERR_OK;
690 }
691
692 /**
693 * Set a callback a server can use to select the next protocol with ALPN.
694 */
set_alpn_cb(lua_State * L)695 static int set_alpn_cb(lua_State *L)
696 {
697 p_context ctx = checkctx(L, 1);
698
699 luaL_getmetatable(L, "SSL:ALPN:Registry");
700 lua_pushlightuserdata(L, (void*)ctx->context);
701 lua_pushvalue(L, 2);
702 lua_settable(L, -3);
703
704 SSL_CTX_set_alpn_select_cb(ctx->context, alpn_cb, ctx);
705
706 lua_pushboolean(L, 1);
707 return 1;
708 }
709
710 #if defined(LSEC_ENABLE_DANE)
711 /*
712 * DANE
713 */
set_dane(lua_State * L)714 static int set_dane(lua_State *L)
715 {
716 int ret;
717 SSL_CTX *ctx = lsec_checkcontext(L, 1);
718 ret = SSL_CTX_dane_enable(ctx);
719 lua_pushboolean(L, (ret > 0));
720 return 1;
721 }
722 #endif
723
724 /**
725 * Package functions
726 */
727 static luaL_Reg funcs[] = {
728 {"create", create},
729 {"locations", load_locations},
730 {"loadcert", load_cert},
731 {"loadkey", load_key},
732 {"checkkey", check_key},
733 {"setalpn", set_alpn},
734 {"setalpncb", set_alpn_cb},
735 {"setcipher", set_cipher},
736 {"setciphersuites", set_ciphersuites},
737 {"setdepth", set_depth},
738 {"setdhparam", set_dhparam},
739 {"setverify", set_verify},
740 {"setoptions", set_options},
741 {"setmode", set_mode},
742 #if !defined(OPENSSL_NO_EC)
743 {"setcurve", set_curve},
744 {"setcurveslist", set_curves_list},
745 #endif
746 #if defined(LSEC_ENABLE_DANE)
747 {"setdane", set_dane},
748 #endif
749 {NULL, NULL}
750 };
751
752 /*-------------------------------- Metamethods -------------------------------*/
753
754 /**
755 * Collect SSL context -- GC metamethod.
756 */
meth_destroy(lua_State * L)757 static int meth_destroy(lua_State *L)
758 {
759 p_context ctx = checkctx(L, 1);
760 if (ctx->context) {
761 /* Clear registries */
762 luaL_getmetatable(L, "SSL:DH:Registry");
763 lua_pushlightuserdata(L, (void*)ctx->context);
764 lua_pushnil(L);
765 lua_settable(L, -3);
766 luaL_getmetatable(L, "SSL:Verify:Registry");
767 lua_pushlightuserdata(L, (void*)ctx->context);
768 lua_pushnil(L);
769 lua_settable(L, -3);
770 luaL_getmetatable(L, "SSL:ALPN:Registry");
771 lua_pushlightuserdata(L, (void*)ctx->context);
772 lua_pushnil(L);
773 lua_settable(L, -3);
774
775 SSL_CTX_free(ctx->context);
776 ctx->context = NULL;
777 }
778 return 0;
779 }
780
781 /**
782 * Object information -- tostring metamethod.
783 */
meth_tostring(lua_State * L)784 static int meth_tostring(lua_State *L)
785 {
786 p_context ctx = checkctx(L, 1);
787 lua_pushfstring(L, "SSL context: %p", ctx);
788 return 1;
789 }
790
791 /**
792 * Set extra flags for handshake verification.
793 */
meth_set_verify_ext(lua_State * L)794 static int meth_set_verify_ext(lua_State *L)
795 {
796 int i;
797 const char *str;
798 int crl_flag = 0;
799 int lsec_flag = 0;
800 SSL_CTX *ctx = lsec_checkcontext(L, 1);
801 int max = lua_gettop(L);
802 for (i = 2; i <= max; i++) {
803 str = luaL_checkstring(L, i);
804 if (!strcmp(str, "lsec_continue")) {
805 lsec_flag |= LSEC_VERIFY_CONTINUE;
806 } else if (!strcmp(str, "lsec_ignore_purpose")) {
807 lsec_flag |= LSEC_VERIFY_IGNORE_PURPOSE;
808 } else if (!strcmp(str, "crl_check")) {
809 crl_flag |= X509_V_FLAG_CRL_CHECK;
810 } else if (!strcmp(str, "crl_check_chain")) {
811 crl_flag |= X509_V_FLAG_CRL_CHECK_ALL;
812 } else {
813 lua_pushboolean(L, 0);
814 lua_pushfstring(L, "invalid verify option (%s)", str);
815 return 2;
816 }
817 }
818 /* Set callback? */
819 if (lsec_flag) {
820 SSL_CTX_set_verify(ctx, SSL_CTX_get_verify_mode(ctx), verify_cb);
821 SSL_CTX_set_cert_verify_callback(ctx, cert_verify_cb, (void*)ctx);
822 /* Save flag */
823 luaL_getmetatable(L, "SSL:Verify:Registry");
824 lua_pushlightuserdata(L, (void*)ctx);
825 lua_pushnumber(L, lsec_flag);
826 lua_settable(L, -3);
827 } else {
828 SSL_CTX_set_verify(ctx, SSL_CTX_get_verify_mode(ctx), NULL);
829 SSL_CTX_set_cert_verify_callback(ctx, NULL, NULL);
830 /* Remove flag */
831 luaL_getmetatable(L, "SSL:Verify:Registry");
832 lua_pushlightuserdata(L, (void*)ctx);
833 lua_pushnil(L);
834 lua_settable(L, -3);
835 }
836
837 /* X509 flag */
838 X509_STORE_set_flags(SSL_CTX_get_cert_store(ctx), crl_flag);
839
840 /* Ok */
841 lua_pushboolean(L, 1);
842 return 1;
843 }
844
845 /**
846 * Context metamethods.
847 */
848 static luaL_Reg meta[] = {
849 {"__close", meth_destroy},
850 {"__gc", meth_destroy},
851 {"__tostring", meth_tostring},
852 {NULL, NULL}
853 };
854
855 /**
856 * Index metamethods.
857 */
858 static luaL_Reg meta_index[] = {
859 {"setverifyext", meth_set_verify_ext},
860 {NULL, NULL}
861 };
862
863
864 /*----------------------------- Public Functions ---------------------------*/
865
866 /**
867 * Retrieve the SSL context from the Lua stack.
868 */
lsec_checkcontext(lua_State * L,int idx)869 SSL_CTX* lsec_checkcontext(lua_State *L, int idx)
870 {
871 p_context ctx = checkctx(L, idx);
872 return ctx->context;
873 }
874
lsec_testcontext(lua_State * L,int idx)875 SSL_CTX* lsec_testcontext(lua_State *L, int idx)
876 {
877 p_context ctx = testctx(L, idx);
878 return (ctx) ? ctx->context : NULL;
879 }
880
881 /**
882 * Retrieve the mode from the context in the Lua stack.
883 */
lsec_getmode(lua_State * L,int idx)884 int lsec_getmode(lua_State *L, int idx)
885 {
886 p_context ctx = checkctx(L, idx);
887 return ctx->mode;
888 }
889
890 /*-- Compat - Lua 5.1 --*/
891 #if (LUA_VERSION_NUM == 501)
892
lsec_testudata(lua_State * L,int ud,const char * tname)893 void *lsec_testudata (lua_State *L, int ud, const char *tname) {
894 void *p = lua_touserdata(L, ud);
895 if (p != NULL) { /* value is a userdata? */
896 if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
897 luaL_getmetatable(L, tname); /* get correct metatable */
898 if (!lua_rawequal(L, -1, -2)) /* not the same? */
899 p = NULL; /* value is a userdata with wrong metatable */
900 lua_pop(L, 2); /* remove both metatables */
901 return p;
902 }
903 }
904 return NULL; /* value is not a userdata with a metatable */
905 }
906
907 #endif
908
909 /*------------------------------ Initialization ------------------------------*/
910
911 /**
912 * Registre the module.
913 */
luaopen_ssl_context(lua_State * L)914 LSEC_API int luaopen_ssl_context(lua_State *L)
915 {
916 luaL_newmetatable(L, "SSL:DH:Registry"); /* Keep all DH callbacks */
917 luaL_newmetatable(L, "SSL:ALPN:Registry"); /* Keep all ALPN callbacks */
918 luaL_newmetatable(L, "SSL:Verify:Registry"); /* Keep all verify flags */
919 luaL_newmetatable(L, "SSL:Context");
920 setfuncs(L, meta);
921
922 /* Create __index metamethods for context */
923 luaL_newlib(L, meta_index);
924 lua_setfield(L, -2, "__index");
925
926 lsec_load_curves(L);
927
928 /* Return the module */
929 luaL_newlib(L, funcs);
930
931 return 1;
932 }
933