diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/openssl.c | 152 |
1 files changed, 117 insertions, 35 deletions
diff --git a/src/openssl.c b/src/openssl.c index 5ee969a..a8829ab 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 |
@@ -312,6 +338,13 @@ | |||
312 | #define NOTUSED | 338 | #define NOTUSED |
313 | #endif | 339 | #endif |
314 | 340 | ||
341 | #if HAVE_C___BUILTIN_UNREACHABLE | ||
342 | #define NOTREACHED __builtin_unreachable() | ||
343 | #elif HAVE_C___ASSUME | ||
344 | #define NOTREACHED __assume(0) | ||
345 | #else | ||
346 | #define NOTREACHED (void)0 | ||
347 | #endif | ||
315 | 348 | ||
316 | #define countof(a) (sizeof (a) / sizeof *(a)) | 349 | #define countof(a) (sizeof (a) / sizeof *(a)) |
317 | #define endof(a) (&(a)[countof(a)]) | 350 | #define endof(a) (&(a)[countof(a)]) |
@@ -706,6 +739,8 @@ static size_t auxS_obj2txt(void *dst, size_t lim, const ASN1_OBJECT *obj) { | |||
706 | return auxS_obj2id(dst, lim, obj); | 739 | return auxS_obj2id(dst, lim, obj); |
707 | } /* auxS_obj2txt() */ | 740 | } /* auxS_obj2txt() */ |
708 | 741 | ||
742 | static const EVP_MD *auxS_todigest(const char *name, EVP_PKEY *key, const EVP_MD *def); | ||
743 | |||
709 | static _Bool auxS_isoid(const char *txt) { | 744 | static _Bool auxS_isoid(const char *txt) { |
710 | return (*txt >= '0' && *txt <= '9'); | 745 | return (*txt >= '0' && *txt <= '9'); |
711 | } /* auxS_isoid() */ | 746 | } /* auxS_isoid() */ |
@@ -1092,8 +1127,9 @@ static const char *auxL_pusherror(lua_State *L, int error, const char *fun) { | |||
1092 | 1127 | ||
1093 | static int auxL_error(lua_State *L, int error, const char *fun) { | 1128 | static int auxL_error(lua_State *L, int error, const char *fun) { |
1094 | auxL_pusherror(L, error, fun); | 1129 | auxL_pusherror(L, error, fun); |
1095 | 1130 | lua_error(L); | |
1096 | return lua_error(L); | 1131 | NOTREACHED; |
1132 | return 0; | ||
1097 | } /* auxL_error() */ | 1133 | } /* auxL_error() */ |
1098 | 1134 | ||
1099 | static const char *auxL_pushnid(lua_State *L, int nid) { | 1135 | static const char *auxL_pushnid(lua_State *L, int nid) { |
@@ -1108,6 +1144,8 @@ static const char *auxL_pushnid(lua_State *L, int nid) { | |||
1108 | return lua_tostring(L, -1); | 1144 | return lua_tostring(L, -1); |
1109 | } /* auxL_pushnid() */ | 1145 | } /* auxL_pushnid() */ |
1110 | 1146 | ||
1147 | static const EVP_MD *auxL_optdigest(lua_State *L, int index, EVP_PKEY *key, const EVP_MD *def); | ||
1148 | |||
1111 | 1149 | ||
1112 | /* | 1150 | /* |
1113 | * dl - dynamically loaded module management | 1151 | * dl - dynamically loaded module management |
@@ -1688,6 +1726,53 @@ sslerr: | |||
1688 | 1726 | ||
1689 | 1727 | ||
1690 | /* | 1728 | /* |
1729 | * Auxiliary OpenSSL API routines (with dependencies on OpenSSL compat) | ||
1730 | * | ||
1731 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
1732 | |||
1733 | static const EVP_MD *auxS_todigest(const char *name, EVP_PKEY *key, const EVP_MD *def) { | ||
1734 | const EVP_MD *md; | ||
1735 | int nid; | ||
1736 | |||
1737 | if (name) { | ||
1738 | if ((md = EVP_get_digestbyname(name))) | ||
1739 | return md; | ||
1740 | } else if (key) { | ||
1741 | if ((EVP_PKEY_get_default_digest_nid(key, &nid) > 0)) { | ||
1742 | if ((md = EVP_get_digestbynid(nid))) | ||
1743 | return md; | ||
1744 | } | ||
1745 | } | ||
1746 | |||
1747 | return def; | ||
1748 | } /* auxS_todigest() */ | ||
1749 | |||
1750 | |||
1751 | /* | ||
1752 | * Auxiliary Lua API routines (with dependencies on OpenSSL compat) | ||
1753 | * | ||
1754 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
1755 | |||
1756 | static const EVP_MD *auxL_optdigest(lua_State *L, int index, EVP_PKEY *key, const EVP_MD *def) { | ||
1757 | const char *name = luaL_optstring(L, index, NULL); | ||
1758 | const EVP_MD *md; | ||
1759 | |||
1760 | if ((md = auxS_todigest(name, key, NULL))) | ||
1761 | return md; | ||
1762 | |||
1763 | if (name) { | ||
1764 | luaL_argerror(L, index, lua_pushfstring(L, "invalid digest type (%s)", name)); | ||
1765 | NOTREACHED; | ||
1766 | } else if (key) { | ||
1767 | luaL_argerror(L, index, lua_pushfstring(L, "no digest type for key type (%d)", EVP_PKEY_base_id(key))); | ||
1768 | NOTREACHED; | ||
1769 | } | ||
1770 | |||
1771 | return def; | ||
1772 | } /* auxL_optdigest() */ | ||
1773 | |||
1774 | |||
1775 | /* | ||
1691 | * External Application Data Hooks | 1776 | * External Application Data Hooks |
1692 | * | 1777 | * |
1693 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | 1778 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
@@ -3337,18 +3422,11 @@ static int pk_toPEM(lua_State *L) { | |||
3337 | static int pk_getDefaultDigestName(lua_State *L) { | 3422 | static int pk_getDefaultDigestName(lua_State *L) { |
3338 | EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS); | 3423 | EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS); |
3339 | int nid; | 3424 | int nid; |
3340 | char txt[256]; | ||
3341 | size_t len; | ||
3342 | 3425 | ||
3343 | if (!(EVP_PKEY_get_default_digest_nid(key, &nid) > 0)) | 3426 | if (!(EVP_PKEY_get_default_digest_nid(key, &nid) > 0)) |
3344 | return auxL_error(L, auxL_EOPENSSL, "pkey:getDefaultDigestName"); | 3427 | return auxL_error(L, auxL_EOPENSSL, "pkey:getDefaultDigestName"); |
3345 | 3428 | ||
3346 | if (!(len = auxS_nid2txt(txt, sizeof txt, nid))) | 3429 | auxL_pushnid(L, nid); |
3347 | return auxL_error(L, auxL_EOPENSSL, "pkey:getDefaultDigestName"); | ||
3348 | if (len > sizeof txt) | ||
3349 | return auxL_error(L, EOVERFLOW, "pkey:getDefaultDigestName"); | ||
3350 | |||
3351 | lua_pushlstring(L, txt, len); | ||
3352 | 3430 | ||
3353 | return 1; | 3431 | return 1; |
3354 | } /* pk_getDefaultDigestName() */ | 3432 | } /* pk_getDefaultDigestName() */ |
@@ -5656,49 +5734,50 @@ static int xc_setPublicKey(lua_State *L) { | |||
5656 | 5734 | ||
5657 | 5735 | ||
5658 | static int xc_getPublicKeyDigest(lua_State *L) { | 5736 | static int xc_getPublicKeyDigest(lua_State *L) { |
5659 | ASN1_BIT_STRING *pk = X509_get0_pubkey_bitstr(checksimple(L, 1, X509_CERT_CLASS)); | 5737 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); |
5660 | const char *id = luaL_optstring(L, 2, "sha1"); | 5738 | EVP_PKEY *key; |
5661 | const EVP_MD *md; | 5739 | const EVP_MD *md; |
5740 | ASN1_BIT_STRING *bitstr; | ||
5662 | unsigned char digest[EVP_MAX_MD_SIZE]; | 5741 | unsigned char digest[EVP_MAX_MD_SIZE]; |
5663 | unsigned int len; | 5742 | unsigned int len; |
5664 | 5743 | ||
5665 | if (!(md = EVP_get_digestbyname(id))) | 5744 | if (!(key = X509_get_pubkey(crt))) |
5666 | return luaL_error(L, "x509.cert:getPublicKeyDigest: %s: invalid digest type", id); | 5745 | return luaL_argerror(L, 1, "no public key"); |
5746 | md = auxL_optdigest(L, 2, key, NULL); | ||
5747 | bitstr = X509_get0_pubkey_bitstr(crt); | ||
5667 | 5748 | ||
5668 | if (!EVP_Digest(pk->data, pk->length, digest, &len, md, NULL)) | 5749 | if (!EVP_Digest(bitstr->data, bitstr->length, digest, &len, md, NULL)) |
5669 | return auxL_error(L, auxL_EOPENSSL, "x509.cert:getPublicKeyDigest"); | 5750 | return auxL_error(L, auxL_EOPENSSL, "x509.cert:getPublicKeyDigest"); |
5670 | |||
5671 | lua_pushlstring(L, (char *)digest, len); | 5751 | lua_pushlstring(L, (char *)digest, len); |
5672 | 5752 | ||
5673 | return 1; | 5753 | return 1; |
5674 | } /* xc_getPublicKeyDigest() */ | 5754 | } /* xc_getPublicKeyDigest() */ |
5675 | 5755 | ||
5676 | 5756 | ||
5677 | static const EVP_MD *xc_signature(lua_State *L, int index, EVP_PKEY *key) { | 5757 | #if 0 |
5678 | const char *id; | 5758 | /* |
5679 | const EVP_MD *md; | 5759 | * TODO: X509_get_signature_type always seems to return NID_undef. Are we |
5760 | * using it wrong or is it broken? | ||
5761 | */ | ||
5762 | static int xc_getSignatureName(lua_State *L) { | ||
5763 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | ||
5680 | int nid; | 5764 | int nid; |
5681 | 5765 | ||
5682 | if ((id = luaL_optstring(L, index, NULL))) { | 5766 | if (NID_undef == (nid = X509_get_signature_type(crt))) |
5683 | if (!(md = EVP_get_digestbyname(id))) | 5767 | return 0; |
5684 | goto unknown; | 5768 | |
5685 | } else { | 5769 | auxL_pushnid(L, nid); |
5686 | if (!(EVP_PKEY_get_default_digest_nid(key, &nid) > 0)) | 5770 | |
5687 | goto unknown; | 5771 | return 1; |
5688 | if (!(md = EVP_get_digestbynid(nid))) | 5772 | } /* xc_getSignatureName() */ |
5689 | goto unknown; | 5773 | #endif |
5690 | } | ||
5691 | 5774 | ||
5692 | return md; | ||
5693 | unknown: | ||
5694 | return EVP_sha1(); | ||
5695 | } /* xc_signature() */ | ||
5696 | 5775 | ||
5697 | static int xc_sign(lua_State *L) { | 5776 | static int xc_sign(lua_State *L) { |
5698 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | 5777 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); |
5699 | EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS); | 5778 | EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS); |
5700 | 5779 | ||
5701 | if (!X509_sign(crt, key, xc_signature(L, 3, key))) | 5780 | if (!X509_sign(crt, key, auxL_optdigest(L, 3, key, NULL))) |
5702 | return auxL_error(L, auxL_EOPENSSL, "x509.cert:sign"); | 5781 | return auxL_error(L, auxL_EOPENSSL, "x509.cert:sign"); |
5703 | 5782 | ||
5704 | lua_pushboolean(L, 1); | 5783 | lua_pushboolean(L, 1); |
@@ -5838,6 +5917,9 @@ static const auxL_Reg xc_methods[] = { | |||
5838 | { "getPublicKey", &xc_getPublicKey }, | 5917 | { "getPublicKey", &xc_getPublicKey }, |
5839 | { "setPublicKey", &xc_setPublicKey }, | 5918 | { "setPublicKey", &xc_setPublicKey }, |
5840 | { "getPublicKeyDigest", &xc_getPublicKeyDigest }, | 5919 | { "getPublicKeyDigest", &xc_getPublicKeyDigest }, |
5920 | #if 0 | ||
5921 | { "getSignatureName", &xc_getSignatureName }, | ||
5922 | #endif | ||
5841 | { "sign", &xc_sign }, | 5923 | { "sign", &xc_sign }, |
5842 | { "text", &xc_text }, | 5924 | { "text", &xc_text }, |
5843 | { "tostring", &xc__tostring }, | 5925 | { "tostring", &xc__tostring }, |
@@ -6091,7 +6173,7 @@ static int xr_sign(lua_State *L) { | |||
6091 | X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); | 6173 | X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); |
6092 | EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS); | 6174 | EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS); |
6093 | 6175 | ||
6094 | if (!X509_REQ_sign(csr, key, xc_signature(L, 3, key))) | 6176 | if (!X509_REQ_sign(csr, key, auxL_optdigest(L, 3, key, NULL))) |
6095 | return auxL_error(L, auxL_EOPENSSL, "x509.csr:sign"); | 6177 | return auxL_error(L, auxL_EOPENSSL, "x509.csr:sign"); |
6096 | 6178 | ||
6097 | lua_pushboolean(L, 1); | 6179 | lua_pushboolean(L, 1); |
@@ -6466,7 +6548,7 @@ static int xx_sign(lua_State *L) { | |||
6466 | X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS); | 6548 | X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS); |
6467 | EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS); | 6549 | EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS); |
6468 | 6550 | ||
6469 | if (!X509_CRL_sign(crl, key, xc_signature(L, 3, key))) | 6551 | if (!X509_CRL_sign(crl, key, auxL_optdigest(L, 3, key, NULL))) |
6470 | return auxL_error(L, auxL_EOPENSSL, "x509.crl:sign"); | 6552 | return auxL_error(L, auxL_EOPENSSL, "x509.crl:sign"); |
6471 | 6553 | ||
6472 | lua_pushboolean(L, 1); | 6554 | lua_pushboolean(L, 1); |