87 Commits

Author SHA1 Message Date
20db8ae168 Update version number: 0.8 -> 0.8.1 2019-08-16 10:31:04 -03:00
dcd385e615 Fix memory leak 2019-08-16 10:15:42 -03: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
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
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
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
de63f21f63 Change version number to 0.7 2018-06-27 10:36:26 -03:00
fbbaa866c3 Missing defines in rockspec 2017-12-21 12:33:47 -02:00
bd87aafaaf Using https instead of git protocol 2017-10-28 10:44:51 -02:00
be3c6d67e0 Make luaL_testudata() compat function visible for all files 2017-10-28 09:53:28 -02:00
2f562e1399 Put an error check back 2017-10-28 09:31:40 -02:00
7934e58b4b Merge pull request #99 from daurnimator/luaossl-integration
Allow passing a luaossl context for socket creation/wrapping
2017-10-28 09:23:07 -02:00
3a8d6e71c4 Removing some VC files 2017-10-11 20:42:54 -03:00
3d170e9f9d Add new source files to VC project, new libs name 2017-10-11 20:29:15 -03:00
ea6a65de84 Rockspec for LuaSec 0.7alpha 2017-09-26 18:24:16 -03:00
0d01b53461 Version number to 0.7alpha 2017-09-26 18:22:49 -03:00
8762441cd2 Add popular aliases for commonly used curves 2017-09-26 17:43:00 -03:00
60f02f7701 LuaJIT 2.1.0 added luaL_newlib() as extension 2017-09-26 17:39:32 -03:00
fe1fb0b350 Adding 'curveslist' parameter
LuaSec will try to set 'curveslist' parameter first.
If the parameter is not present or not supported, LuaSec will
try 'curve' parameter.
2017-08-04 17:00:12 -03:00
db42a5084a Export configuration (protocols, options, curves, algorithms, capabilities) 2017-06-16 22:53:59 -03:00
0b99832ec7 Export configuration (protocols, options, curves, algorithms, capabilities) 2017-06-16 22:50:27 -03:00
fc757e1fd0 Discover curves dynamically 2017-06-16 21:03:10 -03:00
64f11f515d Add example of luaossl integration
Based on 'info' sample
2017-04-04 13:07:48 +10:00
e90a264c93 Allow passing luaossl objects to meth_create() 2017-04-04 13:06:12 +10:00
5299803bef Merge pull request #77 from kekstee/master
Make CC and LD configurable
2017-03-31 15:11:17 -03:00
9c41eaf09a Merge pull request #74 from ka7/spelling
spelling fixes, as seen on lintian.debian.org
2017-03-31 14:50:19 -03:00
31b7a4744b Merge pull request #63 from gleydsonsoares/tweak-OPENSSL_NO_COMP
simplify OPENSSL_NO_COMP guard
2017-03-31 14:48:19 -03:00
d9e7c5d466 Merge pull request #92 from robert-scheck/utf8
Convert CHANGELOG from ISO-8859-1 to UTF-8
2017-03-31 14:46:22 -03:00
6b82fa6104 LuaRocks workaround 2017-03-31 14:40:09 -03:00
9f6d623ccb proper socket invalidation #70 2017-03-31 14:32:35 -03:00
67a2133e7d Merge pull request #47 from wmark/curve-negotiation
Add TLS curve negotiation. (closes #42)
2017-03-31 14:14:54 -03:00
622ef3d6a6 Enable curve negotiation with #ifdef SSL_CTX_set1_curves_list
One of currently three definitions in the wild that indicate support for
SSL_CTX_set1_curves_list().
2017-02-26 00:16:25 +01:00
231563682a Add support for the new curve selection API.
Signed-off-by: W-Mark Kubacki <wmark@hurrikane.de>
2017-02-26 00:16:24 +01:00
3ec117667d Convert CHANGELOG from ISO-8859-1 to UTF-8 2017-02-18 13:26:40 +01:00
98f8872743 Merge pull request #89 from greatwolf/sni_host
Fix for sni host issue #88 and #44. Thanks to @TomasB
2016-12-22 16:21:40 -02:00
77b88e0b0d Fix for sni host issue #88 and #44. Thanks to @TomasB 2016-12-15 16:46:59 -08:00
4889830d53 Compatibility with OpenSSL 1.1.0
Defining macros X509_up_ref() and SSL_is_server to use the same
API of OpenSSL 1.1.0.
2016-09-14 17:47:09 -03:00
80a527d630 Use EVP_PKEY_base_id() to recover the key's type 2016-09-13 13:30:44 -03:00
53db804b9d Use X509_EXTENSION_get_object() to get the 'object' field from extension 2016-09-13 13:22:25 -03:00
22e6652d88 ASN1_STRING_data() is deprecated in OpenSSL 1.1.0
ASN1_STRING_get0_data() must be used instead.
2016-09-13 13:09:18 -03:00
6bb007b75f Make CC and LD configurable 2016-08-13 23:24:11 +02:00
3cfdb878dd Merge pull request #76 from msva/patch-1
Return of DESTDIR support
2016-08-03 15:10:06 -03:00
4101af103e Return the number of data read and remove a useless line. 2016-08-03 14:56:07 -03:00
9efa963e35 Merge pull request #73 from perry-clarke/master
Fix crash after dohandshake() fails (need some adjusts yet)
2016-08-03 14:53:53 -03:00
4aa9ec3b60 Return of DESTDIR support 2016-07-24 02:01:21 +07:00
d45c03a1ad spelling fixes, as seen on lintian.debian.org 2016-07-11 21:57:50 +02:00
0f4eaf06e4 Merge pull request #1 from perry-clarke/perry-clarke-patch-1
Fix crash related to incorrect buffer size
2016-05-03 16:45:06 -07:00
5a98bb6adb Fix crash related to incorrect buffer size
The number of bytes received by ssl_recv() is being passed to luaL_addlstring() (in recvall()) but it was being left either uninitialized or being set to an error code.  The crashing case I found was when the state was not LSEC_STATE_CONNECTED (e.g. when dohandshake() has failed) and ssl_recv() returned immediately without setting "got".
2016-05-03 16:37:47 -07:00
27fbd70424 tweak OPENSSL_NO_COMP 2015-11-20 13:22:00 -03:00
56 changed files with 1296 additions and 691 deletions

View File

@ -1,3 +1,39 @@
--------------------------------------------------------------------------------
LuaSec 0.8.1
---------------
This version includes:
* Fix another memory leak when get certficate extensions
--------------------------------------------------------------------------------
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
---------------
LuaSec depends on OpenSSL, and integrates with LuaSocket to make it
easy to add secure connections to any Lua applications or scripts.
Documentation: https://github.com/brunoos/luasec/wiki
This version includes:
* Add support to OpenSSL 1.1.0
* Add support to elliptic curves list
* Add ssl.config that exports some OpenSSL information
* Add integration with luaossl
--------------------------------------------------------------------------------
LuaSec 0.6
------------
@ -35,7 +71,6 @@ This version includes:
--------------------------------------------------------------------------------
LuaSec 0.5
------------
LuaSec depends on OpenSSL, and integrates with LuaSocket to make it
easy to add secure connections to any Lua applications or scripts.
@ -109,7 +144,7 @@ LuaSec 0.3
--------------------------------------------------------------------------------
LuaSec 0.2.1
------------
- 'key' and 'certificate' configurations become optional. (thanks Ren<EFBFBD> Rebe)
- 'key' and 'certificate' configurations become optional. (thanks René Rebe)
- Add '_VERSION' variable to module.
--------------------------------------------------------------------------------

View File

@ -1,9 +1,9 @@
LuaSec 0.6
LuaSec 0.8.1
------------
* OpenSSL options:
By default, LuaSec 0.6 includes options for OpenSSL 1.0.2f.
By default, LuaSec 0.8.1 includes options for OpenSSL 1.1.0g.
If you need to generate the options for a different version of OpenSSL:

View File

@ -1,5 +1,5 @@
LuaSec 0.6 license
Copyright (C) 2006-2015 Bruno Silvestre, UFG
LuaSec 0.8.1 license
Copyright (C) 2006-2019 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,36 +1,9 @@
LuaSec 0.6
==========
LuaSec 0.8.1
===============
LuaSec depends on OpenSSL, and integrates with LuaSocket to make it
easy to add secure connections to any Lua applications or scripts.
Important: This version requires at least OpenSSL 1.0.2.
For old versions of OpenSSL, use LuaSec 0.7.
Documentation: https://github.com/brunoos/luasec/wiki
This version includes:
* Lua 5.2 and 5.3 compatibility
* Context module:
- Add ctx:checkkey()
* SSL module:
- Add conn:sni() and conn:getsniname()
* Context options:
- Add "any" protocol ("sslv23" is deprecated)
* HTTPS module:
- Using "any" protocol without SSLv2/SSLv3, by default
* X509 module:
- Human readable IP address
- Add cert:issued()
- Add cert:pubkey()
* Some bug fixes
********************************************************************************
PS: 10th anniversary! Thanks to everyone who collaborate with LuaSec.
********************************************************************************

View File

@ -1,8 +1,8 @@
package = "LuaSec"
version = "0.6-1"
version = "0.8.1-1"
source = {
url = "git://github.com/brunoos/luasec.git",
tag = "luasec-0.6"
url = "https://github.com/brunoos/luasec/archive/luasec-0.8.1.tar.gz",
dir = "luasec-luasec-0.8.1"
}
description = {
summary = "A binding for OpenSSL library to provide TLS/SSL communication over LuaSocket.",
@ -45,6 +45,9 @@ build = {
},
modules = {
ssl = {
defines = {
"WITH_LUASOCKET", "LUASOCKET_DEBUG",
},
incdirs = {
"$(OPENSSL_INCDIR)", "src/", "src/luasocket",
},
@ -55,6 +58,7 @@ build = {
"ssl", "crypto"
},
sources = {
"src/config.c", "src/ec.c",
"src/x509.c", "src/context.c", "src/ssl.c",
"src/luasocket/buffer.c", "src/luasocket/io.c",
"src/luasocket/timeout.c", "src/luasocket/usocket.c"
@ -75,6 +79,7 @@ build = {
ssl = {
defines = {
"WIN32", "NDEBUG", "_WINDOWS", "_USRDLL", "LSEC_EXPORTS", "BUFFER_DEBUG", "LSEC_API=__declspec(dllexport)",
"WITH_LUASOCKET", "LUASOCKET_DEBUG",
"LUASEC_INET_NTOP", "WINVER=0x0501", "_WIN32_WINNT=0x0501", "NTDDI_VERSION=0x05010300"
},
libdirs = {
@ -82,32 +87,18 @@ build = {
"$(OPENSSL_BINDIR)",
},
libraries = {
"libeay32", "ssleay32", "ws2_32"
"libssl32MD", "libcrypto32MD", "ws2_32"
},
incdirs = {
"$(OPENSSL_INCDIR)", "src/", "src/luasocket"
},
sources = {
"src/config.c", "src/ec.c",
"src/x509.c", "src/context.c", "src/ssl.c",
"src/luasocket/buffer.c", "src/luasocket/io.c",
"src/luasocket/timeout.c", "src/luasocket/wsocket.c"
}
}
},
patches = {
["luarocks_vs_compiler.patch"] = [[
--- a/src/ssl.c.orig
+++ b/src/ssl.c
@@ -844,3 +844,8 @@ LSEC_API int luaopen_ssl_core(lua_State *L)
return 1;
}
+
+#if defined(_MSC_VER)
+/* Empty implementation to allow building with LuaRocks and MS compilers */
+LSEC_API int luaopen_ssl(lua_State *L) { return 0; }
+#endif
]]
}
}
}

Binary file not shown.

View File

@ -1,253 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Name="luasec"
ProjectGUID="{A629932F-8819-4C0B-8835-CBF1FEED6376}"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="C:\devel\openssl\include;C:\devel\lua-dll9\include"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LUASEC_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2_32.lib libeay32MDd.lib ssleay32MDd.lib lua5.1.lib"
OutputFile="$(OutDir)/ssl.dll"
LinkIncremental="2"
AdditionalLibraryDirectories="C:\devel\openssl\lib\VC;C:\devel\lua-dll9"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(OutDir)/luasec.pdb"
SubSystem="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
ImportLibrary="$(OutDir)/ssl.lib"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="C:\devel\openssl\include;C:\devel\lua-dll9\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;BUFFER_DEBUG"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2_32.lib libeay32MD.lib ssleay32MD.lib lua5.1.lib"
OutputFile="$(OutDir)/ssl.dll"
LinkIncremental="1"
AdditionalLibraryDirectories="C:\devel\openssl\lib\VC;C:\devel\lua-dll9\lib"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
ImportLibrary="$(OutDir)/ssl.lib"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\src\buffer.c"
>
</File>
<File
RelativePath=".\src\context.c"
>
</File>
<File
RelativePath=".\src\io.c"
>
</File>
<File
RelativePath=".\src\ssl.c"
>
</File>
<File
RelativePath=".\src\timeout.c"
>
</File>
<File
RelativePath=".\src\wsocket.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\src\buffer.h"
>
</File>
<File
RelativePath=".\src\context.h"
>
</File>
<File
RelativePath=".\src\io.h"
>
</File>
<File
RelativePath=".\src\socket.h"
>
</File>
<File
RelativePath=".\src\ssl.h"
>
</File>
<File
RelativePath=".\src\timeout.h"
>
</File>
<File
RelativePath=".\src\wsocket.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@ -18,10 +18,12 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@ -74,7 +76,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>C:\devel\openssl\include;C:\devel\lua5.2\include;.\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>C:\devel\openssl-1.1.0\include;C:\devel\lua-5.1\include;.\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_WIN32;NDEBUG;_WINDOWS;_USRDLL;LUASOCKET_DEBUG;WITH_LUASOCKET;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>
@ -83,9 +85,9 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;libeay32MD.lib;ssleay32MD.lib;lua52.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>ws2_32.lib;libssl32MD.lib;libcrypto32MD.lib;lua5.1.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<AdditionalLibraryDirectories>C:\devel\openssl\lib\VC;C:\devel\lua5.2\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>C:\devel\openssl-1.1.0\lib\VC;C:\devel\lua-5.1\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
@ -98,7 +100,9 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="src\config.c" />
<ClCompile Include="src\context.c" />
<ClCompile Include="src\ec.c" />
<ClCompile Include="src\luasocket\buffer.c" />
<ClCompile Include="src\luasocket\io.c" />
<ClCompile Include="src\luasocket\timeout.c" />
@ -107,6 +111,7 @@
<ClCompile Include="src\x509.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\compat.h" />
<ClInclude Include="src\config.h" />
<ClInclude Include="src\context.h" />
<ClInclude Include="src\ec.h" />

View File

@ -1,75 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\x509.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\context.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ssl.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\luasocket\wsocket.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\luasocket\buffer.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\luasocket\io.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\luasocket\timeout.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\x509.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\config.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\context.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\ec.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\options.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\ssl.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\luasocket\wsocket.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\luasocket\buffer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\luasocket\io.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\luasocket\socket.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\luasocket\timeout.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

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.
@ -17,7 +23,7 @@ Directories:
Elliptic curve cipher.
* info
Informations about the connection.
Information about the connection.
* key
Test encrypted private key.
@ -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 @@
#!/bin/bash
./rootA.sh
./rootB.sh
./clientA.sh
./clientB.sh
./serverA.sh
./serverB.sh

View File

@ -50,7 +50,7 @@ crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.pem # The private key
RANDFILE = $dir/private/.rand # private random number file
x509_extensions = usr_cert # The extentions to add to the cert
x509_extensions = usr_cert # The extensions to add to the cert
# Comment out the following two lines for the "traditional"
# (and highly broken) format.
@ -102,7 +102,7 @@ default_bits = 1024
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert
x509_extensions = v3_ca # The extensions to add to the self signed cert
# Passwords for private keys if not present they will be prompted for
# input_password = secret

View File

@ -1,9 +1,9 @@
#!/bin/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

@ -50,7 +50,7 @@ crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.pem # The private key
RANDFILE = $dir/private/.rand # private random number file
x509_extensions = usr_cert # The extentions to add to the cert
x509_extensions = usr_cert # The extensions to add to the cert
# Comment out the following two lines for the "traditional"
# (and highly broken) format.
@ -102,7 +102,7 @@ default_bits = 1024
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert
x509_extensions = v3_ca # The extensions to add to the self signed cert
# Passwords for private keys if not present they will be prompted for
# input_password = secret

View File

@ -1,9 +1,9 @@
#!/bin/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

@ -50,7 +50,7 @@ crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.pem # The private key
RANDFILE = $dir/private/.rand # private random number file
x509_extensions = usr_cert # The extentions to add to the cert
x509_extensions = usr_cert # The extensions to add to the cert
# Comment out the following two lines for the "traditional"
# (and highly broken) format.
@ -102,7 +102,7 @@ default_bits = 1024
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert
x509_extensions = v3_ca # The extensions to add to the self signed cert
# Passwords for private keys if not present they will be prompted for
# input_password = secret

View File

@ -1,7 +1,7 @@
#!/bin/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

@ -50,7 +50,7 @@ crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.pem # The private key
RANDFILE = $dir/private/.rand # private random number file
x509_extensions = usr_cert # The extentions to add to the cert
x509_extensions = usr_cert # The extensions to add to the cert
# Comment out the following two lines for the "traditional"
# (and highly broken) format.
@ -102,7 +102,7 @@ default_bits = 1024
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert
x509_extensions = v3_ca # The extensions to add to the self signed cert
# Passwords for private keys if not present they will be prompted for
# input_password = secret

View File

@ -1,7 +1,7 @@
#!/bin/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

@ -50,7 +50,7 @@ crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.pem # The private key
RANDFILE = $dir/private/.rand # private random number file
x509_extensions = usr_cert # The extentions to add to the cert
x509_extensions = usr_cert # The extensions to add to the cert
# Comment out the following two lines for the "traditional"
# (and highly broken) format.
@ -102,7 +102,7 @@ default_bits = 1024
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert
x509_extensions = v3_ca # The extensions to add to the self signed cert
# Passwords for private keys if not present they will be prompted for
# input_password = secret
@ -118,7 +118,7 @@ x509_extensions = v3_ca # The extentions 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
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

@ -50,7 +50,7 @@ crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.pem # The private key
RANDFILE = $dir/private/.rand # private random number file
x509_extensions = usr_cert # The extentions to add to the cert
x509_extensions = usr_cert # The extensions to add to the cert
# Comment out the following two lines for the "traditional"
# (and highly broken) format.
@ -102,7 +102,7 @@ default_bits = 1024
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert
x509_extensions = v3_ca # The extensions to add to the self signed cert
# Passwords for private keys if not present they will be prompted for
# input_password = secret
@ -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
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

View File

@ -0,0 +1,28 @@
--
-- Public domain
--
local socket = require("socket")
local ssl = require("ssl")
local params = {
mode = "client",
protocol = "any",
key = "../certs/clientAkey.pem",
certificate = "../certs/clientA.pem",
cafile = "../certs/rootA.pem",
verify = {"peer", "fail_if_no_peer_cert"},
options = {"all"},
--
curve = "P-256:P-384",
}
local peer = socket.tcp()
peer:connect("127.0.0.1", 8888)
-- [[ SSL wrapper
peer = assert( ssl.wrap(peer, params) )
assert(peer:dohandshake())
--]]
print(peer:receive("*l"))
peer:close()

View File

@ -0,0 +1,37 @@
--
-- Public domain
--
local socket = require("socket")
local ssl = require("ssl")
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"},
--
curve = "P-384:P-256:P-521",
}
-- [[ 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 with curve negotiation test\n")
peer:close()

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

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

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,40 @@
--
-- Public domain
--
local socket = require("socket")
local ssl = require("ssl")
local pkey = require "openssl.pkey"
local ssl_context = require "openssl.ssl.context"
local x509 = require "openssl.x509"
local x509_store = require "openssl.x509.store"
local function read_file(path)
local file, err, errno = io.open(path, "rb")
if not file then
return nil, err, errno
end
local contents
contents, err, errno = file:read "*a"
file:close()
return contents, err, errno
end
local ctx = ssl_context.new("TLSv1_2", false)
ctx:setPrivateKey(pkey.new(assert(read_file("../certs/clientAkey.pem"))))
ctx:setCertificate(x509.new(assert(read_file("../certs/clientA.pem"))))
local store = x509_store.new()
store:add("../certs/rootA.pem")
ctx:setStore(store)
ctx:setVerify(ssl_context.VERIFY_FAIL_IF_NO_PEER_CERT)
local peer = socket.tcp()
peer:connect("127.0.0.1", 8888)
-- [[ SSL wrapper
peer = assert( ssl.wrap(peer, ctx) )
assert(peer:dohandshake())
--]]
print(peer:receive("*l"))
peer:close()

View File

@ -0,0 +1,58 @@
--
-- Public domain
--
local socket = require("socket")
local ssl = require("ssl")
local pkey = require "openssl.pkey"
local ssl_context = require "openssl.ssl.context"
local x509 = require "openssl.x509"
local x509_store = require "openssl.x509.store"
local function read_file(path)
local file, err, errno = io.open(path, "rb")
if not file then
return nil, err, errno
end
local contents
contents, err, errno = file:read "*a"
file:close()
return contents, err, errno
end
local ctx = ssl_context.new("TLSv1_2", true)
ctx:setPrivateKey(pkey.new(assert(read_file("../certs/serverAkey.pem"))))
ctx:setCertificate(x509.new(assert(read_file("../certs/serverA.pem"))))
local store = x509_store.new()
store:add("../certs/rootA.pem")
ctx:setStore(store)
ctx:setVerify(ssl_context.VERIFY_FAIL_IF_NO_PEER_CERT)
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) )
-- Before handshake: nil
print( peer:info() )
assert( peer:dohandshake() )
--]]
print("---")
local info = peer:info()
for k, v in pairs(info) do
print(k, v)
end
print("---")
print("-> Compression", peer:info("compression"))
peer:send("oneshot test\n")
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/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 @@
#!/bin/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()

