summaryrefslogtreecommitdiff
path: root/src/openssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/openssl.c')
-rw-r--r--src/openssl.c200
1 files changed, 173 insertions, 27 deletions
diff --git a/src/openssl.c b/src/openssl.c
index dd406bc..ab729d4 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -74,9 +74,7 @@
74#include <lualib.h> 74#include <lualib.h>
75#include <lauxlib.h> 75#include <lauxlib.h>
76 76
77#if LUA_VERSION_NUM < 502
78#include "compat52.h" 77#include "compat52.h"
79#endif
80 78
81#define GNUC_2VER(M, m, p) (((M) * 10000) + ((m) * 100) + (p)) 79#define GNUC_2VER(M, m, p) (((M) * 10000) + ((m) * 100) + (p))
82#define GNUC_PREREQ(M, m, p) (__GNUC__ > 0 && GNUC_2VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) >= GNUC_2VER((M), (m), (p))) 80#define GNUC_PREREQ(M, m, p) (__GNUC__ > 0 && GNUC_2VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) >= GNUC_2VER((M), (m), (p)))
@@ -3070,6 +3068,7 @@ static int pk_new(lua_State *L) {
3070 unsigned exp = 65537; 3068 unsigned exp = 65537;
3071 int curve = NID_X9_62_prime192v1; 3069 int curve = NID_X9_62_prime192v1;
3072 const char *id; 3070 const char *id;
3071 const char *dhparam = NULL;
3073 lua_Number n; 3072 lua_Number n;
3074 3073
3075 if (!lua_istable(L, 1)) 3074 if (!lua_istable(L, 1))
@@ -3111,6 +3110,9 @@ static int pk_new(lua_State *L) {
3111 luaL_argerror(L, 1, lua_pushfstring(L, "%s: invalid curve", id)); 3110 luaL_argerror(L, 1, lua_pushfstring(L, "%s: invalid curve", id));
3112 } 3111 }
3113 3112
3113 /* dhparam field can contain a PEM encoded string. */
3114 loadfield(L, 1, "dhparam", LUA_TSTRING, &dhparam);
3115
3114creat: 3116creat:
3115 if (!(*ud = EVP_PKEY_new())) 3117 if (!(*ud = EVP_PKEY_new()))
3116 return auxL_error(L, auxL_EOPENSSL, "pkey.new"); 3118 return auxL_error(L, auxL_EOPENSSL, "pkey.new");
@@ -3148,9 +3150,23 @@ creat:
3148 case EVP_PKEY_DH: { 3150 case EVP_PKEY_DH: {
3149 DH *dh; 3151 DH *dh;
3150 3152
3151 if (!(dh = DH_generate_parameters(bits, exp, 0, 0))) 3153 /* DH Parameter Generation can take a long time, therefore we look
3154 * at the "dhparam" field, provided by the user.
3155 * The "dhparam" field takes precedence over "bits"
3156 */
3157 if (dhparam) {
3158 BIO *bio = BIO_new_mem_buf((void*)dhparam, strlen(dhparam));
3159 if (!bio)
3160 return auxL_error(L, auxL_EOPENSSL, "pkey.new");
3161
3162 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
3163 BIO_free(bio);
3164 if (!dh)
3165 return auxL_error(L, auxL_EOPENSSL, "pkey.new");
3166 } else if (!(dh = DH_generate_parameters(bits, exp, 0, 0)))
3152 return auxL_error(L, auxL_EOPENSSL, "pkey.new"); 3167 return auxL_error(L, auxL_EOPENSSL, "pkey.new");
3153 3168
3169
3154 if (!DH_generate_key(dh)) { 3170 if (!DH_generate_key(dh)) {
3155 DH_free(dh); 3171 DH_free(dh);
3156 return auxL_error(L, auxL_EOPENSSL, "pkey.new"); 3172 return auxL_error(L, auxL_EOPENSSL, "pkey.new");
@@ -4966,6 +4982,25 @@ static _Bool xe_new_isder(const char *value, _Bool *crit) {
4966 return 0; 4982 return 0;
4967} /* xs_new_isder() */ 4983} /* xs_new_isder() */
4968 4984
4985static CONF* loadconf(lua_State *L, int idx) {
4986 CONF *conf;
4987 size_t len;
4988 const char *cdata = luaL_checklstring(L, idx, &len);
4989 BIO *bio = getbio(L);
4990 if (BIO_write(bio, cdata, len) < 0)
4991 return NULL;
4992
4993 if (!(conf = NCONF_new(NULL)))
4994 return NULL;
4995
4996 if (!NCONF_load_bio(conf, bio, NULL)) {
4997 NCONF_free(conf);
4998 return NULL;
4999 }
5000
5001 return conf;
5002}
5003
4969static int xe_new(lua_State *L) { 5004static int xe_new(lua_State *L) {
4970 const char *name = luaL_checkstring(L, 1); 5005 const char *name = luaL_checkstring(L, 1);
4971 const char *value = luaL_checkstring(L, 2); 5006 const char *value = luaL_checkstring(L, 2);
@@ -4974,42 +5009,87 @@ static int xe_new(lua_State *L) {
4974 CONF *conf = NULL; 5009 CONF *conf = NULL;
4975 X509V3_CTX cbuf = { 0 }, *ctx = NULL; 5010 X509V3_CTX cbuf = { 0 }, *ctx = NULL;
4976 X509_EXTENSION **ud; 5011 X509_EXTENSION **ud;
5012 _Bool crit;
4977 5013
4978 lua_settop(L, 3); 5014 lua_settop(L, 3);
4979 ud = prepsimple(L, X509_EXT_CLASS); 5015 ud = prepsimple(L, X509_EXT_CLASS);
4980 5016
4981 if (!lua_isnil(L, 3)) { 5017 if (xe_new_isder(value, &crit)) {
4982 size_t len; 5018 size_t len;
4983 const char *cdata = luaL_checklstring(L, 3, &len); 5019 const char *cdata = lua_tolstring(L, 3, &len);
4984 _Bool crit; 5020 if (!(obj = OBJ_txt2obj(name, 0)))
5021 goto error;
5022 if (!(oct = ASN1_STRING_new()))
5023 goto error;
5024 if (!ASN1_STRING_set(oct, cdata, len))
5025 goto error;
5026 if (!(*ud = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct)))
5027 goto error;
4985 5028
4986 if (xe_new_isder(value, &crit)) { 5029 ASN1_OBJECT_free(obj);
4987 if (!(obj = OBJ_txt2obj(name, 0))) 5030 ASN1_STRING_free(oct);
4988 goto error; 5031
4989 if (!(oct = ASN1_STRING_new())) 5032 return 1;
4990 goto error; 5033 }
4991 if (!ASN1_STRING_set(oct, cdata, len)) 5034
4992 goto error; 5035 switch (lua_type(L, 3)) {
4993 if (!(*ud = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct))) 5036 case LUA_TNONE:
5037 case LUA_TNIL:
5038 break;
5039 case LUA_TSTRING: {
5040 if (!(conf = loadconf(L, 3)))
5041 goto error;
5042
5043 ctx = &cbuf;
5044 X509V3_set_nconf(ctx, conf);
5045 break;
5046 }
5047 case LUA_TTABLE: {
5048 X509 *issuer = NULL;
5049 X509 *subject = NULL;
5050 X509_REQ *request = NULL;
5051 X509_CRL *crl = NULL;
5052 int flags = 0;
5053
5054 ctx = &cbuf;
5055
5056 if (lua_getfield(L, 3, "db") != LUA_TNIL) {
5057 if (!(conf = loadconf(L, -1)))
4994 goto error; 5058 goto error;
5059 X509V3_set_nconf(ctx, conf);
5060 }
5061 lua_pop(L, 1);
5062
5063 if (lua_getfield(L, 3, "issuer") != LUA_TNIL) {
5064 issuer = checksimple(L, -1, X509_CERT_CLASS);
5065 }
5066 lua_pop(L, 1);
4995 5067
4996 ASN1_OBJECT_free(obj); 5068 if (lua_getfield(L, 3, "subject") != LUA_TNIL) {
4997 ASN1_STRING_free(oct); 5069 subject = checksimple(L, -1, X509_CERT_CLASS);
5070 }
5071 lua_pop(L, 1);
4998 5072
4999 return 1; 5073 if (lua_getfield(L, 3, "request") != LUA_TNIL) {
5074 request = checksimple(L, -1, X509_CSR_CLASS);
5000 } 5075 }
5076 lua_pop(L, 1);
5001 5077
5002 BIO *bio = getbio(L); 5078 if (lua_getfield(L, 3, "crl") != LUA_TNIL) {
5003 if (BIO_puts(bio, cdata) < 0) 5079 crl = checksimple(L, -1, X509_CRL_CLASS);
5004 goto error; 5080 }
5081 lua_pop(L, 1);
5005 5082
5006 if (!(conf = NCONF_new(NULL))) 5083 if (lua_getfield(L, 3, "flags") != LUA_TNIL) {
5007 goto error; 5084 flags = luaL_checkinteger(L, -1);
5008 if (!NCONF_load_bio(conf, bio, NULL)) 5085 }
5009 goto error; 5086 lua_pop(L, 1);
5010 5087
5011 ctx = &cbuf; 5088 X509V3_set_ctx(ctx, issuer, subject, request, crl, flags);
5012 X509V3_set_nconf(ctx, conf); 5089 break;
5090 }
5091 default:
5092 return luaL_argerror(L, 3, "invalid extra parameter (expected string, table or nil)");
5013 } 5093 }
5014 5094
5015 /* 5095 /*
@@ -6630,7 +6710,7 @@ static int xx_getNextUpdate(lua_State *L) {
6630 updateby = timeutc(time); 6710 updateby = timeutc(time);
6631 6711
6632 if (isfinite(updateby)) 6712 if (isfinite(updateby))
6633 lua_pushnumber(L, 1); 6713 lua_pushnumber(L, updateby);
6634 else 6714 else
6635 lua_pushnil(L); 6715 lua_pushnil(L);
6636 6716
@@ -6820,6 +6900,19 @@ static int xx_sign(lua_State *L) {
6820} /* xx_sign() */ 6900} /* xx_sign() */
6821 6901
6822 6902
6903static int xx_verify(lua_State *L) {
6904 X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS);
6905 EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS);
6906
6907 if (!X509_CRL_verify(crl, key))
6908 return auxL_error(L, auxL_EOPENSSL, "x509.crl:verify");
6909
6910 lua_pushboolean(L, 1);
6911
6912 return 1;
6913} /* xx_verify() */
6914
6915
6823static int xx_text(lua_State *L) { 6916static int xx_text(lua_State *L) {
6824 X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS); 6917 X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS);
6825 6918
@@ -6889,6 +6982,7 @@ static const auxL_Reg xx_methods[] = {
6889 { "getExtension", &xx_getExtension }, 6982 { "getExtension", &xx_getExtension },
6890 { "getExtensionCount", &xx_getExtensionCount }, 6983 { "getExtensionCount", &xx_getExtensionCount },
6891 { "sign", &xx_sign }, 6984 { "sign", &xx_sign },
6985 { "verify", &xx_verify },
6892 { "text", &xx_text }, 6986 { "text", &xx_text },
6893 { "tostring", &xx__tostring }, 6987 { "tostring", &xx__tostring },
6894 { NULL, NULL }, 6988 { NULL, NULL },
@@ -7416,6 +7510,57 @@ static int p12_interpose(lua_State *L) {
7416} /* p12_interpose() */ 7510} /* p12_interpose() */
7417 7511
7418 7512
7513static int p12_parse(lua_State *L) {
7514 /* parse a p12 binary string and return the parts */
7515 PKCS12 *p12;
7516
7517 /* gather input parameters */
7518 size_t len;
7519 const char *blob = luaL_checklstring(L, 1, &len);
7520 const char *passphrase = luaL_optstring(L, 2, NULL);
7521
7522 /* prepare return values */
7523 EVP_PKEY **ud_pkey = prepsimple(L, PKEY_CLASS);
7524 X509 **ud_cert = prepsimple(L, X509_CERT_CLASS);
7525 STACK_OF(X509) **ud_chain = prepsimple(L, X509_CHAIN_CLASS);
7526 /* Note: *ud_chain must be initialised to NULL, which prepsimple does. */
7527
7528 /* read PKCS#12 data into OpenSSL memory buffer */
7529 BIO *bio = BIO_new_mem_buf((void*)blob, len);
7530 if (!bio)
7531 return auxL_error(L, auxL_EOPENSSL, "pkcs12.parse");
7532 p12 = d2i_PKCS12_bio(bio, NULL);
7533 BIO_free(bio);
7534 if (!p12)
7535 return auxL_error(L, auxL_EOPENSSL, "pkcs12.parse");
7536
7537 /* the p12 pointer holds the data we're interested in */
7538 int rc = PKCS12_parse(p12, passphrase, ud_pkey, ud_cert, ud_chain);
7539 PKCS12_free(p12);
7540 if (!rc)
7541 auxL_error(L, auxL_EOPENSSL, "pkcs12.parse");
7542
7543 /* replace the return values by nil if the ud pointers are NULL */
7544 if (*ud_pkey == NULL) {
7545 lua_pushnil(L);
7546 lua_replace(L, -4);
7547 }
7548
7549 if (*ud_cert == NULL) {
7550 lua_pushnil(L);
7551 lua_replace(L, -3);
7552 }
7553
7554 /* other certificates (a chain, STACK_OF(X509) *) */
7555 if (*ud_chain == NULL) {
7556 lua_pop(L, 1);
7557 lua_pushnil(L);
7558 }
7559
7560 return 3;
7561} /* p12_parse() */
7562
7563
7419static int p12__tostring(lua_State *L) { 7564static int p12__tostring(lua_State *L) {
7420 PKCS12 *p12 = checksimple(L, 1, PKCS12_CLASS); 7565 PKCS12 *p12 = checksimple(L, 1, PKCS12_CLASS);
7421 BIO *bio = getbio(L); 7566 BIO *bio = getbio(L);
@@ -7459,6 +7604,7 @@ static const auxL_Reg p12_metatable[] = {
7459static const auxL_Reg p12_globals[] = { 7604static const auxL_Reg p12_globals[] = {
7460 { "new", &p12_new }, 7605 { "new", &p12_new },
7461 { "interpose", &p12_interpose }, 7606 { "interpose", &p12_interpose },
7607 { "parse", &p12_parse },
7462 { NULL, NULL }, 7608 { NULL, NULL },
7463}; 7609};
7464 7610