summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwilliam <william@25thandclement.com>2015-03-05 14:57:45 -0800
committerwilliam <william@25thandclement.com>2015-03-05 14:57:45 -0800
commitafeb65d5c21019132a9b7759f864f19e0ad0df43 (patch)
tree06e6842ba6444d1765a344800163d09f5e5c30be
parentfe19dfb57495c54c16edbeb52eae64b01404364f (diff)
downloadluaossl-afeb65d5c21019132a9b7759f864f19e0ad0df43.tar.gz
luaossl-afeb65d5c21019132a9b7759f864f19e0ad0df43.tar.bz2
luaossl-afeb65d5c21019132a9b7759f864f19e0ad0df43.zip
add openssl.ssl:setAlpnProtos
-rw-r--r--src/openssl.c106
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
353static _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 */
367static 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
349static _Bool getfield(lua_State *L, int index, const char *k) { 392static _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
4528static int sx_setAlpnProtos(lua_State *L) { 4572static 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 }
4554done:
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
4574static int sx__gc(lua_State *L) { 4600static 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
4851static int ssl_getAlpnSelected(lua_State *L) { 4878static 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
4894static 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
4865static int ssl__gc(lua_State *L) { 4922static 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