summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Ahern <william@25thandclement.com>2016-11-01 15:19:00 -0700
committerWilliam Ahern <william@25thandclement.com>2016-11-01 15:19:00 -0700
commit95ad8770b7fc6e0441be52483a45311a98669518 (patch)
tree09b946b13896ad8f13e15ec83b1ff3773ddb68a8
parent8caed30aa43a9a8e5bb3333e9408cd29c14fbf15 (diff)
downloadluaossl-95ad8770b7fc6e0441be52483a45311a98669518.tar.gz
luaossl-95ad8770b7fc6e0441be52483a45311a98669518.tar.bz2
luaossl-95ad8770b7fc6e0441be52483a45311a98669518.zip
refactor xc_signature to auxL_optdigest
refactor xc_getPublicKeyDigestName to use auxL_optdigest closes issue #63
-rw-r--r--src/openssl.c145
1 files changed, 116 insertions, 29 deletions
diff --git a/src/openssl.c b/src/openssl.c
index fd392d7..ed88c3a 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -77,12 +77,34 @@
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_VER_FULL > 0 && _MSC_VER_FULL >= 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___ASSUME
101#define HAVE___ASSUME MSC_PREREQ(8,0,0)
102#endif
103
104#ifndef HAVE___BUILTIN_UNREACHABLE
105#define HAVE___BUILTIN_UNREACHABLE (GNUC_PREREQ(4,5,0) || __has_builtin(__builtin_unreachable))
106#endif
107
86#ifndef HAVE_ASN1_STRING_GET0_DATA 108#ifndef HAVE_ASN1_STRING_GET0_DATA
87#define HAVE_ASN1_STRING_GET0_DATA OPENSSL_PREREQ(1,1,0) 109#define HAVE_ASN1_STRING_GET0_DATA OPENSSL_PREREQ(1,1,0)
88#endif 110#endif
@@ -320,6 +342,13 @@
320#define NOTUSED 342#define NOTUSED
321#endif 343#endif
322 344
345#if HAVE___BUILTIN_UNREACHABLE
346#define NOTREACHED __builtin_unreachable()
347#elif HAVE___ASSUME
348#define NOTREACHED __assume(0)
349#else
350#define NOTREACHED (void)0
351#endif
323 352
324#define countof(a) (sizeof (a) / sizeof *(a)) 353#define countof(a) (sizeof (a) / sizeof *(a))
325#define endof(a) (&(a)[countof(a)]) 354#define endof(a) (&(a)[countof(a)])
@@ -714,6 +743,23 @@ static size_t auxS_obj2txt(void *dst, size_t lim, const ASN1_OBJECT *obj) {
714 return auxS_obj2id(dst, lim, obj); 743 return auxS_obj2id(dst, lim, obj);
715} /* auxS_obj2txt() */ 744} /* auxS_obj2txt() */
716 745
746static const EVP_MD *auxS_todigest(const char *name, EVP_PKEY *key, const EVP_MD *def) {
747 const EVP_MD *md;
748 int nid;
749
750 if (name) {
751 if ((md = EVP_get_digestbyname(name)))
752 return md;
753 } else if (key) {
754 if ((EVP_PKEY_get_default_digest_nid(key, &nid) > 0)) {
755 if ((md = EVP_get_digestbynid(nid)))
756 return md;
757 }
758 }
759
760 return def;
761} /* auxS_todigest() */
762
717static _Bool auxS_isoid(const char *txt) { 763static _Bool auxS_isoid(const char *txt) {
718 return (*txt >= '0' && *txt <= '9'); 764 return (*txt >= '0' && *txt <= '9');
719} /* auxS_isoid() */ 765} /* auxS_isoid() */
@@ -753,6 +799,11 @@ static _Bool auxS_txt2nid(int *nid, const char *txt) {
753 * 799 *
754 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 800 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
755 801
802static int auxL_absindex(lua_State *L, int *index) {
803 *index = lua_absindex(L, *index);
804 return *index;
805} /* auxL_absindex() */
806
756typedef int auxref_t; 807typedef int auxref_t;
757typedef int auxtype_t; 808typedef int auxtype_t;
758 809
@@ -1097,8 +1148,9 @@ static const char *auxL_pusherror(lua_State *L, int error, const char *fun) {
1097 1148
1098static int auxL_error(lua_State *L, int error, const char *fun) { 1149static int auxL_error(lua_State *L, int error, const char *fun) {
1099 auxL_pusherror(L, error, fun); 1150 auxL_pusherror(L, error, fun);
1100 1151 lua_error(L);
1101 return lua_error(L); 1152 NOTREACHED;
1153 return 0;
1102} /* auxL_error() */ 1154} /* auxL_error() */
1103 1155
1104static const char *auxL_pushnid(lua_State *L, int nid) { 1156static const char *auxL_pushnid(lua_State *L, int nid) {
@@ -1113,6 +1165,24 @@ static const char *auxL_pushnid(lua_State *L, int nid) {
1113 return lua_tostring(L, -1); 1165 return lua_tostring(L, -1);
1114} /* auxL_pushnid() */ 1166} /* auxL_pushnid() */
1115 1167
1168static const EVP_MD *auxL_optdigest(lua_State *L, int index, EVP_PKEY *key, const EVP_MD *def) {
1169 const char *name = luaL_optstring(L, auxL_absindex(L, &index), NULL);
1170 const EVP_MD *md;
1171
1172 if ((md = auxS_todigest(name, key, NULL)))
1173 return md;
1174
1175 if (name) {
1176 luaL_argerror(L, index, lua_pushfstring(L, "invalid digest type (%s)", name));
1177 NOTREACHED;
1178 } else if (key) {
1179 luaL_argerror(L, index, lua_pushfstring(L, "no digest type for key type (%d)", EVP_PKEY_base_id(key)));
1180 NOTREACHED;
1181 }
1182
1183 return def;
1184} /* auxL_optdigest() */
1185
1116 1186
1117/* 1187/*
1118 * dl - dynamically loaded module management 1188 * dl - dynamically loaded module management
@@ -3400,18 +3470,11 @@ static int pk_toPEM(lua_State *L) {
3400static int pk_getDefaultDigestName(lua_State *L) { 3470static int pk_getDefaultDigestName(lua_State *L) {
3401 EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS); 3471 EVP_PKEY *key = checksimple(L, 1, PKEY_CLASS);
3402 int nid; 3472 int nid;
3403 char txt[256];
3404 size_t len;
3405 3473
3406 if (!(EVP_PKEY_get_default_digest_nid(key, &nid) > 0)) 3474 if (!(EVP_PKEY_get_default_digest_nid(key, &nid) > 0))
3407 return auxL_error(L, auxL_EOPENSSL, "pkey:getDefaultDigestName"); 3475 return auxL_error(L, auxL_EOPENSSL, "pkey:getDefaultDigestName");
3408 3476
3409 if (!(len = auxS_nid2txt(txt, sizeof txt, nid))) 3477 auxL_pushnid(L, nid);
3410 return auxL_error(L, auxL_EOPENSSL, "pkey:getDefaultDigestName");
3411 if (len > sizeof txt)
3412 return auxL_error(L, EOVERFLOW, "pkey:getDefaultDigestName");
3413
3414 lua_pushlstring(L, txt, len);
3415 3478
3416 return 1; 3479 return 1;
3417} /* pk_getDefaultDigestName() */ 3480} /* pk_getDefaultDigestName() */
@@ -5730,6 +5793,7 @@ static int xc_setPublicKey(lua_State *L) {
5730} /* xc_setPublicKey() */ 5793} /* xc_setPublicKey() */
5731 5794
5732 5795
5796#if 0
5733static int xc_getPublicKeyDigest(lua_State *L) { 5797static int xc_getPublicKeyDigest(lua_State *L) {
5734 ASN1_BIT_STRING *pk = X509_get0_pubkey_bitstr(checksimple(L, 1, X509_CERT_CLASS)); 5798 ASN1_BIT_STRING *pk = X509_get0_pubkey_bitstr(checksimple(L, 1, X509_CERT_CLASS));
5735 const char *id = luaL_optstring(L, 2, "sha1"); 5799 const char *id = luaL_optstring(L, 2, "sha1");
@@ -5747,33 +5811,53 @@ static int xc_getPublicKeyDigest(lua_State *L) {
5747 5811
5748 return 1; 5812 return 1;
5749} /* xc_getPublicKeyDigest() */ 5813} /* xc_getPublicKeyDigest() */
5814#else
5815static int xc_getPublicKeyDigest(lua_State *L) {
5816 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
5817 EVP_PKEY *key;
5818 const EVP_MD *md;
5819 ASN1_BIT_STRING *bitstr;
5820 unsigned char digest[EVP_MAX_MD_SIZE];
5821 unsigned int len;
5750 5822
5823 if (!(key = X509_get_pubkey(crt)))
5824 return luaL_argerror(L, 1, "no public key");
5825 md = auxL_optdigest(L, 2, key, NULL);
5826 bitstr = X509_get0_pubkey_bitstr(crt);
5751 5827
5752static const EVP_MD *xc_signature(lua_State *L, int index, EVP_PKEY *key) { 5828 if (!EVP_Digest(bitstr->data, bitstr->length, digest, &len, md, NULL))
5753 const char *id; 5829 return auxL_error(L, auxL_EOPENSSL, "x509.cert:getPublicKeyDigest");
5754 const EVP_MD *md; 5830 lua_pushlstring(L, (char *)digest, len);
5831
5832 return 1;
5833} /* xc_getPublicKeyDigest() */
5834#endif
5835
5836
5837#if 0
5838/*
5839 * TODO: X509_get_signature_type always seems to return NID_undef. Are we
5840 * using it wrong or is it broken?
5841 */
5842static int xc_getSignatureName(lua_State *L) {
5843 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
5755 int nid; 5844 int nid;
5756 5845
5757 if ((id = luaL_optstring(L, index, NULL))) { 5846 if (NID_undef == (nid = X509_get_signature_type(crt)))
5758 if (!(md = EVP_get_digestbyname(id))) 5847 return 0;
5759 goto unknown; 5848
5760 } else { 5849 auxL_pushnid(L, nid);
5761 if (!(EVP_PKEY_get_default_digest_nid(key, &nid) > 0)) 5850
5762 goto unknown; 5851 return 1;
5763 if (!(md = EVP_get_digestbynid(nid))) 5852} /* xc_getSignatureName() */
5764 goto unknown; 5853#endif
5765 }
5766 5854
5767 return md;
5768unknown:
5769 return EVP_sha1();
5770} /* xc_signature() */
5771 5855
5772static int xc_sign(lua_State *L) { 5856static int xc_sign(lua_State *L) {
5773 X509 *crt = checksimple(L, 1, X509_CERT_CLASS); 5857 X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
5774 EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS); 5858 EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS);
5775 5859
5776 if (!X509_sign(crt, key, xc_signature(L, 3, key))) 5860 if (!X509_sign(crt, key, auxL_optdigest(L, 3, key, NULL)))
5777 return auxL_error(L, auxL_EOPENSSL, "x509.cert:sign"); 5861 return auxL_error(L, auxL_EOPENSSL, "x509.cert:sign");
5778 5862
5779 lua_pushboolean(L, 1); 5863 lua_pushboolean(L, 1);
@@ -5913,6 +5997,9 @@ static const auxL_Reg xc_methods[] = {
5913 { "getPublicKey", &xc_getPublicKey }, 5997 { "getPublicKey", &xc_getPublicKey },
5914 { "setPublicKey", &xc_setPublicKey }, 5998 { "setPublicKey", &xc_setPublicKey },
5915 { "getPublicKeyDigest", &xc_getPublicKeyDigest }, 5999 { "getPublicKeyDigest", &xc_getPublicKeyDigest },
6000#if 0
6001 { "getSignatureName", &xc_getSignatureName },
6002#endif
5916 { "sign", &xc_sign }, 6003 { "sign", &xc_sign },
5917 { "text", &xc_text }, 6004 { "text", &xc_text },
5918 { "tostring", &xc__tostring }, 6005 { "tostring", &xc__tostring },
@@ -6166,7 +6253,7 @@ static int xr_sign(lua_State *L) {
6166 X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS); 6253 X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS);
6167 EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS); 6254 EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS);
6168 6255
6169 if (!X509_REQ_sign(csr, key, xc_signature(L, 3, key))) 6256 if (!X509_REQ_sign(csr, key, auxL_optdigest(L, 3, key, NULL)))
6170 return auxL_error(L, auxL_EOPENSSL, "x509.csr:sign"); 6257 return auxL_error(L, auxL_EOPENSSL, "x509.csr:sign");
6171 6258
6172 lua_pushboolean(L, 1); 6259 lua_pushboolean(L, 1);
@@ -6541,7 +6628,7 @@ static int xx_sign(lua_State *L) {
6541 X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS); 6628 X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS);
6542 EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS); 6629 EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS);
6543 6630
6544 if (!X509_CRL_sign(crl, key, xc_signature(L, 3, key))) 6631 if (!X509_CRL_sign(crl, key, auxL_optdigest(L, 3, key, NULL)))
6545 return auxL_error(L, auxL_EOPENSSL, "x509.crl:sign"); 6632 return auxL_error(L, auxL_EOPENSSL, "x509.crl:sign");
6546 6633
6547 lua_pushboolean(L, 1); 6634 lua_pushboolean(L, 1);