static int openssl_ssl_ctx_mode(lua_State*L) { SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); int mode = 0; int ret; int i; if (!lua_isnoneornil(L, 2)) { int clear = lua_isboolean(L, 2) ? lua_toboolean(L, 2) : 0; i = lua_isboolean(L, 2) ? 3 : 2; while (i <= lua_gettop(L)) { mode = mode | auxiliar_checkoption(L, i++, NULL, sMode_options, iMode_options); } if (clear != 0) mode = SSL_CTX_set_mode(ctx, mode); else mode = SSL_CTX_clear_mode(ctx, mode); } else mode = SSL_CTX_get_mode(ctx); ret = 0; for (i = 0; i < sizeof(iMode_options) / sizeof(int); i++) { if (mode & iMode_options[i]) { lua_pushstring(L, sMode_options[i]); ret++; } } return ret; };
static LUA_FUNCTION(openssl_list) { static int options[] = { OBJ_NAME_TYPE_MD_METH, OBJ_NAME_TYPE_CIPHER_METH, OBJ_NAME_TYPE_PKEY_METH, OBJ_NAME_TYPE_COMP_METH }; static const char *names[] = {"digests", "ciphers", "pkeys", "comps", NULL}; int type = auxiliar_checkoption (L, 1, NULL, names, options); lua_createtable(L, 0, 0); OBJ_NAME_do_all_sorted(type, list_callback, L); return 1; }
static LUA_FUNCTION(openssl_pkey_decrypt) { size_t dlen = 0; EVP_PKEY *pkey = CHECK_OBJECT(1, EVP_PKEY, "openssl.evp_pkey"); const char *data = luaL_checklstring(L, 2, &dlen); int padding = auxiliar_checkoption(L, 3, "pkcs1", sPadding, iPadding); size_t clen = EVP_PKEY_size(pkey); EVP_PKEY_CTX *ctx = NULL; int ret = 0; if (pkey->type != EVP_PKEY_RSA && pkey->type != EVP_PKEY_RSA2) { luaL_argerror(L, 2, "EVP_PKEY must be of type RSA or RSA2"); return ret; } if (openssl_pkey_is_private(pkey)) { ctx = EVP_PKEY_CTX_new(pkey, pkey->engine); if (EVP_PKEY_decrypt_init(ctx) == 1) { if (EVP_PKEY_CTX_set_rsa_padding(ctx, padding) == 1) { byte* buf = malloc(clen); if (EVP_PKEY_decrypt(ctx, buf, &clen, (const unsigned char*)data, dlen) == 1) { lua_pushlstring(L, (const char*)buf, clen); ret = 1; } else ret = openssl_pushresult(L, 0); free(buf); } else ret = openssl_pushresult(L, 0); } else ret = openssl_pushresult(L, 0); EVP_PKEY_CTX_free(ctx); } else { luaL_argerror(L, 2, "EVP_PKEY must be private key"); } return ret; }
int openssl_get_padding(lua_State *L, int idx, const char *defval) { return auxiliar_checkoption(L, idx, defval, sPadding, iPadding); }
static int openssl_session_cache_mode(lua_State *L) { static const char* smode[] = { "off", "client", "server", "both", "no_auto_clear", NULL }; static const int imode[] = { SSL_SESS_CACHE_OFF, SSL_SESS_CACHE_CLIENT, SSL_SESS_CACHE_SERVER, SSL_SESS_CACHE_BOTH, SSL_SESS_CACHE_NO_AUTO_CLEAR, -1 }; SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); int n = lua_gettop(L); long mode = 0; int i; if (n > 1) { if (lua_isnumber(L, 2)) { mode = luaL_checkinteger(L, 2); mode = SSL_CTX_set_session_cache_mode(ctx, mode); } else { for (i = 2; i <= n; i++) { int j = auxiliar_checkoption(L, i, NULL, smode, imode); mode |= j; } mode = SSL_CTX_set_session_cache_mode(ctx, mode); } } else { mode = SSL_CTX_get_session_cache_mode(ctx); }; lua_newtable(L); i = 0; if (mode & SSL_SESS_CACHE_NO_AUTO_CLEAR) { lua_pushstring(L, smode[4]); lua_rawseti(L, -2, i++); } if (mode & SSL_SESS_CACHE_BOTH) { lua_pushstring(L, smode[3]); lua_rawseti(L, -2, i++); } else if (mode & SSL_SESS_CACHE_SERVER) { lua_pushstring(L, smode[2]); lua_rawseti(L, -2, i++); } else if (mode & SSL_SESS_CACHE_CLIENT) { lua_pushstring(L, smode[1]); lua_rawseti(L, -2, i++); } else if (mode & SSL_SESS_CACHE_OFF) { lua_pushstring(L, smode[0]); lua_rawseti(L, -2, i++); } return 1; }
static int openssl_ssl_ctx_verify_mode(lua_State*L) { SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); if (lua_gettop(L) > 1) { size_t i; int mode = 0; luaL_checktable(L, 2); for (i = 0; i < lua_rawlen(L, 2); i++) { lua_rawgeti(L, 2, i + 1); mode |= auxiliar_checkoption(L, -1, NULL, sVerifyMode_Options, iVerifyMode_Options); lua_pop(L, 1); } luaL_argcheck(L, lua_isnoneornil(L, 3) || lua_isfunction(L, 3), 3, "must be function callback"); if (lua_isfunction(L, 3)) { lua_pushvalue(L, 3); openssl_setvalue(L, ctx, "verify_cb"); SSL_CTX_set_verify(ctx, mode, openssl_verify_cb); } else { SSL_CTX_set_verify(ctx, mode, openssl_verify_cb); } return 0; } else { int i = 0; int mode = SSL_CTX_get_verify_mode(ctx); lua_pushinteger(L, mode); i += 1; if (mode == SSL_VERIFY_NONE) { lua_pushstring(L, "none"); i += 1; } else { if (mode & SSL_VERIFY_PEER) { lua_pushstring(L, "peer"); i += 1; } if (mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) { lua_pushstring(L, "fail_if_no_peer_cert"); i += 1; } if (mode & SSL_VERIFY_CLIENT_ONCE) { lua_pushstring(L, "client_once"); i += 1; } } return i; } return 0; }