static LUA_FUNCTION(openssl_bio_accept) { BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio"); int first = lua_isnoneornil(L, 2) ? 0 : lua_toboolean(L, 2); int ret = BIO_do_accept(bio); if (ret == 1) { if (!first) { BIO *nb = BIO_pop(bio); PUSH_OBJECT(nb, "openssl.bio"); openssl_newvalue(L, nb); lua_pushboolean(L, 1); openssl_setvalue(L, nb, "free_all"); return 1; } else return openssl_pushresult(L, ret); } else luaL_error(L, "BIO_do_accept fail"); return 0; }
static int openssl_ssl_ctx_new_ssl(lua_State*L) { SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); int server = 0; int mode_idx = 2; SSL *ssl = SSL_new(ctx); int ret = 1; BIO* bio = NULL; if (auxiliar_isclass(L, "openssl.bio", 2)) { BIO *bi = CHECK_OBJECT(2, BIO, "openssl.bio"); BIO *bo = bi; CRYPTO_add(&bi->references, 1, CRYPTO_LOCK_BIO); if (auxiliar_isclass(L, "openssl.bio", 3)) { bo = CHECK_OBJECT(3, BIO, "openssl.bio"); CRYPTO_add(&bo->references, 1, CRYPTO_LOCK_BIO); mode_idx = 4; } else mode_idx = 3; SSL_set_bio(ssl, bi, bo); ret = 1; } else if (lua_isnumber(L, 2)) { ret = SSL_set_fd(ssl, luaL_checkint(L, 2)); mode_idx = 3; } if (ret == 1 && !lua_isnoneornil(L, mode_idx)) { server = auxiliar_checkboolean(L, mode_idx); } if (ret == 1) { if (server) SSL_set_accept_state(ssl); else SSL_set_connect_state(ssl); PUSH_OBJECT(ssl, "openssl.ssl"); openssl_newvalue(L, ssl); } else { SSL_free(ssl); return openssl_pushresult(L, ret); } return 1; }
static LUA_FUNCTION(openssl_bio_get_ssl) { BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio"); SSL* ssl = NULL; int ret = BIO_get_ssl(bio, &ssl); if (ret == 1) { openssl_newvalue(L, ssl); PUSH_OBJECT(ssl, "openssl.ssl"); openssl_refrence(L, ssl, +1); return 1; } return 0; }
static int openssl_bio_new_connect(lua_State *L) { const char *host = luaL_checkstring(L, 1); BIO* bio = BIO_new_connect((char*)host); int doconn = 1; if (lua_isstring(L, 2)) { if (BIO_set_conn_port(bio, lua_tostring(L, 2)) <= 0) { BIO_free(bio); bio = NULL; } else { doconn = lua_isnoneornil(L, 3) ? doconn : auxiliar_checkboolean(L, 3); } } else doconn = auxiliar_checkboolean(L, 2); if (bio) { int ret = 1; if (doconn) { ret = BIO_do_connect(bio); } if (ret == 1) { PUSH_OBJECT(bio, "openssl.bio"); openssl_newvalue(L, bio); lua_pushboolean(L, 1); openssl_setvalue(L, bio, "free_all"); return 1; } else { BIO_free(bio); luaL_error(L, "Error creating connection to remote machine"); } } if (!bio) luaL_error(L, "Error creating connection BIO"); return 0; }
static int openssl_ssl_ctx_new_bio(lua_State*L) { SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); const char* host_addr = luaL_checkstring(L, 2); int server = lua_isnoneornil(L, 3) ? 0 : auxiliar_checkboolean(L, 3); int autoretry = lua_isnoneornil(L, 4) ? 1 : auxiliar_checkboolean(L, 4); SSL *ssl = NULL; BIO *bio = server ? BIO_new_ssl(ctx, 0) : BIO_new_ssl_connect(ctx); int ret = BIO_get_ssl(bio, &ssl); if (ret == 1 && ssl) { if (autoretry) SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); if (server) { BIO* acpt = BIO_new_accept((char*)host_addr); BIO_set_accept_bios(acpt, bio); bio = acpt; } else { ret = BIO_set_conn_hostname(bio, host_addr); } if (ret == 1) { PUSH_OBJECT(bio, "openssl.bio"); openssl_newvalue(L, bio); lua_pushboolean(L, 1); openssl_setvalue(L, bio, "free_all"); return 1; } else return openssl_pushresult(L, ret); } else { BIO_free(bio); bio = NULL; return 0; } }
static LUA_FUNCTION(openssl_bio_new_filter) { /* 0 1 2 3 4 5 */ static const char* sType[] = {"base64", "buffer", "cipher", "md", "ssl", NULL}; int type = luaL_checkoption(L, 1, NULL, sType); BIO* bio = NULL; int ret = 1; int closeflag = 0; switch (type) { case 0: bio = BIO_new(BIO_f_base64()); break; case 1: bio = BIO_new(BIO_f_buffer()); break; case 2: { const EVP_CIPHER* c = get_cipher(L, 2, NULL); size_t kl, il; const char* k = luaL_checklstring(L, 3, &kl); const char* v = luaL_checklstring(L, 4, &il); int encrypt = auxiliar_checkboolean(L, 5); bio = BIO_new(BIO_f_cipher()); BIO_set_cipher(bio, c, (const unsigned char*)k, (const unsigned char*)v, encrypt); } break; case 3: { const EVP_MD* md = get_digest(L, 2); bio = BIO_new(BIO_f_md()); ret = BIO_set_md(bio, md); } case 4: { SSL* ssl = CHECK_OBJECT(2, SSL, "openssl.ssl"); closeflag = luaL_checkoption(L, 3, "noclose", close_flags); bio = BIO_new(BIO_f_ssl()); ret = BIO_set_ssl(bio, ssl, closeflag); } break; default: ret = 0; } if (ret == 1 && bio) { PUSH_OBJECT(bio, "openssl.bio"); if (closeflag) { openssl_newvalue(L, bio); lua_pushboolean(L, 1); openssl_setvalue(L, bio, "free_all"); } return 1; } else { if (bio) BIO_free(bio); return openssl_pushresult(L, ret); } return 0; }
static int openssl_ssl_ctx_new(lua_State*L) { const char* meth = luaL_optstring(L, 1, "TLSv1"); #if OPENSSL_VERSION_NUMBER >= 0x01000000L const #endif SSL_METHOD* method = NULL; const char* ciphers; SSL_CTX* ctx; if (strcmp(meth, "SSLv3") == 0) method = SSLv3_method(); /* SSLv3 */ else if (strcmp(meth, "SSLv3_server") == 0) method = SSLv3_server_method(); /* SSLv3 */ else if (strcmp(meth, "SSLv3_client") == 0) method = SSLv3_client_method(); /* SSLv3 */ else if (strcmp(meth, "SSLv23") == 0) method = SSLv23_method(); /* SSLv3 but can rollback to v2 */ else if (strcmp(meth, "SSLv23_server") == 0) method = SSLv23_server_method(); /* SSLv3 but can rollback to v2 */ else if (strcmp(meth, "SSLv23_client") == 0) method = SSLv23_client_method(); /* SSLv3 but can rollback to v2 */ else if (strcmp(meth, "TLSv1_1") == 0) method = TLSv1_1_method(); /* TLSv1.0 */ else if (strcmp(meth, "TLSv1_1_server") == 0) method = TLSv1_1_server_method(); /* TLSv1.0 */ else if (strcmp(meth, "TLSv1_1_client") == 0) method = TLSv1_1_client_method(); /* TLSv1.0 */ else if (strcmp(meth, "TLSv1_2") == 0) method = TLSv1_2_method(); /* TLSv1.0 */ else if (strcmp(meth, "TLSv1_2_server") == 0) method = TLSv1_2_server_method(); /* TLSv1.0 */ else if (strcmp(meth, "TLSv1_2_client") == 0) method = TLSv1_2_client_method(); /* TLSv1.0 */ else if (strcmp(meth, "TLSv1") == 0) method = TLSv1_method(); /* TLSv1.0 */ else if (strcmp(meth, "TLSv1_server") == 0) method = TLSv1_server_method(); /* TLSv1.0 */ else if (strcmp(meth, "TLSv1_client") == 0) method = TLSv1_client_method(); /* TLSv1.0 */ else if (strcmp(meth, "DTLSv1") == 0) method = DTLSv1_method(); /* DTLSv1.0 */ else if (strcmp(meth, "DTLSv1_server") == 0) method = DTLSv1_server_method(); /* DTLSv1.0 */ else if (strcmp(meth, "DTLSv1_client") == 0) method = DTLSv1_client_method(); /* DTLSv1.0 */ #ifndef OPENSSL_NO_SSL2 #if OPENSSL_VERSION_NUMBER < 0x10100000L else if (strcmp(meth, "SSLv2") == 0) method = SSLv2_method(); /* SSLv2 */ else if (strcmp(meth, "SSLv2_server") == 0) method = SSLv2_server_method(); /* SSLv2 */ else if (strcmp(meth, "SSLv2_client") == 0) method = SSLv2_client_method(); #endif #ifdef LOAD_SSL_CUSTOM LOAD_SSL_CUSTOM #endif #endif else luaL_error(L, "#1:%s not supported\n" "Maybe SSLv3 SSLv23 TLSv1 TLSv1_1 TLSv1_2 DTLSv1 [SSLv2], option followed by _client or _server\n", "default is SSLv3", meth); ciphers = luaL_optstring(L, 2, SSL_DEFAULT_CIPHER_LIST); ctx = SSL_CTX_new(method); if (!ctx) luaL_error(L, "#1:%s not supported\n" "Maybe SSLv3 SSLv23 TLSv1 TLSv1_1 TLSv1_2 DTLSv1 [SSLv2], option followed by _client or _server\n", "default is SSLv3", meth); openssl_newvalue(L, ctx); SSL_CTX_set_cipher_list(ctx, ciphers); PUSH_OBJECT(ctx, "openssl.ssl_ctx"); SSL_CTX_set_app_data(ctx, L); return 1; }