Blob Blame History Raw
From 903955971a5461e0ee207af03b075687306f4c0b Mon Sep 17 00:00:00 2001
From: John Regan <john@jrjrtech.com>
Date: Wed, 4 May 2022 15:18:57 -0400
Subject: [PATCH] openssl 3.0.0 compatibility

---
 regress/regress.lua |   2 +-
 src/openssl.c       | 168 +++++++++++++++++++++++++++++++++++++-------
 2 files changed, 144 insertions(+), 26 deletions(-)

diff --git a/regress/regress.lua b/regress/regress.lua
index 044e342..f1038f7 100644
--- a/regress/regress.lua
+++ b/regress/regress.lua
@@ -126,7 +126,7 @@ function regress.genkey(type, ca_key, ca_crt)
 	if type == "EC" then
 		key = regress.check(pkey.new{ type = "EC",  curve = "prime192v1" })
 	else
-		key = regress.check(pkey.new{ type = type, bits = 1024 })
+		key = regress.check(pkey.new{ type = type, bits = 2048 })
 	end
 
 	local dn = name.new()
diff --git a/src/openssl.c b/src/openssl.c
index b56c78a..198e6a6 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -236,7 +236,11 @@
 #endif
 
 #ifndef HAVE_EVP_KDF_CTX
-#define HAVE_EVP_KDF_CTX OPENSSL_PREREQ(1,2,0)
+#define HAVE_EVP_KDF_CTX OPENSSL_PREREQ(3,0,0)
+#endif
+
+#ifndef HAVE_OSSL_PARAM
+#define HAVE_OSSL_PARAM OPENSSL_PREREQ(3,0,0)
 #endif
 
 #ifndef HAVE_PKCS5_PBKDF2_HMAC
@@ -617,6 +621,10 @@
 #include <openssl/kdf.h>
 #endif
 
+#if HAVE_EVP_KDF_CTX
+#include <openssl/core_names.h>
+#endif
+
 #ifndef STRERROR_R_CHAR_P
 #ifdef __GLIBC__
 #define STRERROR_R_CHAR_P (_GNU_SOURCE || !(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600))
