diff options
author | daurnimator <quae@daurnimator.com> | 2017-04-04 16:29:15 +1000 |
---|---|---|
committer | daurnimator <quae@daurnimator.com> | 2017-04-04 17:27:01 +1000 |
commit | 59766e63abfeb30342d413777b507940a739cc97 (patch) | |
tree | eff376dfe6062a5e0cd4692767716fa08aca8f7c /src | |
parent | 62f401c31942d16c1b28ebb528ca0f444a2b9af3 (diff) | |
download | luaossl-59766e63abfeb30342d413777b507940a739cc97.tar.gz luaossl-59766e63abfeb30342d413777b507940a739cc97.tar.bz2 luaossl-59766e63abfeb30342d413777b507940a739cc97.zip |
Bind SSL_CTX_set_tlsext_servername_callback
Closes #84
Diffstat (limited to 'src')
-rw-r--r-- | src/compat52.h | 10 | ||||
-rw-r--r-- | src/openssl.c | 85 |
2 files changed, 91 insertions, 4 deletions
diff --git a/src/compat52.h b/src/compat52.h index 163aecb..9b0a48e 100644 --- a/src/compat52.h +++ b/src/compat52.h | |||
@@ -29,6 +29,16 @@ | |||
29 | 29 | ||
30 | #define lua_getfield(L, i, f) (lua_getfield(L, (i), (f)), lua_type(L, -1)) | 30 | #define lua_getfield(L, i, f) (lua_getfield(L, (i), (f)), lua_type(L, -1)) |
31 | 31 | ||
32 | static int lua_isinteger(lua_State *L, int index) { | ||
33 | if (lua_type(L, index) == LUA_TNUMBER) { | ||
34 | lua_Number n = lua_tonumber(L, index); | ||
35 | lua_Integer i = lua_tointeger(L, index); | ||
36 | if (i == n) | ||
37 | return 1; | ||
38 | } | ||
39 | return 0; | ||
40 | } | ||
41 | |||
32 | #endif | 42 | #endif |
33 | 43 | ||
34 | #if LUA_VERSION_NUM < 502 | 44 | #if LUA_VERSION_NUM < 502 |
diff --git a/src/openssl.c b/src/openssl.c index b0bc5f6..35ddaf7 100644 --- a/src/openssl.c +++ b/src/openssl.c | |||
@@ -261,6 +261,10 @@ | |||
261 | #define HAVE_SSL_CTX_SET_ALPN_SELECT_CB HAVE_SSL_CTX_SET_ALPN_PROTOS | 261 | #define HAVE_SSL_CTX_SET_ALPN_SELECT_CB HAVE_SSL_CTX_SET_ALPN_PROTOS |
262 | #endif | 262 | #endif |
263 | 263 | ||
264 | #ifndef HAVE_SSL_CTX_SET_TLSEXT_SERVERNAME_CALLBACK | ||
265 | #define HAVE_SSL_CTX_SET_TLSEXT_SERVERNAME_CALLBACK OPENSSL_PREREQ(1,0,0) | ||
266 | #endif | ||
267 | |||
264 | #ifndef HAVE_SSL_CTX_SET1_CERT_STORE | 268 | #ifndef HAVE_SSL_CTX_SET1_CERT_STORE |
265 | #define HAVE_SSL_CTX_SET1_CERT_STORE (HAVE_SSL_CTX_set1_cert_store || 0) /* backwards compatible with old macro name */ | 269 | #define HAVE_SSL_CTX_SET1_CERT_STORE (HAVE_SSL_CTX_set1_cert_store || 0) /* backwards compatible with old macro name */ |
266 | #endif | 270 | #endif |
@@ -678,6 +682,10 @@ static void *loadfield_udata(lua_State *L, int index, const char *k, const char | |||
678 | } /* loadfield_udata() */ | 682 | } /* loadfield_udata() */ |
679 | 683 | ||
680 | 684 | ||
685 | /* Forward declarations */ | ||
686 | static SSL *ssl_push(lua_State *, SSL *); | ||
687 | |||
688 | |||
681 | /* | 689 | /* |
682 | * Auxiliary C routines | 690 | * Auxiliary C routines |
683 | * | 691 | * |
@@ -1939,6 +1947,7 @@ struct ex_data { | |||
1939 | 1947 | ||
1940 | enum { | 1948 | enum { |
1941 | EX_SSL_CTX_ALPN_SELECT_CB, | 1949 | EX_SSL_CTX_ALPN_SELECT_CB, |
1950 | EX_SSL_CTX_TLSEXT_SERVERNAME_CB, | ||
1942 | }; | 1951 | }; |
1943 | 1952 | ||
1944 | static struct ex_type { | 1953 | static struct ex_type { |
@@ -1948,6 +1957,7 @@ static struct ex_type { | |||
1948 | int (*set_ex_data)(); | 1957 | int (*set_ex_data)(); |
1949 | } ex_type[] = { | 1958 | } ex_type[] = { |
1950 | [EX_SSL_CTX_ALPN_SELECT_CB] = { CRYPTO_EX_INDEX_SSL_CTX, -1, &SSL_CTX_get_ex_data, &SSL_CTX_set_ex_data }, | 1959 | [EX_SSL_CTX_ALPN_SELECT_CB] = { CRYPTO_EX_INDEX_SSL_CTX, -1, &SSL_CTX_get_ex_data, &SSL_CTX_set_ex_data }, |
1960 | [EX_SSL_CTX_TLSEXT_SERVERNAME_CB] = { CRYPTO_EX_INDEX_SSL_CTX, -1, &SSL_CTX_get_ex_data, &SSL_CTX_set_ex_data }, | ||
1951 | }; | 1961 | }; |
1952 | 1962 | ||
1953 | #if OPENSSL_PREREQ(1,1,0) | 1963 | #if OPENSSL_PREREQ(1,1,0) |
@@ -8028,9 +8038,8 @@ static int sx_setAlpnProtos(lua_State *L) { | |||
8028 | } /* sx_setAlpnProtos() */ | 8038 | } /* sx_setAlpnProtos() */ |
8029 | #endif | 8039 | #endif |
8030 | 8040 | ||
8031 | #if HAVE_SSL_CTX_SET_ALPN_SELECT_CB | ||
8032 | static SSL *ssl_push(lua_State *, SSL *); | ||
8033 | 8041 | ||
8042 | #if HAVE_SSL_CTX_SET_ALPN_SELECT_CB | ||
8034 | static int sx_setAlpnSelect_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *_ctx) { | 8043 | static int sx_setAlpnSelect_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *_ctx) { |
8035 | SSL_CTX *ctx = _ctx; | 8044 | SSL_CTX *ctx = _ctx; |
8036 | lua_State *L = NULL; | 8045 | lua_State *L = NULL; |
@@ -8125,6 +8134,74 @@ static int sx_setAlpnSelect(lua_State *L) { | |||
8125 | #endif | 8134 | #endif |
8126 | 8135 | ||
8127 | 8136 | ||
8137 | #if HAVE_SSL_CTX_SET_TLSEXT_SERVERNAME_CALLBACK | ||
8138 | static int sx_setHostnameCallback_cb(SSL *ssl, int *ad, void *_ctx) { | ||
8139 | SSL_CTX *ctx = _ctx; | ||
8140 | lua_State *L = NULL; | ||
8141 | size_t n; | ||
8142 | int otop, status, ret = SSL_TLSEXT_ERR_ALERT_FATAL; | ||
8143 | |||
8144 | *ad = SSL_AD_INTERNAL_ERROR; | ||
8145 | |||
8146 | /* expect at least one value: closure */ | ||
8147 | if ((n = ex_getdata(&L, EX_SSL_CTX_TLSEXT_SERVERNAME_CB, ctx)) < 1) | ||
8148 | return SSL_TLSEXT_ERR_ALERT_FATAL; | ||
8149 | |||
8150 | otop = lua_gettop(L) - n; | ||
8151 | |||
8152 | /* TODO: Install temporary panic handler to catch OOM errors */ | ||
8153 | |||
8154 | /* pass SSL object as 1st argument */ | ||
8155 | ssl_push(L, ssl); | ||
8156 | lua_insert(L, otop + 2); | ||
8157 | |||
8158 | if (LUA_OK != (status = lua_pcall(L, 1 + (n - 1), 2, 0))) | ||
8159 | goto done; | ||
8160 | |||
8161 | /* callback should return a boolean for OK/NOACK | ||
8162 | * or nil + an integer for a controlled error | ||
8163 | * everything else will be a fatal internal error | ||
8164 | */ | ||
8165 | if (lua_isboolean(L, -2)) { | ||
8166 | ret = lua_toboolean(L, -2) ? SSL_TLSEXT_ERR_OK : SSL_TLSEXT_ERR_NOACK; | ||
8167 | } else { | ||
8168 | ret = SSL_TLSEXT_ERR_ALERT_FATAL; | ||
8169 | if (lua_isnil(L, -2) && lua_isinteger(L, -1)) | ||
8170 | *ad = lua_tointeger(L, -1); | ||
8171 | } | ||
8172 | |||
8173 | done: | ||
8174 | lua_settop(L, otop); | ||
8175 | |||
8176 | return ret; | ||
8177 | } /* sx_setHostnameCallback_cb() */ | ||
8178 | |||
8179 | |||
8180 | static int sx_setHostnameCallback(lua_State *L) { | ||
8181 | SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS); | ||
8182 | int error; | ||
8183 | |||
8184 | luaL_checktype(L, 2, LUA_TFUNCTION); | ||
8185 | |||
8186 | if ((error = ex_setdata(L, EX_SSL_CTX_TLSEXT_SERVERNAME_CB, ctx, lua_gettop(L) - 1))) { | ||
8187 | if (error > 0) { | ||
8188 | return luaL_error(L, "unable to set hostname selection callback: %s", aux_strerror(error)); | ||
8189 | } else if (error == auxL_EOPENSSL && !ERR_peek_error()) { | ||
8190 | return luaL_error(L, "unable to set hostname selection callback: Unknown internal error"); | ||
8191 | } else { | ||
8192 | return auxL_error(L, error, "ssl.context:setAlpnSelect"); | ||
8193 | } | ||
8194 | } | ||
8195 | SSL_CTX_set_tlsext_servername_callback(ctx, sx_setHostnameCallback_cb); | ||
8196 | SSL_CTX_set_tlsext_servername_arg(ctx, ctx); | ||
8197 | |||
8198 | lua_pushboolean(L, 1); | ||
8199 | |||
8200 | return 1; | ||
8201 | } /* sx_setHostnameCallback() */ | ||
8202 | #endif | ||
8203 | |||
8204 | |||
8128 | int TLSEXT_STATUSTYPEs[] = { TLSEXT_STATUSTYPE_ocsp }; | 8205 | int TLSEXT_STATUSTYPEs[] = { TLSEXT_STATUSTYPE_ocsp }; |
8129 | const char *TLSEXT_STATUSTYPEs_names[] = { "ocsp", NULL }; | 8206 | const char *TLSEXT_STATUSTYPEs_names[] = { "ocsp", NULL }; |
8130 | #define checkTLSEXT_STATUSTYPE(L, idx) \ | 8207 | #define checkTLSEXT_STATUSTYPE(L, idx) \ |
@@ -8199,8 +8276,8 @@ static const auxL_Reg sx_methods[] = { | |||
8199 | #if HAVE_SSL_CTX_SET_ALPN_SELECT_CB | 8276 | #if HAVE_SSL_CTX_SET_ALPN_SELECT_CB |
8200 | { "setAlpnSelect", &sx_setAlpnSelect }, | 8277 | { "setAlpnSelect", &sx_setAlpnSelect }, |
8201 | #endif | 8278 | #endif |
8202 | #if HAVE_SSL_CTX_SET_TLSEXT_STATUS_TYPE | 8279 | #if HAVE_SSL_CTX_SET_TLSEXT_SERVERNAME_CALLBACK |
8203 | { "setTLSextStatusType", &sx_setTLSextStatusType }, | 8280 | { "setHostnameCallback", &sx_setHostnameCallback }, |
8204 | #endif | 8281 | #endif |
8205 | #if HAVE_SSL_CTX_GET_TLSEXT_STATUS_TYPE | 8282 | #if HAVE_SSL_CTX_GET_TLSEXT_STATUS_TYPE |
8206 | { "getTLSextStatusType", &sx_getTLSextStatusType }, | 8283 | { "getTLSextStatusType", &sx_getTLSextStatusType }, |