From b8c6bb03d9638e429e7b0051d9eb0f46e72cb6bd Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Thu, 3 May 2018 21:37:30 +0300 Subject: [PATCH 5/5] pkey: PEM password callback --- src/openssl.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/openssl.c b/src/openssl.c index be585fe..bd9d4ea 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -3428,9 +3428,15 @@ static BIO *getbio(lua_State *L) { static int pem_pw_cb(char *buf, int size, int rwflag, void *u) { - if (!u) + lua_State *L = (lua_State *) u; + + if (lua_isnil(L, -1) || (lua_isfunction(L, -1) && lua_pcall(L, 0, 1, 0))) + return 0; + + const char *pass = lua_tostring(L, -1); + if (!pass) return 0; - char *pass = (char *) u; + strncpy(buf, pass, size); return MIN(strlen(pass), (unsigned int) size); } /* pem_pw_cb() */ @@ -3646,7 +3652,7 @@ static int pk_new(lua_State *L) { } else if (lua_isstring(L, 1)) { int type = optencoding(L, 2, "*", X509_ANY|X509_PEM|X509_DER); int pubonly = 0, prvtonly = 0; - const char *opt, *data, *pass; + const char *opt, *data; size_t len; BIO *bio; EVP_PKEY *pub = NULL, *prvt = NULL; @@ -3664,7 +3670,6 @@ static int pk_new(lua_State *L) { } data = luaL_checklstring(L, 1, &len); - pass = luaL_optstring(L, 4, NULL); ud = prepsimple(L, PKEY_CLASS); @@ -3672,6 +3677,8 @@ static int pk_new(lua_State *L) { return auxL_error(L, auxL_EOPENSSL, "pkey.new"); if (type == X509_PEM || type == X509_ANY) { + lua_pushvalue(L, 4); + if (!prvtonly && !pub) { /* * BIO_reset is a rewind for read-only @@ -3680,16 +3687,18 @@ static int pk_new(lua_State *L) { */ BIO_reset(bio); - if (!(pub = PEM_read_bio_PUBKEY(bio, NULL, pem_pw_cb, pass))) + if (!(pub = PEM_read_bio_PUBKEY(bio, NULL, pem_pw_cb, L))) goterr = 1; } if (!pubonly && !prvt) { BIO_reset(bio); - if (!(prvt = PEM_read_bio_PrivateKey(bio, NULL, pem_pw_cb, pass))) + if (!(prvt = PEM_read_bio_PrivateKey(bio, NULL, pem_pw_cb, L))) goterr = 1; } + + lua_pop(L, 1); } if (type == X509_DER || type == X509_ANY) { @@ -4116,11 +4125,10 @@ static int pk_toPEM(lua_State *L) { static int pk_getPrivateKey(lua_State *L) { EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS); const char *cname = luaL_optstring(L, 2, NULL); - const char *pass = NULL; EVP_CIPHER *cipher = NULL; + lua_settop(L, 3); if (cname) { - pass = luaL_checkstring(L, 3); cipher = EVP_get_cipherbyname(cname); if (!cipher) return luaL_error(L, "pkey:getPrivateKey: unknown cipher: %s", cname); @@ -4130,7 +4138,7 @@ static int pk_getPrivateKey(lua_State *L) { char *str; long len; - if (!PEM_write_bio_PrivateKey(bio, key, cipher, NULL, 0, pem_pw_cb, pass)) + if (!PEM_write_bio_PrivateKey(bio, key, cipher, NULL, 0, pem_pw_cb, L)) return auxL_error(L, auxL_EOPENSSL, "pkey:getPrivateKey"); len = BIO_get_mem_data(bio, &str); lua_pushlstring(L, str, len); -- 2.18.0