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 | ||