1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
From cf6557954e012cb9f4453d84566bec30958c5a58 Mon Sep 17 00:00:00 2001
From: Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>
Date: Thu, 3 May 2018 21:37:30 +0300
Subject: [PATCH 10/10] pkey: PEM password callback
---
src/openssl.c | 37 +++++++++++++++++++++++++++----------
1 file changed, 27 insertions(+), 10 deletions(-)
diff --git a/src/openssl.c b/src/openssl.c
index 3af285b..03c2b68 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -4071,9 +4071,21 @@ 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))
return 0;
- char *pass = (char *) u;
+
+ if (lua_isfunction(L, -1) && lua_pcall(L, 0, 1, 0)) {
+ lua_pop(L, 1);
+ lua_pushnil(L);
+ return 0;
+ }
+
+ const char *pass = lua_tostring(L, -1);
+ if (!pass)
+ return 0;
+
strncpy(buf, pass, size);
return MIN(strlen(pass), (unsigned int) size);
} /* pem_pw_cb() */
@@ -4318,7 +4330,7 @@ static int pk_new(lua_State *L) {
} else if (lua_isstring(L, 1)) {
int format;
int pubonly = 0, prvtonly = 0;
- const char *type, *data, *pass;
+ const char *type, *data;
size_t len;
BIO *bio;
EVP_PKEY *pub = NULL, *prvt = NULL;
@@ -4344,8 +4356,7 @@ static int pk_new(lua_State *L) {
}
}
- pass = luaL_optstring(L, -1, NULL);
- if (pass) {
+ if (!lua_isnil(L, -1)) {
if (format == X509_DER)
return luaL_error(L, "decryption supported only for PEM keys");
else format = X509_PEM;
@@ -4359,6 +4370,8 @@ static int pk_new(lua_State *L) {
return auxL_error(L, auxL_EOPENSSL, "pkey.new");
if (format == X509_PEM || format == X509_ANY) {
+ lua_pushvalue(L, -2);
+
if (!prvtonly && !pub) {
/*
* BIO_reset is a rewind for read-only
@@ -4367,16 +4380,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 (format == X509_DER || format == X509_ANY) {
@@ -4717,7 +4732,6 @@ static int pk_toPEM(lua_State *L) {
int type;
const char *cname = NULL;
const EVP_CIPHER *cipher = NULL;
- const char *pass = NULL;
if (lua_istable(L, i)) {
loadfield(L, i, "cipher", LUA_TSTRING, &cname);
@@ -4744,13 +4758,16 @@ static int pk_toPEM(lua_State *L) {
cipher = EVP_get_cipherbyname(cname);
if (!cipher)
return luaL_error(L, "pkey:toPEM: unknown cipher: %s", cname);
- if (!loadfield(L, i, "password", LUA_TSTRING, &pass))
+ if (!getfield(L, i, "password"))
return luaL_error(L, "pkey:toPEM: password not defined");
}
- 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:__tostring");
+ if (cname)
+ lua_pop(L, 1);
+
len = BIO_get_mem_data(bio, &pem);
lua_pushlstring(L, pem, len);
BIO_reset(bio);
--
2.24.1
|