Modify :getpeercertificate() to return a decoded certificate (subject only at the moment)

Fri, 05 Nov 2010 02:17:23 +0000

author
Matthew Wild <mwild1@gmail.com>
date
Fri, 05 Nov 2010 02:17:23 +0000
changeset 7
da3cf40976f6
parent 6
d559a15eeb40
child 8
fbaccf44ea01

Modify :getpeercertificate() to return a decoded certificate (subject only at the moment)

src/ssl.c file | annotate | diff | comparison | revisions
--- 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)

mercurial