Ssl¶
The ssl library implements (most of) the LuaSec API.
The most common use of this library is to wrap an existing
Socket and use it as a client, connecting out to a remote
server (for example, over HTTPS). ssl.wrap does not apply any
defaults of its own – whatever SslConfig
table you pass it is used as-is – so it is up to the caller to supply
reasonable values. The fields below are the ones that matter for a
client connection and the values you will typically want to use.
- mode
Should always be set to
"client"when connecting out to a server. ("server"is only relevant if this code is itself accepting inbound connections.)- protocol
The protocol version to negotiate.
"any"lets the two sides negotiate the highest protocol version they both support, and is a reasonable default for a client connecting to an unknown server.- options
A list of protocol tweaks and bug workarounds to enable. For a client connecting to a modern server,
{"all", "no_sslv2", "no_sslv3", "no_tlsv1"}is a reasonable set:"all"turns on the standard collection of SSL bug workarounds, and the remaining entries disable the old, insecure SSLv2, SSLv3, and TLSv1 protocols.- verify
Controls whether the server’s certificate is verified, and how. One of
none,peer,fail_if_no_peer_cert, orclient_once. When connecting as a client,"peer"should be preferred if a certificate is provided (againstcafile/capath).- cafile / capath
The certificate authority root certificate (or a path to one), or a directory of trusted CA certificates, used to validate the server’s certificate when
verifyis not"none". Neither has a value unless one is explicitly provided.- certificates
A list of
CertificateTable. This is only needed on the client side if the server requires mutual TLS (i.e. it also verifies the client’s certificate); most client connections to a server can leave this unset.- depth
The maximum length of the certificate chain to verify. If left unset, the underlying library’s own default depth is used.
Driver Example¶
Looking at the SmartThings JBL driver, we can see a basic example of establishing an SSL connection.
First, a selfSignedRoot.crt file is provided at the base of the
directory. A default SSL_CONFIG is then defined in
drivers/SmartThings/jbl/src/jbl/api.lua. This configuration can be
passed to the SSL wrapper when establishing a socket connection.
Error handling should be included in a production implementation, but has been omitted from this example for brevity.
local SSL_CONFIG = {
mode = "client",
protocol = "any",
verify = "peer",
options = "all",
cafile = "./selfSignedRoot.crt"
}
local sock, _ = socket.tcp()
_, err = sock:connect(host, port)
sock, err = ssl.wrap(sock, SSL_CONFIG)
sock:dohandshake()
sock:send("GET /get_info HTTP/1.1\r\nHost: " .. host .. "\r\n\r\n")
local response, err = sock:receive("*a")
- class ssl.CertificateTable¶
Both the certificate and key field can either be a relative path pointing to a file in the driver package or the contents as a string formatted in the PEM format.
- certificate: str¶
The certificate
- key: str¶
Optional private key, should only be set in 1 of the certificates list
- password: str¶
Optional password
- class ssl.SslConfig¶
- mode: str¶
client or server
- protocol: str¶
any
- cafile: str¶
The contents of the certificate authority’s root cert or relative path to the root cert file
- capath: str¶
A path to the certificate authority directory
- certificates: list[CertificateTable]¶
list of certificates
- verify: str¶
One of none, peer, fail_if_no_peer_cert, or client_once
- depth: integer¶
The depth to verify
- options: list[str]¶
“all” | “allow_unsafe_legacy_renegotiation” | “cipher_server_preference” | “cookie_exchange” | “dont_insert_empty_fragments” | “no_compression” | “no_dtlsv1” | “no_dtlsv1_2” | “no_query_mtu” | “no_session_resumption_on_renegotiation” | “no_ssl_mask” | “no_sslv2” | “no_sslv3” | “no_ticket” | “no_tlsv1” | “no_tlsv1_1” | “no_tlsv1_2” | “single_dh_use” | “single_ecdh_use” | “tls_rollback_bug”