static LUA_FUNCTION(openssl_csr_sign) { X509_REQ * csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); luaL_argcheck(L, csr->req_info->pubkey, 1, "has not set public key!!!"); if (auxiliar_isclass(L, "openssl.evp_pkey", 2)) { EVP_PKEY *pkey = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey"); const EVP_MD* md = lua_isnone(L, 3) ? EVP_get_digestbyname("sha1") : get_digest(L, 3); int ret = 1; if (X509_REQ_get_pubkey(csr) == NULL) { BIO* bio = BIO_new(BIO_s_mem()); if ( ret = i2d_PUBKEY_bio(bio, pkey)) { ret = X509_REQ_set_pubkey(csr, d2i_PUBKEY_bio(bio, NULL)); } BIO_free(bio); } if (ret == 1) ret = X509_REQ_sign(csr, pkey, md); return openssl_pushresult(L, ret); } else if (lua_isstring(L, 2)) { size_t siglen; const unsigned char* sigdata = (const unsigned char*)luaL_checklstring(L, 2, &siglen); const EVP_MD* md = get_digest(L, 3); /* (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL) ? V_ASN1_NULL : V_ASN1_UNDEF, */ X509_ALGOR_set0(csr->sig_alg, OBJ_nid2obj(md->pkey_type), V_ASN1_NULL, NULL); if (csr->signature->data != NULL) OPENSSL_free(csr->signature->data); csr->signature->data = OPENSSL_malloc(siglen); memcpy(csr->signature->data, sigdata, siglen); csr->signature->length = siglen; /* * In the interests of compatibility, I'll make sure that the bit string * has a 'not-used bits' value of 0 */ csr->signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); csr->signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; lua_pushboolean(L, 1); return 1; } else { unsigned char* tosign = NULL; const ASN1_ITEM *it = ASN1_ITEM_rptr(X509_REQ_INFO); int inl = ASN1_item_i2d((void*)csr->req_info, &tosign, it); if (inl > 0 && tosign) { lua_pushlstring(L, (const char*)tosign, inl); OPENSSL_free(tosign); return 1; } return openssl_pushresult(L, 0); } }
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_xalgor_md(lua_State* L) { X509_ALGOR* alg = CHECK_OBJECT(1, X509_ALGOR, "openssl.x509_algor"); const EVP_MD* md = get_digest(L, 2); X509_ALGOR_set_md(alg, md); return 0; }
static LUA_FUNCTION(openssl_digest_get) { const EVP_MD* md = get_digest(L, 1); if (md) PUSH_OBJECT((void*)md, "openssl.evp_digest"); else lua_pushnil(L); return 1; }
static LUA_FUNCTION(openssl_csr_sign) { X509_REQ * csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); EVP_PKEY *pkey = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey"); if (openssl_pkey_is_private(pkey)) { const EVP_MD* md = get_digest(L, 3); return openssl_pushresult(L, X509_REQ_sign(csr, pkey, md)); } else if (lua_isnoneornil(L, 3) && X509_REQ_set_pubkey(csr, pkey)) { unsigned char* tosign = NULL; const ASN1_ITEM *it = ASN1_ITEM_rptr(X509_REQ_INFO); int inl = ASN1_item_i2d((void*)csr->req_info, &tosign, it); if (inl > 0 && tosign) { lua_pushlstring(L, (const char*)tosign, inl); OPENSSL_free(tosign); return 1; } return openssl_pushresult(L, 0); } else { size_t siglen; const unsigned char* sigdata = (const unsigned char*)luaL_checklstring(L, 3, &siglen); const EVP_MD* md = get_digest(L, 4); /* (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL) ? V_ASN1_NULL : V_ASN1_UNDEF, */ X509_ALGOR_set0(csr->sig_alg, OBJ_nid2obj(md->pkey_type), V_ASN1_NULL, NULL); if (csr->signature->data != NULL) OPENSSL_free(csr->signature->data); csr->signature->data = OPENSSL_malloc(siglen); memcpy(csr->signature->data, sigdata, siglen); csr->signature->length = siglen; /* * In the interests of compatibility, I'll make sure that the bit string * has a 'not-used bits' value of 0 */ csr->signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); csr->signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; lua_pushboolean(L, 1); return 1; } }
inline digest8_t get_digest_bytes() { digest8_t digest; digest32_t d32 =get_digest(); // big endian to little endiant typedef boost::uint32_t (*endian_ntoh) (boost::uint32_t); std::transform(d32.begin(), d32.end(), d32.begin(), static_cast< endian_ntoh >(hadoken::ntoh)); ::memcpy(&digest[0], &(d32[0]), digest.size()); return digest; }
/* **! method: string digest() **! Get the result of the hashing operation. **! name: digest, hexdigest - Return the resulting hash **! see_also: Mhash.to_hex **! returns: **! The resulting digest. */ void f_hash_digest(INT32 args) { int len, i; struct pike_string *res; len = get_digest(); res = begin_shared_string(len); for(i = 0; i < len; i++) { STR0(res)[i] = THIS->res[i]; } res = end_shared_string(res); pop_n_elems(args); push_string(res); }
static int openssl_hmac_new(lua_State *L) { const EVP_MD *type = get_digest(L, 1); size_t l; const char *k = luaL_checklstring(L, 2, &l); ENGINE* e = lua_isnoneornil(L, 3) ? NULL : CHECK_OBJECT(3, ENGINE, "openssl.engine"); HMAC_CTX *c = HMAC_CTX_new(); HMAC_Init_ex(c, k, (int)l, type, e); PUSH_OBJECT(c, "openssl.hmac_ctx"); return 1; }
/*** create or generate a new x509_req object. Note if not give evp_pkey, will create a new x509_req object,or will generate a signed x509_req object. @function new @tparam[opt] x509_name subject subject name set to x509_req @tparam[opt] stack_of_x509_extension extensions add to x509_req @tparam[opt] stack_of_x509_attribute attributes add to x509_req @tparam[opt] evp_pkey pkey private key sign the x509_req, and set as public key @tparam[opt='sha1WithRSAEncryption'] evp_digest|string md_alg, only used when pkey exist, and should fellow pkey @treturn x509_req certificate sign request object @see x509_req */ 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_getclassudata(L, "openssl.x509_name", i) || auxiliar_getclassudata(L, "openssl.evp_pkey", i), i, "must be x509_name or evp_pkey"); if (auxiliar_getclassudata(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_getclassudata(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"); if (i == n - 1) md = get_digest(L, n, NULL); else md = EVP_get_digestbyname("sha256"); 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; }
static int openssl_xname_digest(lua_State*L) { X509_NAME* xname = CHECK_OBJECT(1, X509_NAME, "openssl.x509_name"); const EVP_MD* md = get_digest(L, 2); unsigned char buf [EVP_MAX_MD_SIZE]; unsigned int len = sizeof(buf); int ret = X509_NAME_digest(xname, md, buf, &len); if (ret == 1) lua_pushlstring(L, (const char *) buf, len); else return openssl_pushresult(L, ret); return 1; };
static LUA_FUNCTION(openssl_crl_digest) { X509_CRL *crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); byte buf[EVP_MAX_MD_SIZE]; unsigned int lbuf = sizeof(buf); const EVP_MD *md = lua_isnoneornil(L, 2) ? EVP_get_digestbyname("sha1") : get_digest(L, 2); int ret = X509_CRL_digest(crl, md, buf, &lbuf); if (ret == 1) { lua_pushlstring(L, (const char*)buf, (size_t)lbuf); return ret; } return openssl_pushresult(L, ret); }
/*** get digest of x509_req @function digest @tparam[opt='SHA1'] evp_md|string md_alg default use sha1 @treturn string digest result */ static LUA_FUNCTION(openssl_csr_digest) { X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); unsigned char buf[EVP_MAX_MD_SIZE]; unsigned int len = sizeof(buf); int ret; const EVP_MD *md = get_digest(L, 2, "sha256"); 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_pkcs7_sign_add_signer) { PKCS7 *p7 = CHECK_OBJECT(1, PKCS7, "openssl.pkcs7"); X509 *signcert = CHECK_OBJECT(2, X509, "openssl.x509"); EVP_PKEY *pkey = CHECK_OBJECT(3, EVP_PKEY, "openssl.evp_pkey"); const EVP_MD* md = get_digest(L, 4); long flags = luaL_optint(L, 5, 0); PKCS7_SIGNER_INFO *signer = 0; luaL_argcheck(L, openssl_pkey_is_private(pkey), 3, "must be private key"); luaL_argcheck(L, X509_check_private_key(signcert, pkey), 3, "sigcert and private key not match"); signer = PKCS7_sign_add_signer(p7, signcert, pkey, md, flags); (void) signer; return openssl_pushresult(L, signcert != NULL ? 1 : 0); }
static LUA_FUNCTION(openssl_signInit) { 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_SignInit_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; }
/*** convert x509_req to x509 object @function to_x509 @treturn x509 object not signed */ static LUA_FUNCTION(openssl_csr_to_x509) { X509_REQ * csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); EVP_PKEY * pkey = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey"); int days = luaL_optint(L, 3, 365); #if OPENSSL_VERSION_NUMBER < 0x10100000L const EVP_MD* md = get_digest(L, 4, "sha256"); X509* cert = X509_REQ_to_X509_ex(csr, days, pkey, md); #else X509* cert = X509_REQ_to_X509(csr, days, pkey); #endif if (cert) { PUSH_OBJECT(cert, "openssl.x509"); return 1; } return openssl_pushresult(L, 0); }
static int openssl_ts_req_msg_imprint(lua_State*L) { TS_REQ* req = CHECK_OBJECT(1, TS_REQ, "openssl.ts_req"); if (lua_isnone(L, 2)) { TS_MSG_IMPRINT * msg = TS_REQ_get_msg_imprint(req); if (msg) { ASN1_OCTET_STRING *s = TS_MSG_IMPRINT_get_msg(msg); X509_ALGOR *a = TS_MSG_IMPRINT_get_algo(msg); PUSH_ASN1_OCTET_STRING(L, s); openssl_push_x509_algor(L, a); ASN1_OCTET_STRING_free(s); X509_ALGOR_free(a); return 2; } return 1; } else { size_t size; const char* data = luaL_checklstring(L, 2, &size); const EVP_MD* md = lua_isnoneornil(L, 3) ? EVP_get_digestbyname("sha1") : get_digest(L, 3); TS_MSG_IMPRINT *msg = TS_MSG_IMPRINT_new(); int ret = TS_MSG_IMPRINT_set_msg(msg, (unsigned char*)data, size); if (ret == 1) { X509_ALGOR* alg = X509_ALGOR_new(); X509_ALGOR_set_md(alg, md); if (ret == 1) { ret = TS_MSG_IMPRINT_set_algo(msg, alg); if (ret == 1) ret = TS_REQ_set_msg_imprint(req, msg); } X509_ALGOR_free(alg); } TS_MSG_IMPRINT_free(msg); return openssl_pushresult(L, ret); } };
static int openssl_hmac(lua_State *L) { if (lua_istable(L, 1)) { if (lua_getmetatable(L, 1) && lua_equal(L, 1, -1)) { lua_pop(L, 1); lua_remove(L, 1); } else luaL_error(L, "call function with invalid state"); } { const EVP_MD *type = get_digest(L, 1); size_t len; const char *dat = luaL_checklstring(L, 2, &len); size_t l; const char *k = luaL_checklstring(L, 3, &l); int raw = (lua_isnoneornil(L, 4)) ? 0 : lua_toboolean(L, 4); ENGINE* e = lua_isnoneornil(L, 5) ? NULL : CHECK_OBJECT(5, ENGINE, "openssl.engine"); unsigned char digest[EVP_MAX_MD_SIZE]; HMAC_CTX *c = HMAC_CTX_new(); HMAC_Init_ex(c, k, (int)l, type, e); HMAC_Update(c, (unsigned char *)dat, len); len = EVP_MAX_MD_SIZE; HMAC_Final(c, digest, (unsigned int*)&len); HMAC_CTX_free(c); if (raw) lua_pushlstring(L, (char *)digest, len); else { char hex[2 * EVP_MAX_MD_SIZE + 1]; to_hex((const char*)digest, len, hex); lua_pushstring(L, hex); } } return 1; }
static LUA_FUNCTION(openssl_crl_diff) { X509_CRL *crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); X509_CRL *newer = CHECK_OBJECT(2, X509_CRL, "openssl.x509_crl"); EVP_PKEY* pkey = CHECK_OBJECT(3, EVP_PKEY, "openssl.evp_pkey"); const EVP_MD *md = lua_isnoneornil(L, 4) ? EVP_get_digestbyname("sha1") : get_digest(L, 4); unsigned int flags = luaL_optinteger(L, 5, 0); X509_CRL *diff; diff = X509_CRL_diff(crl, newer, pkey, md, flags); if (diff) { PUSH_OBJECT(diff, "openssl.x509_crl"); } 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_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_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; }
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 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; }
/*** sign x509_req object @function sign @tparam evp_pkey pkey private key which to sign x509_req object @tparam number|string|evp_md md message digest alg used to sign @treturn boolean result true for suceess */ static LUA_FUNCTION(openssl_csr_sign) { X509_REQ * csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); EVP_PKEY *pubkey = X509_REQ_get_pubkey(csr); if (auxiliar_getclassudata(L, "openssl.evp_pkey", 2)) { EVP_PKEY *pkey = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey"); const EVP_MD* md = get_digest(L, 3, "sha256"); int ret = 1; if (pubkey == NULL) { BIO* bio = BIO_new(BIO_s_mem()); if ((ret = i2d_PUBKEY_bio(bio, pkey)) == 1) { pubkey = d2i_PUBKEY_bio(bio, NULL); if (pubkey) { ret = X509_REQ_set_pubkey(csr, pubkey); EVP_PKEY_free(pubkey); } else { ret = 0; } } BIO_free(bio); } else { EVP_PKEY_free(pubkey); } if (ret == 1) ret = X509_REQ_sign(csr, pkey, md); return openssl_pushresult(L, ret); } else if (lua_isstring(L, 2)) { size_t siglen; unsigned char* sigdata = (unsigned char*)luaL_checklstring(L, 2, &siglen); const EVP_MD* md = get_digest(L, 3, NULL); ASN1_BIT_STRING *sig = NULL; X509_ALGOR *alg = NULL; luaL_argcheck(L, pubkey != NULL, 1, "has not set public key!!!"); X509_REQ_get0_signature(csr, (const ASN1_BIT_STRING **)&sig, (const X509_ALGOR **)&alg); /* (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL) ? V_ASN1_NULL : V_ASN1_UNDEF, */ X509_ALGOR_set0((X509_ALGOR *)alg, OBJ_nid2obj(EVP_MD_pkey_type(md)), V_ASN1_NULL, NULL); ASN1_BIT_STRING_set((ASN1_BIT_STRING *)sig, sigdata, siglen); /* * In the interests of compatibility, I'll make sure that the bit string * has a 'not-used bits' value of 0 */ sig->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); sig->flags |= ASN1_STRING_FLAG_BITS_LEFT; lua_pushboolean(L, 1); return 1; } else { int inl; unsigned char* tosign = NULL; luaL_argcheck(L, pubkey != NULL, 1, "has not set public key!!!"); inl = i2d_re_X509_REQ_tbs(csr, &tosign); if (inl > 0 && tosign) { lua_pushlstring(L, (const char*)tosign, inl); OPENSSL_free(tosign); return 1; } return openssl_pushresult(L, 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 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; }
/** Generate a new certificate for our loaded or generated keys, and write it * to disk. Return 0 on success, nonzero on failure. */ static int generate_certificate(void) { char buf[8192]; time_t now = time(NULL); struct tm tm; char published[ISO_TIME_LEN+1]; char expires[ISO_TIME_LEN+1]; char id_digest[DIGEST_LEN]; char fingerprint[FINGERPRINT_LEN+1]; char *ident = key_to_string(identity_key); char *signing = key_to_string(signing_key); FILE *f; size_t signed_len; char digest[DIGEST_LEN]; char signature[1024]; /* handles up to 8192-bit keys. */ int r; get_fingerprint(identity_key, fingerprint); get_digest(identity_key, id_digest); tor_localtime_r(&now, &tm); tm.tm_mon += months_lifetime; format_iso_time(published, now); format_iso_time(expires, mktime(&tm)); tor_snprintf(buf, sizeof(buf), "dir-key-certificate-version 3" "%s%s" "\nfingerprint %s\n" "dir-key-published %s\n" "dir-key-expires %s\n" "dir-identity-key\n%s" "dir-signing-key\n%s" "dir-key-crosscert\n" "-----BEGIN ID SIGNATURE-----\n", address?"\ndir-address ":"", address?address:"", fingerprint, published, expires, ident, signing ); tor_free(ident); tor_free(signing); /* Append a cross-certification */ r = RSA_private_encrypt(DIGEST_LEN, (unsigned char*)id_digest, (unsigned char*)signature, EVP_PKEY_get1_RSA(signing_key), RSA_PKCS1_PADDING); signed_len = strlen(buf); base64_encode(buf+signed_len, sizeof(buf)-signed_len, signature, r); strlcat(buf, "-----END ID SIGNATURE-----\n" "dir-key-certification\n", sizeof(buf)); signed_len = strlen(buf); SHA1((const unsigned char*)buf,signed_len,(unsigned char*)digest); r = RSA_private_encrypt(DIGEST_LEN, (unsigned char*)digest, (unsigned char*)signature, EVP_PKEY_get1_RSA(identity_key), RSA_PKCS1_PADDING); strlcat(buf, "-----BEGIN SIGNATURE-----\n", sizeof(buf)); signed_len = strlen(buf); base64_encode(buf+signed_len, sizeof(buf)-signed_len, signature, r); strlcat(buf, "-----END SIGNATURE-----\n", sizeof(buf)); if (!(f = fopen(certificate_file, "w"))) { log_err(LD_GENERAL, "Couldn't open %s for writing: %s", certificate_file, strerror(errno)); return 1; } fputs(buf, f); fclose(f); 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; }