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 | |
| parent | 62f401c31942d16c1b28ebb528ca0f444a2b9af3 (diff) | |
| download | luaossl-59766e63abfeb30342d413777b507940a739cc97.tar.gz luaossl-59766e63abfeb30342d413777b507940a739cc97.tar.bz2 luaossl-59766e63abfeb30342d413777b507940a739cc97.zip | |
Bind SSL_CTX_set_tlsext_servername_callback
Closes #84
| -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 }, |
