static LUA_FUNCTION(openssl_csr_subject) { X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); if (lua_isnone(L, 2)) { X509_NAME *xn = X509_REQ_get_subject_name(csr); if (xn) openssl_push_xname_asobject(L, xn); else lua_pushnil(L); return 1; } else { X509_NAME* xn = CHECK_OBJECT(2, X509_NAME, "openssl.x509_name"); int ret = X509_REQ_set_subject_name(csr, xn); return openssl_pushresult(L, ret); } }
static LUA_FUNCTION(openssl_verifyInit) { const EVP_MD *md = get_digest(L, 1); ENGINE *e = lua_isnoneornil(L, 2) ? NULL : CHECK_OBJECT(2, ENGINE, "openssl.engine"); int ret = 0; EVP_MD_CTX *ctx = EVP_MD_CTX_create(); if (ctx) { ret = EVP_VerifyInit_ex(ctx, md, e); if (ret) { PUSH_OBJECT(ctx, "openssl.evp_digest_ctx"); } else return openssl_pushresult(L, ret); } else lua_pushnil(L); return 1; }
static LUA_FUNCTION(openssl_csr_digest) { X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); const EVP_MD *md = NULL; unsigned char buf[EVP_MAX_MD_SIZE]; unsigned int len = sizeof(buf); int ret; if (lua_isnoneornil(L, 2)) md = EVP_get_digestbyname("SHA1"); else md = get_digest(L, 2); ret = X509_REQ_digest(csr, md, buf, &len); if (ret == 1) { lua_pushlstring(L, (const char*)buf, len); return 1; } return openssl_pushresult(L, ret); };
static LUA_FUNCTION(openssl_rsa_sign) { RSA* rsa = CHECK_OBJECT(1, RSA, "openssl.rsa"); size_t l; const unsigned char* msg = (const unsigned char *)luaL_checklstring(L, 2, &l); int type = luaL_optint(L, 3, NID_md5_sha1); unsigned char* sig = OPENSSL_malloc(RSA_size(rsa)); int flen = l; unsigned int slen = RSA_size(rsa); int ret = RSA_sign(type, msg, flen, sig, &slen, rsa); if (ret == 1) { lua_pushlstring(L, (const char*)sig, slen); OPENSSL_free(sig); return 1; } OPENSSL_free(sig); return openssl_pushresult(L, ret); };
static int openssl_xext_object(lua_State* L) { X509_EXTENSION *x = CHECK_OBJECT(1, X509_EXTENSION, "openssl.x509_extension"); ASN1_OBJECT* obj; if (lua_isnone(L, 2)) { obj = X509_EXTENSION_get_object(x); obj = OBJ_dup(obj); PUSH_OBJECT(obj, "openssl.asn1_object"); return 1; } else { int nid = openssl_get_nid(L, 2); int ret; obj = OBJ_nid2obj(nid); ret = X509_EXTENSION_set_object(x, obj); return openssl_pushresult(L, ret); } };
static int openssl_xname_add_entry(lua_State*L) { X509_NAME* xn = CHECK_OBJECT(1, X509_NAME, "openssl.x509_name"); int nid = openssl_get_nid(L, 2); size_t size; const char*value = luaL_checklstring(L, 3, &size); int utf8 = lua_isnoneornil(L, 4) ? 1 : lua_toboolean(L, 4); int ret; if (nid == NID_undef) { lua_pushfstring(L, "(%s) is not a valid object identity", lua_tostring(L, 2)); luaL_argerror(L, 2, lua_tostring(L, -1)); } ret = X509_NAME_add_entry_by_NID(xn, nid, utf8 ? MBSTRING_UTF8 : MBSTRING_ASC, (unsigned char*)value, (int)size, -1, 0); if (ret != 1) { luaL_error(L, "%s=%s can't add to X509 name", lua_tostring(L, 2), value); }; return openssl_pushresult(L, ret); };
static int openssl_xattr_object(lua_State*L) { X509_ATTRIBUTE* attr = CHECK_OBJECT(1, X509_ATTRIBUTE, "openssl.x509_attribute"); if (lua_isnone(L, 2)) { ASN1_OBJECT* obj = X509_ATTRIBUTE_get0_object(attr); openssl_push_asn1object(L, obj); return 1; } else { int nid = openssl_get_nid(L, 2); ASN1_OBJECT* obj; int ret; luaL_argcheck(L, nid != NID_undef, 2, "invalid asn1_object identity"); obj = OBJ_nid2obj(nid); ret = X509_ATTRIBUTE_set1_object(attr, obj); return openssl_pushresult(L, ret); } }
static LUA_FUNCTION(openssl_signInit) { const EVP_MD *md = get_digest(L, 1); EVP_PKEY* pkey = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey"); ENGINE* e = lua_gettop(L) > 2 ? CHECK_OBJECT(3, ENGINE, "openssl.engine") : NULL; EVP_PKEY_CTX *pctx; EVP_MD_CTX *ctx = EVP_MD_CTX_create(); if (ctx) { int ret = EVP_DigestSignInit(ctx, &pctx, md, e, pkey); if (ret) { PUSH_OBJECT(ctx, "openssl.evp_digest_ctx"); } else return openssl_pushresult(L, ret); } else lua_pushnil(L); return 1; }
static LUA_FUNCTION(openssl_csr_extensions) { X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); if (lua_isnone(L, 2)) { STACK_OF(X509_EXTENSION) *sk = X509_REQ_get_extensions(csr); if (sk) { PUSH_OBJECT(sk, "openssl.stack_of_x509_extension"); } else lua_pushnil(L); return 1; } else { STACK_OF(X509_EXTENSION) *sk = CHECK_OBJECT(2, STACK_OF(X509_EXTENSION), "openssl.stack_of_x509_extension"); int ret = X509_REQ_add_extensions(csr, sk); return openssl_pushresult(L, ret); } }
static int openssl_cms_sign_receipt(lua_State*L) { CMS_ContentInfo *cms = CHECK_OBJECT(1, CMS_ContentInfo, "openssl.cms"); X509 *signcert = CHECK_OBJECT(2, X509, "openssl.x509"); EVP_PKEY* pkey = CHECK_OBJECT(3, EVP_PKEY, "openssl.evp_pkey"); STACK_OF(X509) *other = CHECK_OBJECT(4, STACK_OF(X509), "openssl.stack_of_x509"); unsigned int flags = luaL_optint(L, 5, 0); STACK_OF(CMS_SignerInfo) *sis = CMS_get0_SignerInfos(cms); if (sis) { CMS_SignerInfo *si = sk_CMS_SignerInfo_value(sis, 0); CMS_ContentInfo *srcms = CMS_sign_receipt(si, signcert, pkey, other, flags); if (srcms) { PUSH_OBJECT(srcms, "openssl.cms"); return 1; } } return openssl_pushresult(L, 0); }
static LUA_FUNCTION(openssl_crl_nextUpdate) { X509_CRL *crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); if (lua_isnone(L, 2)) { ASN1_TIME *tm = X509_CRL_get_nextUpdate(crl); PUSH_ASN1_TIME(L, tm); return 1; } else { int ret; time_t time = luaL_checkint(L, 2); ASN1_TIME *tm = ASN1_TIME_new(); ASN1_TIME_set(tm, time); ret = X509_CRL_set_nextUpdate(crl, tm); ASN1_TIME_free(tm); return openssl_pushresult(L, ret); } }
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 LUA_FUNCTION(openssl_signFinal) { EVP_MD_CTX *ctx = CHECK_OBJECT(1, EVP_MD_CTX, "openssl.evp_digest_ctx"); EVP_PKEY *pkey = lua_gettop(L) > 1 ? CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey") : NULL; size_t siglen = EVP_PKEY_size(pkey); unsigned char *sigbuf = malloc(siglen + 1); int ret = 0; if (pkey) ret = EVP_SignFinal(ctx, sigbuf, (unsigned int *)&siglen, pkey); else ret = EVP_DigestSignFinal(ctx, sigbuf, &siglen); if (ret == 1) { lua_pushlstring(L, (char *)sigbuf, siglen); } free(sigbuf); EVP_MD_CTX_cleanup(ctx); if (ret == 1) return 1; return openssl_pushresult(L, ret); }
static int openssl_ts_req_policy_id(lua_State*L) { TS_REQ* req = CHECK_OBJECT(1, TS_REQ, "openssl.ts_req"); if (lua_isnone(L, 2)) { ASN1_OBJECT* obj = TS_REQ_get_policy_id(req); openssl_push_asn1object(L, obj); ASN1_OBJECT_free(obj); return 1; } else { int nid = openssl_get_nid(L, 2); ASN1_OBJECT* obj; int ret; luaL_argcheck(L, nid != NID_undef, 2, "must be asn1_object object identified"); obj = OBJ_nid2obj(nid); ret = TS_REQ_set_policy_id(req, obj); return openssl_pushresult(L, ret); } }
static int openssl_ts_req_nonce(lua_State*L) { TS_REQ* req = CHECK_OBJECT(1, TS_REQ, "openssl.ts_req"); if (lua_isnone(L, 2)) { const ASN1_INTEGER* ai = TS_REQ_get_nonce(req); BIGNUM *bn; PUSH_ASN1_INTEGER(L, ai); bn = ASN1_INTEGER_to_BN(ai, NULL); PUSH_OBJECT(bn, "openssl.bn"); return 2; } else { BIGNUM *bn = BN_get(L, 2); ASN1_INTEGER *ai = BN_to_ASN1_INTEGER(bn, NULL); int ret = TS_REQ_set_nonce(req, ai); ASN1_INTEGER_free(ai); BN_free(bn); return openssl_pushresult(L, ret); } }
static LUA_FUNCTION(openssl_digest_ctx_clone) { EVP_MD_CTX *ctx = CHECK_OBJECT(1, EVP_MD_CTX, "openssl.evp_digest_ctx"); EVP_MD_CTX *d = EVP_MD_CTX_create(); if (d) { int ret; EVP_MD_CTX_init(d); ret = EVP_MD_CTX_copy_ex(d, ctx); if (ret == 1) { PUSH_OBJECT(d, "openssl.evp_digest_ctx"); return 1; } EVP_MD_CTX_destroy(d); return openssl_pushresult(L, ret); } else lua_pushnil(L); return 1; }
static LUA_FUNCTION(openssl_verifyInit) { const EVP_MD *md = get_digest(L, 1); EVP_PKEY* pkey = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey"); ENGINE* e = lua_gettop(L) > 2 ? CHECK_OBJECT(3, ENGINE, "openssl.engine") : NULL; EVP_PKEY_CTX *pctx = 0; EVP_MD_CTX *ctx = EVP_MD_CTX_create(); luaL_argcheck(L, !openssl_pkey_is_private(pkey), 2, "need public key"); if (ctx) { int ret = EVP_DigestVerifyInit(ctx, &pctx, md, e, pkey); if (ret) { PUSH_OBJECT(ctx, "openssl.evp_digest_ctx"); } else return openssl_pushresult(L, ret); } else lua_pushnil(L); return 1; }
/*** get FIPS mode @function FIPS_mode @treturn boolean return true when FIPS mode enabled, false when FIPS mode disabled. */ static int openssl_fips_mode(lua_State *L) { #if defined(LIBRESSL_VERSION_NUMBER) return 0; #else int ret =0, on = 0; if(lua_isnone(L, 1)) { on = FIPS_mode(); lua_pushboolean(L, on); return 1; } on = auxiliar_checkboolean(L, 1); ret = FIPS_mode_set(on); if(ret) lua_pushboolean(L, ret); else ret = openssl_pushresult(L, ret); return ret; #endif }
static int openssl_cms_write(lua_State *L) { CMS_ContentInfo *cms = CHECK_OBJECT(1, CMS_ContentInfo, "openssl.cms"); BIO *out = load_bio_object(L, 2); BIO *in = load_bio_object(L, 3); int flags = luaL_optint(L, 4, 0); int fmt = luaL_checkoption(L, 5, "smime", format); int ret = 0; if (fmt == FORMAT_SMIME) ret = SMIME_write_CMS(out, cms, in, flags); else if (fmt == FORMAT_PEM) ret = PEM_write_bio_CMS_stream(out, cms, in, flags); else if (fmt == FORMAT_DER) { ret = i2d_CMS_bio_stream(out, cms, in, flags); //i2d_CMS_bio } else luaL_argerror(L, 5, "only accept smime, pem or der"); return openssl_pushresult(L, ret); }
static LUA_FUNCTION(openssl_rsa_decrypt) { RSA* rsa = CHECK_OBJECT(1, RSA, "openssl.rsa"); size_t l; const unsigned char* from = (const unsigned char *) luaL_checklstring(L, 2, &l); int padding = openssl_get_padding(L, 3, "pkcs1"); int ispriv = lua_isnone(L, 4) ? is_private(rsa) : lua_toboolean(L, 4); unsigned char* to = OPENSSL_malloc(RSA_size(rsa)); int flen = l; flen = ispriv ? RSA_private_decrypt(flen, from, to, rsa, padding) : RSA_public_decrypt(flen, from, to, rsa, padding); if (flen > 0) { lua_pushlstring(L, (const char*)to, flen); OPENSSL_free(to); return 1; } OPENSSL_free(to); return openssl_pushresult(L, flen); };
static LUA_FUNCTION(openssl_pkcs7_verify) { int ret = 0; PKCS7 *p7 = CHECK_OBJECT(1, PKCS7, "openssl.pkcs7"); STACK_OF(X509) *signers = lua_isnoneornil(L, 2) ? NULL : openssl_sk_x509_fromtable(L, 2); X509_STORE *store = lua_isnoneornil(L, 3) ? NULL : CHECK_OBJECT(3, X509_STORE, "openssl.x509_store"); BIO* in = lua_isnoneornil(L, 4) ? NULL : load_bio_object(L, 4); long flags = luaL_optint(L, 5, 0); BIO* out = BIO_new(BIO_s_mem()); if (!store) flags |= PKCS7_NOVERIFY; if (PKCS7_verify(p7, signers, store, in, out, flags) == 1) { if (out && (flags & PKCS7_DETACHED) == 0) { BUF_MEM *bio_buf; BIO_get_mem_ptr(out, &bio_buf); lua_pushlstring(L, bio_buf->data, bio_buf->length); } else { lua_pushboolean(L, 1); } ret += 1; } else { ret = openssl_pushresult(L, 0); } if (signers) sk_X509_pop_free(signers, X509_free); if (out) BIO_free(out); if (in) BIO_free(in); return ret; }
/*** set extension of x509_req object @function extensions @tparam stack_of_x509_extension extensions @treturn boolean result true for success */ static LUA_FUNCTION(openssl_csr_extensions) { X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); if (lua_isnone(L, 2)) { STACK_OF(X509_EXTENSION) *sk = X509_REQ_get_extensions(csr); if (sk) { openssl_sk_x509_extension_totable(L, sk); sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free); } else lua_pushnil(L); return 1; } else { STACK_OF(X509_EXTENSION) *sk = openssl_sk_x509_extension_fromtable(L, 2); int ret = X509_REQ_add_extensions(csr, sk); sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free); return openssl_pushresult(L, ret); } }
static int openssl_random_load(lua_State*L) { const char *file = luaL_optstring(L, 1, NULL); char buffer[MAX_PATH]; if (file == NULL) file = RAND_file_name(buffer, sizeof buffer); else if (RAND_egd(file) > 0) { /* we try if the given filename is an EGD socket. if it is, we don't write anything back to the file. */; lua_pushboolean(L, 1); return 1; } if (file == NULL || !RAND_load_file(file, 2048)) { return openssl_pushresult(L, 0); } lua_pushboolean(L, RAND_status()); return 1; }
static LUA_FUNCTION(openssl_evp_BytesToKey) { EVP_CIPHER* c = CHECK_OBJECT(1, EVP_CIPHER, "openssl.evp_cipher"); size_t lsalt, lk; const char* k = luaL_checklstring(L, 2, &lk); const char* salt = luaL_optlstring(L, 3, NULL, &lsalt); const EVP_MD* m = lua_isnoneornil(L, 4) ? EVP_get_digestbyname("sha1") : get_digest(L, 4); char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; int ret; if (salt != NULL && lsalt < PKCS5_SALT_LEN) { lua_pushfstring(L, "salt must not shorter than %d", PKCS5_SALT_LEN); luaL_argerror(L, 3, lua_tostring(L, -1)); } ret = EVP_BytesToKey(c, m, (unsigned char*)salt, (unsigned char*)k, lk, 1, (unsigned char*)key, (unsigned char*)iv); if (ret > 1) { lua_pushlstring(L, key, EVP_CIPHER_key_length(c)); lua_pushlstring(L, iv, EVP_CIPHER_iv_length(c)); return 2; } return openssl_pushresult(L, ret); }
static int openssl_cms_compress(lua_State *L) { BIO* in = load_bio_object(L, 1); int nid = NID_undef; unsigned int flags = 0; const char* compress_options[] = { "zlib", "rle", NULL }; CMS_ContentInfo *cms; nid = luaL_checkoption(L, 2, "zlib", compress_options); flags = luaL_optint(L, 3, 0); cms = CMS_compress(in, nid, flags); if (cms) { PUSH_OBJECT(cms, "openssl.cms"); return 1; } return openssl_pushresult(L, 0); }
static LUA_FUNCTION(openssl_digest_new) { const EVP_MD* md = get_digest(L, 1); if (md) { int ret; ENGINE* e = (!lua_isnoneornil(L, 2)) ? CHECK_OBJECT(2, ENGINE, "openssl.engine") : NULL; EVP_MD_CTX* ctx = EVP_MD_CTX_create(); 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 LUA_FUNCTION(openssl_bio_handshake) { BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio"); int ret = BIO_do_handshake(bio); return openssl_pushresult(L, ret); }
static int openssl_hmac_reset(lua_State *L) { HMAC_CTX *c = CHECK_OBJECT(1, HMAC_CTX, "openssl.hmac_ctx"); int ret = HMAC_Init_ex(c, NULL, 0, NULL, NULL); return openssl_pushresult(L, ret); }
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 LUA_FUNCTION(openssl_csr_new) { X509_REQ *csr = X509_REQ_new(); int i; int n = lua_gettop(L); int ret = X509_REQ_set_version(csr, 0L); for (i = 1; ret == 1 && i <= n; i++) { luaL_argcheck(L, auxiliar_isclass(L, "openssl.stack_of_x509_extension", i) || auxiliar_isclass(L, "openssl.stack_of_x509_attribute", i) || auxiliar_isclass(L, "openssl.x509_name", i) || auxiliar_isclass(L, "openssl.evp_pkey", i), i, "must be x509_name, stack_of_x509_extension or stack_of_x509_attribute"); if (auxiliar_isclass(L, "openssl.x509_name", i)) { X509_NAME * subject = CHECK_OBJECT(i, X509_NAME, "openssl.x509_name"); ret = X509_REQ_set_subject_name(csr, subject); } if (auxiliar_isclass(L, "openssl.stack_of_x509_attribute", i)) { int j, m; STACK_OF(X509_ATTRIBUTE) *attrs = CHECK_OBJECT(i, STACK_OF(X509_ATTRIBUTE), "openssl.stack_of_x509_attribute"); m = sk_X509_ATTRIBUTE_num(attrs); for (j = 0; ret == 1 && j < m; j++) { ret = X509_REQ_add1_attr(csr, sk_X509_ATTRIBUTE_value(attrs, j)); } } if (auxiliar_isclass(L, "openssl.stack_of_x509_extension", i)) { STACK_OF(X509_EXTENSION) *exts = CHECK_OBJECT(i, STACK_OF(X509_EXTENSION), "openssl.stack_of_x509_extension"); ret = X509_REQ_add_extensions(csr, exts); } if (auxiliar_isclass(L, "openssl.evp_pkey", i)) { EVP_PKEY *pkey; const EVP_MD *md; luaL_argcheck(L, i == n || i == n - 1, i, "must is evp_pkey object"); pkey = CHECK_OBJECT(i, EVP_PKEY, "openssl.evp_pkey"); luaL_argcheck(L, openssl_pkey_is_private(pkey), i, "must be private key"); if (i == n - 1) md = get_digest(L, n); else md = EVP_get_digestbyname("sha1"); ret = X509_REQ_set_pubkey(csr, pkey); if (ret == 1) { ret = X509_REQ_sign(csr, pkey, md); if (ret > 0) ret = 1; } break; } }; if (ret == 1) PUSH_OBJECT(csr, "openssl.x509_req"); else { X509_REQ_free(csr); return openssl_pushresult(L, ret); } return 1; }