From 3bdb5b625285d2d924bb61742a2184008608f0dd Mon Sep 17 00:00:00 2001
From: Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>
Date: Thu, 15 May 2014 10:18:14 +0300
Subject: PKCS #12 module

---
 src/GNUmakefile        |   1 +
 src/openssl.c          | 133 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/openssl.pkcs12.lua |   1 +
 3 files changed, 135 insertions(+)
 create mode 100644 src/openssl.pkcs12.lua

(limited to 'src')

diff --git a/src/GNUmakefile b/src/GNUmakefile
index 75e8c3a..240a773 100644
--- a/src/GNUmakefile
+++ b/src/GNUmakefile
@@ -96,6 +96,7 @@ MODS$(1)_$(d) = \
 	$$(DESTDIR)$(3)/openssl/x509/chain.lua \
 	$$(DESTDIR)$(3)/openssl/x509/crl.lua \
 	$$(DESTDIR)$(3)/openssl/x509/store.lua \
+	$$(DESTDIR)$(3)/openssl/pkcs12.lua \
 	$$(DESTDIR)$(3)/openssl/ssl/context.lua \
 	$$(DESTDIR)$(3)/openssl/ssl.lua \
 	$$(DESTDIR)$(3)/openssl/digest.lua \
diff --git a/src/openssl.c b/src/openssl.c
index c589d6c..2cdf1d4 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -64,6 +64,7 @@
 #include <openssl/asn1.h>
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
+#include <openssl/pkcs12.h>
 #include <openssl/evp.h>
 #include <openssl/pem.h>
 #include <openssl/ssl.h>
@@ -88,6 +89,7 @@
 #define X509_CRL_CLASS   "X509_CRL*"
 #define X509_STORE_CLASS "X509_STORE*"
 #define X509_STCTX_CLASS "X509_STORE_CTX*"
+#define PKCS12_CLASS     "PKCS12*"
 #define SSL_CTX_CLASS    "SSL_CTX*"
 #define SSL_CLASS        "SSL*"
 #define DIGEST_CLASS     "EVP_MD_CTX"     /* not a pointer */
@@ -363,6 +365,18 @@ static _Bool loadfield(lua_State *L, int index, const char *k, int type, void *p
 } /* loadfield() */
 
 