@@ -1467,7 +1475,11 @@ static const char *auxL_pusherror(lua_State *L, int error, const char *fun) {
 		if (!ERR_peek_error())
 			return lua_pushliteral(L, "oops: no OpenSSL errors set");
 
+#if OPENSSL_PREREQ(3,0,0)
+		code = ERR_get_error_all(&path, &line, NULL, NULL, NULL);
+#else
 		code = ERR_get_error_line(&path, &line);
+#endif
 
 		if ((file = strrchr(path, '/'))) {
 			++file;
@@ -2231,7 +2243,7 @@ STACK_OF(X509) *compat_X509_chain_up_ref(STACK_OF(X509) *chain) {
 
 #if !HAVE_EVP_KDF_CTX
 /*
- * Emulate EVP_KDF_CTX API (introduced in OpenSSL 1.2.0)
+ * Emulate EVP_KDF_CTX API (introduced in OpenSSL 3.0.0)
  */
 
 #ifndef ERR_LIB_KDF
@@ -2321,7 +2333,21 @@ static void EVP_KDF_CTX_free(EVP_KDF_CTX *kctx) {
 	OPENSSL_free(kctx);
 } /* EVP_KDF_CTX_free() */
 
-static EVP_KDF_CTX *EVP_KDF_CTX_new_id(int id) {
+typedef int LUAOSSL_EVP_KDF_PTR;
+#define LUAOSSL_EVP_KDF_UNDEF NID_undef
+
+static LUAOSSL_EVP_KDF_PTR EVP_KDF_fetch(void *libctx, const char *algorithm, const char *properties) {
+    LUAOSSL_EVP_KDF_PTR kdf;
+    (void)libctx;
+    (void)properties;
+
+    if(!auxS_txt2nid(&kdf,algorithm)) {
+        return LUAOSSL_EVP_KDF_UNDEF;
+    }
+    return kdf;
+}
+
+static EVP_KDF_CTX *EVP_KDF_CTX_new(LUAOSSL_EVP_KDF_PTR kdf) {
 	EVP_KDF_CTX *ret;
 
 	ret = OPENSSL_zalloc(sizeof(*ret));
@@ -2330,9 +2356,9 @@ static EVP_KDF_CTX *EVP_KDF_CTX_new_id(int id) {
 		return NULL;
 	}
 
-	ret->nid = id;
+	ret->nid = kdf;
 
-	switch(id) {
+	switch(kdf) {
 #if HAVE_PKCS5_PBKDF2_HMAC
 	case NID_id_pbkdf2:
 		break;
@@ -2344,7 +2370,7 @@ static EVP_KDF_CTX *EVP_KDF_CTX_new_id(int id) {
 #if HAVE_EVP_PKEY_CTX_KDF
 	case NID_tls1_prf:
 	case NID_hkdf: {
-			ret->pctx = EVP_PKEY_CTX_new_id(id, NULL);
+			ret->pctx = EVP_PKEY_CTX_new_id(kdf, NULL);
 			if (!ret->pctx) {
 				OPENSSL_free(ret);
 				return NULL;
@@ -2364,7 +2390,7 @@ static EVP_KDF_CTX *EVP_KDF_CTX_new_id(int id) {
 	}
 
 	return ret;
-} /* EVP_KDF_CTX_new_id() */
+} /* EVP_KDF_CTX_new() */
 
 static int set_membuf(unsigned char **buffer, size_t *buflen, const unsigned char *new_buffer, size_t new_buflen) {
 	if (new_buffer == NULL)
@@ -2589,7 +2615,7 @@ static int EVP_KDF_ctrl(EVP_KDF_CTX *kctx, int cmd, ...) {
 	return ret;
 } /* EVP_KDF_ctrl() */
 
-static size_t EVP_KDF_size(EVP_KDF_CTX *kctx) {
+static size_t EVP_KDF_CTX_get_kdf_size(EVP_KDF_CTX *kctx) {
 	if (kctx == NULL)
 		return 0;
 
@@ -2605,9 +2631,9 @@ static size_t EVP_KDF_size(EVP_KDF_CTX *kctx) {
 	default:
 		return SIZE_MAX;
 	}
-} /* EVP_KDF_size() */
+} /* EVP_KDF_CTX_get_kdf_size() */
 
-static int EVP_KDF_derive(EVP_KDF_CTX *kctx, unsigned char *out, size_t *outlen) {
+static int EVP_KDF_derive(EVP_KDF_CTX *kctx, unsigned char *out, size_t outlen, void *params) {
 	switch(kctx->nid) {
 #if HAVE_PKCS5_PBKDF2_HMAC
 	case NID_id_pbkdf2:
@@ -2615,7 +2641,7 @@ static int EVP_KDF_derive(EVP_KDF_CTX *kctx, unsigned char *out, size_t *outlen)
 			kctx->pbkdf2.salt, kctx->pbkdf2.saltlen,
 			kctx->pbkdf2.iter,
 			kctx->pbkdf2.md,
-			*outlen, out);
+			outlen, out);
 #endif
 #if HAVE_SCRYPT
 	case NID_id_scrypt:
@@ -2623,20 +2649,24 @@ static int EVP_KDF_derive(EVP_KDF_CTX *kctx, unsigned char *out, size_t *outlen)
 			kctx->scrypt.salt, kctx->scrypt.saltlen,
 			kctx->scrypt.N, kctx->scrypt.r, kctx->scrypt.p,
 			kctx->scrypt.maxmem_bytes,
-			out, *outlen);
+			out, outlen);
 #endif
 #if HAVE_EVP_PKEY_CTX_KDF
 	case NID_tls1_prf:
 	case NID_hkdf:
-		return EVP_PKEY_derive(kctx->pctx, out, outlen);
+		return EVP_PKEY_derive(kctx->pctx, out, &outlen);
 #endif
 	default:
 		(void)out;
 		(void)outlen;
+		(void)params;
 		return 0;
 	}
 } /* EVP_KDF_derive() */
 
+#else
+typedef EVP_KDF *LUAOSSL_EVP_KDF_PTR;
+#define LUAOSSL_EVP_KDF_UNDEF NULL
 #endif
 
 
@@ -2816,8 +2846,13 @@ typedef const CRYPTO_EX_DATA const_CRYPTO_EX_DATA;
 typedef CRYPTO_EX_DATA const_CRYPTO_EX_DATA;
 #endif
 
+#if OPENSSL_PREREQ(3,0,0)
+/* the function signature was fixed in version 3.0.0 */
+static int ex_ondup(CRYPTO_EX_DATA *to NOTUSED, const_CRYPTO_EX_DATA *from NOTUSED, void **from_d, int idx NOTUSED, long argl NOTUSED, void *argp NOTUSED) {
+#else
 static int ex_ondup(CRYPTO_EX_DATA *to NOTUSED, const_CRYPTO_EX_DATA *from NOTUSED, void *from_d, int idx NOTUSED, long argl NOTUSED, void *argp NOTUSED) {
-	struct ex_data **data = from_d;
+#endif
+	struct ex_data **data = (struct ex_data **)from_d;
 
 	if (*data)
 		(*data)->refs++;
@@ -3265,11 +3300,15 @@ EXPORT int luaopen__openssl(lua_State *L) {
 	lua_pushstring(L, OPENSSL_VERSION_TEXT);
 	lua_setfield(L, -2, "VERSION_TEXT");
 
+#ifdef SHLIB_VERSION_HISTORY
 	lua_pushstring(L, SHLIB_VERSION_HISTORY);
 	lua_setfield(L, -2, "SHLIB_VERSION_HISTORY");
+#endif
 
+#ifdef SHLIB_VERSION_NUMBER
 	lua_pushstring(L, SHLIB_VERSION_NUMBER);
 	lua_setfield(L, -2, "SHLIB_VERSION_NUMBER");
+#endif
 
 	return 1;
 } /* luaopen__openssl() */
@@ -3882,7 +3921,11 @@ static int bn_generatePrime(lua_State *L) {
 static int bn_isPrime(lua_State *L) {
 	BIGNUM *bn = checksimple(L, 1, BIGNUM_CLASS);
 	int nchecks = luaL_optinteger(L, 2, BN_prime_checks);
+#if OPENSSL_PREREQ(3,0,0)
+	int res = BN_check_prime(bn, getctx(L), NULL);
+#else
 	int res = BN_is_prime_ex(bn, nchecks, getctx(L), NULL);
+#endif
 
 	if (res == -1)
 		return auxL_error(L, auxL_EOPENSSL, "bignum:isPrime");
@@ -5384,7 +5427,9 @@ static void pk_luainit(lua_State *L, _Bool reset) {
 
 static const auxL_IntegerReg pk_rsa_pad_opts[] = {
 	{ "RSA_PKCS1_PADDING", RSA_PKCS1_PADDING }, // PKCS#1 padding
+#if RSA_SSLV23_PADDING
 	{ "RSA_SSLV23_PADDING", RSA_SSLV23_PADDING }, // SSLv23 padding
+#endif
 	{ "RSA_NO_PADDING", RSA_NO_PADDING }, // no padding
 	{ "RSA_PKCS1_OAEP_PADDING", RSA_PKCS1_OAEP_PADDING }, // OAEP padding (encrypt and decrypt only)
 	{ "RSA_X931_PADDING", RSA_X931_PADDING }, // (signature operations only)
@@ -12031,15 +12076,21 @@ static int EVP_KDF__gc(lua_State *L) {
 
 
 static int kdf_derive(lua_State *L) {
-	int nid;
+	LUAOSSL_EVP_KDF_PTR kdf;
 	luaL_Buffer b;
 	EVP_KDF_CTX *kctx, **kctxp;
+#if HAVE_OSSL_PARAM
+	OSSL_PARAM params[15], *param = params;
+#endif
 	unsigned char* out;
 	size_t outlen = 0;
 	const char *str = NULL;
 	size_t len;
 	_Bool seed = 0;
 	int mode;
+	unsigned int iter;
+	uint64_t maxmem_bytes, scrypt_n;
+	uint32_t scrypt_r, scrypt_p;
 
 	luaL_checktype(L, 1, LUA_TTABLE);
 
@@ -12047,13 +12098,13 @@ static int kdf_derive(lua_State *L) {
 		const char* type;
 		if (!loadfield(L, 1, "type", LUA_TSTRING, &type))
 			return luaL_argerror(L, 1, "missing 'type' field");
-		if (!auxS_txt2nid(&nid, type))
+		if ((kdf = EVP_KDF_fetch(NULL, type, NULL)) == LUAOSSL_EVP_KDF_UNDEF)
 			return luaL_argerror(L, 1, "unknown 'type'");
 	}
 
 	/* ensure EVP_KDF_CTX is collected on error */
 	kctxp = prepudata(L, sizeof(EVP_KDF_CTX*), NULL, &EVP_KDF__gc);
-	if (!(kctx = EVP_KDF_CTX_new_id(nid)))
+	if (!(kctx = EVP_KDF_CTX_new(kdf)))
 		return auxL_error(L, auxL_EOPENSSL, "kdf.derive");
 	*kctxp = kctx;
 
@@ -12089,51 +12140,91 @@ static int kdf_derive(lua_State *L) {
 
 		case 2:
 			str = luaL_checklstring(L, -1, &len);
+#if HAVE_OSSL_PARAM
+			*param++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD, (void *)str, len);
+#else
 			if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PASS, (const unsigned char*)str, len) <= 0)
 				goto error;
+#endif
 			break;
 
 		case 3:
 			str = luaL_checklstring(L, -1, &len);
+#if HAVE_OSSL_PARAM
+			*param++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, (void *)str, len);
+#else
 			if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT, (const unsigned char*)str, len) <= 0)
 				goto error;
+#endif
 			break;
 
 		case 4:
-			if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_ITER, auxL_checkunsigned(L, -1, 1, (int)-1)) <= 0)
+			iter = auxL_checkunsigned(L, -1, 1, (int)-1);
+#if HAVE_OSSL_PARAM
+			*param++ = OSSL_PARAM_construct_uint(OSSL_KDF_PARAM_ITER, &iter);
+#else
+			if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_ITER, iter) <= 0)
 				goto error;
+#endif
 			break;
 
 		case 5:
+#if HAVE_OSSL_PARAM
+			str = luaL_checklstring(L, -1, &len);
+			*param++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, (void *)str, len);
+#else
 			if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, md_checkdigest(L, -1)) <= 0)
 				goto error;
+#endif
 			break;
 
 		case 6:
 			str = luaL_checklstring(L, -1, &len);
+#if HAVE_OSSL_PARAM
+			*param++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, (void *)str, len);
+#else
 			if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_KEY, (const unsigned char*)str, len) <= 0)
 				goto error;
