diff options
author | William Ahern <william@25thandclement.com> | 2016-11-01 15:19:00 -0700 |
---|---|---|
committer | William Ahern <william@25thandclement.com> | 2016-11-01 15:19:00 -0700 |
commit | 95ad8770b7fc6e0441be52483a45311a98669518 (patch) | |
tree | 09b946b13896ad8f13e15ec83b1ff3773ddb68a8 | |
parent | 8caed30aa43a9a8e5bb3333e9408cd29c14fbf15 (diff) | |
download | luaossl-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.c | 145 |
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 | ||
746 | static 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 | |||
717 | static _Bool auxS_isoid(const char *txt) { | 763 | static _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 | ||
802 | static int auxL_absindex(lua_State *L, int *index) { | ||
803 | *index = lua_absindex(L, *index); | ||
804 | return *index; | ||
805 | } /* auxL_absindex() */ | ||
806 | |||
756 | typedef int auxref_t; | 807 | typedef int auxref_t; |
757 | typedef int auxtype_t; | 808 | typedef int auxtype_t; |
758 | 809 | ||
@@ -1097,8 +1148,9 @@ static const char *auxL_pusherror(lua_State *L, int error, const char *fun) { | |||
1097 | 1148 | ||
1098 | static int auxL_error(lua_State *L, int error, const char *fun) { | 1149 | static 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 | ||
1104 | static const char *auxL_pushnid(lua_State *L, int nid) { | 1156 | static 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 | ||
1168 | static 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) { | |||
3400 | static int pk_getDefaultDigestName(lua_State *L) { | 3470 | static 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 | ||
5733 | static int xc_getPublicKeyDigest(lua_State *L) { | 5797 | static 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 | ||
5815 | static 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 | ||
5752 | static 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 | */ | ||
5842 | static 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; | ||
5768 | unknown: | ||
5769 | return EVP_sha1(); | ||
5770 | } /* xc_signature() */ | ||
5771 | 5855 | ||
5772 | static int xc_sign(lua_State *L) { | 5856 | static 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); |