+static void *loadfield_udata(lua_State *L, int index, const char *k, const char *tname) {
+	if (!getfield(L, index, k))
+		return NULL;
+
+	void **p = luaL_checkudata(L, -1, tname);
+
+	lua_pop(L, 1); /* table keeps reference */
+
+	return *p;
+} /* loadfield_udata() */
+
+
 static const char *pushnid(lua_State *L, int nid) {
 	const char *txt;
 	ASN1_OBJECT *obj;
@@ -3562,6 +3576,124 @@ int luaopen__openssl_x509_store_context(lua_State *L) {
 #endif
 
 
+/*
+ * PKCS12 - openssl.pkcs12
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+static int p12_new(lua_State *L) {
+	char *pass = NULL;
+	loadfield(L, 1, "password", LUA_TSTRING, &pass);
+
+	EVP_PKEY *key = loadfield_udata(L, 1, "key", PKEY_CLASS);
+	STACK_OF(X509) *certs = loadfield_udata(L, 1, "certs", X509_CHAIN_CLASS);
+
+	PKCS12 **ud = prepsimple(L, PKCS12_CLASS);
+
+	int i;
+	int no_kcert = 0;
+	X509 *cert = NULL;
+	X509 *kcert = NULL;
+	STACK_OF(X509) *ca;
+
+	if (!(ca = sk_X509_new_null()))
+		goto error;
+
+	for (i = 0; i < sk_X509_num(certs); i++) {
+		cert = sk_X509_value(certs, i);
+		if (key && X509_check_private_key(cert, key)) {
+			if (!(kcert = X509_dup(cert)))
+				goto error;
+			X509_keyid_set1(kcert, NULL, 0);
+			X509_alias_set1(kcert, NULL, 0);
+		}
+		else sk_X509_push(ca, cert);
+	}
+	if (key && !kcert) {
+		no_kcert = 1;
+		goto error;
+	}
+
+	if (!(*ud = PKCS12_create(pass, NULL, key, kcert, ca, 0, 0, 0, 0, 0)))
+		goto error;
+
+	if (kcert)
+		X509_free(kcert);
+	sk_X509_free(ca);
+
+	return 1;
+
+error:
+	if (kcert)
+		X509_free(kcert);
+	if (ca)
+		sk_X509_free(ca);
+
+	if (no_kcert)
+		luaL_argerror(L, 1, lua_pushstring(L, "certificate matching the key not found"));
+
+	return throwssl(L, "pkcs12.new");
+} /* p12_new() */
+
+
+static int p12_interpose(lua_State *L) {
+	return interpose(L, PKCS12_CLASS);
+} /* p12_interpose() */
+
+
+static int p12__tostring(lua_State *L) {
+	PKCS12 *p12 = checksimple(L, 1, PKCS12_CLASS);
+	BIO *bio = getbio(L);
+	char *data;
+	long len;
+
+	if (!i2d_PKCS12_bio(bio, p12))
+		return throwssl(L, "pkcs12:__tostring");
+
+	len = BIO_get_mem_data(bio, &data);
+
+	lua_pushlstring(L, data, len);
+
+	return 1;
+} /* p12__tostring() */
+
+
+static int p12__gc(lua_State *L) {
+	PKCS12 **ud = luaL_checkudata(L, 1, PKCS12_CLASS);
+
+	PKCS12_free(*ud);
+	*ud = NULL;
+
+	return 0;
+} /* p12__gc() */
+
+
+static const luaL_Reg p12_methods[] = {
+	{ "tostring", &p12__tostring },
+	{ NULL,         NULL },
+};
+
+static const luaL_Reg p12_metatable[] = {
+	{ "__tostring", &p12__tostring },
+	{ "__gc",       &p12__gc },
+	{ NULL,         NULL },
+};
+
+static const luaL_Reg p12_globals[] = {
+	{ "new",       &p12_new },
+	{ "interpose", &p12_interpose },
+	{ NULL,        NULL },
+};
+
+int luaopen__openssl_pkcs12(lua_State *L) {
+	initall(L);
+
+	luaL_newlib(L, p12_globals);
+
+	return 1;
+} /* luaopen__openssl_pkcs12() */
+
+
 /*
  * SSL_CTX - openssl.ssl.context
  *
@@ -4759,6 +4891,7 @@ static void initall(lua_State *L) {
 	addclass(L, X509_CRL_CLASS, xx_methods, xx_metatable);
 	addclass(L, X509_CHAIN_CLASS, xl_methods, xl_metatable);
 	addclass(L, X509_STORE_CLASS, xs_methods, xs_metatable);
+	addclass(L, PKCS12_CLASS, p12_methods, p12_metatable);
 	addclass(L, SSL_CTX_CLASS, sx_methods, sx_metatable);
 	addclass(L, SSL_CLASS, ssl_methods, ssl_metatable);
 	addclass(L, DIGEST_CLASS, md_methods, md_metatable);
diff --git a/src/openssl.pkcs12.lua b/src/openssl.pkcs12.lua
new file mode 100644
index 0000000..d8f70c2
--- /dev/null
+++ b/src/openssl.pkcs12.lua
@@ -0,0 +1 @@
+return require('_openssl.pkcs12')
-- 
cgit v1.2.3-55-g6feb


From d6535be965bc78318cdfd62ea63355c4ecf07f6c Mon Sep 17 00:00:00 2001
From: Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>
Date: Thu, 5 Jun 2014 08:33:11 +0300
Subject: pkcs12.new: use lua_pushfstring for Lua 5.1 compatibility

---
 src/openssl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src')

diff --git a/src/openssl.c b/src/openssl.c
index 2cdf1d4..2ac14f1 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -3630,7 +3630,7 @@ error:
 		sk_X509_free(ca);
 
 	if (no_kcert)
-		luaL_argerror(L, 1, lua_pushstring(L, "certificate matching the key not found"));
+		luaL_argerror(L, 1, lua_pushfstring(L, "certificate matching the key not found"));
 
 	return throwssl(L, "pkcs12.new");
 } /* p12_new() */
-- 
cgit v1.2.3-55-g6feb