aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatarLibravatar Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi> 2014-05-15 10:18:14 +0300
committerLibravatarLibravatar Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi> 2014-05-28 22:42:55 +0300
commit3bdb5b625285d2d924bb61742a2184008608f0dd (patch)
tree57cbd2fe9af58b5780dda6a6e929c73d5923e0ff
parentad5867b4c5c85ac4ade3cd2d4884ade0e1fae5a5 (diff)
downloadluaossl-3bdb5b625285d2d924bb61742a2184008608f0dd.tar.gz
luaossl-3bdb5b625285d2d924bb61742a2184008608f0dd.tar.bz2
luaossl-3bdb5b625285d2d924bb61742a2184008608f0dd.zip
PKCS #12 module
-rw-r--r--src/GNUmakefile1
-rw-r--r--src/openssl.c133
-rw-r--r--src/openssl.pkcs12.lua1
3 files changed, 135 insertions, 0 deletions
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;
@@ -3563,6 +3577,124 @@ int luaopen__openssl_x509_store_context(lua_State *L) {
/*
+ * 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')