diff options
Diffstat (limited to 'src/openssl.c')
-rw-r--r-- | src/openssl.c | 200 |
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 | |||
3114 | creat: | 3116 | creat: |
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 | ||
4985 | static 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 | |||
4969 | static int xe_new(lua_State *L) { | 5004 | static 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 | ||
6903 | static 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 | |||
6823 | static int xx_text(lua_State *L) { | 6916 | static 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 | ||
7513 | static 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 | |||
7419 | static int p12__tostring(lua_State *L) { | 7564 | static 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[] = { | |||
7459 | static const auxL_Reg p12_globals[] = { | 7604 | static 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 | ||