View File

@ -4,7 +4,9 @@ LMOD=ssl.lua
OBJS= \
x509.o \
context.o \
ssl.o
ssl.o \
config.o \
ec.o
LIBS=-lssl -lcrypto -lluasocket
@ -21,8 +23,8 @@ MAC_CFLAGS=-O2 -fno-common $(WARN) $(INCDIR) $(DEFS)
MAC_LDFLAGS=-bundle -undefined dynamic_lookup $(LIBDIR)
INSTALL = install
CC = cc
LD = $(MYENV) cc
CC ?= cc
LD ?= $(MYENV) cc
CFLAGS += $(MYCFLAGS)
LDFLAGS += $(MYLDFLAGS)
@ -31,10 +33,10 @@ LDFLAGS += $(MYLDFLAGS)
all:
install: $(CMOD) $(LMOD)
$(INSTALL) -d $(LUAPATH)/ssl $(LUACPATH)
$(INSTALL) $(CMOD) $(LUACPATH)
$(INSTALL) -m644 $(LMOD) $(LUAPATH)
$(INSTALL) -m644 https.lua $(LUAPATH)/ssl
$(INSTALL) -d $(DESTDIR)$(LUAPATH)/ssl $(DESTDIR)$(LUACPATH)
$(INSTALL) $(CMOD) $(DESTDIR)$(LUACPATH)
$(INSTALL) -m644 $(LMOD) $(DESTDIR)$(LUAPATH)
$(INSTALL) -m644 https.lua $(DESTDIR)$(LUAPATH)/ssl
linux:
@$(MAKE) $(CMOD) MYCFLAGS="$(LNX_CFLAGS)" MYLDFLAGS="$(LNX_LDFLAGS)" EXTRA="$(EXTRA)"
@ -55,6 +57,8 @@ clean:
cd luasocket && $(MAKE) clean
rm -f $(OBJS) $(CMOD)
x509.o: x509.c x509.h config.h
context.o: context.c context.h ec.h config.h
ssl.o: ssl.c ssl.h context.h x509.h config.h
ec.o: ec.c ec.h
x509.o: x509.c x509.h compat.h
context.o: context.c context.h ec.h compat.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,11 +1,12 @@
/*--------------------------------------------------------------------------
* LuaSec 0.6
* Copyright (C) 2006-2016 Bruno Silvestre
* LuaSec 0.8.1
*
* Copyright (C) 2006-2019 Bruno Silvestre
*
*--------------------------------------------------------------------------*/
#ifndef LSEC_CONFIG_H
#define LSEC_CONFIG_H
#ifndef LSEC_COMPAT_H
#define LSEC_COMPAT_H
#if defined(_WIN32)
#define LSEC_API __declspec(dllexport)
@ -14,9 +15,15 @@
#endif
#if (LUA_VERSION_NUM == 501)
#define luaL_testudata(L, ud, tname) lsec_testudata(L, ud, tname)
#define setfuncs(L, R) luaL_register(L, NULL, R)
#define lua_rawlen(L, i) lua_objlen(L, i)
#ifndef luaL_newlib
#define luaL_newlib(L, R) do { lua_newtable(L); luaL_register(L, NULL, R); } while(0)
#endif
#else
#define setfuncs(L, R) luaL_setfuncs(L, R, 0)
#endif

