From 367597c9fbbd8c0179a8b2a75e5b0819ef5bc5d6 Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Mon, 30 Apr 2018 13:26:16 +0300 Subject: [PATCH 03/10] pkey.toPEM: private key encryption --- src/openssl.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/openssl.c b/src/openssl.c index 1905693..9b10165 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) */ +#include /* memset(3) strerror_r(3) strlen(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) */ @@ -4682,11 +4682,16 @@ static int pk_toPEM(lua_State *L) { NULL, }; int type; - - if (!lua_istable(L, i)) + const char *cname = NULL; + const EVP_CIPHER *cipher = NULL; + const char *pass = NULL; + + if (lua_istable(L, i)) { + loadfield(L, i, "cipher", LUA_TSTRING, &cname); + if (!getfield(L, i, "type")) + lua_pushstring(L, cname ? "private" : "public"); + } else lua_pushvalue(L, i); - else if (!getfield(L, i, "type")) - lua_pushliteral(L, "public"); type = auxL_checkoption(L, -1, NULL, types, 1); lua_pop(L, 1); @@ -4702,7 +4707,15 @@ static int pk_toPEM(lua_State *L) { break; case 2: case 3: /* private, PrivateKey */ - if (!PEM_write_bio_PrivateKey(bio, key, 0, 0, 0, 0, 0)) + if (cname) { + cipher = EVP_get_cipherbyname(cname); + if (!cipher) + return luaL_error(L, "pkey:toPEM: unknown cipher: %s", cname); + if (!loadfield(L, i, "password", LUA_TSTRING, &pass)) + return luaL_error(L, "pkey:toPEM: password not defined"); + } + + if (!PEM_write_bio_PrivateKey(bio, key, cipher, pass, pass ? strlen(pass) : 0, 0, 0)) return auxL_error(L, auxL_EOPENSSL, "pkey:__tostring"); len = BIO_get_mem_data(bio, &pem); -- 2.24.1