diff options
-rw-r--r-- | src/openssl.c | 1077 |
1 files changed, 851 insertions, 226 deletions
diff --git a/src/openssl.c b/src/openssl.c index dba7c75..11d02a0 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -148,6 +148,7 @@ #define BIGNUM_CLASS "BIGNUM*" #define PKEY_CLASS "EVP_PKEY*" +#define EC_GROUP_CLASS "EVP_GROUP*" #define X509_NAME_CLASS "X509_NAME*" #define X509_GENS_CLASS "GENERAL_NAMES*" #define X509_EXT_CLASS "X509_EXTENSION*" @@ -284,65 +285,30 @@ static void *testsimple(lua_State *L, int index, const char *tname) { } /* testsimple() */ -static int interpose(lua_State *L, const char *mt) { - luaL_getmetatable(L, mt); - - if (!strncmp("__", luaL_checkstring(L, 1), 2)) - lua_pushvalue(L, -1); - else - lua_getfield(L, -1, "__index"); - - lua_pushvalue(L, -4); /* push method name */ - lua_gettable(L, -2); /* push old method */ - - lua_pushvalue(L, -5); /* push method name */ - lua_pushvalue(L, -5); /* push new method */ - lua_settable(L, -4); /* replace old method */ +static int auxL_swapmetatable(lua_State *, const char *); +static int auxL_swapmetasubtable(lua_State *, const char *, const char *); - return 1; /* return old method */ -} /* interpose() */ - - -static void addclass(lua_State *L, const char *name, const luaL_Reg *methods, const luaL_Reg *metamethods) { - if (luaL_newmetatable(L, name)) { - luaL_setfuncs(L, metamethods, 0); - lua_newtable(L); - luaL_setfuncs(L, methods, 0); - lua_setfield(L, -2, "__index"); - lua_pop(L, 1); - } -} /* addclass() */ - - -static int badoption(lua_State *L, int index, const char *opt) { - opt = (opt)? opt : luaL_checkstring(L, index); - - return luaL_argerror(L, index, lua_pushfstring(L, "invalid option %s", opt)); -} /* badoption() */ - -static int checkoption(lua_State *L, int index, const char *def, const char *const opts[]) { - const char *opt = (def)? luaL_optstring(L, index, def) : luaL_checkstring(L, index); - int i; - - for (i = 0; opts[i]; i++) { - if (strieq(opts[i], opt)) - return i; +static int interpose(lua_State *L, const char *mt) { + if (!strncmp("__", luaL_checkstring(L, lua_absindex(L, -2)), 2)) { + return auxL_swapmetatable(L, mt); + } else { + return auxL_swapmetasubtable(L, mt, "__index"); } +} /* interpose() */ - return badoption(L, index, opt); -} /* checkoption() */ - +static int auxL_checkoption(lua_State *, int, const char *, const char *const *, _Bool); #define X509_ANY 0x01 #define X509_PEM 0x02 #define X509_DER 0x04 +#define X509_TXT 0x08 /* "pretty" */ #define X509_ALL (X509_PEM|X509_DER) static int optencoding(lua_State *L, int index, const char *def, int allow) { - static const char *const opts[] = { "*", "pem", "der", NULL }; + static const char *const opts[] = { "*", "pem", "der", "pretty", NULL }; int type = 0; - switch (checkoption(L, index, def, opts)) { + switch (auxL_checkoption(L, index, def, opts, 1)) { case 0: type = X509_ANY; break; @@ -352,6 +318,9 @@ static int optencoding(lua_State *L, int index, const char *def, int allow) { case 2: type = X509_DER; break; + case 3: + type = X509_TXT; + break; } if (!(type & allow)) @@ -608,6 +577,21 @@ static _Bool auxS_txt2obj(ASN1_OBJECT **obj, const char *txt) { } } /* auxS_txt2obj() */ +static _Bool auxS_txt2nid(int *nid, const char *txt) { + /* try builtins first */ + if ((*nid = OBJ_sn2nid(txt)) != NID_undef + || (*nid = OBJ_ln2nid(txt)) != NID_undef) { + return 1; + } + + /* OBJ_txt2nid creates a temporary ASN1_OBJECT; call sparingly */ + if (auxS_isoid(txt) && (*nid = OBJ_txt2nid(txt)) != NID_undef) { + return 1; + } + + return 0; +} /* auxS_txt2nid() */ + /* * Auxiliary Lua API routines @@ -638,6 +622,27 @@ NOTUSED static auxtype_t auxL_getref(lua_State *L, auxref_t ref) { return lua_type(L, -1); } /* auxL_getref() */ +static int auxL_testoption(lua_State *L, int index, const char *def, const char *const *optlist, _Bool nocase) { + const char *optname = (def)? luaL_optstring(L, index, def) : luaL_checkstring(L, index); + int (*optcmp)() = (nocase)? &strcasecmp : &strcmp; + + for (int i = 0; optlist[i]; i++) { + if (0 == optcmp(optlist[i], optname)) + return i; + } + + return -1; +} /* auxL_testoption() */ + +static int auxL_checkoption(lua_State *L, int index, const char *def, const char *const *optlist, _Bool nocase) { + int i; + + if ((i = auxL_testoption(L, index, def, optlist, nocase)) >= 0) + return i; + + return luaL_argerror(L, index, lua_pushfstring(L, "invalid option '%s'", luaL_optstring(L, index, def))); +} /* auxL_checkoption() */ + /* * Lua 5.3 distinguishes integers and numbers, and by default uses 64-bit * integers. The following routines try to preserve this distinction and @@ -733,6 +738,13 @@ static auxL_Unsigned (auxL_optunsigned)(lua_State *L, int index, auxL_Unsigned d return (lua_isnoneornil(L, index))? def : auxL_checkunsigned(L, index, min, max); } /* auxL_optunsigned() */ +static int auxL_size2int(lua_State *L, size_t n) { + if (n > INT_MAX) + luaL_error(L, "integer value out of range (%zu > INT_MAX)", n); + + return (int)n; +} /* auxL_size2int() */ + typedef struct { const char *name; auxL_Integer value; @@ -745,6 +757,148 @@ static void auxL_setintegers(lua_State *L, const auxL_IntegerReg *l) { } } /* auxL_setintegers() */ +#define AUXL_REG_NULL (&(auxL_Reg[]){ 0 }) + +typedef struct { + const char *name; + lua_CFunction func; + unsigned nups; /* in addition to nups specified to auxL_setfuncs */ +} auxL_Reg; + +static inline size_t auxL_liblen(const auxL_Reg *l) { + size_t n = 0; + + while ((l++)->name) + n++; + + return n; +} /* auxL_liblen() */ + +#define auxL_newlibtable(L, l) \ + lua_createtable((L), 0, countof((l)) - 1) + +#define auxL_newlib(L, l, nups) \ + (auxL_newlibtable((L), (l)), lua_insert((L), -(nups + 1)), auxL_setfuncs((L), (l), (nups))) + +static void auxL_setfuncs(lua_State *L, const auxL_Reg *l, int nups) { + for (; l->name; l++) { + /* copy shared upvalues */ + luaL_checkstack(L, nups, "too many upvalues"); + for (int i = 0; i < nups; i++) + lua_pushvalue(L, -nups); + + /* nil-fill local upvalues */ + luaL_checkstack(L, l->nups, "too many upvalues"); + lua_settop(L, lua_gettop(L) + l->nups); + + /* set closure */ + luaL_checkstack(L, 1, "too many upvalues"); + lua_pushcclosure(L, l->func, nups + l->nups); + lua_setfield(L, -(nups + 2), l->name); + } + + lua_pop(L, nups); + + return; +} /* auxL_setfuncs() */ + +static void auxL_clear(lua_State *L, int tindex) { + tindex = lua_absindex(L, tindex); + + lua_pushnil(L); + while (lua_next(L, tindex)) { + lua_pop(L, 1); + lua_pushvalue(L, -1); + lua_pushnil(L); + lua_rawset(L, tindex); + } +} /* auxL_clear() */ + +static _Bool auxL_newmetatable(lua_State *L, const char *name, _Bool reset) { + if (luaL_newmetatable(L, name)) + return 1; + if (!reset) + return 0; + + /* + * NB: Keep existing table as it may be cached--e.g. in + * another module that isn't being reloaded. But scrub it + * clean so function interposition--which will presumably + * run again if the C module is being reloaded--doesn't + * result in loops. + */ + auxL_clear(L, -1); + lua_pushnil(L); + lua_setmetatable(L, -2); +#if LUA_VERSION_NUM >= 502 + lua_pushnil(L); + lua_setuservalue(L, -2); +#endif + + return 0; +} /* auxL_newmetatable() */ + +static _Bool auxL_newclass(lua_State *L, const char *name, const auxL_Reg *methods, const auxL_Reg *metamethods, _Bool reset) { + _Bool fresh = auxL_newmetatable(L, name, reset); + int n; + + auxL_setfuncs(L, metamethods, 0); + + if ((n = auxL_liblen(methods))) { + lua_createtable(L, 0, auxL_size2int(L, n)); + auxL_setfuncs(L, methods, 0); + lua_setfield(L, -2, "__index"); + } + + return fresh; +} /* auxL_newclass() */ + +#define auxL_addclass(L, ...) \ + (auxL_newclass((L), __VA_ARGS__), lua_pop((L), 1)) + +static int auxL_swaptable(lua_State *L, int index) { + index = lua_absindex(L, index); + + lua_pushvalue(L, -2); /* push key */ + lua_gettable(L, index); /* push old value */ + + lua_pushvalue(L, -3); /* push key */ + lua_pushvalue(L, -3); /* push new value */ + lua_settable(L, index); /* replace old value */ + + lua_replace(L, -3); + lua_pop(L, 1); + + return 1; /* return old value */ +} /* auxL_swaptable() */ + +static int auxL_swapmetatable(lua_State *L, const char *name) { + luaL_getmetatable(L, name); + + lua_pushvalue(L, -3); + lua_pushvalue(L, -3); + auxL_swaptable(L, -3); + + lua_replace(L, -4); + lua_pop(L, 2); + + return 1; +} /* auxL_swapmetatable() */ + +static int auxL_swapmetasubtable(lua_State *L, const char *name, const char *subname) { + luaL_getmetatable(L, name); + lua_getfield(L, -1, subname); + + lua_pushvalue(L, -4); + lua_pushvalue(L, -4); + auxL_swaptable(L, -3); + + lua_replace(L, -5); + lua_pop(L, 3); + + return 1; +} /* auxL_swapmetasubtable() */ + #define auxL_EDYLD -2 #define auxL_EOPENSSL -1 @@ -1348,7 +1502,7 @@ static int ossl_version(lua_State *L) { return 1; } /* ossl_version() */ -static const luaL_Reg ossl_globals[] = { +static const auxL_Reg ossl_globals[] = { { "version", &ossl_version }, { NULL, NULL }, }; @@ -1520,7 +1674,7 @@ static const auxL_IntegerReg ssleay_version[] = { int luaopen__openssl(lua_State *L) { size_t i; - luaL_newlib(L, ossl_globals); + auxL_newlib(L, ossl_globals, 0); for (i = 0; i < countof(opensslconf_no); i++) { if (*opensslconf_no[i]) { @@ -1577,6 +1731,11 @@ static BIGNUM *bn_dup(lua_State *L, const BIGNUM *src) { } /* bn_dup() */ +static BIGNUM *bn_dup_nil(lua_State *L, const BIGNUM *src) { + return (src)? bn_dup(L, src) : (lua_pushnil(L), (BIGNUM *)0); +} /* bn_dup_nil() */ + + #define checkbig_(a, b, c, ...) checkbig((a), (b), (c)) #define checkbig(...) checkbig_(__VA_ARGS__, &(_Bool){ 0 }, 0) @@ -2010,7 +2169,7 @@ static int bn__gc(lua_State *L) { BIGNUM **ud = luaL_checkudata(L, 1, BIGNUM_CLASS); if (*ud) { - BN_free(*ud); + BN_clear_free(*ud); *ud = NULL; } @@ -2106,7 +2265,7 @@ sslerr: } /* bn_tohex() */ -static const luaL_Reg bn_methods[] = { +static const auxL_Reg bn_methods[] = { { "add", &bn__add }, { "sub", &bn__sub }, { "mul", &bn__mul }, @@ -2125,7 +2284,7 @@ static const luaL_Reg bn_methods[] = { { NULL, NULL }, }; -static const luaL_Reg bn_metatable[] = { +static const auxL_Reg bn_metatable[] = { { "__add", &bn__add }, { "__sub", &bn__sub }, { "__mul", &bn__mul }, @@ -2145,7 +2304,7 @@ static const luaL_Reg bn_metatable[] = { }; -static const luaL_Reg bn_globals[] = { +static const auxL_Reg bn_globals[] = { { "new", &bn_new }, { "interpose", &bn_interpose }, { "fromBinary", &bn_fromBinary }, @@ -2156,7 +2315,7 @@ static const luaL_Reg bn_globals[] = { int luaopen__openssl_bignum(lua_State *L) { initall(L); - luaL_newlib(L, bn_globals); + auxL_newlib(L, bn_globals, 0); return 1; } /* luaopen__openssl_bignum() */ @@ -2257,8 +2416,8 @@ static int pk_new(lua_State *L) { } if (loadfield(L, 1, "curve", LUA_TSTRING, &id)) { - curve = OBJ_sn2nid(id); - luaL_argcheck(L, curve != NID_undef, 1, lua_pushfstring(L, "%s: invalid curve", id)); + if (!auxS_txt2nid(&curve, id)) + luaL_argerror(L, 1, lua_pushfstring(L, "%s: invalid curve", id)); } creat: @@ -2463,7 +2622,19 @@ done: static int pk_interpose(lua_State *L) { - return interpose(L, PKEY_CLASS); + lua_settop(L, 2); + + luaL_getmetatable(L, PKEY_CLASS); + if (!strncmp("__", luaL_checkstring(L, 1), 2)) { + lua_insert(L, 1); + } else { + lua_getfield(L, -1, "__index"); + lua_getupvalue(L, -1, 1); + lua_insert(L, 1); + lua_pop(L, 2); + } + + return auxL_swaptable(L, 1); } /* pk_interpose() */ @@ -2609,7 +2780,7 @@ static int pk_toPEM(lua_State *L) { NULL, }; - switch (checkoption(L, i, NULL, opts)) { + switch (auxL_checkoption(L, i, NULL, opts, 1)) { case 0: case 1: /* public, PublicKey */ if (!PEM_write_bio_PUBKEY(bio, key)) return auxL_error(L, auxL_EOPENSSL, "pkey:__tostring"); @@ -2721,8 +2892,14 @@ enum pk_param { PK_DH_PUB_KEY, PK_DH_PRIV_KEY, -#define PK_EC_OPTLIST { "pub_key", "priv_key", NULL } -#define PK_EC_OPTOFFSET PK_EC_PUB_KEY +/* + * NB: group MUST come before pub_key as setting pub_key requires the group + * to be defined. :setParameters will do the requested assignments in the + * order defined by this array. + */ +#define PK_EC_OPTLIST { "group", "pub_key", "priv_key", NULL } +#define PK_EC_OPTOFFSET PK_EC_GROUP + PK_EC_GROUP, PK_EC_PUB_KEY, PK_EC_PRIV_KEY, }; /* enum pk_param */ @@ -2732,22 +2909,50 @@ static const char *const pk_dsa_optlist[] = PK_DSA_OPTLIST; static const char *const pk_dh_optlist[] = PK_DH_OPTLIST; static const char *const pk_ec_optlist[] = PK_EC_OPTLIST; -static int pk_checkparam(lua_State *L, int type, int index) { +const char *const *pk_getoptlist(int type, int *_nopts, int *_optoffset) { + const char *const *optlist = NULL; + int nopts = 0, optoffset = 0; + switch (type) { case EVP_PKEY_RSA: - return luaL_checkoption(L, index, NULL, pk_rsa_optlist) + PK_RSA_OPTOFFSET; + optlist = pk_rsa_optlist; + nopts = countof(pk_rsa_optlist) - 1; + optoffset = PK_RSA_OPTOFFSET; + + break; case EVP_PKEY_DSA: - return luaL_checkoption(L, index, NULL, pk_dsa_optlist) + PK_DSA_OPTOFFSET; + optlist = pk_dsa_optlist; + nopts = countof(pk_dsa_optlist) - 1; + optoffset = PK_DSA_OPTOFFSET; + + break; case EVP_PKEY_DH: - return luaL_checkoption(L, index, NULL, pk_dh_optlist) + PK_DH_OPTOFFSET; + optlist = pk_dh_optlist; + nopts = countof(pk_dh_optlist) - 1; + optoffset = PK_DH_OPTOFFSET; + + break; case EVP_PKEY_EC: - return luaL_checkoption(L, index, NULL, pk_ec_optlist) + PK_EC_OPTOFFSET; - default: - return luaL_error(L, "%d: unsupported EVP_PKEY base type", type); + optlist = pk_ec_optlist; + nopts = countof(pk_ec_optlist) - 1; + optoffset = PK_EC_OPTOFFSET; + + break; } -} /* pk_checkparam() */ -static void pk_pushparam(lua_State *L, void *_key, enum pk_param which) { + if (_nopts) + *_nopts = nopts; + if (_optoffset) + *_optoffset = optoffset; + + return optlist; +} /* pk_getoptlist() */ + +#ifndef OPENSSL_NO_EC +static EC_GROUP *ecg_dup_nil(lua_State *, const EC_GROUP *); +#endif + +static void pk_pushparam(lua_State *L, void *base_key, enum pk_param which) { union { RSA *rsa; DH *dh; @@ -2755,98 +2960,104 @@ static void pk_pushparam(lua_State *L, void *_key, enum pk_param which) { #ifndef OPENSSL_NO_EC EC_KEY *ec; #endif - } key = { _key }; + } key = { base_key }; switch (which) { case PK_RSA_N: /* RSA public modulus n */ - bn_dup(L, key.rsa->n); + bn_dup_nil(L, key.rsa->n); break; case PK_RSA_E: /* RSA public exponent e */ - bn_dup(L, key.rsa->e); + bn_dup_nil(L, key.rsa->e); break; case PK_RSA_D: /* RSA secret exponent d */ - bn_dup(L, key.rsa->d); + bn_dup_nil(L, key.rsa->d); break; case PK_RSA_P: /* RSA secret prime p */ - bn_dup(L, key.rsa->p); + bn_dup_nil(L, key.rsa->p); break; case PK_RSA_Q: /* RSA secret prime q with p < q */ - bn_dup(L, key.rsa->q); + bn_dup_nil(L, key.rsa->q); break; case PK_RSA_DMP1: /* exponent1 */ - bn_dup(L, key.rsa->dmp1); + bn_dup_nil(L, key.rsa->dmp1); break; case PK_RSA_DMQ1: /* exponent2 */ - bn_dup(L, key.rsa->dmq1); + bn_dup_nil(L, key.rsa->dmq1); break; case PK_RSA_IQMP: /* coefficient */ - bn_dup(L, key.rsa->iqmp); + bn_dup_nil(L, key.rsa->iqmp); break; case PK_DSA_P: - bn_dup(L, key.dsa->p); + bn_dup_nil(L, key.dsa->p); break; case PK_DSA_Q: - bn_dup(L, key.dsa->q); + bn_dup_nil(L, key.dsa->q); break; case PK_DSA_G: - bn_dup(L, key.dsa->g); + bn_dup_nil(L, key.dsa->g); break; case PK_DSA_PUB_KEY: - bn_dup(L, key.dsa->pub_key); + bn_dup_nil(L, key.dsa->pub_key); break; case PK_DSA_PRIV_KEY: - bn_dup(L, key.dsa->priv_key); + bn_dup_nil(L, key.dsa->priv_key); break; case PK_DH_P: - bn_dup(L, key.dh->p); + bn_dup_nil(L, key.dh->p); break; case PK_DH_G: - bn_dup(L, key.dh->g); + bn_dup_nil(L, key.dh->g); break; case PK_DH_PUB_KEY: - bn_dup(L, key.dh->pub_key); + bn_dup_nil(L, key.dh->pub_key); break; case PK_DH_PRIV_KEY: - bn_dup(L, key.dh->priv_key); + bn_dup_nil(L, key.dh->priv_key); break; #ifndef OPENSSL_NO_EC + case PK_EC_GROUP: + ecg_dup_nil(L, EC_KEY_get0_group(key.ec)); + + break; case PK_EC_PUB_KEY: { const EC_GROUP *group; - const EC_POINT *public_key; + const EC_POINT *pub_key; - if (!(group = EC_KEY_get0_group(key.ec)) || !(public_key = EC_KEY_get0_public_key(key.ec))) - goto sslerr; - bn_dup(L, EC_POINT_point2bn(group, public_key, EC_KEY_get_conv_form(key.ec), NULL, getctx(L))); + if ((group = EC_KEY_get0_group(key.ec)) && (pub_key = EC_KEY_get0_public_key(key.ec))) { + bn_dup_nil(L, EC_POINT_point2bn(group, pub_key, EC_KEY_get_conv_form(key.ec), NULL, getctx(L))); + } else { + lua_pushnil(L); + } break; } case PK_EC_PRIV_KEY: - bn_dup(L, EC_KEY_get0_private_key(key.ec)); + bn_dup_nil(L, EC_KEY_get0_private_key(key.ec)); break; #endif @@ -2855,84 +3066,204 @@ static void pk_pushparam(lua_State *L, void *_key, enum pk_param which) { } return; -sslerr: - auxL_error(L, auxL_EOPENSSL, "pkey:getParameters"); - - return; } /* pk_pushparam() */ -static int pk_getParameters(lua_State *L) { - EVP_PKEY *_key = checksimple(L, 1, PKEY_CLASS); - int type = EVP_PKEY_base_id(_key); - void *key; - int otop, index, tindex; +static _Bool pk_bn_set_nothrow(BIGNUM **dst, BIGNUM *src) { + BIGNUM *tmp; - if (!(key = EVP_PKEY_get0(_key))) - goto sslerr; + if (!(tmp = BN_dup(src))) + return 0; - if (lua_isnoneornil(L, 2)) { - const char *const *optlist; - const char *const *opt; + if (*dst) + BN_clear_free(*dst); + *dst = tmp; - switch (type) { - case EVP_PKEY_RSA: - optlist = pk_rsa_optlist; - luaL_checkstack(L, countof(pk_rsa_optlist), ""); + return 1; +} /* pk_bn_set_nothrow() */ - break; - case EVP_PKEY_DSA: - optlist = pk_dsa_optlist; - luaL_checkstack(L, countof(pk_dsa_optlist), ""); +#define pk_bn_set(L, dst, index) do { \ + BIGNUM *n = checkbig((L), (index)); \ + if (!pk_bn_set_nothrow((dst), n)) \ + goto sslerr; \ +} while (0) - break; - case EVP_PKEY_DH: - optlist = pk_dh_optlist; - luaL_checkstack(L, countof(pk_dh_optlist), ""); +static void pk_setparam(lua_State *L, void *base_key, enum pk_param which, int index) { + union { + RSA *rsa; + DH *dh; + DSA *dsa; +#ifndef OPENSSL_NO_EC + EC_KEY *ec; +#endif + } key = { base_key }; - break; - case EVP_PKEY_EC: - optlist = pk_ec_optlist; - luaL_checkstack(L, countof(pk_ec_optlist), ""); + switch (which) { + case PK_RSA_N: + pk_bn_set(L, &key.rsa->n, index); - break; - default: - return luaL_error(L, "%d: unsupported EVP_PKEY base type", EVP_PKEY_base_id(key)); - } + break; + case PK_RSA_E: + pk_bn_set(L, &key.rsa->e, index); + + break; + case PK_RSA_D: + pk_bn_set(L, &key.rsa->d, index); + + break; + case PK_RSA_P: + pk_bn_set(L, &key.rsa->p, index); + + break; + case PK_RSA_Q: + pk_bn_set(L, &key.rsa->q, index); + break; + case PK_RSA_DMP1: + pk_bn_set(L, &key.rsa->dmp1, index); + + break; + case PK_RSA_DMQ1: + pk_bn_set(L, &key.rsa->dmq1, index); + + break; + case PK_RSA_IQMP: + pk_bn_set(L, &key.rsa->iqmp, index); + + break; + case PK_DSA_P: + pk_bn_set(L, &key.dsa->p, index); + + break; + case PK_DSA_Q: + pk_bn_set(L, &key.dsa->q, index); + + break; + case PK_DSA_G: + pk_bn_set(L, &key.dsa->g, index); + + break; + case PK_DSA_PUB_KEY: + pk_bn_set(L, &key.dsa->pub_key, index); + + break; + case PK_DSA_PRIV_KEY: + pk_bn_set(L, &key.dsa->priv_key, index); + + break; + case PK_DH_P: + pk_bn_set(L, &key.dh->p, index); + + break; + case PK_DH_G: + pk_bn_set(L, &key.dh->g, index); + + break; + case PK_DH_PUB_KEY: + pk_bn_set(L, &key.dh->pub_key, index); + + break; + case PK_DH_PRIV_KEY: + pk_bn_set(L, &key.dh->priv_key, index); + + break; +#ifndef OPENSSL_NO_EC + case PK_EC_GROUP: { + const EC_GROUP *group = checksimple(L, index, EC_GROUP_CLASS); + + if (!EC_KEY_set_group(key.ec, group)) + goto sslerr; + + break; + } + case PK_EC_PUB_KEY: { + const BIGNUM *n = checkbig(L, index); + const EC_GROUP *group; + EC_POINT *pub_key; + _Bool okay; + + if (!(group = EC_KEY_get0_group(key.ec))) + luaL_error(L, "unable to set EC pub_key (no group defined)"); + + if (!(pub_key = EC_POINT_bn2point(group, n, NULL, getctx(L)))) + goto sslerr; + + /* NB: copies key, doesn't share or take ownership */ + okay = EC_KEY_set_public_key(key.ec, pub_key); + EC_POINT_free(pub_key); + if (!okay) + goto sslerr; + + break; + } + case PK_EC_PRIV_KEY: { + const BIGNUM *n = checkbig(L, index); + + /* NB: copies key, doesn't share or take ownership */ + if (!EC_KEY_set_private_key(key.ec, n)) + goto sslerr; + + break; + } +#endif + default: + luaL_error(L, "%d: invalid EVP_PKEY parameter", which); + } + + return; +sslerr: + auxL_error(L, auxL_EOPENSSL, "pkey:setParameters"); + + return; +} /* pk_setparam() */ + + +static int pk_getParameters(lua_State *L) { + EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS); + int base_type = EVP_PKEY_base_id(key); + void *base_key; + const char *const *optlist; + int nopts, optoffset, otop, index, tindex; + + if (!(base_key = EVP_PKEY_get0(key))) + goto sslerr; + + if (!(optlist = pk_getoptlist(base_type, &nopts, &optoffset))) + return luaL_error(L, "%d: unsupported EVP_PKEY base type", base_type); + + if (lua_isnoneornil(L, 2)) { /* * Use special "{" parameter to tell loop to push table. * Subsequent parameters will be assigned as fields. - * - * NOTE: optlist arrays are NULL-terminated. luaL_checkstack() - * calls above left room for "{". */ lua_pushstring(L, "{"); - - for (opt = optlist; *opt; opt++) { - lua_pushstring(L, *opt); + luaL_checkstack(L, nopts, "too many arguments"); + for (const char *const *optname = optlist; *optname; optname++) { + lua_pushstring(L, *optname); } } otop = lua_gettop(L); /* provide space for results and working area */ - luaL_checkstack(L, (otop - 1) + LUA_MINSTACK, ""); + luaL_checkstack(L, (otop - 1) + LUA_MINSTACK, "too many arguments"); /* no table index, yet */ tindex = 0; for (index = 2; index <= otop; index++) { - const char *opt = luaL_checkstring(L, index); + const char *optname = luaL_checkstring(L, index); + int optid; - if (*opt == '{') { + if (*optname == '{') { lua_newtable(L); tindex = lua_gettop(L); } else { - pk_pushparam(L, key, pk_checkparam(L, type, index)); + optid = luaL_checkoption(L, index, NULL, optlist) + optoffset; + pk_pushparam(L, base_key, optid); if (tindex) { - lua_setfield(L, tindex, opt); + lua_setfield(L, tindex, optname); } } } @@ -2943,6 +3274,34 @@ sslerr: } /* pk_getParameters() */ +static int pk_setParameters(lua_State *L) { + EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS); + int base_type = EVP_PKEY_base_id(key); + void *base_key; + const char *const *optlist; + int optindex, optoffset; + + luaL_checktype(L, 2, LUA_TTABLE); + + if (!(base_key = EVP_PKEY_get0(key))) + goto sslerr; + + if (!(optlist = pk_getoptlist(base_type, NULL, &optoffset))) + return luaL_error(L, "%d: unsupported EVP_PKEY base type", base_type); + + for (optindex = 0; optlist[optindex]; optindex++) { + if (getfield(L, 2, optlist[optindex])) { + pk_setparam(L, base_key, optindex + optoffset, -1); + lua_pop(L, 1); + } + } + + return 0; +sslerr: + return auxL_error(L, auxL_EOPENSSL, "pkey:setParameters"); +} /* pk_setParameters() */ + + static int pk__tostring(lua_State *L) { EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS); int type = optencoding(L, 2, "pem", X509_PEM|X509_DER); @@ -2969,6 +3328,55 @@ static int pk__tostring(lua_State *L) { } /* pk__tostring() */ +static int pk__index(lua_State *L) { + EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS); + void *base_key; + const char *const *optlist; + int optoffset, listoffset; + + lua_pushvalue(L, lua_upvalueindex(1)); + lua_pushvalue(L, 2); + lua_gettable(L, -2); + + if (!lua_isnil(L, -1)) + return 1; + + if (!lua_isstring(L, 2)) + return 0; + if (!(base_key = EVP_PKEY_get0(key))) + return 0; + if (!(optlist = pk_getoptlist(EVP_PKEY_base_id(key), NULL, &optoffset))) + return 0; + if (-1 == (listoffset = auxL_testoption(L, 2, NULL, optlist, 0))) + return 0; + + pk_pushparam(L, base_key, listoffset + optoffset); + + return 1; +} /* pk__index() */ + + +static int pk__newindex(lua_State *L) { + EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS); + void *base_key; + const char *const *optlist; + int optoffset, listoffset; + + if (!lua_isstring(L, 2)) + return 0; + if (!(base_key = EVP_PKEY_get0(key))) + return 0; + if (!(optlist = pk_getoptlist(EVP_PKEY_base_id(key), NULL, &optoffset))) + return 0; + if (-1 == (listoffset = auxL_testoption(L, 2, NULL, optlist, 0))) + return 0; + + pk_setparam(L, base_key, listoffset + optoffset, 3); + + return 0; +} /* pk__newindex() */ + + static int pk__gc(lua_State *L) { EVP_PKEY **ud = luaL_checkudata(L, 1, PKEY_CLASS); @@ -2981,7 +3389,7 @@ static int pk__gc(lua_State *L) { } /* pk__gc() */ -static const luaL_Reg pk_methods[] = { +static const auxL_Reg pk_methods[] = { { "type", &pk_type }, { "setPublicKey", &pk_setPublicKey }, { "setPrivateKey", &pk_setPrivateKey }, @@ -2989,26 +3397,42 @@ static const luaL_Reg pk_methods[] = { { "verify", &pk_verify }, { "toPEM", &pk_toPEM }, { "getParameters", &pk_getParameters }, + { "setParameters", &pk_setParameters }, { NULL, NULL }, }; -static const luaL_Reg pk_metatable[] = { +static const auxL_Reg pk_metatable[] = { { "__tostring", &pk__tostring }, + { "__index", &pk__index, 1 }, + { "__newindex", &pk__newindex, 1 }, { "__gc", &pk__gc }, { NULL, NULL }, }; -static const luaL_Reg pk_globals[] = { +static const auxL_Reg pk_globals[] = { { "new", &pk_new }, { "interpose", &pk_interpose }, { NULL, NULL }, }; +static void pk_luainit(lua_State *L, _Bool reset) { + if (!auxL_newmetatable(L, PKEY_CLASS, reset)) + return; + auxL_setfuncs(L, pk_metatable, 0); + auxL_newlib(L, pk_methods, 0); + for (char **k = (char *[]){ "__index", "__newindex", 0 }; *k; k++) { + lua_getfield(L, -2, *k); /* closure */ + lua_pushvalue(L, -2); /* method table */ + lua_setupvalue(L, -2, 1); + } + lua_pop(L, 2); +} /* pk_luainit() */ + int luaopen__openssl_pkey(lua_State *L) { initall(L); - luaL_newlib(L, pk_globals); + auxL_newlib(L, pk_globals, 0); return 1; } /* luaopen__openssl_pkey() */ @@ -3023,6 +3447,205 @@ int luaopen__openssl_pubkey(lua_State *L) { /* + * EC_GROUP - openssl.ec.group + * + * NOTE: Ensure copy-by-value semantics when passing EC_GROUP objects as it + * doesn't support reference counting. The only persistent reference should + * be the Lua userdata value. + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef OPENSSL_NO_EC + +static EC_GROUP *ecg_dup(lua_State *L, const EC_GROUP *src) { + EC_GROUP **ud = prepsimple(L, EC_GROUP_CLASS); + + if (!(*ud = EC_GROUP_dup(src))) + auxL_error(L, auxL_EOPENSSL, "group"); + + return *ud; +} /* ecg_dup() */ + +static EC_GROUP *ecg_dup_nil(lua_State *L, const EC_GROUP *src) { + return (src)? ecg_dup(L, src) : (lua_pushnil(L), (EC_GROUP *)0); +} /* ecg_dup_nil() */ + +static EC_GROUP *ecg_new_by_nid(int nid) { + EC_GROUP *group; + + if (!(group = EC_GROUP_new_by_curve_name(nid))) + return NULL; + + /* flag as named for benefit of __tostring */ + EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); + + /* compressed points may be patented */ + EC_GROUP_set_point_conversion_form(group, POINT_CONVERSION_UNCOMPRESSED); + + return group; +} /* ecg_new_by_nid() */ + +static EC_GROUP *ecg_push_by_nid(lua_State *L, int nid) { + EC_GROUP **group = prepsimple(L, EC_GROUP_CLASS); + + if (!(*group = EC_GROUP_new_by_curve_name(nid))) + goto oops; + + EC_GROUP_set_asn1_flag(*group, OPENSSL_EC_NAMED_CURVE); + + /* compressed points may be patented */ + EC_GROUP_set_point_conversion_form(*group, POINT_CONVERSION_UNCOMPRESSED); + + return *group; +oops: + lua_pop(L, 1); + + return NULL; +} /* ecg_push_by_nid() */ + +static int ecg_new(lua_State *L) { + switch (lua_type(L, 1)) { + case LUA_TSTRING: { + const char *data; + size_t datalen; + int nid, type, goterr; + BIO *bio; + EC_GROUP **group; + + data = luaL_checklstring(L, 1, &datalen); + + if (auxS_txt2nid(&nid, data)) { + if (!ecg_push_by_nid(L, nid)) + goto sslerr; + } else { + type = optencoding(L, 2, "*", X509_ANY|X509_PEM|X509_DER); + group = prepsimple(L, EC_GROUP_CLASS); + + luaL_argcheck(L, datalen < INT_MAX, 1, "string too long"); + if (!(bio = BIO_new_mem_buf((void *)data, datalen))) + return auxL_error(L, auxL_EOPENSSL, "group.new"); + + goterr = 0; + + if (type == X509_PEM || type == X509_ANY) { + goterr |= !(*group = PEM_read_bio_ECPKParameters(bio, NULL, 0, "")); + } + + if (!*group && (type == X509_DER || type == X509_ANY)) { + BIO_reset(bio); + goterr |= !(*group = d2i_ECPKParameters_bio(bio, NULL)); + } + + BIO_free(bio); + + if (!*group) + return auxL_error(L, auxL_EOPENSSL, "group.new"); + if (goterr) + ERR_clear_error(); + } + + return 1; + } + case LUA_TNUMBER: { + int nid = luaL_checkint(L, 2); + + if (!ecg_push_by_nid(L, nid)) + goto sslerr; + + return 1; + } + default: + return luaL_error(L, "%s: unknown group initializer", lua_typename(L, lua_type(L, 1))); + } /* switch() */ + + return 0; +sslerr: + return auxL_error(L, auxL_EOPENSSL, "group.new"); +} /* ecg_new() */ + +static int ecg_interpose(lua_State *L) { + return interpose(L, EC_GROUP_CLASS); +} /* ecg_interpose() */ + +static int ecg_tostring(lua_State *L) { + EC_GROUP *group = checksimple(L, 1, EC_GROUP_CLASS); + int how = optencoding(L, 2, "pem", X509_PEM|X509_DER|X509_TXT); + BIO *bio = getbio(L); + char *bytes; + int len, indent; + + switch (how) { + case X509_PEM: + if (!PEM_write_bio_ECPKParameters(bio, group)) + goto sslerr; + break; + case X509_DER: + if (!i2d_ECPKParameters_bio(bio, group)) + goto sslerr; + break; + case X509_TXT: + indent = auxL_optinteger(L, 3, 0, 0, INT_MAX); + if (!ECPKParameters_print(bio, group, indent)) + goto sslerr; + break; + } + + len = BIO_get_mem_data(bio, &bytes); + lua_pushlstring(L, bytes, len); + + return 1; +sslerr: + return auxL_error(L, auxL_EOPENSSL, "group:__tostring"); +} /* ecg_tostring() */ + +static int ecg__tostring(lua_State *L) { + return ecg_tostring(L); +} /* ecg__tostring() */ + +static int ecg__gc(lua_State *L) { + EC_GROUP **ud = luaL_checkudata(L, 1, EC_GROUP_CLASS); + + if (*ud) { + EC_GROUP_clear_free(*ud); + *ud = NULL; + } + + return 0; +} /* ecg__gc() */ + +static const auxL_Reg ecg_methods[] = { + { "tostring", &ecg_tostring }, + { NULL, NULL }, +}; + +static const auxL_Reg ecg_metatable[] = { + { "__tostring", &ecg__tostring }, + { "__gc", &ecg__gc }, + { NULL, NULL }, +}; + +static const auxL_Reg ecg_globals[] = { + { "new", &ecg_new }, + { "interpose", &ecg_interpose }, + { NULL, NULL }, +}; + +#endif /* OPENSSL_NO_EC */ + +int luaopen__openssl_ec_group(lua_State *L) { +#ifndef OPENSSL_NO_EC + initall(L); + + auxL_newlib(L, ecg_globals, 0); + + return 1; +#else + return 0; +#endif +} /* luaopen__openssl_ec_group() */ + + +/* * X509_NAME - openssl.x509.name * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ @@ -3196,13 +3819,13 @@ static int xn__tostring(lua_State *L) { } /* xn__tostring() */ -static const luaL_Reg xn_methods[] = { +static const auxL_Reg xn_methods[] = { { "add", &xn_add }, { "all", &xn_all }, { NULL, NULL }, }; -static const luaL_Reg xn_metatable[] = { +static const auxL_Reg xn_metatable[] = { { "__pairs", &xn__pairs }, { "__gc", &xn__gc }, { "__tostring", &xn__tostring }, @@ -3210,7 +3833,7 @@ static const luaL_Reg xn_metatable[] = { }; -static const luaL_Reg xn_globals[] = { +static const auxL_Reg xn_globals[] = { { "new", &xn_new }, { "interpose", &xn_interpose }, { NULL, NULL }, @@ -3219,7 +3842,7 @@ static const luaL_Reg xn_globals[] = { int luaopen__openssl_x509_name(lua_State *L) { initall(L); - luaL_newlib(L, xn_globals); + auxL_newlib(L, xn_globals, 0); return 1; } /* luaopen__openssl_x509_name() */ @@ -3452,19 +4075,19 @@ static int gn__gc(lua_State *L) { } /* gn__gc() */ -static const luaL_Reg gn_methods[] = { +static const auxL_Reg gn_methods[] = { { "add", &gn_add }, { NULL, NULL }, }; -static const luaL_Reg gn_metatable[] = { +static const auxL_Reg gn_metatable[] = { { "__pairs", &gn__pairs }, { "__gc", &gn__gc }, { NULL, NULL }, }; -static const luaL_Reg gn_globals[] = { +static const auxL_Reg gn_globals[] = { { "new", &gn_new }, { "interpose", &gn_interpose }, { NULL, NULL }, @@ -3473,7 +4096,7 @@ static const luaL_Reg gn_globals[] = { int luaopen__openssl_x509_altname(lua_State *L) { initall(L); - luaL_newlib(L, gn_globals); + auxL_newlib(L, gn_globals, 0); return 1; } /* luaopen__openssl_x509_altname() */ @@ -3676,7 +4299,7 @@ static int xe__gc(lua_State *L) { } /* xe__gc() */ -static const luaL_Reg xe_methods[] = { +static const auxL_Reg xe_methods[] = { { "getID", &xe_getID }, { "getName", &xe_getName }, { "getShortName", &xe_getShortName }, @@ -3687,13 +4310,13 @@ static const luaL_Reg xe_methods[] = { { NULL, NULL }, }; -static const luaL_Reg xe_metatable[] = { +static const auxL_Reg xe_metatable[] = { { "__gc", &xe__gc }, { NULL, NULL }, }; -static const luaL_Reg xe_globals[] = { +static const auxL_Reg xe_globals[] = { { "new", &xe_new }, { "interpose", &xe_interpose }, { NULL, NULL }, @@ -3710,7 +4333,7 @@ static const auxL_IntegerReg xe_textopts[] = { int luaopen__openssl_x509_extension(lua_State *L) { initall(L); - luaL_newlib(L, xe_globals); + auxL_newlib(L, xe_globals, 0); auxL_setintegers(L, xe_textopts); return 1; @@ -4282,7 +4905,7 @@ static int xc_getBasicConstraint(lua_State *L) { int n = 0, i, top; for (i = 2, top = lua_gettop(L); i <= top; i++) { - switch (checkoption(L, i, 0, (const char *[]){ "CA", "pathLen", "pathLenConstraint", NULL })) { + switch (auxL_checkoption(L, i, 0, (const char *[]){ "CA", "pathLen", "pathLenConstraint", NULL }, 1)) { case 0: lua_pushboolean(L, CA); n++; @@ -4338,7 +4961,7 @@ static int xc_setBasicConstraint(lua_State *L) { } else { lua_settop(L, 3); - switch (checkoption(L, 2, 0, (const char *[]){ "CA", "pathLen", "pathLenConstraint", NULL })) { + switch (auxL_checkoption(L, 2, 0, (const char *[]){ "CA", "pathLen", "pathLenConstraint", NULL }, 1)) { case 0: luaL_checktype(L, 3, LUA_TBOOLEAN); CA = lua_toboolean(L, 3); @@ -4679,7 +5302,7 @@ static int xc__gc(lua_State *L) { } /* xc__gc() */ -static const luaL_Reg xc_methods[] = { +static const auxL_Reg xc_methods[] = { { "getVersion", &xc_getVersion }, { "setVersion", &xc_setVersion }, { "getSerial", &xc_getSerial }, @@ -4718,14 +5341,14 @@ static const luaL_Reg xc_methods[] = { { NULL, NULL }, }; -static const luaL_Reg xc_metatable[] = { +static const auxL_Reg xc_metatable[] = { { "__tostring", &xc__tostring }, { "__gc", &xc__gc }, { NULL, NULL }, }; -static const luaL_Reg xc_globals[] = { +static const auxL_Reg xc_globals[] = { { "new", &xc_new }, { "interpose", &xc_interpose }, { NULL, NULL }, @@ -4734,7 +5357,7 @@ static const luaL_Reg xc_globals[] = { int luaopen__openssl_x509_cert(lua_State *L) { initall(L); - luaL_newlib(L, xc_globals); + auxL_newlib(L, xc_globals, 0); return 1; } /* luaopen__openssl_x509_cert() */ @@ -4914,7 +5537,7 @@ static int xr__gc(lua_State *L) { return 0; } /* xr__gc() */ -static const luaL_Reg xr_methods[] = { +static const auxL_Reg xr_methods[] = { { "getVersion", &xr_getVersion }, { "setVersion", &xr_setVersion }, { "getSubject", &xr_getSubject }, @@ -4926,14 +5549,14 @@ static const luaL_Reg xr_methods[] = { { NULL, NULL }, }; -static const luaL_Reg xr_metatable[] = { +static const auxL_Reg xr_metatable[] = { { "__tostring", &xr__tostring }, { "__gc", &xr__gc }, { NULL, NULL }, }; -static const luaL_Reg xr_globals[] = { +static const auxL_Reg xr_globals[] = { { "new", &xr_new }, { "interpose", &xr_interpose }, { NULL, NULL }, @@ -4942,7 +5565,7 @@ static const luaL_Reg xr_globals[] = { int luaopen__openssl_x509_csr(lua_State *L) { initall(L); - luaL_newlib(L, xr_globals); + auxL_newlib(L, xr_globals, 0); return 1; } /* luaopen__openssl_x509_csr() */ @@ -5305,7 +5928,7 @@ static int xx__gc(lua_State *L) { return 0; } /* xx__gc() */ -static const luaL_Reg xx_methods[] = { +static const auxL_Reg xx_methods[] = { { "getVersion", &xx_getVersion }, { "setVersion", &xx_setVersion }, { "getLastUpdate", &xx_getLastUpdate }, @@ -5324,14 +5947,14 @@ static const luaL_Reg xx_methods[] = { { NULL, NULL }, }; -static const luaL_Reg xx_metatable[] = { +static const auxL_Reg xx_metatable[] = { { "__tostring", &xx__tostring }, { "__gc", &xx__gc }, { NULL, NULL }, }; -static const luaL_Reg xx_globals[] = { +static const auxL_Reg xx_globals[] = { { "new", &xx_new }, { "interpose", &xx_interpose }, { NULL, NULL }, @@ -5340,7 +5963,7 @@ static const luaL_Reg xx_globals[] = { int luaopen__openssl_x509_crl(lua_State *L) { initall(L); - luaL_newlib(L, xx_globals); + auxL_newlib(L, xx_globals, 0); return 1; } /* luaopen__openssl_x509_crl() */ @@ -5477,19 +6100,19 @@ static int xl__gc(lua_State *L) { } /* xl__gc() */ -static const luaL_Reg xl_methods[] = { +static const auxL_Reg xl_methods[] = { { "add", &xl_add }, { NULL, NULL }, }; -static const luaL_Reg xl_metatable[] = { +static const auxL_Reg xl_metatable[] = { { "__pairs", &xl__pairs }, { "__ipairs", &xl__pairs }, { "__gc", &xl__gc }, { NULL, NULL }, }; -static const luaL_Reg xl_globals[] = { +static const auxL_Reg xl_globals[] = { { "new", &xl_new }, { "interpose", &xl_interpose }, { NULL, NULL }, @@ -5498,7 +6121,7 @@ static const luaL_Reg xl_globals[] = { int luaopen__openssl_x509_chain(lua_State *L) { initall(L); - luaL_newlib(L, xl_globals); + auxL_newlib(L, xl_globals, 0); return 1; } /* luaopen__openssl_x509_chain() */ @@ -5642,18 +6265,18 @@ static int xs__gc(lua_State *L) { } /* xs__gc() */ -static const luaL_Reg xs_methods[] = { +static const auxL_Reg xs_methods[] = { { "add", &xs_add }, { "verify", &xs_verify }, { NULL, NULL }, }; -static const luaL_Reg xs_metatable[] = { +static const auxL_Reg xs_metatable[] = { { "__gc", &xs__gc }, { NULL, NULL }, }; -static const luaL_Reg xs_globals[] = { +static const auxL_Reg xs_globals[] = { { "new", &xs_new }, { "interpose", &xs_interpose }, { NULL, NULL }, @@ -5662,7 +6285,7 @@ static const luaL_Reg xs_globals[] = { int luaopen__openssl_x509_store(lua_State *L) { initall(L); - luaL_newlib(L, xs_globals); + auxL_newlib(L, xs_globals, 0); return 1; } /* luaopen__openssl_x509_store() */ @@ -5713,17 +6336,17 @@ static int stx__gc(lua_State *L) { } /* stx__gc() */ -static const luaL_Reg stx_methods[] = { +static const auxL_Reg stx_methods[] = { { "add", &stx_add }, { NULL, NULL }, }; -static const luaL_Reg stx_metatable[] = { +static const auxL_Reg stx_metatable[] = { { "__gc", &stx__gc }, { NULL, NULL }, }; -static const luaL_Reg stx_globals[] = { +static const auxL_Reg stx_globals[] = { { "new", &stx_new }, { "interpose", &stx_interpose }, { NULL, NULL }, @@ -5732,7 +6355,7 @@ static const luaL_Reg stx_globals[] = { int luaopen__openssl_x509_store_context(lua_State *L) { initall(L); - luaL_newlib(L, stx_globals); + auxL_newlib(L, stx_globals, 0); return 1; } /* luaopen__openssl_x509_store_context() */ @@ -5833,18 +6456,18 @@ static int p12__gc(lua_State *L) { } /* p12__gc() */ -static const luaL_Reg p12_methods[] = { +static const auxL_Reg p12_methods[] = { { "tostring", &p12__tostring }, { NULL, NULL }, }; -static const luaL_Reg p12_metatable[] = { +static const auxL_Reg p12_metatable[] = { { "__tostring", &p12__tostring }, { "__gc", &p12__gc }, { NULL, NULL }, }; -static const luaL_Reg p12_globals[] = { +static const auxL_Reg p12_globals[] = { { "new", &p12_new }, { "interpose", &p12_interpose }, { NULL, NULL }, @@ -5853,7 +6476,7 @@ static const luaL_Reg p12_globals[] = { int luaopen__openssl_pkcs12(lua_State *L) { initall(L); - luaL_newlib(L, p12_globals); + auxL_newlib(L, p12_globals, 0); return 1; } /* luaopen__openssl_pkcs12() */ @@ -5893,7 +6516,7 @@ static int sx_new(lua_State *L) { lua_settop(L, 2); srv = lua_toboolean(L, 2); - switch (checkoption(L, 1, "TLS", opts)) { + switch (auxL_checkoption(L, 1, "TLS", opts, 1)) { case 0: /* SSL */ method = (srv)? &SSLv23_server_method : &SSLv23_client_method; options = SSL_OP_NO_SSLv2; @@ -5949,7 +6572,7 @@ static int sx_new(lua_State *L) { break; #endif default: - return badoption(L, 1, NULL); + return luaL_argerror(L, 1, "invalid option"); } ud = prepsimple(L, SSL_CTX_CLASS); @@ -6270,7 +6893,7 @@ static int sx__gc(lua_State *L) { } /* sx__gc() */ -static const luaL_Reg sx_methods[] = { +static const auxL_Reg sx_methods[] = { { "setOptions", &sx_setOptions }, { "getOptions", &sx_getOptions }, { "clearOptions", &sx_clearOptions }, @@ -6290,12 +6913,12 @@ static const luaL_Reg sx_methods[] = { { NULL, NULL }, }; -static const luaL_Reg sx_metatable[] = { +static const auxL_Reg sx_metatable[] = { { "__gc", &sx__gc }, { NULL, NULL }, }; -static const luaL_Reg sx_globals[] = { +static const auxL_Reg sx_globals[] = { { "new", &sx_new }, { "interpose", &sx_interpose }, { NULL, NULL }, @@ -6358,7 +6981,7 @@ static const auxL_IntegerReg sx_option[] = { int luaopen__openssl_ssl_context(lua_State *L) { initall(L); - luaL_newlib(L, sx_globals); + auxL_newlib(L, sx_globals, 0); auxL_setintegers(L, sx_verify); auxL_setintegers(L, sx_option); @@ -6604,7 +7227,7 @@ static int ssl__gc(lua_State *L) { } /* ssl__gc() */ -static const luaL_Reg ssl_methods[] = { +static const auxL_Reg ssl_methods[] = { { "setOptions", &ssl_setOptions }, { "getOptions", &ssl_getOptions }, { "clearOptions", &ssl_clearOptions }, @@ -6624,12 +7247,12 @@ static const luaL_Reg ssl_methods[] = { { NULL, NULL }, }; -static const luaL_Reg ssl_metatable[] = { +static const auxL_Reg ssl_metatable[] = { { "__gc", &ssl__gc }, { NULL, NULL }, }; -static const luaL_Reg ssl_globals[] = { +static const auxL_Reg ssl_globals[] = { { "new", &ssl_new }, { "interpose", &ssl_interpose }, { NULL, NULL }, @@ -6652,7 +7275,7 @@ static const auxL_IntegerReg ssl_version[] = { int luaopen__openssl_ssl(lua_State *L) { initall(L); - luaL_newlib(L, ssl_globals); + auxL_newlib(L, ssl_globals, 0); auxL_setintegers(L, ssl_version); auxL_setintegers(L, sx_verify); auxL_setintegers(L, sx_option); @@ -6748,18 +7371,18 @@ static int md__gc(lua_State *L) { } /* md__gc() */ -static const luaL_Reg md_methods[] = { +static const auxL_Reg md_methods[] = { { "update", &md_update }, { "final", &md_final }, { NULL, NULL }, }; -static const luaL_Reg md_metatable[] = { +static const auxL_Reg md_metatable[] = { { "__gc", &md__gc }, { NULL, NULL }, }; -static const luaL_Reg md_globals[] = { +static const auxL_Reg md_globals[] = { { "new", &md_new }, { "interpose", &md_interpose }, { NULL, NULL }, @@ -6768,7 +7391,7 @@ static const luaL_Reg md_globals[] = { int luaopen__openssl_digest(lua_State *L) { initall(L); - luaL_newlib(L, md_globals); + auxL_newlib(L, md_globals, 0); return 1; } /* luaopen__openssl_digest() */ @@ -6850,18 +7473,18 @@ static int hmac__gc(lua_State *L) { } /* hmac__gc() */ -static const luaL_Reg hmac_methods[] = { +static const auxL_Reg hmac_methods[] = { { "update", &hmac_update }, { "final", &hmac_final }, { NULL, NULL }, }; -static const luaL_Reg hmac_metatable[] = { +static const auxL_Reg hmac_metatable[] = { { "__gc", &hmac__gc }, { NULL, NULL }, }; -static const luaL_Reg hmac_globals[] = { +static const auxL_Reg hmac_globals[] = { { "new", &hmac_new }, { "interpose", &hmac_interpose }, { NULL, NULL }, @@ -6870,7 +7493,7 @@ static const luaL_Reg hmac_globals[] = { int luaopen__openssl_hmac(lua_State *L) { initall(L); - luaL_newlib(L, hmac_globals); + auxL_newlib(L, hmac_globals, 0); return 1; } /* luaopen__openssl_hmac() */ @@ -7051,7 +7674,7 @@ static int cipher__gc(lua_State *L) { } /* cipher__gc() */ -static const luaL_Reg cipher_methods[] = { +static const auxL_Reg cipher_methods[] = { { "encrypt", &cipher_encrypt }, { "decrypt", &cipher_decrypt }, { "update", &cipher_update }, @@ -7059,12 +7682,12 @@ static const luaL_Reg cipher_methods[] = { { NULL, NULL }, }; -static const luaL_Reg cipher_metatable[] = { +static const auxL_Reg cipher_metatable[] = { { "__gc", &cipher__gc }, { NULL, NULL }, }; -static const luaL_Reg cipher_globals[] = { +static const auxL_Reg cipher_globals[] = { { "new", &cipher_new }, { "interpose", &cipher_interpose }, { NULL, NULL }, @@ -7073,7 +7696,7 @@ static const luaL_Reg cipher_globals[] = { int luaopen__openssl_cipher(lua_State *L) { initall(L); - luaL_newlib(L, cipher_globals); + auxL_newlib(L, cipher_globals, 0); return 1; } /* luaopen__openssl_cipher() */ @@ -7402,7 +8025,7 @@ static int rand_uniform(lua_State *L) { } /* rand_uniform() */ -static const luaL_Reg rand_globals[] = { +static const auxL_Reg rand_globals[] = { { "stir", &rand_stir }, { "add", &rand_add }, { "bytes", &rand_bytes }, @@ -7416,10 +8039,9 @@ int luaopen__openssl_rand(lua_State *L) { initall(L); - luaL_newlibtable(L, rand_globals); st = lua_newuserdata(L, sizeof *st); memset(st, 0, sizeof *st); - luaL_setfuncs(L, rand_globals, 1); + auxL_newlib(L, rand_globals, 1); return 1; } /* luaopen__openssl_rand() */ @@ -7454,7 +8076,7 @@ static int de5_set_odd_parity(lua_State *L) { return 1; } /* de5_set_odd_parity() */ -static const luaL_Reg des_globals[] = { +static const auxL_Reg des_globals[] = { { "string_to_key", &de5_string_to_key }, { "set_odd_parity", &de5_set_odd_parity }, { NULL, NULL }, @@ -7463,7 +8085,7 @@ static const luaL_Reg des_globals[] = { int luaopen__openssl_des(lua_State *L) { initall(L); - luaL_newlib(L, des_globals); + auxL_newlib(L, des_globals, 0); return 1; } /* luaopen__openssl_des() */ @@ -7608,21 +8230,24 @@ static void initall(lua_State *L) { ex_newstate(L); - addclass(L, BIGNUM_CLASS, bn_methods, bn_metatable); - addclass(L, PKEY_CLASS, pk_methods, pk_metatable); - addclass(L, X509_NAME_CLASS, xn_methods, xn_metatable); - addclass(L, X509_GENS_CLASS, gn_methods, gn_metatable); - addclass(L, X509_EXT_CLASS, xe_methods, xe_metatable); - addclass(L, X509_CERT_CLASS, xc_methods, xc_metatable); - addclass(L, X509_CSR_CLASS, xr_methods, xr_metatable); - addclass(L, X509_CRL_CLASS, xx_methods, xx_metatable); - addclass(L, X509_CHAIN_CLASS, xl_methods, xl_metatable); - addclass(L, X509_STORE_CLASS, xs_methods, xs_metatable); - addclass(L, PKCS12_CLASS, p12_methods, p12_metatable); - addclass(L, SSL_CTX_CLASS, sx_methods, sx_metatable); - addclass(L, SSL_CLASS, ssl_methods, ssl_metatable); - addclass(L, DIGEST_CLASS, md_methods, md_metatable); - addclass(L, HMAC_CLASS, hmac_methods, hmac_metatable); - addclass(L, CIPHER_CLASS, cipher_methods, cipher_metatable); + auxL_addclass(L, BIGNUM_CLASS, bn_methods, bn_metatable, 0); + pk_luainit(L, 0); +#ifndef OPENSSL_NO_EC + auxL_addclass(L, EC_GROUP_CLASS, ecg_methods, ecg_metatable, 0); +#endif + auxL_addclass(L, X509_NAME_CLASS, xn_methods, xn_metatable, 0); + auxL_addclass(L, X509_GENS_CLASS, gn_methods, gn_metatable, 0); + auxL_addclass(L, X509_EXT_CLASS, xe_methods, xe_metatable, 0); + auxL_addclass(L, X509_CERT_CLASS, xc_methods, xc_metatable, 0); + auxL_addclass(L, X509_CSR_CLASS, xr_methods, xr_metatable, 0); + auxL_addclass(L, X509_CRL_CLASS, xx_methods, xx_metatable, 0); + auxL_addclass(L, X509_CHAIN_CLASS, xl_methods, xl_metatable, 0); + auxL_addclass(L, X509_STORE_CLASS, xs_methods, xs_metatable, 0); + auxL_addclass(L, PKCS12_CLASS, p12_methods, p12_metatable, 0); + auxL_addclass(L, SSL_CTX_CLASS, sx_methods, sx_metatable, 0); + auxL_addclass(L, SSL_CLASS, ssl_methods, ssl_metatable, 0); + auxL_addclass(L, DIGEST_CLASS, md_methods, md_metatable, 0); + auxL_addclass(L, HMAC_CLASS, hmac_methods, hmac_metatable, 0); + auxL_addclass(L, CIPHER_CLASS, cipher_methods, cipher_metatable, 0); } /* initall() */ |