88
src/config.c Normal file
View File

@ -0,0 +1,88 @@
/*--------------------------------------------------------------------------
* LuaSec 0.8.1
*
* Copyright (C) 2006-2019 Bruno Silvestre.
*
*--------------------------------------------------------------------------*/
#include "compat.h"
#include "options.h"
#include "ec.h"
/**
* Registre the module.
*/
LSEC_API int luaopen_ssl_config(lua_State *L)
{
ssl_option_t *opt;
lua_newtable(L);
// Options
lua_pushstring(L, "options");
lua_newtable(L);
for (opt = ssl_options; opt->name; opt++) {
lua_pushstring(L, opt->name);
lua_pushboolean(L, 1);
lua_rawset(L, -3);
}
lua_rawset(L, -3);
// Protocols
lua_pushstring(L, "protocols");
lua_newtable(L);
lua_pushstring(L, "tlsv1");
lua_pushboolean(L, 1);
lua_rawset(L, -3);
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);
#if defined(TLS1_3_VERSION)
lua_pushstring(L, "tlsv1_3");
lua_pushboolean(L, 1);
lua_rawset(L, -3);
#endif
lua_rawset(L, -3);
// Algorithms
lua_pushstring(L, "algorithms");
lua_newtable(L);
#ifndef OPENSSL_NO_EC
lua_pushstring(L, "ec");
lua_pushboolean(L, 1);
lua_rawset(L, -3);
#endif
lua_rawset(L, -3);
// Curves
lua_pushstring(L, "curves");
lsec_get_curves(L);
lua_rawset(L, -3);
// Capabilities
lua_pushstring(L, "capabilities");
lua_newtable(L);
// ALPN
lua_pushstring(L, "alpn");
lua_pushboolean(L, 1);
lua_rawset(L, -3);
#ifndef OPENSSL_NO_EC
lua_pushstring(L, "curves_list");
lua_pushboolean(L, 1);
lua_rawset(L, -3);
lua_pushstring(L, "ecdh_auto");
lua_pushboolean(L, 1);
lua_rawset(L, -3);
#endif
lua_rawset(L, -3);
return 1;
}

