Module ssl

Lua SSL/TLS Socket binding.

LuaSec is a binding for OpenSSL library to provide TLS/SSL communication. It takes an already established TCP connection and creates a secure session between the peers. This is a simple example of a client and server communication using LuaSec:

Client code

--require("socket")
require("ssl")

-- TLS/SSL client parameters (omitted)
local params

local conn = socket.tcp()
conn:connect("127.0.0.1", 8888)

-- TLS/SSL initialization
conn = ssl.wrap(conn, params)
conn:dohandshake()
--
print(conn:receive("*l"))
conn:close()

Server code

require("socket")
require("ssl")

-- TLS/SSL server parameters (omitted)
local params

local server = socket.tcp()
server:bind("127.0.0.1", 8888)
server:listen()
local conn = server:accept()

-- TLS/SSL initialization
conn = ssl.wrap(conn, params)
conn:dohandshake()
--
conn:send("one line\n")
conn:close()

LuaSec needs a set of information (such as protocol, key, certificate, etc.) to wrap the TCP connection. For instance, we can use the following parameters in the example above:

Client parameters

local params = {
mode = "client",
protocol = "tlsv1",
key = "/etc/certs/clientkey.pem",
certificate = "/etc/certs/client.pem",
cafile = "/etc/certs/CA.pem",
verify = "peer",
options = "all",
}

Server parameters

local params = {
mode = "server",
protocol = "tlsv1",
key = "/etc/certs/serverkey.pem",
certificate = "/etc/certs/server.pem",
cafile = "/etc/certs/CA.pem",
verify = {"peer", "fail_if_no_peer_cert"},
options = {"all", "no_sslv2"},
ciphers = "ALL:!ADH:@STRENGTH",
}

License

LuaSec is available under the same terms and conditions as the Lua language — the MIT license.

Contact

bruno . silvestre at gmail . com brunoos at inf . ufg . br

Type ssl

ssl.newcontext(params)

Creates a context that is used to wrap a TCP connection.

ssl.wrap(sock, params)

Wraps the TCP connection sock and returns a new object that is used to establish a secure session.

Type sslsock

sslsock.close()

Close an ssl socket

sslsock.dohandshake()

Performs theTLS/SSL handshake to establesh the secure connection.

sslsock.info(field)

Get information on the #sslsock.

sslsock.receive(pattern, prefix)

Reads data from the connection conn, according to the specified read pattern.

sslsock.send(data, i, j)

Sends data through the connection.

sslsock.settimeout(value, mode)

Changes the timeout values for the connection.

sslsock.want()

Informs the reason that triggers the timeout in the last call of #sslsock:send, #sslsock:receive, or #sslsock:dohandshake.

Type ssl

Field(s)

ssl.newcontext(params)

Creates a context that is used to wrap a TCP connection.

In case of errors, the function returns nil, followed by an error message.

Parameter

  • params : is a table that contains parameters to create the context. These parameters can be:

    Key Value Type Value Mandatory
    mode String HASH018X Yes
    protocol String
    • "tlsv1": for TLS version 1
    • "tlsv1_1": for TLS version 1.1
    • "tlsv1_2": for TLS version 1.2
    • "sslv3": for SSL version 3
    • "sslv23": for SSL version 2 and 3
    Yes
    key String Path to the file that contains the key (in PEM format). No
    password String / Function Password of the encrypted key, or a callback function that returns it. If the callback does not return a string, a null password is used. No
    certificate String Path to the file that contains the chain certificates. These must be in PEM format and must be sorted starting from the subject's certificate (client or server), followed by intermediate CA certificates if applicable, and ending at the highest level CA. No
    cafile String Path to the file that contains a set of trusting certificates (in PEM format). No
    capath String Path to the directory that constains a set of files with trusting certificates. No
    verify String / Table Options used to verify the certificates. Use an array of strings for multiple options.
    • "none"
    • "peer"
    • "client_once"
    • "fail_if_no_peer_cert"
    No
    options String / Table Options to change the behaviour of the OpenSSL library. Use an array of strings for multiple options. (See the valid options below) No
    ciphers String The list of ciphers to be used in the connection. No
    depth Number Maximum depth in the certificate chain verification. No
    dhparam Function This callback function must return the DH parameters, used in the handshake. No
    curve String Select the elliptic curve. No
    verifyext String / Table Extra options for handshake. HASH021X No

    Please, see OpenSSL documentation for more information.

    The field options supports:

    • all
    • allow_unsafe_legacy_renegotiation
    • cipher_server_preference
    • cisco_anyconnect
    • cookie_exchange
    • cryptopro_tlsext_bug
    • dont_insert_empty_fragments
    • ephemeral_rsa
    • legacy_server_connect
    • microsoft_big_sslv3_buffer
    • microsoft_sess_id_bug
    • msie_sslv2_rsa_padding
    • netscape_ca_dn_bug
    • netscape_challenge_bug
    • netscape_demo_cipher_change_bug
    • netscape_reuse_cipher_change_bug
    • no_compression
    • no_query_mtu
    • no_session_resumption_on_renegotiation
    • no_sslv2
    • no_sslv3
    • no_ticket
    • no_tlsv1
    • pkcs1_check_1
    • pkcs1_check_2
    • single_dh_use
    • single_ecdh_use
    • ssleay_080_client_dh_bug
    • sslref2_reuse_cert_type_bug
    • tls_block_padding_bug
    • tls_d5_bug
    • tls_rollback_bug

    Note: you need to check if your version of OpenSSL provides these options.

