diff options
author | William Ahern <william@server.local> | 2013-03-14 18:05:30 -0700 |
---|---|---|
committer | William Ahern <william@server.local> | 2013-03-14 18:05:30 -0700 |
commit | 9297c48c238eeea1aab59c00001d2f8af75a4b29 (patch) | |
tree | 39785e6899a46d82ea5248bc4241d1ba5bfff8f2 | |
parent | dff7b083b113bbed0de3e6233467cfccf0e7a80c (diff) | |
download | luaossl-9297c48c238eeea1aab59c00001d2f8af75a4b29.tar.gz luaossl-9297c48c238eeea1aab59c00001d2f8af75a4b29.tar.bz2 luaossl-9297c48c238eeea1aab59c00001d2f8af75a4b29.zip |
-n
make cipher API easier to use, and also fix Lua stack traversal bug in digest and hmac code which prematurely exited loop processing parameters
-rw-r--r-- | openssl.c | 83 |
1 files changed, 58 insertions, 25 deletions
@@ -3374,19 +3374,26 @@ static int md_interpose(lua_State *L) { | |||
3374 | } /* md_interpose() */ | 3374 | } /* md_interpose() */ |
3375 | 3375 | ||
3376 | 3376 | ||
3377 | static int md_update(lua_State *L) { | 3377 | static void md_update_(lua_State *L, EVP_MD_CTX *ctx, int from, int to) { |
3378 | EVP_MD_CTX *ctx = luaL_checkudata(L, 1, DIGEST_CLASS); | 3378 | int i; |
3379 | int i, top = lua_gettop(L); | ||
3380 | 3379 | ||
3381 | for (i = 2; i < top; i++) { | 3380 | for (i = from; i <= to; i++) { |
3382 | const void *p; | 3381 | const void *p; |
3383 | size_t n; | 3382 | size_t n; |
3384 | 3383 | ||
3385 | p = luaL_checklstring(L, i, &n); | 3384 | p = luaL_checklstring(L, i, &n); |
3386 | 3385 | ||
3387 | if (!EVP_DigestUpdate(ctx, p, n)) | 3386 | if (!EVP_DigestUpdate(ctx, p, n)) |
3388 | return throwssl(L, "digest:update"); | 3387 | throwssl(L, "digest:update"); |
3389 | } | 3388 | } |
3389 | } /* md_update_() */ | ||
3390 | |||
3391 | |||
3392 | static int md_update(lua_State *L) { | ||
3393 | EVP_MD_CTX *ctx = luaL_checkudata(L, 1, DIGEST_CLASS); | ||
3394 | int i, top = lua_gettop(L); | ||
3395 | |||
3396 | md_update_(L, ctx, 2, lua_gettop(L)); | ||
3390 | 3397 | ||
3391 | lua_pushboolean(L, 1); | 3398 | lua_pushboolean(L, 1); |
3392 | 3399 | ||
@@ -3399,6 +3406,8 @@ static int md_final(lua_State *L) { | |||
3399 | unsigned char md[EVP_MAX_MD_SIZE]; | 3406 | unsigned char md[EVP_MAX_MD_SIZE]; |
3400 | unsigned len; | 3407 | unsigned len; |
3401 | 3408 | ||
3409 | md_update_(L, ctx, 2, lua_gettop(L)); | ||
3410 | |||
3402 | if (!EVP_DigestFinal_ex(ctx, md, &len)) | 3411 | if (!EVP_DigestFinal_ex(ctx, md, &len)) |
3403 | return throwssl(L, "digest:final"); | 3412 | return throwssl(L, "digest:final"); |
3404 | 3413 | ||
@@ -3470,17 +3479,24 @@ static int hmac_interpose(lua_State *L) { | |||
3470 | } /* hmac_interpose() */ | 3479 | } /* hmac_interpose() */ |
3471 | 3480 | ||
3472 | 3481 | ||
3473 | static int hmac_update(lua_State *L) { | 3482 | static void hmac_update_(lua_State *L, HMAC_CTX *ctx, int from, int to) { |
3474 | HMAC_CTX *ctx = luaL_checkudata(L, 1, HMAC_CLASS); | 3483 | int i; |
3475 | int i, top = lua_gettop(L); | ||
3476 | 3484 | ||
3477 | for (i = 2; i < top; i++) { | 3485 | for (i = from; i <= to; i++) { |
3478 | const void *p; | 3486 | const void *p; |
3479 | size_t n; | 3487 | size_t n; |
3480 | 3488 | ||
3481 | p = luaL_checklstring(L, i, &n); | 3489 | p = luaL_checklstring(L, i, &n); |
3490 | |||
3482 | HMAC_Update(ctx, p, n); | 3491 | HMAC_Update(ctx, p, n); |
3483 | } | 3492 | } |
3493 | } /* hmac_update_() */ | ||
3494 | |||
3495 | |||
3496 | static int hmac_update(lua_State *L) { | ||
3497 | HMAC_CTX *ctx = luaL_checkudata(L, 1, HMAC_CLASS); | ||
3498 | |||
3499 | hmac_update_(L, ctx, 2, lua_gettop(L)); | ||
3484 | 3500 | ||
3485 | lua_pushboolean(L, 1); | 3501 | lua_pushboolean(L, 1); |
3486 | 3502 | ||
@@ -3493,6 +3509,8 @@ static int hmac_final(lua_State *L) { | |||
3493 | unsigned char hmac[EVP_MAX_MD_SIZE]; | 3509 | unsigned char hmac[EVP_MAX_MD_SIZE]; |
3494 | unsigned len; | 3510 | unsigned len; |
3495 | 3511 | ||
3512 | hmac_update_(L, ctx, 2, lua_gettop(L)); | ||
3513 | |||
3496 | HMAC_Final(ctx, hmac, &len); | 3514 | HMAC_Final(ctx, hmac, &len); |
3497 | 3515 | ||
3498 | lua_pushlstring(L, (char *)hmac, len); | 3516 | lua_pushlstring(L, (char *)hmac, len); |
@@ -3614,34 +3632,46 @@ static int cipher_decrypt(lua_State *L) { | |||
3614 | } /* cipher_decrypt() */ | 3632 | } /* cipher_decrypt() */ |
3615 | 3633 | ||
3616 | 3634 | ||
3617 | static int cipher_update(lua_State *L) { | 3635 | static _Bool cipher_update_(lua_State *L, EVP_CIPHER_CTX *ctx, luaL_Buffer *B, int from, int to) { |
3618 | EVP_CIPHER_CTX *ctx = luaL_checkudata(L, 1, CIPHER_CLASS); | ||
3619 | const unsigned char *p, *pe; | 3636 | const unsigned char *p, *pe; |
3620 | luaL_Buffer B; | ||
3621 | size_t block, step, n; | 3637 | size_t block, step, n; |
3638 | int i; | ||
3622 | 3639 | ||
3623 | block = EVP_CIPHER_CTX_block_size(ctx); | 3640 | block = EVP_CIPHER_CTX_block_size(ctx); |
3624 | 3641 | ||
3625 | if (LUAL_BUFFERSIZE < block * 2) | 3642 | if (LUAL_BUFFERSIZE < block * 2) |
3626 | return luaL_error(L, "cipher:update: LUAL_BUFFERSIZE(%u) < 2 * EVP_CIPHER_CTX_block_size(%u)", (unsigned)LUAL_BUFFERSIZE, (unsigned)block); | 3643 | luaL_error(L, "cipher:update: LUAL_BUFFERSIZE(%u) < 2 * EVP_CIPHER_CTX_block_size(%u)", (unsigned)LUAL_BUFFERSIZE, (unsigned)block); |
3627 | 3644 | ||
3628 | step = LUAL_BUFFERSIZE - block; | 3645 | step = LUAL_BUFFERSIZE - block; |
3629 | 3646 | ||
3630 | p = (const unsigned char *)luaL_checklstring(L, 2, &n); | 3647 | for (i = from; i <= to; i++) { |
3631 | pe = p + n; | 3648 | p = (const unsigned char *)luaL_checklstring(L, i, &n); |
3632 | 3649 | pe = p + n; | |
3633 | luaL_buffinit(L, &B); | ||
3634 | 3650 | ||
3635 | while (p < pe) { | 3651 | while (p < pe) { |
3636 | int in = (int)MIN((size_t)(pe - p), step), out; | 3652 | int in = (int)MIN((size_t)(pe - p), step), out; |
3637 | 3653 | ||
3638 | if (!EVP_CipherUpdate(ctx, (void *)luaL_prepbuffer(&B), &out, p, in)) | 3654 | if (!EVP_CipherUpdate(ctx, (void *)luaL_prepbuffer(B), &out, p, in)) |
3639 | goto sslerr; | 3655 | return 0; |
3640 | 3656 | ||
3641 | p += in; | 3657 | p += in; |
3642 | luaL_addsize(&B, out); | 3658 | luaL_addsize(B, out); |
3659 | } | ||
3643 | } | 3660 | } |
3644 | 3661 | ||
3662 | return 1; | ||
3663 | } /* cipher_update_() */ | ||
3664 | |||
3665 | |||
3666 | static int cipher_update(lua_State *L) { | ||
3667 | EVP_CIPHER_CTX *ctx = luaL_checkudata(L, 1, CIPHER_CLASS); | ||
3668 | luaL_Buffer B; | ||
3669 | |||
3670 | luaL_buffinit(L, &B); | ||
3671 | |||
3672 | if (!cipher_update_(L, ctx, &B, 2, lua_gettop(L))) | ||
3673 | goto sslerr; | ||
3674 | |||
3645 | luaL_pushresult(&B); | 3675 | luaL_pushresult(&B); |
3646 | 3676 | ||
3647 | return 1; | 3677 | return 1; |
@@ -3659,13 +3689,16 @@ static int cipher_final(lua_State *L) { | |||
3659 | size_t block; | 3689 | size_t block; |
3660 | int out; | 3690 | int out; |
3661 | 3691 | ||
3692 | luaL_buffinit(L, &B); | ||
3693 | |||
3694 | if (!cipher_update_(L, ctx, &B, 2, lua_gettop(L))) | ||
3695 | goto sslerr; | ||
3696 | |||
3662 | block = EVP_CIPHER_CTX_block_size(ctx); | 3697 | block = EVP_CIPHER_CTX_block_size(ctx); |
3663 | 3698 | ||
3664 | if (LUAL_BUFFERSIZE < block) | 3699 | if (LUAL_BUFFERSIZE < block) |
3665 | return luaL_error(L, "cipher:update: LUAL_BUFFERSIZE(%u) < EVP_CIPHER_CTX_block_size(%u)", (unsigned)LUAL_BUFFERSIZE, (unsigned)block); | 3700 | return luaL_error(L, "cipher:update: LUAL_BUFFERSIZE(%u) < EVP_CIPHER_CTX_block_size(%u)", (unsigned)LUAL_BUFFERSIZE, (unsigned)block); |
3666 | 3701 | ||
3667 | luaL_buffinit(L, &B); | ||
3668 | |||
3669 | if (!EVP_CipherFinal(ctx, (void *)luaL_prepbuffer(&B), &out)) | 3702 | if (!EVP_CipherFinal(ctx, (void *)luaL_prepbuffer(&B), &out)) |
3670 | goto sslerr; | 3703 | goto sslerr; |
3671 | 3704 | ||