From 3eb66b869582bcd791cf89dd552abc4bb9e7c627 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Tue, 8 Nov 2016 15:34:44 +1100 Subject: openssl.pkey: Add pkey:encrypt() method --- src/openssl.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/openssl.c b/src/openssl.c index 4564061..87938e5 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -3181,6 +3181,61 @@ static int pk_setPrivateKey(lua_State *L) { } /* pk_setPrivateKey() */ +static int pk_encrypt(lua_State *L) { + size_t outlen, inlen; + EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS); + EVP_PKEY_CTX *ctx; + const char *str = luaL_checklstring(L, 2, &inlen); + BIO *bio; + BUF_MEM *buf; + int rsaPadding = RSA_PKCS1_PADDING; /* default for `openssl rsautl` */ + int base_type = EVP_PKEY_base_id(key); + + if (lua_istable(L, 3)) { + if (base_type == EVP_PKEY_RSA) { + lua_getfield(L, 3, "rsaPadding"); + rsaPadding = luaL_optint(L, -1, rsaPadding); + lua_pop(L, 1); + } + } + + bio = getbio(L); + BIO_get_mem_ptr(bio, &buf); + + if (!(ctx = EVP_PKEY_CTX_new(key, NULL))) + goto sslerr; + + if (EVP_PKEY_encrypt_init(ctx) <= 0) + goto sslerr; + + if (base_type == EVP_PKEY_RSA && !EVP_PKEY_CTX_set_rsa_padding(ctx, rsaPadding)) + goto sslerr; + + if (EVP_PKEY_encrypt(ctx, NULL, &outlen, str, inlen) <= 0) + goto sslerr; + + if (!BUF_MEM_grow_clean(buf, outlen)) + goto sslerr; + + if (EVP_PKEY_encrypt(ctx, buf->data, &outlen, str, inlen) <= 0) + goto sslerr; + + EVP_PKEY_CTX_free(ctx); + ctx = NULL; + + lua_pushlstring(L, buf->data, outlen); + + return 1; +sslerr: + if (ctx) { + EVP_PKEY_CTX_free(ctx); + ctx = NULL; + } + + return auxL_error(L, auxL_EOPENSSL, "pkey:encrypt"); +} /* pk_encrypt() */ + + static int pk_sign(lua_State *L) { EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS); EVP_MD_CTX *md = checksimple(L, 2, DIGEST_CLASS); @@ -3907,6 +3962,7 @@ static const auxL_Reg pk_methods[] = { { "type", &pk_type }, { "setPublicKey", &pk_setPublicKey }, { "setPrivateKey", &pk_setPrivateKey }, + { "encrypt", &pk_encrypt }, { "sign", &pk_sign }, { "verify", &pk_verify }, { "getDefaultDigestName", &pk_getDefaultDigestName }, -- cgit v1.2.3-59-g8ed1b From fa19e1d6bda00c45189530b15f0034549df5b283 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Tue, 8 Nov 2016 15:34:58 +1100 Subject: openssl.pkey: Export rsa padding options --- src/openssl.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/openssl.c b/src/openssl.c index 87938e5..c0fc6de 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -4001,10 +4001,21 @@ static void pk_luainit(lua_State *L, _Bool reset) { lua_pop(L, 2); } /* pk_luainit() */ +static const auxL_IntegerReg pk_rsa_pad_opts[] = { + { "RSA_PKCS1_PADDING", RSA_PKCS1_PADDING }, // PKCS#1 padding + { "RSA_SSLV23_PADDING", RSA_SSLV23_PADDING }, // SSLv23 padding + { "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) + { "RSA_PKCS1_PSS_PADDING", RSA_PKCS1_PSS_PADDING }, // (sign and verify only) + { NULL, 0 }, +}; + int luaopen__openssl_pkey(lua_State *L) { initall(L); auxL_newlib(L, pk_globals, 0); + auxL_setintegers(L, pk_rsa_pad_opts); return 1; } /* luaopen__openssl_pkey() */ -- cgit v1.2.3-59-g8ed1b From d74ec1dc86f4e0e9b3f677628ed136ca4139668c Mon Sep 17 00:00:00 2001 From: daurnimator Date: Tue, 8 Nov 2016 15:38:46 +1100 Subject: openssl.pkey: Add pkey:decrypt() method --- src/openssl.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/openssl.c b/src/openssl.c index c0fc6de..85c7503 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -3181,6 +3181,61 @@ static int pk_setPrivateKey(lua_State *L) { } /* pk_setPrivateKey() */ +static int pk_decrypt(lua_State *L) { + size_t outlen, inlen; + EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS); + EVP_PKEY_CTX *ctx; + const char *str = luaL_checklstring(L, 2, &inlen); + BIO *bio; + BUF_MEM *buf; + int rsaPadding = RSA_PKCS1_PADDING; /* default for `openssl rsautl` */ + int base_type = EVP_PKEY_base_id(key); + + if (lua_istable(L, 3)) { + if (base_type == EVP_PKEY_RSA) { + lua_getfield(L, 3, "rsaPadding"); + rsaPadding = luaL_optint(L, -1, rsaPadding); + lua_pop(L, 1); + } + } + + bio = getbio(L); + BIO_get_mem_ptr(bio, &buf); + + if (!(ctx = EVP_PKEY_CTX_new(key, NULL))) + goto sslerr; + + if (EVP_PKEY_decrypt_init(ctx) <= 0) + goto sslerr; + + if (base_type == EVP_PKEY_RSA && !EVP_PKEY_CTX_set_rsa_padding(ctx, rsaPadding)) + goto sslerr; + + if (EVP_PKEY_decrypt(ctx, NULL, &outlen, str, inlen) <= 0) + goto sslerr; + + if (!BUF_MEM_grow_clean(buf, outlen)) + goto sslerr; + + if (EVP_PKEY_decrypt(ctx, buf->data, &outlen, str, inlen) <= 0) + goto sslerr; + + EVP_PKEY_CTX_free(ctx); + ctx = NULL; + + lua_pushlstring(L, buf->data, outlen); + + return 1; +sslerr: + if (ctx) { + EVP_PKEY_CTX_free(ctx); + ctx = NULL; + } + + return auxL_error(L, auxL_EOPENSSL, "pkey:decrypt"); +} /* pk_decrypt() */ + + static int pk_encrypt(lua_State *L) { size_t outlen, inlen; EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS); @@ -3962,6 +4017,7 @@ static const auxL_Reg pk_methods[] = { { "type", &pk_type }, { "setPublicKey", &pk_setPublicKey }, { "setPrivateKey", &pk_setPrivateKey }, + { "decrypt", &pk_decrypt }, { "encrypt", &pk_encrypt }, { "sign", &pk_sign }, { "verify", &pk_verify }, -- cgit v1.2.3-59-g8ed1b From 8327753dd8f85e2a971e778389f974614146e12d Mon Sep 17 00:00:00 2001 From: daurnimator Date: Tue, 8 Nov 2016 16:58:33 +1100 Subject: openssl.pkey: Use reset bio after :encrypt() and :decrypt() --- src/openssl.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/openssl.c b/src/openssl.c index 85c7503..8ff21ce 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -3225,12 +3225,15 @@ static int pk_decrypt(lua_State *L) { lua_pushlstring(L, buf->data, outlen); + BIO_reset(*bio); + return 1; sslerr: if (ctx) { EVP_PKEY_CTX_free(ctx); ctx = NULL; } + BIO_reset(*bio); return auxL_error(L, auxL_EOPENSSL, "pkey:decrypt"); } /* pk_decrypt() */ @@ -3280,12 +3283,15 @@ static int pk_encrypt(lua_State *L) { lua_pushlstring(L, buf->data, outlen); + BIO_reset(*bio); + return 1; sslerr: if (ctx) { EVP_PKEY_CTX_free(ctx); ctx = NULL; } + BIO_reset(*bio); return auxL_error(L, auxL_EOPENSSL, "pkey:encrypt"); } /* pk_encrypt() */ -- cgit v1.2.3-59-g8ed1b From 06a5b0529ea8d86072b7b759347f2c25e1e1b92c Mon Sep 17 00:00:00 2001 From: William Ahern Date: Wed, 23 Nov 2016 18:53:01 -0800 Subject: fix OpenSSL 0.9.8 build (lacks EVP_PKEY_CTX interfaces), fix use of BIO_reset, fix signedness warnings for EVP_PKEY_encrypt and EVP_PKEY_decrypt --- src/openssl.c | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/openssl.c b/src/openssl.c index 8cf79c0..38c9888 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -193,6 +193,10 @@ #define HAVE_EVP_PKEY_BASE_ID OPENSSL_PREREQ(1,1,0) #endif +#ifndef HAVE_EVP_PKEY_CTX_NEW +#define HAVE_EVP_PKEY_CTX_NEW (OPENSSL_PREREQ(1,0,0) || LIBRESSL_PREREQ(2,0,0)) +#endif + #ifndef HAVE_EVP_PKEY_GET0 #define HAVE_EVP_PKEY_GET0 OPENSSL_PREREQ(1,1,0) #endif @@ -225,6 +229,10 @@ #define HAVE_RSA_GET0_KEY OPENSSL_PREREQ(1,1,0) #endif +#ifndef HAVE_RSA_PKCS1_PSS_PADDING +#define HAVE_RSA_PKCS1_PSS_PADDING (defined RSA_PKCS1_PSS_PADDING || OPENSSL_PREREQ(1,0,0) || LIBRESSL_PREREQ(2,0,0)) +#endif + #ifndef HAVE_RSA_SET0_CRT_PARAMS #define HAVE_RSA_SET0_CRT_PARAMS OPENSSL_PREREQ(1,1,0) #endif @@ -3281,7 +3289,7 @@ static int pk_setPrivateKey(lua_State *L) { return 1; } /* pk_setPrivateKey() */ - +#if HAVE_EVP_PKEY_CTX_NEW static int pk_decrypt(lua_State *L) { size_t outlen, inlen; EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS); @@ -3312,13 +3320,13 @@ static int pk_decrypt(lua_State *L) { if (base_type == EVP_PKEY_RSA && !EVP_PKEY_CTX_set_rsa_padding(ctx, rsaPadding)) goto sslerr; - if (EVP_PKEY_decrypt(ctx, NULL, &outlen, str, inlen) <= 0) + if (EVP_PKEY_decrypt(ctx, NULL, &outlen, (const unsigned char *)str, inlen) <= 0) goto sslerr; if (!BUF_MEM_grow_clean(buf, outlen)) goto sslerr; - if (EVP_PKEY_decrypt(ctx, buf->data, &outlen, str, inlen) <= 0) + if (EVP_PKEY_decrypt(ctx, (unsigned char *)buf->data, &outlen, (const unsigned char *)str, inlen) <= 0) goto sslerr; EVP_PKEY_CTX_free(ctx); @@ -3326,7 +3334,7 @@ static int pk_decrypt(lua_State *L) { lua_pushlstring(L, buf->data, outlen); - BIO_reset(*bio); + BIO_reset(bio); return 1; sslerr: @@ -3334,12 +3342,13 @@ sslerr: EVP_PKEY_CTX_free(ctx); ctx = NULL; } - BIO_reset(*bio); + BIO_reset(bio); return auxL_error(L, auxL_EOPENSSL, "pkey:decrypt"); } /* pk_decrypt() */ +#endif - +#if HAVE_EVP_PKEY_CTX_NEW static int pk_encrypt(lua_State *L) { size_t outlen, inlen; EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS); @@ -3370,13 +3379,13 @@ static int pk_encrypt(lua_State *L) { if (base_type == EVP_PKEY_RSA && !EVP_PKEY_CTX_set_rsa_padding(ctx, rsaPadding)) goto sslerr; - if (EVP_PKEY_encrypt(ctx, NULL, &outlen, str, inlen) <= 0) + if (EVP_PKEY_encrypt(ctx, NULL, &outlen, (const unsigned char *)str, inlen) <= 0) goto sslerr; if (!BUF_MEM_grow_clean(buf, outlen)) goto sslerr; - if (EVP_PKEY_encrypt(ctx, buf->data, &outlen, str, inlen) <= 0) + if (EVP_PKEY_encrypt(ctx, (unsigned char *)buf->data, &outlen, (const unsigned char *)str, inlen) <= 0) goto sslerr; EVP_PKEY_CTX_free(ctx); @@ -3384,7 +3393,7 @@ static int pk_encrypt(lua_State *L) { lua_pushlstring(L, buf->data, outlen); - BIO_reset(*bio); + BIO_reset(bio); return 1; sslerr: @@ -3392,11 +3401,11 @@ sslerr: EVP_PKEY_CTX_free(ctx); ctx = NULL; } - BIO_reset(*bio); + BIO_reset(bio); return auxL_error(L, auxL_EOPENSSL, "pkey:encrypt"); } /* pk_encrypt() */ - +#endif static int pk_sign(lua_State *L) { EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS); @@ -4117,8 +4126,10 @@ static const auxL_Reg pk_methods[] = { { "type", &pk_type }, { "setPublicKey", &pk_setPublicKey }, { "setPrivateKey", &pk_setPrivateKey }, +#if HAVE_EVP_PKEY_CTX_NEW { "decrypt", &pk_decrypt }, { "encrypt", &pk_encrypt }, +#endif { "sign", &pk_sign }, { "verify", &pk_verify }, { "getDefaultDigestName", &pk_getDefaultDigestName }, @@ -4163,7 +4174,9 @@ static const auxL_IntegerReg pk_rsa_pad_opts[] = { { "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) +#if HAVE_RSA_PKCS1_PSS_PADDING { "RSA_PKCS1_PSS_PADDING", RSA_PKCS1_PSS_PADDING }, // (sign and verify only) +#endif { NULL, 0 }, }; -- cgit v1.2.3-59-g8ed1b