diff options
| -rw-r--r-- | src/openssl.c | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/src/openssl.c b/src/openssl.c index c33d934..38c9888 100644 --- a/src/openssl.c +++ b/src/openssl.c | |||
| @@ -193,6 +193,10 @@ | |||
| 193 | #define HAVE_EVP_PKEY_BASE_ID OPENSSL_PREREQ(1,1,0) | 193 | #define HAVE_EVP_PKEY_BASE_ID OPENSSL_PREREQ(1,1,0) |
| 194 | #endif | 194 | #endif |
| 195 | 195 | ||
| 196 | #ifndef HAVE_EVP_PKEY_CTX_NEW | ||
| 197 | #define HAVE_EVP_PKEY_CTX_NEW (OPENSSL_PREREQ(1,0,0) || LIBRESSL_PREREQ(2,0,0)) | ||
| 198 | #endif | ||
| 199 | |||
| 196 | #ifndef HAVE_EVP_PKEY_GET0 | 200 | #ifndef HAVE_EVP_PKEY_GET0 |
| 197 | #define HAVE_EVP_PKEY_GET0 OPENSSL_PREREQ(1,1,0) | 201 | #define HAVE_EVP_PKEY_GET0 OPENSSL_PREREQ(1,1,0) |
| 198 | #endif | 202 | #endif |
| @@ -225,6 +229,10 @@ | |||
| 225 | #define HAVE_RSA_GET0_KEY OPENSSL_PREREQ(1,1,0) | 229 | #define HAVE_RSA_GET0_KEY OPENSSL_PREREQ(1,1,0) |
| 226 | #endif | 230 | #endif |
| 227 | 231 | ||
| 232 | #ifndef HAVE_RSA_PKCS1_PSS_PADDING | ||
| 233 | #define HAVE_RSA_PKCS1_PSS_PADDING (defined RSA_PKCS1_PSS_PADDING || OPENSSL_PREREQ(1,0,0) || LIBRESSL_PREREQ(2,0,0)) | ||
| 234 | #endif | ||
| 235 | |||
| 228 | #ifndef HAVE_RSA_SET0_CRT_PARAMS | 236 | #ifndef HAVE_RSA_SET0_CRT_PARAMS |
| 229 | #define HAVE_RSA_SET0_CRT_PARAMS OPENSSL_PREREQ(1,1,0) | 237 | #define HAVE_RSA_SET0_CRT_PARAMS OPENSSL_PREREQ(1,1,0) |
| 230 | #endif | 238 | #endif |
| @@ -3281,6 +3289,123 @@ static int pk_setPrivateKey(lua_State *L) { | |||
| 3281 | return 1; | 3289 | return 1; |
| 3282 | } /* pk_setPrivateKey() */ | 3290 | } /* pk_setPrivateKey() */ |
| 3283 | 3291 | ||
| 3292 | #if HAVE_EVP_PKEY_CTX_NEW | ||
| 3293 | static int pk_decrypt(lua_State *L) { | ||
| 3294 | size_t outlen, inlen; | ||
| 3295 | EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS); | ||
| 3296 | EVP_PKEY_CTX *ctx; | ||
| 3297 | const char *str = luaL_checklstring(L, 2, &inlen); | ||
| 3298 | BIO *bio; | ||
| 3299 | BUF_MEM *buf; | ||
| 3300 | int rsaPadding = RSA_PKCS1_PADDING; /* default for `openssl rsautl` */ | ||
| 3301 | int base_type = EVP_PKEY_base_id(key); | ||
| 3302 | |||
| 3303 | if (lua_istable(L, 3)) { | ||
| 3304 | if (base_type == EVP_PKEY_RSA) { | ||
| 3305 | lua_getfield(L, 3, "rsaPadding"); | ||
| 3306 | rsaPadding = luaL_optint(L, -1, rsaPadding); | ||
| 3307 | lua_pop(L, 1); | ||
| 3308 | } | ||
| 3309 | } | ||
| 3310 | |||
| 3311 | bio = getbio(L); | ||
| 3312 | BIO_get_mem_ptr(bio, &buf); | ||
| 3313 | |||
| 3314 | if (!(ctx = EVP_PKEY_CTX_new(key, NULL))) | ||
| 3315 | goto sslerr; | ||
| 3316 | |||
| 3317 | if (EVP_PKEY_decrypt_init(ctx) <= 0) | ||
| 3318 | goto sslerr; | ||
| 3319 | |||
| 3320 | if (base_type == EVP_PKEY_RSA && !EVP_PKEY_CTX_set_rsa_padding(ctx, rsaPadding)) | ||
| 3321 | goto sslerr; | ||
| 3322 | |||
| 3323 | if (EVP_PKEY_decrypt(ctx, NULL, &outlen, (const unsigned char *)str, inlen) <= 0) | ||
| 3324 | goto sslerr; | ||
| 3325 | |||
| 3326 | if (!BUF_MEM_grow_clean(buf, outlen)) | ||
| 3327 | goto sslerr; | ||
| 3328 | |||
| 3329 | if (EVP_PKEY_decrypt(ctx, (unsigned char *)buf->data, &outlen, (const unsigned char *)str, inlen) <= 0) | ||
| 3330 | goto sslerr; | ||
| 3331 | |||
| 3332 | EVP_PKEY_CTX_free(ctx); | ||
| 3333 | ctx = NULL; | ||
| 3334 | |||
| 3335 | lua_pushlstring(L, buf->data, outlen); | ||
| 3336 | |||
| 3337 | BIO_reset(bio); | ||
| 3338 | |||
| 3339 | return 1; | ||
| 3340 | sslerr: | ||
| 3341 | if (ctx) { | ||
| 3342 | EVP_PKEY_CTX_free(ctx); | ||
| 3343 | ctx = NULL; | ||
| 3344 | } | ||
| 3345 | BIO_reset(bio); | ||
| 3346 | |||
| 3347 | return auxL_error(L, auxL_EOPENSSL, "pkey:decrypt"); | ||
| 3348 | } /* pk_decrypt() */ | ||
| 3349 | #endif | ||
| 3350 | |||
| 3351 | #if HAVE_EVP_PKEY_CTX_NEW | ||
| 3352 | static int pk_encrypt(lua_State *L) { | ||
| 3353 | size_t outlen, inlen; | ||
| 3354 | EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS); | ||
| 3355 | EVP_PKEY_CTX *ctx; | ||
| 3356 | const char *str = luaL_checklstring(L, 2, &inlen); | ||
| 3357 | BIO *bio; | ||
| 3358 | BUF_MEM *buf; | ||
| 3359 | int rsaPadding = RSA_PKCS1_PADDING; /* default for `openssl rsautl` */ | ||
| 3360 | int base_type = EVP_PKEY_base_id(key); | ||
| 3361 | |||
| 3362 | if (lua_istable(L, 3)) { | ||
| 3363 | if (base_type == EVP_PKEY_RSA) { | ||
| 3364 | lua_getfield(L, 3, "rsaPadding"); | ||
| 3365 | rsaPadding = luaL_optint(L, -1, rsaPadding); | ||
| 3366 | lua_pop(L, 1); | ||
| 3367 | } | ||
| 3368 | } | ||
| 3369 | |||
| 3370 | bio = getbio(L); | ||
| 3371 | BIO_get_mem_ptr(bio, &buf); | ||
| 3372 | |||
| 3373 | if (!(ctx = EVP_PKEY_CTX_new(key, NULL))) | ||
| 3374 | goto sslerr; | ||
| 3375 | |||
| 3376 | if (EVP_PKEY_encrypt_init(ctx) <= 0) | ||
| 3377 | goto sslerr; | ||
| 3378 | |||
| 3379 | if (base_type == EVP_PKEY_RSA && !EVP_PKEY_CTX_set_rsa_padding(ctx, rsaPadding)) | ||
| 3380 | goto sslerr; | ||
| 3381 | |||
| 3382 | if (EVP_PKEY_encrypt(ctx, NULL, &outlen, (const unsigned char *)str, inlen) <= 0) | ||
| 3383 | goto sslerr; | ||
| 3384 | |||
| 3385 | if (!BUF_MEM_grow_clean(buf, outlen)) | ||
| 3386 | goto sslerr; | ||
| 3387 | |||
| 3388 | if (EVP_PKEY_encrypt(ctx, (unsigned char *)buf->data, &outlen, (const unsigned char *)str, inlen) <= 0) | ||
| 3389 | goto sslerr; | ||
| 3390 | |||
| 3391 | EVP_PKEY_CTX_free(ctx); | ||
| 3392 | ctx = NULL; | ||
| 3393 | |||
| 3394 | lua_pushlstring(L, buf->data, outlen); | ||
| 3395 | |||
| 3396 | BIO_reset(bio); | ||
| 3397 | |||
| 3398 | return 1; | ||
| 3399 | sslerr: | ||
| 3400 | if (ctx) { | ||
| 3401 | EVP_PKEY_CTX_free(ctx); | ||
| 3402 | ctx = NULL; | ||
| 3403 | } | ||
| 3404 | BIO_reset(bio); | ||
| 3405 | |||
| 3406 | return auxL_error(L, auxL_EOPENSSL, "pkey:encrypt"); | ||
| 3407 | } /* pk_encrypt() */ | ||
| 3408 | #endif | ||
| 3284 | 3409 | ||
| 3285 | static int pk_sign(lua_State *L) { | 3410 | static int pk_sign(lua_State *L) { |
| 3286 | EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS); | 3411 | EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS); |
| @@ -4001,6 +4126,10 @@ static const auxL_Reg pk_methods[] = { | |||
| 4001 | { "type", &pk_type }, | 4126 | { "type", &pk_type }, |
| 4002 | { "setPublicKey", &pk_setPublicKey }, | 4127 | { "setPublicKey", &pk_setPublicKey }, |
| 4003 | { "setPrivateKey", &pk_setPrivateKey }, | 4128 | { "setPrivateKey", &pk_setPrivateKey }, |
| 4129 | #if HAVE_EVP_PKEY_CTX_NEW | ||
| 4130 | { "decrypt", &pk_decrypt }, | ||
| 4131 | { "encrypt", &pk_encrypt }, | ||
| 4132 | #endif | ||
| 4004 | { "sign", &pk_sign }, | 4133 | { "sign", &pk_sign }, |
| 4005 | { "verify", &pk_verify }, | 4134 | { "verify", &pk_verify }, |
| 4006 | { "getDefaultDigestName", &pk_getDefaultDigestName }, | 4135 | { "getDefaultDigestName", &pk_getDefaultDigestName }, |
| @@ -4039,10 +4168,23 @@ static void pk_luainit(lua_State *L, _Bool reset) { | |||
| 4039 | lua_pop(L, 2); | 4168 | lua_pop(L, 2); |
| 4040 | } /* pk_luainit() */ | 4169 | } /* pk_luainit() */ |
| 4041 | 4170 | ||
| 4171 | static const auxL_IntegerReg pk_rsa_pad_opts[] = { | ||
| 4172 | { "RSA_PKCS1_PADDING", RSA_PKCS1_PADDING }, // PKCS#1 padding | ||
| 4173 | { "RSA_SSLV23_PADDING", RSA_SSLV23_PADDING }, // SSLv23 padding | ||
| 4174 | { "RSA_NO_PADDING", RSA_NO_PADDING }, // no padding | ||
| 4175 | { "RSA_PKCS1_OAEP_PADDING", RSA_PKCS1_OAEP_PADDING }, // OAEP padding (encrypt and decrypt only) | ||
| 4176 | { "RSA_X931_PADDING", RSA_X931_PADDING }, // (signature operations only) | ||
| 4177 | #if HAVE_RSA_PKCS1_PSS_PADDING | ||
| 4178 | { "RSA_PKCS1_PSS_PADDING", RSA_PKCS1_PSS_PADDING }, // (sign and verify only) | ||
| 4179 | #endif | ||
| 4180 | { NULL, 0 }, | ||
| 4181 | }; | ||
| 4182 | |||
| 4042 | int luaopen__openssl_pkey(lua_State *L) { | 4183 | int luaopen__openssl_pkey(lua_State *L) { |
| 4043 | initall(L); | 4184 | initall(L); |
| 4044 | 4185 | ||
| 4045 | auxL_newlib(L, pk_globals, 0); | 4186 | auxL_newlib(L, pk_globals, 0); |
| 4187 | auxL_setintegers(L, pk_rsa_pad_opts); | ||
| 4046 | 4188 | ||
| 4047 | return 1; | 4189 | return 1; |
| 4048 | } /* luaopen__openssl_pkey() */ | 4190 | } /* luaopen__openssl_pkey() */ |
