aboutsummaryrefslogtreecommitdiffstats
path: root/main/lua-ossl/0005-pkey-PEM-password-callback.patch
blob: d3f77cf0292dd4bcabc4facce7dc04eac6359597 (plain) (blame)
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
From b8c6bb03d9638e429e7b0051d9eb0f46e72cb6bd 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 5/5] pkey: PEM password callback

---
 src/openssl.c | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/src/openssl.c b/src/openssl.c
index be585fe..bd9d4ea 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -3428,9 +3428,15 @@ 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) || (lua_isfunction(L, -1) && lua_pcall(L, 0, 1, 0)))
+		return 0;
+
+	const char *pass = lua_tostring(L, -1);
+	if (!pass)
 		return 0;
-	char *pass = (char *) u;
+
 	strncpy(buf, pass, size);
 	return MIN(strlen(pass), (unsigned int) size);
 } /* pem_pw_cb() */
@@ -3646,7 +3652,7 @@ static int pk_new(lua_State *L) {
 	} else if (lua_isstring(L, 1)) {
 		int type = optencoding(L, 2, "*", X509_ANY|X509_PEM|X509_DER);
 		int pubonly = 0, prvtonly = 0;
-		const char *opt, *data, *pass;
+		const char *opt, *data;
 		size_t len;
 		BIO *bio;
 		EVP_PKEY *pub = NULL, *prvt = NULL;
@@ -3664,7 +3670,6 @@ static int pk_new(lua_State *L) {
 		}
 
 		data = luaL_checklstring(L, 1, &len);
-		pass = luaL_optstring(L, 4, NULL);
 
 		ud = prepsimple(L, PKEY_CLASS);
 
@@ -3672,6 +3677,8 @@ static int pk_new(lua_State *L) {
 			return auxL_error(L, auxL_EOPENSSL, "pkey.new");
 
 		if (type == X509_PEM || type == X509_ANY) {
+			lua_pushvalue(L, 4);
+
 			if (!prvtonly && !pub) {
 				/*
 				 * BIO_reset is a rewind for read-only
@@ -3680,16 +3687,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 (type == X509_DER || type == X509_ANY) {
@@ -4116,11 +4125,10 @@ static int pk_toPEM(lua_State *L) {
 static int pk_getPrivateKey(lua_State *L) {
 	EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS);
 	const char *cname = luaL_optstring(L, 2, NULL);
-	const char *pass = NULL;
 	EVP_CIPHER *cipher = NULL;
+	lua_settop(L, 3);
 
 	if (cname) {
-		pass = luaL_checkstring(L, 3);
 		cipher = EVP_get_cipherbyname(cname);
 		if (!cipher)
 			return luaL_error(L, "pkey:getPrivateKey: unknown cipher: %s", cname);
@@ -4130,7 +4138,7 @@ static int pk_getPrivateKey(lua_State *L) {
 	char *str;
 	long len;
 
-	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:getPrivateKey");
 	len = BIO_get_mem_data(bio, &str);
 	lua_pushlstring(L, str, len);
-- 
2.18.0