diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compat52.h | 10 | ||||
-rw-r--r-- | src/openssl.c | 218 |
2 files changed, 191 insertions, 37 deletions
diff --git a/src/compat52.h b/src/compat52.h index 0057b3c..163aecb 100644 --- a/src/compat52.h +++ b/src/compat52.h | |||
@@ -23,6 +23,14 @@ | |||
23 | * USE OR OTHER DEALINGS IN THE SOFTWARE. | 23 | * USE OR OTHER DEALINGS IN THE SOFTWARE. |
24 | * ========================================================================== | 24 | * ========================================================================== |
25 | */ | 25 | */ |
26 | |||
27 | |||
28 | #if LUA_VERSION_NUM < 503 | ||
29 | |||
30 | #define lua_getfield(L, i, f) (lua_getfield(L, (i), (f)), lua_type(L, -1)) | ||
31 | |||
32 | #endif | ||
33 | |||
26 | #if LUA_VERSION_NUM < 502 | 34 | #if LUA_VERSION_NUM < 502 |
27 | 35 | ||
28 | #define LUA_OK 0 | 36 | #define LUA_OK 0 |
@@ -86,7 +94,7 @@ static void luaL_requiref(lua_State *L, const char *modname, lua_CFunction openf | |||
86 | lua_setfield(L, -2, modname); | 94 | lua_setfield(L, -2, modname); |
87 | 95 | ||
88 | lua_pop(L, 2); | 96 | lua_pop(L, 2); |
89 | 97 | ||
90 | if (glb) { | 98 | if (glb) { |
91 | lua_pushvalue(L, -1); | 99 | lua_pushvalue(L, -1); |
92 | lua_setglobal(L, modname); | 100 | lua_setglobal(L, modname); |
diff --git a/src/openssl.c b/src/openssl.c index e8dbead..e902edf 100644 --- a/src/openssl.c +++ b/src/openssl.c | |||
@@ -75,9 +75,7 @@ | |||
75 | #include <lualib.h> | 75 | #include <lualib.h> |
76 | #include <lauxlib.h> | 76 | #include <lauxlib.h> |
77 | 77 | ||
78 | #if LUA_VERSION_NUM < 502 | ||
79 | #include "compat52.h" | 78 | #include "compat52.h" |
80 | #endif | ||
81 | 79 | ||
82 | #define GNUC_2VER(M, m, p) (((M) * 10000) + ((m) * 100) + (p)) | 80 | #define GNUC_2VER(M, m, p) (((M) * 10000) + ((m) * 100) + (p)) |
83 | #define GNUC_PREREQ(M, m, p) (__GNUC__ > 0 && GNUC_2VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) >= GNUC_2VER((M), (m), (p))) | 81 | #define GNUC_PREREQ(M, m, p) (__GNUC__ > 0 && GNUC_2VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) >= GNUC_2VER((M), (m), (p))) |
@@ -315,6 +313,10 @@ | |||
315 | #define HAVE_SSLV2_SERVER_METHOD (!OPENSSL_PREREQ(1,1,0) && !defined OPENSSL_NO_SSL2) | 313 | #define HAVE_SSLV2_SERVER_METHOD (!OPENSSL_PREREQ(1,1,0) && !defined OPENSSL_NO_SSL2) |
316 | #endif | 314 | #endif |
317 | 315 | ||
316 | #ifndef HAVE_X509_GET_SIGNATURE_NID | ||
317 | #define HAVE_X509_GET_SIGNATURE_NID OPENSSL_PREREQ(1,0,2) | ||
318 | #endif | ||
319 | |||
318 | #ifndef HAVE_X509_STORE_REFERENCES | 320 | #ifndef HAVE_X509_STORE_REFERENCES |
319 | #define HAVE_X509_STORE_REFERENCES (!OPENSSL_PREREQ(1,1,0)) | 321 | #define HAVE_X509_STORE_REFERENCES (!OPENSSL_PREREQ(1,1,0)) |
320 | #endif | 322 | #endif |
@@ -1630,6 +1632,10 @@ static int compat_SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm) { | |||
1630 | #define X509_get0_ext(crt, i) X509_get_ext((crt), (i)) | 1632 | #define X509_get0_ext(crt, i) X509_get_ext((crt), (i)) |
1631 | #endif | 1633 | #endif |
1632 | 1634 | ||
1635 | #if !HAVE_X509_GET_SIGNATURE_NID | ||
1636 | #define X509_get_signature_nid(crt) OBJ_obj2nid((crt)->sig_alg->algorithm) | ||
1637 | #endif | ||
1638 | |||
1633 | #if !HAVE_X509_CRL_GET0_EXT | 1639 | #if !HAVE_X509_CRL_GET0_EXT |
1634 | #define X509_CRL_get0_ext(crt, i) X509_CRL_get_ext((crt), (i)) | 1640 | #define X509_CRL_get0_ext(crt, i) X509_CRL_get_ext((crt), (i)) |
1635 | #endif | 1641 | #endif |
@@ -3077,6 +3083,7 @@ static int pk_new(lua_State *L) { | |||
3077 | unsigned exp = 65537; | 3083 | unsigned exp = 65537; |
3078 | int curve = NID_X9_62_prime192v1; | 3084 | int curve = NID_X9_62_prime192v1; |
3079 | const char *id; | 3085 | const char *id; |
3086 | const char *dhparam = NULL; | ||
3080 | lua_Number n; | 3087 | lua_Number n; |
3081 | 3088 | ||
3082 | if (!lua_istable(L, 1)) | 3089 | if (!lua_istable(L, 1)) |
@@ -3118,6 +3125,9 @@ static int pk_new(lua_State *L) { | |||
3118 | luaL_argerror(L, 1, lua_pushfstring(L, "%s: invalid curve", id)); | 3125 | luaL_argerror(L, 1, lua_pushfstring(L, "%s: invalid curve", id)); |
3119 | } | 3126 | } |
3120 | 3127 | ||
3128 | /* dhparam field can contain a PEM encoded string. */ | ||
3129 | loadfield(L, 1, "dhparam", LUA_TSTRING, &dhparam); | ||
3130 | |||
3121 | creat: | 3131 | creat: |
3122 | if (!(*ud = EVP_PKEY_new())) | 3132 | if (!(*ud = EVP_PKEY_new())) |
3123 | return auxL_error(L, auxL_EOPENSSL, "pkey.new"); | 3133 | return auxL_error(L, auxL_EOPENSSL, "pkey.new"); |
@@ -3155,9 +3165,23 @@ creat: | |||
3155 | case EVP_PKEY_DH: { | 3165 | case EVP_PKEY_DH: { |
3156 | DH *dh; | 3166 | DH *dh; |
3157 | 3167 | ||
3158 | if (!(dh = DH_generate_parameters(bits, exp, 0, 0))) | 3168 | /* DH Parameter Generation can take a long time, therefore we look |
3169 | * at the "dhparam" field, provided by the user. | ||
3170 | * The "dhparam" field takes precedence over "bits" | ||
3171 | */ | ||
3172 | if (dhparam) { | ||
3173 | BIO *bio = BIO_new_mem_buf((void*)dhparam, strlen(dhparam)); | ||
3174 | if (!bio) | ||
3175 | return auxL_error(L, auxL_EOPENSSL, "pkey.new"); | ||
3176 | |||
3177 | dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); | ||
3178 | BIO_free(bio); | ||
3179 | if (!dh) | ||
3180 | return auxL_error(L, auxL_EOPENSSL, "pkey.new"); | ||
3181 | } else if (!(dh = DH_generate_parameters(bits, exp, 0, 0))) | ||
3159 | return auxL_error(L, auxL_EOPENSSL, "pkey.new"); | 3182 | return auxL_error(L, auxL_EOPENSSL, "pkey.new"); |
3160 | 3183 | ||
3184 | |||
3161 | if (!DH_generate_key(dh)) { | 3185 | if (!DH_generate_key(dh)) { |
3162 | DH_free(dh); | 3186 | DH_free(dh); |
3163 | return auxL_error(L, auxL_EOPENSSL, "pkey.new"); | 3187 | return auxL_error(L, auxL_EOPENSSL, "pkey.new"); |
@@ -4973,6 +4997,25 @@ static _Bool xe_new_isder(const char *value, _Bool *crit) { | |||
4973 | return 0; | 4997 | return 0; |
4974 | } /* xs_new_isder() */ | 4998 | } /* xs_new_isder() */ |
4975 | 4999 | ||
5000 | static CONF* loadconf(lua_State *L, int idx) { | ||
5001 | CONF *conf; | ||
5002 | size_t len; | ||
5003 | const char *cdata = luaL_checklstring(L, idx, &len); | ||
5004 | BIO *bio = getbio(L); | ||
5005 | if (BIO_write(bio, cdata, len) < 0) | ||
5006 | return NULL; | ||
5007 | |||
5008 | if (!(conf = NCONF_new(NULL))) | ||
5009 | return NULL; | ||
5010 | |||
5011 | if (!NCONF_load_bio(conf, bio, NULL)) { | ||
5012 | NCONF_free(conf); | ||
5013 | return NULL; | ||
5014 | } | ||
5015 | |||
5016 | return conf; | ||
5017 | } | ||
5018 | |||
4976 | static int xe_new(lua_State *L) { | 5019 | static int xe_new(lua_State *L) { |
4977 | const char *name = luaL_checkstring(L, 1); | 5020 | const char *name = luaL_checkstring(L, 1); |
4978 | const char *value = luaL_checkstring(L, 2); | 5021 | const char *value = luaL_checkstring(L, 2); |
@@ -4981,42 +5024,87 @@ static int xe_new(lua_State *L) { | |||
4981 | CONF *conf = NULL; | 5024 | CONF *conf = NULL; |
4982 | X509V3_CTX cbuf = { 0 }, *ctx = NULL; | 5025 | X509V3_CTX cbuf = { 0 }, *ctx = NULL; |
4983 | X509_EXTENSION **ud; | 5026 | X509_EXTENSION **ud; |
5027 | _Bool crit; | ||
4984 | 5028 | ||
4985 | lua_settop(L, 3); | 5029 | lua_settop(L, 3); |
4986 | ud = prepsimple(L, X509_EXT_CLASS); | 5030 | ud = prepsimple(L, X509_EXT_CLASS); |
4987 | 5031 | ||
4988 | if (!lua_isnil(L, 3)) { | 5032 | if (xe_new_isder(value, &crit)) { |
4989 | size_t len; | 5033 | size_t len; |
4990 | const char *cdata = luaL_checklstring(L, 3, &len); | 5034 | const char *cdata = lua_tolstring(L, 3, &len); |
4991 | _Bool crit; | 5035 | if (!(obj = OBJ_txt2obj(name, 0))) |
5036 | goto error; | ||
5037 | if (!(oct = ASN1_STRING_new())) | ||
5038 | goto error; | ||
5039 | if (!ASN1_STRING_set(oct, cdata, len)) | ||
5040 | goto error; | ||
5041 | if (!(*ud = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct))) | ||
5042 | goto error; | ||
4992 | 5043 | ||
4993 | if (xe_new_isder(value, &crit)) { | 5044 | ASN1_OBJECT_free(obj); |
4994 | if (!(obj = OBJ_txt2obj(name, 0))) | 5045 | ASN1_STRING_free(oct); |
4995 | goto error; | 5046 | |
4996 | if (!(oct = ASN1_STRING_new())) | 5047 | return 1; |
4997 | goto error; | 5048 | } |
4998 | if (!ASN1_STRING_set(oct, cdata, len)) | 5049 | |
4999 | goto error; | 5050 | switch (lua_type(L, 3)) { |
5000 | if (!(*ud = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct))) | 5051 | case LUA_TNONE: |
5052 | case LUA_TNIL: | ||
5053 | break; | ||
5054 | case LUA_TSTRING: { | ||
5055 | if (!(conf = loadconf(L, 3))) | ||
5056 | goto error; | ||
5057 | |||
5058 | ctx = &cbuf; | ||
5059 | X509V3_set_nconf(ctx, conf); | ||
5060 | break; | ||
5061 | } | ||
5062 | case LUA_TTABLE: { | ||
5063 | X509 *issuer = NULL; | ||
5064 | X509 *subject = NULL; | ||
5065 | X509_REQ *request = NULL; | ||
5066 | X509_CRL *crl = NULL; | ||
5067 | int flags = 0; | ||
5068 | |||
5069 | ctx = &cbuf; | ||
5070 | |||
5071 | if (lua_getfield(L, 3, "db") != LUA_TNIL) { | ||
5072 | if (!(conf = loadconf(L, -1))) | ||
5001 | goto error; | 5073 | goto error; |
5074 | X509V3_set_nconf(ctx, conf); | ||
5075 | } | ||
5076 | lua_pop(L, 1); | ||
5077 | |||
5078 | if (lua_getfield(L, 3, "issuer") != LUA_TNIL) { | ||
5079 | issuer = checksimple(L, -1, X509_CERT_CLASS); | ||
5080 | } | ||
5081 | lua_pop(L, 1); | ||
5002 | 5082 | ||
5003 | ASN1_OBJECT_free(obj); | 5083 | if (lua_getfield(L, 3, "subject") != LUA_TNIL) { |
5004 | ASN1_STRING_free(oct); | 5084 | subject = checksimple(L, -1, X509_CERT_CLASS); |
5085 | } | ||
5086 | lua_pop(L, 1); | ||
5005 | 5087 | ||
5006 | return 1; | 5088 | if (lua_getfield(L, 3, "request") != LUA_TNIL) { |
5089 | request = checksimple(L, -1, X509_CSR_CLASS); | ||
5007 | } | 5090 | } |
5091 | lua_pop(L, 1); | ||
5008 | 5092 | ||
5009 | BIO *bio = getbio(L); | 5093 | if (lua_getfield(L, 3, "crl") != LUA_TNIL) { |
5010 | if (BIO_puts(bio, cdata) < 0) | 5094 | crl = checksimple(L, -1, X509_CRL_CLASS); |
5011 | goto error; | 5095 | } |
5096 | lua_pop(L, 1); | ||
5012 | 5097 | ||
5013 | if (!(conf = NCONF_new(NULL))) | 5098 | if (lua_getfield(L, 3, "flags") != LUA_TNIL) { |
5014 | goto error; | 5099 | flags = luaL_checkinteger(L, -1); |
5015 | if (!NCONF_load_bio(conf, bio, NULL)) | 5100 | } |
5016 | goto error; | 5101 | lua_pop(L, 1); |
5017 | 5102 | ||
5018 | ctx = &cbuf; | 5103 | X509V3_set_ctx(ctx, issuer, subject, request, crl, flags); |
5019 | X509V3_set_nconf(ctx, conf); | 5104 | break; |
5105 | } | ||
5106 | default: | ||
5107 | return luaL_argerror(L, 3, "invalid extra parameter (expected string, table or nil)"); | ||
5020 | } | 5108 | } |
5021 | 5109 | ||
5022 | /* | 5110 | /* |
@@ -6066,23 +6154,17 @@ static int xc_getPublicKeyDigest(lua_State *L) { | |||
6066 | } /* xc_getPublicKeyDigest() */ | 6154 | } /* xc_getPublicKeyDigest() */ |
6067 | 6155 | ||
6068 | 6156 | ||
6069 | #if 0 | ||
6070 | /* | ||
6071 | * TODO: X509_get_signature_type always seems to return NID_undef. Are we | ||
6072 | * using it wrong or is it broken? | ||
6073 | */ | ||
6074 | static int xc_getSignatureName(lua_State *L) { | 6157 | static int xc_getSignatureName(lua_State *L) { |
6075 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); | 6158 | X509 *crt = checksimple(L, 1, X509_CERT_CLASS); |
6076 | int nid; | 6159 | int nid; |
6077 | 6160 | ||
6078 | if (NID_undef == (nid = X509_get_signature_type(crt))) | 6161 | if (NID_undef == (nid = X509_get_signature_nid(crt))) |
6079 | return 0; | 6162 | return 0; |
6080 | 6163 | ||
6081 | auxL_pushnid(L, nid); | 6164 | auxL_pushnid(L, nid); |
6082 | 6165 | ||
6083 | return 1; | 6166 | return 1; |
6084 | } /* xc_getSignatureName() */ | 6167 | } /* xc_getSignatureName() */ |
6085 | #endif | ||
6086 | 6168 | ||
6087 | 6169 | ||
6088 | static int xc_sign(lua_State *L) { | 6170 | static int xc_sign(lua_State *L) { |
@@ -6230,9 +6312,7 @@ static const auxL_Reg xc_methods[] = { | |||
6230 | { "getPublicKey", &xc_getPublicKey }, | 6312 | { "getPublicKey", &xc_getPublicKey }, |
6231 | { "setPublicKey", &xc_setPublicKey }, | 6313 | { "setPublicKey", &xc_setPublicKey }, |
6232 | { "getPublicKeyDigest", &xc_getPublicKeyDigest }, | 6314 | { "getPublicKeyDigest", &xc_getPublicKeyDigest }, |
6233 | #if 0 | ||
6234 | { "getSignatureName", &xc_getSignatureName }, | 6315 | { "getSignatureName", &xc_getSignatureName }, |
6235 | #endif | ||
6236 | { "sign", &xc_sign }, | 6316 | { "sign", &xc_sign }, |
6237 | { "text", &xc_text }, | 6317 | { "text", &xc_text }, |
6238 | { "tostring", &xc__tostring }, | 6318 | { "tostring", &xc__tostring }, |
@@ -6680,7 +6760,7 @@ static int xx_getNextUpdate(lua_State *L) { | |||
6680 | updateby = timeutc(time); | 6760 | updateby = timeutc(time); |
6681 | 6761 | ||
6682 | if (isfinite(updateby)) | 6762 | if (isfinite(updateby)) |
6683 | lua_pushnumber(L, 1); | 6763 | lua_pushnumber(L, updateby); |
6684 | else | 6764 | else |
6685 | lua_pushnil(L); | 6765 | lua_pushnil(L); |
6686 | 6766 | ||
@@ -6870,6 +6950,19 @@ static int xx_sign(lua_State *L) { | |||
6870 | } /* xx_sign() */ | 6950 | } /* xx_sign() */ |
6871 | 6951 | ||
6872 | 6952 | ||
6953 | static int xx_verify(lua_State *L) { | ||
6954 | X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS); | ||
6955 | EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS); | ||
6956 | |||
6957 | if (!X509_CRL_verify(crl, key)) | ||
6958 | return auxL_error(L, auxL_EOPENSSL, "x509.crl:verify"); | ||
6959 | |||
6960 | lua_pushboolean(L, 1); | ||
6961 | |||
6962 | return 1; | ||
6963 | } /* xx_verify() */ | ||
6964 | |||
6965 | |||
6873 | static int xx_text(lua_State *L) { | 6966 | static int xx_text(lua_State *L) { |
6874 | X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS); | 6967 | X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS); |
6875 | 6968 | ||
@@ -6939,6 +7032,7 @@ static const auxL_Reg xx_methods[] = { | |||
6939 | { "getExtension", &xx_getExtension }, | 7032 | { "getExtension", &xx_getExtension }, |
6940 | { "getExtensionCount", &xx_getExtensionCount }, | 7033 | { "getExtensionCount", &xx_getExtensionCount }, |
6941 | { "sign", &xx_sign }, | 7034 | { "sign", &xx_sign }, |
7035 | { "verify", &xx_verify }, | ||
6942 | { "text", &xx_text }, | 7036 | { "text", &xx_text }, |
6943 | { "tostring", &xx__tostring }, | 7037 | { "tostring", &xx__tostring }, |
6944 | { NULL, NULL }, | 7038 | { NULL, NULL }, |
@@ -7466,6 +7560,57 @@ static int p12_interpose(lua_State *L) { | |||
7466 | } /* p12_interpose() */ | 7560 | } /* p12_interpose() */ |
7467 | 7561 | ||
7468 | 7562 | ||
7563 | static int p12_parse(lua_State *L) { | ||
7564 | /* parse a p12 binary string and return the parts */ | ||
7565 | PKCS12 *p12; | ||
7566 | |||
7567 | /* gather input parameters */ | ||
7568 | size_t len; | ||
7569 | const char *blob = luaL_checklstring(L, 1, &len); | ||
7570 | const char *passphrase = luaL_optstring(L, 2, NULL); | ||
7571 | |||
7572 | /* prepare return values */ | ||
7573 | EVP_PKEY **ud_pkey = prepsimple(L, PKEY_CLASS); | ||
7574 | X509 **ud_cert = prepsimple(L, X509_CERT_CLASS); | ||
7575 | STACK_OF(X509) **ud_chain = prepsimple(L, X509_CHAIN_CLASS); | ||
7576 | /* Note: *ud_chain must be initialised to NULL, which prepsimple does. */ | ||
7577 | |||
7578 | /* read PKCS#12 data into OpenSSL memory buffer */ | ||
7579 | BIO *bio = BIO_new_mem_buf((void*)blob, len); | ||
7580 | if (!bio) | ||
7581 | return auxL_error(L, auxL_EOPENSSL, "pkcs12.parse"); | ||
7582 | p12 = d2i_PKCS12_bio(bio, NULL); | ||
7583 | BIO_free(bio); | ||
7584 | if (!p12) | ||
7585 | return auxL_error(L, auxL_EOPENSSL, "pkcs12.parse"); | ||
7586 | |||
7587 | /* the p12 pointer holds the data we're interested in */ | ||
7588 | int rc = PKCS12_parse(p12, passphrase, ud_pkey, ud_cert, ud_chain); | ||
7589 | PKCS12_free(p12); | ||
7590 | if (!rc) | ||
7591 | auxL_error(L, auxL_EOPENSSL, "pkcs12.parse"); | ||
7592 | |||
7593 | /* replace the return values by nil if the ud pointers are NULL */ | ||
7594 | if (*ud_pkey == NULL) { | ||
7595 | lua_pushnil(L); | ||
7596 | lua_replace(L, -4); | ||
7597 | } | ||
7598 | |||
7599 | if (*ud_cert == NULL) { | ||
7600 | lua_pushnil(L); | ||
7601 | lua_replace(L, -3); | ||
7602 | } | ||
7603 | |||
7604 | /* other certificates (a chain, STACK_OF(X509) *) */ | ||
7605 | if (*ud_chain == NULL) { | ||
7606 | lua_pop(L, 1); | ||
7607 | lua_pushnil(L); | ||
7608 | } | ||
7609 | |||
7610 | return 3; | ||
7611 | } /* p12_parse() */ | ||
7612 | |||
7613 | |||
7469 | static int p12__tostring(lua_State *L) { | 7614 | static int p12__tostring(lua_State *L) { |
7470 | PKCS12 *p12 = checksimple(L, 1, PKCS12_CLASS); | 7615 | PKCS12 *p12 = checksimple(L, 1, PKCS12_CLASS); |
7471 | BIO *bio = getbio(L); | 7616 | BIO *bio = getbio(L); |
@@ -7509,6 +7654,7 @@ static const auxL_Reg p12_metatable[] = { | |||
7509 | static const auxL_Reg p12_globals[] = { | 7654 | static const auxL_Reg p12_globals[] = { |
7510 | { "new", &p12_new }, | 7655 | { "new", &p12_new }, |
7511 | { "interpose", &p12_interpose }, | 7656 | { "interpose", &p12_interpose }, |
7657 | { "parse", &p12_parse }, | ||
7512 | { NULL, NULL }, | 7658 | { NULL, NULL }, |
7513 | }; | 7659 | }; |
7514 | 7660 | ||