From 7de198bea222358c7ea147a2aa097ecc9265c7be Mon Sep 17 00:00:00 2001 From: Bart van Strien Date: Fri, 5 Jun 2015 21:17:33 +0200 Subject: [PATCH] Add connection helper ssl.connect --- doc/luasec.md | 15 +++++++++++++++ src/ssl.lua | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/doc/luasec.md b/doc/luasec.md index 9ae4dc1..add156c 100644 --- a/doc/luasec.md +++ b/doc/luasec.md @@ -57,3 +57,18 @@ and alternative names. **NOTE**: It is crucial the hostname is checked to verify the certificate is not only valid, but belonging to the host connected to. + +### ssl.connect ### + + conn, socket = ssl.connect(hostname, port, [flags]) + +Creates a tcp socket, connects it to the specified hostname and port, wraps it +in an ssl object, does the handshake and verifies the hostname. It makes sure +the mode flag is set to `client`, and defaults verify to `none`, and protocol +to `tlsv1_2`. Can fail, in which case it returns nil, followed by an error. + +See `ssl.wrap` and `ssl.checkhostname` for details. + +**WARNING**: Peer verification is off by default. It is highly recommended to +specify either a `capath` or a `cafile` in the flags, and turn peer +verification on. diff --git a/src/ssl.lua b/src/ssl.lua index 3f42de5..1fc6fb5 100644 --- a/src/ssl.lua +++ b/src/ssl.lua @@ -4,6 +4,7 @@ -- ------------------------------------------------------------------------------ +local socket = require("socket") local core = require("ssl.core") local context = require("ssl.context") local x509 = require("ssl.x509") @@ -205,6 +206,36 @@ local function checkhostname_ssl(ssl, hostname) return checkhostname(ssl:getpeercertificate(), hostname) end +-- +-- Connect helper +-- +local function connect(hostname, port, flags) + local sock, conn, success, err + sock = socket.tcp() + success, err = sock:connect(hostname, port) + if not success then + return nil, err + end + flags = flags or {} + flags.mode = "client" + flags.verify = flags.verify or "none" + flags.protocol = flags.protocol or "tlsv1_2" + conn, err = ssl.wrap(sock, flags or {}) + if not conn then + sock:close() + return nil, err + end + success, err = conn:dohandshake() + if not success then + return nil, err + end + if not conn:checkhostname(hostname) then + sock:close() + return nil, "hostname does not match certificate" + end + return conn, sock +end + -- -- Set method for SSL connections. -- @@ -222,6 +253,7 @@ local _M = { newcontext = newcontext, wrap = wrap, checkhostname = checkhostname, + connect = connect, } return _M