Merge pull request #133 from quickdudley/multi-certs

Enable multiple SSL certificates
This commit is contained in:
Bruno Silvestre 2019-02-26 14:42:47 -03:00 committed by GitHub
commit 1c3bf23551
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 115 additions and 18 deletions

View File

@ -0,0 +1,33 @@
--
-- Public domain
--
local socket = require("socket")
local ssl = require("ssl")
local params = {
mode = "client",
protocol = "tlsv1_2",
key = "../certs/clientAkey.pem",
certificate = "../certs/clientA.pem",
cafile = "../certs/rootA.pem",
verify = {"peer", "fail_if_no_peer_cert"},
options = "all",
--
curve = "secp384r1",
}
--------------------------------------------------------------------------------
local peer = socket.tcp()
peer:connect("127.0.0.1", 8888)
peer = assert( ssl.wrap(peer, params) )
assert(peer:dohandshake())
print("--- INFO ---")
local info = peer:info()
for k, v in pairs(info) do
print(k, v)
end
print("---")
peer:close()

View File

@ -0,0 +1,48 @@
--
-- Public domain
--
local socket = require("socket")
local ssl = require("ssl")
local params = {
mode = "server",
protocol = "any",
certificates = {
{
key = "../certs/serverAkey.pem",
certificate = "../certs/serverA.pem"
},
{
key = "../certs/serverBkey.pem",
certificate = "../certs/serverB.pem"
}
},
cafile = "../certs/rootA.pem",
verify = {"peer", "fail_if_no_peer_cert"},
options = "all",
--
curve = "secp384r1",
}
------------------------------------------------------------------------------
local ctx = assert(ssl.newcontext(params))
local server = socket.tcp()
server:setoption('reuseaddr', true)
assert( server:bind("127.0.0.1", 8888) )
server:listen()
local peer = server:accept()
peer = assert( ssl.wrap(peer, ctx) )
assert( peer:dohandshake() )
print("--- INFO ---")
local info = peer:info()
for k, v in pairs(info) do
print(k, v)
end
print("---")
peer:close()
server:close()

View File

@ -74,26 +74,42 @@ local function newcontext(cfg)
-- Mode -- Mode
succ, msg = context.setmode(ctx, cfg.mode) succ, msg = context.setmode(ctx, cfg.mode)
if not succ then return nil, msg end if not succ then return nil, msg end
if not cfg.certificates then
cfg.certificates = {}
end
local singularcertificate = {}
local singularexists = false
for _, prop in pairs({ "key", "certificate", "password" }) do
if cfg[prop] then
singularexists = true
singularcertificate[prop] = cfg[prop]
end
end
if singularexists then
table.insert(crt.certificates, singularcertificate)
end
for _, certificate in pairs(cfg.certificates) do
-- Load the key -- Load the key
if cfg.key then if certificate.key then
if cfg.password and if certificate.password and
type(cfg.password) ~= "function" and type(certificate.password) ~= "function" and
type(cfg.password) ~= "string" type(certificate.password) ~= "string"
then then
return nil, "invalid password type" return nil, "invalid password type"
end end
succ, msg = context.loadkey(ctx, cfg.key, cfg.password) succ, msg = context.loadkey(ctx, certificate.key, certificate.password)
if not succ then return nil, msg end if not succ then return nil, msg end
end end
-- Load the certificate -- Load the certificate(s)
if cfg.certificate then if certificate.certificate then
succ, msg = context.loadcert(ctx, cfg.certificate) succ, msg = context.loadcert(ctx, certificate.certificate)
if not succ then return nil, msg end if not succ then return nil, msg end
if cfg.key and context.checkkey then if certificate.key and context.checkkey then
succ = context.checkkey(ctx) succ = context.checkkey(ctx)
if not succ then return nil, "private key does not match public key" end if not succ then return nil, "private key does not match public key" end
end end
end end
end
-- Load the CA certificates -- Load the CA certificates
if cfg.cafile or cfg.capath then if cfg.cafile or cfg.capath then
succ, msg = context.locations(ctx, cfg.cafile, cfg.capath) succ, msg = context.locations(ctx, cfg.cafile, cfg.capath)