summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordaurnimator <quae@daurnimator.com>2017-04-04 16:29:15 +1000
committerdaurnimator <quae@daurnimator.com>2017-04-04 17:27:01 +1000
commit59766e63abfeb30342d413777b507940a739cc97 (patch)
treeeff376dfe6062a5e0cd4692767716fa08aca8f7c
parent62f401c31942d16c1b28ebb528ca0f444a2b9af3 (diff)
downloadluaossl-59766e63abfeb30342d413777b507940a739cc97.tar.gz
luaossl-59766e63abfeb30342d413777b507940a739cc97.tar.bz2
luaossl-59766e63abfeb30342d413777b507940a739cc97.zip
Bind SSL_CTX_set_tlsext_servername_callback
Closes #84
-rw-r--r--src/compat52.h10
-rw-r--r--src/openssl.c85
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
32static 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 */
686static 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
1940enum { 1948enum {
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
1944static struct ex_type { 1953static 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
8032static SSL *ssl_push(lua_State *, SSL *);
8033 8041
8042#if HAVE_SSL_CTX_SET_ALPN_SELECT_CB
8034static int sx_setAlpnSelect_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *_ctx) { 8043static 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
8138static 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
8173done:
8174 lua_settop(L, otop);
8175
8176 return ret;
8177} /* sx_setHostnameCallback_cb() */
8178
8179
8180static 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
8128int TLSEXT_STATUSTYPEs[] = { TLSEXT_STATUSTYPE_ocsp }; 8205int TLSEXT_STATUSTYPEs[] = { TLSEXT_STATUSTYPE_ocsp };
8129const char *TLSEXT_STATUSTYPEs_names[] = { "ocsp", NULL }; 8206const 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 },