diff --git a/samples/dane/client.lua b/samples/dane/client.lua new file mode 100644 index 0000000..5cdab70 --- /dev/null +++ b/samples/dane/client.lua @@ -0,0 +1,40 @@ + +local socket = require "socket"; +local ssl = require "ssl"; + +local dns = require "lunbound".new(); + + +local cfg = { + protocol = "tlsv1_2", + mode = "client", + ciphers = "DEFAULT", + capath = "/etc/ssl/certs", + verify = "peer", + dane = true, +}; + +local function daneconnect(host, port) + port = port or "443"; + local conn = ssl.wrap(socket.connect(host, port), cfg); + + local tlsa = dns:resolve("_" .. port .. "._tcp." .. host, 52); + assert(tlsa.secure, "Insecure DNS"); + + assert(conn:setdane(host)); + for i = 1, tlsa.n do + local usage, selector, mtype = tlsa[i] :byte(1, 3); + assert(conn:settlsa(usage, selector, mtype, tlsa[i] :sub(4, - 1))); + end + + assert(conn:dohandshake()); + return conn; +end + +if not ... then + print("Usage: client.lua example.com [port]"); + return os.exit(1); +end +local conn = daneconnect(...); + +print(conn:getpeerverification()); diff --git a/src/context.c b/src/context.c index fd74869..0e311f7 100644 --- a/src/context.c +++ b/src/context.c @@ -704,6 +704,17 @@ static int set_alpn_cb(lua_State *L) } +/* + * DANE + */ +static int set_dane(lua_State *L) +{ + SSL_CTX *ctx = lsec_checkcontext(L, 1); + int ret = SSL_CTX_dane_enable(ctx); + lua_pushboolean(L, ret); + return 1; +} + /** * Package functions */ @@ -728,6 +739,8 @@ static luaL_Reg funcs[] = { {"setcurveslist", set_curves_list}, #endif + {"setdane", set_dane}, + {NULL, NULL} }; diff --git a/src/ssl.c b/src/ssl.c index 31d56ef..c39af14 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -826,6 +826,31 @@ static int meth_copyright(lua_State *L) return 1; } +static int meth_dane(lua_State *L) +{ + p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection"); + int ret = SSL_dane_enable(ssl->ssl, luaL_checkstring(L, 2)); + lua_pushboolean(L, ret); + return 1; +} + +static int meth_tlsa(lua_State *L) +{ + p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection"); + uint8_t usage = luaL_checkinteger(L, 2); + uint8_t selector = luaL_checkinteger(L, 3); + uint8_t mtype = luaL_checkinteger(L, 4); + size_t len; + const char *data = luaL_checklstring(L, 5, &len); + + ERR_clear_error(); + int ret = SSL_dane_tlsa_add(ssl->ssl, usage, selector, mtype, data, len); + lua_pushboolean(L, ret); + + return 1; +} + + /*---------------------------------------------------------------------------*/ /** @@ -850,6 +875,8 @@ static luaL_Reg methods[] = { {"settimeout", meth_settimeout}, {"sni", meth_sni}, {"want", meth_want}, + {"setdane", meth_dane}, + {"settlsa", meth_tlsa}, {NULL, NULL} }; diff --git a/src/ssl.lua b/src/ssl.lua index 1ee035a..5f2aac8 100644 --- a/src/ssl.lua +++ b/src/ssl.lua @@ -201,6 +201,10 @@ local function newcontext(cfg) if not succ then return nil, msg end end + if cfg.dane then + context.setdane(ctx) + end + return ctx end