@@ -4062,10 +4062,32 @@ static BIO *getbio(lua_State *L) {
4062
4062
} /* getbio() */
4063
4063
4064
4064
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
+ */
4065
4076
static 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 ))
4067
4085
return 0 ;
4068
- char * pass = (char * ) u ;
4086
+
4087
+ const char * pass = lua_tostring (L , -1 );
4088
+ if (!pass )
4089
+ return 0 ;
4090
+
4069
4091
strncpy (buf , pass , size );
4070
4092
return MIN (strlen (pass ), (unsigned int ) size );
4071
4093
} /* pem_pw_cb() */
@@ -4310,7 +4332,7 @@ static int pk_new(lua_State *L) {
4310
4332
} else if (lua_isstring (L , 1 )) {
4311
4333
int format ;
4312
4334
int pubonly = 0 , prvtonly = 0 ;
4313
- const char * type , * data , * pass ;
4335
+ const char * type , * data ;
4314
4336
size_t len ;
4315
4337
BIO * bio ;
4316
4338
EVP_PKEY * pub = NULL , * prvt = NULL ;
@@ -4341,8 +4363,7 @@ static int pk_new(lua_State *L) {
4341
4363
}
4342
4364
}
4343
4365
4344
- pass = luaL_optstring (L , 4 , NULL );
4345
- if (pass ) {
4366
+ if (!lua_isnil (L , 4 )) {
4346
4367
if (format == X509_DER )
4347
4368
return luaL_error (L , "decryption supported only for PEM keys" );
4348
4369
else format = X509_PEM ;
@@ -4354,6 +4375,8 @@ static int pk_new(lua_State *L) {
4354
4375
return auxL_error (L , auxL_EOPENSSL , "pkey.new" );
4355
4376
4356
4377
if (format == X509_PEM || format == X509_ANY ) {
4378
+ lua_pushvalue (L , 4 );
4379
+
4357
4380
if (!prvtonly && !pub ) {
4358
4381
/*
4359
4382
* BIO_reset is a rewind for read-only
@@ -4362,16 +4385,18 @@ static int pk_new(lua_State *L) {
4362
4385
*/
4363
4386
BIO_reset (bio );
4364
4387
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 )))
4366
4389
goterr = 1 ;
4367
4390
}
4368
4391
4369
4392
if (!pubonly && !prvt ) {
4370
4393
BIO_reset (bio );
4371
4394
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 )))
4373
4396
goterr = 1 ;
4374
4397
}
4398
+
4399
+ lua_pop (L , 1 );
4375
4400
}
4376
4401
4377
4402
if (format == X509_DER || format == X509_ANY ) {
@@ -4712,7 +4737,6 @@ static int pk_toPEM(lua_State *L) {
4712
4737
int type ;
4713
4738
const char * cname = NULL ;
4714
4739
const EVP_CIPHER * cipher = NULL ;
4715
- const char * pass = NULL ;
4716
4740
4717
4741
if (lua_istable (L , i )) {
4718
4742
loadfield (L , i , "cipher" , LUA_TSTRING , & cname );
@@ -4739,13 +4763,17 @@ static int pk_toPEM(lua_State *L) {
4739
4763
cipher = EVP_get_cipherbyname (cname );
4740
4764
if (!cipher )
4741
4765
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" ))
4743
4767
return luaL_error (L , "pkey:toPEM: password not defined" );
4744
4768
}
4769
+ else
4770
+ lua_pushnil (L );
4745
4771
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 ))
4747
4773
return auxL_error (L , auxL_EOPENSSL , "pkey:__tostring" );
4748
4774
4775
+ lua_pop (L , 1 );
4776
+
4749
4777
len = BIO_get_mem_data (bio , & pem );
4750
4778
lua_pushlstring (L , pem , len );
4751
4779
BIO_reset (bio );
0 commit comments