Return value

an ssl context

ssl.wrap(sock, params)

Wraps the TCP connection sock and returns a new object that is used to establish a secure session.

ssl.wrap needs a context, which provides parameters such as protocol, certificate, key, etc., in order to create the new connection object. You can provide a already created context in params or a table with the parameters. In this case, ssl.wrap calls ssl.newcontext to obtain the context.

Parameters

  • sock : socket to wrap

  • params : ssl context

Return value

an #sslsock. In case of error, the function returns nil, followed by an error message.

Note: ssl.wrap invalidates the socket passed as argument. This prevents the garbage collector to close the TCP connection when the socket object is disposed.

Type sslsock

Field(s)

sslsock.close()

Close an ssl socket

sslsock.dohandshake()

Performs theTLS/SSL handshake to establesh the secure connection.

In case of success, the function returns true, otherwise, false followed by an error message.

If timeout is set, #sslsock:dohandshake can return false followed by "wantread" or "wantwrite" to indicate that the handshake was not finished yet. You have to wait the connection to be readable or writable, respectively (you can use socket.select), then call #sslsock:dohandshake again to finish the operation.

For example:

local succ, msg
conn:settimeout(0)
while not succ do
succ, msg = conn:dohandshake()
if msg == "wantread" then
    socket.select({conn}, nil)
elseif msg == "wantwrite" then
    socket.select(nil, {conn})
else
    -- other errors
end
end

sslsock.info(field)

Get information on the #sslsock.

If field is omitted, this function returns a table with information about the connection. Possible items contained in the info table

algbits
authentication
bits
cipher
compression
encryption
export
key
mac
protocol

Parameter

  • field : (optional) If field is present, this function returns its value only.

Return value

a table with the info, or the value if field is defined

sslsock.receive(pattern, prefix)

Reads data from the connection conn, according to the specified read pattern.

Parameters

  • pattern : it can be one of:
    - '*a': reads from the connection until it is closed. No end-of-line translation is performed;
    - '*l': reads a line of text from the connection. The line is terminated by a LF character (ASCII 10), optionally preceded by a CR character (ASCII 13). The CR and LF characters are not included in the returned line. In fact, all CR characters are ignored by the pattern. This is the default pattern;
    - number: causes the method to read a specified number of bytes from the socket.

  • prefix : The parameter prefix is an optional string to be concatenated to the beginning of any received data before return.

Return value

If successful, the method returns the received pattern. In case of error, the method returns nil followed by an error message.

Among the error messages, "closed" indicates that the connection was closed before the transmission was completed; "wantread" and "wantwrite" indicates that a timeout occurred during the operation. Also, after the error message, the function returns the partial result of the transmission.

In the case of "wantread" or "wantwrite" errors, you should wait the connection to be ready for reading or writing, respectively, and call #sslsock:receive again.

sslsock.send(data, i, j)

Sends data through the connection.

Parameters

  • data : the string to be sent. The optional arguments i and j work exactly like the standard string.sub Lua function to allow the selection of a substring to be sent.

  • i : (optional) start index

  • j : (optional) end index

Return value

If successful, the method returns the index of the last byte within [i, j] that has been sent. Notice that, if i is 1 or absent, this is effectively the total number of bytes sent.
In case of error, the method returns nil, followed by an error message and the index of the last byte within [i, j] that has been sent. You might want to try again from the byte following that.

Among the error messages, "closed" indicates that the connection was closed before the transmission was completed; "wantread" and "wantwrite" indicates that a timeout occured during the operation.

In the case of "wantread" or "wantwrite" errors, you should wait the connection to be ready for reading or writing, respectively, and call #sslsock:send again.

sslsock.settimeout(value, mode)

Changes the timeout values for the connection.

By default, the operations #sslsock:send, #sslsock:receive, and #sslsock:dohandshake will block indefinitely, until the operation completes. When a timeout is set and the specified amount of time has elapsed, the affected methods give up and fail with an error code.

Parameters

  • value : The amount of time to wait is specified as the value parameter, in seconds. The nil timeout value allows operations to block indefinitely. Negative timeout values have the same effect.

  • mode : (optional) There are two timeout modes and both can be used together for fine tuning:
    - 'b': block timeout. Specifies the upper limit on the amount of time LuaSec can be blocked by the operating system while waiting for completion of any single I/O operation. This is the default mode;
    - 't': total timeout. Specifies the upper limit on the amount of time LuaSec can block a Lua script before returning from a call.

sslsock.want()

Informs the reason that triggers the timeout in the last call of #sslsock:send, #sslsock:receive, or #sslsock:dohandshake.

Return value

The string "read" indicates the operation was not performed because the connection was not ready for reading. In the same way, "write" indicates the connection was not ready for writing. If the operations were successfully complited, the string "nothing" is returned.