static int openssl_xalgor_get(lua_State* L) { int type; void* val; ASN1_OBJECT *obj, *dup; X509_ALGOR* alg = CHECK_OBJECT(1, X509_ALGOR, "openssl.x509_algor"); X509_ALGOR_get0(&obj, &type, &val, alg); if (obj != NULL) { dup = OBJ_dup(obj); PUSH_OBJECT(dup, "openssl.asn1_object"); } else lua_pushnil(L); if (type == V_ASN1_UNDEF) lua_pushnil(L); else { ASN1_STRING *s = ASN1_STRING_dup(val); PUSH_OBJECT(s, "openssl.asn1_string"); } return 2; }
static LUA_FUNCTION(openssl_csr_parse) { X509_REQ * csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); X509_NAME * subject = X509_REQ_get_subject_name(csr); STACK_OF(X509_EXTENSION) *exts = X509_REQ_get_extensions(csr); lua_newtable(L); openssl_push_asn1(L, csr->signature, V_ASN1_BIT_STRING); lua_setfield(L, -2, "signature"); openssl_push_x509_algor(L, csr->sig_alg); lua_setfield(L, -2, "sig_alg"); lua_newtable(L); AUXILIAR_SET(L, -1, "version", X509_REQ_get_version(csr), integer); openssl_push_xname_asobject(L, subject); lua_setfield(L, -2, "subject"); if (exts) { PUSH_OBJECT(exts, "openssl.stack_of_x509_extension"); lua_setfield(L, -2, "extensions"); } { X509_REQ_INFO* ri = csr->req_info; int i, c; EVP_PKEY *pubkey = X509_REQ_get_pubkey(csr); lua_newtable(L); c = X509_REQ_get_attr_count(csr); if (c > 0) { lua_newtable(L); for (i = 0; i < c ; i++) { X509_ATTRIBUTE *attr = X509_REQ_get_attr(csr, i); attr = X509_ATTRIBUTE_dup(attr); PUSH_OBJECT(attr, "openssl.x509_attribute"); lua_rawseti(L, -2, i + 1); } lua_setfield(L, -2, "attributes"); } lua_newtable(L); openssl_push_asn1object(L, ri->pubkey->algor->algorithm); lua_setfield(L, -2, "algorithm"); AUXILIAR_SETOBJECT(L, pubkey , "openssl.evp_pkey", -1, "pubkey"); lua_setfield(L, -2, "pubkey"); lua_setfield(L, -2, "req_info"); } return 1; }
static int openssl_eckey_group(lua_State *L) { const EC_GROUP* g = openssl_get_ec_group(L, 1, 2, 3); if (g) { const EC_POINT* p = EC_GROUP_get0_generator(g); p = EC_POINT_dup(p, g); PUSH_OBJECT(g, "openssl.ec_group"); PUSH_OBJECT(p, "openssl.ec_point"); return 2; } return 0; };
static int openssl_ssl_peer(lua_State*L) { SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); X509* x = SSL_get_peer_certificate(s); STACK_OF(X509) *sk = SSL_get_peer_cert_chain(s); PUSH_OBJECT(x, "openssl.x509"); if (sk) { sk = openssl_sk_x509_dup(sk); PUSH_OBJECT(sk, "openssl.stack_of_x509"); return 2; } return 1; }
static int openssl_ssl_dup(lua_State*L) { SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); SSL* ss = SSL_dup(s); PUSH_OBJECT(ss, "openssl.ssl"); return 1; }
static int openssl_ssl_session_peer(lua_State*L) { SSL_SESSION* session = CHECK_OBJECT(1, SSL_SESSION, "openssl.ssl_session"); X509 *x = SSL_SESSION_get0_peer(session); PUSH_OBJECT(x, "openssl.x509"); return 1; }
static int openssl_cms_create(lua_State*L) { CMS_ContentInfo *cms = NULL; if (lua_gettop(L) == 1) { cms = CMS_ContentInfo_new(); } else { BIO* in = load_bio_object(L, 1); if (lua_isuserdata(L, 2)) { const EVP_MD* md = get_digest(L, 2); int flags = luaL_optint(L, 3, 0); cms = CMS_digest_create(in, md, flags); } else { int flags = luaL_optint(L, 2, 0); cms = CMS_data_create(in, flags); } } PUSH_OBJECT(cms, "openssl.cms"); return 1; }
static int openssl_cms_read(lua_State *L) { BIO* in = load_bio_object(L, 1); int fmt = luaL_checkoption(L, 2, "auto", format); CMS_ContentInfo *cms = NULL; if (fmt == FORMAT_AUTO) { fmt = bio_is_der(in) ? FORMAT_DER : FORMAT_PEM; } if (fmt == FORMAT_DER) { cms = d2i_CMS_bio(in, NULL); //CMS_ContentInfo *cms = CMS_ContentInfo_new(); //int ret = i2d_CMS_bio(bio, cms); }else if (fmt == FORMAT_PEM) { cms = PEM_read_bio_CMS(in, NULL, NULL, NULL); }else if (fmt == FORMAT_SMIME) { BIO *indata = load_bio_object(L, 3); cms = SMIME_read_CMS(in, &indata); } if (cms) { PUSH_OBJECT(cms, "openssl.cms"); return 1; } return openssl_pushresult(L, 0); }
static LUA_FUNCTION(openssl_csr_dup) { X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); csr = X509_REQ_dup(csr); PUSH_OBJECT(csr, "openssl.x509_req"); return 1; };
static int openssl_xattr_dup(lua_State*L) { X509_ATTRIBUTE* attr = CHECK_OBJECT(1, X509_ATTRIBUTE, "openssl.x509_attribute"); X509_ATTRIBUTE* dup = X509_ATTRIBUTE_dup(attr); PUSH_OBJECT(dup, "openssl.x509_attribute"); return 1; }
static int openssl_xext_dup(lua_State* L) { X509_EXTENSION *x = CHECK_OBJECT(1, X509_EXTENSION, "openssl.x509_extension"); X509_EXTENSION *d = X509_EXTENSION_dup(x); PUSH_OBJECT(d, "openssl.x509_extension"); return 1; };
static LUA_FUNCTION(openssl_pkcs7_encrypt) { PKCS7 * p7 = NULL; BIO *in = load_bio_object(L, 1); STACK_OF(X509) *recipcerts = openssl_sk_x509_fromtable(L, 2); const EVP_CIPHER *cipher = get_cipher(L, 3, "des3"); long flags = luaL_optint(L, 4, 0); if (cipher == NULL) { luaL_error(L, "Failed to get cipher"); } p7 = PKCS7_encrypt(recipcerts, in, cipher, flags); BIO_free(in); sk_X509_pop_free(recipcerts, X509_free); if (p7 == NULL) { lua_pushnil(L); } else { PUSH_OBJECT(p7, "openssl.pkcs7"); } return 1; }
static LUA_FUNCTION(openssl_pkcs7_sign) { BIO *in = load_bio_object(L, 1); X509 *cert = CHECK_OBJECT(2, X509, "openssl.x509"); EVP_PKEY *privkey = CHECK_OBJECT(3, EVP_PKEY, "openssl.evp_pkey"); STACK_OF(X509) *others = lua_isnoneornil(L, 4) ? 0 : openssl_sk_x509_fromtable(L, 4); long flags = luaL_optint(L, 5, 0); PKCS7 *p7 = NULL; luaL_argcheck(L, openssl_pkey_is_private(privkey), 3, "must be private key"); if (!X509_check_private_key(cert, privkey)) luaL_error(L, "sigcert and private key not match"); p7 = PKCS7_sign(cert, privkey, others, in, flags); BIO_free(in); if (others) sk_X509_pop_free(others, X509_free); if (p7) { PUSH_OBJECT(p7, "openssl.pkcs7"); return 1; } else { luaL_error(L, "error creating PKCS7 structure!"); } return 0; }
static int openssl_ocsp_request_parse(lua_State*L) { OCSP_REQUEST *req = CHECK_OBJECT(1, OCSP_REQUEST, "openssl.ocsp_request"); int utf8 = lua_isnoneornil(L, 2) ? 1 : lua_toboolean(L, 2); OCSP_REQINFO *inf = req->tbsRequest; OCSP_SIGNATURE *sig = req->optionalSignature; BIO* bio = BIO_new(BIO_s_mem()); int i, num; lua_newtable(L); AUXILIAR_SET(L, -1, "version", ASN1_INTEGER_get(inf->version), integer); if (inf->requestorName) { opensl_push_general_name(L, inf->requestorName, utf8); lua_setfield(L, -2, "requestorName"); } num = sk_OCSP_ONEREQ_num(inf->requestList); lua_newtable(L); for (i = 0; i < num; i++) { OCSP_ONEREQ *one = sk_OCSP_ONEREQ_value(inf->requestList, i); OCSP_CERTID *a = one->reqCert; lua_newtable(L); { openssl_push_x509_algor(L, a->hashAlgorithm); lua_setfield(L, -2, "hashAlgorithm"); PUSH_ASN1_OCTET_STRING(L, a->issuerNameHash); lua_setfield(L, -2, "issuerNameHash"); PUSH_ASN1_OCTET_STRING(L, a->issuerKeyHash); lua_setfield(L, -2, "issuerKeyHash"); PUSH_ASN1_INTEGER(L, a->serialNumber); lua_setfield(L, -2, "serialNumber"); } lua_rawseti(L, -2, i + 1); } lua_setfield(L, -2, "requestList"); if (inf->requestExtensions){ STACK_OF(X509_EXTENSION) *extensions = sk_X509_EXTENSION_dup(inf->requestExtensions); PUSH_OBJECT(extensions,"openssl.stack_of_x509_extension"); lua_setfield(L,-2, "extensions"); } if (sig) { BIO_reset(bio); X509_signature_print(bio, sig->signatureAlgorithm, sig->signature); for (i = 0; i < sk_X509_num(sig->certs); i++) { X509_print(bio, sk_X509_value(sig->certs, i)); PEM_write_bio_X509(bio, sk_X509_value(sig->certs, i)); } } BIO_free(bio); return 1; }
static LUA_FUNCTION(openssl_ts_req_to_verify_ctx) { TS_REQ *req = CHECK_OBJECT(1, TS_REQ, "openssl.ts_req"); TS_VERIFY_CTX *ctx = TS_REQ_to_TS_VERIFY_CTX(req, NULL); PUSH_OBJECT(ctx, "openssl.ts_verify_ctx"); return 1; }
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 LUA_FUNCTION(openssl_evp_digest_init) { EVP_MD* md = CHECK_OBJECT(1, EVP_MD, "openssl.evp_digest"); ENGINE* e = lua_gettop(L) > 1 ? CHECK_OBJECT(2, ENGINE, "openssl.engine") : NULL; EVP_MD_CTX* ctx = EVP_MD_CTX_create(); if (ctx) { int ret; EVP_MD_CTX_init(ctx); ret = EVP_DigestInit_ex(ctx, md, e); if (ret == 1) { PUSH_OBJECT(ctx, "openssl.evp_digest_ctx"); } else { EVP_MD_CTX_destroy(ctx); return openssl_pushresult(L, ret); } } else lua_pushnil(L); return 1; }
static int openssl_xattr_data(lua_State*L) { X509_ATTRIBUTE* attr = CHECK_OBJECT(1, X509_ATTRIBUTE, "openssl.x509_attribute"); if (lua_type(L, 2) == LUA_TSTRING) { int attrtype = luaL_checkint(L, 2); size_t size; int ret; const char *data = luaL_checklstring(L, 3, &size); if (attr->single) ASN1_TYPE_free((ASN1_TYPE*)attr->value.ptr); else sk_ASN1_TYPE_pop_free(attr->value.set, ASN1_TYPE_free); attr->value.ptr = NULL; ret = X509_ATTRIBUTE_set1_data(attr, attrtype, data, size); return openssl_pushresult(L, ret); } else { int idx = luaL_checkint(L, 2); int attrtype = luaL_checkint(L, 3); ASN1_STRING *as = (ASN1_STRING *)X509_ATTRIBUTE_get0_data(attr, idx, attrtype, NULL); as = ASN1_STRING_dup(as); PUSH_OBJECT(as, "openssl.asn1_string"); return 1; } }
static int openssl_xname_dup(lua_State*L) { X509_NAME* xn = CHECK_OBJECT(1, X509_NAME, "openssl.x509_name"); X509_NAME* dup = X509_NAME_dup(xn); PUSH_OBJECT(dup, "openssl.x509_name"); return 1; };
static int openssl_ssl_ctx_cert_store(lua_State*L) { SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); X509_STORE *store = NULL; #if OPENSSL_VERSION_NUMBER > 0x10002000L if (lua_isnoneornil(L, 2)) { store = SSL_CTX_get_cert_store(ctx); CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE); PUSH_OBJECT(store, "openssl.x509_store"); return 1; } else { store = CHECK_OBJECT(2, X509_STORE, "openssl.x509_store"); CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE); SSL_CTX_set_cert_store(ctx, store); X509_STORE_set_trust(store, 1); return 0; } #else luaL_error(L, "NYI, openssl below 1.0.2 not fully support this feature"); return 0; #endif }
static int openssl_ts_req_dup(lua_State*L) { TS_REQ* req = CHECK_OBJECT(1, TS_REQ, "openssl.ts_req"); req = TS_REQ_dup(req); PUSH_OBJECT(req, "openssl.ts_req"); return 1; }
int openssl_engine(lua_State *L) { const ENGINE* eng = NULL; if (lua_isstring(L, 1)) { const char* id = luaL_checkstring(L, 1); eng = ENGINE_by_id(id); } else if (lua_isboolean(L, 1)) { int first = lua_toboolean(L, 1); if (first) eng = ENGINE_get_first(); else eng = ENGINE_get_last(); } else luaL_error(L, "#1 may be string or boolean\n" "\tstring for an engine id to load\n" "\ttrue for first engine, false or last engine\n" "\tbut we get %s:%s", lua_typename(L, lua_type(L, 1)), lua_tostring(L, 1)); if (eng) { PUSH_OBJECT((void*)eng, "openssl.engine"); } else lua_pushnil(L); return 1; }
static int openssl_xalgor_dup(lua_State* L) { X509_ALGOR* alg = CHECK_OBJECT(1, X509_ALGOR, "openssl.x509_algor"); X509_ALGOR* ano = X509_ALGOR_dup(alg); PUSH_OBJECT(ano, "openssl.x509_algor"); return 1; }
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 LUA_FUNCTION(openssl_crl_read) { BIO * in = load_bio_object(L, 1); int fmt = luaL_checkoption(L, 2, "auto", format); X509_CRL *crl = NULL; if (fmt == FORMAT_AUTO || fmt == FORMAT_PEM) { crl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); BIO_reset(in); } if ((fmt == FORMAT_AUTO && crl == NULL) || fmt == FORMAT_DER) { crl = d2i_X509_CRL_bio(in, NULL); BIO_reset(in); } BIO_free(in); if (crl) { PUSH_OBJECT(crl, "openssl.x509_crl"); return 1; } return 0; }
static LUA_FUNCTION(openssl_csr_read) { BIO * in = load_bio_object(L, 1); int fmt = luaL_checkoption(L, 2, "auto", format); X509_REQ * csr = NULL; if (fmt == FORMAT_AUTO) { fmt = bio_is_der(in) ? FORMAT_DER : FORMAT_PEM; } if (fmt == FORMAT_PEM) { csr = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL); BIO_reset(in); }else if (fmt == FORMAT_DER) { csr = d2i_X509_REQ_bio(in, NULL); BIO_reset(in); } BIO_free(in); if (csr) { PUSH_OBJECT(csr, "openssl.x509_req"); return 1; } return openssl_pushresult(L, 0); }
static LUA_FUNCTION(openssl_csr_attribute) { X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); if (auxiliar_isclass(L, "openssl.x509_attribute", 2)) { X509_ATTRIBUTE *attr = CHECK_OBJECT(2, X509_ATTRIBUTE, "openssl.x509_attribute"); int ret = X509_REQ_add1_attr(csr, attr); return openssl_pushresult(L, ret); } else if (lua_isnumber(L, 2)) { int loc = luaL_checkint(L, 2); X509_ATTRIBUTE *attr = NULL; if (lua_isnone(L, 3)) { attr = X509_REQ_get_attr(csr, loc); attr = X509_ATTRIBUTE_dup(attr); } else if (lua_isnil(L, 3)) { attr = X509_REQ_delete_attr(csr, loc); } if (attr) { PUSH_OBJECT(attr, "openssl.x509_attribute"); } else lua_pushnil(L); return 1; } return 0; }
/*** add attribute to x509_req object @function attribute @tparam x509_attribute attribute attribute to add @treturn boolean result */ static LUA_FUNCTION(openssl_csr_attribute) { X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); if (auxiliar_getclassudata(L, "openssl.x509_attribute", 2)) { X509_ATTRIBUTE *attr = CHECK_OBJECT(2, X509_ATTRIBUTE, "openssl.x509_attribute"); int ret = X509_REQ_add1_attr(csr, attr); return openssl_pushresult(L, ret); } else if (lua_isnumber(L, 2)) { int loc = luaL_checkint(L, 2); X509_ATTRIBUTE *attr = NULL; if (lua_isnone(L, 3)) { attr = X509_REQ_get_attr(csr, loc); attr = X509_ATTRIBUTE_dup(attr); } else if (lua_isnil(L, 3)) { attr = X509_REQ_delete_attr(csr, loc); } if (attr) { PUSH_OBJECT(attr, "openssl.x509_attribute"); } else lua_pushnil(L); return 1; } else if (lua_istable(L, 2)) { int i; int ret = 1; int n = lua_rawlen(L, 2); for (i = 1; ret == 1 && i <= n; i++) { X509_ATTRIBUTE *attr; lua_rawgeti(L, 2, i); attr = NULL; if (lua_istable(L, -1)) { attr = openssl_new_xattribute(L, &attr, -1, NULL); ret = X509_REQ_add1_attr(csr, attr); X509_ATTRIBUTE_free(attr); } else { attr = CHECK_OBJECT(-1, X509_ATTRIBUTE, "openssl.x509_attribute"); ret = X509_REQ_add1_attr(csr, attr); } lua_pop(L, 1); } openssl_pushresult(L, ret); return 1; } return 0; }
static LUA_FUNCTION(openssl_bio_new_dgram) { int s = luaL_checkint(L, 1); int closeflag = luaL_checkoption(L, 2, "noclose", close_flags); BIO *bio = BIO_new_dgram(s, closeflag); PUSH_OBJECT(bio, "openssl.bio"); return 1; }
static LUA_FUNCTION(openssl_bio_new_accept) { const char* port = lua_tostring(L, 1); BIO* b = BIO_new_accept((char*)port); PUSH_OBJECT(b, "openssl.bio"); return 1; }