From d2c87d71f7ebb0db36a73d966384b2be2bcd6795 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 19 Apr 2014 22:58:28 +0200 Subject: [PATCH 1/4] Add cert:issued(leafcert) for checking chains --- src/x509.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/x509.c b/src/x509.c index 5e7a1dd..a71608c 100644 --- a/src/x509.c +++ b/src/x509.c @@ -393,6 +393,17 @@ static int meth_notafter(lua_State *L) return push_asn1_time(L, X509_get_notAfter(cert)); } +/** + * Check if this certificate issued some other certificate + */ +static int meth_issued(lua_State *L) +{ + X509* issuer = lsec_checkx509(L, 1); + X509* subject = lsec_checkx509(L, 2); + lua_pushboolean(L, X509_check_issued(issuer, subject) == X509_V_OK); + return 1; +} + /** * Collect X509 objects. */ @@ -459,6 +470,7 @@ static luaL_Reg methods[] = { {"issuer", meth_issuer}, {"notbefore", meth_notbefore}, {"notafter", meth_notafter}, + {"issued", meth_issued}, {"pem", meth_pem}, {"serial", meth_serial}, {"subject", meth_subject}, From 97e836696be2b8aef3531d5e58cf72c4080f04ce Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 22 Apr 2014 01:17:34 +0200 Subject: [PATCH 2/4] Return human readable error message from cert:issued() --- src/x509.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/x509.c b/src/x509.c index a71608c..7e1550f 100644 --- a/src/x509.c +++ b/src/x509.c @@ -400,8 +400,13 @@ static int meth_issued(lua_State *L) { X509* issuer = lsec_checkx509(L, 1); X509* subject = lsec_checkx509(L, 2); - lua_pushboolean(L, X509_check_issued(issuer, subject) == X509_V_OK); - return 1; + int ret = X509_check_issued(issuer, subject); + lua_pushboolean(L, ret == X509_V_OK); + if (ret != X509_V_OK) { + lua_pushstring(L, X509_verify_cert_error_string(ret)); + return 2; + } + return 1; } /** From aa0c7ea1e5ab12362a09e896282bb67b21939ed5 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 20 Mar 2015 16:36:05 +0100 Subject: [PATCH 3/4] Validate signatures too. API changes to root:issued([intermediate]*, cert) --- src/x509.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 74 insertions(+), 8 deletions(-) diff --git a/src/x509.c b/src/x509.c index 7e1550f..e141252 100644 --- a/src/x509.c +++ b/src/x509.c @@ -6,6 +6,7 @@ * *--------------------------------------------------------------------------*/ +#include #include #if defined(WIN32) @@ -396,17 +397,82 @@ static int meth_notafter(lua_State *L) /** * Check if this certificate issued some other certificate */ -static int meth_issued(lua_State *L) +static int meth_issued(lua_State* L) { + int ret, i, len; + + X509_STORE_CTX* ctx = NULL; + X509_STORE* root = NULL; + STACK_OF(X509)* chain = sk_X509_new_null(); + X509* issuer = lsec_checkx509(L, 1); - X509* subject = lsec_checkx509(L, 2); - int ret = X509_check_issued(issuer, subject); - lua_pushboolean(L, ret == X509_V_OK); - if (ret != X509_V_OK) { - lua_pushstring(L, X509_verify_cert_error_string(ret)); - return 2; + X509* subject; + + ctx = X509_STORE_CTX_new(); + root = X509_STORE_new(); + + len = lua_gettop(L); + /* fprintf(stderr, "len = %d\n", len); */ + + if (ctx == NULL || root == NULL) { + lua_pushnil(L); + lua_pushstring(L, "X509_STORE_new() or X509_STORE_CTX_new() error"); + ret = 2; + goto cleanup; } - return 1; + + ret = X509_STORE_add_cert(root, issuer); + + if(!ret) { + lua_pushnil(L); + lua_pushstring(L, "X509_STORE_add_cert() error"); + ret = 2; + goto cleanup; + } + + for (i = 2; i < len && lua_isuserdata(L, i); i++) { + /* fprintf(stderr, "i = %d\n", i); */ + /* FIXME Don't leak stuff if it's wrong */ + subject = lsec_checkx509(L, i); + sk_X509_push(chain, subject); + issuer = subject; + } + + subject = lsec_checkx509(L, len); + + ret = X509_STORE_CTX_init(ctx, root, subject, chain); + + if(!ret) { + lua_pushnil(L); + lua_pushstring(L, "X509_STORE_CTX_init() error"); + ret = 2; + goto cleanup; + } + + /* Actual verification */ + if (X509_verify_cert(ctx) <= 0) { + ret = X509_STORE_CTX_get_error(ctx); + lua_pushnil(L); + lua_pushstring(L, X509_verify_cert_error_string(ret)); + ret = 2; + } else { + lua_pushboolean(L, 1); + ret = 1; + } + +cleanup: + + if (ctx != NULL) { + X509_STORE_CTX_free(ctx); + } + + if (chain != NULL) { + X509_STORE_free(root); + } + + sk_X509_free(chain); + + return ret; } /** From 4e59c719dfcf740134959722a601422ad8c834b0 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 31 Mar 2015 17:48:44 +0200 Subject: [PATCH 4/4] Perform all validation before allocating structures Check that all arguments are certificates before allocating OpenSSL structures that require cleanup afterwards. API of issued() changes (again) to root:issued(cert, [chain]*) --- src/x509.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/x509.c b/src/x509.c index e141252..c030927 100644 --- a/src/x509.c +++ b/src/x509.c @@ -403,16 +403,25 @@ static int meth_issued(lua_State* L) X509_STORE_CTX* ctx = NULL; X509_STORE* root = NULL; - STACK_OF(X509)* chain = sk_X509_new_null(); + STACK_OF(X509)* chain = NULL; X509* issuer = lsec_checkx509(L, 1); - X509* subject; - - ctx = X509_STORE_CTX_new(); - root = X509_STORE_new(); + X509* subject = lsec_checkx509(L, 2); + X509* cert = NULL; len = lua_gettop(L); - /* fprintf(stderr, "len = %d\n", len); */ + + /* Check that all arguments are certificates */ + + for (i = 3; i <= len; i++) { + lsec_checkx509(L, i); + } + + /* Before allocating things that require freeing afterwards */ + + chain = sk_X509_new_null(); + ctx = X509_STORE_CTX_new(); + root = X509_STORE_new(); if (ctx == NULL || root == NULL) { lua_pushnil(L); @@ -430,16 +439,11 @@ static int meth_issued(lua_State* L) goto cleanup; } - for (i = 2; i < len && lua_isuserdata(L, i); i++) { - /* fprintf(stderr, "i = %d\n", i); */ - /* FIXME Don't leak stuff if it's wrong */ - subject = lsec_checkx509(L, i); - sk_X509_push(chain, subject); - issuer = subject; + for (i = 3; i <= len && lua_isuserdata(L, i); i++) { + cert = lsec_checkx509(L, i); + sk_X509_push(chain, cert); } - subject = lsec_checkx509(L, len); - ret = X509_STORE_CTX_init(ctx, root, subject, chain); if(!ret) { @@ -470,7 +474,7 @@ cleanup: X509_STORE_free(root); } - sk_X509_free(chain); + sk_X509_free(chain); return ret; }