@@ -4105,10 +4105,28 @@ static BIO *getbio(lua_State *L) {
41054105} /* getbio() */
41064106
41074107
4108+ /*
4109+ * PEM password callback for openssl
4110+ *
4111+ * Expects nil, string, or function on top of the stack. Leaves one item on the
4112+ * top of the stack: the original string, the string returned by the function,
4113+ * or nil (in case of an error or missing password).
4114+ *
4115+ * This callback may be called twice by pk_new when the PEM key is encrypted and
4116+ * its type is not specified. The user-provided function is called only once
4117+ * because it gets replaced on the stack by the return value. This callback may
4118+ * not be called at all if the supplied PEM key is not encrypted.
4119+ */
41084120static int pem_pw_cb (char * buf , int size , int rwflag , void * u ) {
4109- if (!u )
4121+ lua_State * L = (lua_State * ) u ;
4122+
4123+ if (lua_isfunction (L , -1 ) && lua_pcall (L , 0 , 1 , 0 ) || !lua_isstring (L , -1 )) {
4124+ lua_pop (L , 1 );
4125+ lua_pushnil (L );
41104126 return -1 ;
4111- char * pass = (char * ) u ;
4127+ }
4128+
4129+ const char * pass = lua_tostring (L , -1 );
41124130 strncpy (buf , pass , size );
41134131 return MIN (strlen (pass ), (unsigned int ) size );
41144132} /* pem_pw_cb() */
@@ -4353,7 +4371,7 @@ static int pk_new(lua_State *L) {
43534371 } else if (lua_isstring (L , 1 )) {
43544372 int format ;
43554373 int pubonly = 0 , prvtonly = 0 ;
4356- const char * type , * data , * pass ;
4374+ const char * type , * data ;
43574375 size_t len ;
43584376 BIO * bio ;
43594377 EVP_PKEY * pub = NULL , * prvt = NULL ;
@@ -4384,8 +4402,7 @@ static int pk_new(lua_State *L) {
43844402 }
43854403 }
43864404
4387- pass = luaL_optstring (L , 4 , NULL );
4388- if (pass ) {
4405+ if (!lua_isnil (L , 4 )) {
43894406 if (format == X509_DER )
43904407 return luaL_error (L , "decryption supported only for PEM keys" );
43914408 else format = X509_PEM ;
@@ -4397,6 +4414,8 @@ static int pk_new(lua_State *L) {
43974414 return auxL_error (L , auxL_EOPENSSL , "pkey.new" );
43984415
43994416 if (format == X509_PEM || format == X509_ANY ) {
4417+ lua_pushvalue (L , 4 );
4418+
44004419 if (!prvtonly && !pub ) {
44014420 /*
44024421 * BIO_reset is a rewind for read-only
@@ -4405,16 +4424,18 @@ static int pk_new(lua_State *L) {
44054424 */
44064425 BIO_reset (bio );
44074426
4408- if (!(pub = PEM_read_bio_PUBKEY (bio , NULL , pem_pw_cb , pass )))
4427+ if (!(pub = PEM_read_bio_PUBKEY (bio , NULL , pem_pw_cb , L )))
44094428 goterr = 1 ;
44104429 }
44114430
44124431 if (!pubonly && !prvt ) {
44134432 BIO_reset (bio );
44144433
4415- if (!(prvt = PEM_read_bio_PrivateKey (bio , NULL , pem_pw_cb , pass )))
4434+ if (!(prvt = PEM_read_bio_PrivateKey (bio , NULL , pem_pw_cb , L )))
44164435 goterr = 1 ;
44174436 }
4437+
4438+ lua_pop (L , 1 );
44184439 }
44194440
44204441 if (format == X509_DER || format == X509_ANY ) {
@@ -4755,7 +4776,6 @@ static int pk_toPEM(lua_State *L) {
47554776 int type ;
47564777 const char * cname = NULL ;
47574778 const EVP_CIPHER * cipher = NULL ;
4758- const char * pass = NULL ;
47594779
47604780 if (lua_istable (L , i )) {
47614781 loadfield (L , i , "cipher" , LUA_TSTRING , & cname );
@@ -4782,13 +4802,17 @@ static int pk_toPEM(lua_State *L) {
47824802 cipher = EVP_get_cipherbyname (cname );
47834803 if (!cipher )
47844804 return luaL_error (L , "pkey:toPEM: unknown cipher: %s" , cname );
4785- if (!loadfield (L , i , "password" , LUA_TSTRING , & pass ))
4805+ if (!getfield (L , i , "password" ))
47864806 return luaL_error (L , "pkey:toPEM: password not defined" );
47874807 }
4808+ else
4809+ lua_pushnil (L );
47884810
4789- if (!PEM_write_bio_PrivateKey (bio , key , cipher , NULL , 0 , pem_pw_cb , pass ))
4811+ if (!PEM_write_bio_PrivateKey (bio , key , cipher , NULL , 0 , pem_pw_cb , L ))
47904812 return auxL_error (L , auxL_EOPENSSL , "pkey:__tostring" );
47914813
4814+ lua_pop (L , 1 );
4815+
47924816 len = BIO_get_mem_data (bio , & pem );
47934817 lua_pushlstring (L , pem , len );
47944818 BIO_reset (bio );
0 commit comments