src/context.c

changeset 34
510432315106
parent 30
36ed99e1ce1e
child 36
96f23601ce7a
--- 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;

mercurial