Skip to content

Commit 652de88

Browse files
committed
pkey: PEM password callback
1 parent 4f41ae9 commit 652de88

File tree

1 file changed

+39
-10
lines changed

1 file changed

+39
-10
lines changed

src/openssl.c

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4062,10 +4062,33 @@ static BIO *getbio(lua_State *L) {
40624062
} /* getbio() */
40634063

40644064

4065+
/*
4066+
* PEM password callback for openssl
4067+
*
4068+
* Expects nil, string, or function on top of the stack. Errors from the
4069+
* user-provided function are not reported. Leaves one item on the top of the
4070+
* stack: nil, the original string, or the return value.
4071+
*
4072+
* This callback may be called twice by pk_new when the PEM key is encrypted
4073+
* and its type is not specified. The user-provided function is called only
4074+
* once because it gets replaced on the stack by the return value. This
4075+
* callback may not be called at all if the supplied PEM key is not encrypted.
4076+
*/
40654077
static int pem_pw_cb(char *buf, int size, int rwflag, void *u) {
4066-
if (!u)
4078+
lua_State *L = (lua_State *) u;
4079+
4080+
if (lua_isfunction(L, -1) && lua_pcall(L, 0, 1, 0)) {
4081+
lua_pop(L, 1);
4082+
lua_pushnil(L);
4083+
}
4084+
4085+
if (lua_isnil(L, -1))
40674086
return 0;
4068-
char *pass = (char *) u;
4087+
4088+
const char *pass = lua_tostring(L, -1);
4089+
if (!pass)
4090+
return 0;
4091+
40694092
strncpy(buf, pass, size);
40704093
return MIN(strlen(pass), (unsigned int) size);
40714094
} /* pem_pw_cb() */
@@ -4310,7 +4333,7 @@ static int pk_new(lua_State *L) {
43104333
} else if (lua_isstring(L, 1)) {
43114334
int format;
43124335
int pubonly = 0, prvtonly = 0;
4313-
const char *type, *data, *pass;
4336+
const char *type, *data;
43144337
size_t len;
43154338
BIO *bio;
43164339
EVP_PKEY *pub = NULL, *prvt = NULL;
@@ -4341,8 +4364,7 @@ static int pk_new(lua_State *L) {
43414364
}
43424365
}
43434366

4344-
pass = luaL_optstring(L, 4, NULL);
4345-
if (pass) {
4367+
if (!lua_isnil(L, 4)) {
43464368
if (format == X509_DER)
43474369
return luaL_error(L, "decryption supported only for PEM keys");
43484370
else format = X509_PEM;
@@ -4354,6 +4376,8 @@ static int pk_new(lua_State *L) {
43544376
return auxL_error(L, auxL_EOPENSSL, "pkey.new");
43554377

43564378
if (format == X509_PEM || format == X509_ANY) {
4379+
lua_pushvalue(L, 4);
4380+
43574381
if (!prvtonly && !pub) {
43584382
/*
43594383
* BIO_reset is a rewind for read-only
@@ -4362,16 +4386,18 @@ static int pk_new(lua_State *L) {
43624386
*/
43634387
BIO_reset(bio);
43644388

4365-
if (!(pub = PEM_read_bio_PUBKEY(bio, NULL, pem_pw_cb, pass)))
4389+
if (!(pub = PEM_read_bio_PUBKEY(bio, NULL, pem_pw_cb, L)))
43664390
goterr = 1;
43674391
}
43684392

43694393
if (!pubonly && !prvt) {
43704394
BIO_reset(bio);
43714395

4372-
if (!(prvt = PEM_read_bio_PrivateKey(bio, NULL, pem_pw_cb, pass)))
4396+
if (!(prvt = PEM_read_bio_PrivateKey(bio, NULL, pem_pw_cb, L)))
43734397
goterr = 1;
43744398
}
4399+
4400+
lua_pop(L, 1);
43754401
}
43764402

43774403
if (format == X509_DER || format == X509_ANY) {
@@ -4712,7 +4738,6 @@ static int pk_toPEM(lua_State *L) {
47124738
int type;
47134739
const char *cname = NULL;
47144740
const EVP_CIPHER *cipher = NULL;
4715-
const char *pass = NULL;
47164741

47174742
if (lua_istable(L, i)) {
47184743
loadfield(L, i, "cipher", LUA_TSTRING, &cname);
@@ -4739,13 +4764,17 @@ static int pk_toPEM(lua_State *L) {
47394764
cipher = EVP_get_cipherbyname(cname);
47404765
if (!cipher)
47414766
return luaL_error(L, "pkey:toPEM: unknown cipher: %s", cname);
4742-
if (!loadfield(L, i, "password", LUA_TSTRING, &pass))
4767+
if (!getfield(L, i, "password"))
47434768
return luaL_error(L, "pkey:toPEM: password not defined");
47444769
}
4770+
else
4771+
lua_pushnil(L);
47454772

4746-
if (!PEM_write_bio_PrivateKey(bio, key, cipher, NULL, 0, pem_pw_cb, pass))
4773+
if (!PEM_write_bio_PrivateKey(bio, key, cipher, NULL, 0, pem_pw_cb, L))
47474774
return auxL_error(L, auxL_EOPENSSL, "pkey:__tostring");
47484775

4776+
lua_pop(L, 1);
4777+
47494778
len = BIO_get_mem_data(bio, &pem);
47504779
lua_pushlstring(L, pem, len);
47514780
BIO_reset(bio);

0 commit comments

Comments
 (0)