+#endif
 			break;
 
 		case 7:
-			if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MAXMEM_BYTES, auxL_checkunsigned(L, -1, 0, UINT64_MAX)) <= 0)
+			maxmem_bytes = auxL_checkunsigned(L, -1, 0, UINT64_MAX);
+#if HAVE_OSSL_PARAM
+			*param++ = OSSL_PARAM_construct_uint64(OSSL_KDF_PARAM_SCRYPT_MAXMEM, &maxmem_bytes);
+#else
+			if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MAXMEM_BYTES, maxmem_bytes) <= 0)
 				goto error;
+#endif
 			break;
 
 		case 8:
 			str = luaL_checklstring(L, -1, &len);
+#if HAVE_OSSL_PARAM
+			*param++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SECRET, (void *)str, len);
+#else
 			if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_TLS_SECRET, (const unsigned char*)str, len) <= 0)
 				goto error;
+#endif
 			break;
 
 		case 9:
-			seed = 1;
+			str = luaL_checklstring(L, -1, &len);
+#if HAVE_OSSL_PARAM
+			*param++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, (void *)str, len);
+#else
+            seed = 1;
+#endif
 			break;
 
 		case 10:
 			str = luaL_checklstring(L, -1, &len);
+#if HAVE_OSSL_PARAM
+			*param++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, (void *)str, len);
+#else
 			if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_ADD_HKDF_INFO, (const unsigned char*)str, len) <= 0)
 				goto error;
