aboutsummaryrefslogtreecommitdiffstats
path: root/main/lua-ossl/0008-pkey.new-decryption.patch
blob: e143fd04923046ba7137d34f382070b6ba94d2eb (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
From 132ac48cea935829c31f873aaab920a940bc6b98 Mon Sep 17 00:00:00 2001
From: Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>
Date: Mon, 30 Apr 2018 13:49:57 +0300
Subject: [PATCH 08/10] pkey.new: decryption

---
 src/openssl.c | 32 +++++++++++++++++++++++++-------
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/src/openssl.c b/src/openssl.c
index 2aaa5d8..937ffa6 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -31,7 +31,7 @@
 
 #include <limits.h>       /* INT_MAX INT_MIN LLONG_MAX LLONG_MIN UCHAR_MAX ULLONG_MAX */
 #include <stdint.h>       /* uintptr_t */
-#include <string.h>       /* memset(3) strerror_r(3) strlen(3) */
+#include <string.h>       /* memset(3) strerror_r(3) strlen(3) strncpy(3) */
 #include <math.h>         /* INFINITY fabs(3) floor(3) frexp(3) fmod(3) round(3) isfinite(3) */
 #include <time.h>         /* struct tm time_t strptime(3) time(2) */
 #include <ctype.h>        /* isdigit(3), isxdigit(3), tolower(3) */
@@ -4070,6 +4070,15 @@ static BIO *getbio(lua_State *L) {
 } /* getbio() */
 
 
+static int pem_pw_cb(char *buf, int size, int rwflag, void *u) {
+	if (!u)
+		return 0;
+	char *pass = (char *) u;
+	strncpy(buf, pass, size);
+	return MIN(strlen(pass), (unsigned int) size);
+} /* pem_pw_cb() */
+
+
 static int pk_new(lua_State *L) {
 	EVP_PKEY **ud;
 
@@ -4309,7 +4318,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;
+		const char *type, *data, *pass;
 		size_t len;
 		BIO *bio;
 		EVP_PKEY *pub = NULL, *prvt = NULL;
@@ -4318,12 +4327,14 @@ static int pk_new(lua_State *L) {
 		if (lua_istable(L, 2)) {
 			lua_getfield(L, 2, "format");
 			lua_getfield(L, 2, "type");
-		}
+			lua_getfield(L, 2, "password");
+		} else
+			lua_pushnil(L);
 
-		format = optencoding(L, -2, "*", X509_ANY|X509_PEM|X509_DER);
+		format = optencoding(L, -3, "*", X509_ANY|X509_PEM|X509_DER);
 
 		/* check if specified publickey or privatekey */
-		if ((type = luaL_optstring(L, -1, NULL))) {
+		if ((type = luaL_optstring(L, -2, NULL))) {
 			if (xtolower(type[0]) == 'p' && xtolower(type[1]) == 'u') {
 				pubonly = 1;
 			} else if (xtolower(type[0]) == 'p' && xtolower(type[1]) == 'r') {
@@ -4333,6 +4344,13 @@ static int pk_new(lua_State *L) {
 			}
 		}
 
+		pass = luaL_optstring(L, -1, NULL);
+		if (pass) {
+			if (format == X509_DER)
+				return luaL_error(L, "decryption supported only for PEM keys");
+			else format = X509_PEM;
+		}
+
 		data = luaL_checklstring(L, 1, &len);
 
 		ud = prepsimple(L, PKEY_CLASS);
@@ -4349,14 +4367,14 @@ static int pk_new(lua_State *L) {
 				 */
 				BIO_reset(bio);
 
-				if (!(pub = PEM_read_bio_PUBKEY(bio, NULL, 0, "")))
+				if (!(pub = PEM_read_bio_PUBKEY(bio, NULL, pem_pw_cb, pass)))
 					goterr = 1;
 			}
 
 			if (!pubonly && !prvt) {
 				BIO_reset(bio);
 
-				if (!(prvt = PEM_read_bio_PrivateKey(bio, NULL, 0, "")))
+				if (!(prvt = PEM_read_bio_PrivateKey(bio, NULL, pem_pw_cb, pass)))
 					goterr = 1;
 			}
 		}
-- 
2.24.1