aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/openssl.c253
1 files changed, 220 insertions, 33 deletions
diff --git a/src/openssl.c b/src/openssl.c
index 629373d..a4efcdc 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -460,32 +460,25 @@ static void *loadfield_udata(lua_State *L, int index, const char *k, const char
} /* loadfield_udata() */
-static const char *pushnid(lua_State *L, int nid) {
- const char *txt;
- ASN1_OBJECT *obj;
- char buf[256];
- int len;
-
- if ((txt = OBJ_nid2sn(nid)) || (txt = OBJ_nid2ln(nid))) {
- lua_pushstring(L, txt);
- } else {
- if (!(obj = OBJ_nid2obj(nid)))
- luaL_error(L, "%d: unknown ASN.1 NID", nid);
+/*
+ * Auxiliary C routines
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
- if (-1 == (len = OBJ_obj2txt(buf, sizeof buf, obj, 1)))
- luaL_error(L, "%d: invalid ASN.1 NID", nid);
+#define AUX_MIN(a, b) (((a) < (b))? (a) : (b))
- lua_pushlstring(L, buf, len);
- }
+static size_t aux_strlcpy(char *dst, const char *src, size_t lim) {
+ size_t n = strlen(src);
- return lua_tostring(L, -1);
-} /* pushnid() */
+ if (lim > 0) {
+ size_t m = AUX_MIN(lim - 1, n);
+ memcpy(dst, src, m);
+ dst[m] = '\0';
+ }
-/*
- * Auxiliary C routines
- *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+ return n;
+} /* aux_strlcpy() */
#define aux_strerror(error) aux_strerror_r((error), (char[256]){ 0 }, 256)
@@ -517,6 +510,83 @@ static const char *aux_strerror_r(int error, char *dst, size_t lim) {
/*
+ * Auxiliary OpenSSL API routines
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+static size_t auxS_nid2sn(void *dst, size_t lim, int nid) {
+ const char *sn;
+
+ if (nid == NID_undef || !(sn = OBJ_nid2sn(nid)))
+ return 0;
+
+ return aux_strlcpy(dst, sn, lim);
+} /* aux2_nid2sn() */
+
+static size_t auxS_obj2sn(void *dst, size_t lim, const ASN1_OBJECT *obj) {
+ return auxS_nid2sn(dst, lim, OBJ_obj2nid(obj));
+} /* auxS_obj2sn() */
+
+static size_t auxS_nid2ln(void *dst, size_t lim, int nid) {
+ const char *ln;
+
+ if (nid == NID_undef || !(ln = OBJ_nid2ln(nid)))
+ return 0;
+
+ return aux_strlcpy(dst, ln, lim);
+} /* aux2_nid2ln() */
+
+static size_t auxS_obj2ln(void *dst, size_t lim, const ASN1_OBJECT *obj) {
+ return auxS_nid2ln(dst, lim, OBJ_obj2nid(obj));
+} /* auxS_obj2ln() */
+
+static size_t auxS_obj2id(void *dst, size_t lim, const ASN1_OBJECT *obj) {
+ int n = OBJ_obj2txt(dst, AUX_MIN(lim, INT_MAX), obj, 1);
+
+ /* TODO: push custom errors onto error stack */
+ if (n == 0) {
+ return 0; /* obj->data == NULL */
+ } else if (n < 0) {
+ return 0; /* memory allocation error */
+ } else {
+ return n;
+ }
+} /* auxS_obj2id() */
+
+static size_t auxS_nid2id(void *dst, size_t lim, int nid) {
+ ASN1_OBJECT *obj;
+
+ /* TODO: push custom error onto error stack */
+ if (!(obj = OBJ_nid2obj(nid)))
+ return 0;
+
+ return auxS_obj2id(dst, lim, obj);
+} /* auxS_nid2id() */
+
+static size_t auxS_nid2txt(void *dst, size_t lim, int nid) {
+ size_t n;
+
+ if ((n = auxS_nid2sn(dst, lim, nid)))
+ return n;
+ if ((n = auxS_nid2ln(dst, lim, nid)))
+ return n;
+
+ return auxS_nid2id(dst, lim, nid);
+} /* auxS_nid2txt() */
+
+static size_t auxS_obj2txt(void *dst, size_t lim, const ASN1_OBJECT *obj) {
+ size_t n;
+
+ if ((n = auxS_obj2sn(dst, lim, obj)))
+ return n;
+ if ((n = auxS_obj2ln(dst, lim, obj)))
+ return n;
+
+ return auxS_obj2id(dst, lim, obj);
+} /* auxS_obj2txt() */
+
+
+/*
* Auxiliary Lua API routines
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -685,6 +755,18 @@ static int auxL_error(lua_State *L, int error, const char *fun) {
return lua_error(L);
} /* auxL_error() */
+static const char *auxL_pushnid(lua_State *L, int nid) {
+ char txt[256] = { 0 };
+ size_t n;
+
+ if (!(n = auxS_nid2txt(txt, sizeof txt, nid)) || n >= sizeof txt)
+ luaL_error(L, "%d: invalid ASN.1 NID", nid);
+
+ lua_pushlstring(L, txt, n);
+
+ return lua_tostring(L, -1);
+} /* auxL_pushnid() */
+
/*
* dl - dynamically loaded module management
@@ -796,6 +878,14 @@ static void *compat_EVP_PKEY_get0(EVP_PKEY *key) {
#define X509_get0_ext(crt, i) X509_get_ext((crt), (i))
#endif
+#if !HAVE_X509_CRL_GET0_EXT
+#define X509_CRL_get0_ext(crt, i) X509_CRL_get_ext((crt), (i))
+#endif
+
+#if !HAVE_X509_EXTENSION_GET0_OBJECT
+#define X509_EXTENSION_get0_object(ext) X509_EXTENSION_get_object((ext))
+#endif
+
#if !HAVE_X509_EXTENSION_GET0_DATA
#define X509_EXTENSION_get0_data(ext) X509_EXTENSION_get_data((ext))
#endif
@@ -2103,7 +2193,7 @@ static int pk_type(lua_State *L) {
EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS);
int nid = key->type;
- pushnid(L, nid);
+ auxL_pushnid(L, nid);
return 1;
} /* pk_type() */
@@ -2526,16 +2616,10 @@ static int xn__next(lua_State *L) {
continue;
obj = X509_NAME_ENTRY_get_object(entry);
- nid = OBJ_obj2nid(obj);
-
- if (nid != NID_undef && ((id = OBJ_nid2sn(nid)) || (id = OBJ_nid2ln(nid)))) {
- lua_pushstring(L, id);
- } else {
- if (0 > (len = OBJ_obj2txt(txt, sizeof txt, obj, 1)))
- return auxL_error(L, auxL_EOPENSSL, "x509.name:__pairs");
- lua_pushlstring(L, txt, len);
- }
+ if (!(len = auxS_obj2txt(txt, sizeof txt, obj)))
+ return auxL_error(L, auxL_EOPENSSL, "x509.name:__pairs");
+ lua_pushlstring(L, txt, len);
len = ASN1_STRING_length(X509_NAME_ENTRY_get_data(entry));
lua_pushlstring(L, (char *)ASN1_STRING_data(X509_NAME_ENTRY_get_data(entry)), len);
@@ -2960,6 +3044,63 @@ static int xe_interpose(lua_State *L) {
} /* xe_interpose() */
+static int xe_getID(lua_State *L) {
+ X509_EXTENSION *ext = checksimple(L, 1, X509_EXT_CLASS);
+ ASN1_OBJECT *obj = X509_EXTENSION_get0_object(ext);
+ char txt[256];
+ int len;
+
+ if (!(len = auxS_obj2id(txt, sizeof txt, obj)))
+ return auxL_error(L, auxL_EOPENSSL, "x509.extension:getID");
+
+ lua_pushlstring(L, txt, len);
+
+ return 1;
+} /* xe_getID() */
+
+
+static int xe_getName(lua_State *L) {
+ X509_EXTENSION *ext = checksimple(L, 1, X509_EXT_CLASS);
+ char txt[256];
+ int len;
+
+ if (!(len = auxS_obj2txt(txt, sizeof txt, X509_EXTENSION_get0_object(ext))))
+ return auxL_error(L, auxL_EOPENSSL, "x509.extension:getName");
+
+ lua_pushlstring(L, txt, len);
+
+ return 1;
+} /* xe_getName() */
+
+
+static int xe_getShortName(lua_State *L) {
+ X509_EXTENSION *ext = checksimple(L, 1, X509_EXT_CLASS);
+ char txt[256];
+ int len;
+
+ if (!(len = auxS_obj2sn(txt, sizeof txt, X509_EXTENSION_get0_object(ext))))
+ return 0;
+
+ lua_pushlstring(L, txt, len);
+
+ return 1;
+} /* xe_getShortName() */
+
+
+static int xe_getLongName(lua_State *L) {
+ X509_EXTENSION *ext = checksimple(L, 1, X509_EXT_CLASS);
+ char txt[256];
+ int len;
+
+ if (!(len = auxS_obj2ln(txt, sizeof txt, X509_EXTENSION_get0_object(ext))))
+ return 0;
+
+ lua_pushlstring(L, txt, len);
+
+ return 1;
+} /* xe_getLongName() */
+
+
static int xe_getData(lua_State *L) {
ASN1_STRING *data = X509_EXTENSION_get0_data(checksimple(L, 1, X509_EXT_CLASS));
@@ -2969,6 +3110,13 @@ static int xe_getData(lua_State *L) {
} /* xe_getData() */
+static int xe_getCritical(lua_State *L) {
+ lua_pushboolean(L, X509_EXTENSION_get_critical(checksimple(L, 1, X509_EXT_CLASS)));
+
+ return 1;
+} /* xe_getCritical() */
+
+
static int xe__gc(lua_State *L) {
X509_EXTENSION **ud = luaL_checkudata(L, 1, X509_EXT_CLASS);
@@ -2982,8 +3130,13 @@ static int xe__gc(lua_State *L) {
static const luaL_Reg xe_methods[] = {
- { "getData", &xe_getData },
- { NULL, NULL },
+ { "getID", &xe_getID },
+ { "getName", &xe_getName },
+ { "getShortName", &xe_getShortName },
+ { "getLongName", &xe_getLongName },
+ { "getData", &xe_getData },
+ { "getCritical", &xe_getCritical },
+ { NULL, NULL },
};
static const luaL_Reg xe_metatable[] = {
@@ -3702,6 +3855,7 @@ static int xc_addExtension(lua_State *L) {
X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
X509_EXTENSION *ext = checksimple(L, 2, X509_EXT_CLASS);
+ /* NOTE: Will dup extension in X509v3_add_ext. */
if (!X509_add_ext(crt, ext, -1))
return auxL_error(L, auxL_EOPENSSL, "x509.cert:addExtension");
@@ -4461,6 +4615,38 @@ static int xx_addExtension(lua_State *L) {
return 1;
} /* xx_addExtension() */
+
+static int xx_getExtension(lua_State *L) {
+ X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS);
+ const char *name = luaL_checkstring(L, 2);
+ X509_EXTENSION *ext, **ud;
+ ASN1_OBJECT *obj = NULL;
+
+ if (!(obj = OBJ_txt2obj(name, 0)))
+ goto error;
+
+ int i = X509_CRL_get_ext_by_OBJ(crl, obj, -1);
+ if (i > -1) {
+ ud = prepsimple(L, X509_CRL_CLASS);
+ if (!(ext = X509_CRL_get0_ext(crl, i)))
+ goto error;
+ if (!(*ud = X509_EXTENSION_dup(ext)))
+ goto error;
+ } else {
+ lua_pushnil(L);
+ }
+
+ ASN1_OBJECT_free(obj);
+
+ return 1;
+error:
+ if (obj)
+ ASN1_OBJECT_free(obj);
+
+ return auxL_error(L, auxL_EOPENSSL, "x509.crl:getExtension");
+} /* xx_getExtension() */
+
+
static int xx_sign(lua_State *L) {
X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS);
EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS);
@@ -4540,6 +4726,7 @@ static const luaL_Reg xx_methods[] = {
{ "setIssuer", &xx_setIssuer },
{ "add", &xx_add },
{ "addExtension", &xx_addExtension },
+ { "getExtension", &xx_getExtension },
{ "sign", &xx_sign },
{ "text", &xx_text },
{ "tostring", &xx__tostring },