aboutsummaryrefslogtreecommitdiff
path: root/vendor/luasec/src/context.c
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/luasec/src/context.c')
-rw-r--r--vendor/luasec/src/context.c1099
1 files changed, 1099 insertions, 0 deletions
diff --git a/vendor/luasec/src/context.c b/vendor/luasec/src/context.c
new file mode 100644
index 00000000..881ebb90
--- /dev/null
+++ b/vendor/luasec/src/context.c
@@ -0,0 +1,1099 @@
1/*--------------------------------------------------------------------------
2 * LuaSec 1.3.2
3 *
4 * Copyright (C) 2014-2023 Kim Alvefur, Paul Aurich, Tobias Markmann, Matthew Wild
5 * Copyright (C) 2006-2023 Bruno Silvestre
6 *
7 *--------------------------------------------------------------------------*/
8
9#include <string.h>
10
11#if defined(WIN32)
12#include <windows.h>
13#endif
14
15#include <openssl/ssl.h>
16#include <openssl/err.h>
17#include <openssl/x509.h>
18#include <openssl/x509v3.h>
19#include <openssl/x509_vfy.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 */
39static p_context checkctx(lua_State *L, int idx)
40{
41 return (p_context)luaL_checkudata(L, idx, "SSL:Context");
42}
43
44static 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 */
52static 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 */
68static 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 */
85static 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 */
121static 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 */
145static 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 */
169static 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 */
199static 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 */
237static 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 */
269static 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 */
308static 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 */
356static 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 */
374static 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 */
391static 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
425static 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 */
435static 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 */
451static 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 */
469static 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 */
480static 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 */
503static 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 */
529static 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 */
551static 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 */
569static 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 */
604static 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 */
629static 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 */
651static 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 */
695static 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_PSK)
711/**
712 * Callback to select the PSK.
713 */
714static unsigned int server_psk_cb(SSL *ssl, const char *identity, unsigned char *psk,
715 unsigned int max_psk_len)
716{
717 size_t psk_len;
718 const char *ret_psk;
719 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
720 p_context pctx = (p_context)SSL_CTX_get_app_data(ctx);
721 lua_State *L = pctx->L;
722
723 luaL_getmetatable(L, "SSL:PSK:Registry");
724 lua_pushlightuserdata(L, (void*)pctx->context);
725 lua_gettable(L, -2);
726
727 lua_pushstring(L, identity);
728 lua_pushinteger(L, max_psk_len);
729
730 lua_call(L, 2, 1);
731
732 if (!lua_isstring(L, -1)) {
733 lua_pop(L, 2);
734 return 0;
735 }
736
737 ret_psk = lua_tolstring(L, -1, &psk_len);
738
739 if (psk_len == 0 || psk_len > max_psk_len)
740 psk_len = 0;
741 else
742 memcpy(psk, ret_psk, psk_len);
743
744 lua_pop(L, 2);
745
746 return psk_len;
747}
748
749/**
750 * Set a PSK callback for server.
751 */
752static int set_server_psk_cb(lua_State *L)
753{
754 p_context ctx = checkctx(L, 1);
755
756 luaL_getmetatable(L, "SSL:PSK:Registry");
757 lua_pushlightuserdata(L, (void*)ctx->context);
758 lua_pushvalue(L, 2);
759 lua_settable(L, -3);
760
761 SSL_CTX_set_psk_server_callback(ctx->context, server_psk_cb);
762
763 lua_pushboolean(L, 1);
764 return 1;
765}
766
767/*
768 * Set the PSK indentity hint.
769 */
770static int set_psk_identity_hint(lua_State *L)
771{
772 p_context ctx = checkctx(L, 1);
773 const char *hint = luaL_checkstring(L, 2);
774 int ret = SSL_CTX_use_psk_identity_hint(ctx->context, hint);
775 lua_pushboolean(L, ret);
776 return 1;
777}
778
779/*
780 * Client callback to PSK.
781 */
782static unsigned int client_psk_cb(SSL *ssl, const char *hint, char *identity,
783 unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len)
784{
785 size_t psk_len;
786 size_t identity_len;
787 const char *ret_psk;
788 const char *ret_identity;
789 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
790 p_context pctx = (p_context)SSL_CTX_get_app_data(ctx);
791 lua_State *L = pctx->L;
792
793 luaL_getmetatable(L, "SSL:PSK:Registry");
794 lua_pushlightuserdata(L, (void*)pctx->context);
795 lua_gettable(L, -2);
796
797 if (hint)
798 lua_pushstring(L, hint);
799 else
800 lua_pushnil(L);
801
802 // Leave space to '\0'
803 lua_pushinteger(L, max_identity_len-1);
804 lua_pushinteger(L, max_psk_len);
805
806 lua_call(L, 3, 2);
807
808 if (!lua_isstring(L, -1) || !lua_isstring(L, -2)) {
809 lua_pop(L, 3);
810 return 0;
811 }
812
813 ret_identity = lua_tolstring(L, -2, &identity_len);
814 ret_psk = lua_tolstring(L, -1, &psk_len);
815
816 if (identity_len >= max_identity_len || psk_len > max_psk_len)
817 psk_len = 0;
818 else {
819 memcpy(identity, ret_identity, identity_len);
820 identity[identity_len] = 0;
821 memcpy(psk, ret_psk, psk_len);
822 }
823
824 lua_pop(L, 3);
825
826 return psk_len;
827}
828
829/**
830 * Set a PSK callback for client.
831 */
832static int set_client_psk_cb(lua_State *L) {
833 p_context ctx = checkctx(L, 1);
834
835 luaL_getmetatable(L, "SSL:PSK:Registry");
836 lua_pushlightuserdata(L, (void*)ctx->context);
837 lua_pushvalue(L, 2);
838 lua_settable(L, -3);
839
840 SSL_CTX_set_psk_client_callback(ctx->context, client_psk_cb);
841
842 lua_pushboolean(L, 1);
843 return 1;
844}
845#endif
846
847#if defined(LSEC_ENABLE_DANE)
848/*
849 * DANE
850 */
851static int dane_options[] = {
852 /* TODO move into options.c
853 * however this symbol is not from openssl/ssl.h but rather from
854 * openssl/x509_vfy.h
855 * */
856#ifdef DANE_FLAG_NO_DANE_EE_NAMECHECKS
857 DANE_FLAG_NO_DANE_EE_NAMECHECKS,
858#endif
859 0
860};
861static const char *dane_option_names[] = {
862#ifdef DANE_FLAG_NO_DANE_EE_NAMECHECKS
863 "no_ee_namechecks",
864#endif
865 NULL
866};
867
868static int set_dane(lua_State *L)
869{
870 int ret, i;
871 SSL_CTX *ctx = lsec_checkcontext(L, 1);
872 ret = SSL_CTX_dane_enable(ctx);
873 for (i = 2; ret > 0 && i <= lua_gettop(L); i++) {
874 ret = SSL_CTX_dane_set_flags(ctx, dane_options[luaL_checkoption(L, i, NULL, dane_option_names)]);
875 }
876 lua_pushboolean(L, (ret > 0));
877 return 1;
878}
879#endif
880
881/**
882 * Package functions
883 */
884static luaL_Reg funcs[] = {
885 {"create", create},
886 {"locations", load_locations},
887 {"loadcert", load_cert},
888 {"loadkey", load_key},
889 {"checkkey", check_key},
890 {"setalpn", set_alpn},
891 {"setalpncb", set_alpn_cb},
892 {"setcipher", set_cipher},
893 {"setciphersuites", set_ciphersuites},
894 {"setdepth", set_depth},
895 {"setdhparam", set_dhparam},
896 {"setverify", set_verify},
897 {"setoptions", set_options},
898#if defined(LSEC_ENABLE_PSK)
899 {"setpskhint", set_psk_identity_hint},
900 {"setserverpskcb", set_server_psk_cb},
901 {"setclientpskcb", set_client_psk_cb},
902#endif
903 {"setmode", set_mode},
904#if !defined(OPENSSL_NO_EC)
905 {"setcurve", set_curve},
906 {"setcurveslist", set_curves_list},
907#endif
908#if defined(LSEC_ENABLE_DANE)
909 {"setdane", set_dane},
910#endif
911 {NULL, NULL}
912};
913
914/*-------------------------------- Metamethods -------------------------------*/
915
916/**
917 * Collect SSL context -- GC metamethod.
918 */
919static int meth_destroy(lua_State *L)
920{
921 p_context ctx = checkctx(L, 1);
922 if (ctx->context) {
923 /* Clear registries */
924 luaL_getmetatable(L, "SSL:DH:Registry");
925 lua_pushlightuserdata(L, (void*)ctx->context);
926 lua_pushnil(L);
927 lua_settable(L, -3);
928 luaL_getmetatable(L, "SSL:Verify:Registry");
929 lua_pushlightuserdata(L, (void*)ctx->context);
930 lua_pushnil(L);
931 lua_settable(L, -3);
932 luaL_getmetatable(L, "SSL:ALPN:Registry");
933 lua_pushlightuserdata(L, (void*)ctx->context);
934 lua_pushnil(L);
935 lua_settable(L, -3);
936 luaL_getmetatable(L, "SSL:PSK:Registry");
937 lua_pushlightuserdata(L, (void*)ctx->context);
938 lua_pushnil(L);
939 lua_settable(L, -3);
940
941 SSL_CTX_free(ctx->context);
942 ctx->context = NULL;
943 }
944 return 0;
945}
946
947/**
948 * Object information -- tostring metamethod.
949 */
950static int meth_tostring(lua_State *L)
951{
952 p_context ctx = checkctx(L, 1);
953 lua_pushfstring(L, "SSL context: %p", ctx);
954 return 1;
955}
956
957/**
958 * Set extra flags for handshake verification.
959 */
960static int meth_set_verify_ext(lua_State *L)
961{
962 int i;
963 const char *str;
964 int crl_flag = 0;
965 int lsec_flag = 0;
966 SSL_CTX *ctx = lsec_checkcontext(L, 1);
967 int max = lua_gettop(L);
968 for (i = 2; i <= max; i++) {
969 str = luaL_checkstring(L, i);
970 if (!strcmp(str, "lsec_continue")) {
971 lsec_flag |= LSEC_VERIFY_CONTINUE;
972 } else if (!strcmp(str, "lsec_ignore_purpose")) {
973 lsec_flag |= LSEC_VERIFY_IGNORE_PURPOSE;
974 } else if (!strcmp(str, "crl_check")) {
975 crl_flag |= X509_V_FLAG_CRL_CHECK;
976 } else if (!strcmp(str, "crl_check_chain")) {
977 crl_flag |= X509_V_FLAG_CRL_CHECK_ALL;
978 } else {
979 lua_pushboolean(L, 0);
980 lua_pushfstring(L, "invalid verify option (%s)", str);
981 return 2;
982 }
983 }
984 /* Set callback? */
985 if (lsec_flag) {
986 SSL_CTX_set_verify(ctx, SSL_CTX_get_verify_mode(ctx), verify_cb);
987 SSL_CTX_set_cert_verify_callback(ctx, cert_verify_cb, (void*)ctx);
988 /* Save flag */
989 luaL_getmetatable(L, "SSL:Verify:Registry");
990 lua_pushlightuserdata(L, (void*)ctx);
991 lua_pushnumber(L, lsec_flag);
992 lua_settable(L, -3);
993 } else {
994 SSL_CTX_set_verify(ctx, SSL_CTX_get_verify_mode(ctx), NULL);
995 SSL_CTX_set_cert_verify_callback(ctx, NULL, NULL);
996 /* Remove flag */
997 luaL_getmetatable(L, "SSL:Verify:Registry");
998 lua_pushlightuserdata(L, (void*)ctx);
999 lua_pushnil(L);
1000 lua_settable(L, -3);
1001 }
1002
1003 /* X509 flag */
1004 X509_STORE_set_flags(SSL_CTX_get_cert_store(ctx), crl_flag);
1005
1006 /* Ok */
1007 lua_pushboolean(L, 1);
1008 return 1;
1009}
1010
1011/**
1012 * Context metamethods.
1013 */
1014static luaL_Reg meta[] = {
1015 {"__close", meth_destroy},
1016 {"__gc", meth_destroy},
1017 {"__tostring", meth_tostring},
1018 {NULL, NULL}
1019};
1020
1021/**
1022 * Index metamethods.
1023 */
1024static luaL_Reg meta_index[] = {
1025 {"setverifyext", meth_set_verify_ext},
1026 {NULL, NULL}
1027};
1028
1029
1030/*----------------------------- Public Functions ---------------------------*/
1031
1032/**
1033 * Retrieve the SSL context from the Lua stack.
1034 */
1035SSL_CTX* lsec_checkcontext(lua_State *L, int idx)
1036{
1037 p_context ctx = checkctx(L, idx);
1038 return ctx->context;
1039}
1040
1041SSL_CTX* lsec_testcontext(lua_State *L, int idx)
1042{
1043 p_context ctx = testctx(L, idx);
1044 return (ctx) ? ctx->context : NULL;
1045}
1046
1047/**
1048 * Retrieve the mode from the context in the Lua stack.
1049 */
1050int lsec_getmode(lua_State *L, int idx)
1051{
1052 p_context ctx = checkctx(L, idx);
1053 return ctx->mode;
1054}
1055
1056/*-- Compat - Lua 5.1 --*/
1057#if (LUA_VERSION_NUM == 501)
1058
1059void *lsec_testudata (lua_State *L, int ud, const char *tname) {
1060 void *p = lua_touserdata(L, ud);
1061 if (p != NULL) { /* value is a userdata? */
1062 if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
1063 luaL_getmetatable(L, tname); /* get correct metatable */
1064 if (!lua_rawequal(L, -1, -2)) /* not the same? */
1065 p = NULL; /* value is a userdata with wrong metatable */
1066 lua_pop(L, 2); /* remove both metatables */
1067 return p;
1068 }
1069 }
1070 return NULL; /* value is not a userdata with a metatable */
1071}
1072
1073#endif
1074
1075/*------------------------------ Initialization ------------------------------*/
1076
1077/**
1078 * Registre the module.
1079 */
1080LSEC_API int luaopen_ssl_context(lua_State *L)
1081{
1082 luaL_newmetatable(L, "SSL:DH:Registry"); /* Keep all DH callbacks */
1083 luaL_newmetatable(L, "SSL:ALPN:Registry"); /* Keep all ALPN callbacks */
1084 luaL_newmetatable(L, "SSL:PSK:Registry"); /* Keep all PSK callbacks */
1085 luaL_newmetatable(L, "SSL:Verify:Registry"); /* Keep all verify flags */
1086 luaL_newmetatable(L, "SSL:Context");
1087 setfuncs(L, meta);
1088
1089 /* Create __index metamethods for context */
1090 luaL_newlib(L, meta_index);
1091 lua_setfield(L, -2, "__index");
1092
1093 lsec_load_curves(L);
1094
1095 /* Return the module */
1096 luaL_newlib(L, funcs);
1097
1098 return 1;
1099}