# HG changeset patch # User Matthew Wild # Date 1288923443 0 # Node ID da3cf40976f6302410c1950efdb856add97540aa # Parent d559a15eeb40d2e2f30ba13b6865f4eb9fe31f31 Modify :getpeercertificate() to return a decoded certificate (subject only at the moment) diff -r d559a15eeb40 -r da3cf40976f6 src/ssl.c --- a/src/ssl.c Fri Oct 08 21:12:48 2010 +0100 +++ b/src/ssl.c Fri Nov 05 02:17:23 2010 +0000 @@ -385,29 +385,73 @@ /* No client certificate available */ lua_pushboolean(L, 0); return 1; - } else { - char *buffer = NULL; - char length = 0; - BIO *bp = BIO_new(BIO_s_mem()); /* To memory */ - i2d_X509_bio(bp, peer); /* as der */ - if ((length = BIO_read(bp, 0, 0)) == 0) { - BIO_free(bp); - return 0; + } + else + { + X509_NAME *subject; + int i, n_entries, len; + char buffer[4096]; + + lua_newtable(L); + + 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); /* ret */ + 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; + ASN1_STRING *value; + int len; + + entry = X509_NAME_get_entry(subject, i); + object = X509_NAME_ENTRY_get_object(entry); + + /* Get numeric ID as string into buffer */ + len = OBJ_obj2txt(buffer, sizeof(buffer), object, 1); + + if(len == 0) + continue; + + /* Push numeric ID to Lua (e.g. 1.22.3...) */ + lua_pushlstring(L, buffer, (len>sizeof(buffer))?sizeof(buffer):(len)); + lua_pushvalue(L, -1); /* k */ + + lua_gettable(L, -4); /* ret.subject[k] */ + + if(lua_isnil(L, -1)) + { + lua_pop(L, 1); + lua_newtable(L); + lua_pushvalue(L, -2); /* k */ + lua_pushvalue(L, -2); /* v */ + lua_settable(L, -6); /* ret.subject[k] = v */ + /* Get short/long name of the entry */ + len = OBJ_obj2txt(buffer, sizeof(buffer), object, 0); + lua_pushlstring(L, buffer, (len>sizeof(buffer))?sizeof(buffer):(len)); + lua_setfield(L, -2, "name"); + } + + value = X509_NAME_ENTRY_get_data(entry); + if(value) + { + lua_pushlstring(L, (char*)ASN1_STRING_data(value), ASN1_STRING_length(value)); + lua_rawseti(L, -2, lua_objlen(L, -2)+1); + } + + lua_pop(L, 2); /* k, v */ } - if ((buffer = malloc(length)) == NULL) { - BIO_free(bp); - return 0; - } - if ((length = BIO_read(bp, buffer, length)) > length) { - free(buffer); - BIO_free(bp); - return 0; - } - lua_pushlstring(L, buffer, length); - free(buffer); - BIO_free(bp); - return 1; } + lua_pop(L, 1); /* ret.subject */ + return 1; } static int meth_getfinished(lua_State *L)