From 132ac48cea935829c31f873aaab920a940bc6b98 Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Mon, 30 Apr 2018 13:49:57 +0300 Subject: [PATCH 08/10] pkey.new: decryption --- src/openssl.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/openssl.c b/src/openssl.c index 2aaa5d8..937ffa6 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -31,7 +31,7 @@ #include /* INT_MAX INT_MIN LLONG_MAX LLONG_MIN UCHAR_MAX ULLONG_MAX */ #include /* uintptr_t */ -#include /* memset(3) strerror_r(3) strlen(3) */ +#include /* memset(3) strerror_r(3) strlen(3) strncpy(3) */ #include /* INFINITY fabs(3) floor(3) frexp(3) fmod(3) round(3) isfinite(3) */ #include /* struct tm time_t strptime(3) time(2) */ #include /* isdigit(3), isxdigit(3), tolower(3) */ @@ -4070,6 +4070,15 @@ static BIO *getbio(lua_State *L) { } /* getbio() */ +static int pem_pw_cb(char *buf, int size, int rwflag, void *u) { + if (!u) + return 0; + char *pass = (char *) u; + strncpy(buf, pass, size); + return MIN(strlen(pass), (unsigned int) size); +} /* pem_pw_cb() */ + + static int pk_new(lua_State *L) { EVP_PKEY **ud; @@ -4309,7 +4318,7 @@ static int pk_new(lua_State *L) { } else if (lua_isstring(L, 1)) { int format; int pubonly = 0, prvtonly = 0; - const char *type, *data; + const char *type, *data, *pass; size_t len; BIO *bio; EVP_PKEY *pub = NULL, *prvt = NULL; @@ -4318,12 +4327,14 @@ static int pk_new(lua_State *L) { if (lua_istable(L, 2)) { lua_getfield(L, 2, "format"); lua_getfield(L, 2, "type"); - } + lua_getfield(L, 2, "password"); + } else + lua_pushnil(L); - format = optencoding(L, -2, "*", X509_ANY|X509_PEM|X509_DER); + format = optencoding(L, -3, "*", X509_ANY|X509_PEM|X509_DER); /* check if specified publickey or privatekey */ - if ((type = luaL_optstring(L, -1, NULL))) { + if ((type = luaL_optstring(L, -2, NULL))) { if (xtolower(type[0]) == 'p' && xtolower(type[1]) == 'u') { pubonly = 1; } else if (xtolower(type[0]) == 'p' && xtolower(type[1]) == 'r') { @@ -4333,6 +4344,13 @@ static int pk_new(lua_State *L) { } } + pass = luaL_optstring(L, -1, NULL); + if (pass) { + if (format == X509_DER) + return luaL_error(L, "decryption supported only for PEM keys"); + else format = X509_PEM; + } + data = luaL_checklstring(L, 1, &len); ud = prepsimple(L, PKEY_CLASS); @@ -4349,14 +4367,14 @@ static int pk_new(lua_State *L) { */ BIO_reset(bio); - if (!(pub = PEM_read_bio_PUBKEY(bio, NULL, 0, ""))) + if (!(pub = PEM_read_bio_PUBKEY(bio, NULL, pem_pw_cb, pass))) goterr = 1; } if (!pubonly && !prvt) { BIO_reset(bio); - if (!(prvt = PEM_read_bio_PrivateKey(bio, NULL, 0, ""))) + if (!(prvt = PEM_read_bio_PrivateKey(bio, NULL, pem_pw_cb, pass))) goterr = 1; } } -- 2.24.1