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 /src | |
| 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
Diffstat (limited to 'src')
| -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); |