View File

@ -1,9 +1,9 @@
/*--------------------------------------------------------------------------
* LuaSec 0.6
* LuaSec 0.8.1
*
* Copyright (C) 2014-2016 Kim Alvefur, Paul Aurich, Tobias Markmann,
* Copyright (C) 2014-2019 Kim Alvefur, Paul Aurich, Tobias Markmann,
* Matthew Wild.
* Copyright (C) 2006-2016 Bruno Silvestre.
* Copyright (C) 2006-2019 Bruno Silvestre.
*
*--------------------------------------------------------------------------*/
@ -24,43 +24,11 @@
#include "context.h"
#include "options.h"
#ifndef OPENSSL_NO_ECDH
#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
#if OPENSSL_VERSION_NUMBER>=0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
#define SSLv23_method() TLS_method()
#endif
/*-- Compat - Lua 5.1 --------------------------------------------------------*/
#if (LUA_VERSION_NUM == 501)
#define luaL_testudata(L, ud, tname) testudata(L, ud, tname)
static void *testudata (lua_State *L, int ud, const char *tname) {
void *p = lua_touserdata(L, ud);
if (p != NULL) { /* value is a userdata? */
if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
luaL_getmetatable(L, tname); /* get correct metatable */
if (!lua_rawequal(L, -1, -2)) /* not the same? */
p = NULL; /* value is a userdata with wrong metatable */
lua_pop(L, 2); /* remove both metatables */
return p;
}
}
return NULL; /* value is not a userdata with a metatable */
}
#endif
/*--------------------------- Auxiliary Functions ----------------------------*/
/**
@ -91,23 +59,59 @@ static int set_option_flag(const char *opt, unsigned long *flag)
return 0;
}
#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL) || (OPENSSL_VERSION_NUMBER < 0x1010000fL)
/**
* 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.
@ -194,7 +198,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);
@ -215,24 +218,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;
}
/**
@ -304,18 +298,6 @@ static int verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
return (verify & LSEC_VERIFY_CONTINUE ? 1 : preverify_ok);
}
#ifndef OPENSSL_NO_ECDH
static EC_KEY *find_ec_key(const char *str)
{
p_ec ptr;
for (ptr = curves; ptr->name; ptr++) {
if (!strcmp(str, ptr->name))
return EC_KEY_new_by_curve_name(ptr->nid);
}
return NULL;
}
#endif
/*------------------------------ Lua Functions -------------------------------*/
/**
@ -325,10 +307,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);
@ -348,6 +331,10 @@ static int create(lua_State *L)
ERR_reason_error_string(ERR_get_error()));
return 2;
}
#if ! ((defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL) || (OPENSSL_VERSION_NUMBER < 0x1010000fL))
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");
@ -449,14 +436,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.
*/
@ -505,12 +509,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);
@ -562,27 +560,24 @@ static int set_dhparam(lua_State *L)
return 0;
}
#if !defined(OPENSSL_NO_EC)
/**
* Set elliptic curve.
*/
#ifdef OPENSSL_NO_ECDH
static int set_curve(lua_State *L)
{
lua_pushboolean(L, 0);
lua_pushstring(L, "OpenSSL does not support ECDH");
return 2;
}
#else
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);
EC_KEY *key = find_ec_key(str);
SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE);
key = lsec_find_ec_key(L, str);
if (!key) {
lua_pushboolean(L, 0);
lua_pushfstring(L, "elliptic curve %s not supported", str);
lua_pushfstring(L, "elliptic curve '%s' not supported", str);
return 2;
}
@ -596,11 +591,119 @@ static int set_curve(lua_State *L)
ERR_reason_error_string(ERR_get_error()));
return 2;
}
lua_pushboolean(L, 1);
return 1;
}
/**
* Set elliptic curves list.
*/
static int set_curves_list(lua_State *L)
{
SSL_CTX *ctx = lsec_checkcontext(L, 1);
const char *str = luaL_checkstring(L, 2);
SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE);
if (SSL_CTX_set1_curves_list(ctx, str) != 1) {
lua_pushboolean(L, 0);
lua_pushfstring(L, "unknown elliptic curve in \"%s\"", str);
return 2;
}
(void)SSL_CTX_set_ecdh_auto(ctx, 1);
lua_pushboolean(L, 1);
return 1;
}
#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;
}
/**
* Package functions
*/
@ -610,13 +713,21 @@ 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},
{"setcurve", set_curve},
{"setverify", set_verify},
{"setoptions", set_options},
{"setmode", set_mode},
#if !defined(OPENSSL_NO_EC)
{"setcurve", set_curve},
{"setcurveslist", set_curves_list},
#endif
{NULL, NULL}
};
@ -638,15 +749,14 @@ 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);
SSL_CTX_free(ctx->context);
ctx->context = NULL;
}
if (ctx->dh_param) {
DH_free(ctx->dh_param);
ctx->dh_param = NULL;
}
return 0;
}
@ -758,6 +868,25 @@ int lsec_getmode(lua_State *L, int idx)
return ctx->mode;
}
/*-- Compat - Lua 5.1 --*/
#if (LUA_VERSION_NUM == 501)
void *lsec_testudata (lua_State *L, int ud, const char *tname) {
void *p = lua_touserdata(L, ud);
if (p != NULL) { /* value is a userdata? */
if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
luaL_getmetatable(L, tname); /* get correct metatable */
if (!lua_rawequal(L, -1, -2)) /* not the same? */
p = NULL; /* value is a userdata with wrong metatable */
lua_pop(L, 2); /* remove both metatables */
return p;
}
}
return NULL; /* value is not a userdata with a metatable */
}
#endif
/*------------------------------ Initialization ------------------------------*/
/**
@ -766,6 +895,7 @@ int lsec_getmode(lua_State *L, int idx)
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:Context");
setfuncs(L, meta);
@ -774,6 +904,8 @@ LSEC_API int luaopen_ssl_context(lua_State *L)
luaL_newlib(L, meta_index);
lua_setfield(L, -2, "__index");
lsec_load_curves(L);
/* Return the module */
luaL_newlib(L, funcs);

