Add x509:setencode() function to change the encode of ASN.1 string.

This commit is contained in:
Bruno Silvestre 2013-10-23 13:42:34 -02:00
parent 063e8a8a5c
commit ce504d3554
2 changed files with 61 additions and 14 deletions

View File

@ -32,6 +32,7 @@ void lsec_pushx509(lua_State* L, X509 *cert)
{ {
p_x509 cert_obj = (p_x509)lua_newuserdata(L, sizeof(t_x509)); p_x509 cert_obj = (p_x509)lua_newuserdata(L, sizeof(t_x509));
cert_obj->cert = cert; cert_obj->cert = cert;
cert_obj->encode = LSEC_AI5_STRING;
luaL_getmetatable(L, "SSL:Certificate"); luaL_getmetatable(L, "SSL:Certificate");
lua_setmetatable(L, -2); 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 ((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. * 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), lua_pushlstring(L, (char*)ASN1_STRING_data(string),
ASN1_STRING_length(string)); ASN1_STRING_length(string));
else break;
lua_pushnil(L); 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. * 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 i;
int n_entries; int n_entries;
@ -136,7 +156,7 @@ static int push_x509_name(lua_State* L, X509_NAME *name)
lua_setfield(L, -2, "oid"); lua_setfield(L, -2, "oid");
push_asn1_objname(L, object, 0); push_asn1_objname(L, object, 0);
lua_setfield(L, -2, "name"); 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_setfield(L, -2, "value");
lua_rawseti(L, -2, i+1); 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) 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) 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; X509_EXTENSION *extension;
GENERAL_NAME *general_name; GENERAL_NAME *general_name;
STACK_OF(GENERAL_NAME) *values; 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) */ /* Return (ret) */
lua_newtable(L); lua_newtable(L);
@ -205,35 +228,35 @@ int meth_extensions(lua_State* L)
push_asn1_objname(L, otherName->type_id, 0); push_asn1_objname(L, otherName->type_id, 0);
lua_setfield(L, -2, "name"); 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_rawseti(L, -2, lua_rawlen(L, -2) + 1);
lua_pop(L, 1); lua_pop(L, 1);
break; break;
case GEN_DNS: case GEN_DNS:
lua_pushstring(L, "dNSName"); lua_pushstring(L, "dNSName");
push_subtable(L, -2); 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_rawseti(L, -2, lua_rawlen(L, -2) + 1);
lua_pop(L, 1); lua_pop(L, 1);
break; break;
case GEN_EMAIL: case GEN_EMAIL:
lua_pushstring(L, "rfc822Name"); lua_pushstring(L, "rfc822Name");
push_subtable(L, -2); 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_rawseti(L, -2, lua_rawlen(L, -2) + 1);
lua_pop(L, 1); lua_pop(L, 1);
break; break;
case GEN_URI: case GEN_URI:
lua_pushstring(L, "uniformResourceIdentifier"); lua_pushstring(L, "uniformResourceIdentifier");
push_subtable(L, -2); 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_rawseti(L, -2, lua_rawlen(L, -2)+1);
lua_pop(L, 1); lua_pop(L, 1);
break; break;
case GEN_IPADD: case GEN_IPADD:
lua_pushstring(L, "iPAddress"); lua_pushstring(L, "iPAddress");
push_subtable(L, -2); 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_rawseti(L, -2, lua_rawlen(L, -2)+1);
lua_pop(L, 1); lua_pop(L, 1);
break; break;
@ -383,6 +406,25 @@ static int meth_tostring(lua_State *L)
return 1; 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) static int load_cert(lua_State* L)
@ -409,6 +451,7 @@ static int load_cert(lua_State* L)
*/ */
static luaL_Reg methods[] = { static luaL_Reg methods[] = {
{"digest", meth_digest}, {"digest", meth_digest},
{"setencode", meth_set_encode},
{"extensions", meth_extensions}, {"extensions", meth_extensions},
{"issuer", meth_issuer}, {"issuer", meth_issuer},
{"notbefore", meth_notbefore}, {"notbefore", meth_notbefore},

View File

@ -12,8 +12,12 @@
#include "config.h" #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_ { typedef struct t_x509_ {
X509 *cert; X509 *cert;
int encode;
} t_x509; } t_x509;
typedef t_x509* p_x509; typedef t_x509* p_x509;