18 Commits

Author SHA1 Message Date
b47bfff382 Some minor adjusts in parameters and script 2022-12-12 18:19:37 -03:00
480aef1626 Merge pull request #192 from mwild1/conn-local-cert-methods
ssl: Add :getlocalchain() + :getlocalcertificate() to mirror peer methods
2022-10-06 16:48:57 -03:00
4cecbb2783 ssl: Add :getlocalchain() + :getlocalcertificate() to mirror the peer methods
These methods mirror the existing methods that fetch the peer certificate and
chain. Due to various factors (SNI, multiple key types, etc.) it is not always
trivial for an application to determine what certificate was presented to the
client. However there are various use-cases where this is needed, such as
tls-server-end-point channel binding and OCSP stapling.

Requires OpenSSL 1.0.2+ (note: SSL_get_certificate() has existed for a very
long time, but was lacking documentation until OpenSSL 3.0).
2022-09-21 18:40:10 +01:00
d9215ee00f Update rockspec 2022-07-30 08:42:53 -03:00
03e03140cd Update version number 2022-07-30 08:41:46 -03:00
8b3b2318d2 Merge pull request #188 from mckaygerhard/patch-1
backguard compat for openssl on providers, like LTS linuxes
2022-07-29 11:42:21 -03:00
2c248947df Adjust some types and casts 2022-07-20 17:52:01 -03:00
f22b3ea609 Code format 2022-07-20 17:39:20 -03:00
c9539bca86 Fix variable shadowing 2022-07-20 17:36:27 -03:00
afb2d44b0e Merge pull request #187 from Zash/exporter
Add key material export method
2022-07-20 17:32:02 -03:00
f9afada3d1 backguard compat for openssl on providers, like LTS linuxes
* The commit de393417b7 introduces high dependency due raices requirement to openssl 1.1.0l+
* The X509_REQ_get0_signature(), X509_REQ_get_signature_nid(), X509_CRL_get0_signature() and X509_CRL_get_signature_nid() were added in OpenSSL 1.1.0.
* This patch makes luasec runs on all kind of embebed systems that cannot be upgraded due vendors limitations
2022-06-24 01:09:44 -04:00
371abcf718 Add key material export method 2022-06-01 16:26:35 +02:00
df27c62f4c Update source protocol on rockspec 2022-04-13 10:46:36 -03:00
09691fe782 Update rockspec 2022-04-13 10:38:18 -03:00
3a71559e13 Update version number 2022-04-13 10:35:06 -03:00
3f04fd7529 Removing useless code 2022-04-04 15:48:22 -03:00
d7161ca026 Merge pull request #179 from Zash/dane_no_hostname
Support passing DANE flags
2022-01-05 09:35:10 -03:00
65ee83275b Support passing DANE flags
The only flag at the moment is one that disables name checks, which is
needed for certain protocols such as XMPP.
2022-01-01 19:42:09 +01:00
27 changed files with 250 additions and 54 deletions

View File

@ -1,3 +1,19 @@
--------------------------------------------------------------------------------
LuaSec 1.2.0
---------------
This version includes:
* Add key material export method
* Backguard compat for openssl on providers, like LTS linuxes
--------------------------------------------------------------------------------
LuaSec 1.1.0
---------------
This version includes:
* Fix missing DANE flag
* Remove unused parameter in https.lua
--------------------------------------------------------------------------------
LuaSec 1.0.2
---------------

View File

@ -1,4 +1,4 @@
LuaSec 1.0.2
LuaSec 1.2.0
------------
* OpenSSL options:

View File

