--- a/src/context.c Sat Nov 20 20:04:11 2010 -0800 +++ b/src/context.c Sun Nov 21 20:14:31 2010 -0800 @@ -19,6 +19,8 @@ }; typedef struct ssl_option_s ssl_option_t; +int luasec_ssl_idx = -1; + /* The export DH key */ static DH *dh_512 = NULL; /* The larger key (builtin is 2048, caller may specify larger) */ @@ -107,7 +109,7 @@ /** * Return the context. */ -static p_context checkctx(lua_State *L, int idx) +p_context checkctx(lua_State *L, int idx) { return (p_context)luaL_checkudata(L, idx, "SSL:Context"); } @@ -243,6 +245,7 @@ lua_pushstring(L, "error creating context"); return 2; } + ctx->verify_flags = LUASEC_VERIFY_FLAGS_NONE; ctx->mode = MD_CTX_INVALID; /* No session support */ SSL_CTX_set_session_cache_mode(ctx->context, SSL_SESS_CACHE_OFF); @@ -389,7 +392,29 @@ int verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx) { - return 1; + SSL *ssl; + p_context ctx = NULL; + + /* Short-circuit optimization */ + if (preverify_ok) + return 1; + + ssl = X509_STORE_CTX_get_ex_data(x509_ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); + ctx = SSL_get_ex_data(ssl, luasec_ssl_idx); + + if (ctx->verify_flags & LUASEC_VERIFY_FLAGS_IGNORE_PURPOSE) { + int err, depth; + + err = X509_STORE_CTX_get_error(x509_ctx); + depth = X509_STORE_CTX_get_error_depth(x509_ctx); + + if (depth == 0 && err == X509_V_ERR_INVALID_PURPOSE) { + /* You see nothing! */ + X509_STORE_CTX_set_error(x509_ctx, X509_V_OK); + preverify_ok = 1; + } + } + return (ctx->verify_flags & LUASEC_VERIFY_FLAGS_ALWAYS_CONTINUE ? 1 : preverify_ok); } /** @@ -400,21 +425,25 @@ int i; int flag = 0; int ignore_errors = 0; - SSL_CTX *ctx = ctx_getcontext(L, 1); + p_context ctx = checkctx(L, 1); int max = lua_gettop(L); /* any flag? */ if (max > 1) { + ctx->verify_flags = LUASEC_VERIFY_FLAGS_NONE; for (i = 2; i <= max; i++) { const char *s = luaL_checkstring(L, i); if (!strcmp(s, "continue")) { + ctx->verify_flags |= LUASEC_VERIFY_FLAGS_ALWAYS_CONTINUE; ignore_errors = 1; + } else if (!strcmp(s, "ignore_purpose")) { + ctx->verify_flags |= LUASEC_VERIFY_FLAGS_IGNORE_PURPOSE; } else if (!set_verify_flag(s, &flag)) { lua_pushboolean(L, 0); lua_pushstring(L, "invalid verify option"); return 2; } } - SSL_CTX_set_verify(ctx, flag, ignore_errors ? verify_cb : NULL); + SSL_CTX_set_verify(ctx->context, flag, ctx->verify_flags ? verify_cb : NULL); } lua_pushboolean(L, 1); return 1;