aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xexamples/self.x5094
-rw-r--r--src/GNUmakefile1
-rw-r--r--src/openssl.c220
-rw-r--r--src/openssl.pkcs12.lua1
4 files changed, 220 insertions, 6 deletions
diff --git a/examples/self.x509 b/examples/self.x509
index 31d6058..b2d14f9 100755
--- a/examples/self.x509
+++ b/examples/self.x509
@@ -49,6 +49,4 @@ crt:setBasicConstraintsCritical(true)
crt:setPublicKey(key)
crt:sign(key)
--- pretty-print using openssl command-line utility.
-io.popen("openssl x509 -text -noout", "w"):write(tostring(crt))
-
+print(crt:text())
diff --git a/src/GNUmakefile b/src/GNUmakefile
index c3cddf0..f988855 100644
--- a/src/GNUmakefile
+++ b/src/GNUmakefile
@@ -97,6 +97,7 @@ MODS$(1)_$(d) = \
$$(DESTDIR)$(3)/openssl/x509/crl.lua \
$$(DESTDIR)$(3)/openssl/x509/extension.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 b72b28e..7bd9c61 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -27,6 +27,7 @@
#define LUAOSSL_H
#include <limits.h> /* INT_MAX INT_MIN */
+#include <stdint.h> /* uintptr_t */
#include <string.h> /* memset(3) strerror_r(3) */
#include <strings.h> /* strcasecmp(3) */
#include <math.h> /* INFINITY fabs(3) floor(3) frexp(3) fmod(3) round(3) isfinite(3) */
@@ -64,6 +65,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>
@@ -89,6 +91,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 */
@@ -364,6 +367,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;
@@ -1029,7 +1044,7 @@ done:
static int pk_interpose(lua_State *L) {
- return interpose(L, X509_NAME_CLASS);
+ return interpose(L, PKEY_CLASS);
} /* pk_interpose() */
@@ -2695,6 +2710,66 @@ static int xc_sign(lua_State *L) {
} /* xc_sign() */
+static int xc_text(lua_State *L) {
+ static const struct { const char *kw; unsigned int flag; } map[] = {
+ { "no_header", X509_FLAG_NO_HEADER },
+ { "no_version", X509_FLAG_NO_VERSION },
+ { "no_serial", X509_FLAG_NO_SERIAL },
+ { "no_signame", X509_FLAG_NO_SIGNAME },
+ { "no_validity", X509_FLAG_NO_VALIDITY },
+ { "no_subject", X509_FLAG_NO_SUBJECT },
+ { "no_issuer", X509_FLAG_NO_ISSUER },
+ { "no_pubkey", X509_FLAG_NO_PUBKEY },
+ { "no_extensions", X509_FLAG_NO_EXTENSIONS },
+ { "no_sigdump", X509_FLAG_NO_SIGDUMP },
+ { "no_aux", X509_FLAG_NO_AUX },
+ { "no_attributes", X509_FLAG_NO_ATTRIBUTES },
+ { "ext_default", X509V3_EXT_DEFAULT },
+ { "ext_error", X509V3_EXT_ERROR_UNKNOWN },
+ { "ext_parse", X509V3_EXT_PARSE_UNKNOWN },
+ { "ext_dump", X509V3_EXT_DUMP_UNKNOWN }
+ };
+
+ lua_settop(L, 2);
+
+ X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
+
+ unsigned int flags = 0;
+ const char *kw;
+ int found;
+ unsigned int i;
+
+ BIO *bio = getbio(L);
+ char *data;
+ long len;
+
+ if (!lua_isnil(L, 2)) {
+ lua_pushnil(L);
+ while (lua_next(L, 2)) {
+ kw = luaL_checkstring(L, -1);
+ found = 0;
+ for (i = 0; i < countof(map); i++)
+ if (!strcmp(kw, map[i].kw)) {
+ flags |= map[i].flag;
+ found = 1;
+ }
+ if (!found)
+ luaL_argerror(L, 2, lua_pushfstring(L, "invalid flag: %s", kw));
+ lua_pop(L, 1);
+ }
+ }
+
+ if (!X509_print_ex(bio, crt, 0, flags))
+ return throwssl(L, "x509.cert:text");
+
+ len = BIO_get_mem_data(bio, &data);
+
+ lua_pushlstring(L, data, len);
+
+ return 1;
+} /* xc_text() */
+
+
static int xc__tostring(lua_State *L) {
X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
int type = optencoding(L, 2, "pem", X509_PEM|X509_DER);
@@ -2762,6 +2837,7 @@ static const luaL_Reg xc_methods[] = {
{ "getPublicKey", &xc_getPublicKey },
{ "setPublicKey", &xc_setPublicKey },
{ "sign", &xc_sign },
+ { "text", &xc_text },
{ "tostring", &xc__tostring },
{ NULL, NULL },
};
@@ -3049,7 +3125,7 @@ static int xx_getLastUpdate(lua_State *L) {
updated = timeutc(time);
if (isfinite(updated))
- lua_pushnumber(L, 1);
+ lua_pushnumber(L, updated);
else
lua_pushnil(L);
@@ -3210,6 +3286,24 @@ static int xx_sign(lua_State *L) {
} /* xx_sign() */
+static int xx_text(lua_State *L) {
+ X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS);
+
+ BIO *bio = getbio(L);
+ char *data;
+ long len;
+
+ if (!X509_CRL_print(bio, crl))
+ return throwssl(L, "x509.crl:text");
+
+ len = BIO_get_mem_data(bio, &data);
+
+ lua_pushlstring(L, data, len);
+
+ return 1;
+} /* xx_text() */
+
+
static int xx__tostring(lua_State *L) {
X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS);
int type = optencoding(L, 2, "pem", X509_PEM|X509_DER);
@@ -3256,6 +3350,7 @@ static const luaL_Reg xx_methods[] = {
{ "setIssuer", &xx_setIssuer },
{ "add", &xx_add },
{ "sign", &xx_sign },
+ { "text", &xx_text },
{ "tostring", &xx__tostring },
{ NULL, NULL },
};
@@ -3670,6 +3765,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_pushfstring(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
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -4213,7 +4426,7 @@ static int cipher_new(lua_State *L) {
static int cipher_interpose(lua_State *L) {
- return interpose(L, HMAC_CLASS);
+ return interpose(L, CIPHER_CLASS);
} /* cipher_interpose() */
@@ -4867,6 +5080,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')