diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/openssl.c | 309 | ||||
-rw-r--r-- | src/openssl.ssl.lua | 6 |
2 files changed, 289 insertions, 26 deletions
diff --git a/src/openssl.c b/src/openssl.c index 5bec55a..f93b1cf 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -298,7 +298,7 @@ #endif #ifndef HAVE_SSL_CTX_SET1_CERT_STORE -#define HAVE_SSL_CTX_SET1_CERT_STORE (HAVE_SSL_CTX_set1_cert_store || 0) /* backwards compatible with old macro name */ +#define HAVE_SSL_CTX_SET1_CERT_STORE (HAVE_SSL_CTX_set1_cert_store || OPENSSL_PREREQ(1,1,1)) /* backwards compatible with old macro name */ #endif #ifndef HAVE_SSL_CTX_SET1_PARAM @@ -329,6 +329,14 @@ #define HAVE_SSL_SET_ALPN_PROTOS HAVE_SSL_CTX_SET_ALPN_PROTOS #endif +#ifndef HAVE_SSL_SET1_CHAIN_CERT_STORE +#define HAVE_SSL_SET1_CHAIN_CERT_STORE OPENSSL_PREREQ(1,0,2) +#endif + +#ifndef HAVE_SSL_SET1_VERIFY_CERT_STORE +#define HAVE_SSL_SET1_VERIFY_CERT_STORE OPENSSL_PREREQ(1,0,2) +#endif + #ifndef HAVE_SSL_SET_CURVES_LIST #define HAVE_SSL_SET_CURVES_LIST (OPENSSL_PREREQ(1,0,2) || LIBRESSL_PREREQ(2,5,1)) #endif @@ -1856,18 +1864,16 @@ static void (compat_X509_STORE_free)(X509_STORE *store) { #endif #if !HAVE_SSL_CTX_SET1_CERT_STORE -#if !HAVE_SSL_CTX_CERT_STORE || !HAVE_X509_STORE_REFERENCES -#define SSL_CTX_set1_cert_store(ctx, store) \ - SSL_CTX_set_cert_store((ctx), (store)) -#else -#define SSL_CTX_set1_cert_store(ctx, store) \ - compat_SSL_CTX_set1_cert_store((ctx), (store)) -/* to support preprocessor detection below */ -#define compat_SSL_CTX_set1_cert_store(ctx, store) \ +#define SSL_CTX_set1_cert_store(ctx, store) \ compat_SSL_CTX_set1_cert_store((ctx), (store)) static void (compat_SSL_CTX_set1_cert_store)(SSL_CTX *ctx, X509_STORE *store) { +#if !HAVE_SSL_CTX_CERT_STORE || !HAVE_X509_STORE_REFERENCES + if (store != NULL) + X509_STORE_up_ref(store); + SSL_CTX_set_cert_store(ctx, store); +#else int n; /* @@ -1885,8 +1891,9 @@ static void (compat_SSL_CTX_set1_cert_store)(SSL_CTX *ctx, X509_STORE *store) { if (n == store->references) CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE); -} /* compat_SSL_CTX_set1_cert_store() */ #endif +} /* compat_SSL_CTX_set1_cert_store() */ + #endif #if HAVE_SSL_CTX_CERT_STORE @@ -4581,16 +4588,17 @@ static const auxL_Reg pk_methods[] = { { "type", &pk_type }, { "setPublicKey", &pk_setPublicKey }, { "setPrivateKey", &pk_setPrivateKey }, + { "getDefaultDigestName", &pk_getDefaultDigestName }, + { "getParameters", &pk_getParameters }, + { "setParameters", &pk_setParameters }, #if HAVE_EVP_PKEY_CTX_NEW { "decrypt", &pk_decrypt }, { "encrypt", &pk_encrypt }, #endif { "sign", &pk_sign }, - { "verify", &pk_verify }, - { "getDefaultDigestName", &pk_getDefaultDigestName }, { "toPEM", &pk_toPEM }, - { "getParameters", &pk_getParameters }, - { "setParameters", &pk_setParameters }, + { "tostring", &pk__tostring }, + { "verify", &pk_verify }, { NULL, NULL }, }; @@ -4759,6 +4767,23 @@ static int ecg_interpose(lua_State *L) { return interpose(L, EC_GROUP_CLASS); } /* ecg_interpose() */ + +static int ecg_toPEM(lua_State *L) { + EC_GROUP *group = checksimple(L, 1, EC_GROUP_CLASS); + BIO *bio = getbio(L); + size_t len; + char *bytes; + + if (!PEM_write_bio_ECPKParameters(bio, group)) + return auxL_error(L, auxL_EOPENSSL, "group:toPEM"); + + len = BIO_get_mem_data(bio, &bytes); + lua_pushlstring(L, bytes, len); + + return 1; +} /* ecg_toPEM() */ + + 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); @@ -4806,6 +4831,7 @@ static int ecg__gc(lua_State *L) { } /* ecg__gc() */ static const auxL_Reg ecg_methods[] = { + { "toPEM", &ecg_toPEM }, { "tostring", &ecg_tostring }, { NULL, NULL }, }; @@ -5533,7 +5559,7 @@ static int xe_text(lua_State *L) { size_t len; if (!X509V3_EXT_print(bio, ext, flags, indent)) - return auxL_error(L, auxL_EOPENSSL, "x509.extension.text"); + return auxL_error(L, auxL_EOPENSSL, "x509.extension:text"); len = BIO_get_mem_data(bio, &data); @@ -6298,6 +6324,25 @@ static int xc_addExtension(lua_State *L) { } /* xc_addExtension() */ +static int xc_setExtension(lua_State *L) { + X509 *crt = checksimple(L, 1, X509_CERT_CLASS); + X509_EXTENSION *ext = checksimple(L, 2, X509_EXT_CLASS); + int nid, crit; + void *value; + + nid = OBJ_obj2nid(X509_EXTENSION_get_object(ext)); + crit = X509_EXTENSION_get_critical(ext); + value = X509_EXTENSION_get_data(ext); + + if (!X509_add1_ext_i2d(crt, nid, value, crit, X509V3_ADD_REPLACE)) + return auxL_error(L, auxL_EOPENSSL, "x509.cert:setExtension"); + + lua_pushboolean(L, 1); + + return 1; +} /* xc_setExtension() */ + + static int xc_getExtension(lua_State *L) { X509 *crt = checksimple(L, 1, X509_CERT_CLASS); X509_EXTENSION *ext = NULL, **ud; @@ -6547,6 +6592,22 @@ static int xc_text(lua_State *L) { } /* xc_text() */ +static int xc_toPEM(lua_State *L) { + X509 *crt = checksimple(L, 1, X509_CERT_CLASS); + BIO *bio = getbio(L); + size_t len; + char *bytes; + + if (!PEM_write_bio_X509(bio, crt)) + return auxL_error(L, auxL_EOPENSSL, "x509.cert:toPEM"); + + len = BIO_get_mem_data(bio, &bytes); + lua_pushlstring(L, bytes, len); + + return 1; +} /* xc_toPEM() */ + + static int xc__tostring(lua_State *L) { X509 *crt = checksimple(L, 1, X509_CERT_CLASS); int type = optencoding(L, 2, "pem", X509_PEM|X509_DER); @@ -6612,6 +6673,7 @@ static const auxL_Reg xc_methods[] = { { "getBasicConstraintsCritical", &xc_getBasicConstraintsCritical }, { "setBasicConstraintsCritical", &xc_setBasicConstraintsCritical }, { "addExtension", &xc_addExtension }, + { "setExtension", &xc_setExtension }, { "getExtension", &xc_getExtension }, { "getExtensionCount", &xc_getExtensionCount }, { "getOCSP", &xc_getOCSP }, @@ -6622,6 +6684,7 @@ static const auxL_Reg xc_methods[] = { { "getSignatureName", &xc_getSignatureName }, { "sign", &xc_sign }, { "text", &xc_text }, + { "toPEM", &xc_toPEM }, { "tostring", &xc__tostring }, { NULL, NULL }, }; @@ -6753,7 +6816,7 @@ static int xr_getPublicKey(lua_State *L) { EVP_PKEY **key = prepsimple(L, PKEY_CLASS); if (!(*key = X509_REQ_get_pubkey(csr))) - return auxL_error(L, auxL_EOPENSSL, "x509.cert:getPublicKey"); + return auxL_error(L, auxL_EOPENSSL, "x509.csr:getPublicKey"); return 1; } /* xr_getPublicKey() */ @@ -6772,7 +6835,7 @@ static int xr_setPublicKey(lua_State *L) { } /* xr_setPublicKey() */ -static int xr_setExtensionByNid(lua_State *L, X509_REQ *csr, int target_nid, void* value) { +static int xr_modifyRequestedExtension(X509_REQ *csr, int target_nid, int crit, void* value, unsigned long flags) { STACK_OF(X509_EXTENSION) *sk = NULL; int has_attrs=0; @@ -6785,7 +6848,7 @@ static int xr_setExtensionByNid(lua_State *L, X509_REQ *csr, int target_nid, voi * everything is stored under a list in a single "attribute" so we * can't use X509_REQ_add1_attr or similar. * - * Instead we have to get the extensions, find and replace the SAN + * Instead we have to get the extensions, find and replace the extension * if it's in there, then *replace* the extensions in the list of * attributes. (If we just try to add it the old ones are found * first and don't take priority.) @@ -6793,7 +6856,7 @@ static int xr_setExtensionByNid(lua_State *L, X509_REQ *csr, int target_nid, voi has_attrs = X509_REQ_get_attr_count(csr); sk = X509_REQ_get_extensions(csr); - if (!X509V3_add1_i2d(&sk, target_nid, value, 0, X509V3_ADD_REPLACE)) + if (!X509V3_add1_i2d(&sk, target_nid, value, crit, flags)) goto error; if (X509_REQ_add_extensions(csr, sk) == 0) goto error; @@ -6831,22 +6894,24 @@ static int xr_setExtensionByNid(lua_State *L, X509_REQ *csr, int target_nid, voi csr->req_info->enc.modified = 1; #endif - lua_pushboolean(L, 1); - - return 1; + return 0; error: if (sk) sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free); - return auxL_error(L, auxL_EOPENSSL, "x509.csr.setExtensionByNid"); -} /* xr_setExtensionByNid() */ + return 1; +} /* xr_modifyRequestedExtension() */ static int xr_setSubjectAlt(lua_State *L) { X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); GENERAL_NAMES *gens = checksimple(L, 2, X509_GENS_CLASS); - return xr_setExtensionByNid(L, csr, NID_subject_alt_name, gens); + if (xr_modifyRequestedExtension(csr, NID_subject_alt_name, 0, gens, X509V3_ADD_REPLACE)) + return auxL_error(L, auxL_EOPENSSL, "x509.csr:setSubjectAlt"); + + lua_pushboolean(L, 1); + return 1; } /* xr_setSubjectAlt */ @@ -6868,6 +6933,106 @@ error: } /* xr_getSubjectAlt() */ +static int xr_addRequestedExtension(lua_State *L) { + X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); + X509_EXTENSION *ext = checksimple(L, 2, X509_EXT_CLASS); + int nid, crit; + void *value; + + nid = OBJ_obj2nid(X509_EXTENSION_get_object(ext)); + crit = X509_EXTENSION_get_critical(ext); + value = X509_EXTENSION_get_data(ext); + + if (xr_modifyRequestedExtension(csr, nid, crit, value, X509V3_ADD_APPEND)) + return auxL_error(L, auxL_EOPENSSL, "x509.csr:addRequestedExtension"); + + lua_pushboolean(L, 1); + return 1; +} /* xr_addRequestedExtension() */ + + +static int xr_setRequestedExtension(lua_State *L) { + X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); + X509_EXTENSION *ext = checksimple(L, 2, X509_EXT_CLASS); + int nid, crit; + void *value; + + nid = OBJ_obj2nid(X509_EXTENSION_get_object(ext)); + crit = X509_EXTENSION_get_critical(ext); + value = X509_EXTENSION_get_data(ext); + + if (xr_modifyRequestedExtension(csr, nid, crit, value, X509V3_ADD_REPLACE)) + return auxL_error(L, auxL_EOPENSSL, "x509.csr:setRequestedExtension"); + + lua_pushboolean(L, 1); + return 1; +} /* xr_setRequestedExtension() */ + + +static int xr_getRequestedExtension(lua_State *L) { + X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); + STACK_OF(X509_EXTENSION) *exts = NULL; + X509_EXTENSION *ext = NULL, **ud; + int i; + + luaL_checkany(L, 2); + + ud = prepsimple(L, X509_EXT_CLASS); + + if (lua_type(L, 2) == LUA_TNUMBER) { + /* NB: Lua 1-based indexing */ + i = auxL_checkinteger(L, 2, 1, INT_MAX) - 1; + exts = X509_REQ_get_extensions(csr); + } else { + ASN1_OBJECT *obj; + + if (!auxS_txt2obj(&obj, luaL_checkstring(L, 2))) { + goto error; + } else if (!obj) { + goto undef; + } + + exts = X509_REQ_get_extensions(csr); + i = X509v3_get_ext_by_OBJ(exts, obj, -1); + + ASN1_OBJECT_free(obj); + } + + if (i < 0 || !(ext = X509v3_get_ext(exts, i))) + goto undef; + + if (!(*ud = X509_EXTENSION_dup(ext))) + goto error; + + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); + exts = NULL; + + return 1; +undef: + if (exts) + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); + return 0; +error: + if (exts) + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); + return auxL_error(L, auxL_EOPENSSL, "x509.csr:getRequestedExtension"); +} /* xr_getRequestedExtension() */ + + +static int xr_getRequestedExtensionCount(lua_State *L) { + X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); + STACK_OF(X509_EXTENSION) *exts = NULL; + auxL_Integer len = 0; + + exts = X509_REQ_get_extensions(csr); + len = sk_X509_EXTENSION_num(exts); + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); + + auxL_pushinteger(L, len); + + return 1; +} /* xr_getRequestedExtensionCount() */ + static int xr_sign(lua_State *L) { X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); @@ -6882,6 +7047,22 @@ static int xr_sign(lua_State *L) { } /* xr_sign() */ +static int xr_toPEM(lua_State *L) { + X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); + BIO *bio = getbio(L); + size_t len; + char *bytes; + + if (!PEM_write_bio_X509_REQ(bio, csr)) + return auxL_error(L, auxL_EOPENSSL, "x509.csr:toPEM"); + + len = BIO_get_mem_data(bio, &bytes); + lua_pushlstring(L, bytes, len); + + return 1; +} /* xr_toPEM() */ + + static int xr__tostring(lua_State *L) { X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); int type = optencoding(L, 2, "pem", X509_PEM|X509_DER); @@ -6928,7 +7109,12 @@ static const auxL_Reg xr_methods[] = { { "setPublicKey", &xr_setPublicKey }, { "getSubjectAlt", &xr_getSubjectAlt }, { "setSubjectAlt", &xr_setSubjectAlt }, + { "getRequestedExtension", &xr_getRequestedExtension }, + { "getRequestedExtensionCount", &xr_getRequestedExtensionCount }, + { "addRequestedExtension", &xr_addRequestedExtension }, + { "setRequestedExtension", &xr_setRequestedExtension }, { "sign", &xr_sign }, + { "toPEM", &xr_toPEM }, { "tostring", &xr__tostring }, { NULL, NULL }, }; @@ -7204,6 +7390,25 @@ static int xx_addExtension(lua_State *L) { } /* xx_addExtension() */ +static int xx_setExtension(lua_State *L) { + X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS); + X509_EXTENSION *ext = checksimple(L, 2, X509_EXT_CLASS); + int nid, crit; + void *value; + + nid = OBJ_obj2nid(X509_EXTENSION_get_object(ext)); + crit = X509_EXTENSION_get_critical(ext); + value = X509_EXTENSION_get_data(ext); + + if (!X509_CRL_add1_ext_i2d(crl, nid, value, crit, X509V3_ADD_REPLACE)) + return auxL_error(L, auxL_EOPENSSL, "x509.crl:setExtension"); + + lua_pushboolean(L, 1); + + return 1; +} /* xx_setExtension() */ + + static int xx_getExtension(lua_State *L) { X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS); X509_EXTENSION *ext = NULL, **ud; @@ -7295,6 +7500,22 @@ static int xx_text(lua_State *L) { } /* xx_text() */ +static int xx_toPEM(lua_State *L) { + X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS); + BIO *bio = getbio(L); + size_t len; + char *bytes; + + if (!PEM_write_bio_X509_CRL(bio, crl)) + return auxL_error(L, auxL_EOPENSSL, "x509.crl:toPEM"); + + len = BIO_get_mem_data(bio, &bytes); + lua_pushlstring(L, bytes, len); + + return 1; +} /* xx_toPEM() */ + + static int xx__tostring(lua_State *L) { X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS); int type = optencoding(L, 2, "pem", X509_PEM|X509_DER); @@ -7343,11 +7564,13 @@ static const auxL_Reg xx_methods[] = { { "setIssuer", &xx_setIssuer }, { "add", &xx_add }, { "addExtension", &xx_addExtension }, + { "setExtension", &xx_setExtension }, { "getExtension", &xx_getExtension }, { "getExtensionCount", &xx_getExtensionCount }, { "sign", &xx_sign }, { "verify", &xx_verify }, { "text", &xx_text }, + { "toPEM", &xx_toPEM }, { "tostring", &xx__tostring }, { NULL, NULL }, }; @@ -8730,7 +8953,7 @@ static int ssl_setContext(lua_State *L) { SSL_CTX *ctx = checksimple(L, 2, SSL_CTX_CLASS); if (!SSL_set_SSL_CTX(ssl, ctx)) - return auxL_error(L, auxL_EOPENSSL, "ssl.setContext"); + return auxL_error(L, auxL_EOPENSSL, "ssl:setContext"); lua_pushboolean(L, 1); @@ -8766,6 +8989,34 @@ static int ssl_clearOptions(lua_State *L) { } /* ssl_clearOptions() */ +#if HAVE_SSL_SET1_CHAIN_CERT_STORE +static int ssl_setChainStore(lua_State *L) { + SSL *ssl = checksimple(L, 1, SSL_CLASS); + X509_STORE *store = checksimple(L, 2, X509_STORE_CLASS); + + SSL_set1_chain_cert_store(ssl, store); + + lua_pushboolean(L, 1); + + return 1; +} /* ssl_setChainStore() */ +#endif + + +#if HAVE_SSL_SET1_VERIFY_CERT_STORE +static int ssl_setVerifyStore(lua_State *L) { + SSL *ssl = checksimple(L, 1, SSL_CLASS); + X509_STORE *store = checksimple(L, 2, X509_STORE_CLASS); + + SSL_set1_verify_cert_store(ssl, store); + + lua_pushboolean(L, 1); + + return 1; +} /* ssl_setVerifyStore() */ +#endif + + static int ssl_setParam(lua_State *L) { SSL *ssl = checksimple(L, 1, SSL_CLASS); X509_VERIFY_PARAM *xp = checksimple(L, 2, X509_VERIFY_PARAM_CLASS); @@ -9171,6 +9422,12 @@ static const auxL_Reg ssl_methods[] = { { "setOptions", &ssl_setOptions }, { "getOptions", &ssl_getOptions }, { "clearOptions", &ssl_clearOptions }, +#if HAVE_SSL_SET1_CHAIN_CERT_STORE + { "setChainStore", &ssl_setChainStore }, +#endif +#if HAVE_SSL_SET1_VERIFY_CERT_STORE + { "setVerifyStore", &ssl_setVerifyStore }, +#endif { "setParam", &ssl_setParam }, { "getParam", &ssl_getParam }, { "setVerify", &ssl_setVerify }, diff --git a/src/openssl.ssl.lua b/src/openssl.ssl.lua index bf90f29..2a18024 100644 --- a/src/openssl.ssl.lua +++ b/src/openssl.ssl.lua @@ -2,6 +2,12 @@ local ssl = require"_openssl.ssl" local pack = table.pack or function(...) return { n = select("#", ...); ... } end +ssl.interpose("setStore", function(self, store) + self:setChainStore(store) + self:setVerifyStore(store) + return true +end) + -- Allow passing a vararg of curves, or an array local setCurvesList = ssl.interpose("setCurvesList", nil) if setCurvesList then |