# HG changeset patch # User Paul Aurich # Date 1290399271 28800 # Node ID 5104323151064dde68603db1904ddd4dcb450911 # Parent cc36229b3be1f1271bda0e7989da51017695fc4d verify: Flag to ignore 'invalid purpose' errors on end cert diff -r cc36229b3be1 -r 510432315106 src/context.c --- 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; diff -r cc36229b3be1 -r 510432315106 src/context.h --- a/src/context.h Sat Nov 20 20:04:11 2010 -0800 +++ b/src/context.h Sun Nov 21 20:14:31 2010 -0800 @@ -20,12 +20,23 @@ #define MD_CTX_SERVER 1 #define MD_CTX_CLIENT 2 +#define LUASEC_VERIFY_FLAGS_NONE 0x0000 +#define LUASEC_VERIFY_FLAGS_ALWAYS_CONTINUE 0x0001 +#define LUASEC_VERIFY_FLAGS_IGNORE_PURPOSE 0x0002 + typedef struct t_context_ { SSL_CTX *context; + unsigned int verify_flags; char mode; } t_context; typedef t_context* p_context; +/* index into the SSL storage where the context is. + * see SSL_get_ex_data(). + */ +extern int luasec_ssl_idx; + +p_context checkctx(lua_State *L, int idx); /* Retrieve the SSL context from the Lua stack */ SSL_CTX *ctx_getcontext(lua_State *L, int idx); /* Retrieve the mode from the context in the Lua stack */ diff -r cc36229b3be1 -r 510432315106 src/ssl.c --- a/src/ssl.c Sat Nov 20 20:04:11 2010 -0800 +++ b/src/ssl.c Sun Nov 21 20:14:31 2010 -0800 @@ -209,20 +209,28 @@ { p_ssl ssl; int mode = ctx_getmode(L, 1); - SSL_CTX *ctx = ctx_getcontext(L, 1); + p_context ctx = checkctx(L, 1); if (mode == MD_CTX_INVALID) { lua_pushnil(L); lua_pushstring(L, "invalid mode"); return 2; } + if (luasec_ssl_idx == -1) { + luasec_ssl_idx = SSL_get_ex_new_index(0, "luasec context", NULL, NULL, NULL); + if (luasec_ssl_idx == -1) { + lua_pushnil(L); + lua_pushstring(L, "error creating luasec SSL index"); + return 2; + } + } ssl = (p_ssl) lua_newuserdata(L, sizeof(t_ssl)); if (!ssl) { lua_pushnil(L); lua_pushstring(L, "error creating SSL object"); return 2; } - ssl->ssl = SSL_new(ctx); + ssl->ssl = SSL_new(ctx->context); if (!ssl->ssl) { lua_pushnil(L); lua_pushstring(L, "error creating SSL object"); @@ -237,6 +245,8 @@ SSL_set_mode(ssl->ssl, SSL_MODE_RELEASE_BUFFERS); #endif + SSL_set_ex_data(ssl->ssl, luasec_ssl_idx, ctx); + if (mode == MD_CTX_SERVER) SSL_set_accept_state(ssl->ssl); else