src/context.c

changeset 41
e26f1f91118a
parent 38
4ecd7b0e67ea
child 42
b6271d3bae0b
equal deleted inserted replaced
40:85d59ac3328b 41:e26f1f91118a
5 *--------------------------------------------------------------------------*/ 5 *--------------------------------------------------------------------------*/
6 6
7 #include <string.h> 7 #include <string.h>
8 #include <openssl/ssl.h> 8 #include <openssl/ssl.h>
9 #include <openssl/err.h> 9 #include <openssl/err.h>
10 #include <openssl/x509.h>
11 #include <openssl/x509v3.h>
10 12
11 #include <lua.h> 13 #include <lua.h>
12 #include <lauxlib.h> 14 #include <lauxlib.h>
13 15
14 #include "context.h" 16 #include "context.h"
17 #include "ssl.h"
15 18
16 struct ssl_option_s { 19 struct ssl_option_s {
17 const char *name; 20 const char *name;
18 unsigned long code; 21 unsigned long code;
19 }; 22 };
247 ctx = (p_context) lua_newuserdata(L, sizeof(t_context)); 250 ctx = (p_context) lua_newuserdata(L, sizeof(t_context));
248 if (!ctx) { 251 if (!ctx) {
249 lua_pushnil(L); 252 lua_pushnil(L);
250 lua_pushstring(L, "error creating context"); 253 lua_pushstring(L, "error creating context");
251 return 2; 254 return 2;
252 } 255 }
256 ctx->L = L;
253 ctx->context = SSL_CTX_new(method); 257 ctx->context = SSL_CTX_new(method);
254 if (!ctx->context) { 258 if (!ctx->context) {
255 lua_pushnil(L); 259 lua_pushnil(L);
256 lua_pushstring(L, "error creating context"); 260 lua_pushstring(L, "error creating context");
257 return 2; 261 return 2;
401 SSL_CTX_set_verify_depth(ctx, luaL_checkint(L, 2)); 405 SSL_CTX_set_verify_depth(ctx, luaL_checkint(L, 2));
402 lua_pushboolean(L, 1); 406 lua_pushboolean(L, 1);
403 return 1; 407 return 1;
404 } 408 }
405 409
410 static void
411 luasec_push_cert_error(lua_State *L, int ref, int depth, int err)
412 {
413 int created = 0;
414
415 lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
416 lua_rawgeti(L, -1, depth + 1);
417 if (!lua_istable(L, -1)) {
418 /* If the table doesn't exist, create it */
419 created = 1;
420 lua_pop(L, 1);
421 lua_newtable(L);
422 }
423
424 lua_pushstring(L, X509_verify_cert_error_string(err));
425 lua_rawseti(L, -2, lua_objlen(L, -2)+1);
426
427 if (created) {
428 lua_rawseti(L, -2, depth + 1);
429 lua_pop(L, 1);
430 } else
431 lua_pop(L, 2);
432 }
433
406 int verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx) 434 int verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
407 { 435 {
408 SSL_CTX *context; 436 SSL_CTX *context;
409 SSL *ssl; 437 SSL *ssl;
410 p_context l_ctx; 438 p_context l_ctx;
439 p_ssl l_ssl;
440 int err, depth;
411 441
412 /* Short-circuit optimization */ 442 /* Short-circuit optimization */
413 if (preverify_ok) 443 if (preverify_ok)
414 return 1; 444 return 1;
415 445
416 ssl = X509_STORE_CTX_get_ex_data(x509_ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); 446 ssl = X509_STORE_CTX_get_ex_data(x509_ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
417 context = ssl->ctx; 447 context = ssl->ctx;
448 l_ssl = SSL_get_ex_data(ssl, luasec_ssl_idx);
418 l_ctx = SSL_CTX_get_ex_data(context, luasec_sslctx_idx); 449 l_ctx = SSL_CTX_get_ex_data(context, luasec_sslctx_idx);
419 450
420 if (l_ctx->verify_flags & LUASEC_VERIFY_FLAGS_IGNORE_PURPOSE) { 451 err = X509_STORE_CTX_get_error(x509_ctx);
421 int err, depth; 452 depth = X509_STORE_CTX_get_error_depth(x509_ctx);
422 453
423 err = X509_STORE_CTX_get_error(x509_ctx); 454 if (err != X509_V_OK) {
424 depth = X509_STORE_CTX_get_error_depth(x509_ctx); 455 if (l_ssl->t_cert_errors == LUA_NOREF) {
425 456 lua_newtable(l_ctx->L);
426 if (depth == 0 && err == X509_V_ERR_INVALID_PURPOSE) { 457 l_ssl->t_cert_errors = luaL_ref(l_ctx->L, LUA_REGISTRYINDEX);
427 /* You see nothing! */ 458 }
428 X509_STORE_CTX_set_error(x509_ctx, X509_V_OK); 459
429 preverify_ok = 1; 460 luasec_push_cert_error(l_ctx->L, l_ssl->t_cert_errors, depth, err);
430 } 461 }
431 } 462
432 return (l_ctx->verify_flags & LUASEC_VERIFY_FLAGS_ALWAYS_CONTINUE ? 1 : preverify_ok); 463 return (l_ctx->verify_flags & LUASEC_VERIFY_FLAGS_ALWAYS_CONTINUE ? 1 : preverify_ok);
464 }
465
466 static int luasec_verify(X509_STORE_CTX *x509_ctx, void *ptr)
467 {
468 p_context ctx = ptr;
469
470 if (ctx->verify_flags & LUASEC_VERIFY_FLAGS_IGNORE_PURPOSE) {
471 X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(x509_ctx);
472 if (param) {
473 X509_VERIFY_PARAM_set_purpose(param, X509_PURPOSE_SSL_SERVER);
474 X509_VERIFY_PARAM_set_trust(param, X509_TRUST_SSL_SERVER);
475 }
476 }
477
478 return X509_verify_cert(x509_ctx);
433 } 479 }
434 480
435 /** 481 /**
436 * Set the handshake verify options. 482 * Set the handshake verify options.
437 */ 483 */
461 lua_pushstring(L, "invalid verify option"); 507 lua_pushstring(L, "invalid verify option");
462 return 2; 508 return 2;
463 } 509 }
464 } 510 }
465 SSL_CTX_set_verify(ctx->context, flag, ctx->verify_flags ? verify_cb : NULL); 511 SSL_CTX_set_verify(ctx->context, flag, ctx->verify_flags ? verify_cb : NULL);
512 SSL_CTX_set_cert_verify_callback(ctx->context, luasec_verify, ctx);
466 if(vflag) 513 if(vflag)
467 { 514 {
468 X509_STORE *store = SSL_CTX_get_cert_store(ctx->context); 515 X509_STORE *store = SSL_CTX_get_cert_store(ctx->context);
469 X509_STORE_set_flags(store, vflag); 516 X509_STORE_set_flags(store, vflag);
470 } 517 }

mercurial