diff options
author | william <william@25thandclement.com> | 2015-04-17 19:09:28 -0700 |
---|---|---|
committer | william <william@25thandclement.com> | 2015-04-17 19:09:28 -0700 |
commit | 23eafb649ad3e5a8fec499986ecafc453901548a (patch) | |
tree | d328968585ca59e2e2936cfa969a6bf3dd841362 /src/openssl.c | |
parent | 551ef0b4d84767eaf0c9a88b7a297f19052218e1 (diff) | |
download | luaossl-23eafb649ad3e5a8fec499986ecafc453901548a.tar.gz luaossl-23eafb649ad3e5a8fec499986ecafc453901548a.tar.bz2 luaossl-23eafb649ad3e5a8fec499986ecafc453901548a.zip |
finish setAlpnSelect
Diffstat (limited to 'src/openssl.c')
-rw-r--r-- | src/openssl.c | 74 |
1 files changed, 56 insertions, 18 deletions
diff --git a/src/openssl.c b/src/openssl.c index 5872197..77cec55 100644 --- a/src/openssl.c +++ b/src/openssl.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <math.h> /* INFINITY fabs(3) floor(3) frexp(3) fmod(3) round(3) isfinite(3) */ | 30 | #include <math.h> /* INFINITY fabs(3) floor(3) frexp(3) fmod(3) round(3) isfinite(3) */ |
31 | #include <time.h> /* struct tm time_t strptime(3) time(2) */ | 31 | #include <time.h> /* struct tm time_t strptime(3) time(2) */ |
32 | #include <ctype.h> /* tolower(3) */ | 32 | #include <ctype.h> /* tolower(3) */ |
33 | #include <errno.h> /* ENOMEM ENOTSUP errno */ | 33 | #include <errno.h> /* ENOMEM ENOTSUP EOVERFLOW errno */ |
34 | #include <assert.h> /* assert */ | 34 | #include <assert.h> /* assert */ |
35 | 35 | ||
36 | #include <sys/types.h> /* ssize_t pid_t */ | 36 | #include <sys/types.h> /* ssize_t pid_t */ |
@@ -881,7 +881,7 @@ struct ex_state { | |||
881 | }; /* struct ex_state */ | 881 | }; /* struct ex_state */ |
882 | 882 | ||
883 | #ifndef EX_DATA_MAXARGS | 883 | #ifndef EX_DATA_MAXARGS |
884 | #define EX_DATA_MAXARGS 4 | 884 | #define EX_DATA_MAXARGS 8 |
885 | #endif | 885 | #endif |
886 | 886 | ||
887 | struct ex_data { | 887 | struct ex_data { |
@@ -1058,6 +1058,9 @@ static int ex_setdata(lua_State *L, int _type, void *obj, size_t n) { | |||
1058 | struct ex_data *data; | 1058 | struct ex_data *data; |
1059 | size_t i, j; | 1059 | size_t i, j; |
1060 | 1060 | ||
1061 | if (n > countof(data->arg)) | ||
1062 | return EOVERFLOW; | ||
1063 | |||
1061 | if ((data = type->get_ex_data(obj, type->index)) && data->state) { | 1064 | if ((data = type->get_ex_data(obj, type->index)) && data->state) { |
1062 | for (i = 0; i < countof(data->arg); i++) { | 1065 | for (i = 0; i < countof(data->arg); i++) { |
1063 | auxL_unref(L, &data->arg[i]); | 1066 | auxL_unref(L, &data->arg[i]); |
@@ -1069,7 +1072,7 @@ static int ex_setdata(lua_State *L, int _type, void *obj, size_t n) { | |||
1069 | return errno; | 1072 | return errno; |
1070 | 1073 | ||
1071 | if (!type->set_ex_data(obj, type->index, data)) | 1074 | if (!type->set_ex_data(obj, type->index, data)) |
1072 | return -1; | 1075 | return auxL_EOPENSSL; |
1073 | 1076 | ||
1074 | data->state = state; | 1077 | data->state = state; |
1075 | data->refs = 1; | 1078 | data->refs = 1; |
@@ -5139,37 +5142,64 @@ static SSL *ssl_push(lua_State *, SSL *); | |||
5139 | static int sx_setAlpnSelect_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *_ctx) { | 5142 | static int sx_setAlpnSelect_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *_ctx) { |
5140 | SSL_CTX *ctx = _ctx; | 5143 | SSL_CTX *ctx = _ctx; |
5141 | lua_State *L = NULL; | 5144 | lua_State *L = NULL; |
5142 | size_t n; | 5145 | size_t n, protolen, tmpsiz; |
5143 | int top, status; | 5146 | int otop, status; |
5147 | const void *proto; | ||
5148 | void *tmpbuf; | ||
5144 | 5149 | ||
5145 | if (0 == (n = ex_getdata(&L, EX_SSL_CTX_ALPN_SELECT_CB, ctx))) | 5150 | *out = NULL; |
5151 | *outlen = 0; | ||
5152 | |||
5153 | /* always expect function (1st) and return string buffer (Nth) */ | ||
5154 | if ((n = ex_getdata(&L, EX_SSL_CTX_ALPN_SELECT_CB, ctx)) < 2) | ||
5146 | return SSL_TLSEXT_ERR_ALERT_FATAL; | 5155 | return SSL_TLSEXT_ERR_ALERT_FATAL; |
5147 | 5156 | ||
5148 | top = lua_gettop(L) - n; | 5157 | otop = lua_gettop(L) - n; |
5149 | 5158 | ||
5150 | /* TODO: Install temporary panic handler to catch OOM errors */ | 5159 | /* TODO: Install temporary panic handler to catch OOM errors */ |
5151 | 5160 | ||
5152 | /* pass the SSL object as first argument */ | 5161 | /* pass SSL object as 1st argument */ |
5153 | ssl_push(L, ssl); | 5162 | ssl_push(L, ssl); |
5163 | lua_insert(L, otop + 3); | ||
5164 | |||
5165 | /* pass table of protocol names as 2nd argument */ | ||
5154 | pushprotos(L, in, inlen); | 5166 | pushprotos(L, in, inlen); |
5167 | lua_insert(L, otop + 4); | ||
5168 | |||
5169 | if (LUA_OK != (status = lua_pcall(L, 2 + (n - 2), 1, 0))) | ||
5170 | goto fatal; | ||
5171 | |||
5172 | /* did we get a string result? */ | ||
5173 | if (!(proto = lua_tolstring(L, -1, &protolen))) | ||
5174 | goto noack; | ||
5175 | |||
5176 | /* will it fit in our return buffer? */ | ||
5177 | if (!(tmpbuf = lua_touserdata(L, otop + 1))) | ||
5178 | goto fatal; | ||
5155 | 5179 | ||
5156 | /* TODO: lua_rotate ssl and protocols table into position. */ | 5180 | tmpsiz = lua_rawlen(L, otop + 1); |
5157 | 5181 | ||
5158 | if (LUA_OK != (status = lua_pcall(L, 2 + (n - 1), 1, 0))) | 5182 | if (protolen > tmpsiz) |
5159 | goto fatal; | 5183 | goto fatal; |
5160 | 5184 | ||
5161 | /* TODO: check return value */ | 5185 | memcpy(tmpbuf, proto, protolen); |
5162 | (void)out; (void)outlen; | 5186 | |
5187 | /* | ||
5188 | * NB: Our return buffer is anchored using the luaL_ref API, so even | ||
5189 | * once we pop the stack it will remain valid. | ||
5190 | */ | ||
5191 | *out = tmpbuf; | ||
5192 | *outlen = protolen; | ||
5163 | 5193 | ||
5164 | lua_settop(L, top); | 5194 | lua_settop(L, otop); |
5165 | 5195 | ||
5166 | return SSL_TLSEXT_ERR_OK; | 5196 | return SSL_TLSEXT_ERR_OK; |
5167 | fatal: | 5197 | fatal: |
5168 | lua_settop(L, top); | 5198 | lua_settop(L, otop); |
5169 | 5199 | ||
5170 | return SSL_TLSEXT_ERR_ALERT_FATAL; | 5200 | return SSL_TLSEXT_ERR_ALERT_FATAL; |
5171 | noack: | 5201 | noack: |
5172 | lua_settop(L, top); | 5202 | lua_settop(L, otop); |
5173 | 5203 | ||
5174 | return SSL_TLSEXT_ERR_NOACK; | 5204 | return SSL_TLSEXT_ERR_NOACK; |
5175 | } /* sx_setAlpnSelect_cb() */ | 5205 | } /* sx_setAlpnSelect_cb() */ |
@@ -5180,13 +5210,18 @@ static int sx_setAlpnSelect(lua_State *L) { | |||
5180 | int error; | 5210 | int error; |
5181 | 5211 | ||
5182 | luaL_checktype(L, 2, LUA_TFUNCTION); | 5212 | luaL_checktype(L, 2, LUA_TFUNCTION); |
5183 | if ((error = ex_setdata(L, EX_SSL_CTX_ALPN_SELECT_CB, ctx, 1))) { | 5213 | |
5214 | /* allocate space to store the selected protocol in our callback */ | ||
5215 | lua_newuserdata(L, UCHAR_MAX); | ||
5216 | lua_insert(L, 2); | ||
5217 | |||
5218 | if ((error = ex_setdata(L, EX_SSL_CTX_ALPN_SELECT_CB, ctx, lua_gettop(L) - 1))) { | ||
5184 | if (error > 0) { | 5219 | if (error > 0) { |
5185 | return luaL_error(L, "unable to set ALPN protocol selection callback: %s", aux_strerror(error)); | 5220 | return luaL_error(L, "unable to set ALPN protocol selection callback: %s", aux_strerror(error)); |
5186 | } else if (!ERR_peek_error()) { | 5221 | } else if (error == auxL_EOPENSSL && !ERR_peek_error()) { |
5187 | return luaL_error(L, "unable to set ALPN protocol selection callback: Unknown internal error"); | 5222 | return luaL_error(L, "unable to set ALPN protocol selection callback: Unknown internal error"); |
5188 | } else { | 5223 | } else { |
5189 | return auxL_error(L, auxL_EOPENSSL, "ssl.context:setAlpnSelect"); | 5224 | return auxL_error(L, error, "ssl.context:setAlpnSelect"); |
5190 | } | 5225 | } |
5191 | } | 5226 | } |
5192 | 5227 | ||
@@ -5225,6 +5260,9 @@ static const luaL_Reg sx_methods[] = { | |||
5225 | #if HAVE_SSL_CTX_SET_ALPN_PROTOS | 5260 | #if HAVE_SSL_CTX_SET_ALPN_PROTOS |
5226 | { "setAlpnProtos", &sx_setAlpnProtos }, | 5261 | { "setAlpnProtos", &sx_setAlpnProtos }, |
5227 | #endif | 5262 | #endif |
5263 | #if HAVE_SSL_CTX_SET_ALPN_SELECT_CB | ||
5264 | { "setAlpnSelect", &sx_setAlpnSelect }, | ||
5265 | #endif | ||
5228 | { NULL, NULL }, | 5266 | { NULL, NULL }, |
5229 | }; | 5267 | }; |
5230 | 5268 | ||