diff options
| author | William Ahern <william@server.local> | 2013-03-11 22:46:03 -0700 |
|---|---|---|
| committer | William Ahern <william@server.local> | 2013-03-11 22:46:03 -0700 |
| commit | 993866fa039071ac77f5157bfdfb709bb31b5821 (patch) | |
| tree | 7dee4034c5866f74eb9b4eb75a33bfc7fbac30e3 | |
| parent | 86c0d06ca02033efe9be6c0736ec5ebd7fe77c2d (diff) | |
| download | luaossl-993866fa039071ac77f5157bfdfb709bb31b5821.tar.gz luaossl-993866fa039071ac77f5157bfdfb709bb31b5821.tar.bz2 luaossl-993866fa039071ac77f5157bfdfb709bb31b5821.zip | |
-n
add EVP_CIPHER_CTX bindings
| -rw-r--r-- | openssl.c | 170 | ||||
| -rw-r--r-- | openssl.cipher.lua | 3 |
2 files changed, 172 insertions, 1 deletions
| @@ -71,6 +71,7 @@ | |||
| 71 | #define SSL_CLASS "OpenSSL SSL" | 71 | #define SSL_CLASS "OpenSSL SSL" |
| 72 | #define DIGEST_CLASS "OpenSSL Digest" | 72 | #define DIGEST_CLASS "OpenSSL Digest" |
| 73 | #define HMAC_CLASS "OpenSSL HMAC" | 73 | #define HMAC_CLASS "OpenSSL HMAC" |
| 74 | #define CIPHER_CLASS "OpenSSL Cipher" | ||
| 74 | 75 | ||
| 75 | 76 | ||
| 76 | #define countof(a) (sizeof (a) / sizeof *(a)) | 77 | #define countof(a) (sizeof (a) / sizeof *(a)) |
| @@ -78,6 +79,9 @@ | |||
| 78 | 79 | ||
| 79 | #define CLAMP(i, min, max) (((i) < (min))? (min) : ((i) > (max))? (max) : (i)) | 80 | #define CLAMP(i, min, max) (((i) < (min))? (min) : ((i) > (max))? (max) : (i)) |
| 80 | 81 | ||
| 82 | #undef MIN | ||
| 83 | #define MIN(a, b) (((a) < (b))? (a) : (b)) | ||
| 84 | |||
| 81 | #define stricmp(a, b) strcasecmp((a), (b)) | 85 | #define stricmp(a, b) strcasecmp((a), (b)) |
| 82 | #define strieq(a, b) (!stricmp((a), (b))) | 86 | #define strieq(a, b) (!stricmp((a), (b))) |
| 83 | 87 | ||
| @@ -947,7 +951,7 @@ static int pk_sign(lua_State *L) { | |||
| 947 | unsigned n; | 951 | unsigned n; |
| 948 | 952 | ||
| 949 | if (LUAL_BUFFERSIZE < EVP_PKEY_size(key)) | 953 | if (LUAL_BUFFERSIZE < EVP_PKEY_size(key)) |
| 950 | return luaL_error(L, "pubkey:sign: LUAL_BUFFERSIZE(%zu) < EVP_PKEY_size(%zu)", (size_t)LUAL_BUFFERSIZE, (size_t)EVP_PKEY_size(key)); | 954 | return luaL_error(L, "pubkey:sign: LUAL_BUFFERSIZE(%u) < EVP_PKEY_size(%u)", (unsigned)LUAL_BUFFERSIZE, (unsigned)EVP_PKEY_size(key)); |
| 951 | 955 | ||
| 952 | luaL_buffinit(L, &B); | 956 | luaL_buffinit(L, &B); |
| 953 | n = LUAL_BUFFERSIZE; | 957 | n = LUAL_BUFFERSIZE; |
| @@ -3521,6 +3525,169 @@ int luaopen__openssl_hmac(lua_State *L) { | |||
| 3521 | } /* luaopen__openssl_hmac() */ | 3525 | } /* luaopen__openssl_hmac() */ |
| 3522 | 3526 | ||
| 3523 | 3527 | ||
| 3528 | /* | ||
| 3529 | * Cipher - openssl.cipher | ||
| 3530 | * | ||
| 3531 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
| 3532 | |||
| 3533 | static const EVP_CIPHER *cipher_checktype(lua_State *L, int index) { | ||
| 3534 | const char *name = luaL_checkstring(L, index); | ||
| 3535 | const EVP_CIPHER *type; | ||
| 3536 | |||
| 3537 | if (!(type = EVP_get_cipherbyname(name))) | ||
| 3538 | luaL_argerror(L, index, lua_pushfstring(L, "%s: invalid cipher type", name)); | ||
| 3539 | |||
| 3540 | return type; | ||
| 3541 | } /* cipher_checktype() */ | ||
| 3542 | |||
| 3543 | |||
| 3544 | static int cipher_new(lua_State *L) { | ||
| 3545 | const EVP_CIPHER *type; | ||
| 3546 | EVP_CIPHER_CTX *ctx; | ||
| 3547 | |||
| 3548 | type = cipher_checktype(L, 1); | ||
| 3549 | |||
| 3550 | ctx = prepudata(L, sizeof *ctx, CIPHER_CLASS, NULL); | ||
| 3551 | EVP_CIPHER_CTX_init(ctx); | ||
| 3552 | |||
| 3553 | if (!EVP_CipherInit_ex(ctx, type, NULL, NULL, NULL, -1)) | ||
| 3554 | return throwssl(L, "cipher.new"); | ||
| 3555 | |||
| 3556 | return 1; | ||
| 3557 | } /* cipher_new() */ | ||
| 3558 | |||
| 3559 | |||
| 3560 | static int cipher_interpose(lua_State *L) { | ||
| 3561 | return interpose(L, HMAC_CLASS); | ||
| 3562 | } /* cipher_interpose() */ | ||
| 3563 | |||
| 3564 | |||
| 3565 | static int cipher_init(lua_State *L, _Bool encrypt) { | ||
| 3566 | EVP_CIPHER_CTX *ctx = luaL_checkudata(L, 1, CIPHER_CLASS); | ||
| 3567 | const void *key, *iv; | ||
| 3568 | size_t n, m; | ||
| 3569 | |||
| 3570 | key = luaL_checklstring(L, 1, &n); | ||
| 3571 | m = (size_t)EVP_CIPHER_CTX_key_length(ctx); | ||
| 3572 | luaL_argcheck(L, 1, n == m, lua_pushfstring(L, "%u: invalid key length (should be %u)", (unsigned)n, (unsigned)m)); | ||
| 3573 | |||
| 3574 | iv = luaL_checklstring(L, 2, &n); | ||
| 3575 | m = (size_t)EVP_CIPHER_CTX_iv_length(ctx); | ||
| 3576 | luaL_argcheck(L, 2, n == m, lua_pushfstring(L, "%u: invalid IV length (should be %u)", (unsigned)n, (unsigned)m)); | ||
| 3577 | |||
| 3578 | if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, encrypt)) | ||
| 3579 | return throwssl(L, (encrypt)? "cipher:encrypt" : "cipher:decrypt"); | ||
| 3580 | |||
| 3581 | lua_settop(L, 1); | ||
| 3582 | |||
| 3583 | return 1; | ||
| 3584 | } /* cipher_init() */ | ||
| 3585 | |||
| 3586 | |||
| 3587 | static int cipher_encrypt(lua_State *L) { | ||
| 3588 | return cipher_init(L, 1); | ||
| 3589 | } /* cipher_encrypt() */ | ||
| 3590 | |||
| 3591 | |||
| 3592 | static int cipher_decrypt(lua_State *L) { | ||
| 3593 | return cipher_init(L, 0); | ||
| 3594 | } /* cipher_decrypt() */ | ||
| 3595 | |||
| 3596 | |||
| 3597 | static int cipher_update(lua_State *L) { | ||
| 3598 | EVP_CIPHER_CTX *ctx = luaL_checkudata(L, 1, CIPHER_CLASS); | ||
| 3599 | const unsigned char *p, *pe; | ||
| 3600 | luaL_Buffer B; | ||
| 3601 | size_t block, step, n; | ||
| 3602 | |||
| 3603 | block = EVP_CIPHER_CTX_block_size(ctx); | ||
| 3604 | |||
| 3605 | if (LUAL_BUFFERSIZE < block * 2) | ||
| 3606 | return luaL_error(L, "cipher:update: LUAL_BUFFERSIZE(%u) < 2 * EVP_CIPHER_CTX_block_size(%u)", (unsigned)LUAL_BUFFERSIZE, (unsigned)block); | ||
| 3607 | |||
| 3608 | step = LUAL_BUFFERSIZE - block; | ||
| 3609 | |||
| 3610 | p = (const unsigned char *)luaL_checklstring(L, 2, &n); | ||
| 3611 | pe = p + n; | ||
| 3612 | |||
| 3613 | luaL_buffinit(L, &B); | ||
| 3614 | |||
| 3615 | while (p < pe) { | ||
| 3616 | int in = (int)MIN((size_t)(pe - p), step), out; | ||
| 3617 | |||
| 3618 | if (!EVP_CipherUpdate(ctx, (void *)luaL_prepbuffer(&B), &out, p, in)) | ||
| 3619 | return throwssl(L, "cipher:update"); | ||
| 3620 | |||
| 3621 | p += in; | ||
| 3622 | luaL_addsize(&B, out); | ||
| 3623 | } | ||
| 3624 | |||
| 3625 | luaL_pushresult(&B); | ||
| 3626 | |||
| 3627 | return 1; | ||
| 3628 | } /* cipher_update() */ | ||
| 3629 | |||
| 3630 | |||
| 3631 | static int cipher_final(lua_State *L) { | ||
| 3632 | EVP_CIPHER_CTX *ctx = luaL_checkudata(L, 1, CIPHER_CLASS); | ||
| 3633 | luaL_Buffer B; | ||
| 3634 | size_t block; | ||
| 3635 | int out; | ||
| 3636 | |||
| 3637 | block = EVP_CIPHER_CTX_block_size(ctx); | ||
| 3638 | |||
| 3639 | if (LUAL_BUFFERSIZE < block) | ||
| 3640 | return luaL_error(L, "cipher:update: LUAL_BUFFERSIZE(%u) < EVP_CIPHER_CTX_block_size(%u)", (unsigned)LUAL_BUFFERSIZE, (unsigned)block); | ||
| 3641 | |||
| 3642 | luaL_buffinit(L, &B); | ||
| 3643 | |||
| 3644 | if (!EVP_CipherFinal(ctx, (void *)luaL_prepbuffer(&B), &out)) | ||
| 3645 | return throwssl(L, "cipher:final"); | ||
| 3646 | |||
| 3647 | luaL_addsize(&B, out); | ||
| 3648 | luaL_pushresult(&B); | ||
| 3649 | |||
| 3650 | return 1; | ||
| 3651 | } /* cipher_final() */ | ||
| 3652 | |||
| 3653 | |||
| 3654 | static int cipher__gc(lua_State *L) { | ||
| 3655 | EVP_CIPHER_CTX *ctx = luaL_checkudata(L, 1, CIPHER_CLASS); | ||
| 3656 | |||
| 3657 | EVP_CIPHER_CTX_cleanup(ctx); | ||
| 3658 | |||
| 3659 | return 0; | ||
| 3660 | } /* cipher__gc() */ | ||
| 3661 | |||
| 3662 | |||
| 3663 | static const luaL_Reg cipher_methods[] = { | ||
| 3664 | { "encrypt", &cipher_update }, | ||
| 3665 | { "decrypt", &cipher_final }, | ||
| 3666 | { "update", &cipher_update }, | ||
| 3667 | { "final", &cipher_final }, | ||
| 3668 | { NULL, NULL }, | ||
| 3669 | }; | ||
| 3670 | |||
| 3671 | static const luaL_Reg cipher_metatable[] = { | ||
| 3672 | { "__gc", &cipher__gc }, | ||
| 3673 | { NULL, NULL }, | ||
| 3674 | }; | ||
| 3675 | |||
| 3676 | static const luaL_Reg cipher_globals[] = { | ||
| 3677 | { "new", &cipher_new }, | ||
| 3678 | { "interpose", &cipher_interpose }, | ||
| 3679 | { NULL, NULL }, | ||
| 3680 | }; | ||
| 3681 | |||
| 3682 | int luaopen__openssl_cipher(lua_State *L) { | ||
| 3683 | initall(L); | ||
| 3684 | |||
| 3685 | luaL_newlib(L, cipher_globals); | ||
| 3686 | |||
| 3687 | return 1; | ||
| 3688 | } /* luaopen__openssl_cipher() */ | ||
| 3689 | |||
| 3690 | |||
| 3524 | static void initall(lua_State *L) { | 3691 | static void initall(lua_State *L) { |
| 3525 | ERR_load_crypto_strings(); | 3692 | ERR_load_crypto_strings(); |
| 3526 | OpenSSL_add_all_algorithms(); | 3693 | OpenSSL_add_all_algorithms(); |
| @@ -3537,6 +3704,7 @@ static void initall(lua_State *L) { | |||
| 3537 | addclass(L, SSL_CLASS, ssl_methods, ssl_metatable); | 3704 | addclass(L, SSL_CLASS, ssl_methods, ssl_metatable); |
| 3538 | addclass(L, DIGEST_CLASS, md_methods, md_metatable); | 3705 | addclass(L, DIGEST_CLASS, md_methods, md_metatable); |
| 3539 | addclass(L, HMAC_CLASS, hmac_methods, hmac_metatable); | 3706 | addclass(L, HMAC_CLASS, hmac_methods, hmac_metatable); |
| 3707 | addclass(L, CIPHER_CLASS, cipher_methods, cipher_metatable); | ||
| 3540 | } /* initall() */ | 3708 | } /* initall() */ |
| 3541 | 3709 | ||
| 3542 | 3710 | ||
diff --git a/openssl.cipher.lua b/openssl.cipher.lua new file mode 100644 index 0000000..876cd1b --- /dev/null +++ b/openssl.cipher.lua | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | local ctx = require"_openssl.cipher" | ||
| 2 | |||
| 3 | return ctx | ||
