aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/openssl.c199
1 files changed, 155 insertions, 44 deletions
diff --git a/src/openssl.c b/src/openssl.c
index d4f75aa..ee2cd68 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -77,12 +77,38 @@
#include "compat52.h"
#endif
+#define GNUC_2VER(M, m, p) (((M) * 10000) + ((m) * 100) + (p))
+#define GNUC_PREREQ(M, m, p) (__GNUC__ > 0 && GNUC_2VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) >= GNUC_2VER((M), (m), (p)))
+
+#define MSC_2VER(M, m, p) ((((M) + 6) * 10000000) + ((m) * 1000000) + (p))
+#define MSC_PREREQ(M, m, p) (_MSC_FULL_VER > 0 && _MSC_FULL_VER >= MSC_2VER((M), (m), (p)))
+
#define OPENSSL_PREREQ(M, m, p) \
(OPENSSL_VERSION_NUMBER >= (((M) << 28) | ((m) << 20) | ((p) << 12)) && !defined LIBRESSL_VERSION_NUMBER)
#define LIBRESSL_PREREQ(M, m, p) \
(LIBRESSL_VERSION_NUMBER >= (((M) << 28) | ((m) << 20) | ((p) << 12)))
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+
+#ifndef __has_extension
+#define __has_extension(x) 0
+#endif
+
+#ifndef HAVE_C___ASSUME
+#define HAVE_C___ASSUME MSC_PREREQ(8,0,0)
+#endif
+
+#ifndef HAVE_C___BUILTIN_UNREACHABLE
+#define HAVE_C___BUILTIN_UNREACHABLE (GNUC_PREREQ(4,5,0) || __has_builtin(__builtin_unreachable))
+#endif
+
+#ifndef HAVE_C___DECLSPEC_NORETURN
+#define HAVE_C___DECLSPEC_NORETURN MSC_PREREQ(8,0,0)
+#endif
+
#ifndef HAVE_ASN1_STRING_GET0_DATA
#define HAVE_ASN1_STRING_GET0_DATA OPENSSL_PREREQ(1,1,0)
#endif
@@ -316,6 +342,13 @@
#define NOTUSED
#endif
+#if HAVE_C___BUILTIN_UNREACHABLE
+#define NOTREACHED __builtin_unreachable()
+#elif HAVE_C___ASSUME
+#define NOTREACHED __assume(0)
+#else
+#define NOTREACHED (void)0
+#endif
#define countof(a) (sizeof (a) / sizeof *(a))
#define endof(a) (&(a)[countof(a)])
@@ -710,6 +743,8 @@ static size_t auxS_obj2txt(void *dst, size_t lim, const ASN1_OBJECT *obj) {
return auxS_obj2id(dst, lim, obj);
} /* auxS_obj2txt() */
+static const EVP_MD *auxS_todigest(const char *name, EVP_PKEY *key, const EVP_MD *def);
+
static _Bool auxS_isoid(const char *txt) {
return (*txt >= '0' && *txt <= '9');
} /* auxS_isoid() */
@@ -1096,8 +1131,9 @@ static const char *auxL_pusherror(lua_State *L, int error, const char *fun) {
static int auxL_error(lua_State *L, int error, const char *fun) {
auxL_pusherror(L, error, fun);
-
- return lua_error(L);
+ lua_error(L);
+ NOTREACHED;
+ return 0;
} /* auxL_error() */
static const char *auxL_pushnid(lua_State *L, int nid) {
@@ -1112,6 +1148,8 @@ static const char *auxL_pushnid(lua_State *L, int nid) {
return lua_tostring(L, -1);
} /* auxL_pushnid() */
+static const EVP_MD *auxL_optdigest(lua_State *L, int index, EVP_PKEY *key, const EVP_MD *def);
+
/*
* dl - dynamically loaded module management
@@ -1704,6 +1742,53 @@ sslerr:
/*
+ * Auxiliary OpenSSL API routines (with dependencies on OpenSSL compat)
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+static const EVP_MD *auxS_todigest(const char *name, EVP_PKEY *key, const EVP_MD *def) {
+ const EVP_MD *md;
+ int nid;
+
+ if (name) {
+ if ((md = EVP_get_digestbyname(name)))
+ return md;
+ } else if (key) {
+ if ((EVP_PKEY_get_default_digest_nid(key, &nid) > 0)) {
+ if ((md = EVP_get_digestbynid(nid)))
+ return md;
+ }
+ }
+
+ return def;
+} /* auxS_todigest() */
+
+
+/*
+ * Auxiliary Lua API routines (with dependencies on OpenSSL compat)
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+static const EVP_MD *auxL_optdigest(lua_State *L, int index, EVP_PKEY *key, const EVP_MD *def) {
+ const char *name = luaL_optstring(L, index, NULL);
+ const EVP_MD *md;
+
+ if ((md = auxS_todigest(name, key, NULL)))
+ return md;
+
+ if (name) {
+ luaL_argerror(L, index, lua_pushfstring(L, "invalid digest type (%s)", name));
+ NOTREACHED;
+ } else if (key) {
+ luaL_argerror(L, index, lua_pushfstring(L, "no digest type for key type (%d)", EVP_PKEY_base_id(key)));
+ NOTREACHED;
+ }
+
+ return def;
+} /* auxL_optdigest() */
+
+
+/*
* External Application Data Hooks
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -3353,18 +3438,11 @@ static int pk_toPEM(lua_State *L) {
static int pk_getDefaultDigestName(lua_State *L) {
EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS);
int nid;
- char txt[256];
- size_t len;
if (!(EVP_PKEY_get_default_digest_nid(key, &nid) > 0))
return auxL_error(L, auxL_EOPENSSL, "pkey:getDefaultDigestName");
- if (!(len = auxS_nid2txt(txt, sizeof txt, nid)))
- return auxL_error(L, auxL_EOPENSSL, "pkey:getDefaultDigestName");
- if (len > sizeof txt)
- return auxL_error(L, EOVERFLOW, "pkey:getDefaultDigestName");
-
- lua_pushlstring(L, txt, len);
+ auxL_pushnid(L, nid);
return 1;
} /* pk_getDefaultDigestName() */
@@ -5672,49 +5750,50 @@ static int xc_setPublicKey(lua_State *L) {
static int xc_getPublicKeyDigest(lua_State *L) {
- ASN1_BIT_STRING *pk = X509_get0_pubkey_bitstr(checksimple(L, 1, X509_CERT_CLASS));
- const char *id = luaL_optstring(L, 2, "sha1");
+ X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
+ EVP_PKEY *key;
const EVP_MD *md;
+ ASN1_BIT_STRING *bitstr;
unsigned char digest[EVP_MAX_MD_SIZE];
unsigned int len;
- if (!(md = EVP_get_digestbyname(id)))
- return luaL_error(L, "x509.cert:getPublicKeyDigest: %s: invalid digest type", id);
+ if (!(key = X509_get_pubkey(crt)))
+ return luaL_argerror(L, 1, "no public key");
+ md = auxL_optdigest(L, 2, key, NULL);
+ bitstr = X509_get0_pubkey_bitstr(crt);
- if (!EVP_Digest(pk->data, pk->length, digest, &len, md, NULL))
+ if (!EVP_Digest(bitstr->data, bitstr->length, digest, &len, md, NULL))
return auxL_error(L, auxL_EOPENSSL, "x509.cert:getPublicKeyDigest");
-
lua_pushlstring(L, (char *)digest, len);
return 1;
} /* xc_getPublicKeyDigest() */
-static const EVP_MD *xc_signature(lua_State *L, int index, EVP_PKEY *key) {
- const char *id;
- const EVP_MD *md;
+#if 0
+/*
+ * TODO: X509_get_signature_type always seems to return NID_undef. Are we
+ * using it wrong or is it broken?
+ */
+static int xc_getSignatureName(lua_State *L) {
+ X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
int nid;
- if ((id = luaL_optstring(L, index, NULL))) {
- if (!(md = EVP_get_digestbyname(id)))
- goto unknown;
- } else {
- if (!(EVP_PKEY_get_default_digest_nid(key, &nid) > 0))
- goto unknown;
- if (!(md = EVP_get_digestbynid(nid)))
- goto unknown;
- }
+ if (NID_undef == (nid = X509_get_signature_type(crt)))
+ return 0;
+
+ auxL_pushnid(L, nid);
+
+ return 1;
+} /* xc_getSignatureName() */
+#endif
- return md;
-unknown:
- return EVP_sha1();
-} /* xc_signature() */
static int xc_sign(lua_State *L) {
X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS);
- if (!X509_sign(crt, key, xc_signature(L, 3, key)))
+ if (!X509_sign(crt, key, auxL_optdigest(L, 3, key, NULL)))
return auxL_error(L, auxL_EOPENSSL, "x509.cert:sign");
lua_pushboolean(L, 1);
@@ -5854,6 +5933,9 @@ static const auxL_Reg xc_methods[] = {
{ "getPublicKey", &xc_getPublicKey },
{ "setPublicKey", &xc_setPublicKey },
{ "getPublicKeyDigest", &xc_getPublicKeyDigest },
+#if 0
+ { "getSignatureName", &xc_getSignatureName },
+#endif
{ "sign", &xc_sign },
{ "text", &xc_text },
{ "tostring", &xc__tostring },
@@ -6107,7 +6189,7 @@ static int xr_sign(lua_State *L) {
X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS);
EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS);
- if (!X509_REQ_sign(csr, key, xc_signature(L, 3, key)))
+ if (!X509_REQ_sign(csr, key, auxL_optdigest(L, 3, key, NULL)))
return auxL_error(L, auxL_EOPENSSL, "x509.csr:sign");
lua_pushboolean(L, 1);
@@ -6482,7 +6564,7 @@ static int xx_sign(lua_State *L) {
X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS);
EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS);
- if (!X509_CRL_sign(crl, key, xc_signature(L, 3, key)))
+ if (!X509_CRL_sign(crl, key, auxL_optdigest(L, 3, key, NULL)))
return auxL_error(L, auxL_EOPENSSL, "x509.crl:sign");
lua_pushboolean(L, 1);
@@ -6778,17 +6860,24 @@ static int xs_interpose(lua_State *L) {
static int xs_add(lua_State *L) {
X509_STORE *store = checksimple(L, 1, X509_STORE_CLASS);
int i, top = lua_gettop(L);
+ X509 *crt, *crt_dup;
+ X509_CRL *crl, *crl_dup;
for (i = 2; i <= top; i++) {
- if (lua_isuserdata(L, i)) {
- X509 *crt = checksimple(L, i, X509_CERT_CLASS);
- X509 *dup;
+ if ((crt = testsimple(L, i, X509_CERT_CLASS))) {
+ if (!(crt_dup = X509_dup(crt)))
+ return auxL_error(L, auxL_EOPENSSL, "x509.store:add");
- if (!(dup = X509_dup(crt)))
+ if (!X509_STORE_add_cert(store, crt_dup)) {
+ X509_free(crt_dup);
+ return auxL_error(L, auxL_EOPENSSL, "x509.store:add");
+ }
+ } else if ((crl = testsimple(L, i, X509_CRL_CLASS))) {
+ if (!(crl_dup = X509_CRL_dup(crl)))
return auxL_error(L, auxL_EOPENSSL, "x509.store:add");
- if (!X509_STORE_add_cert(store, dup)) {
- X509_free(dup);
+ if (!X509_STORE_add_crl(store, crl_dup)) {
+ X509_CRL_free(crl_dup);
return auxL_error(L, auxL_EOPENSSL, "x509.store:add");
}
} else {
@@ -6815,6 +6904,18 @@ static int xs_add(lua_State *L) {
} /* xs_add() */
+static int xs_addDefaults(lua_State *L) {
+ X509_STORE *store = checksimple(L, 1, X509_STORE_CLASS);
+
+ if (!X509_STORE_set_default_paths(store))
+ return auxL_error(L, auxL_EOPENSSL, "x509.store:addDefaults");
+
+ lua_pushvalue(L, 1);
+
+ return 1;
+} /* xs_addDefaults() */
+
+
static int xs_verify(lua_State *L) {
X509_STORE *store = checksimple(L, 1, X509_STORE_CLASS);
X509 *crt = checksimple(L, 2, X509_CERT_CLASS);
@@ -6897,9 +6998,10 @@ static int xs__gc(lua_State *L) {
static const auxL_Reg xs_methods[] = {
- { "add", &xs_add },
- { "verify", &xs_verify },
- { NULL, NULL },
+ { "add", &xs_add },
+ { "addDefaults", &xs_addDefaults },
+ { "verify", &xs_verify },
+ { NULL, NULL },
};
static const auxL_Reg xs_metatable[] = {
@@ -6918,6 +7020,15 @@ int luaopen__openssl_x509_store(lua_State *L) {
auxL_newlib(L, xs_globals, 0);
+ lua_pushstring(L, X509_get_default_cert_dir());
+ lua_setfield(L, -2, "CERT_DIR");
+ lua_pushstring(L, X509_get_default_cert_file());
+ lua_setfield(L, -2, "CERT_FILE");
+ lua_pushstring(L, X509_get_default_cert_dir_env());
+ lua_setfield(L, -2, "CERT_DIR_EVP");
+ lua_pushstring(L, X509_get_default_cert_file_env());
+ lua_setfield(L, -2, "CERT_FILE_EVP");
+
return 1;
} /* luaopen__openssl_x509_store() */