mirror of
https://github.com/brunoos/luasec.git
synced 2024-11-09 15:08:26 +01:00
Add ssl.checkhostname and conn:checkhostname
Convenient (and important!) methods that allow checking for hostnames against a (peer) certificate. Deals with wildcards and alternative names (via the dnsnames extension).
This commit is contained in:
parent
88fa9b8bc2
commit
cde151739e
@ -47,3 +47,13 @@ Alias for `cert.load`.
|
|||||||
|
|
||||||
`ssl.wrap` wraps an existing luasocket socket into a luasec connection object.
|
`ssl.wrap` wraps an existing luasocket socket into a luasec connection object.
|
||||||
`cfg` is defined as for `ssl.newcontext`.
|
`cfg` is defined as for `ssl.newcontext`.
|
||||||
|
|
||||||
|
### ssl.checkhostname ###
|
||||||
|
|
||||||
|
valid = ssl.checkhostname(cert, hostname)
|
||||||
|
|
||||||
|
Check if the certificate is valid for the given hostname. Deals with wildcards
|
||||||
|
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.
|
||||||
|
@ -119,3 +119,10 @@ context associated with this `conn` object.
|
|||||||
|
|
||||||
Returns luasec's current `want`, if the connection is dirty (see `conn:dirty`).
|
Returns luasec's current `want`, if the connection is dirty (see `conn:dirty`).
|
||||||
This can either be `nothing`, `read`, `write` or `x509lookup`.
|
This can either be `nothing`, `read`, `write` or `x509lookup`.
|
||||||
|
|
||||||
|
### conn:checkhostname ###
|
||||||
|
|
||||||
|
valid = conn:checkhostname(hostname)
|
||||||
|
|
||||||
|
Checks whether the certificate is valid for the given hostname. Helper for
|
||||||
|
`ssl.checkhostname`, see `ssl.checkhostname` for more information.
|
||||||
|
48
src/ssl.lua
48
src/ssl.lua
@ -159,10 +159,57 @@ local function info(ssl, field)
|
|||||||
return ( (next(info)) and info )
|
return ( (next(info)) and info )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Verify host name against a common name
|
||||||
|
--
|
||||||
|
local function checkhostname_single(hostname, cn)
|
||||||
|
if cn:match("^%*%.") then
|
||||||
|
-- If it's a wildcard domain name, strip the first element of the hostname
|
||||||
|
-- and the cn, then check neither are empty.
|
||||||
|
hostname = hostname:match("%.(.+)$")
|
||||||
|
cn = cn:match("%.(.+)$")
|
||||||
|
if cn == "" or hostname == "" then return false end
|
||||||
|
end
|
||||||
|
return cn == hostname
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Verify host name against certificate
|
||||||
|
--
|
||||||
|
local function checkhostname(cert, hostname)
|
||||||
|
local subject, ext
|
||||||
|
subject = cert:subject()
|
||||||
|
for i, v in ipairs(subject) do
|
||||||
|
if v.name == "commonName" then
|
||||||
|
if checkhostname_single(hostname, v.value) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- If we got here, the cn doesn't match, check for the dNSName extension
|
||||||
|
ext = (cert:extensions() or {})["2.5.29.17"]
|
||||||
|
if not ext or not ext.dNSName then return false end
|
||||||
|
for i, v in ipairs(ext.dNSName) do
|
||||||
|
if checkhostname_single(hostname, v) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Verify host name against peer certificate
|
||||||
|
--
|
||||||
|
local function checkhostname_ssl(ssl, hostname)
|
||||||
|
return checkhostname(ssl:getpeercertificate(), hostname)
|
||||||
|
end
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Set method for SSL connections.
|
-- Set method for SSL connections.
|
||||||
--
|
--
|
||||||
core.setmethod("info", info)
|
core.setmethod("info", info)
|
||||||
|
core.setmethod("checkhostname", checkhostname_ssl)
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- Export module
|
-- Export module
|
||||||
@ -174,6 +221,7 @@ local _M = {
|
|||||||
loadcertificate = x509.load,
|
loadcertificate = x509.load,
|
||||||
newcontext = newcontext,
|
newcontext = newcontext,
|
||||||
wrap = wrap,
|
wrap = wrap,
|
||||||
|
checkhostname = checkhostname,
|
||||||
}
|
}
|
||||||
|
|
||||||
return _M
|
return _M
|
||||||
|
Loading…
Reference in New Issue
Block a user