+#endif
 			break;
 
 		case 11:
@@ -12158,23 +12249,42 @@ static int kdf_derive(lua_State *L) {
 				"expand_only",
 #endif
 			NULL }, 0)];
+#if HAVE_OSSL_PARAM
+			*param++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &mode);
+#else
 			if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_HKDF_MODE, mode) <= 0)
 				goto error;
+#endif
 			break;
 
 		case 12:
-			if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_N, auxL_checkunsigned(L, -1, 0, UINT64_MAX)) <= 0)
+			scrypt_n = auxL_checkunsigned(L, -1, 0, UINT64_MAX);
+#if HAVE_OSSL_PARAM
+			*param++ = OSSL_PARAM_construct_uint64(OSSL_KDF_PARAM_SCRYPT_N, &scrypt_n);
+#else
+			if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_N, scrypt_n) <= 0)
 				goto error;
+#endif
 			break;
 
 		case 13:
-			if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_R, auxL_checkunsigned(L, -1, 0, UINT32_MAX)) <= 0)
+			scrypt_r = auxL_checkunsigned(L, -1, 0, UINT32_MAX);
+#if HAVE_OSSL_PARAM
+			*param++ = OSSL_PARAM_construct_uint32(OSSL_KDF_PARAM_SCRYPT_R, &scrypt_r);
+#else
+			if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_R, scrypt_r) <= 0)
 				goto error;
