diff options
| author | william <william@25thandclement.com> | 2015-03-05 14:57:45 -0800 |
|---|---|---|
| committer | william <william@25thandclement.com> | 2015-03-05 14:57:45 -0800 |
| commit | afeb65d5c21019132a9b7759f864f19e0ad0df43 (patch) | |
| tree | 06e6842ba6444d1765a344800163d09f5e5c30be /src | |
| parent | fe19dfb57495c54c16edbeb52eae64b01404364f (diff) | |
| download | luaossl-afeb65d5c21019132a9b7759f864f19e0ad0df43.tar.gz luaossl-afeb65d5c21019132a9b7759f864f19e0ad0df43.tar.bz2 luaossl-afeb65d5c21019132a9b7759f864f19e0ad0df43.zip | |
add openssl.ssl:setAlpnProtos
Diffstat (limited to 'src')
| -rw-r--r-- | src/openssl.c | 106 |
1 files changed, 83 insertions, 23 deletions
diff --git a/src/openssl.c b/src/openssl.c index 2dee037..773930b 100644 --- a/src/openssl.c +++ b/src/openssl.c | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | #ifndef LUAOSSL_H | 26 | #ifndef LUAOSSL_H |
| 27 | #define LUAOSSL_H | 27 | #define LUAOSSL_H |
| 28 | 28 | ||
| 29 | #include <limits.h> /* INT_MAX INT_MIN */ | 29 | #include <limits.h> /* INT_MAX INT_MIN UCHAR_MAX */ |
| 30 | #include <stdint.h> /* uintptr_t */ | 30 | #include <stdint.h> /* uintptr_t */ |
| 31 | #include <string.h> /* memset(3) strerror_r(3) */ | 31 | #include <string.h> /* memset(3) strerror_r(3) */ |
| 32 | #include <strings.h> /* strcasecmp(3) */ | 32 | #include <strings.h> /* strcasecmp(3) */ |
| @@ -87,6 +87,10 @@ | |||
| 87 | #define HAVE_SSL_CTX_SET_ALPN_PROTOS (OPENSSL_VERSION_NUMBER >= 0x1000200fL) | 87 | #define HAVE_SSL_CTX_SET_ALPN_PROTOS (OPENSSL_VERSION_NUMBER >= 0x1000200fL) |
| 88 | #endif | 88 | #endif |
| 89 | 89 | ||
| 90 | #ifndef HAVE_SSL_SET_ALPN_PROTOS | ||
| 91 | #define HAVE_SSL_SET_ALPN_PROTOS HAVE_SSL_CTX_SET_ALPN_PROTOS | ||
| 92 | #endif | ||
| 93 | |||
| 90 | #ifndef HAVE_SSL_GET0_ALPN_SELECTED | 94 | #ifndef HAVE_SSL_GET0_ALPN_SELECTED |
| 91 | #define HAVE_SSL_GET0_ALPN_SELECTED HAVE_SSL_CTX_SET_ALPN_PROTOS | 95 | #define HAVE_SSL_GET0_ALPN_SELECTED HAVE_SSL_CTX_SET_ALPN_PROTOS |
| 92 | #endif | 96 | #endif |
| @@ -346,6 +350,45 @@ static int optencoding(lua_State *L, int index, const char *def, int allow) { | |||
| 346 | } /* optencoding() */ | 350 | } /* optencoding() */ |
| 347 | 351 | ||
| 348 | 352 | ||
| 353 | static _Bool rawgeti(lua_State *L, int index, int n) { | ||
| 354 | lua_rawgeti(L, index, n); | ||
| 355 | |||
| 356 | if (lua_isnil(L, -1)) { | ||
| 357 | lua_pop(L, 1); | ||
| 358 | |||
| 359 | return 0; | ||
| 360 | } else { | ||
| 361 | return 1; | ||
| 362 | } | ||
| 363 | } /* rawgeti() */ | ||
| 364 | |||
| 365 | |||
| 366 | /* check ALPN protocols and add to buffer of length-prefixed strings */ | ||
| 367 | static void checkprotos(luaL_Buffer *B, lua_State *L, int index) { | ||
| 368 | int n; | ||
| 369 | |||
| 370 | luaL_checktype(L, index, LUA_TTABLE); | ||
| 371 | |||
| 372 | for (n = 1; rawgeti(L, index, n); n++) { | ||
| 373 | const char *tmp; | ||
| 374 | size_t len; | ||
| 375 | |||
| 376 | switch (lua_type(L, -1)) { | ||
| 377 | case LUA_TSTRING: | ||
| 378 | break; | ||
| 379 | default: | ||
| 380 | luaL_argerror(L, index, "array of strings expected"); | ||
| 381 | } | ||
| 382 | |||
| 383 | tmp = luaL_checklstring(L, -1, &len); | ||
| 384 | luaL_argcheck(L, len > 0 && len <= UCHAR_MAX, index, "proto string length invalid"); | ||
| 385 | luaL_addchar(B, (unsigned char)len); | ||
| 386 | luaL_addlstring(B, tmp, len); | ||
| 387 | lua_pop(L, 1); | ||
| 388 | } | ||
| 389 | } /* checkprotos() */ | ||
| 390 | |||
| 391 | |||
| 349 | static _Bool getfield(lua_State *L, int index, const char *k) { | 392 | static _Bool getfield(lua_State *L, int index, const char *k) { |
| 350 | lua_getfield(L, index, k); | 393 | lua_getfield(L, index, k); |
| 351 | 394 | ||
| @@ -4524,34 +4567,16 @@ static int sx_setEphemeralKey(lua_State *L) { | |||
| 4524 | return 1; | 4567 | return 1; |
| 4525 | } /* sx_setEphemeralKey() */ | 4568 | } /* sx_setEphemeralKey() */ |
| 4526 | 4569 | ||
| 4570 | |||
| 4527 | #if HAVE_SSL_CTX_SET_ALPN_PROTOS | 4571 | #if HAVE_SSL_CTX_SET_ALPN_PROTOS |
| 4528 | static int sx_setAlpnProtos(lua_State *L) { | 4572 | static int sx_setAlpnProtos(lua_State *L) { |
| 4529 | SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS); | 4573 | SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS); |
| 4574 | luaL_Buffer B; | ||
| 4530 | size_t len; | 4575 | size_t len; |
| 4531 | const char *tmp; | 4576 | const char *tmp; |
| 4532 | unsigned protos_len = 0; | ||
| 4533 | luaL_Buffer B; | ||
| 4534 | luaL_checktype(L, 2, LUA_TTABLE); | ||
| 4535 | luaL_buffinit(L, &B); | ||
| 4536 | 4577 | ||
| 4537 | while (1) { | 4578 | luaL_buffinit(L, &B); |
| 4538 | protos_len++; | 4579 | checkprotos(&B, L, 2); |
| 4539 | lua_rawgeti(L, 2, protos_len); | ||
| 4540 | switch (lua_type(L, -1)) { | ||
| 4541 | case LUA_TNIL: | ||
| 4542 | goto done; | ||
| 4543 | case LUA_TSTRING: | ||
| 4544 | break; | ||
| 4545 | default: | ||
| 4546 | return luaL_argerror(L, 2, "array of strings expected"); | ||
| 4547 | } | ||
| 4548 | tmp = luaL_checklstring(L, -1, &len); | ||
| 4549 | luaL_argcheck(L, len > 0 && len <= UCHAR_MAX, 2, "proto string length invalid"); | ||
| 4550 | luaL_addchar(&B, (unsigned char)len); | ||
| 4551 | luaL_addlstring(&B, tmp, len); | ||
| 4552 | lua_pop(L, 1); | ||
| 4553 | } | ||
| 4554 | done: | ||
| 4555 | luaL_pushresult(&B); | 4580 | luaL_pushresult(&B); |
| 4556 | tmp = lua_tolstring(L, -1, &len); | 4581 | tmp = lua_tolstring(L, -1, &len); |
| 4557 | 4582 | ||
| @@ -4571,6 +4596,7 @@ done: | |||
| 4571 | } /* sx_setAlpnProtos() */ | 4596 | } /* sx_setAlpnProtos() */ |
| 4572 | #endif | 4597 | #endif |
| 4573 | 4598 | ||
| 4599 | |||
| 4574 | static int sx__gc(lua_State *L) { | 4600 | static int sx__gc(lua_State *L) { |
| 4575 | SSL_CTX **ud = luaL_checkudata(L, 1, SSL_CTX_CLASS); | 4601 | SSL_CTX **ud = luaL_checkudata(L, 1, SSL_CTX_CLASS); |
| 4576 | 4602 | ||
| @@ -4847,6 +4873,7 @@ static int ssl_getClientVersion(lua_State *L) { | |||
| 4847 | return 1; | 4873 | return 1; |
| 4848 | } /* ssl_getClientVersion() */ | 4874 | } /* ssl_getClientVersion() */ |
| 4849 | 4875 | ||
| 4876 | |||
| 4850 | #if HAVE_SSL_GET0_ALPN_SELECTED | 4877 | #if HAVE_SSL_GET0_ALPN_SELECTED |
| 4851 | static int ssl_getAlpnSelected(lua_State *L) { | 4878 | static int ssl_getAlpnSelected(lua_State *L) { |
| 4852 | SSL *ssl = checksimple(L, 1, SSL_CLASS); | 4879 | SSL *ssl = checksimple(L, 1, SSL_CLASS); |
| @@ -4862,6 +4889,36 @@ static int ssl_getAlpnSelected(lua_State *L) { | |||
| 4862 | } /* ssl_getAlpnSelected() */ | 4889 | } /* ssl_getAlpnSelected() */ |
| 4863 | #endif | 4890 | #endif |
| 4864 | 4891 | ||
| 4892 | |||
| 4893 | #if HAVE_SSL_SET_ALPN_PROTOS | ||
| 4894 | static int ssl_setAlpnProtos(lua_State *L) { | ||
| 4895 | SSL *ssl = checksimple(L, 1, SSL_CLASS); | ||
| 4896 | luaL_Buffer B; | ||
| 4897 | size_t len; | ||
| 4898 | const char *tmp; | ||
| 4899 | |||
| 4900 | luaL_buffinit(L, &B); | ||
| 4901 | checkprotos(&B, L, 2); | ||
| 4902 | luaL_pushresult(&B); | ||
| 4903 | tmp = lua_tolstring(L, -1, &len); | ||
| 4904 | |||
| 4905 | /* OpenSSL 1.0.2 doesn't update the error stack on failure. */ | ||
| 4906 | ERR_clear_error(); | ||
| 4907 | if (0 != SSL_set_alpn_protos(ssl, (const unsigned char*)tmp, len)) { | ||
| 4908 | if (!ERR_peek_error()) { | ||
| 4909 | return luaL_error(L, "unable to set ALPN protocols: %s", xstrerror(ENOMEM)); | ||
| 4910 | } else { | ||
| 4911 | return throwssl(L, "ssl:setAlpnProtos"); | ||
| 4912 | } | ||
| 4913 | } | ||
| 4914 | |||
| 4915 | lua_pushboolean(L, 1); | ||
| 4916 | |||
| 4917 | return 1; | ||
| 4918 | } /* ssl_setAlpnProtos() */ | ||
| 4919 | #endif | ||
| 4920 | |||
| 4921 | |||
| 4865 | static int ssl__gc(lua_State *L) { | 4922 | static int ssl__gc(lua_State *L) { |
| 4866 | SSL **ud = luaL_checkudata(L, 1, SSL_CLASS); | 4923 | SSL **ud = luaL_checkudata(L, 1, SSL_CLASS); |
| 4867 | 4924 | ||
| @@ -4888,6 +4945,9 @@ static const luaL_Reg ssl_methods[] = { | |||
| 4888 | #if HAVE_SSL_GET0_ALPN_SELECTED | 4945 | #if HAVE_SSL_GET0_ALPN_SELECTED |
| 4889 | { "getAlpnSelected", &ssl_getAlpnSelected }, | 4946 | { "getAlpnSelected", &ssl_getAlpnSelected }, |
| 4890 | #endif | 4947 | #endif |
| 4948 | #if HAVE_SSL_SET_ALPN_PROTOS | ||
| 4949 | { "setAlpnProtos", &ssl_setAlpnProtos }, | ||
| 4950 | #endif | ||
| 4891 | { NULL, NULL }, | 4951 | { NULL, NULL }, |
| 4892 | }; | 4952 | }; |
| 4893 | 4953 | ||
