From 8eda64a509319b36a0d6fc8dd4a4037ee08d1f29 Mon Sep 17 00:00:00 2001 From: John Regan Date: Wed, 4 May 2022 15:18:57 -0400 Subject: openssl 3.0.0 compatibility --- src/openssl.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 133 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/openssl.c b/src/openssl.c index b56c78a..6dc9f66 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 #endif +#if HAVE_EVP_KDF_CTX +#include +#endif + #ifndef STRERROR_R_CHAR_P #ifdef __GLIBC__ #define STRERROR_R_CHAR_P (_GNU_SOURCE || !(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600)) @@ -2231,7 +2239,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 @@ -2258,6 +2266,10 @@ STACK_OF(X509) *compat_X509_chain_up_ref(STACK_OF(X509) *chain) { #define EVP_R_COMMAND_NOT_SUPPORTED EVP_R_UNKNOWN_OPTION #endif +typedef struct { + int nid; +} EVP_KDF; + typedef struct { int nid; union { @@ -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 @@ -3265,11 +3295,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() */ @@ -5384,7 +5418,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 +12067,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 +12089,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 +12131,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 +12240,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 +12284,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 +12300,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 +12312,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); -- cgit v1.2.3-59-g8ed1b From 58c6315bdb61b2a00d7152e424658da33bf14a49 Mon Sep 17 00:00:00 2001 From: John Regan Date: Wed, 4 May 2022 15:36:47 -0400 Subject: remove unused struct def --- src/openssl.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src') diff --git a/src/openssl.c b/src/openssl.c index 6dc9f66..5b17335 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -2266,10 +2266,6 @@ STACK_OF(X509) *compat_X509_chain_up_ref(STACK_OF(X509) *chain) { #define EVP_R_COMMAND_NOT_SUPPORTED EVP_R_UNKNOWN_OPTION #endif -typedef struct { - int nid; -} EVP_KDF; - typedef struct { int nid; union { -- cgit v1.2.3-59-g8ed1b From 708534b83b1c29036081a80d94ac809fb198ef9f Mon Sep 17 00:00:00 2001 From: John Regan Date: Wed, 4 May 2022 23:04:06 +0200 Subject: openssl 3.0.0: use non-deprecated ERR_get_error_all function --- src/openssl.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/openssl.c b/src/openssl.c index 5b17335..814d95c 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -1475,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; -- cgit v1.2.3-59-g8ed1b From 719fa58363ab4e5f6ebd77b4d17f11339d762d3e Mon Sep 17 00:00:00 2001 From: John Regan Date: Wed, 4 May 2022 23:05:03 +0200 Subject: openssl 3.0.0: use new function signature for the dup_func callback --- src/openssl.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/openssl.c b/src/openssl.c index 814d95c..92e91ea 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -2846,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++; -- cgit v1.2.3-59-g8ed1b From 03ffa376011ff5ddf346657c4bb377dde9ecb584 Mon Sep 17 00:00:00 2001 From: John Regan Date: Wed, 4 May 2022 23:05:24 +0200 Subject: openssl 3.0.0: use new BN_check_prime --- src/openssl.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/openssl.c b/src/openssl.c index 92e91ea..c23988e 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -3920,8 +3920,12 @@ static int bn_generatePrime(lua_State *L) { static int bn_isPrime(lua_State *L) { BIGNUM *bn = checksimple(L, 1, BIGNUM_CLASS); +#if OPENSSL_PREREQ(3,0,0) + int res = BN_check_prime(bn, getctx(L), NULL); +#else int nchecks = luaL_optinteger(L, 2, BN_prime_checks); int res = BN_is_prime_ex(bn, nchecks, getctx(L), NULL); +#endif if (res == -1) return auxL_error(L, auxL_EOPENSSL, "bignum:isPrime"); -- cgit v1.2.3-59-g8ed1b From df0f1541e7abf453de2337df967bcc1bd362124a Mon Sep 17 00:00:00 2001 From: John Regan Date: Thu, 5 May 2022 14:25:49 +0200 Subject: bn: use nchecks in both openssl-3 and openssl-1 branches --- src/openssl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/openssl.c b/src/openssl.c index c23988e..198e6a6 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -3920,10 +3920,10 @@ 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 nchecks = luaL_optinteger(L, 2, BN_prime_checks); int res = BN_is_prime_ex(bn, nchecks, getctx(L), NULL); #endif -- cgit v1.2.3-59-g8ed1b