diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/openssl.c | 199 |
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 @@ | |||
77 | #include "compat52.h" | 77 | #include "compat52.h" |
78 | #endif | 78 | #endif |
79 | 79 | ||
80 | #define GNUC_2VER(M, m, p) (((M) * 10000) + ((m) * 100) + (p)) | ||
81 | #define GNUC_PREREQ(M, m, p) (__GNUC__ > 0 && GNUC_2VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) >= GNUC_2VER((M), (m), (p))) | ||
82 | |||
83 | #define MSC_2VER(M, m, p) ((((M) + 6) * 10000000) + ((m) * 1000000) + (p)) | ||
84 | #define MSC_PREREQ(M, m, p) (_MSC_FULL_VER > 0 && _MSC_FULL_VER >= MSC_2VER((M), (m), (p))) | ||
85 | |||
80 | #define OPENSSL_PREREQ(M, m, p) \ | 86 | #define OPENSSL_PREREQ(M, m, p) \ |
81 | (OPENSSL_VERSION_NUMBER >= (((M) << 28) | ((m) << 20) | ((p) << 12)) && !defined LIBRESSL_VERSION_NUMBER) | 87 | (OPENSSL_VERSION_NUMBER >= (((M) << 28) | ((m) << 20) | ((p) << 12)) && !defined LIBRESSL_VERSION_NUMBER) |
82 | 88 | ||
83 | #define LIBRESSL_PREREQ(M, m, p) \ | 89 | #define LIBRESSL_PREREQ(M, m, p) \ |
84 | (LIBRESSL_VERSION_NUMBER >= (((M) << 28) | ((m) << 20) | ((p) << 12))) | 90 | (LIBRESSL_VERSION_NUMBER >= (((M) << 28) | ((m) << 20) | ((p) << 12))) |
85 | 91 | ||
92 | #ifndef __has_builtin | ||
93 | #define __has_builtin(x) 0 | ||
94 | #endif | ||
95 | |||
96 | #ifndef __has_extension | ||
97 | #define __has_extension(x) 0 | ||
98 | #endif | ||
99 | |||
100 | #ifndef HAVE_C___ASSUME | ||
101 | #define HAVE_C___ASSUME MSC_PREREQ(8,0,0) | ||
102 | #endif | ||
103 | |||
104 | #ifndef HAVE_C___BUILTIN_UNREACHABLE | ||
105 | #define HAVE_C___BUILTIN_UNREACHABLE (GNUC_PREREQ(4,5,0) || __has_builtin(__builtin_unreachable)) | ||
106 | #endif | ||
107 | |||
108 | #ifndef HAVE_C___DECLSPEC_NORETURN | ||
109 | #define HAVE_C___DECLSPEC_NORETURN MSC_PREREQ(8,0,0) | ||
110 | #endif | ||
111 | |||
86 | #ifndef HAVE_ASN1_STRING_GET0_DATA | 112 | #ifndef HAVE_ASN1_STRING_GET0_DATA |
87 | #define HAVE_ASN1_STRING_GET0_DATA OPENSSL_PREREQ(1,1,0) | 113 | #define HAVE_ASN1_STRING_GET0_DATA OPENSSL_PREREQ(1,1,0) |
88 | #endif | 114 | #endif |
@@ -316,6 +342,13 @@ | |||
316 | #define NOTUSED | 342 | #define NOTUSED |
317 | #endif | 343 | #endif |
318 | 344 | ||
345 | #if HAVE_C___BUILTIN_UNREACHABLE | ||
346 | #define NOTREACHED __builtin_unreachable() | ||
347 | #elif HAVE_C___ASSUME | ||
348 | #define NOTREACHED __assume(0) | ||
349 | #else | ||
350 | #define NOTREACHED (void)0 | ||
351 | #endif | ||
319 | 352 | ||
320 | #define countof(a) (sizeof (a) / sizeof *(a)) | 353 | #define countof(a) (sizeof (a) / sizeof *(a)) |
321 | #define endof(a) (&(a)[countof(a)]) | 354 | #define endof(a) (&(a)[countof(a)]) |
@@ -710,6 +743,8 @@ static size_t auxS_obj2txt(void *dst, size_t lim, const ASN1_OBJECT *obj) { | |||
710 | return auxS_obj2id(dst, lim, obj); | 743 | return auxS_obj2id(dst, lim, obj); |
711 | } /* auxS_obj2txt() */ | 744 | } /* auxS_obj2txt() */ |
712 | 745 | ||
746 | static const EVP_MD *auxS_todigest(const char *name, EVP_PKEY *key, const EVP_MD *def); | ||
747 | |||
713 | static _Bool auxS_isoid(const char *txt) { | 748 | static _Bool auxS_isoid(const char *txt) { |
714 | return (*txt >= '0' && *txt <= '9'); | 749 | return (*txt >= '0' && *txt <= '9'); |
715 | } /* auxS_isoid() */ | 750 | } /* auxS_isoid() */ |
@@ -1096,8 +1131,9 @@ static const char *auxL_pusherror(lua_State *L, int error, const char *fun) { | |||
1096 | 1131 | ||
1097 | static int auxL_error(lua_State *L, int error, const char *fun) { | 1132 | static int auxL_error(lua_State *L, int error, const char *fun) { |
1098 | auxL_pusherror(L, error, fun); | 1133 | auxL_pusherror(L, error, fun); |
1099 | 1134 | lua_error(L); | |
1100 | return lua_error(L); | 1135 | NOTREACHED; |
1136 | return 0; | ||
1101 | } /* auxL_error() */ | 1137 | } /* auxL_error() */ |
1102 | 1138 | ||
1103 | static const char *auxL_pushnid(lua_State *L, int nid) { | 1139 | static const char *auxL_pushnid(lua_State *L, int nid) { |
@@ -1112,6 +1148,8 @@ static const char *auxL_pushnid(lua_State *L, int nid) { | |||
1112 | return lua_tostring(L, -1); | 1148 | return lua_tostring(L, -1); |
1113 | } /* auxL_pushnid() */ | 1149 | } /* auxL_pushnid() */ |
1114 | 1150 | ||
1151 | static const EVP_MD *auxL_optdigest(lua_State *L, int index, EVP_PKEY *key, const EVP_MD *def); | ||
1152 | |||
1115 | 1153 | ||
1116 | /* | 1154 | /* |
1117 | * dl - dynamically loaded module management | 1155 | * dl - dynamically loaded module management |
@@ -1704,6 +1742,53 @@ sslerr: | |||
1704 | 1742 | ||
1705 | 1743 | ||
1706 | /* | 1744 | /* |
1745 | * Auxiliary OpenSSL API routines (with dependencies on OpenSSL compat) | ||
1746 | * | ||
1747 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
1748 | |||
1749 | static const EVP_MD *auxS_todigest(const char *name, EVP_PKEY *key, const EVP_MD *def) { | ||
1750 | const EVP_MD *md; | ||
1751 | int nid; | ||
1752 | |||
1753 | if (name) { | ||
1754 | if ((md = EVP_get_digestbyname(name))) | ||
1755 | return md; | ||
1756 | } else if (key) { | ||
1757 | if ((EVP_PKEY_get_default_digest_nid(key, &nid) > 0)) { | ||
1758 | if ((md = EVP_get_digestbynid(nid))) | ||
1759 | return md; | ||
1760 | } | ||
1761 | } | ||
1762 | |||
1763 | return def; | ||
1764 | } /* auxS_todigest() */ | ||
1765 | |||
1766 | |||
1767 | /* | ||
1768 | * Auxiliary Lua API routines (with dependencies on OpenSSL compat) | ||
1769 | * | ||
1770 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
1771 | |||
1772 | static const EVP_MD *auxL_optdigest(lua_State *L, int index, EVP_PKEY *key, const EVP_MD *def) { | ||
1773 | const char *name = luaL_optstring(L, index, NULL); | ||
1774 | const EVP_MD *md; | ||
1775 | |||
1776 | if ((md = auxS_todigest(name, key, NULL))) | ||
1777 | return md; | ||
1778 | |||
1779 | if (name) { | ||
1780 | luaL_argerror(L, index, lua_pushfstring(L, "invalid digest type (%s)", name)); | ||
1781 | NOTREACHED; | ||
1782 | } else if (key) { | ||
1783 | luaL_argerror(L, index, lua_pushfstring(L, "no digest type for key type (%d)", EVP_PKEY_base_id(key))); | ||
1784 | NOTREACHED; | ||
1785 | } | ||
1786 | |||
1787 | return def; | ||
1788 | } /* auxL_optdigest() */ | ||
1789 | |||
1790 | |||
1791 | /* | ||
1707 | * External Application Data Hooks | 1792 | * External Application Data Hooks |
1708 | * | 1793 | * |
1709 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | 1794 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
@@ -3353,18 +3438,11 @@ static int pk_toPEM(lua_State *L) { | |||
3353 | static int pk_getDefaultDigestName(lua_State *L) { | 3438 | static int pk_getDefaultDigestName(lua_State *L) { |
3354 | EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS); | 3439 | EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS); |
3355 | int nid; | 3440 | int nid; |
3356 | char txt[256]; | ||
3357 | size_t len; | ||
3358 | 3441 | ||
3359 | if (!(EVP_PKEY_get_default_digest_nid(key, &nid) > 0)) | 3442 | if (!(EVP_PKEY_get_default_digest_nid(key, &nid) > 0)) |
3360 | return auxL_error(L, auxL_EOPENSSL, "pkey:getDefaultDigestName"); | 3443 | return auxL_error(L, auxL_EOPENSSL, "pkey:getDefaultDigestName"); |
3361 | 3444 | ||
3362 | if (!(len = auxS_nid2txt(txt, sizeof txt, nid))) | 3445 | auxL_pushnid(L, nid); |
3363 | return auxL_error(L, auxL_EOPENSSL, "pkey:getDefaultDigestName"); | ||
3364 | if (len > sizeof txt) | ||
3365 | return auxL_error(L, EOVERFLOW, "pkey:getDefaultDigestName"); | ||
3366 | |||
3367 | lua_pushlstring(L, txt, len); | ||
3368 | 3446 | ||
3369 | return 1; | 3447 | return 1; |
3370 | } /* pk_getDefaultDigestName() */ | 3448 | } /* pk_getDefaultDigestName() */ |
@@ -5672,49 +5750,50 @@ static int xc_setPublicKey(lua_State *L) { | |||
5672 | 5750 | ||
5673 | 5751 | ||
5674 | static int xc_getPublicKeyDigest(lua_State *L) { | 5752 | static int xc_getPublicKeyDigest(lua_State *L) { |
5675 | ASN1_BIT_STRING *pk = X509_get0_pubkey_bitstr(checksimple(L, 1, X509_CERT_CLASS)); | 5753 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); |
5676 | const char *id = luaL_optstring(L, 2, "sha1"); | 5754 | EVP_PKEY *key; |
5677 | const EVP_MD *md; | 5755 | const EVP_MD *md; |
5756 | ASN1_BIT_STRING *bitstr; | ||
5678 | unsigned char digest[EVP_MAX_MD_SIZE]; | 5757 | unsigned char digest[EVP_MAX_MD_SIZE]; |
5679 | unsigned int len; | 5758 | unsigned int len; |
5680 | 5759 | ||
5681 | if (!(md = EVP_get_digestbyname(id))) | 5760 | if (!(key = X509_get_pubkey(crt))) |
5682 | return luaL_error(L, "x509.cert:getPublicKeyDigest: %s: invalid digest type", id); | 5761 | return luaL_argerror(L, 1, "no public key"); |
5762 | md = auxL_optdigest(L, 2, key, NULL); | ||
5763 | bitstr = X509_get0_pubkey_bitstr(crt); | ||
5683 | 5764 | ||
5684 | if (!EVP_Digest(pk->data, pk->length, digest, &len, md, NULL)) | 5765 | if (!EVP_Digest(bitstr->data, bitstr->length, digest, &len, md, NULL)) |
5685 | return auxL_error(L, auxL_EOPENSSL, "x509.cert:getPublicKeyDigest"); | 5766 | return auxL_error(L, auxL_EOPENSSL, "x509.cert:getPublicKeyDigest"); |
5686 | |||
5687 | lua_pushlstring(L, (char *)digest, len); | 5767 | lua_pushlstring(L, (char *)digest, len); |
5688 | 5768 | ||
5689 | return 1; | 5769 | return 1; |
5690 | } /* xc_getPublicKeyDigest() */ | 5770 | } /* xc_getPublicKeyDigest() */ |
5691 | 5771 | ||
5692 | 5772 | ||
5693 | static const EVP_MD *xc_signature(lua_State *L, int index, EVP_PKEY *key) { | 5773 | #if 0 |
5694 | const char *id; | 5774 | /* |
5695 | const EVP_MD *md; | 5775 | * TODO: X509_get_signature_type always seems to return NID_undef. Are we |
5776 | * using it wrong or is it broken? | ||
5777 | */ | ||
5778 | static int xc_getSignatureName(lua_State *L) { | ||
5779 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
5696 | int nid; | 5780 | int nid; |
5697 | 5781 | ||
5698 | if ((id = luaL_optstring(L, index, NULL))) { | 5782 | if (NID_undef == (nid = X509_get_signature_type(crt))) |
5699 | if (!(md = EVP_get_digestbyname(id))) | 5783 | return 0; |
5700 | goto unknown; | 5784 | |
5701 | } else { | 5785 | auxL_pushnid(L, nid); |
5702 | if (!(EVP_PKEY_get_default_digest_nid(key, &nid) > 0)) | 5786 | |
5703 | goto unknown; | 5787 | return 1; |
5704 | if (!(md = EVP_get_digestbynid(nid))) | 5788 | } /* xc_getSignatureName() */ |
5705 | goto unknown; | 5789 | #endif |
5706 | } | ||
5707 | 5790 | ||
5708 | return md; | ||
5709 | unknown: | ||
5710 | return EVP_sha1(); | ||
5711 | } /* xc_signature() */ | ||
5712 | 5791 | ||
5713 | static int xc_sign(lua_State *L) { | 5792 | static int xc_sign(lua_State *L) { |
5714 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | 5793 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); |
5715 | EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS); | 5794 | EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS); |
5716 | 5795 | ||
5717 | if (!X509_sign(crt, key, xc_signature(L, 3, key))) | 5796 | if (!X509_sign(crt, key, auxL_optdigest(L, 3, key, NULL))) |
5718 | return auxL_error(L, auxL_EOPENSSL, "x509.cert:sign"); | 5797 | return auxL_error(L, auxL_EOPENSSL, "x509.cert:sign"); |
5719 | 5798 | ||
5720 | lua_pushboolean(L, 1); | 5799 | lua_pushboolean(L, 1); |
@@ -5854,6 +5933,9 @@ static const auxL_Reg xc_methods[] = { | |||
5854 | { "getPublicKey", &xc_getPublicKey }, | 5933 | { "getPublicKey", &xc_getPublicKey }, |
5855 | { "setPublicKey", &xc_setPublicKey }, | 5934 | { "setPublicKey", &xc_setPublicKey }, |
5856 | { "getPublicKeyDigest", &xc_getPublicKeyDigest }, | 5935 | { "getPublicKeyDigest", &xc_getPublicKeyDigest }, |
5936 | #if 0 | ||
5937 | { "getSignatureName", &xc_getSignatureName }, | ||
5938 | #endif | ||
5857 | { "sign", &xc_sign }, | 5939 | { "sign", &xc_sign }, |
5858 | { "text", &xc_text }, | 5940 | { "text", &xc_text }, |
5859 | { "tostring", &xc__tostring }, | 5941 | { "tostring", &xc__tostring }, |
@@ -6107,7 +6189,7 @@ static int xr_sign(lua_State *L) { | |||
6107 | X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); | 6189 | X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); |
6108 | EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS); | 6190 | EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS); |
6109 | 6191 | ||
6110 | if (!X509_REQ_sign(csr, key, xc_signature(L, 3, key))) | 6192 | if (!X509_REQ_sign(csr, key, auxL_optdigest(L, 3, key, NULL))) |
6111 | return auxL_error(L, auxL_EOPENSSL, "x509.csr:sign"); | 6193 | return auxL_error(L, auxL_EOPENSSL, "x509.csr:sign"); |
6112 | 6194 | ||
6113 | lua_pushboolean(L, 1); | 6195 | lua_pushboolean(L, 1); |
@@ -6482,7 +6564,7 @@ static int xx_sign(lua_State *L) { | |||
6482 | X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS); | 6564 | X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS); |
6483 | EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS); | 6565 | EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS); |
6484 | 6566 | ||
6485 | if (!X509_CRL_sign(crl, key, xc_signature(L, 3, key))) | 6567 | if (!X509_CRL_sign(crl, key, auxL_optdigest(L, 3, key, NULL))) |
6486 | return auxL_error(L, auxL_EOPENSSL, "x509.crl:sign"); | 6568 | return auxL_error(L, auxL_EOPENSSL, "x509.crl:sign"); |
6487 | 6569 | ||
6488 | lua_pushboolean(L, 1); | 6570 | lua_pushboolean(L, 1); |
@@ -6778,17 +6860,24 @@ static int xs_interpose(lua_State *L) { | |||
6778 | static int xs_add(lua_State *L) { | 6860 | static int xs_add(lua_State *L) { |
6779 | X509_STORE *store = checksimple(L, 1, X509_STORE_CLASS); | 6861 | X509_STORE *store = checksimple(L, 1, X509_STORE_CLASS); |
6780 | int i, top = lua_gettop(L); | 6862 | int i, top = lua_gettop(L); |
6863 | X509 *crt, *crt_dup; | ||
6864 | X509_CRL *crl, *crl_dup; | ||
6781 | 6865 | ||
6782 | for (i = 2; i <= top; i++) { | 6866 | for (i = 2; i <= top; i++) { |
6783 | if (lua_isuserdata(L, i)) { | 6867 | if ((crt = testsimple(L, i, X509_CERT_CLASS))) { |
6784 | X509 *crt = checksimple(L, i, X509_CERT_CLASS); | 6868 | if (!(crt_dup = X509_dup(crt))) |
6785 | X509 *dup; | 6869 | return auxL_error(L, auxL_EOPENSSL, "x509.store:add"); |
6786 | 6870 | ||
6787 | if (!(dup = X509_dup(crt))) | 6871 | if (!X509_STORE_add_cert(store, crt_dup)) { |
6872 | X509_free(crt_dup); | ||
6873 | return auxL_error(L, auxL_EOPENSSL, "x509.store:add"); | ||
6874 | } | ||
6875 | } else if ((crl = testsimple(L, i, X509_CRL_CLASS))) { | ||
6876 | if (!(crl_dup = X509_CRL_dup(crl))) | ||
6788 | return auxL_error(L, auxL_EOPENSSL, "x509.store:add"); | 6877 | return auxL_error(L, auxL_EOPENSSL, "x509.store:add"); |
6789 | 6878 | ||
6790 | if (!X509_STORE_add_cert(store, dup)) { | 6879 | if (!X509_STORE_add_crl(store, crl_dup)) { |
6791 | X509_free(dup); | 6880 | X509_CRL_free(crl_dup); |
6792 | return auxL_error(L, auxL_EOPENSSL, "x509.store:add"); | 6881 | return auxL_error(L, auxL_EOPENSSL, "x509.store:add"); |
6793 | } | 6882 | } |
6794 | } else { | 6883 | } else { |
@@ -6815,6 +6904,18 @@ static int xs_add(lua_State *L) { | |||
6815 | } /* xs_add() */ | 6904 | } /* xs_add() */ |
6816 | 6905 | ||
6817 | 6906 | ||
6907 | static int xs_addDefaults(lua_State *L) { | ||
6908 | X509_STORE *store = checksimple(L, 1, X509_STORE_CLASS); | ||
6909 | |||
6910 | if (!X509_STORE_set_default_paths(store)) | ||
6911 | return auxL_error(L, auxL_EOPENSSL, "x509.store:addDefaults"); | ||
6912 | |||
6913 | lua_pushvalue(L, 1); | ||
6914 | |||
6915 | return 1; | ||
6916 | } /* xs_addDefaults() */ | ||
6917 | |||
6918 | |||
6818 | static int xs_verify(lua_State *L) { | 6919 | static int xs_verify(lua_State *L) { |
6819 | X509_STORE *store = checksimple(L, 1, X509_STORE_CLASS); | 6920 | X509_STORE *store = checksimple(L, 1, X509_STORE_CLASS); |
6820 | X509 *crt = checksimple(L, 2, X509_CERT_CLASS); | 6921 | X509 *crt = checksimple(L, 2, X509_CERT_CLASS); |
@@ -6897,9 +6998,10 @@ static int xs__gc(lua_State *L) { | |||
6897 | 6998 | ||
6898 | 6999 | ||
6899 | static const auxL_Reg xs_methods[] = { | 7000 | static const auxL_Reg xs_methods[] = { |
6900 | { "add", &xs_add }, | 7001 | { "add", &xs_add }, |
6901 | { "verify", &xs_verify }, | 7002 | { "addDefaults", &xs_addDefaults }, |
6902 | { NULL, NULL }, | 7003 | { "verify", &xs_verify }, |
7004 | { NULL, NULL }, | ||
6903 | }; | 7005 | }; |
6904 | 7006 | ||
6905 | static const auxL_Reg xs_metatable[] = { | 7007 | static const auxL_Reg xs_metatable[] = { |
@@ -6918,6 +7020,15 @@ int luaopen__openssl_x509_store(lua_State *L) { | |||
6918 | 7020 | ||
6919 | auxL_newlib(L, xs_globals, 0); | 7021 | auxL_newlib(L, xs_globals, 0); |
6920 | 7022 | ||
7023 | lua_pushstring(L, X509_get_default_cert_dir()); | ||
7024 | lua_setfield(L, -2, "CERT_DIR"); | ||
7025 | lua_pushstring(L, X509_get_default_cert_file()); | ||
7026 | lua_setfield(L, -2, "CERT_FILE"); | ||
7027 | lua_pushstring(L, X509_get_default_cert_dir_env()); | ||
7028 | lua_setfield(L, -2, "CERT_DIR_EVP"); | ||
7029 | lua_pushstring(L, X509_get_default_cert_file_env()); | ||
7030 | lua_setfield(L, -2, "CERT_FILE_EVP"); | ||
7031 | |||
6921 | return 1; | 7032 | return 1; |
6922 | } /* luaopen__openssl_x509_store() */ | 7033 | } /* luaopen__openssl_x509_store() */ |
6923 | 7034 | ||