+#endif
 			break;
 
 		case 14:
-			if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_P, auxL_checkunsigned(L, -1, 0, UINT32_MAX)) <= 0)
+			scrypt_p = auxL_checkunsigned(L, -1, 0, UINT32_MAX);
+#if HAVE_OSSL_PARAM
+			*param++ = OSSL_PARAM_construct_uint32(OSSL_KDF_PARAM_SCRYPT_P, &scrypt_p);
+#else
+			if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SCRYPT_P, scrypt_p) <= 0)
 				goto error;
+#endif
 			break;
 
 		default:
@@ -12183,6 +12293,13 @@ static int kdf_derive(lua_State *L) {
 		lua_pop(L, 1);
 	}
 
+#if HAVE_OSSL_PARAM
+	*param = OSSL_PARAM_construct_end();
+
+	if(EVP_KDF_CTX_set_params(kctx,params) <= 0) {
+		goto error;
+	}
+#else
 	/* XXX: seed must be set *after* secret
 	 * https://github.com/openssl/openssl/issues/7728 */
 	if (seed) {
@@ -12192,9 +12309,10 @@ static int kdf_derive(lua_State *L) {
 			goto error;
 		lua_pop(L, 1);
 	}
+#endif
 
 	if (outlen == 0) {
-		outlen = EVP_KDF_size(kctx);
+		outlen = EVP_KDF_CTX_get_kdf_size(kctx);
 		if (outlen == 0)
 			goto error;
 		if (outlen == SIZE_MAX)
@@ -12203,7 +12321,7 @@ static int kdf_derive(lua_State *L) {
 
 	out = (unsigned char *)luaL_buffinitsize(L, &b, outlen);
 
-	if (EVP_KDF_derive(kctx, out, &outlen) <= 0)
+	if (EVP_KDF_derive(kctx, out, outlen, NULL) <= 0)
 		goto error;
 
 	EVP_KDF_CTX_free(kctx);
-- 
2.36.1