static int openssl_new_xname(lua_State*L, X509_NAME* xname, int idx, int utf8) { int i, n; luaL_checktable(L, idx); luaL_argcheck(L, lua_istable(L, idx) && lua_rawlen(L, idx) > 0, idx, "must be not empty table as array"); n = lua_rawlen(L, idx); for (i = 0; i < n; i++) { lua_rawgeti(L, idx, i + 1); lua_pushnil(L); while (lua_next(L, -2) != 0) { size_t size; ASN1_OBJECT *obj = openssl_get_asn1object(L, -2, 0); const char *value = luaL_checklstring(L, -1, &size); int ret = X509_NAME_add_entry_by_OBJ(xname, obj, utf8 ? MBSTRING_UTF8 : MBSTRING_ASC, (unsigned char*)value, (int)size, -1, 0); ASN1_OBJECT_free(obj); if (ret != 1) { lua_pushfstring(L, "node at %d which %s=%s can't add to X509 name", i + 1, lua_tostring(L, -2), value); luaL_argerror(L, idx, lua_tostring(L, -1)); } lua_pop(L, 1); } } return 0; }
static int openssl_new_xattrs(lua_State*L) { size_t i; int idx = 1; STACK_OF(X509_ATTRIBUTE) *attrs = sk_X509_ATTRIBUTE_new_null(); luaL_checktable(L, idx); for (i = 0; i < lua_rawlen(L, idx); i++) { X509_ATTRIBUTE* a = NULL; const char* eprefix = NULL; lua_rawgeti(L, idx, i + 1); if (!lua_istable(L, -1)) { lua_pushfstring(L, "value at %d is not table", i + 1); luaL_argerror(L, idx, lua_tostring(L, -1)); } lua_pushfstring(L, "table %d at argument #%d:", idx, i + 1); eprefix = lua_tostring(L, -1); lua_pop(L, 1); a = openssl_new_xattribute(L, &a, lua_gettop(L), eprefix); if (a) { sk_X509_ATTRIBUTE_push(attrs, a); } lua_pop(L, 1); } PUSH_OBJECT(attrs, "openssl.stack_of_x509_attribute"); return 1; }
static int openssl_xattr_new(lua_State*L) { X509_ATTRIBUTE *x = NULL; luaL_checktable(L, 1); x = openssl_new_xattribute(L, &x, 1, NULL); PUSH_OBJECT(x, "openssl.x509_attribute"); return 1; }
static int openssl_xname_new(lua_State*L) { X509_NAME* xn; int utf8; luaL_checktable(L,1); utf8 = lua_isnoneornil(L, 2) ? 1 : lua_toboolean(L, 2); xn = X509_NAME_new(); openssl_new_xname(L, xn, 1, utf8); PUSH_OBJECT(xn,"openssl.x509_name"); return 1; };
static int openssl_xattr_new(lua_State*L) { X509_ATTRIBUTE *x=NULL; int utf8; luaL_checktable(L,1); utf8 = lua_isnoneornil(L, 2) ? 1 : lua_toboolean(L, 2); x = openssl_new_xattribute(L, &x, 1, utf8); PUSH_OBJECT(x,"openssl.x509_attribute"); return 1; }
static int openssl_xext_new(lua_State* L) { X509_EXTENSION *x=NULL; int utf8; luaL_checktable(L,1); utf8 = lua_isnoneornil(L, 2) ? 1 : lua_toboolean(L, 2); x = openssl_new_xextension(L, &x, 1, utf8); PUSH_OBJECT(x,"openssl.x509_extension"); return 1; };
static int openssl_xext_new(lua_State* L) { X509_EXTENSION *x = NULL; int v3 = 1; luaL_checktable(L, 1); if (!lua_isnone(L, 2)) v3 = lua_toboolean(L, 2); x = openssl_new_xextension(L, 1, v3); if (x) { PUSH_OBJECT(x, "openssl.x509_extension"); } else lua_pushnil(L); return 1; };
static int openssl_xext_new_sk(lua_State* L) { size_t i; X509_EXTENSION *x=NULL; STACK_OF(X509_EXTENSION) *exts; int utf8 = lua_isnoneornil(L, 2) ? 1 : lua_toboolean(L, 2); luaL_checktable(L,1); exts = sk_X509_EXTENSION_new_null(); for (i=0; i<lua_objlen(L, 1); i++) { lua_rawgeti(L,1, i+1); x = openssl_new_xextension(L, NULL, -1, utf8); sk_X509_EXTENSION_push(exts, x); } PUSH_OBJECT(exts, "openssl.stack_of_x509_extension"); return 1; };
static int openssl_ssl_ctx_add(lua_State*L) { SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); X509* x = CHECK_OBJECT(2, X509, "openssl.x509"); int ret = SSL_CTX_add_client_CA(ctx, x); if (ret == 1 && !lua_isnoneornil(L, 3)) { size_t i; luaL_checktable(L, 3); for (i = 1; ret == 1 && i <= lua_rawlen(L, 3); i++ ) { lua_rawgeti(L, 3, i); x = CHECK_OBJECT(2, X509, "openssl.x509"); lua_pop(L, 1); CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); ret = SSL_CTX_add_extra_chain_cert(ctx, x); } } return openssl_pushresult(L, ret); }
static int openssl_new_xattrs(lua_State*L) { size_t i; int idx = 1; int utf8 = lua_isnoneornil(L, 2) ? 1 : lua_toboolean(L, 2); STACK_OF(X509_ATTRIBUTE) *attrs = sk_X509_ATTRIBUTE_new_null(); luaL_checktable(L, idx); for(i=0; i<lua_rawlen(L, idx); i++) { X509_ATTRIBUTE* a = NULL; lua_rawgeti(L, idx, i+1); a = openssl_new_xattribute(L, &a, -1,utf8); if(a) { sk_X509_ATTRIBUTE_push(attrs,a); } lua_pop(L,1); } PUSH_OBJECT(attrs, "openssl.stack_of_x509_attribute"); return 1; }
static int openssl_new_xname(lua_State*L, X509_NAME* xname, int idx, int utf8) { int i, n; luaL_checktable(L, idx); luaL_argcheck(L, lua_istable(L, idx) && lua_rawlen(L, idx) > 0, idx, "must be not empty table as array"); n = lua_rawlen(L, idx); for (i = 0; i < n; i++) { lua_rawgeti(L, idx, i + 1); lua_pushnil(L); while (lua_next(L, -2) != 0) { size_t size; const char *value; int ret; int nid = openssl_get_nid(L, -2); value = luaL_checklstring(L, -1, &size); if (nid == NID_undef) { lua_pushfstring(L, "node at %d which key (%s) is not a valid object identity", i + 1, lua_tostring(L, -2)); luaL_argerror(L, idx, lua_tostring(L, -1)); } ret = X509_NAME_add_entry_by_NID(xname, nid, utf8 ? MBSTRING_UTF8 : MBSTRING_ASC, (unsigned char*)value, (int)size, -1, 0); if (ret != 1) { lua_pushfstring(L, "node at %d which %s=%s can't add to X509 name", i + 1, lua_tostring(L, -2), value); luaL_argerror(L, idx, lua_tostring(L, -1)); } lua_pop(L, 1); } } return 0; }
static int openssl_xext_new_sk(lua_State* L) { size_t i; X509_EXTENSION *x = NULL; STACK_OF(X509_EXTENSION) *exts; int v3 = 1; luaL_checktable(L, 1); if (!lua_isnone(L, 2)) v3 = lua_toboolean(L, 2); exts = sk_X509_EXTENSION_new_null(); for (i = 0; i < lua_rawlen(L, 1); i++) { lua_rawgeti(L, 1, i + 1); x = openssl_new_xextension(L, lua_gettop(L), v3); if (x) sk_X509_EXTENSION_push(exts, x); } PUSH_OBJECT(exts, "openssl.stack_of_x509_extension"); 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; }
static LUA_FUNCTION(openssl_crl_new) { int i; int n = lua_gettop(L); X509_CRL * crl = X509_CRL_new(); int ret = X509_CRL_set_version(crl, 0); X509* cacert = NULL; EVP_PKEY* capkey = NULL; const EVP_MD* md = NULL; int step; for (i = 1; ret == 1 && i <= n; i++) { if (i == 1) { luaL_argcheck(L, lua_istable(L, 1), 1, "must be table contains rovked entry table{reason,time,sn}"); if (lua_rawlen(L, i) > 0) { int j, m; m = lua_rawlen(L, i); for (j = 1; ret == 1 && j <= m; j++) { X509_REVOKED *revoked; BIGNUM* sn; lua_rawgeti(L, i, j); luaL_checktable(L, -1); lua_getfield(L, -1, "reason"); lua_getfield(L, -2, "time"); lua_getfield(L, -3, "sn"); sn = BN_get(L, -1); revoked = create_revoked(sn, lua_tointeger(L, -2), reason_get(L, -3)); if (revoked) { ret = X509_CRL_add0_revoked(crl, revoked); } BN_free(sn); lua_pop(L, 3); lua_pop(L, 1); }; } }; if (i == 2) { cacert = CHECK_OBJECT(2, X509, "openssl.x509"); ret = X509_CRL_set_issuer_name(crl, X509_get_issuer_name(cacert)); } if (i == 3) { capkey = CHECK_OBJECT(3, EVP_PKEY, "openssl.evp_pkey"); luaL_argcheck(L, openssl_pkey_is_private(capkey), 3, "must be private key"); luaL_argcheck(L, X509_check_private_key(cacert, capkey) == 1, 3, "evp_pkey not match with x509 in #2"); } } md = lua_isnoneornil(L, 4) ? EVP_get_digestbyname("sha1") : get_digest(L, 4); step = lua_isnoneornil(L, 5) ? 7 * 24 * 3600 : luaL_checkint(L, 5); if (ret == 1) { time_t lastUpdate; time_t nextUpdate; ASN1_TIME *ltm, *ntm; time(&lastUpdate); nextUpdate = lastUpdate + step; ltm = ASN1_TIME_new(); ntm = ASN1_TIME_new(); ASN1_TIME_set(ltm, lastUpdate); ASN1_TIME_set(ntm, nextUpdate); ret = X509_CRL_set_lastUpdate(crl, ltm); if (ret == 1) ret = X509_CRL_set_nextUpdate(crl, ntm); ASN1_TIME_free(ltm); ASN1_TIME_free(ntm); } if (cacert && capkey && md) { ret = (X509_CRL_sign(crl, capkey, md) == EVP_PKEY_size(capkey)); } if (ret == 1) { PUSH_OBJECT(crl, "openssl.x509_crl"); } else { X509_CRL_free(crl); return openssl_pushresult(L, ret); }; return 1; }
int l_easy_post(lua_State *L) { l_easy_private *privatep = luaL_checkudata(L, 1, LUACURL_EASYMETATABLE); CURL *curl = privatep->curl; int index_next, index_table, index_key; const char *value, *key; struct curl_httppost* post = NULL; struct curl_httppost* last = NULL; /* param verification */ luaL_checktable(L, 2); lua_getglobal(L, "pairs"); lua_pushvalue(L, 2); lua_call(L, 1, 3); /* got next, t, k on stack */ index_key = lua_gettop(L); index_table = index_key - 1; index_next = index_table - 1; while (1) { lua_pushvalue(L, index_next); lua_pushvalue(L, index_table); lua_pushvalue(L, index_key); lua_call(L, 2, 2); if (lua_isnil(L, -2)) break; /* duplicate key before converting to string (we need the original type for the iter function) */ lua_pushvalue(L, -2); key = lua_tostring(L, -1); lua_pop(L, 1); /* got {name = {file="/tmp/test.txt", type="text/plain"}} or {name = {file="dummy.html", data="<html><bold>bold</bold></html>, type="text/html"}} */ if (lua_istable(L, -1)) { const char* type, *file, *data; CURLFORMcode rc = CURLE_OK; int datalen; /* check for type option */ type = luaL_getstrfield(L, "type"); /* check for file option */ file = luaL_getstrfield(L, "file"); /* check for data option */ data = luaL_getlstrfield(L, "data", &datalen); /* file upload */ if ((file != NULL) && (data == NULL)) { rc = (type == NULL)? curl_formadd(&post, &last, CURLFORM_COPYNAME, key, CURLFORM_FILE, file, CURLFORM_END): curl_formadd(&post, &last, CURLFORM_COPYNAME, key, CURLFORM_FILE, file, CURLFORM_CONTENTTYPE, type, CURLFORM_END); } /* data field */ else if ((file != NULL) && (data != NULL)) { /* Add a buffer to upload */ rc = (type != NULL)? curl_formadd(&post, &last, CURLFORM_COPYNAME, key, CURLFORM_BUFFER, file, CURLFORM_BUFFERPTR, data, CURLFORM_BUFFERLENGTH, datalen, CURLFORM_CONTENTTYPE, type, CURLFORM_END): curl_formadd(&post, &last, CURLFORM_COPYNAME, key, CURLFORM_BUFFER, file, CURLFORM_BUFFERPTR, data, CURLFORM_BUFFERLENGTH, datalen, CURLFORM_END); } else luaL_error(L, "Mandatory: \"file\""); if (rc != CURLE_OK) luaL_error(L, "cannot add form: %s", curl_easy_strerror(rc)); } /* go name=value */ else { value = luaL_checkstring(L, -1); /* add name/content section */ curl_formadd(&post, &last, CURLFORM_COPYNAME, key, CURLFORM_COPYCONTENTS, value, CURLFORM_END); } /* remove value */ lua_pop(L, 1); /* move key */ lua_replace(L, index_key); } curl_easy_setopt(curl, CURLOPT_HTTPPOST, post); return 0; }