diff --git a/nse_ssl_cert.cc b/nse_ssl_cert.cc index 9582c2150..50a8d0a3c 100644 --- a/nse_ssl_cert.cc +++ b/nse_ssl_cert.cc @@ -137,6 +137,7 @@ #include #include #include +#include #include #include @@ -271,6 +272,54 @@ static void x509_name_to_table(lua_State *L, X509_NAME *name) } } +static bool x509_extensions_to_table(lua_State *L, const STACK_OF(X509_EXTENSION) *exts) +{ + if (sk_X509_EXTENSION_num(exts) <= 0) + return false; + + lua_newtable(L); + + for (int i = 0; i < sk_X509_EXTENSION_num(exts); i++) { + ASN1_OBJECT *obj; + X509_EXTENSION *ext; + char *value = NULL; + BIO *out; + + ext = sk_X509_EXTENSION_value(exts, i); + obj = X509_EXTENSION_get_object(ext); + + lua_newtable(L); + char objname[256]; + long len = 0; + len = OBJ_obj2txt(objname, 256, obj, 0); + lua_pushlstring(L, objname, MIN(len, 256)); + lua_setfield(L, -2, "name"); + + + if (X509_EXTENSION_get_critical(ext)) { + lua_pushboolean(L, true); + lua_setfield(L, -2, "critical"); + } + + out = BIO_new(BIO_s_mem()); + if (!X509V3_EXT_print(out, ext, 0, 0)) { + lua_pushboolean(L, true); + lua_setfield(L, -2, "error"); + } + else { + len = BIO_get_mem_data(out, &value); + lua_pushlstring(L, value, len); + lua_setfield(L, -2, "value"); + } + BIO_free_all(out); + + lua_seti(L, -2, i+1); + } + + return true; + +} + /* Parse as a decimal integer the len characters starting at s. This function can only process positive numbers; if the return value is negative then a parsing error occurred. */ @@ -559,6 +608,14 @@ static int parse_ssl_cert(lua_State *L, X509 *cert) cert_pem_to_string(L, cert); lua_setfield(L, -2, "pem"); +#if HAVE_OPAQUE_STRUCTS + if (x509_extensions_to_table(L, X509_get0_extensions(cert))) { +#else + if (x509_extensions_to_table(L, cert->cert_info->extensions)) { +#endif + lua_setfield(L, -2, "extensions"); + } + pubkey = X509_get_pubkey(cert); if (pubkey == NULL) { lua_pushnil(L); diff --git a/scripts/ssl-cert.nse b/scripts/ssl-cert.nse index e0e6ef34c..d67efc9b5 100644 --- a/scripts/ssl-cert.nse +++ b/scripts/ssl-cert.nse @@ -208,6 +208,7 @@ local function output_tab(cert) o.subject = name_to_table(cert.subject) o.issuer = name_to_table(cert.issuer) o.pubkey = cert.pubkey + o.extensions = cert.extensions o.sig_algo = cert.sig_algorithm o.validity = {} for k, v in pairs(cert.validity) do @@ -227,6 +228,14 @@ local function output_str(cert) local lines = {} lines[#lines + 1] = "Subject: " .. stringify_name(cert.subject) + if cert.extensions then + for _, e in ipairs(cert.extensions) do + if e.name == "X509v3 Subject Alternative Name" then + lines[#lines + 1] = "Subject Alternative Name: " .. e.value + break + end + end + end if nmap.verbosity() > 0 then lines[#lines + 1] = "Issuer: " .. stringify_name(cert.issuer)