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) { } /* md_interpose() */ -static int md_update(lua_State *L) { - EVP_MD_CTX *ctx = luaL_checkudata(L, 1, DIGEST_CLASS); - int i, top = lua_gettop(L); +static void md_update_(lua_State *L, EVP_MD_CTX *ctx, int from, int to) { + int i; - for (i = 2; i < top; i++) { + for (i = from; i <= to; i++) { const void *p; size_t n; p = luaL_checklstring(L, i, &n); if (!EVP_DigestUpdate(ctx, p, n)) - return throwssl(L, "digest:update"); + throwssl(L, "digest:update"); } +} /* md_update_() */ + + +static int md_update(lua_State *L) { + EVP_MD_CTX *ctx = luaL_checkudata(L, 1, DIGEST_CLASS); + int i, top = lua_gettop(L); + + md_update_(L, ctx, 2, lua_gettop(L)); lua_pushboolean(L, 1); @@ -3399,6 +3406,8 @@ static int md_final(lua_State *L) { unsigned char md[EVP_MAX_MD_SIZE]; unsigned len; + md_update_(L, ctx, 2, lua_gettop(L)); + if (!EVP_DigestFinal_ex(ctx, md, &len)) return throwssl(L, "digest:final"); @@ -3470,17 +3479,24 @@ static int hmac_interpose(lua_State *L) { } /* hmac_interpose() */ -static int hmac_update(lua_State *L) { - HMAC_CTX *ctx = luaL_checkudata(L, 1, HMAC_CLASS); - int i, top = lua_gettop(L); +static void hmac_update_(lua_State *L, HMAC_CTX *ctx, int from, int to) { + int i; - for (i = 2; i < top; i++) { + for (i = from; i <= to; i++) { const void *p; size_t n; p = luaL_checklstring(L, i, &n); + HMAC_Update(ctx, p, n); } +} /* hmac_update_() */ + + +static int hmac_update(lua_State *L) { + HMAC_CTX *ctx = luaL_checkudata(L, 1, HMAC_CLASS); + + hmac_update_(L, ctx, 2, lua_gettop(L)); lua_pushboolean(L, 1); @@ -3493,6 +3509,8 @@ static int hmac_final(lua_State *L) { unsigned char hmac[EVP_MAX_MD_SIZE]; unsigned len; + hmac_update_(L, ctx, 2, lua_gettop(L)); + HMAC_Final(ctx, hmac, &len); lua_pushlstring(L, (char *)hmac, len); @@ -3614,34 +3632,46 @@ static int cipher_decrypt(lua_State *L) { } /* cipher_decrypt() */ -static int cipher_update(lua_State *L) { - EVP_CIPHER_CTX *ctx = luaL_checkudata(L, 1, CIPHER_CLASS); +static _Bool cipher_update_(lua_State *L, EVP_CIPHER_CTX *ctx, luaL_Buffer *B, int from, int to) { const unsigned char *p, *pe; - luaL_Buffer B; size_t block, step, n; + int i; block = EVP_CIPHER_CTX_block_size(ctx); if (LUAL_BUFFERSIZE < block * 2) - return luaL_error(L, "cipher:update: LUAL_BUFFERSIZE(%u) < 2 * EVP_CIPHER_CTX_block_size(%u)", (unsigned)LUAL_BUFFERSIZE, (unsigned)block); + luaL_error(L, "cipher:update: LUAL_BUFFERSIZE(%u) < 2 * EVP_CIPHER_CTX_block_size(%u)", (unsigned)LUAL_BUFFERSIZE, (unsigned)block); step = LUAL_BUFFERSIZE - block; - p = (const unsigned char *)luaL_checklstring(L, 2, &n); - pe = p + n; - - luaL_buffinit(L, &B); + for (i = from; i <= to; i++) { + p = (const unsigned char *)luaL_checklstring(L, i, &n); + pe = p + n; - while (p < pe) { - int in = (int)MIN((size_t)(pe - p), step), out; + while (p < pe) { + int in = (int)MIN((size_t)(pe - p), step), out; - if (!EVP_CipherUpdate(ctx, (void *)luaL_prepbuffer(&B), &out, p, in)) - goto sslerr; + if (!EVP_CipherUpdate(ctx, (void *)luaL_prepbuffer(B), &out, p, in)) + return 0; - p += in; - luaL_addsize(&B, out); + p += in; + luaL_addsize(B, out); + } } + return 1; +} /* cipher_update_() */ + + +static int cipher_update(lua_State *L) { + EVP_CIPHER_CTX *ctx = luaL_checkudata(L, 1, CIPHER_CLASS); + luaL_Buffer B; + + luaL_buffinit(L, &B); + + if (!cipher_update_(L, ctx, &B, 2, lua_gettop(L))) + goto sslerr; + luaL_pushresult(&B); return 1; @@ -3659,13 +3689,16 @@ static int cipher_final(lua_State *L) { size_t block; int out; + luaL_buffinit(L, &B); + + if (!cipher_update_(L, ctx, &B, 2, lua_gettop(L))) + goto sslerr; + block = EVP_CIPHER_CTX_block_size(ctx); if (LUAL_BUFFERSIZE < block) return luaL_error(L, "cipher:update: LUAL_BUFFERSIZE(%u) < EVP_CIPHER_CTX_block_size(%u)", (unsigned)LUAL_BUFFERSIZE, (unsigned)block); - luaL_buffinit(L, &B); - if (!EVP_CipherFinal(ctx, (void *)luaL_prepbuffer(&B), &out)) goto sslerr; |