82 Commits

Author SHA1 Message Date
7ce63ad392 Return nil instead boolean 2021-06-25 19:59:22 -03:00
a3e74db781 Some work with OCSP 2021-06-25 19:50:47 -03:00
cdcf5fdb30 Off by one in cert:validat(notafter) #173 2021-06-23 13:35:49 -03:00
bdbc67b188 Move the fix of SSL_get_error() in OpenSSL 1.1.1
Moving to lsec_socket_error() coverts better 'errno == 0' with SSL_ERROR_SYSCALL.
2021-05-29 10:11:02 -03:00
359151144b Merge pull request #172 from edzius/master
Handle SSL_send SYSCALL error without errno
https://www.openssl.org/docs/man1.1.1/man3/SSL_get_error.html
2021-05-29 09:38:29 -03:00
d6b2fd7d35 Handle SSL_send SYSCALL error without errno
Either intentionaly or due to bug in openssl in some marginal
cases SSL_send reports SYSCALL error whilst errno is set to 0.
This either could mean that SSL_send did not made any system
call or errno were prematurely reset with consequent syscalls.
And in consequence sendraw() is not propagate correct errno
ends up in infinite loop trying to send same data.

Such behaviour was usually observed after third consequential
failed SSL send attempt which application was not aware of.
First send failed with syscall errno 32 (Broken pipe) second
one with SSL error 0x1409e10f (bad length) and lastly next
send attemt results with SYSCALL error and errno 0.

Tested using:
* OpenSSL v1.1.1
* musl v1.1.20 (c50985d5c8e316c5c464f352e79eeebfed1121a9)
* Linux 4.4.60+yocto armv7l
2021-05-21 21:20:19 +03:00
d5df315617 Update version and rockspec 2021-04-26 09:16:05 -03:00
34252fb10a Set parameter 2 and 3 to none before luaL_buffinit() 2021-04-26 08:37:09 -03:00
711a98b760 Update rockspec 2021-01-30 10:32:28 -03:00
4894c2f6a4 Update version number 2021-01-30 10:29:53 -03:00
ae774258c5 Merge pull request #164 from murillopaula/master
feature: getsignaturename
2021-01-16 10:13:29 -03:00
de393417b7 feature: getsignaturename 2021-01-12 10:49:27 -03:00
22eadbd20e Merge pull request #156 from Petr-kk/upstream
SOCKET_INVALID pushed as integer, not as number
2020-03-06 13:44:42 -03:00
63e35c161f SOCKET_INVALID pushed as integer, not as number
winsock define INVALID_SOCKET as (UINT_PTR)(~0)
in win64 it is 0xffffffffffffffff
if pushed by lua_pushnumber, then ssl.core.SOCKET_INVALID is 1.84467440737096E19

