From ce504d35545106ad7bb64ef73cd6538f71b868e3 Mon Sep 17 00:00:00 2001 From: Bruno Silvestre Date: Wed, 23 Oct 2013 13:42:34 -0200 Subject: [PATCH] Add x509:setencode() function to change the encode of ASN.1 string. --- src/x509.c | 71 +++++++++++++++++++++++++++++++++++++++++++----------- src/x509.h | 4 +++ 2 files changed, 61 insertions(+), 14 deletions(-) diff --git a/src/x509.c b/src/x509.c index 104cfd3..5502972 100644 --- a/src/x509.c +++ b/src/x509.c @@ -32,6 +32,7 @@ void lsec_pushx509(lua_State* L, X509 *cert) { p_x509 cert_obj = (p_x509)lua_newuserdata(L, sizeof(t_x509)); cert_obj->cert = cert; + cert_obj->encode = LSEC_AI5_STRING; luaL_getmetatable(L, "SSL:Certificate"); lua_setmetatable(L, -2); } @@ -44,6 +45,14 @@ X509* lsec_checkx509(lua_State* L, int idx) return ((p_x509)luaL_checkudata(L, idx, "SSL:Certificate"))->cert; } +/** + * Return LuaSec certificate X509 representation. + */ +p_x509 lsec_checkp_x509(lua_State* L, int idx) +{ + return (p_x509)luaL_checkudata(L, idx, "SSL:Certificate"); +} + /*---------------------------------------------------------------------------*/ /** @@ -73,13 +82,24 @@ static void push_asn1_objname(lua_State* L, ASN1_OBJECT *object, int no_name) /** * Push the ASN1 string on the stack. */ -static void push_asn1_string(lua_State* L, ASN1_STRING *string) +static void push_asn1_string(lua_State* L, ASN1_STRING *string, int encode) { - if (string) + size_t len; + unsigned char *data; + if (!string) + lua_pushnil(L); + switch (encode) { + case LSEC_AI5_STRING: lua_pushlstring(L, (char*)ASN1_STRING_data(string), ASN1_STRING_length(string)); - else - lua_pushnil(L); + break; + case LSEC_UTF8_STRING: + len = ASN1_STRING_to_UTF8(&data, string); + if (len >= 0) { + lua_pushlstring(L, (char*)data, len); + OPENSSL_free(data); + } + } } /** @@ -120,7 +140,7 @@ static int push_subtable(lua_State* L, int idx) /** * Retrive the general names from the object. */ -static int push_x509_name(lua_State* L, X509_NAME *name) +static int push_x509_name(lua_State* L, X509_NAME *name, int encode) { int i; int n_entries; @@ -136,7 +156,7 @@ static int push_x509_name(lua_State* L, X509_NAME *name) lua_setfield(L, -2, "oid"); push_asn1_objname(L, object, 0); lua_setfield(L, -2, "name"); - push_asn1_string(L, X509_NAME_ENTRY_get_data(entry)); + push_asn1_string(L, X509_NAME_ENTRY_get_data(entry), encode); lua_setfield(L, -2, "value"); lua_rawseti(L, -2, i+1); } @@ -150,7 +170,8 @@ static int push_x509_name(lua_State* L, X509_NAME *name) */ static int meth_subject(lua_State* L) { - return push_x509_name(L, X509_get_subject_name(lsec_checkx509(L, 1))); + p_x509 px = lsec_checkp_x509(L, 1); + return push_x509_name(L, X509_get_subject_name(px->cert), px->encode); } /** @@ -158,7 +179,8 @@ static int meth_subject(lua_State* L) */ static int meth_issuer(lua_State* L) { - return push_x509_name(L, X509_get_issuer_name(lsec_checkx509(L, 1))); + p_x509 px = lsec_checkp_x509(L, 1); + return push_x509_name(L, X509_get_issuer_name(px->cert), px->encode); } /** @@ -173,7 +195,8 @@ int meth_extensions(lua_State* L) X509_EXTENSION *extension; GENERAL_NAME *general_name; STACK_OF(GENERAL_NAME) *values; - X509 *peer = lsec_checkx509(L, 1); + p_x509 px = lsec_checkp_x509(L, 1); + X509 *peer = px->cert; /* Return (ret) */ lua_newtable(L); @@ -205,35 +228,35 @@ int meth_extensions(lua_State* L) push_asn1_objname(L, otherName->type_id, 0); lua_setfield(L, -2, "name"); } - push_asn1_string(L, otherName->value->value.asn1_string); + push_asn1_string(L, otherName->value->value.asn1_string, px->encode); lua_rawseti(L, -2, lua_rawlen(L, -2) + 1); lua_pop(L, 1); break; case GEN_DNS: lua_pushstring(L, "dNSName"); push_subtable(L, -2); - push_asn1_string(L, general_name->d.dNSName); + push_asn1_string(L, general_name->d.dNSName, px->encode); lua_rawseti(L, -2, lua_rawlen(L, -2) + 1); lua_pop(L, 1); break; case GEN_EMAIL: lua_pushstring(L, "rfc822Name"); push_subtable(L, -2); - push_asn1_string(L, general_name->d.rfc822Name); + push_asn1_string(L, general_name->d.rfc822Name, px->encode); lua_rawseti(L, -2, lua_rawlen(L, -2) + 1); lua_pop(L, 1); break; case GEN_URI: lua_pushstring(L, "uniformResourceIdentifier"); push_subtable(L, -2); - push_asn1_string(L, general_name->d.uniformResourceIdentifier); + push_asn1_string(L, general_name->d.uniformResourceIdentifier, px->encode); lua_rawseti(L, -2, lua_rawlen(L, -2)+1); lua_pop(L, 1); break; case GEN_IPADD: lua_pushstring(L, "iPAddress"); push_subtable(L, -2); - push_asn1_string(L, general_name->d.iPAddress); + push_asn1_string(L, general_name->d.iPAddress, px->encode); lua_rawseti(L, -2, lua_rawlen(L, -2)+1); lua_pop(L, 1); break; @@ -383,6 +406,25 @@ static int meth_tostring(lua_State *L) return 1; } +/** + * Set the encode for ASN.1 string. + */ +static int meth_set_encode(lua_State* L) +{ + int succ = 0; + p_x509 px = lsec_checkp_x509(L, 1); + const char *enc = luaL_checkstring(L, 2); + if (strncmp(enc, "ai5", 3) == 0) { + succ = 1; + px->encode = LSEC_AI5_STRING; + } else if (strncmp(enc, "utf8", 4) == 0) { + succ = 1; + px->encode = LSEC_UTF8_STRING; + } + lua_pushboolean(L, succ); + return 1; +} + /*---------------------------------------------------------------------------*/ static int load_cert(lua_State* L) @@ -409,6 +451,7 @@ static int load_cert(lua_State* L) */ static luaL_Reg methods[] = { {"digest", meth_digest}, + {"setencode", meth_set_encode}, {"extensions", meth_extensions}, {"issuer", meth_issuer}, {"notbefore", meth_notbefore}, diff --git a/src/x509.h b/src/x509.h index ffe212e..8a65ced 100644 --- a/src/x509.h +++ b/src/x509.h @@ -12,8 +12,12 @@ #include "config.h" +/* We do not support UniversalString nor BMPString as ASN.1 String types */ +enum { LSEC_AI5_STRING, LSEC_UTF8_STRING }; + typedef struct t_x509_ { X509 *cert; + int encode; } t_x509; typedef t_x509* p_x509;