@ -1,5 +1,5 @@
LuaSec 1.0.2 license
Copyright (C) 2006-2021 Bruno Silvestre, UFG
LuaSec 1.2.0 license
Copyright (C) 2006-2022 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 1.0.2
LuaSec 1.2.0
===============
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 = "1.0.2-1"
version = "1.2.0-1"
source = {
url = "git://github.com/brunoos/luasec",
tag = "v1.0.2",
url = "git+https://github.com/brunoos/luasec",
tag = "v1.2.0",
}
description = {
summary = "A binding for OpenSSL library to provide TLS/SSL communication over LuaSocket.",

View File

@ -1,4 +1,4 @@
#!/usr/bin/env sh
#!/bin/sh
./rootA.sh
./rootB.sh
./clientA.sh

View File

@ -1,4 +1,4 @@
#!/usr/bin/env sh
#!/bin/sh
openssl req -newkey rsa:2048 -sha256 -keyout clientAkey.pem -out clientAreq.pem \
-nodes -config ./clientA.cnf -days 365 -batch

View File

@ -1,4 +1,4 @@
#!/usr/bin/env sh
#!/bin/sh
openssl req -newkey rsa:2048 -sha256 -keyout clientBkey.pem -out clientBreq.pem \
-nodes -config ./clientB.cnf -days 365 -batch

View File

@ -1,4 +1,4 @@
#!/usr/bin/env sh
#!/bin/sh
openssl req -newkey rsa:2048 -sha256 -keyout rootAkey.pem -out rootAreq.pem -nodes -config ./rootA.cnf -days 365 -batch

View File

@ -1,4 +1,4 @@
#!/usr/bin/env sh
#!/bin/sh
openssl req -newkey rsa:2048 -sha256 -keyout rootBkey.pem -out rootBreq.pem -nodes -config ./rootB.cnf -days 365 -batch

View File

@ -1,6 +1,6 @@
#!/usr/bin/env sh
#!/bin/sh
openssl req -newkey rsa:2048 -keyout serverAkey.pem -out serverAreq.pem \
openssl req -newkey rsa:2048 -sha256 -keyout serverAkey.pem -out serverAreq.pem \
-config ./serverA.cnf -nodes -days 365 -batch
openssl x509 -req -in serverAreq.pem -sha256 -extfile ./serverA.cnf \

View File

@ -1,6 +1,6 @@
#!/usr/bin/env sh
#!/bin/sh
openssl req -newkey rsa:2048 -keyout serverBkey.pem -out serverBreq.pem \
openssl req -newkey rsa:2048 -sha256 -keyout serverBkey.pem -out serverBreq.pem \
-config ./serverB.cnf -nodes -days 365 -batch
openssl x509 -req -in serverBreq.pem -sha256 -extfile ./serverB.cnf \

View File

@ -31,8 +31,27 @@ util.show( conn:getpeercertificate() )
print("----------------------------------------------------------------------")
for k, cert in ipairs( conn:getpeerchain() ) do
local expectedpeerchain = { "../certs/clientAcert.pem", "../certs/rootA.pem" }
local peerchain = conn:getpeerchain()
assert(#peerchain == #expectedpeerchain)
for k, cert in ipairs( peerchain ) do
util.show(cert)
local expectedpem = assert(io.open(expectedpeerchain[k])):read("*a")
assert(cert:pem() == expectedpem, "peer chain mismatch @ "..tostring(k))
end
local expectedlocalchain = { "../certs/serverAcert.pem" }
local localchain = assert(conn:getlocalchain())
assert(#localchain == #expectedlocalchain)
for k, cert in ipairs( localchain ) do
util.show(cert)
local expectedpem = assert(io.open(expectedlocalchain[k])):read("*a")
assert(cert:pem() == expectedpem, "local chain mismatch @ "..tostring(k))
if k == 1 then
assert(cert:pem() == conn:getlocalcertificate():pem())
end
end
local f = io.open(params.certificate)

View File

@ -1,7 +1,7 @@
/*--------------------------------------------------------------------------
* LuaSec 1.0.2
* LuaSec 1.2.0
*
* Copyright (C) 2006-2021 Bruno Silvestre
* Copyright (C) 2006-2022 Bruno Silvestre
*
*--------------------------------------------------------------------------*/

View File

@ -1,7 +1,7 @@
/*--------------------------------------------------------------------------
* LuaSec 1.0.2
* LuaSec 1.2.0
*
* Copyright (C) 2006-2021 Bruno Silvestre.
* Copyright (C) 2006-2022 Bruno Silvestre.
*
*--------------------------------------------------------------------------*/
@ -77,8 +77,15 @@ LSEC_API int luaopen_ssl_config(lua_State *L)
#ifdef LSEC_ENABLE_DANE
// DANE
lua_pushstring(L, "dane");
#ifdef DANE_FLAG_NO_DANE_EE_NAMECHECKS
lua_createtable(L, 0, 1);
lua_pushstring(L, "no_ee_namechecks");
lua_pushboolean(L, 1);
lua_rawset(L, -3);
#else
lua_pushboolean(L, 1);
#endif
lua_rawset(L, -3);
#endif
#ifndef OPENSSL_NO_EC

View File

@ -1,9 +1,9 @@
/*--------------------------------------------------------------------------
* LuaSec 1.0.2
* LuaSec 1.2.0
*
* Copyright (C) 2014-2021 Kim Alvefur, Paul Aurich, Tobias Markmann,
* Copyright (C) 2014-2022 Kim Alvefur, Paul Aurich, Tobias Markmann,
* Matthew Wild.
* Copyright (C) 2006-2021 Bruno Silvestre.
* Copyright (C) 2006-2022 Bruno Silvestre.
*
*--------------------------------------------------------------------------*/
@ -17,6 +17,7 @@
#include <openssl/err.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/x509_vfy.h>
#include <openssl/dh.h>
#include <lua.h>
@ -711,11 +712,31 @@ static int set_alpn_cb(lua_State *L)
/*
* DANE
*/
static int dane_options[] = {
/* TODO move into options.c
* however this symbol is not from openssl/ssl.h but rather from
* openssl/x509_vfy.h
* */
#ifdef DANE_FLAG_NO_DANE_EE_NAMECHECKS
DANE_FLAG_NO_DANE_EE_NAMECHECKS,
#endif
0
};
static const char *dane_option_names[] = {
#ifdef DANE_FLAG_NO_DANE_EE_NAMECHECKS
"no_ee_namechecks",
#endif
NULL
};
static int set_dane(lua_State *L)
{
int ret;
int ret, i;
SSL_CTX *ctx = lsec_checkcontext(L, 1);
ret = SSL_CTX_dane_enable(ctx);
for (i = 2; ret > 0 && i <= lua_gettop(L); i++) {
ret = SSL_CTX_dane_set_flags(ctx, dane_options[luaL_checkoption(L, i, NULL, dane_option_names)]);
}
lua_pushboolean(L, (ret > 0));
return 1;
}

View File

@ -2,9 +2,9 @@
#define LSEC_CONTEXT_H
/*--------------------------------------------------------------------------
* LuaSec 1.0.2
* LuaSec 1.2.0
*
* Copyright (C) 2006-2021 Bruno Silvestre
* Copyright (C) 2006-2022 Bruno Silvestre
*
*--------------------------------------------------------------------------*/

View File

@ -1,7 +1,7 @@
/*--------------------------------------------------------------------------
* LuaSec 1.0.2
* LuaSec 1.2.0
*
* Copyright (C) 2006-2021 Bruno Silvestre
* Copyright (C) 2006-2022 Bruno Silvestre
*
*--------------------------------------------------------------------------*/

View File

@ -1,6 +1,6 @@
----------------------------------------------------------------------------
-- LuaSec 1.0.2
-- Copyright (C) 2009-2021 PUC-Rio
-- LuaSec 1.2.0
-- Copyright (C) 2009-2022 PUC-Rio
--
-- Author: Pablo Musa
-- Author: Tomas Guisasola
@ -18,8 +18,8 @@ local try = socket.try
-- Module
--
local _M = {
_VERSION = "1.0.2",
_COPYRIGHT = "LuaSec 1.0.2 - Copyright (C) 2009-2021 PUC-Rio",
_VERSION = "1.2.0",
_COPYRIGHT = "LuaSec 1.2.0 - Copyright (C) 2009-2022 PUC-Rio",
PORT = 443,
TIMEOUT = 60
}
@ -93,7 +93,7 @@ local function tcp(params)
self.sock:sni(host)
self.sock:settimeout(_M.TIMEOUT)
try(self.sock:dohandshake())
reg(self, getmetatable(self.sock))
reg(self)
return 1
end
return conn

View File

@ -1,7 +1,7 @@
/*--------------------------------------------------------------------------
* LuaSec 1.0.2
* LuaSec 1.2.0
*
* Copyright (C) 2006-2021 Bruno Silvestre
* Copyright (C) 2006-2022 Bruno Silvestre
*
*--------------------------------------------------------------------------*/

View File

@ -2,9 +2,9 @@
#define LSEC_OPTIONS_H
/*--------------------------------------------------------------------------
* LuaSec 1.0.2
* LuaSec 1.2.0
*
* Copyright (C) 2006-2021 Bruno Silvestre
* Copyright (C) 2006-2022 Bruno Silvestre
*
*--------------------------------------------------------------------------*/

View File

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

133
src/ssl.c
View File

@ -1,9 +1,9 @@
/*--------------------------------------------------------------------------
* LuaSec 1.0.2
* LuaSec 1.2.0
*
* Copyright (C) 2014-2021 Kim Alvefur, Paul Aurich, Tobias Markmann,
* Copyright (C) 2014-2022 Kim Alvefur, Paul Aurich, Tobias Markmann,
* Matthew Wild.
* Copyright (C) 2006-2021 Bruno Silvestre.
* Copyright (C) 2006-2022 Bruno Silvestre.
*
*--------------------------------------------------------------------------*/
@ -530,6 +530,58 @@ static int meth_getpeercertificate(lua_State *L)
return 1;
}
/**
* Return the nth certificate of the chain sent to our peer.
*/
static int meth_getlocalcertificate(lua_State *L)
{
int n;
X509 *cert;
STACK_OF(X509) *certs;
p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
if (ssl->state != LSEC_STATE_CONNECTED) {
lua_pushnil(L);
lua_pushstring(L, "closed");
return 2;
}
/* Default to the first cert */
n = (int)luaL_optinteger(L, 2, 1);
/* This function is 1-based, but OpenSSL is 0-based */
--n;
if (n < 0) {
lua_pushnil(L);
lua_pushliteral(L, "invalid certificate index");
return 2;
}
if (n == 0) {
cert = SSL_get_certificate(ssl->ssl);
if (cert)
lsec_pushx509(L, cert);
else
lua_pushnil(L);
return 1;
}
/* In a server-context, the stack doesn't contain the peer cert,
* so adjust accordingly.
*/
if (SSL_is_server(ssl->ssl))
--n;
if(SSL_get0_chain_certs(ssl->ssl, &certs) != 1) {
lua_pushnil(L);
} else {
if (n >= sk_X509_num(certs)) {
lua_pushnil(L);
return 1;
}
cert = sk_X509_value(certs, n);
/* Increment the reference counting of the object. */
/* See SSL_get_peer_certificate() source code. */
X509_up_ref(cert);
lsec_pushx509(L, cert);
}
return 1;
}
/**
* Return the chain of certificate of the peer.
*/
@ -564,6 +616,41 @@ static int meth_getpeerchain(lua_State *L)
return 1;
}
/**
* Return the chain of certificates sent to the peer.
*/
static int meth_getlocalchain(lua_State *L)
{
int i;
int idx = 1;
int n_certs;
X509 *cert;
STACK_OF(X509) *certs;
p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
if (ssl->state != LSEC_STATE_CONNECTED) {
lua_pushnil(L);
lua_pushstring(L, "closed");
return 2;
}
lua_newtable(L);
if (SSL_is_server(ssl->ssl)) {
lsec_pushx509(L, SSL_get_certificate(ssl->ssl));
lua_rawseti(L, -2, idx++);
}
if(SSL_get0_chain_certs(ssl->ssl, &certs)) {
n_certs = sk_X509_num(certs);
for (i = 0; i < n_certs; i++) {
cert = sk_X509_value(certs, i);
/* Increment the reference counting of the object. */
/* See SSL_get_peer_certificate() source code. */
X509_up_ref(cert);
lsec_pushx509(L, cert);
lua_rawseti(L, -2, idx++);
}
}
return 1;
}
/**
* Copy the table src to the table dst.
*/
@ -671,6 +758,41 @@ static int meth_getpeerfinished(lua_State *L)
return 1;
}
/**
* Get some shared keying material
*/
static int meth_exportkeyingmaterial(lua_State *L)
{
p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
if(ssl->state != LSEC_STATE_CONNECTED) {
lua_pushnil(L);
lua_pushstring(L, "closed");
return 0;
}
size_t llen = 0;
size_t contextlen = 0;
const unsigned char *context = NULL;
const char *label = (const char*)luaL_checklstring(L, 2, &llen);
size_t olen = (size_t)luaL_checkinteger(L, 3);
if (!lua_isnoneornil(L, 4))
context = (const unsigned char*)luaL_checklstring(L, 4, &contextlen);
/* Temporary buffer memory-managed by Lua itself */
unsigned char *out = (unsigned char*)lua_newuserdata(L, olen);
if(SSL_export_keying_material(ssl->ssl, out, olen, label, llen, context, contextlen, context != NULL) != 1) {
lua_pushnil(L);
lua_pushstring(L, "error exporting keying material");
return 2;
}
lua_pushlstring(L, (char*)out, olen);
return 1;
}
/**
* Object information -- tostring metamethod
*/
@ -826,7 +948,7 @@ static int meth_getalpn(lua_State *L)
static int meth_copyright(lua_State *L)
{
lua_pushstring(L, "LuaSec 1.0.2 - Copyright (C) 2006-2021 Bruno Silvestre, UFG"
lua_pushstring(L, "LuaSec 1.2.0 - Copyright (C) 2006-2022 Bruno Silvestre, UFG"
#if defined(WITH_LUASOCKET)
"\nLuaSocket 3.0-RC1 - Copyright (C) 2004-2013 Diego Nehab"
#endif
@ -873,9 +995,12 @@ static luaL_Reg methods[] = {
{"getfd", meth_getfd},
{"getfinished", meth_getfinished},
{"getpeercertificate", meth_getpeercertificate},
{"getlocalcertificate", meth_getlocalcertificate},
{"getpeerchain", meth_getpeerchain},
{"getlocalchain", meth_getlocalchain},
{"getpeerverification", meth_getpeerverification},
{"getpeerfinished", meth_getpeerfinished},
{"exportkeyingmaterial",meth_exportkeyingmaterial},
{"getsniname", meth_getsniname},
{"getstats", meth_getstats},
{"setstats", meth_setstats},

View File

@ -2,9 +2,9 @@
#define LSEC_SSL_H
/*--------------------------------------------------------------------------
* LuaSec 1.0.2
* LuaSec 1.2.0
*
* Copyright (C) 2006-2021 Bruno Silvestre
* Copyright (C) 2006-2022 Bruno Silvestre
*
*--------------------------------------------------------------------------*/

View File

@ -1,7 +1,7 @@
------------------------------------------------------------------------------
-- LuaSec 1.0.2
-- LuaSec 1.2.0
--
-- Copyright (C) 2006-2021 Bruno Silvestre
-- Copyright (C) 2006-2022 Bruno Silvestre
--
------------------------------------------------------------------------------
@ -202,8 +202,12 @@ local function newcontext(cfg)
end
if config.capabilities.dane and cfg.dane then
if type(cfg.dane) == "table" then
context.setdane(ctx, unpack(cfg.dane))
else
context.setdane(ctx)
end
end
return ctx
end
@ -271,7 +275,7 @@ core.setmethod("info", info)
--
local _M = {
_VERSION = "1.0.2",
_VERSION = "1.2.0",
_COPYRIGHT = core.copyright(),
config = config,
loadcertificate = x509.load,

View File

@ -1,7 +1,7 @@
/*--------------------------------------------------------------------------
* LuaSec 1.0.2
* LuaSec 1.2.0
*
* Copyright (C) 2014-2021 Kim Alvefur, Paul Aurich, Tobias Markmann
* Copyright (C) 2014-2022 Kim Alvefur, Paul Aurich, Tobias Markmann
* Matthew Wild, Bruno Silvestre.
*
*--------------------------------------------------------------------------*/
@ -655,6 +655,7 @@ static int meth_set_encode(lua_State* L)
return 1;
}
#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL)
/**
* Get signature name.
*/
@ -669,6 +670,7 @@ static int meth_get_signature_name(lua_State* L)
lua_pushstring(L, name);
return 1;
}
#endif
/*---------------------------------------------------------------------------*/
@ -698,7 +700,9 @@ static luaL_Reg methods[] = {
{"digest", meth_digest},
{"setencode", meth_set_encode},
{"extensions", meth_extensions},
#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL)
{"getsignaturename", meth_get_signature_name},
#endif
{"issuer", meth_issuer},
{"notbefore", meth_notbefore},
{"notafter", meth_notafter},

View File

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