diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/openssl.c | 60 | ||||
-rw-r--r-- | src/openssl.ssl.context.lua | 13 |
2 files changed, 67 insertions, 6 deletions
diff --git a/src/openssl.c b/src/openssl.c index 82483af..c3f8bbb 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -1763,6 +1763,20 @@ static BN_CTX *getctx(lua_State *L) { } /* getctx() */ +static int bn_tobin(lua_State *L) { + BIGNUM *bn = checksimple(L, 1, BIGNUM_CLASS); + size_t len; + void *dst; + + len = BN_num_bytes(bn); + dst = lua_newuserdata(L, len); + BN_bn2bin(bn, dst); + lua_pushlstring(L, dst, len); + + return 1; +} /* bn_tobin() */ + + static int bn__add(lua_State *L) { BIGNUM *r, *a, *b; @@ -1819,6 +1833,12 @@ static int bn__mod(lua_State *L) { if (!BN_mod(r, a, b, getctx(L))) return auxL_error(L, auxL_EOPENSSL, "bignum:__mod"); + /* lua has different rounding behaviour for mod than C */ + if (!BN_is_zero(r) && (BN_is_negative(a) ^ BN_is_negative(b))) { + if (!BN_add(r, r, b)) + return auxL_error(L, auxL_EOPENSSL, "bignum:__mod"); + } + return 1; } /* bn__mod() */ @@ -1888,21 +1908,40 @@ static int bn__gc(lua_State *L) { } /* bn__gc() */ +static BIO *getbio(lua_State *); + static int bn__tostring(lua_State *L) { BIGNUM *bn = checksimple(L, 1, BIGNUM_CLASS); - char *txt; + char *txt = NULL; + BIO *bio; + BUF_MEM *buf; if (!(txt = BN_bn2dec(bn))) - return auxL_error(L, auxL_EOPENSSL, "bignum:__tostring"); + goto sslerr; - lua_pushstring(L, txt); + /* use GC-visible BIO as temporary buffer */ + bio = getbio(L); + + if (BIO_puts(bio, txt) < 0) + goto sslerr; + + OPENSSL_free(txt); + txt = NULL; + + BIO_get_mem_ptr(bio, &buf); + lua_pushlstring(L, buf->data, buf->length); return 1; +sslerr: + OPENSSL_free(txt); + + return auxL_error(L, auxL_EOPENSSL, "bignum:__tostring"); } /* bn__tostring() */ static const luaL_Reg bn_methods[] = { - { NULL, NULL }, + { "tobin", &bn_tobin }, + { NULL, NULL }, }; static const luaL_Reg bn_metatable[] = { @@ -2391,8 +2430,8 @@ static int pk_toPEM(lua_State *L) { len = BIO_get_mem_data(bio, &pem); lua_pushlstring(L, pem, len); - BIO_reset(bio); + break; case 2: case 3: /* private, PrivateKey */ if (!PEM_write_bio_PrivateKey(bio, key, 0, 0, 0, 0, 0)) @@ -2400,6 +2439,7 @@ static int pk_toPEM(lua_State *L) { len = BIO_get_mem_data(bio, &pem); lua_pushlstring(L, pem, len); + BIO_reset(bio); break; #if 0 @@ -5539,9 +5579,11 @@ static int sx_new(lua_State *L) { method = (srv)? &SSLv2_server_method : &SSLv2_client_method; break; #endif +#ifndef OPENSSL_NO_SSL3 case 3: /* SSLv3 */ method = (srv)? &SSLv3_server_method : &SSLv3_client_method; break; +#endif case 4: /* SSLv23 */ method = (srv)? &SSLv23_server_method : &SSLv23_client_method; break; @@ -6525,13 +6567,19 @@ static const EVP_CIPHER *cipher_checktype(lua_State *L, int index) { static int cipher_new(lua_State *L) { const EVP_CIPHER *type; EVP_CIPHER_CTX *ctx; + unsigned char key[EVP_MAX_KEY_LENGTH] = { 0 }; type = cipher_checktype(L, 1); ctx = prepudata(L, sizeof *ctx, CIPHER_CLASS, NULL); EVP_CIPHER_CTX_init(ctx); - if (!EVP_CipherInit_ex(ctx, type, NULL, NULL, NULL, -1)) + /* + * NOTE: For some ciphers like AES calling :update or :final without + * setting a key causes a SEGV. Set a dummy key here. Same solution + * as used by Ruby OSSL. + */ + if (!EVP_CipherInit_ex(ctx, type, NULL, key, NULL, -1)) return auxL_error(L, auxL_EOPENSSL, "cipher.new"); return 1; diff --git a/src/openssl.ssl.context.lua b/src/openssl.ssl.context.lua index 44a9163..2098b54 100644 --- a/src/openssl.ssl.context.lua +++ b/src/openssl.ssl.context.lua @@ -1,3 +1,16 @@ local ctx = require"_openssl.ssl.context" +local pack = table.pack or function(...) return { n = select("#", ...); ... } end + +-- Allow passing a vararg of ciphers, or an array +local setCipherList; setCipherList = ctx.interpose("setCipherList", function (self, ciphers, ...) + if (...) then + local ciphers_t = pack(ciphers, ...) + ciphers = table.concat(ciphers_t, ":", 1, ciphers_t.n) + elseif type(ciphers) == "table" then + ciphers = table.concat(ciphers, ":") + end + return setCipherList(self, ciphers) +end) + return ctx |