From 85bcdb001a5d65ed32087b23ebd802ddba470088 Mon Sep 17 00:00:00 2001 From: Ash Berlin Date: Sat, 9 Apr 2016 18:37:05 +0100 Subject: Add terminator to openssl.x509.extension. Without this we ended up over-running the buffer and setting functions as numbers again. Before: $ lua -e 'print(require "openssl.x509.extension".new)' 4519558960 After: $ lua -e 'print(require "openssl.x509.extension".new)' function: 0x10f9755e0 --- src/openssl.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/openssl.c') diff --git a/src/openssl.c b/src/openssl.c index 11d02a0..2893d04 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -4328,6 +4328,7 @@ static const auxL_IntegerReg xe_textopts[] = { { "ERROR_UNKNOWN", X509V3_EXT_ERROR_UNKNOWN }, { "PARSE_UNKNOWN", X509V3_EXT_PARSE_UNKNOWN }, { "DUMP_UNKNOWN", X509V3_EXT_DUMP_UNKNOWN }, + { NULL, 0 }, }; int luaopen__openssl_x509_extension(lua_State *L) { -- cgit v1.2.3-59-g8ed1b From 36277465de786618aa94bc2d33c0ffce5e2102a3 Mon Sep 17 00:00:00 2001 From: Ash Berlin Date: Sun, 10 Apr 2016 22:15:33 +0100 Subject: Support for getting and setting SAN on a CSR Extensions in a CSR are a bit more complex than in a CRL or a certificate itself so we don't quite use the same interface. --- doc/luaossl.tex | 8 ++++++ src/openssl.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) (limited to 'src/openssl.c') diff --git a/doc/luaossl.tex b/doc/luaossl.tex index 433dd03..7db7463 100644 --- a/doc/luaossl.tex +++ b/doc/luaossl.tex @@ -597,6 +597,14 @@ Returns the subject distinguished name as an \module{x509.name} object. Sets the subject distinguished name. $name$ should be an \module{x509.name} object. +\subsubsection[\fn{csr:getSubjectAlt}]{\fn{csr:getSubjectAlt()}} + +Returns the subject alternative name as an \module{x509.altname} object. + +\subsubsection[\fn{csr:setSubjectAlt}]{\fn{csr:setSubjectAlt($name$)}} + +Sets the subject alternative names. $name$ should be an \module{x509.altname} object. + \subsubsection[\fn{csr:getPublicKey}]{\fn{csr:getPublicKey()}} Returns the public key component as an \module{openssl.pkey} object. diff --git a/src/openssl.c b/src/openssl.c index 2893d04..f8c5047 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -5488,6 +5488,85 @@ static int xr_setPublicKey(lua_State *L) { } /* xr_setPublicKey() */ +static int xr_setExtensionByNid(lua_State *L, X509_REQ *csr, int target_nid, void* value) { + STACK_OF(X509_EXTENSION) *sk = NULL; + X509_ATTRIBUTE *attr; + int has_attrs=0, idx, *pnid; + + // Replace existing if it's there. Extensions are stored in a CSR in an interesting way: + // + // They are stored as a list under either (most likely) the "official" + // NID_ext_req or under NID_ms_ext_req which means everything is stored + // under a list in a single "attribute" so we can't use X509_REQ_add1_attr + // or similar. + // + // Instead we have to get the extensions, find and replace the SAN if it's + // in there, then *replace* the extensions in the list of attributes. (If + // we just try to add it the old ones are found first and don't take + // priority) + + has_attrs = X509_REQ_get_attr_count(csr); + sk = X509_REQ_get_extensions(csr); + + if (!X509V3_add1_i2d(&sk, target_nid, value, 0, X509V3_ADD_REPLACE)) + goto error; + + if (X509_REQ_add_extensions(csr, sk) == 0) + goto error; + + // Delete the old extensions attribute, so that the one we just added takes priority + if (has_attrs) { + for (pnid = X509_REQ_get_extension_nids(); *pnid != NID_undef; pnid++) { + idx = X509_REQ_get_attr_by_NID(csr, *pnid, -1); + if (idx == -1) + continue; + if (!(attr = X509_REQ_delete_attr(csr, idx))) + goto error; + X509_ATTRIBUTE_free(attr); + break; + } + if (!attr) + goto error; + } + + // We have to mark the encoded form as invalid, otherwise when we write it + // out again it will use the loaded version + csr->req_info->enc.modified = 1; + + sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free); + lua_pushboolean(L, 1); + return 1; +error: + if (sk) + sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free); + return auxL_error(L, auxL_EOPENSSL, "x509.csr.setExtensionByNid"); +} /* xr_setExtensionByNid() */ + + +static int xr_setSubjectAlt(lua_State *L) { + X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); + GENERAL_NAMES *gens = checksimple(L, 2, X509_GENS_CLASS); + return xr_setExtensionByNid(L, csr, NID_subject_alt_name, gens); +} /* xr_setSubjectAlt */ + + +static int xr_getSubjectAlt(lua_State *L) { + X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); + GENERAL_NAMES *gens; + STACK_OF(X509_EXTENSION) *exts = X509_REQ_get_extensions(csr); + + gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL); + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); + if (!gens) goto error; + + gn_dup(L, gens); + return 1; +error: + return 0; +} /* xr_getSubjectAlt() */ + + + static int xr_sign(lua_State *L) { X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS); @@ -5545,6 +5624,8 @@ static const auxL_Reg xr_methods[] = { { "setSubject", &xr_setSubject }, { "getPublicKey", &xr_getPublicKey }, { "setPublicKey", &xr_setPublicKey }, + { "getSubjectAlt", &xr_getSubjectAlt }, + { "setSubjectAlt", &xr_setSubjectAlt }, { "sign", &xr_sign }, { "tostring", &xr__tostring }, { NULL, NULL }, -- cgit v1.2.3-59-g8ed1b From 82b9b3af389b70ed38963ca8d6e2aa9f69b16450 Mon Sep 17 00:00:00 2001 From: William Ahern Date: Thu, 23 Jun 2016 10:49:27 -0700 Subject: initialize attr to NULL in xr_setExtensionByNid to silence clang, which can't see that has_attrs indirectly assures at least one iteration of the for loop (in the single-threaded case, at least) --- src/openssl.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/openssl.c') diff --git a/src/openssl.c b/src/openssl.c index f8c5047..6b74025 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -5516,6 +5516,7 @@ static int xr_setExtensionByNid(lua_State *L, X509_REQ *csr, int target_nid, voi // Delete the old extensions attribute, so that the one we just added takes priority if (has_attrs) { + attr = NULL; for (pnid = X509_REQ_get_extension_nids(); *pnid != NID_undef; pnid++) { idx = X509_REQ_get_attr_by_NID(csr, *pnid, -1); if (idx == -1) -- cgit v1.2.3-59-g8ed1b From bddd9f5a79ae4aea43d7dca09157c53e40503bfb Mon Sep 17 00:00:00 2001 From: William Ahern Date: Fri, 24 Jun 2016 19:10:40 -0700 Subject: refactor style to more closely match the style of the existing code, such as it is --- src/openssl.c | 57 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 22 deletions(-) (limited to 'src/openssl.c') diff --git a/src/openssl.c b/src/openssl.c index 6b74025..9c40e57 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -5490,33 +5490,40 @@ static int xr_setPublicKey(lua_State *L) { static int xr_setExtensionByNid(lua_State *L, X509_REQ *csr, int target_nid, void* value) { STACK_OF(X509_EXTENSION) *sk = NULL; - X509_ATTRIBUTE *attr; - int has_attrs=0, idx, *pnid; - - // Replace existing if it's there. Extensions are stored in a CSR in an interesting way: - // - // They are stored as a list under either (most likely) the "official" - // NID_ext_req or under NID_ms_ext_req which means everything is stored - // under a list in a single "attribute" so we can't use X509_REQ_add1_attr - // or similar. - // - // Instead we have to get the extensions, find and replace the SAN if it's - // in there, then *replace* the extensions in the list of attributes. (If - // we just try to add it the old ones are found first and don't take - // priority) + int has_attrs=0; + /* + * Replace existing if it's there. Extensions are stored in a CSR in + * an interesting way: + * + * They are stored as a list under either (most likely) the + * "official" NID_ext_req or under NID_ms_ext_req which means + * everything is stored under a list in a single "attribute" so we + * can't use X509_REQ_add1_attr or similar. + * + * Instead we have to get the extensions, find and replace the SAN + * if it's in there, then *replace* the extensions in the list of + * attributes. (If we just try to add it the old ones are found + * first and don't take priority.) + */ has_attrs = X509_REQ_get_attr_count(csr); - sk = X509_REQ_get_extensions(csr); + sk = X509_REQ_get_extensions(csr); if (!X509V3_add1_i2d(&sk, target_nid, value, 0, X509V3_ADD_REPLACE)) goto error; - if (X509_REQ_add_extensions(csr, sk) == 0) goto error; + sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free); + sk = NULL; - // Delete the old extensions attribute, so that the one we just added takes priority + /* + * Delete the old extensions attribute, so that the one we just + * added takes priority. + */ if (has_attrs) { - attr = NULL; + X509_ATTRIBUTE *attr = NULL; + int idx, *pnid; + for (pnid = X509_REQ_get_extension_nids(); *pnid != NID_undef; pnid++) { idx = X509_REQ_get_attr_by_NID(csr, *pnid, -1); if (idx == -1) @@ -5530,16 +5537,19 @@ static int xr_setExtensionByNid(lua_State *L, X509_REQ *csr, int target_nid, voi goto error; } - // We have to mark the encoded form as invalid, otherwise when we write it - // out again it will use the loaded version + /* + * We have to mark the encoded form as invalid, otherwise when we + * write it out again it will use the loaded version. + */ csr->req_info->enc.modified = 1; - sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free); lua_pushboolean(L, 1); + return 1; error: if (sk) sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free); + return auxL_error(L, auxL_EOPENSSL, "x509.csr.setExtensionByNid"); } /* xr_setExtensionByNid() */ @@ -5547,20 +5557,23 @@ error: static int xr_setSubjectAlt(lua_State *L) { X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); GENERAL_NAMES *gens = checksimple(L, 2, X509_GENS_CLASS); + return xr_setExtensionByNid(L, csr, NID_subject_alt_name, gens); } /* xr_setSubjectAlt */ static int xr_getSubjectAlt(lua_State *L) { X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); + STACK_OF(X509_EXTENSION) *exts; GENERAL_NAMES *gens; - STACK_OF(X509_EXTENSION) *exts = X509_REQ_get_extensions(csr); + exts = X509_REQ_get_extensions(csr); gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL); sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); if (!gens) goto error; gn_dup(L, gens); + return 1; error: return 0; -- cgit v1.2.3-59-g8ed1b