aboutsummaryrefslogtreecommitdiffstats
path: root/openssl.c
diff options
context:
space:
mode:
authorLibravatarLibravatar William Ahern <william@server.local> 2013-03-14 18:05:30 -0700
committerLibravatarLibravatar William Ahern <william@server.local> 2013-03-14 18:05:30 -0700
commit9297c48c238eeea1aab59c00001d2f8af75a4b29 (patch)
tree39785e6899a46d82ea5248bc4241d1ba5bfff8f2 /openssl.c
parentdff7b083b113bbed0de3e6233467cfccf0e7a80c (diff)
downloadluaossl-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
Diffstat (limited to 'openssl.c')
-rw-r--r--openssl.c83
1 files changed, 58 insertions, 25 deletions
diff --git a/openssl.c b/openssl.c
index 7d01172..660d463 100644
--- a/openssl.c
+++ b/openssl.c
@@ -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;