summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compat52.h10
-rw-r--r--src/openssl.c218
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
3121creat: 3131creat:
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
5000static 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
4976static int xe_new(lua_State *L) { 5019static 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 */
6074static int xc_getSignatureName(lua_State *L) { 6157static 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
6088static int xc_sign(lua_State *L) { 6170static 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
6953static 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
6873static int xx_text(lua_State *L) { 6966static 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
7563static 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
7469static int p12__tostring(lua_State *L) { 7614static 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[] = {
7509static const auxL_Reg p12_globals[] = { 7654static 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