aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/openssl.c60
-rw-r--r--src/openssl.ssl.context.lua13
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