tested in win32/64, linux32/64 lua5.1 and lua5.3
2020-03-04 17:05:06 +01:00
c6704919bd Typo 2019-10-31 11:43:53 -03:00
d7ccfad97f Fix source in rockspec 2019-10-31 11:39:37 -03:00
43feb51c5e Update 0.8 -> 0.9 2019-10-31 11:34:27 -03:00
860b2a8b5f Use a more generic form 2019-10-19 10:22:21 -03:00
caeaa5ffda Use a more generic form 2019-10-19 10:12:20 -03:00
9d84469912 Use a more generic form 2019-10-19 10:04:30 -03:00
87e51d99ea Add __close metamethod 2019-10-15 13:25:12 -03:00
7898bd2043 Remove warning from cast. 2019-10-14 10:00:47 -03:00
c810df6839 Cleanup of #if expression 2019-10-13 22:21:05 -03:00
1e2f342006 Using same form to ifdefs 2019-10-13 22:11:55 -03:00
8ef33e33cf Some adjusts to OpenSSL 1.1.1 with --api=1.1.0 2019-10-13 22:10:03 -03:00
3490d8d1c0 Merge pull request #126 from neheb/master
Get rid of some deprecation warnings with OpenSSL 1.1
2019-10-13 19:42:19 -03:00
86c8fa40c9 Merge pull request #134 from neheb/patch-1
use $(CC) for LD definition.
2019-10-13 19:11:48 -03:00
4903e2f2c1 Export 'config' table (#149)
Avoid duplicating variable 'ssl_options'.
2019-10-09 14:49:58 -03:00
2480572bdf Merge pull request #147 from Zash/issue146
Special case listing of TLS 1.3 EC curves
2019-08-28 11:10:37 -03:00
c26513f4f7 Special case listing of TLS 1.3 EC curves (fixes #146) 2019-08-21 20:58:01 +02:00
f64e660de0 Disable DANE for LibreSSL 2019-07-11 11:19:21 -03:00
8722f83e8f Fix check for error in DANE functions 2019-07-11 10:20:53 -03:00
a2dcfffcfa Enable DANE only for OpenSSL 1.1.0 or higher 2019-07-11 10:09:39 -03:00
18fa0118be Merge pull request #122 from Zash/dane
DANE support
2019-07-11 09:50:25 -03:00
9f3a97e397 Merge pull request #144 from Zash/fix-general-name-leak
Fix general_name leak in cert:extensions()
2019-07-11 09:42:23 -03:00
daf728fec2 Fix general_name leak in cert:extensions()
Thanks to @zeen for identifying and @horazont for providing test
environment.
2019-07-07 23:03:54 +02:00
041a37874b Inform OpenSSL 1.0.2 dependency 2019-04-22 10:31:32 -03:00
d6ba8d21da Update version to 0.8, new rock file 2019-04-16 14:01:52 -03:00
f8b2968e79 Declare variable "key" before use it. 2019-04-16 10:48:15 -03:00
57f2f1363f Replace LD with CCLD variable
When cross compiling, the LD variable typically gets overriden.
2019-04-08 09:45:40 -07:00
1efa37087e Add 'ciphersuites' property for TLS 1.3 2019-03-22 11:34:33 -03:00
1c9401ae54 README for samples updated 2019-02-26 16:06:17 -03:00
ea8ccc3113 Update sample of multiple certificates 2019-02-26 15:52:02 -03:00
c0cb85d77f Do not create 'certificates' on 'cfg' if it does not exist 2019-02-26 15:49:51 -03:00
1c3bf23551 Merge pull request #133 from quickdudley/multi-certs
Enable multiple SSL certificates
2019-02-26 14:42:47 -03:00
31237195a3 Fix invalid section 2019-02-26 13:37:12 -03:00
c72dc02ecb Sample for multiple certificates. 2019-02-26 10:52:53 +13:00
143ccf1323 PR feedback (Data structure) 2019-02-26 10:51:44 +13:00
5e2b27fa71 Merge pull request #132 from ewestbrook/prc-expose-tcp
Expose tcp() for use by LuaSocket
2019-02-25 15:25:20 -03:00
ff868e4a06 Enable multiple SSL certificates (issue 27) 2019-02-22 13:42:44 +13:00
ef342a7cda Merge pull request #125 from horazont/feature/fix-memleak
Fix memory leak in meth_extensions
2019-01-10 10:03:25 -02:00
569d12dc64 Merge pull request #124 from horazont/feature/modernize-certs
Modernize certificate generation
2019-01-10 10:02:22 -02:00
79c629956e Get rid of some deprecation warnings with OpenSSL 1.1 2018-11-20 20:12:39 -08:00
81c38864d4 Fix memory leak in meth_extensions 2018-11-19 16:00:30 +01:00
0775d5744f Make memory leak reproducible in loop sample 2018-11-19 16:00:20 +01:00
8bcabff0c1 Modernize certificate generation
- Use 2048 bit keys (required for modern OpenSSL)
- Use SHA256 instead of SHA1 (required for modern OpenSSL)
- Add a SubjectAltName to be able to trigger certain edge-cases
- Add all.sh to conveniently re-generate certificates
2018-11-19 15:56:42 +01:00
3f38f0929c Expose src/https.lua:tcp() for use by e.g. luasocket redirects 2018-10-13 07:31:38 -06:00
5ffe22e98e Add sample DANE usage 2018-10-06 19:37:43 +02:00
6359275c5f Add support for setting DANE TLSA information 2018-09-29 21:38:18 +02:00
550777a9d6 Merge pull request #120 from narcistesa/update-tls-cfg
Disable TLSv1 protocol by default in https module
2018-09-29 10:26:08 -03:00
4c5996a499 Disable TLSv1 to fix *received tlsv1 alert protocol version from* errors with certain websites 2018-09-19 16:25:39 -04:00
421c897dd3 Support for TLS 1.3 from OpenSSL 1.1.1
Based on PR #97 from @wmark.
2018-09-12 19:08:19 -03:00
2ecf239cfe Suppress warning with OpenSSL 1.1.0 and 1.1.1 2018-09-12 18:43:44 -03:00
113331fa0c Assuming that TLS 1.1 and TLS 1.2 are available 2018-09-12 18:27:43 -03:00
8440bc3d59 Assuming curves list is available if EC is available 2018-09-12 18:26:19 -03:00
5ece6049e5 Fix constant: OPENSS_NO_ECDH -> OPENSSL_NO_EC 2018-09-12 18:24:12 -03:00
9883782102 Fix constant: OPENSS_NO_ECDH -> OPENSSL_NO_EC 2018-09-12 18:17:19 -03:00
661d08e5f3 Removing OpenSSL 0.9.8 code 2018-09-12 18:08:19 -03:00
5514c4a06e Assuming that TLS 1.1 and TLS 1.2 are available
Fix some #if's also.
2018-09-12 18:03:37 -03:00
f42c171d55 This mode is available in new versions of OpenSSL, no more check 2018-09-12 17:45:13 -03:00
706e0f0281 New version of LibreSSL already implement these functions 2018-09-12 17:41:03 -03:00
d4ea2d12f3 Update reference to Lua state prior to handshake
The Lua thread that creates the context is saved to be used for
accessing callback related data. However that thread may become garbage
and its memory could be overwritten with anything if the handshake
happens later, in a different thread.

Fixes #75

Thanks @Zash
2018-09-10 10:49:18 -03:00
dea60edf4f Add ALPN support based on PR #64 from xnyhps 2018-08-27 15:10:18 -03:00
fdb2fa5f59 Let the library choose the min and max versions
Some protocols can be disable with 'options'.
2018-07-26 11:25:57 -03:00
93e0e8cc64 Force a cipher that use DH parameter 2018-07-26 11:22:24 -03:00
d9d0cd620d Free DH parameter right after handshake 2018-07-26 11:21:54 -03:00
953a363a59 Add timeout to https module
Glocal attribute https.TIMEOUT controls connection tiemout.

Sample:
  https.TIMEOUT = 5  -- seconds
  https.request()
2018-07-02 10:40:14 -03:00
28e247dbc5 Removing deprecated methods to select the protocol
Using TLS_method(), SSL_set_min_proto_version() and
SSL_set_max_proto_version().
2018-07-02 10:31:45 -03:00
89bdc6148c Removing SSLv3 support 2018-06-29 14:06:51 -03:00
8212b89f1a Using 'const SSL_METHOD*'
This change was introduced in OpenSSL 1.0.0.
Start droping 0.9.8 code.
2018-06-29 14:02:39 -03:00
879ba6d4f9 Merge pull request #116 from hishamhm/cross-windows
Use lowercase Windows header name
2018-06-29 13:49:01 -03:00
4d10a5a0c0 Use lowercase Windows header name
This is necessary for cross-compilation of Windows binaries on non-Windows
platforms (and harmless for Windows).
2018-06-29 10:21:22 -03:00
46 changed files with 1320 additions and 209 deletions

View File

@ -1,16 +1,76 @@
--------------------------------------------------------------------------------
LuaSec 1.0.1
---------------
This version includes:
* Fix luaL_buffinit() can use the stack and broke buffer_meth_receive()
--------------------------------------------------------------------------------
LuaSec 1.0
---------------
This version includes:
* Add cert:getsignaturename()
--------------------------------------------------------------------------------
LuaSec 0.9
---------------
This version includes:
* Add DNS-based Authentication of Named Entities (DANE) support
* Add __close() metamethod
* Fix deprecation warnings with OpenSSL 1.1
* Fix special case listing of TLS 1.3 EC curves
* Fix general_name leak in cert:extensions()
* Fix unexported 'ssl.config' table
* Replace $(LD) with $(CCLD) variable
* Remove multiple definitions of 'ssl_options' variable
* Use tag in git format: v0.9
--------------------------------------------------------------------------------
LuaSec 0.8.2
---------------
This version includes:
* Fix unexported 'ssl.config' table (backported)
--------------------------------------------------------------------------------
LuaSec 0.8.1
---------------
This version includes:
* Fix general_name leak in cert:extensions() (backported)
--------------------------------------------------------------------------------
LuaSec 0.8
---------------
This version includes:
* Add support to ALPN
* Add support to TLS 1.3
* Add support to multiple certificates
* Add timeout to https module (https.TIMEOUT)
* Drop support to SSL 3.0
* Drop support to TLS 1.0 from https module
* Fix invalid reference to Lua state
* Fix memory leak when get certficate extensions
--------------------------------------------------------------------------------
LuaSec 0.7.2
---------------
This version includes:
* Fix unexported 'ssl.config' table
* Fix unexported 'ssl.config' table (backported)
--------------------------------------------------------------------------------
LuaSec 0.7.1
---------------
This version includes:
* Fix general_name leak in cert:extensions()
* Fix general_name leak in cert:extensions() (backported)
--------------------------------------------------------------------------------
LuaSec 0.7

View File

@ -1,4 +1,4 @@
LuaSec 0.7.2
LuaSec 1.0.1
------------
* OpenSSL options:

View File

@ -1,5 +1,5 @@
LuaSec 0.7.2 license
Copyright (C) 2006-2019 Bruno Silvestre, UFG
LuaSec 1.0.1 license
Copyright (C) 2006-2021 Bruno Silvestre, UFG
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

View File

@ -1,4 +1,4 @@
LuaSec 0.7.2
LuaSec 1.0.1
===============
LuaSec depends on OpenSSL, and integrates with LuaSocket to make it
easy to add secure connections to any Lua applications or scripts.

View File

@ -1,8 +1,8 @@
package = "LuaSec"
version = "0.7.2-1"
version = "1.0.1-1"
source = {
url = "https://github.com/brunoos/luasec/archive/luasec-0.7.2.tar.gz",
dir = "luasec-luasec-0.7.2"
url = "git://github.com/brunoos/luasec",
tag = "v1.0.1",
}
description = {
summary = "A binding for OpenSSL library to provide TLS/SSL communication over LuaSocket.",

View File

@ -1,5 +1,8 @@
Directories:
------------
* alpn
Test ALPN (Application-Layer Protocol Negotiation) support.
* certs
Contains scripts to generate the certificates used by the examples.
Generate Root CA 'A' and 'B' first, then the servers and clients.
@ -7,6 +10,9 @@ Directories:
* chain
Example of certificate chain in handshake.
* curve-negotiation
Elliptic curve negotiation.
* dhparam
DH parameters for handshake.
@ -30,20 +36,29 @@ Directories:
Same of above, but the connection is not explicit closed, the gabage
collector is encharge of that.
* luaossl
Integration with luaossl.
* multicert
Support to multiple certificate for dual RSA/ECDSA.
* oneshot
A simple connection example.
* sni
Support to SNI (Server Name Indication).
* verification
Retrieve the certificate verification errors from the handshake.
* verify
Ignore handshake errors and proceed.
* want
Test want() method.
* wantread
Test timeout in handshake() and receive().
* wantwrite
Test timeout in send().
* want
Test want() method.

27
samples/alpn/client.lua Normal file
View File

@ -0,0 +1,27 @@
--
-- 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",
--alpn = {"foo","bar","baz"}
alpn = "foo"
}
local peer = socket.tcp()
peer:connect("127.0.0.1", 8888)
peer = assert( ssl.wrap(peer, params) )
assert(peer:dohandshake())
print("ALPN", peer:getalpn())
peer:close()

77
samples/alpn/server.lua Normal file
View File

@ -0,0 +1,77 @@
--
-- Public domain
--
local socket = require("socket")
local ssl = require("ssl")
--
-- Callback that selects one protocol from client's list.
--
local function alpncb01(protocols)
print("--- ALPN protocols from client")
for k, v in ipairs(protocols) do
print(k, v)
end
print("--- Selecting:", protocols[1])
return protocols[1]
end
--
-- Callback that returns a fixed list, ignoring the client's list.
--
local function alpncb02(protocols)
print("--- ALPN protocols from client")
for k, v in ipairs(protocols) do
print(k, v)
end
print("--- Returning a fixed list")
return {"bar", "foo"}
end
--
-- Callback that generates a list as it whishes.
--
local function alpncb03(protocols)
local resp = {}
print("--- ALPN protocols from client")
for k, v in ipairs(protocols) do
print(k, v)
if k%2 ~= 0 then resp[#resp+1] = v end
end
print("--- Returning an odd list")
return resp
end
local params = {
mode = "server",
protocol = "any",
key = "../certs/serverAkey.pem",
certificate = "../certs/serverA.pem",
cafile = "../certs/rootA.pem",
verify = {"peer", "fail_if_no_peer_cert"},
options = "all",
--alpn = alpncb01,
--alpn = alpncb02,
--alpn = alpncb03,
alpn = {"bar", "baz", "foo"},
}
-- [[ SSL context
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("ALPN", peer:getalpn())
peer:close()
server:close()

7
samples/certs/all.sh Executable file
View File

@ -0,0 +1,7 @@
#!/usr/bin/env sh
./rootA.sh
./rootB.sh
./clientA.sh
./clientB.sh
./serverA.sh
./serverB.sh

View File

@ -1,9 +1,9 @@
#!/bin/sh
#!/usr/bin/env sh
openssl req -newkey rsa:1024 -sha1 -keyout clientAkey.pem -out clientAreq.pem \
openssl req -newkey rsa:2048 -sha256 -keyout clientAkey.pem -out clientAreq.pem \
-nodes -config ./clientA.cnf -days 365 -batch
openssl x509 -req -in clientAreq.pem -sha1 -extfile ./clientA.cnf \
openssl x509 -req -in clientAreq.pem -sha256 -extfile ./clientA.cnf \
-extensions usr_cert -CA rootA.pem -CAkey rootAkey.pem -CAcreateserial \
-out clientAcert.pem -days 365

View File

@ -1,9 +1,9 @@
#!/bin/sh
#!/usr/bin/env sh
openssl req -newkey rsa:1024 -sha1 -keyout clientBkey.pem -out clientBreq.pem \
openssl req -newkey rsa:2048 -sha256 -keyout clientBkey.pem -out clientBreq.pem \
-nodes -config ./clientB.cnf -days 365 -batch
openssl x509 -req -in clientBreq.pem -sha1 -extfile ./clientB.cnf \
openssl x509 -req -in clientBreq.pem -sha256 -extfile ./clientB.cnf \
-extensions usr_cert -CA rootB.pem -CAkey rootBkey.pem -CAcreateserial \
-out clientBcert.pem -days 365

View File

@ -1,7 +1,7 @@
#!/bin/sh
#!/usr/bin/env sh
openssl req -newkey rsa:1024 -sha1 -keyout rootAkey.pem -out rootAreq.pem -nodes -config ./rootA.cnf -days 365 -batch
openssl req -newkey rsa:2048 -sha256 -keyout rootAkey.pem -out rootAreq.pem -nodes -config ./rootA.cnf -days 365 -batch
openssl x509 -req -in rootAreq.pem -sha1 -extfile ./rootA.cnf -extensions v3_ca -signkey rootAkey.pem -out rootA.pem -days 365
openssl x509 -req -in rootAreq.pem -sha256 -extfile ./rootA.cnf -extensions v3_ca -signkey rootAkey.pem -out rootA.pem -days 365
openssl x509 -subject -issuer -noout -in rootA.pem

View File

@ -1,7 +1,7 @@
#!/bin/sh
#!/usr/bin/env sh
openssl req -newkey rsa:1024 -sha1 -keyout rootBkey.pem -out rootBreq.pem -nodes -config ./rootB.cnf -days 365 -batch
openssl req -newkey rsa:2048 -sha256 -keyout rootBkey.pem -out rootBreq.pem -nodes -config ./rootB.cnf -days 365 -batch
openssl x509 -req -in rootBreq.pem -sha1 -extfile ./rootB.cnf -extensions v3_ca -signkey rootBkey.pem -out rootB.pem -days 365
openssl x509 -req -in rootBreq.pem -sha256 -extfile ./rootB.cnf -extensions v3_ca -signkey rootBkey.pem -out rootB.pem -days 365
openssl x509 -subject -issuer -noout -in rootB.pem

View File

@ -118,7 +118,7 @@ x509_extensions = v3_ca # The extensions to add to the self signed cert
# so use this option with caution!
string_mask = nombstr
# req_extensions = v3_req # The extensions to add to a certificate request
# req_extensions = v3_ext # The extensions to add to a certificate request
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
@ -198,7 +198,7 @@ authorityKeyIdentifier=keyid,issuer
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
subjectAltName=DNS:foo.bar.example
# Copy subject details
# issuerAltName=issuer:copy

View File

@ -1,9 +1,9 @@
#!/bin/sh
#!/usr/bin/env sh
openssl req -newkey rsa:1024 -keyout serverAkey.pem -out serverAreq.pem \
openssl req -newkey rsa:2048 -keyout serverAkey.pem -out serverAreq.pem \
-config ./serverA.cnf -nodes -days 365 -batch
openssl x509 -req -in serverAreq.pem -sha1 -extfile ./serverA.cnf \
openssl x509 -req -in serverAreq.pem -sha256 -extfile ./serverA.cnf \
-extensions usr_cert -CA rootA.pem -CAkey rootAkey.pem -CAcreateserial \
-out serverAcert.pem -days 365

View File

@ -195,7 +195,7 @@ authorityKeyIdentifier=keyid,issuer
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
subjectAltName=DNS:fnord.bar.example
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move

View File

@ -1,9 +1,9 @@
#!/bin/sh
#!/usr/bin/env sh
openssl req -newkey rsa:1024 -keyout serverBkey.pem -out serverBreq.pem \
openssl req -newkey rsa:2048 -keyout serverBkey.pem -out serverBreq.pem \
-config ./serverB.cnf -nodes -days 365 -batch
openssl x509 -req -in serverBreq.pem -sha1 -extfile ./serverB.cnf \
openssl x509 -req -in serverBreq.pem -sha256 -extfile ./serverB.cnf \
-extensions usr_cert -CA rootB.pem -CAkey rootBkey.pem -CAcreateserial \
-out serverBcert.pem -days 365

40
samples/dane/client.lua Normal file
View File

@ -0,0 +1,40 @@
local socket = require "socket";
local ssl = require "ssl";
local dns = require "lunbound".new();
local cfg = {
protocol = "tlsv1_2",
mode = "client",
ciphers = "DEFAULT",
capath = "/etc/ssl/certs",
verify = "peer",
dane = true,
};
local function daneconnect(host, port)
port = port or "443";
local conn = ssl.wrap(socket.connect(host, port), cfg);
local tlsa = dns:resolve("_" .. port .. "._tcp." .. host, 52);
assert(tlsa.secure, "Insecure DNS");
assert(conn:setdane(host));
for i = 1, tlsa.n do
local usage, selector, mtype = tlsa[i] :byte(1, 3);
assert(conn:settlsa(usage, selector, mtype, tlsa[i] :sub(4, - 1)));
end
assert(conn:dohandshake());
return conn;
end
if not ... then
print("Usage: client.lua example.com [port]");
return os.exit(1);
end
local conn = daneconnect(...);
print(conn:getpeerverification());

View File

@ -6,12 +6,13 @@ local ssl = require("ssl")
local params = {
mode = "client",
protocol = "tlsv1_2",
protocol = "any",
key = "../certs/clientAkey.pem",
certificate = "../certs/clientA.pem",
cafile = "../certs/rootA.pem",
verify = {"peer", "fail_if_no_peer_cert"},
options = "all",
ciphers = "EDH+AESGCM"
}
local peer = socket.tcp()

View File

@ -1,4 +1,4 @@
#!/bin/sh
#!/usr/bin/env sh
openssl dhparam -2 -out dh-512.pem -outform PEM 512
openssl dhparam -2 -out dh-1024.pem -outform PEM 1024

View File

@ -38,6 +38,7 @@ local params = {
verify = {"peer", "fail_if_no_peer_cert"},
options = "all",
dhparam = dhparam_cb,
ciphers = "EDH+AESGCM"
}

2
samples/key/genkey.sh Normal file → Executable file
View File

@ -1,3 +1,3 @@
#!/bin/sh
#!/usr/bin/env sh
openssl genrsa -des3 -out key.pem -passout pass:foobar 2048

View File

@ -23,6 +23,8 @@ while true do
assert( peer:dohandshake() )
--]]
peer:getpeercertificate():extensions()
print(peer:receive("*l"))
peer:close()
end

View File

@ -0,0 +1,29 @@
--
-- Public domain
--
local socket = require("socket")
local ssl = require("ssl")
local params = {
mode = "client",
protocol = "tlsv1_2",
key = "certs/clientECDSAkey.pem",
certificate = "certs/clientECDSA.pem",
verify = "none",
options = "all",
ciphers = "ALL:!aRSA"
}
local peer = socket.tcp()
peer:connect("127.0.0.1", 8888)
-- [[ SSL wrapper
peer = assert( ssl.wrap(peer, params) )
assert(peer:dohandshake())
--]]
local i = peer:info()
for k, v in pairs(i) do print(k, v) end
print(peer:receive("*l"))
peer:close()

View File

@ -0,0 +1,29 @@
--
-- Public domain
--
local socket = require("socket")
local ssl = require("ssl")
local params = {
mode = "client",
protocol = "tlsv1_2",
key = "certs/clientRSAkey.pem",
certificate = "certs/clientRSA.pem",
verify = "none",
options = "all",
ciphers = "ALL:!ECDSA"
}
local peer = socket.tcp()
peer:connect("127.0.0.1", 8888)
-- [[ SSL wrapper
peer = assert( ssl.wrap(peer, params) )
assert(peer:dohandshake())
--]]
local i = peer:info()
for k, v in pairs(i) do print(k, v) end
print(peer:receive("*l"))
peer:close()

13
samples/multicert/gencerts.sh Executable file
View File

@ -0,0 +1,13 @@
#!/usr/bin/env sh
mkdir -p certs
openssl ecparam -name secp256r1 -genkey -out certs/serverECDSAkey.pem
openssl req -new -config ../certs/serverA.cnf -extensions usr_cert -x509 -key certs/serverECDSAkey.pem -out certs/serverECDSA.pem -days 360 -batch
openssl ecparam -name secp256r1 -genkey -out certs/clientECDSAkey.pem
openssl req -config ../certs/clientA.cnf -extensions usr_cert -x509 -new -key certs/clientECDSAkey.pem -out certs/clientECDSA.pem -days 360 -batch
openssl req -config ../certs/serverB.cnf -extensions usr_cert -x509 -new -newkey rsa:2048 -keyout certs/serverRSAkey.pem -out certs/serverRSA.pem -nodes -days 365 -batch
openssl req -config ../certs/clientB.cnf -extensions usr_cert -x509 -new -newkey rsa:2048 -keyout certs/clientRSAkey.pem -out certs/clientRSA.pem -nodes -days 365 -batch

View File

@ -0,0 +1,38 @@
--
-- Public domain
--
local socket = require("socket")
local ssl = require("ssl")
local params = {
mode = "server",
protocol = "any",
certificates = {
-- Comment line below and 'client-rsa' stop working
{ certificate = "certs/serverRSA.pem", key = "certs/serverRSAkey.pem" },
-- Comment line below and 'client-ecdsa' stop working
{ certificate = "certs/serverECDSA.pem", key = "certs/serverECDSAkey.pem" }
},
verify = "none",
options = "all"
}
-- [[ SSL context
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()
-- [[ SSL wrapper
peer = assert( ssl.wrap(peer, ctx) )
assert( peer:dohandshake() )
--]]
peer:send("oneshot test\n")
peer:close()

54
samples/ocsp/client.lua Normal file
View File

@ -0,0 +1,54 @@
--
-- Public domain
--
local socket = require("socket")
local ssl = require("ssl")
local ocsp = ssl.ocsp
-- Parameters
-- * status:
-- * nil (no status was sent by server)
-- * ocsp.status.successful
-- * ocsp.status.malformedrequest
-- * ocsp.status.internalerror
-- * ocsp.status.trylater
-- * ocsp.status.sigrequired
-- * ocsp.status.unauthorized
--
-- Returns
-- * nil: on error
-- * true: status was accepted (continue the handshake)
-- * false: status not accepted (handshake stops with error)
--
local callback = function(status)
print("Status: ", status)
print("---")
if status == nil then
print("[WARN] No OCSP response")
return true
end
return (status == ocsp.status.successful)
end
local params = {
mode = "client",
protocol = "tlsv1_2",
verify = "none",
options = "all",
ocsp = callback,
}
while true do
local peer = socket.tcp()
peer:connect("127.0.0.1", 8443)
peer = assert(ssl.wrap(peer, params))
assert(peer:dohandshake())
print(peer:receive())
print("------------")
peer:close()
end

89
samples/ocsp/server.lua Normal file
View File

@ -0,0 +1,89 @@
--
-- Public domain
--
local socket = require("socket")
local ssl = require("ssl")
local mime = require("mime")
local ltn12 = require("ltn12")
local http = require("socket.http")
local ocsp = ssl.ocsp
--------------------------------------------------------------------------------
local response
function loadresponse(certfile, cafile)
local f = io.open(cafile)
local ca = f:read("*a")
ca = ssl.loadcertificate(ca)
f:close()
f = io.open(certfile)
local cert = f:read("*a")
cert = ssl.loadcertificate(cert)
f:close()
local res = {}
local req = ocsp.buildrequest(cert, ca)
req = mime.b64(req)
local a, b = http.request {
url = "http://zerossl.ocsp.sectigo.com/" .. req,
method = "GET",
sink = ltn12.sink.table(res),
header = {
["Content-Type"] = "application/ocsp-request",
["Host"] = "zerossl.ocsp.sectigo.com",
},
}
response = table.concat(res)
local thisupd, nextupd = ocsp.responsetime(response)
print("This update: ", thisupd)
print("Next update: ", nextupd)
end
--------------------------------------------------------------------------------
local cafile = "ca.pem"
local certfile = "server.pem"
-- Remember to update 'response' before 'next update'
local callback = function()
if not response then
loadresponse(certfile, cafile)
end
return response
end
local params = {
mode = "server",
protocol = "any",
key = "server.key",
certificate = certfile,
verify = "none",
options = "all",
ocsp = callback,
}
--------------------------------------------------------------------------------
local ctx = assert(ssl.newcontext(params))
local server = socket.tcp()
server:setoption('reuseaddr', true)
assert(server:bind("127.0.0.1", 8443))
server:listen()
while true do
local peer = server:accept()
peer = assert(ssl.wrap(peer, ctx))
local succ = peer:dohandshake()
if succ then
peer:send("OCSP test\n")
peer:close()
end
end

View File

@ -25,7 +25,7 @@ MAC_LDFLAGS=-bundle -undefined dynamic_lookup $(LIBDIR)
INSTALL = install
CC ?= cc
LD ?= $(MYENV) cc
CCLD ?= $(MYENV) $(CC)
CFLAGS += $(MYCFLAGS)
LDFLAGS += $(MYLDFLAGS)
@ -52,7 +52,7 @@ luasocket:
@cd luasocket && $(MAKE)
$(CMOD): $(EXTRA) $(OBJS)
$(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
$(CCLD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
clean:
cd luasocket && $(MAKE) clean
@ -61,6 +61,6 @@ clean:
options.o: options.h options.c
ec.o: ec.c ec.h
x509.o: x509.c x509.h compat.h
context.o: context.c context.h ec.h compat.h
context.o: context.c context.h ec.h compat.h options.h
ssl.o: ssl.c ssl.h context.h x509.h compat.h
config.o: config.c ec.h options.h compat.h

View File

@ -1,19 +1,25 @@
/*--------------------------------------------------------------------------
* LuaSec 0.7.2
* LuaSec 1.0.1
*
* Copyright (C) 2006-2019 Bruno Silvestre
* Copyright (C) 2006-2021 Bruno Silvestre
*
*--------------------------------------------------------------------------*/
#ifndef LSEC_COMPAT_H
#define LSEC_COMPAT_H
#include <openssl/ssl.h>
//------------------------------------------------------------------------------
#if defined(_WIN32)
#define LSEC_API __declspec(dllexport)
#else
#define LSEC_API extern
#endif
//------------------------------------------------------------------------------
#if (LUA_VERSION_NUM == 501)
#define luaL_testudata(L, ud, tname) lsec_testudata(L, ud, tname)
@ -28,4 +34,24 @@
#define setfuncs(L, R) luaL_setfuncs(L, R, 0)
#endif
//------------------------------------------------------------------------------
#if (!defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x1010000fL))
#define LSEC_ENABLE_DANE
#endif
//------------------------------------------------------------------------------
#if !((defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER < 0x2070000fL)) || (OPENSSL_VERSION_NUMBER < 0x1010000fL))
#define LSEC_API_OPENSSL_1_1_0
#endif
//------------------------------------------------------------------------------
#if !defined(LIBRESSL_VERSION_NUMBER) && ((OPENSSL_VERSION_NUMBER & 0xFFFFF000L) == 0x10101000L)
#define LSEC_OPENSSL_1_1_1
#endif
//------------------------------------------------------------------------------
#endif

View File

@ -1,7 +1,7 @@
/*--------------------------------------------------------------------------
* LuaSec 0.7.2
* LuaSec 1.0.1
*
* Copyright (C) 2006-2019 Bruno Silvestre.
* Copyright (C) 2006-2021 Bruno Silvestre.
*
*--------------------------------------------------------------------------*/
@ -32,22 +32,21 @@ LSEC_API int luaopen_ssl_config(lua_State *L)
lua_pushstring(L, "protocols");
lua_newtable(L);
#ifndef OPENSSL_NO_SSL3
lua_pushstring(L, "sslv3");
lua_pushboolean(L, 1);
lua_rawset(L, -3);
#endif
lua_pushstring(L, "tlsv1");
lua_pushboolean(L, 1);
lua_rawset(L, -3);
#if (OPENSSL_VERSION_NUMBER >= 0x1000100fL)
lua_pushstring(L, "tlsv1_1");
lua_pushboolean(L, 1);
lua_rawset(L, -3);
lua_pushstring(L, "tlsv1_2");
lua_pushboolean(L, 1);
lua_rawset(L, -3);
#ifdef TLS1_3_VERSION
lua_pushstring(L, "tlsv1_3");
lua_pushboolean(L, 1);
lua_rawset(L, -3);
#endif
lua_rawset(L, -3);
// Algorithms
@ -70,17 +69,32 @@ LSEC_API int luaopen_ssl_config(lua_State *L)
lua_pushstring(L, "capabilities");
lua_newtable(L);
// ALPN
lua_pushstring(L, "alpn");
lua_pushboolean(L, 1);
lua_rawset(L, -3);
#ifdef LSEC_ENABLE_DANE
// DANE
lua_pushstring(L, "dane");
lua_pushboolean(L, 1);
lua_rawset(L, -3);
#endif
#ifndef OPENSSL_NO_OCSP
// OCSP
lua_pushstring(L, "ocsp");
lua_pushboolean(L, 1);
lua_rawset(L, -3);
#endif
#ifndef OPENSSL_NO_EC
#if defined(SSL_CTRL_SET_ECDH_AUTO) || defined(SSL_CTRL_SET_CURVES_LIST) || defined(SSL_CTX_set1_curves_list)
lua_pushstring(L, "curves_list");
lua_pushboolean(L, 1);
lua_rawset(L, -3);
#ifdef SSL_CTRL_SET_ECDH_AUTO
lua_pushstring(L, "ecdh_auto");
lua_pushboolean(L, 1);
lua_rawset(L, -3);
#endif
#endif
#endif
lua_rawset(L, -3);

View File

@ -1,9 +1,9 @@
/*--------------------------------------------------------------------------
* LuaSec 0.7.2
* LuaSec 1.0.1
*
* Copyright (C) 2014-2019 Kim Alvefur, Paul Aurich, Tobias Markmann,
* Copyright (C) 2014-2021 Kim Alvefur, Paul Aurich, Tobias Markmann,
* Matthew Wild.
* Copyright (C) 2006-2019 Bruno Silvestre.
* Copyright (C) 2006-2021 Bruno Silvestre.
*
*--------------------------------------------------------------------------*/
@ -17,24 +17,25 @@
#include <openssl/err.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/dh.h>
#ifndef OPENSSL_NO_OCSP
#include <openssl/ocsp.h>
#endif
#include <lua.h>
#include <lauxlib.h>
#include "compat.h"
#include "context.h"
#include "options.h"
#include "x509.h"
#ifndef OPENSSL_NO_EC
#include <openssl/ec.h>
#include "ec.h"
#endif
#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
typedef const SSL_METHOD LSEC_SSL_METHOD;
#else
typedef SSL_METHOD LSEC_SSL_METHOD;
#endif
/*--------------------------- Auxiliary Functions ----------------------------*/
/**
@ -65,23 +66,59 @@ static int set_option_flag(const char *opt, unsigned long *flag)
return 0;
}
#ifndef LSEC_API_OPENSSL_1_1_0
/**
* Find the protocol.
*/
static LSEC_SSL_METHOD* str2method(const char *method)
static const SSL_METHOD* str2method(const char *method, int *vmin, int *vmax)
{
(void)vmin;
(void)vmax;
if (!strcmp(method, "any")) return SSLv23_method();
if (!strcmp(method, "sslv23")) return SSLv23_method(); // deprecated
#ifndef OPENSSL_NO_SSL3
if (!strcmp(method, "sslv3")) return SSLv3_method();
#endif
if (!strcmp(method, "tlsv1")) return TLSv1_method();
#if (OPENSSL_VERSION_NUMBER >= 0x1000100fL)
if (!strcmp(method, "tlsv1_1")) return TLSv1_1_method();
if (!strcmp(method, "tlsv1_2")) return TLSv1_2_method();
return NULL;
}
#else
/**
* Find the protocol.
*/
static const SSL_METHOD* str2method(const char *method, int *vmin, int *vmax)
{
if (!strcmp(method, "any") || !strcmp(method, "sslv23")) { // 'sslv23' is deprecated
*vmin = 0;
*vmax = 0;
return TLS_method();
}
else if (!strcmp(method, "tlsv1")) {
*vmin = TLS1_VERSION;
*vmax = TLS1_VERSION;
return TLS_method();
}
else if (!strcmp(method, "tlsv1_1")) {
*vmin = TLS1_1_VERSION;
*vmax = TLS1_1_VERSION;
return TLS_method();
}
else if (!strcmp(method, "tlsv1_2")) {
*vmin = TLS1_2_VERSION;
*vmax = TLS1_2_VERSION;
return TLS_method();
}
#if defined(TLS1_3_VERSION)
else if (!strcmp(method, "tlsv1_3")) {
*vmin = TLS1_3_VERSION;
*vmax = TLS1_3_VERSION;
return TLS_method();
}
#endif
return NULL;
}
#endif
/**
* Prepare the SSL handshake verify flag.
@ -168,7 +205,6 @@ static DH *dhparam_cb(SSL *ssl, int is_export, int keylength)
{
BIO *bio;
lua_State *L;
DH *dh_tmp = NULL;
SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
p_context pctx = (p_context)SSL_CTX_get_app_data(ctx);
@ -189,24 +225,15 @@ static DH *dhparam_cb(SSL *ssl, int is_export, int keylength)
lua_pop(L, 2); /* Remove values from stack */
return NULL;
}
bio = BIO_new_mem_buf((void*)lua_tostring(L, -1),
lua_rawlen(L, -1));
bio = BIO_new_mem_buf((void*)lua_tostring(L, -1), lua_rawlen(L, -1));
if (bio) {
dh_tmp = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
pctx->dh_param = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
BIO_free(bio);
}
/*
* OpenSSL exepcts the callback to maintain a reference to the DH*. So,
* cache it here, and clean up the previous set of parameters. Any remaining
* set is cleaned up when destroying the LuaSec context.
*/
if (pctx->dh_param)
DH_free(pctx->dh_param);
pctx->dh_param = dh_tmp;
lua_pop(L, 2); /* Remove values from stack */
return dh_tmp;
return pctx->dh_param;
}
/**
@ -287,10 +314,11 @@ static int create(lua_State *L)
{
p_context ctx;
const char *str_method;
LSEC_SSL_METHOD *method;
const SSL_METHOD *method;
int vmin, vmax;
str_method = luaL_checkstring(L, 1);
method = str2method(str_method);
method = str2method(str_method, &vmin, &vmax);
if (!method) {
lua_pushnil(L);
lua_pushfstring(L, "invalid protocol (%s)", str_method);
@ -310,6 +338,10 @@ static int create(lua_State *L)
ERR_reason_error_string(ERR_get_error()));
return 2;
}
#ifdef LSEC_API_OPENSSL_1_1_0
SSL_CTX_set_min_proto_version(ctx->context, vmin);
SSL_CTX_set_max_proto_version(ctx->context, vmax);
#endif
ctx->mode = LSEC_MODE_INVALID;
ctx->L = L;
luaL_getmetatable(L, "SSL:Context");
@ -411,14 +443,31 @@ static int set_cipher(lua_State *L)
const char *list = luaL_checkstring(L, 2);
if (SSL_CTX_set_cipher_list(ctx, list) != 1) {
lua_pushboolean(L, 0);
lua_pushfstring(L, "error setting cipher list (%s)",
ERR_reason_error_string(ERR_get_error()));
lua_pushfstring(L, "error setting cipher list (%s)", ERR_reason_error_string(ERR_get_error()));
return 2;
}
lua_pushboolean(L, 1);
return 1;
}
/**
* Set the cipher suites.
*/
static int set_ciphersuites(lua_State *L)
{
#if defined(TLS1_3_VERSION)
SSL_CTX *ctx = lsec_checkcontext(L, 1);
const char *list = luaL_checkstring(L, 2);
if (SSL_CTX_set_ciphersuites(ctx, list) != 1) {
lua_pushboolean(L, 0);
lua_pushfstring(L, "error setting cipher list (%s)", ERR_reason_error_string(ERR_get_error()));
return 2;
}
#endif
lua_pushboolean(L, 1);
return 1;
}
/**
* Set the depth for certificate checking.
*/
@ -467,12 +516,6 @@ static int set_options(lua_State *L)
if (max > 1) {
for (i = 2; i <= max; i++) {
str = luaL_checkstring(L, i);
#if !defined(SSL_OP_NO_COMPRESSION) && (OPENSSL_VERSION_NUMBER >= 0x0090800f) && (OPENSSL_VERSION_NUMBER < 0x1000000fL)
/* Version 0.9.8 has a different way to disable compression */
if (!strcmp(str, "no_compression"))
ctx->comp_methods = NULL;
else
#endif
if (!set_option_flag(str, &flag)) {
lua_pushboolean(L, 0);
lua_pushfstring(L, "invalid option (%s)", str);
@ -531,12 +574,13 @@ static int set_dhparam(lua_State *L)
static int set_curve(lua_State *L)
{
long ret;
EC_KEY *key = NULL;
SSL_CTX *ctx = lsec_checkcontext(L, 1);
const char *str = luaL_checkstring(L, 2);
SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE);
EC_KEY *key = lsec_find_ec_key(L, str);
key = lsec_find_ec_key(L, str);
if (!key) {
lua_pushboolean(L, 0);
@ -558,9 +602,7 @@ static int set_curve(lua_State *L)
lua_pushboolean(L, 1);
return 1;
}
#endif
#if !defined(OPENSSL_NO_EC) && (defined(SSL_CTRL_SET_CURVES_LIST) || defined(SSL_CTX_set1_curves_list) || defined(SSL_CTRL_SET_ECDH_AUTO))
/**
* Set elliptic curves list.
*/
@ -577,8 +619,8 @@ static int set_curves_list(lua_State *L)
return 2;
}
#ifdef SSL_CTRL_SET_ECDH_AUTO
SSL_CTX_set_ecdh_auto(ctx, 1);
#if defined(LIBRESSL_VERSION_NUMBER) || !defined(LSEC_API_OPENSSL_1_1_0)
(void)SSL_CTX_set_ecdh_auto(ctx, 1);
#endif
lua_pushboolean(L, 1);
@ -586,6 +628,296 @@ static int set_curves_list(lua_State *L)
}
#endif
/**
* Set the protocols a client should send for ALPN.
*/
static int set_alpn(lua_State *L)
{
long ret;
size_t len;
p_context ctx = checkctx(L, 1);
const char *str = luaL_checklstring(L, 2, &len);
ret = SSL_CTX_set_alpn_protos(ctx->context, (const unsigned char*)str, len);
if (ret) {
lua_pushboolean(L, 0);
lua_pushfstring(L, "error setting ALPN (%s)", ERR_reason_error_string(ERR_get_error()));
return 2;
}
lua_pushboolean(L, 1);
return 1;
}
/**
* This standard callback calls the server's callback in Lua sapce.
* The server has to return a list in wire-format strings.
* This function uses a helper function to match server and client lists.
*/
static int alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen,
const unsigned char *in, unsigned int inlen, void *arg)
{
int ret;
size_t server_len;
const char *server;
p_context ctx = (p_context)arg;
lua_State *L = ctx->L;
luaL_getmetatable(L, "SSL:ALPN:Registry");
lua_pushlightuserdata(L, (void*)ctx->context);
lua_gettable(L, -2);
lua_pushlstring(L, (const char*)in, inlen);
lua_call(L, 1, 1);
if (!lua_isstring(L, -1)) {
lua_pop(L, 2);
return SSL_TLSEXT_ERR_NOACK;
}
// Protocol list from server in wire-format string
server = luaL_checklstring(L, -1, &server_len);
ret = SSL_select_next_proto((unsigned char**)out, outlen, (const unsigned char*)server,
server_len, in, inlen);
if (ret != OPENSSL_NPN_NEGOTIATED) {
lua_pop(L, 2);
return SSL_TLSEXT_ERR_NOACK;
}
// Copy the result because lua_pop() can collect the pointer
ctx->alpn = malloc(*outlen);
memcpy(ctx->alpn, (void*)*out, *outlen);
*out = (const unsigned char*)ctx->alpn;
lua_pop(L, 2);
return SSL_TLSEXT_ERR_OK;
}
/**
* Set a callback a server can use to select the next protocol with ALPN.
*/
static int set_alpn_cb(lua_State *L)
{
p_context ctx = checkctx(L, 1);
luaL_getmetatable(L, "SSL:ALPN:Registry");
lua_pushlightuserdata(L, (void*)ctx->context);
lua_pushvalue(L, 2);
lua_settable(L, -3);
SSL_CTX_set_alpn_select_cb(ctx->context, alpn_cb, ctx);
lua_pushboolean(L, 1);
return 1;
}
#ifndef OPENSSL_NO_OCSP
static int ocsp_server_cb(SSL *ssl, void *arg)
{
int len;
BIO *bio;
const char *data;
unsigned char *r = NULL;
OCSP_RESPONSE *resp = NULL;
p_context ctx = (p_context)arg;
lua_State *L = ctx->L;
// Retrieve the callback
luaL_getmetatable(L, "SSL:OCSP:Registry");
lua_pushlightuserdata(L, ctx->context);
lua_rawget(L, -2);
lua_call(L, 0, 1);
if (lua_type(L, -1) != LUA_TSTRING) {
return SSL_TLSEXT_ERR_NOACK;
}
data = lua_tostring(L, -1);
len = (int)lua_rawlen(L, -1);
bio = BIO_new_mem_buf(data, len);
if (bio == NULL)
return SSL_TLSEXT_ERR_NOACK;
resp = d2i_OCSP_RESPONSE_bio(bio, NULL);
BIO_free(bio);
if (resp == NULL)
return SSL_TLSEXT_ERR_NOACK;
len = i2d_OCSP_RESPONSE(resp, &r);
if (len <= 0) {
OCSP_RESPONSE_free(resp);
return SSL_TLSEXT_ERR_NOACK;
}
SSL_set_tlsext_status_ocsp_resp(ssl, r, len);
OCSP_RESPONSE_free(resp);
return SSL_TLSEXT_ERR_OK;
}
static int ocsp_client_cb(SSL *ssl, void *arg)
{
long len;
const unsigned char *b;
OCSP_RESPONSE *ocsp = NULL;
p_context ctx = (p_context)arg;
lua_State *L = ctx->L;
// Retrieve the callback
luaL_getmetatable(L, "SSL:OCSP:Registry");
lua_pushlightuserdata(L, ctx->context);
lua_rawget(L, -2);
len = SSL_get_tlsext_status_ocsp_resp(ssl, &b);
if (len == -1)
lua_pushnil(L);
else {
ocsp = d2i_OCSP_RESPONSE(NULL, &b, len);
lua_pushinteger(L, OCSP_response_status(ocsp));
OCSP_RESPONSE_free(ocsp);
}
lua_call(L, 1, 1);
return (lua_type(L, -1) != LUA_TBOOLEAN) ? -1 : (int)lua_toboolean(L, -1);
}
static int set_ocsp_cb(lua_State *L)
{
int ret;
p_context ctx = checkctx(L, 1);
luaL_getmetatable(L, "SSL:OCSP:Registry");
lua_pushlightuserdata(L, (void*)ctx->context);
lua_pushvalue(L, 2);
lua_settable(L, -3);
ret = (int)SSL_CTX_set_tlsext_status_type(ctx->context, TLSEXT_STATUSTYPE_ocsp);
if (ret == 0) {
lua_pushboolean(L, 0);
return 1;
}
if (ctx->mode == LSEC_MODE_CLIENT)
ret = (int)SSL_CTX_set_tlsext_status_cb(ctx->context, ocsp_client_cb);
else
ret = (int)SSL_CTX_set_tlsext_status_cb(ctx->context, ocsp_server_cb);
if (ret == 0) {
lua_pushboolean(L, 0);
return 1;
}
ret = (int)SSL_CTX_set_tlsext_status_arg(ctx->context, ctx);
lua_pushboolean(L, ret == 1);
return 1;
}
static int ocsp_build_request(lua_State *L)
{
long len;
BIO *bio;
X509 *cert;
X509 *issuer;
OCSP_CERTID *cid;
OCSP_REQUEST *req;
char *buf;
cert = lsec_checkx509(L, 1);
issuer = lsec_checkx509(L, 2);
req = OCSP_REQUEST_new();
if (req == NULL) {
lua_pushnil(L);
return 1;
}
cid = OCSP_cert_to_id(NULL, cert, issuer);
if (cid == NULL) {
lua_pushnil(L);
return 1;
}
if (OCSP_request_add0_id(req, cid) == NULL) {
lua_pushnil(L);
return 1;
}
bio = BIO_new(BIO_s_mem());
i2d_OCSP_REQUEST_bio(bio, req);
len = BIO_get_mem_data(bio, &buf);
lua_pushlstring(L, buf, len);
BIO_free(bio);
OCSP_REQUEST_free(req);
return 1;
}
static int ocsp_response_time(lua_State *L)
{
long len;
BIO *bio;
char *buf;
int reason;
OCSP_BASICRESP *bs;
OCSP_SINGLERESP *sr;
OCSP_RESPONSE *res;
ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd;
buf = (char*)lua_tostring(L, 1);
len = (long)lua_rawlen(L, 1);
res = d2i_OCSP_RESPONSE(NULL, (const unsigned char**)&buf, (int)len);
if (res == NULL) {
lua_pushnil(L);
lua_pushnil(L);
return 2;
}
bs = OCSP_response_get1_basic(res);
if (bs == NULL) {
lua_pushnil(L);
lua_pushnil(L);
return 2;
}
sr = OCSP_resp_get0(bs, 0);
OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
bio = BIO_new(BIO_s_mem());
ASN1_GENERALIZEDTIME_print(bio, thisupd);
len = BIO_get_mem_data(bio, &buf);
lua_pushlstring(L, buf, len);
BIO_free(bio);
bio = BIO_new(BIO_s_mem());
ASN1_GENERALIZEDTIME_print(bio, nextupd);
len = BIO_get_mem_data(bio, &buf);
lua_pushlstring(L, buf, len);
BIO_free(bio);
OCSP_BASICRESP_free(bs);
OCSP_RESPONSE_free(res);
return 2;
}
#endif
#if defined(LSEC_ENABLE_DANE)
/*
* DANE
*/
static int set_dane(lua_State *L)
{
int ret;
SSL_CTX *ctx = lsec_checkcontext(L, 1);
ret = SSL_CTX_dane_enable(ctx);
lua_pushboolean(L, (ret > 0));
return 1;
}
#endif
/**
* Package functions
*/
@ -595,21 +927,25 @@ static luaL_Reg funcs[] = {
{"loadcert", load_cert},
{"loadkey", load_key},
{"checkkey", check_key},
{"setalpn", set_alpn},
{"setalpncb", set_alpn_cb},
{"setcipher", set_cipher},
{"setciphersuites", set_ciphersuites},
{"setdepth", set_depth},
{"setdhparam", set_dhparam},
{"setverify", set_verify},
{"setoptions", set_options},
{"setmode", set_mode},
#if !defined(OPENSSL_NO_EC)
{"setcurve", set_curve},
#endif
#if !defined(OPENSSL_NO_EC) && (defined(SSL_CTRL_SET_CURVES_LIST) || defined(SSL_CTX_set1_curves_list) || defined(SSL_CTRL_SET_ECDH_AUTO))
{"setcurveslist", set_curves_list},
#endif
#if defined(LSEC_ENABLE_DANE)
{"setdane", set_dane},
#endif
#if !defined(OPENSSL_NO_OCSP)
{"setocspcb", set_ocsp_cb},
#endif
{NULL, NULL}
};
@ -631,15 +967,18 @@ static int meth_destroy(lua_State *L)
lua_pushlightuserdata(L, (void*)ctx->context);
lua_pushnil(L);
lua_settable(L, -3);
luaL_getmetatable(L, "SSL:ALPN:Registry");
lua_pushlightuserdata(L, (void*)ctx->context);
lua_pushnil(L);
lua_settable(L, -3);
luaL_getmetatable(L, "SSL:OCSP:Registry");
lua_pushlightuserdata(L, (void*)ctx->context);
lua_pushnil(L);
lua_settable(L, -3);
SSL_CTX_free(ctx->context);
ctx->context = NULL;
}
if (ctx->dh_param) {
DH_free(ctx->dh_param);
ctx->dh_param = NULL;
}
return 0;
}
@ -711,6 +1050,7 @@ static int meth_set_verify_ext(lua_State *L)
* Context metamethods.
*/
static luaL_Reg meta[] = {
{"__close", meth_destroy},
{"__gc", meth_destroy},
{"__tostring", meth_tostring},
{NULL, NULL}
@ -772,13 +1112,64 @@ void *lsec_testudata (lua_State *L, int ud, const char *tname) {
/*------------------------------ Initialization ------------------------------*/
#ifndef OPENSSL_NO_OCSP
struct ocsp_status_response_s {
const char *name;
int value;
};
typedef struct ocsp_status_response_s ocsp_status_response_t;
static ocsp_status_response_t status_response[] = {
{"successful", OCSP_RESPONSE_STATUS_SUCCESSFUL},
{"malformedrequest", OCSP_RESPONSE_STATUS_MALFORMEDREQUEST},
{"internalerror", OCSP_RESPONSE_STATUS_INTERNALERROR},
{"trylater", OCSP_RESPONSE_STATUS_TRYLATER},
{"sigrequired", OCSP_RESPONSE_STATUS_SIGREQUIRED},
{"unauthorized", OCSP_RESPONSE_STATUS_UNAUTHORIZED},
{NULL, 0}
};
static luaL_Reg ocsp_funcs[] = {
{"buildrequest", ocsp_build_request},
{"responsetime", ocsp_response_time},
{NULL, NULL}
};
/**
* OCSP module
*/
LSEC_API int luaopen_ssl_context_ocsp(lua_State *L)
{
ocsp_status_response_t *ptr;
luaL_newlib(L, ocsp_funcs);
lua_pushstring(L, "status");
lua_newtable(L);
for (ptr = status_response; ptr->name; ptr++) {
lua_pushstring(L, ptr->name);
lua_pushinteger(L, ptr->value);
lua_rawset(L, -3);
}
lua_rawset(L, -3);
return 1;
}
#endif
//------------------------------------------------------------------------------
/**
* Registre the module.
*/
LSEC_API int luaopen_ssl_context(lua_State *L)
{
luaL_newmetatable(L, "SSL:DH:Registry"); /* Keep all DH callbacks */
luaL_newmetatable(L, "SSL:ALPN:Registry"); /* Keep all ALPN callbacks */
luaL_newmetatable(L, "SSL:Verify:Registry"); /* Keep all verify flags */
luaL_newmetatable(L, "SSL:OCSP:Registry"); /* Keep all OCSP callbacks */
luaL_newmetatable(L, "SSL:Context");
setfuncs(L, meta);

View File

@ -2,9 +2,9 @@
#define LSEC_CONTEXT_H
/*--------------------------------------------------------------------------
* LuaSec 0.7.2
* LuaSec 1.0.1
*
* Copyright (C) 2006-2019 Bruno Silvestre
* Copyright (C) 2006-2021 Bruno Silvestre
*
*--------------------------------------------------------------------------*/
@ -24,6 +24,7 @@ typedef struct t_context_ {
SSL_CTX *context;
lua_State *L;
DH *dh_param;
void *alpn;
int mode;
} t_context;
typedef t_context* p_context;

View File

@ -2,7 +2,7 @@
#include "ec.h"
#ifndef OPENSSL_NO_ECDH
#ifndef OPENSSL_NO_EC
EC_KEY *lsec_find_ec_key(lua_State *L, const char *str)
{
@ -56,25 +56,24 @@ void lsec_load_curves(lua_State *L)
lua_pushnumber(L, curves[i].nid);
lua_rawset(L, -3);
break;
#ifdef NID_X25519
case NID_X25519:
lua_pushstring(L, "X25519");
lua_pushnumber(L, curves[i].nid);
lua_rawset(L, -3);
break;
#endif
#ifdef NID_X448
case NID_X448:
lua_pushstring(L, "X448");
lua_pushnumber(L, curves[i].nid);
lua_rawset(L, -3);
break;
#endif
}
}
free(curves);
}
/* These are special so are manually added here */
#ifdef NID_X25519
lua_pushstring(L, "X25519");
lua_pushnumber(L, NID_X25519);
lua_rawset(L, -3);
#endif
#ifdef NID_X448
lua_pushstring(L, "X448");
lua_pushnumber(L, NID_X448);
lua_rawset(L, -3);
#endif
lua_rawset(L, LUA_REGISTRYINDEX);
}

View File

@ -1,7 +1,7 @@
/*--------------------------------------------------------------------------
* LuaSec 0.7.2
* LuaSec 1.0.1
*
* Copyright (C) 2006-2019 Bruno Silvestre
* Copyright (C) 2006-2021 Bruno Silvestre
*
*--------------------------------------------------------------------------*/
@ -10,7 +10,7 @@
#include <lua.h>
#ifndef OPENSSL_NO_ECDH
#ifndef OPENSSL_NO_EC
#include <openssl/ec.h>
EC_KEY *lsec_find_ec_key(lua_State *L, const char *str);

View File

@ -1,6 +1,6 @@
----------------------------------------------------------------------------
-- LuaSec 0.7.2
-- Copyright (C) 2009-2019 PUC-Rio
-- LuaSec 1.0.1
-- Copyright (C) 2009-2021 PUC-Rio
--
-- Author: Pablo Musa
-- Author: Tomas Guisasola
@ -18,15 +18,16 @@ local try = socket.try
-- Module
--
local _M = {
_VERSION = "0.7.2",
_COPYRIGHT = "LuaSec 0.7.2 - Copyright (C) 2009-2019 PUC-Rio",
_VERSION = "1.0.1",
_COPYRIGHT = "LuaSec 1.0.1 - Copyright (C) 2009-2021 PUC-Rio",
PORT = 443,
TIMEOUT = 60
}
-- TLS configuration
local cfg = {
protocol = "any",
options = {"all", "no_sslv2", "no_sslv3"},
options = {"all", "no_sslv2", "no_sslv3", "no_tlsv1"},
verify = "none",
}
@ -83,13 +84,14 @@ local function tcp(params)
conn.sock = try(socket.tcp())
local st = getmetatable(conn.sock).__index.settimeout
function conn:settimeout(...)
return st(self.sock, ...)
return st(self.sock, _M.TIMEOUT)
end
-- Replace TCP's connection function
function conn:connect(host, port)
try(self.sock:connect(host, port))
self.sock = try(ssl.wrap(self.sock, params))
self.sock:sni(host)
self.sock:settimeout(_M.TIMEOUT)
try(self.sock:dohandshake())
reg(self, getmetatable(self.sock))
return 1
@ -139,5 +141,6 @@ end
--
_M.request = request
_M.tcp = tcp
return _M

View File

@ -107,10 +107,16 @@ int buffer_meth_send(lua_State *L, p_buffer buf) {
* object:receive() interface
\*-------------------------------------------------------------------------*/
int buffer_meth_receive(lua_State *L, p_buffer buf) {
int err = IO_DONE, top = lua_gettop(L);
luaL_Buffer b;
size_t size;
const char *part = luaL_optlstring(L, 3, "", &size);
const char *part;
int err = IO_DONE;
int top = lua_gettop(L);
if (top < 3) {
lua_settop(L, 3);
top = 3;
}
part = luaL_optlstring(L, 3, "", &size);
#ifdef LUASOCKET_DEBUG
p_timeout tm = timeout_markstart(buf->tm);
#endif

View File

@ -1,7 +1,7 @@
/*--------------------------------------------------------------------------
* LuaSec 0.7.2
* LuaSec 1.0.1
*
* Copyright (C) 2006-2019 Bruno Silvestre
* Copyright (C) 2006-2021 Bruno Silvestre
*
*--------------------------------------------------------------------------*/

View File

@ -2,9 +2,9 @@
#define LSEC_OPTIONS_H
/*--------------------------------------------------------------------------
* LuaSec 0.7.2
* LuaSec 1.0.1
*
* Copyright (C) 2006-2019 Bruno Silvestre
* Copyright (C) 2006-2021 Bruno Silvestre
*
*--------------------------------------------------------------------------*/

View File

@ -18,9 +18,9 @@ end
local function generate(options, version)
print([[
/*--------------------------------------------------------------------------
* LuaSec 0.7.2
* LuaSec 1.0.1
*
* Copyright (C) 2006-2019 Bruno Silvestre
* Copyright (C) 2006-2021 Bruno Silvestre
*
*--------------------------------------------------------------------------*/

View File

@ -1,9 +1,9 @@
/*--------------------------------------------------------------------------
* LuaSec 0.7.2
* LuaSec 1.0.1
*
* Copyright (C) 2014-2019 Kim Alvefur, Paul Aurich, Tobias Markmann,
* Copyright (C) 2014-2021 Kim Alvefur, Paul Aurich, Tobias Markmann,
* Matthew Wild.
* Copyright (C) 2006-2019 Bruno Silvestre.
* Copyright (C) 2006-2021 Bruno Silvestre.
*
*--------------------------------------------------------------------------*/
@ -11,13 +11,14 @@
#include <string.h>
#if defined(WIN32)
#include <Winsock2.h>
#include <winsock2.h>
#endif
#include <openssl/ssl.h>
#include <openssl/x509v3.h>
#include <openssl/x509_vfy.h>
#include <openssl/err.h>
#include <openssl/dh.h>
#include <lua.h>
#include <lauxlib.h>
@ -32,7 +33,7 @@
#include "ssl.h"
#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER<0x10100000L
#ifndef LSEC_API_OPENSSL_1_1_0
#define SSL_is_server(s) (s->server)
#define SSL_up_ref(ssl) CRYPTO_add(&(ssl)->references, 1, CRYPTO_LOCK_SSL)
#define X509_up_ref(c) CRYPTO_add(&c->references, 1, CRYPTO_LOCK_X509)
@ -47,6 +48,11 @@ static int lsec_socket_error()
#if defined(WIN32)
return WSAGetLastError();
#else
#if defined(LSEC_OPENSSL_1_1_1)
// Bug in OpenSSL 1.1.1
if (errno == 0)
return LSEC_IO_SSL;
#endif
return errno;
#endif
}
@ -302,9 +308,7 @@ static int meth_create(lua_State *L)
SSL_set_fd(ssl->ssl, (int)SOCKET_INVALID);
SSL_set_mode(ssl->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE |
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
#if defined(SSL_MODE_RELEASE_BUFFERS)
SSL_set_mode(ssl->ssl, SSL_MODE_RELEASE_BUFFERS);
#endif
if (mode == LSEC_MODE_SERVER)
SSL_set_accept_state(ssl->ssl);
else
@ -382,8 +386,19 @@ static int meth_setfd(lua_State *L)
*/
static int meth_handshake(lua_State *L)
{
int err;
p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
int err = handshake(ssl);
p_context ctx = (p_context)SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl->ssl));
ctx->L = L;
err = handshake(ssl);
if (ctx->dh_param) {
DH_free(ctx->dh_param);
ctx->dh_param = NULL;
}
if (ctx->alpn) {
free(ctx->alpn);
ctx->alpn = NULL;
}
if (err == IO_DONE) {
lua_pushboolean(L, 1);
return 1;
@ -794,9 +809,22 @@ static int meth_getsniname(lua_State *L)
return 1;
}
static int meth_getalpn(lua_State *L)
{
unsigned len;
const unsigned char *data;
p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
SSL_get0_alpn_selected(ssl->ssl, &data, &len);
if (data == NULL && len == 0)
lua_pushnil(L);
else
lua_pushlstring(L, (const char*)data, len);
return 1;
}
static int meth_copyright(lua_State *L)
{
lua_pushstring(L, "LuaSec 0.7.2 - Copyright (C) 2006-2019 Bruno Silvestre, UFG"
lua_pushstring(L, "LuaSec 1.0.1 - Copyright (C) 2006-2021 Bruno Silvestre, UFG"
#if defined(WITH_LUASOCKET)
"\nLuaSocket 3.0-RC1 - Copyright (C) 2004-2013 Diego Nehab"
#endif
@ -804,6 +832,34 @@ static int meth_copyright(lua_State *L)
return 1;
}
#if defined(LSEC_ENABLE_DANE)
static int meth_dane(lua_State *L)
{
int ret;
p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
ret = SSL_dane_enable(ssl->ssl, luaL_checkstring(L, 2));
lua_pushboolean(L, (ret > 0));
return 1;
}
static int meth_tlsa(lua_State *L)
{
int ret;
size_t len;
p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
uint8_t usage = (uint8_t)luaL_checkinteger(L, 2);
uint8_t selector = (uint8_t)luaL_checkinteger(L, 3);
uint8_t mtype = (uint8_t)luaL_checkinteger(L, 4);
unsigned char *data = (unsigned char*)luaL_checklstring(L, 5, &len);
ERR_clear_error();
ret = SSL_dane_tlsa_add(ssl->ssl, usage, selector, mtype, data, len);
lua_pushboolean(L, (ret > 0));
return 1;
}
#endif
/*---------------------------------------------------------------------------*/
/**
@ -811,6 +867,7 @@ static int meth_copyright(lua_State *L)
*/
static luaL_Reg methods[] = {
{"close", meth_close},
{"getalpn", meth_getalpn},
{"getfd", meth_getfd},
{"getfinished", meth_getfinished},
{"getpeercertificate", meth_getpeercertificate},
@ -827,6 +884,10 @@ static luaL_Reg methods[] = {
{"settimeout", meth_settimeout},
{"sni", meth_sni},
{"want", meth_want},
#if defined(LSEC_ENABLE_DANE)
{"setdane", meth_dane},
{"settlsa", meth_tlsa},
#endif
{NULL, NULL}
};
@ -834,6 +895,7 @@ static luaL_Reg methods[] = {
* SSL metamethods.
*/
static luaL_Reg meta[] = {
{"__close", meth_destroy},
{"__gc", meth_destroy},
{"__tostring", meth_tostring},
{NULL, NULL}
@ -857,6 +919,7 @@ static luaL_Reg funcs[] = {
*/
LSEC_API int luaopen_ssl_core(lua_State *L)
{
#ifndef LSEC_API_OPENSSL_1_1_0
/* Initialize SSL */
if (!SSL_library_init()) {
lua_pushstring(L, "unable to initialize SSL library");
@ -864,6 +927,7 @@ LSEC_API int luaopen_ssl_core(lua_State *L)
}
OpenSSL_add_all_algorithms();
SSL_load_error_strings();
#endif
#if defined(WITH_LUASOCKET)
/* Initialize internal library */
@ -882,7 +946,7 @@ LSEC_API int luaopen_ssl_core(lua_State *L)
luaL_newlib(L, funcs);
lua_pushstring(L, "SOCKET_INVALID");
lua_pushnumber(L, SOCKET_INVALID);
lua_pushinteger(L, SOCKET_INVALID);
lua_rawset(L, -3);
return 1;

View File

@ -2,9 +2,9 @@
#define LSEC_SSL_H
/*--------------------------------------------------------------------------
* LuaSec 0.7.2
* LuaSec 1.0.1
*
* Copyright (C) 2006-2019 Bruno Silvestre
* Copyright (C) 2006-2021 Bruno Silvestre
*
*--------------------------------------------------------------------------*/

View File

@ -1,7 +1,7 @@
------------------------------------------------------------------------------
-- LuaSec 0.7.2
-- LuaSec 1.0.1
--
-- Copyright (C) 2006-2019 Bruno Silvestre
-- Copyright (C) 2006-2021 Bruno Silvestre
--
------------------------------------------------------------------------------
@ -10,6 +10,11 @@ local context = require("ssl.context")
local x509 = require("ssl.x509")
local config = require("ssl.config")
local ocsp
if config.capabilities.ocsp then
ocsp = require("ssl.context.ocsp")
end
local unpack = table.unpack or unpack
-- We must prevent the contexts to be collected before the connections,
@ -30,6 +35,39 @@ local function optexec(func, param, ctx)
return true
end
--
-- Convert an array of strings to wire-format
--
local function array2wireformat(array)
local str = ""
for k, v in ipairs(array) do
if type(v) ~= "string" then return nil end
local len = #v
if len == 0 then
return nil, "invalid ALPN name (empty string)"
elseif len > 255 then
return nil, "invalid ALPN name (length > 255)"
end
str = str .. string.char(len) .. v
end
if str == "" then return nil, "invalid ALPN list (empty)" end
return str
end
--
-- Convert wire-string format to array
--
local function wireformat2array(str)
local i = 1
local array = {}
while i < #str do
local len = str:byte(i)
array[#array + 1] = str:sub(i + 1, i + len)
i = i + len + 1
end
return array
end
--
--
--
@ -41,26 +79,34 @@ local function newcontext(cfg)
-- Mode
succ, msg = context.setmode(ctx, cfg.mode)
if not succ then return nil, msg end
local certificates = cfg.certificates
if not certificates then
certificates = {
{ certificate = cfg.certificate, key = cfg.key, password = cfg.password }
}
end
for _, certificate in ipairs(certificates) do
-- Load the key
if cfg.key then
if cfg.password and
type(cfg.password) ~= "function" and
type(cfg.password) ~= "string"
if certificate.key then
if certificate.password and
type(certificate.password) ~= "function" and
type(certificate.password) ~= "string"
then
return nil, "invalid password type"
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
end
-- Load the certificate
if cfg.certificate then
succ, msg = context.loadcert(ctx, cfg.certificate)
-- Load the certificate(s)
if certificate.certificate then
succ, msg = context.loadcert(ctx, certificate.certificate)
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)
if not succ then return nil, "private key does not match public key" end
end
end
end
-- Load the CA certificates
if cfg.cafile or cfg.capath then
succ, msg = context.locations(ctx, cfg.cafile, cfg.capath)
@ -70,6 +116,11 @@ local function newcontext(cfg)
if cfg.ciphers then
succ, msg = context.setcipher(ctx, cfg.ciphers)
if not succ then return nil, msg end
end
-- Set SSL cipher suites
if cfg.ciphersuites then
succ, msg = context.setciphersuites(ctx, cfg.ciphersuites)
if not succ then return nil, msg end
end
-- Set the verification options
succ, msg = optexec(context.setverify, cfg.verify, ctx)
@ -113,6 +164,60 @@ local function newcontext(cfg)
if not succ then return nil, msg end
end
-- ALPN
if cfg.mode == "server" and cfg.alpn then
if type(cfg.alpn) == "function" then
local alpncb = cfg.alpn
-- This callback function has to return one value only
succ, msg = context.setalpncb(ctx, function(str)
local protocols = alpncb(wireformat2array(str))
if type(protocols) == "string" then
protocols = { protocols }
elseif type(protocols) ~= "table" then
return nil
end
return (array2wireformat(protocols)) -- use "()" to drop error message
end)
if not succ then return nil, msg end
elseif type(cfg.alpn) == "table" then
local protocols = cfg.alpn
-- check if array is valid before use it
succ, msg = array2wireformat(protocols)
if not succ then return nil, msg end
-- This callback function has to return one value only
succ, msg = context.setalpncb(ctx, function()
return (array2wireformat(protocols)) -- use "()" to drop error message
end)
if not succ then return nil, msg end
else
return nil, "invalid ALPN parameter"
end
elseif cfg.mode == "client" and cfg.alpn then
local alpn
if type(cfg.alpn) == "string" then
alpn, msg = array2wireformat({ cfg.alpn })
elseif type(cfg.alpn) == "table" then
alpn, msg = array2wireformat(cfg.alpn)
else
return nil, "invalid ALPN parameter"
end
if not alpn then return nil, msg end
succ, msg = context.setalpn(ctx, alpn)
if not succ then return nil, msg end
end
if config.capabilities.dane and cfg.dane then
context.setdane(ctx)
end
if config.capabilities.ocsp and cfg.ocsp then
msg = "error setting OCSP"
succ = type(cfg.ocsp) == "function"
if not succ then return nil, msg end
succ = context.setocspcb(ctx, cfg.ocsp)
if not succ then return nil, msg end
end
return ctx
end
@ -179,9 +284,10 @@ core.setmethod("info", info)
--
local _M = {
_VERSION = "0.7.2",
_VERSION = "1.0.1",
_COPYRIGHT = core.copyright(),
config = config,
ocsp = ocsp,
loadcertificate = x509.load,
newcontext = newcontext,
wrap = wrap,

View File

@ -1,7 +1,7 @@
/*--------------------------------------------------------------------------
* LuaSec 0.7.2
* LuaSec 1.0.1
*
* Copyright (C) 2014-2019 Kim Alvefur, Paul Aurich, Tobias Markmann
* Copyright (C) 2014-2021 Kim Alvefur, Paul Aurich, Tobias Markmann
* Matthew Wild, Bruno Silvestre.
*
*--------------------------------------------------------------------------*/
@ -33,16 +33,12 @@
#include "x509.h"
/*
* ASN1_STRING_data is deprecated in OpenSSL 1.1.0
*/
#if OPENSSL_VERSION_NUMBER>=0x1010000fL && !defined(LIBRESSL_VERSION_NUMBER)
#define LSEC_ASN1_STRING_data(x) ASN1_STRING_get0_data(x)
#else
#define LSEC_ASN1_STRING_data(x) ASN1_STRING_data(x)
#ifndef LSEC_API_OPENSSL_1_1_0
#define X509_get0_notBefore X509_get_notBefore
#define X509_get0_notAfter X509_get_notAfter
#define ASN1_STRING_get0_data ASN1_STRING_data
#endif
static const char* hex_tab = "0123456789abcdef";
/**
@ -157,8 +153,7 @@ static void push_asn1_string(lua_State* L, ASN1_STRING *string, int encode)
}
switch (encode) {
case LSEC_AI5_STRING:
lua_pushlstring(L, (char*)LSEC_ASN1_STRING_data(string),
ASN1_STRING_length(string));
lua_pushlstring(L, (char*)ASN1_STRING_get0_data(string), ASN1_STRING_length(string));
break;
case LSEC_UTF8_STRING:
len = ASN1_STRING_to_UTF8(&data, string);
@ -174,7 +169,7 @@ static void push_asn1_string(lua_State* L, ASN1_STRING *string, int encode)
/**
* Return a human readable time.
*/
static int push_asn1_time(lua_State *L, ASN1_UTCTIME *tm)
static int push_asn1_time(lua_State *L, const ASN1_UTCTIME *tm)
{
char *tmp;
long size;
@ -193,7 +188,7 @@ static void push_asn1_ip(lua_State *L, ASN1_STRING *string)
{
int af;
char dst[INET6_ADDRSTRLEN];
unsigned char *ip = (unsigned char*)LSEC_ASN1_STRING_data(string);
unsigned char *ip = (unsigned char*)ASN1_STRING_get0_data(string);
switch(ASN1_STRING_length(string)) {
case 4:
af = AF_INET;
@ -490,10 +485,13 @@ static int meth_digest(lua_State* L)
*/
static int meth_valid_at(lua_State* L)
{
int nb, na;
X509* cert = lsec_checkx509(L, 1);
time_t time = luaL_checkinteger(L, 2);
lua_pushboolean(L, (X509_cmp_time(X509_get_notAfter(cert), &time) >= 0
&& X509_cmp_time(X509_get_notBefore(cert), &time) <= 0));
nb = X509_cmp_time(X509_get0_notBefore(cert), &time);
time -= 1;
na = X509_cmp_time(X509_get0_notAfter(cert), &time);
lua_pushboolean(L, nb == -1 && na == 1);
return 1;
}
@ -521,7 +519,7 @@ static int meth_serial(lua_State *L)
static int meth_notbefore(lua_State *L)
{
X509* cert = lsec_checkx509(L, 1);
return push_asn1_time(L, X509_get_notBefore(cert));
return push_asn1_time(L, X509_get0_notBefore(cert));
}
/**
@ -530,7 +528,7 @@ static int meth_notbefore(lua_State *L)
static int meth_notafter(lua_State *L)
{
X509* cert = lsec_checkx509(L, 1);
return push_asn1_time(L, X509_get_notAfter(cert));
return push_asn1_time(L, X509_get0_notAfter(cert));
}
/**
@ -623,7 +621,11 @@ cleanup:
*/
static int meth_destroy(lua_State* L)
{
X509_free(lsec_checkx509(L, 1));
p_x509 px = lsec_checkp_x509(L, 1);
if (px->cert) {
X509_free(px->cert);
px->cert = NULL;
}
return 0;
}
@ -653,6 +655,21 @@ static int meth_set_encode(lua_State* L)
return 1;
}
/**
* Get signature name.
*/
static int meth_get_sinagure_name(lua_State* L)
{
p_x509 px = lsec_checkp_x509(L, 1);
int nid = X509_get_signature_nid(px->cert);
const char *name = OBJ_nid2sn(nid);
if (!name)
lua_pushnil(L);
else
lua_pushstring(L, name);
return 1;
}
/*---------------------------------------------------------------------------*/
static int load_cert(lua_State* L)
@ -681,6 +698,7 @@ static luaL_Reg methods[] = {
{"digest", meth_digest},
{"setencode", meth_set_encode},
{"extensions", meth_extensions},
{"getsignaturename", meth_get_sinagure_name},
{"issuer", meth_issuer},
{"notbefore", meth_notbefore},
{"notafter", meth_notafter},
@ -697,6 +715,7 @@ static luaL_Reg methods[] = {
* X509 metamethods.
*/
static luaL_Reg meta[] = {
{"__close", meth_destroy},
{"__gc", meth_destroy},
{"__tostring", meth_tostring},
{NULL, NULL}

View File

@ -1,7 +1,7 @@
/*--------------------------------------------------------------------------
* LuaSec 0.7.2
* LuaSec 1.0.1
*
* Copyright (C) 2014-2019 Kim Alvefur, Paul Aurich, Tobias Markmann
* Copyright (C) 2014-2021 Kim Alvefur, Paul Aurich, Tobias Markmann
* Matthew Wild, Bruno Silvestre.
*
*--------------------------------------------------------------------------*/