# HG changeset patch # User Matthew Wild # Date 1288990086 0 # Node ID 1927b7b32faf8c0d0c4dc7eded03c322eb5e22cd # Parent ebe0d286481c1aa56e9679f93f4d72ff201f954f Split X509 decoding into a separate module, ssl.x509 diff -r ebe0d286481c -r 1927b7b32faf src/Makefile --- a/src/Makefile Fri Nov 05 20:47:20 2010 +0000 +++ b/src/Makefile Fri Nov 05 20:48:06 2010 +0000 @@ -7,6 +7,7 @@ io.o \ usocket.o \ context.o \ + x509.o \ ssl.o LIBS=-lssl -lcrypto @@ -59,4 +60,5 @@ timeout.o: timeout.c timeout.h usocket.o: usocket.c socket.h io.h timeout.h usocket.h context.o: context.c context.h +x509.o: x509.c x509.h ssl.o: ssl.c socket.h io.h timeout.h usocket.h buffer.h context.h context.c diff -r ebe0d286481c -r 1927b7b32faf src/ssl.c --- a/src/ssl.c Fri Nov 05 20:47:20 2010 +0000 +++ b/src/ssl.c Fri Nov 05 20:48:06 2010 +0000 @@ -418,128 +418,17 @@ static int meth_getpeercertificate(lua_State *L) { X509 *peer; - int i, j; p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection"); peer = SSL_get_peer_certificate(ssl->ssl); if (peer == NULL) { /* No client certificate available */ - lua_pushboolean(L, 0); - return 1; + lua_pushnil(L); } else { - X509_NAME *subject; - int n_entries; - - lua_newtable(L); /* ret */ - - lua_pushboolean(L, (SSL_get_verify_result(ssl->ssl) == X509_V_OK)); - lua_setfield(L, -2, "trusted"); - - subject = X509_get_subject_name(peer); - - n_entries = X509_NAME_entry_count(subject); - - lua_newtable(L); /* {} */ - lua_pushvalue(L, -1); - lua_setfield(L, -3, "subject"); /* ret.subject = {} */ - for(i = 0; i <= n_entries; i++) - { - X509_NAME_ENTRY *entry; - ASN1_OBJECT *object; - - entry = X509_NAME_get_entry(subject, i); - object = X509_NAME_ENTRY_get_object(entry); - - luasec_push_asn1_objname(L, object, 1); - - if(luasec_push_subtable(L, -2)) - { - /* Get short/long name of the entry */ - luasec_push_asn1_objname(L, object, 0); - lua_setfield(L, -2, "name"); - } - - luasec_push_asn1_string(L, X509_NAME_ENTRY_get_data(entry)); - lua_rawseti(L, -2, lua_objlen(L, -2)+1); - - lua_pop(L, 1); - } + /* Push metatabled peer */ + luasec_push_x509(L, peer); } - lua_pop(L, 1); /* ret.subject */ - - lua_newtable(L); /* {} */ - lua_pushvalue(L, -1); - lua_setfield(L, -3, "extensions"); /* ret.extensions = {} */ - - i = -1; - while((i = X509_get_ext_by_NID(peer, NID_subject_alt_name, i)) != -1) - { - X509_EXTENSION *extension; - STACK_OF(GENERAL_NAME) *values; - int n_general_names; - - extension = X509_get_ext(peer, i); - if(extension == NULL) - break; - - values = X509V3_EXT_d2i(extension); - if(values == NULL) - break; - - /* Push ret.extensions[oid] */ - luasec_push_asn1_objname(L, extension->object, 1); - luasec_push_subtable(L, -2); - /* Set ret.extensions[oid].name = name */ - luasec_push_asn1_objname(L, extension->object, 0); - lua_setfield(L, -2, "name"); - - n_general_names = sk_GENERAL_NAME_num(values); - for(j = 0; j < n_general_names; j++) - { - GENERAL_NAME *general_name; - - general_name = sk_GENERAL_NAME_value(values, j); - - switch(general_name->type) - { - case GEN_OTHERNAME: - { - OTHERNAME *otherName = general_name->d.otherName; - - luasec_push_asn1_objname(L, otherName->type_id, 1); - - if(luasec_push_subtable(L, -2)) - { - luasec_push_asn1_objname(L, otherName->type_id, 0); - lua_setfield(L, -2, "name"); - } - - luasec_push_asn1_string(L, otherName->value->value.asn1_string); - lua_rawseti(L, -2, lua_objlen(L, -2)+1); - - lua_pop(L, 1); - break; - } - case GEN_DNS: - { - lua_pushstring(L, "dNSName"); - luasec_push_subtable(L, -2); - luasec_push_asn1_string(L, general_name->d.dNSName); - lua_rawseti(L, -2, lua_objlen(L, -2)+1); - lua_pop(L, 1); - break; - } - default: - break; - } - } - - lua_pop(L, 1); /* array */ - i++; /* Next extension */ - } - lua_pop(L, 1); /* ret.extensions */ - return 1; } diff -r ebe0d286481c -r 1927b7b32faf src/ssl.lua --- a/src/ssl.lua Fri Nov 05 20:47:20 2010 +0000 +++ b/src/ssl.lua Fri Nov 05 20:48:06 2010 +0000 @@ -8,6 +8,7 @@ require("ssl.core") require("ssl.context") +require("ssl.x509") _VERSION = "0.4" diff -r ebe0d286481c -r 1927b7b32faf src/x509.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/x509.c Fri Nov 05 20:48:06 2010 +0000 @@ -0,0 +1,169 @@ +/*-------------------------------------------------------------------------- + * LuaSec 0.4 + * Copyright (C) 2006-2009 Bruno Silvestre + * + *--------------------------------------------------------------------------*/ + +#include + +#include +#include +#include + +#include +#include + +#include "io.h" +#include "buffer.h" +#include "timeout.h" +#include "socket.h" +#include "ssl.h" +#include "x509.h" + +#define min(a, b) (acert = cert; + luaL_getmetatable(L, "SSL:Certificate"); + lua_setmetatable(L, -2); +} + +X509* luasec_to_x509(lua_State* L, int idx) +{ + return ((p_x509)luaL_checkudata(L, idx, "SSL:Certificate"))->cert; +} + +int meth_decode(lua_State* L) +{ + X509 *peer; + X509_NAME *subject; + int i, j, n_entries; + + peer = luasec_to_x509(L, 1); + + lua_newtable(L); /* ret */ + + subject = X509_get_subject_name(peer); + + n_entries = X509_NAME_entry_count(subject); + + lua_newtable(L); /* {} */ + lua_pushvalue(L, -1); + lua_setfield(L, -3, "subject"); /* ret.subject = {} */ + for(i = 0; i <= n_entries; i++) + { + X509_NAME_ENTRY *entry; + ASN1_OBJECT *object; + + entry = X509_NAME_get_entry(subject, i); + object = X509_NAME_ENTRY_get_object(entry); + + luasec_push_asn1_objname(L, object, 1); + + if(luasec_push_subtable(L, -2)) + { + /* Get short/long name of the entry */ + luasec_push_asn1_objname(L, object, 0); + lua_setfield(L, -2, "name"); + } + + luasec_push_asn1_string(L, X509_NAME_ENTRY_get_data(entry)); + lua_rawseti(L, -2, lua_objlen(L, -2)+1); + + lua_pop(L, 1); + } + + lua_pop(L, 1); /* ret.subject */ + + lua_newtable(L); /* {} */ + lua_pushvalue(L, -1); + lua_setfield(L, -3, "extensions"); /* ret.extensions = {} */ + + i = -1; + while((i = X509_get_ext_by_NID(peer, NID_subject_alt_name, i)) != -1) + { + X509_EXTENSION *extension; + STACK_OF(GENERAL_NAME) *values; + int n_general_names; + + extension = X509_get_ext(peer, i); + if(extension == NULL) + break; + + values = X509V3_EXT_d2i(extension); + if(values == NULL) + break; + + /* Push ret.extensions[oid] */ + luasec_push_asn1_objname(L, extension->object, 1); + luasec_push_subtable(L, -2); + /* Set ret.extensions[oid].name = name */ + luasec_push_asn1_objname(L, extension->object, 0); + lua_setfield(L, -2, "name"); + + n_general_names = sk_GENERAL_NAME_num(values); + for(j = 0; j < n_general_names; j++) + { + GENERAL_NAME *general_name; + + general_name = sk_GENERAL_NAME_value(values, j); + + switch(general_name->type) + { + case GEN_OTHERNAME: + { + OTHERNAME *otherName = general_name->d.otherName; + + luasec_push_asn1_objname(L, otherName->type_id, 1); + + if(luasec_push_subtable(L, -2)) + { + luasec_push_asn1_objname(L, otherName->type_id, 0); + lua_setfield(L, -2, "name"); + } + + luasec_push_asn1_string(L, otherName->value->value.asn1_string); + lua_rawseti(L, -2, lua_objlen(L, -2)+1); + + lua_pop(L, 1); + break; + } + case GEN_DNS: + { + lua_pushstring(L, "dNSName"); + luasec_push_subtable(L, -2); + luasec_push_asn1_string(L, general_name->d.dNSName); + lua_rawseti(L, -2, lua_objlen(L, -2)+1); + lua_pop(L, 1); + break; + } + default: + break; + } + } + + lua_pop(L, 1); /* array */ + i++; /* Next extension */ + } + lua_pop(L, 1); /* ret.extensions */ + return 1; +} + +/** + * Certificate metamethods + */ +static luaL_Reg meta[] = { + {"decode", meth_decode}, + {NULL, NULL} +}; + +LUASEC_API int luaopen_ssl_x509(lua_State *L) +{ + /* Register the functions and tables */ + luaL_newmetatable(L, "SSL:Certificate"); + lua_newtable(L); + luaL_register(L, NULL, meta); + lua_setfield(L, -2, "__index"); +} diff -r ebe0d286481c -r 1927b7b32faf src/x509.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/x509.h Fri Nov 05 20:48:06 2010 +0000 @@ -0,0 +1,12 @@ +#include +#include + +typedef struct t_x509_ { + X509 *cert; +} t_x509; +typedef t_x509* p_x509; + +void luasec_push_x509(lua_State* L, X509* cert); +X509* luasec_to_x509(lua_State* L, int idx); + +LUASEC_API int luaopen_ssl_x509(lua_State *L);