summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/openssl.c152
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
742static const EVP_MD *auxS_todigest(const char *name, EVP_PKEY *key, const EVP_MD *def);
743
709static _Bool auxS_isoid(const char *txt) { 744static _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
1093static int auxL_error(lua_State *L, int error, const char *fun) { 1128static 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
1099static const char *auxL_pushnid(lua_State *L, int nid) { 1135static 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
1147static 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
1733static 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
1756static 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) {
3337static int pk_getDefaultDigestName(lua_State *L) { 3422static 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
5658static int xc_getPublicKeyDigest(lua_State *L) { 5736static 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
5677static 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 */
5762static 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;
5693unknown:
5694 return EVP_sha1();
5695} /* xc_signature() */
5696 5775
5697static int xc_sign(lua_State *L) { 5776static 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);