@@ -4062,10 +4062,32 @@ 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 type is not
4073+ * specified. The user-provided function is called only once because it gets
4074+ * replaced by the return value.
4075+ */
40654076static int pem_pw_cb (char * buf , int size , int rwflag , void * u ) {
4066- if (!u )
4077+ lua_State * L = (lua_State * ) u ;
4078+
4079+ if (lua_isfunction (L , -1 ) && lua_pcall (L , 0 , 1 , 0 )) {
4080+ lua_pop (L , 1 );
4081+ lua_pushnil (L );
4082+ }
4083+
4084+ if (lua_isnil (L , -1 ))
40674085 return 0 ;
4068- char * pass = (char * ) u ;
4086+
4087+ const char * pass = lua_tostring (L , -1 );
4088+ if (!pass )
4089+ return 0 ;
4090+
40694091 strncpy (buf , pass , size );
40704092 return MIN (strlen (pass ), (unsigned int ) size );
40714093} /* pem_pw_cb() */
@@ -4310,7 +4332,7 @@ static int pk_new(lua_State *L) {
43104332 } else if (lua_isstring (L , 1 )) {
43114333 int format ;
43124334 int pubonly = 0 , prvtonly = 0 ;
4313- const char * type , * data , * pass ;
4335+ const char * type , * data ;
43144336 size_t len ;
43154337 BIO * bio ;
43164338 EVP_PKEY * pub = NULL , * prvt = NULL ;
@@ -4341,8 +4363,7 @@ static int pk_new(lua_State *L) {
43414363 }
43424364 }
43434365
4344- pass = luaL_optstring (L , 4 , NULL );
4345- if (pass ) {
4366+ if (!lua_isnil (L , 4 )) {
43464367 if (format == X509_DER )
43474368 return luaL_error (L , "decryption supported only for PEM keys" );
43484369 else format = X509_PEM ;
@@ -4354,6 +4375,8 @@ static int pk_new(lua_State *L) {
43544375 return auxL_error (L , auxL_EOPENSSL , "pkey.new" );
43554376
43564377 if (format == X509_PEM || format == X509_ANY ) {
4378+ lua_pushvalue (L , 4 );
4379+
43574380 if (!prvtonly && !pub ) {
43584381 /*
43594382 * BIO_reset is a rewind for read-only
@@ -4362,16 +4385,18 @@ static int pk_new(lua_State *L) {
43624385 */
43634386 BIO_reset (bio );
43644387
4365- if (!(pub = PEM_read_bio_PUBKEY (bio , NULL , pem_pw_cb , pass )))
4388+ if (!(pub = PEM_read_bio_PUBKEY (bio , NULL , pem_pw_cb , L )))
43664389 goterr = 1 ;
43674390 }
43684391
43694392 if (!pubonly && !prvt ) {
43704393 BIO_reset (bio );
43714394
4372- if (!(prvt = PEM_read_bio_PrivateKey (bio , NULL , pem_pw_cb , pass )))
4395+ if (!(prvt = PEM_read_bio_PrivateKey (bio , NULL , pem_pw_cb , L )))
43734396 goterr = 1 ;
43744397 }
4398+
4399+ lua_pop (L , 1 );
43754400 }
43764401
43774402 if (format == X509_DER || format == X509_ANY ) {
@@ -4712,7 +4737,6 @@ static int pk_toPEM(lua_State *L) {
47124737 int type ;
47134738 const char * cname = NULL ;
47144739 const EVP_CIPHER * cipher = NULL ;
4715- const char * pass = NULL ;
47164740
47174741 if (lua_istable (L , i )) {
47184742 loadfield (L , i , "cipher" , LUA_TSTRING , & cname );
@@ -4739,13 +4763,17 @@ static int pk_toPEM(lua_State *L) {
47394763 cipher = EVP_get_cipherbyname (cname );
47404764 if (!cipher )
47414765 return luaL_error (L , "pkey:toPEM: unknown cipher: %s" , cname );
4742- if (!loadfield (L , i , "password" , LUA_TSTRING , & pass ))
4766+ if (!getfield (L , i , "password" ))
47434767 return luaL_error (L , "pkey:toPEM: password not defined" );
47444768 }
4769+ else
4770+ lua_pushnil (L );
47454771
4746- if (!PEM_write_bio_PrivateKey (bio , key , cipher , NULL , 0 , pem_pw_cb , pass ))
4772+ if (!PEM_write_bio_PrivateKey (bio , key , cipher , NULL , 0 , pem_pw_cb , L ))
47474773 return auxL_error (L , auxL_EOPENSSL , "pkey:__tostring" );
47484774
4775+ lua_pop (L , 1 );
4776+
47494777 len = BIO_get_mem_data (bio , & pem );
47504778 lua_pushlstring (L , pem , len );
47514779 BIO_reset (bio );
0 commit comments