View File

@ -2,15 +2,16 @@
#define LSEC_CONTEXT_H
/*--------------------------------------------------------------------------
* LuaSec 0.6
* Copyright (C) 2006-2016 Bruno Silvestre
* LuaSec 0.8.1
*
* Copyright (C) 2006-2019 Bruno Silvestre
*
*--------------------------------------------------------------------------*/
#include <lua.h>
#include <openssl/ssl.h>
#include "config.h"
#include "compat.h"
#define LSEC_MODE_INVALID 0
#define LSEC_MODE_SERVER 1
@ -23,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;
@ -37,4 +39,9 @@ int lsec_getmode(lua_State *L, int idx);
/* Registre the module. */
LSEC_API int luaopen_ssl_context(lua_State *L);
/* Compat - Lua 5.1 */
#if (LUA_VERSION_NUM == 501)
void *lsec_testudata (lua_State *L, int ud, const char *tname);
#endif
#endif

110
src/ec.c Normal file
View File

@ -0,0 +1,110 @@
#include <openssl/objects.h>
#include "ec.h"
#ifndef OPENSSL_NO_EC
EC_KEY *lsec_find_ec_key(lua_State *L, const char *str)
{
int nid;
lua_pushstring(L, "SSL:EC:CURVES");
lua_rawget(L, LUA_REGISTRYINDEX);
lua_pushstring(L, str);
lua_rawget(L, -2);
if (!lua_isnumber(L, -1))
return NULL;
nid = (int)lua_tonumber(L, -1);
return EC_KEY_new_by_curve_name(nid);
}
void lsec_load_curves(lua_State *L)
{
size_t i;
size_t size;
const char *name;
EC_builtin_curve *curves = NULL;
lua_pushstring(L, "SSL:EC:CURVES");
lua_newtable(L);
size = EC_get_builtin_curves(NULL, 0);
if (size > 0) {
curves = (EC_builtin_curve*)malloc(sizeof(EC_builtin_curve) * size);
EC_get_builtin_curves(curves, size);
for (i = 0; i < size; i++) {
name = OBJ_nid2sn(curves[i].nid);
if (name != NULL) {
lua_pushstring(L, name);
lua_pushnumber(L, curves[i].nid);
lua_rawset(L, -3);
}
switch (curves[i].nid) {
case NID_X9_62_prime256v1:
lua_pushstring(L, "P-256");
lua_pushnumber(L, curves[i].nid);
lua_rawset(L, -3);
break;
case NID_secp384r1:
lua_pushstring(L, "P-384");
lua_pushnumber(L, curves[i].nid);
lua_rawset(L, -3);
break;
case NID_secp521r1:
lua_pushstring(L, "P-521");
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);
}
lua_rawset(L, LUA_REGISTRYINDEX);
}
void lsec_get_curves(lua_State *L)
{
lua_newtable(L);
lua_pushstring(L, "SSL:EC:CURVES");
lua_rawget(L, LUA_REGISTRYINDEX);
lua_pushnil(L);
while (lua_next(L, -2) != 0) {
lua_pop(L, 1);
lua_pushvalue(L, -1);
lua_pushboolean(L, 1);
lua_rawset(L, -5);
}
lua_pop(L, 1);
}
#else
void lsec_load_curves(lua_State *L)
{
// do nothing
}
void lsec_get_curves(lua_State *L)
{
lua_newtable(L);
}
#endif

View File

@ -1,64 +1,22 @@
/*--------------------------------------------------------------------------
* LuaSec 0.6
* Copyright (C) 2006-2016 Bruno Silvestre
* LuaSec 0.8.1
*
* Copyright (C) 2006-2019 Bruno Silvestre
*
*--------------------------------------------------------------------------*/
#ifndef LSEC_EC_H
#define LSEC_EC_H
#include <openssl/objects.h>
#include <lua.h>
typedef struct t_ec_ {
char *name;
int nid;
} t_ec;
typedef t_ec* p_ec;
#ifndef OPENSSL_NO_EC
#include <openssl/ec.h>
/* Elliptic curves supported */
static t_ec curves[] = {
/* SECG */
{"secp112r1", NID_secp112r1},
{"secp112r2", NID_secp112r2},
{"secp128r1", NID_secp128r1},
{"secp128r2", NID_secp128r2},
{"secp160k1", NID_secp160k1},
{"secp160r1", NID_secp160r1},
{"secp160r2", NID_secp160r2},
{"secp192k1", NID_secp192k1},
{"secp224k1", NID_secp224k1},
{"secp224r1", NID_secp224r1},
{"secp256k1", NID_secp256k1},
{"secp384r1", NID_secp384r1},
{"secp521r1", NID_secp521r1},
{"sect113r1", NID_sect113r1},
{"sect113r2", NID_sect113r2},
{"sect131r1", NID_sect131r1},
{"sect131r2", NID_sect131r2},
{"sect163k1", NID_sect163k1},
{"sect163r1", NID_sect163r1},
{"sect163r2", NID_sect163r2},
{"sect193r1", NID_sect193r1},
{"sect193r2", NID_sect193r2},
{"sect233k1", NID_sect233k1},
{"sect233r1", NID_sect233r1},
{"sect239k1", NID_sect239k1},
{"sect283k1", NID_sect283k1},
{"sect283r1", NID_sect283r1},
{"sect409k1", NID_sect409k1},
{"sect409r1", NID_sect409r1},
{"sect571k1", NID_sect571k1},
{"sect571r1", NID_sect571r1},
/* ANSI X9.62 */
{"prime192v1", NID_X9_62_prime192v1},
{"prime192v2", NID_X9_62_prime192v2},
{"prime192v3", NID_X9_62_prime192v3},
{"prime239v1", NID_X9_62_prime239v1},
{"prime239v2", NID_X9_62_prime239v2},
{"prime239v3", NID_X9_62_prime239v3},
{"prime256v1", NID_X9_62_prime256v1},
/* End */
{NULL, 0U}
};
EC_KEY *lsec_find_ec_key(lua_State *L, const char *str);
#endif
void lsec_get_curves(lua_State *L);
void lsec_load_curves(lua_State *L);
#endif

View File

@ -1,6 +1,6 @@
----------------------------------------------------------------------------
-- LuaSec 0.6
-- Copyright (C) 2009-2016 PUC-Rio
-- LuaSec 0.8.1
-- Copyright (C) 2009-2019 PUC-Rio
--
-- Author: Pablo Musa
-- Author: Tomas Guisasola
@ -18,15 +18,16 @@ local try = socket.try
-- Module
--
local _M = {
_VERSION = "0.6",
_COPYRIGHT = "LuaSec 0.6 - Copyright (C) 2009-2016 PUC-Rio",
_VERSION = "0.8.1",
_COPYRIGHT = "LuaSec 0.8.1 - Copyright (C) 2009-2019 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,12 +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
@ -138,5 +141,6 @@ end
--
_M.request = request
_M.tcp = tcp
return _M

View File

@ -135,7 +135,7 @@ int buffer_meth_receive(lua_State *L, p_buffer buf) {
}
/* check if there was an error */
if (err != IO_DONE) {
/* we can't push anyting in the stack before pushing the
/* we can't push anything in the stack before pushing the
* contents of the buffer. this is the reason for the complication */
luaL_pushresult(&b);
lua_pushstring(L, buf->io->error(buf->io->ctx, err));

View File

@ -43,7 +43,7 @@ typedef int (*p_send) (
/* interface to recv function */
typedef int (*p_recv) (
void *ctx, /* context needed by recv */
char *data, /* pointer to buffer where data will be writen */
char *data, /* pointer to buffer where data will be written */
size_t count, /* number of bytes to receive into buffer */
size_t *got, /* number of bytes received uppon return */
p_timeout tm /* timeout control */

View File

@ -32,7 +32,7 @@
typedef struct sockaddr SA;
/*=========================================================================*\
* Functions bellow implement a comfortable platform independent
* Functions below implement a comfortable platform independent
* interface to sockets
\*=========================================================================*/
int socket_open(void);

View File

@ -9,7 +9,7 @@
/* timeout control structure */
typedef struct t_timeout_ {
double block; /* maximum time for blocking calls */
double total; /* total number of miliseconds for operation */
double total; /* total number of milliseconds for operation */
double start; /* time of start of operation */
} t_timeout;
typedef t_timeout *p_timeout;

View File

@ -40,7 +40,7 @@ int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
if (*ps >= FD_SETSIZE) return EINVAL;
if (timeout_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */
do {
/* must set bits within loop, because select may have modifed them */
/* must set bits within loop, because select may have modified them */
rp = wp = NULL;
if (sw & WAITFD_R) { FD_ZERO(&rfds); FD_SET(*ps, &rfds); rp = &rfds; }
if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(*ps, &wfds); wp = &wfds; }

View File

@ -2,8 +2,9 @@
#define LSEC_OPTIONS_H
/*--------------------------------------------------------------------------
* LuaSec 0.6
* Copyright (C) 2006-2016 Bruno Silvestre
* LuaSec 0.8.1
*
* Copyright (C) 2006-2019 Bruno Silvestre
*
*--------------------------------------------------------------------------*/
@ -12,7 +13,7 @@
/* If you need to generate these options again, see options.lua */
/*
OpenSSL version: OpenSSL 1.0.2f
OpenSSL version: OpenSSL 1.1.1b
*/
struct ssl_option_s {
@ -25,6 +26,9 @@ static ssl_option_t ssl_options[] = {
#if defined(SSL_OP_ALL)
{"all", SSL_OP_ALL},
#endif
#if defined(SSL_OP_ALLOW_NO_DHE_KEX)
{"allow_no_dhe_kex", SSL_OP_ALLOW_NO_DHE_KEX},
#endif
#if defined(SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)
{"allow_unsafe_legacy_renegotiation", SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION},
#endif
@ -43,6 +47,9 @@ static ssl_option_t ssl_options[] = {
#if defined(SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)
{"dont_insert_empty_fragments", SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS},
#endif
#if defined(SSL_OP_ENABLE_MIDDLEBOX_COMPAT)
{"enable_middlebox_compat", SSL_OP_ENABLE_MIDDLEBOX_COMPAT},
#endif
#if defined(SSL_OP_EPHEMERAL_RSA)
{"ephemeral_rsa", SSL_OP_EPHEMERAL_RSA},
#endif
@ -70,18 +77,30 @@ static ssl_option_t ssl_options[] = {
#if defined(SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG)
{"netscape_reuse_cipher_change_bug", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG},
#endif
#if defined(SSL_OP_NO_ANTI_REPLAY)
{"no_anti_replay", SSL_OP_NO_ANTI_REPLAY},
#endif
#if defined(SSL_OP_NO_COMPRESSION)
{"no_compression", SSL_OP_NO_COMPRESSION},
#endif
#if defined(SSL_OP_NO_DTLS_MASK)
{"no_dtls_mask", SSL_OP_NO_DTLS_MASK},
#endif
#if defined(SSL_OP_NO_DTLSv1)
{"no_dtlsv1", SSL_OP_NO_DTLSv1},
#endif
#if defined(SSL_OP_NO_DTLSv1_2)
{"no_dtlsv1_2", SSL_OP_NO_DTLSv1_2},
#endif
#if defined(SSL_OP_NO_ENCRYPT_THEN_MAC)
{"no_encrypt_then_mac", SSL_OP_NO_ENCRYPT_THEN_MAC},
#endif
#if defined(SSL_OP_NO_QUERY_MTU)
{"no_query_mtu", SSL_OP_NO_QUERY_MTU},
#endif
#if defined(SSL_OP_NO_RENEGOTIATION)
{"no_renegotiation", SSL_OP_NO_RENEGOTIATION},
#endif
#if defined(SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)
{"no_session_resumption_on_renegotiation", SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION},
#endif
@ -106,12 +125,18 @@ static ssl_option_t ssl_options[] = {
#if defined(SSL_OP_NO_TLSv1_2)
{"no_tlsv1_2", SSL_OP_NO_TLSv1_2},
#endif
#if defined(SSL_OP_NO_TLSv1_3)
{"no_tlsv1_3", SSL_OP_NO_TLSv1_3},
#endif
#if defined(SSL_OP_PKCS1_CHECK_1)
{"pkcs1_check_1", SSL_OP_PKCS1_CHECK_1},
#endif
#if defined(SSL_OP_PKCS1_CHECK_2)
{"pkcs1_check_2", SSL_OP_PKCS1_CHECK_2},
#endif
#if defined(SSL_OP_PRIORITIZE_CHACHA)
{"prioritize_chacha", SSL_OP_PRIORITIZE_CHACHA},
#endif
#if defined(SSL_OP_SAFARI_ECDHE_ECDSA_BUG)
{"safari_ecdhe_ecdsa_bug", SSL_OP_SAFARI_ECDHE_ECDSA_BUG},
#endif

View File

@ -1,7 +1,7 @@
local function usage()
print("Usage:")
print("* Generate options of your system:")
print(" lua options.lua -g /path/to/ssl.h [verion] > options.h")
print(" lua options.lua -g /path/to/ssl.h [version] > options.h")
print("* Examples:")
print(" lua options.lua -g /usr/include/openssl/ssl.h > options.h\n")
print(" lua options.lua -g /usr/include/openssl/ssl.h \"OpenSSL 1.0.1 14\" > options.h\n")
@ -21,8 +21,9 @@ local function generate(options, version)
#define LSEC_OPTIONS_H
/*--------------------------------------------------------------------------
* LuaSec 0.6
* Copyright (C) 2006-2016 Bruno Silvestre
* LuaSec 0.8.1
*
* Copyright (C) 2006-2019 Bruno Silvestre
*
*--------------------------------------------------------------------------*/

131
src/ssl.c
View File

@ -1,9 +1,9 @@
/*--------------------------------------------------------------------------
* LuaSec 0.6
* LuaSec 0.8.1
*
* Copyright (C) 2014-2016 Kim Alvefur, Paul Aurich, Tobias Markmann,
* Copyright (C) 2014-2019 Kim Alvefur, Paul Aurich, Tobias Markmann,
* Matthew Wild.
* Copyright (C) 2006-2016 Bruno Silvestre.
* Copyright (C) 2006-2019 Bruno Silvestre.
*
*--------------------------------------------------------------------------*/
@ -11,7 +11,7 @@
#include <string.h>
#if defined(WIN32)
#include <Winsock2.h>
#include <winsock2.h>
#endif
#include <openssl/ssl.h>
@ -31,6 +31,14 @@
#include "context.h"
#include "ssl.h"
#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL) || (OPENSSL_VERSION_NUMBER < 0x1010000fL)
#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)
#endif
/**
* Underline socket error.
*/
@ -191,9 +199,9 @@ static int ssl_recv(void *ctx, char *data, size_t count, size_t *got,
{
int err;
p_ssl ssl = (p_ssl)ctx;
*got = 0;
if (ssl->state != LSEC_STATE_CONNECTED)
return IO_CLOSED;
*got = 0;
for ( ; ; ) {
ERR_clear_error();
err = SSL_read(ssl->ssl, data, (int)count);
@ -203,7 +211,6 @@ static int ssl_recv(void *ctx, char *data, size_t count, size_t *got,
*got = err;
return IO_DONE;
case SSL_ERROR_ZERO_RETURN:
*got = err;
return IO_CLOSED;
case SSL_ERROR_WANT_READ:
err = socket_waitfd(&ssl->sock, WAITFD_R, tm);
@ -230,26 +237,45 @@ static int ssl_recv(void *ctx, char *data, size_t count, size_t *got,
return IO_UNKNOWN;
}
static SSL_CTX* luaossl_testcontext(lua_State *L, int arg) {
SSL_CTX **ctx = luaL_testudata(L, arg, "SSL_CTX*");
if (ctx)
return *ctx;
return NULL;
}
static SSL* luaossl_testssl(lua_State *L, int arg) {
SSL **ssl = luaL_testudata(L, arg, "SSL*");
if (ssl)
return *ssl;
return NULL;
}
/**
* Create a new TLS/SSL object and mark it as new.
*/
static int meth_create(lua_State *L)
{
p_ssl ssl;
int mode = lsec_getmode(L, 1);
SSL_CTX *ctx = lsec_checkcontext(L, 1);
int mode;
SSL_CTX *ctx;
lua_settop(L, 1);
if (mode == LSEC_MODE_INVALID) {
lua_pushnil(L);
lua_pushstring(L, "invalid mode");
return 2;
}
ssl = (p_ssl)lua_newuserdata(L, sizeof(t_ssl));
if (!ssl) {
lua_pushnil(L);
lua_pushstring(L, "error creating SSL object");
return 2;
}
if ((ctx = lsec_testcontext(L, 1))) {
mode = lsec_getmode(L, 1);
if (mode == LSEC_MODE_INVALID) {
lua_pushnil(L);
lua_pushstring(L, "invalid mode");
return 2;
}
ssl->ssl = SSL_new(ctx);
if (!ssl->ssl) {
lua_pushnil(L);
@ -257,13 +283,26 @@ static int meth_create(lua_State *L)
ERR_reason_error_string(ERR_get_error()));
return 2;
}
} else if ((ctx = luaossl_testcontext(L, 1))) {
ssl->ssl = SSL_new(ctx);
if (!ssl->ssl) {
lua_pushnil(L);
lua_pushfstring(L, "error creating SSL object (%s)",
ERR_reason_error_string(ERR_get_error()));
return 2;
}
mode = SSL_is_server(ssl->ssl) ? LSEC_MODE_SERVER : LSEC_MODE_CLIENT;
} else if ((ssl->ssl = luaossl_testssl(L, 1))) {
SSL_up_ref(ssl->ssl);
mode = SSL_is_server(ssl->ssl) ? LSEC_MODE_SERVER : LSEC_MODE_CLIENT;
} else {
return luaL_argerror(L, 1, "invalid context");
}
ssl->state = LSEC_STATE_NEW;
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
@ -341,8 +380,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;
@ -406,7 +456,9 @@ static int meth_want(lua_State *L)
*/
static int meth_compression(lua_State *L)
{
#if !defined(OPENSSL_NO_COMP)
#ifdef OPENSSL_NO_COMP
const void *comp;
#else
const COMP_METHOD *comp;
#endif
p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
@ -415,15 +467,11 @@ static int meth_compression(lua_State *L)
lua_pushstring(L, "closed");
return 2;
}
#if !defined(OPENSSL_NO_COMP)
comp = SSL_get_current_compression(ssl->ssl);
if (comp)
lua_pushstring(L, SSL_COMP_get_name(comp));
else
lua_pushnil(L);
#else
lua_pushnil(L);
#endif
return 1;
}
@ -461,7 +509,7 @@ static int meth_getpeercertificate(lua_State *L)
/* In a server-context, the stack doesn't contain the peer cert,
* so adjust accordingly.
*/
if (ssl->ssl->server)
if (SSL_is_server(ssl->ssl))
--n;
certs = SSL_get_peer_cert_chain(ssl->ssl);
if (n >= sk_X509_num(certs)) {
@ -471,7 +519,7 @@ static int meth_getpeercertificate(lua_State *L)
cert = sk_X509_value(certs, n);
/* Increment the reference counting of the object. */
/* See SSL_get_peer_certificate() source code. */
CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
X509_up_ref(cert);
lsec_pushx509(L, cert);
return 1;
}
@ -493,7 +541,7 @@ static int meth_getpeerchain(lua_State *L)
return 2;
}
lua_newtable(L);
if (ssl->ssl->server) {
if (SSL_is_server(ssl->ssl)) {
lsec_pushx509(L, SSL_get_peer_certificate(ssl->ssl));
lua_rawseti(L, -2, idx++);
}
@ -503,7 +551,7 @@ static int meth_getpeerchain(lua_State *L)
cert = sk_X509_value(certs, i);
/* Increment the reference counting of the object. */
/* See SSL_get_peer_certificate() source code. */
CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
X509_up_ref(cert);
lsec_pushx509(L, cert);
lua_rawseti(L, -2, idx++);
}
@ -755,9 +803,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.6 - Copyright (C) 2006-2016 Bruno Silvestre, UFG"
lua_pushstring(L, "LuaSec 0.8.1 - Copyright (C) 2006-2019 Bruno Silvestre, UFG"
#if defined(WITH_LUASOCKET)
"\nLuaSocket 3.0-RC1 - Copyright (C) 2004-2013 Diego Nehab"
#endif
@ -772,6 +833,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},
@ -842,5 +904,22 @@ LSEC_API int luaopen_ssl_core(lua_State *L)
luaL_newlib(L, funcs);
lua_pushstring(L, "SOCKET_INVALID");
lua_pushnumber(L, SOCKET_INVALID);
lua_rawset(L, -3);
return 1;
}
//------------------------------------------------------------------------------
#if defined(_MSC_VER)
/* Empty implementation to allow building with LuaRocks and MS compilers */
LSEC_API int luaopen_ssl(lua_State *L) {
lua_pushstring(L, "you should not call this function");
lua_error(L);
return 0;
}
#endif

View File

@ -2,8 +2,9 @@
#define LSEC_SSL_H
/*--------------------------------------------------------------------------
* LuaSec 0.6
* Copyright (C) 2006-2016 Bruno Silvestre
* LuaSec 0.8.1
*
* Copyright (C) 2006-2019 Bruno Silvestre
*
*--------------------------------------------------------------------------*/
@ -15,7 +16,7 @@
#include <luasocket/timeout.h>
#include <luasocket/socket.h>
#include "config.h"
#include "compat.h"
#include "context.h"
#define LSEC_STATE_NEW 1

View File

@ -1,12 +1,14 @@
------------------------------------------------------------------------------
-- LuaSec 0.6
-- Copyright (C) 2006-2016 Bruno Silvestre
-- LuaSec 0.8.1
--
-- Copyright (C) 2006-2019 Bruno Silvestre
--
------------------------------------------------------------------------------
local core = require("ssl.core")
local context = require("ssl.context")
local x509 = require("ssl.x509")
local config = require("ssl.config")
local unpack = table.unpack or unpack
@ -28,6 +30,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
--
--
--
@ -39,26 +74,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)
@ -68,6 +111,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)
@ -92,17 +140,67 @@ local function newcontext(cfg)
end
context.setdhparam(ctx, cfg.dhparam)
end
-- Set elliptic curve
if cfg.curve then
-- Set elliptic curves
if (not config.algorithms.ec) and (cfg.curve or cfg.curveslist) then
return false, "elliptic curves not supported"
end
if config.capabilities.curves_list and cfg.curveslist then
succ, msg = context.setcurveslist(ctx, cfg.curveslist)
if not succ then return nil, msg end
elseif cfg.curve then
succ, msg = context.setcurve(ctx, cfg.curve)
if not succ then return nil, msg end
end
-- Set extra verification options
if cfg.verifyext and ctx.setverifyext then
succ, msg = optexec(ctx.setverifyext, cfg.verifyext, ctx)
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
return ctx
end
@ -120,7 +218,7 @@ local function wrap(sock, cfg)
local s, msg = core.create(ctx)
if s then
core.setfd(s, sock:getfd())
sock:setfd(-1)
sock:setfd(core.SOCKET_INVALID)
registry[s] = ctx
return s
end
@ -169,7 +267,7 @@ core.setmethod("info", info)
--
local _M = {
_VERSION = "0.6",
_VERSION = "0.8.1",
_COPYRIGHT = core.copyright(),
loadcertificate = x509.load,
newcontext = newcontext,

View File

@ -1,7 +1,7 @@
/*--------------------------------------------------------------------------
* LuaSec 0.6
* LuaSec 0.8.1
*
* Copyright (C) 2014-2016 Kim Alvefur, Paul Aurich, Tobias Markmann
* Copyright (C) 2014-2019 Kim Alvefur, Paul Aurich, Tobias Markmann
* Matthew Wild, Bruno Silvestre.
*
*--------------------------------------------------------------------------*/
@ -32,6 +32,17 @@
#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)
#endif
static const char* hex_tab = "0123456789abcdef";
/**
@ -146,7 +157,7 @@ static void push_asn1_string(lua_State* L, ASN1_STRING *string, int encode)
}
switch (encode) {
case LSEC_AI5_STRING:
lua_pushlstring(L, (char*)ASN1_STRING_data(string),
lua_pushlstring(L, (char*)LSEC_ASN1_STRING_data(string),
ASN1_STRING_length(string));
break;
case LSEC_UTF8_STRING:
@ -182,7 +193,7 @@ static void push_asn1_ip(lua_State *L, ASN1_STRING *string)
{
int af;
char dst[INET6_ADDRSTRLEN];
unsigned char *ip = ASN1_STRING_data(string);
unsigned char *ip = (unsigned char*)LSEC_ASN1_STRING_data(string);
switch(ASN1_STRING_length(string)) {
case 4:
af = AF_INET;
@ -221,7 +232,7 @@ static int push_subtable(lua_State* L, int idx)
}
/**
* Retrive the general names from the object.
* Retrieve the general names from the object.
*/
static int push_x509_name(lua_State* L, X509_NAME *name, int encode)
{
@ -249,7 +260,7 @@ static int push_x509_name(lua_State* L, X509_NAME *name, int encode)
/*---------------------------------------------------------------------------*/
/**
* Retrive the Subject from the certificate.
* Retrieve the Subject from the certificate.
*/
static int meth_subject(lua_State* L)
{
@ -258,7 +269,7 @@ static int meth_subject(lua_State* L)
}
/**
* Retrive the Issuer from the certificate.
* Retrieve the Issuer from the certificate.
*/
static int meth_issuer(lua_State* L)
{
@ -293,11 +304,11 @@ int meth_extensions(lua_State* L)
break;
/* Push ret[oid] */
push_asn1_objname(L, extension->object, 1);
push_asn1_objname(L, X509_EXTENSION_get_object(extension), 1);
push_subtable(L, -2);
/* Set ret[oid].name = name */
push_asn1_objname(L, extension->object, 0);
push_asn1_objname(L, X509_EXTENSION_get_object(extension), 0);
lua_setfield(L, -2, "name");
n_general_names = sk_GENERAL_NAME_num(values);
@ -360,7 +371,9 @@ int meth_extensions(lua_State* L)
/* not supported */
break;
}
GENERAL_NAME_free(general_name);
}
sk_GENERAL_NAME_free(values);
lua_pop(L, 1); /* ret[oid] */
i++; /* Next extension */
}
@ -404,7 +417,7 @@ static int meth_pubkey(lua_State* L)
bytes = BIO_get_mem_data(bio, &data);
if (bytes > 0) {
lua_pushlstring(L, data, bytes);
switch(EVP_PKEY_type(pkey->type)) {
switch(EVP_PKEY_base_id(pkey)) {
case EVP_PKEY_RSA:
lua_pushstring(L, "RSA");
break;

View File

@ -1,7 +1,7 @@
/*--------------------------------------------------------------------------
* LuaSec 0.6
* LuaSec 0.8.1
*
* Copyright (C) 2014-2016 Kim Alvefur, Paul Aurich, Tobias Markmann
* Copyright (C) 2014-2019 Kim Alvefur, Paul Aurich, Tobias Markmann
* Matthew Wild, Bruno Silvestre.
*
*--------------------------------------------------------------------------*/
@ -12,7 +12,7 @@
#include <openssl/x509v3.h>
#include <lua.h>
#include "config.h"
#include "compat.h"
/* We do not support UniversalString nor BMPString as ASN.1 String types */
enum { LSEC_AI5_STRING, LSEC_UTF8_STRING };