Initial commit (LuaSec 0.4)

Sat, 24 Jul 2010 13:40:16 +0100

author
Matthew Wild <mwild1@gmail.com>
date
Sat, 24 Jul 2010 13:40:16 +0100
changeset 0
f7d2d78eb424
child 1
5f89e535765a

Initial commit (LuaSec 0.4)

CHANGELOG file | annotate | diff | comparison | revisions
INSTALL file | annotate | diff | comparison | revisions
LICENSE file | annotate | diff | comparison | revisions
Makefile file | annotate | diff | comparison | revisions
luasec.sln file | annotate | diff | comparison | revisions
luasec.suo file | annotate | diff | comparison | revisions
luasec.vcproj file | annotate | diff | comparison | revisions
samples/README file | annotate | diff | comparison | revisions
samples/certs/clientA.cnf file | annotate | diff | comparison | revisions
samples/certs/clientA.sh file | annotate | diff | comparison | revisions
samples/certs/clientB.cnf file | annotate | diff | comparison | revisions
samples/certs/clientB.sh file | annotate | diff | comparison | revisions
samples/certs/rootA.cnf file | annotate | diff | comparison | revisions
samples/certs/rootA.sh file | annotate | diff | comparison | revisions
samples/certs/rootB.cnf file | annotate | diff | comparison | revisions
samples/certs/rootB.sh file | annotate | diff | comparison | revisions
samples/certs/serverA.cnf file | annotate | diff | comparison | revisions
samples/certs/serverA.sh file | annotate | diff | comparison | revisions
samples/certs/serverB.cnf file | annotate | diff | comparison | revisions
samples/certs/serverB.sh file | annotate | diff | comparison | revisions
samples/key/genkey.sh file | annotate | diff | comparison | revisions
samples/key/loadkey.lua file | annotate | diff | comparison | revisions
samples/loop-gc/client.lua file | annotate | diff | comparison | revisions
samples/loop-gc/server.lua file | annotate | diff | comparison | revisions
samples/loop/client.lua file | annotate | diff | comparison | revisions
samples/loop/server.lua file | annotate | diff | comparison | revisions
samples/oneshot/client.lua file | annotate | diff | comparison | revisions
samples/oneshot/server.lua file | annotate | diff | comparison | revisions
samples/want/client.lua file | annotate | diff | comparison | revisions
samples/want/server.lua file | annotate | diff | comparison | revisions
samples/wantread/client.lua file | annotate | diff | comparison | revisions
samples/wantread/server.lua file | annotate | diff | comparison | revisions
samples/wantwrite/client.lua file | annotate | diff | comparison | revisions
samples/wantwrite/server.lua file | annotate | diff | comparison | revisions
src/Makefile file | annotate | diff | comparison | revisions
src/buffer.c file | annotate | diff | comparison | revisions
src/buffer.h file | annotate | diff | comparison | revisions
src/context.c file | annotate | diff | comparison | revisions
src/context.h file | annotate | diff | comparison | revisions
src/https.lua file | annotate | diff | comparison | revisions
src/io.c file | annotate | diff | comparison | revisions
src/io.h file | annotate | diff | comparison | revisions
src/socket.h file | annotate | diff | comparison | revisions
src/ssl.c file | annotate | diff | comparison | revisions
src/ssl.h file | annotate | diff | comparison | revisions
src/ssl.lua file | annotate | diff | comparison | revisions
src/timeout.c file | annotate | diff | comparison | revisions
src/timeout.h file | annotate | diff | comparison | revisions
src/usocket.c file | annotate | diff | comparison | revisions
src/usocket.h file | annotate | diff | comparison | revisions
src/wsocket.c file | annotate | diff | comparison | revisions
src/wsocket.h file | annotate | diff | comparison | revisions
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CHANGELOG	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,41 @@
+--------------------------------------------------------------------------------
+LuaSec 0.4
+------------
+- Add option 'no_ticket' (included in OpenSSL 0.9.8f).
+- Add HTTPS module. (thanks Tomas Guisasola and Pablo Musa)
+
+--------------------------------------------------------------------------------
+LuaSec 0.3.3
+------------
+- BUG: Clear the error queue before call I/O functions (see SSL_get_error 
+  manual).
+  (thanks Matthew Wild)
+
+--------------------------------------------------------------------------------
+LuaSec 0.3.2
+------------
+- BUG: Windows uses a different way to report socket error.
+  (thanks Sebastien Perin)
+
+--------------------------------------------------------------------------------
+LuaSec 0.3.1
+------------
+- BUG: receive("a") returns 'closed' error instead of the content when the
+  SSL/TLS connection is shut down cleanly. (thanks Matthias Diener)
+
+--------------------------------------------------------------------------------
+LuaSec 0.3
+----------
+- Add functions ssl.rawcontext() and ssl.rawconnection()
+- Add support to encrypted key password. (thanks Norbert Kiesel)
+
+--------------------------------------------------------------------------------
+LuaSec 0.2.1
+------------
+- 'key' and 'certificate' configurations become optional. (thanks René Rebe)
+- Add '_VERSION' variable to module.
+
+--------------------------------------------------------------------------------
+LuaSec 0.2
+----------
+Initial version
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/INSTALL	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,26 @@
+LuaSec 0.4
+------------
+
+* On Linux, BSD, and Mac OS X:
+
+  - Edit 'Makefile'
+    * Inform the path to where install the Lua modules (LUAPATH) and binaries 
+      modules (LUACPATH)
+    * If Lua or OpenSSL are not in the default path, set the 
+      variables INCDIR and LIBDIR.
+    * For Mac OS X, set the variable MACOSX_VERSION.
+
+  - Use 'make <platform>' to compile
+    * Platforms: linux, bsd, or macosx
+
+  - Use 'make install' to install the modules.
+
+* On Windows:
+  
+  - Use the Visual C++ project to compile the library.
+
+  - Copy the 'ssl.lua' file to some place in your LUA_PATH.
+
+  - Copy the 'ssl.dll' file to some place in your LUA_CPATH.
+
+  - Create a directory 'ssl' in your LUA_PATH and copy 'https.lua' to it.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LICENSE	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,45 @@
+LuaSec 0.4 license
+Copyright (C) 2006-2009 Bruno Silvestre, PUC-Rio
+
+Permission is hereby granted, free  of charge, to any person obtaining
+a  copy  of this  software  and  associated  documentation files  (the
+"Software"), to  deal in  the Software without  restriction, including
+without limitation  the rights to  use, copy, modify,  merge, publish,
+distribute,  sublicense, and/or sell  copies of  the Software,  and to
+permit persons to whom the Software  is furnished to do so, subject to
+the following conditions:
+
+The  above  copyright  notice  and  this permission  notice  shall  be
+included in all copies or substantial portions of the Software.
+
+THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
+EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
+MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+----------------------------------------------------------------------
+
+LuaSocket 2.0.2 license
+Copyright © 2004-2007 Diego Nehab
+
+Permission is hereby granted, free  of charge, to any person obtaining
+a  copy  of this  software  and  associated documentation  files  (the
+"Software"), to  deal in  the Software without  restriction, including
+without limitation  the rights to  use, copy, modify,  merge, publish,
+distribute, sublicense,  and/or sell  copies of  the Software,  and to
+permit persons to whom the Software  is furnished to do so, subject to
+the following conditions:
+
+The  above  copyright  notice  and this  permission  notice  shall  be
+included in all copies or substantial portions of the Software.
+
+THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
+EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT  SHALL THE AUTHORS OR COPYRIGHT HOLDERS  BE LIABLE FOR ANY
+CLAIM, DAMAGES OR  OTHER LIABILITY, WHETHER IN AN  ACTION OF CONTRACT,
+TORT OR  OTHERWISE, ARISING  FROM, OUT  OF OR  IN CONNECTION  WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,50 @@
+# Inform the location to intall the modules
+LUAPATH=/usr/local/share/lua/5.1
+LUACPATH=/usr/local/lib/lua/5.1
+
+# Edit the lines below to inform new path, if necessary
+#
+#INCDIR=-I/usr/local/lua-5.1/include -I/usr/local/openssl-0.9.8/include
+#LIBDIR=-L/usr/local/openssl-0.9.8/lib -R/usr/local/openssl-0.9.8/lib
+
+# For Mac OS X: set the system version
+MACOSX_VERSION=10.4
+
+DEFS=-DBUFFER_DEBUG
+
+#----------------------
+# Do not edit this part
+
+.PHONY: all clean install none linux bsd macosx
+
+all: none
+
+none:
+	@echo "Usage: $(MAKE) <platform>"
+	@echo "  * linux"
+	@echo "  * bsd"
+	@echo "  * macosx"
+
+install:
+	@cd src ; $(MAKE) LUACPATH="$(LUACPATH)" LUAPATH="$(LUAPATH)" install
+
+linux:
+	@echo "---------------------"
+	@echo "** Build for Linux **"
+	@echo "---------------------"
+	@cd src ; $(MAKE) INCDIR="$(INCDIR)" LIBDIR="$(LIBDIR)" DEFS="$(DEFS)" $@
+
+bsd:
+	@echo "-------------------"
+	@echo "** Build for BSD **"
+	@echo "-------------------"
+	@cd src ; $(MAKE) INCDIR="$(INCDIR)" LIBDIR="$(LIBDIR)" DEFS="$(DEFS)" $@
+
+macosx:
+	@echo "------------------------------"
+	@echo "** Build for Mac OS X $(MACOSX_VERSION) **"
+	@echo "------------------------------"
+	@cd src ; $(MAKE) INCDIR="$(INCDIR)" LIBDIR="$(LIBDIR)" DEFS="$(DEFS)" MACVER="$(MACOSX_VERSION)" $@
+
+clean:
+	@cd src ; $(MAKE) clean
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/luasec.sln	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,19 @@
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual C++ Express 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "luasec", "luasec.vcproj", "{A629932F-8819-4C0B-8835-CBF1FEED6376}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{A629932F-8819-4C0B-8835-CBF1FEED6376}.Debug|Win32.ActiveCfg = Debug|Win32
+		{A629932F-8819-4C0B-8835-CBF1FEED6376}.Debug|Win32.Build.0 = Debug|Win32
+		{A629932F-8819-4C0B-8835-CBF1FEED6376}.Release|Win32.ActiveCfg = Release|Win32
+		{A629932F-8819-4C0B-8835-CBF1FEED6376}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
Binary file luasec.suo has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/luasec.vcproj	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,253 @@
+<?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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/README	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,28 @@
+Directories: 
+------------
+* certs
+ Contains scripts to generate the certificates used by the examples.
+ Generate Root CA 'A' and 'B' first, then the servers and clients.
+
+* oneshot
+ A simple connection example.
+
+* loop
+ Test successive connections between the server and the client 
+ (to check memory leak).
+
+* loop-gc
+ Same of above,  but the connection is not  explicit closed, the gabage
+ collector is encharge of that.
+
+* wantread
+ Test timeout in handshake() and receive().
+
+* wantwrite
+ Test timeout in send().
+
+* want
+ Test want().
+
+* key
+ Test encrypted private key.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/certs/clientA.cnf	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,316 @@
+#
+# OpenSSL example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+
+# This definition stops the following lines choking if HOME isn't
+# defined.
+HOME			= .
+RANDFILE		= $ENV::HOME/.rnd
+
+# Extra OBJECT IDENTIFIER info:
+#oid_file		= $ENV::HOME/.oid
+oid_section		= new_oids
+
+# To use this configuration file with the "-extfile" option of the
+# "openssl x509" utility, name here the section containing the
+# X.509v3 extensions to use:
+# extensions		= 
+# (Alternatively, use a configuration file that has only
+# X.509v3 extensions in its main [= default] section.)
+
+[ new_oids ]
+
+# We can add new OIDs in here for use by 'ca' and 'req'.
+# Add a simple OID like this:
+# testoid1=1.2.3.4
+# Or use config file substitution like this:
+# testoid2=${testoid1}.5.6
+
+####################################################################
+[ ca ]
+default_ca	= CA_default		# The default ca section
+
+####################################################################
+[ CA_default ]
+
+dir		= ./demoCA		# Where everything is kept
+certs		= $dir/certs		# Where the issued certs are kept
+crl_dir		= $dir/crl		# Where the issued crl are kept
+database	= $dir/index.txt	# database index file.
+#unique_subject	= no			# Set to 'no' to allow creation of
+					# several ctificates with same subject.
+new_certs_dir	= $dir/newcerts		# default place for new certs.
+
+certificate	= $dir/cacert.pem 	# The CA certificate
+serial		= $dir/serial 		# The current serial number
+crlnumber	= $dir/crlnumber	# the current crl number
+					# must be commented out to leave a V1 CRL
+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
+
+# Comment out the following two lines for the "traditional"
+# (and highly broken) format.
+name_opt 	= ca_default		# Subject Name options
+cert_opt 	= ca_default		# Certificate field options
+
+# Extension copying option: use with caution.
+# copy_extensions = copy
+
+# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
+# so this is commented out by default to leave a V1 CRL.
+# crlnumber must also be commented out to leave a V1 CRL.
+# crl_extensions	= crl_ext
+
+default_days	= 365			# how long to certify for
+default_crl_days= 30			# how long before next CRL
+default_md	= sha1			# which md to use.
+preserve	= no			# keep passed DN ordering
+
+# A few difference way of specifying how similar the request should look
+# For type CA, the listed attributes must be the same, and the optional
+# and supplied fields are just that :-)
+policy		= policy_match
+
+# For the CA policy
+[ policy_match ]
+countryName		= match
+stateOrProvinceName	= match
+organizationName	= match
+organizationalUnitName	= optional
+commonName		= supplied
+emailAddress		= optional
+
+# For the 'anything' policy
+# At this point in time, you must list all acceptable 'object'
+# types.
+[ policy_anything ]
+countryName		= optional
+stateOrProvinceName	= optional
+localityName		= optional
+organizationName	= optional
+organizationalUnitName	= optional
+commonName		= supplied
+emailAddress		= optional
+
+####################################################################
+[ req ]
+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
+
+# Passwords for private keys if not present they will be prompted for
+# input_password = secret
+# output_password = secret
+
+# This sets a mask for permitted string types. There are several options. 
+# default: PrintableString, T61String, BMPString.
+# pkix	 : PrintableString, BMPString.
+# utf8only: only UTF8Strings.
+# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
+# MASK:XXXX a literal mask value.
+# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
+# so use this option with caution!
+string_mask = nombstr
+
+# req_extensions = v3_req # The extensions to add to a certificate request
+
+[ req_distinguished_name ]
+countryName			= Country Name (2 letter code)
+countryName_default		= BR
+countryName_min			= 2
+countryName_max			= 2
+
+stateOrProvinceName		= State or Province Name (full name)
+stateOrProvinceName_default	= Some-State
+stateOrProvinceName_default	= Espirito Santo
+
+localityName			= Locality Name (eg, city)
+localityName_default		= Santo Antonio do Canaa
+
+0.organizationName		= Organization Name (eg, company)
+0.organizationName_default	= Sao Tonico Ltda
+
+# we can do this but it is not needed normally :-)
+#1.organizationName		= Second Organization Name (eg, company)
+#1.organizationName_default	= World Wide Web Pty Ltd
+
+organizationalUnitName		= Organizational Unit Name (eg, section)
+organizationalUnitName_default	= Department of Computer Science
+
+commonName			= Common Name (eg, YOUR name)
+commonName_default		= Client A
+commonName_max			= 64
+
+emailAddress			= Email Address
+emailAddress_max		= 64
+
+# SET-ex3			= SET extension number 3
+
+[ req_attributes ]
+challengePassword		= A challenge password
+challengePassword_min		= 4
+challengePassword_max		= 20
+
+unstructuredName		= An optional company name
+
+[ usr_cert ]
+
+# These extensions are added when 'ca' signs a request.
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType			= server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment			= "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+[ v3_req ]
+
+# Extensions to add to a certificate request
+
+basicConstraints = CA:FALSE
+keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+[ v3_ca ]
+
+
+# Extensions for a typical CA
+
+
+# PKIX recommendation.
+
+subjectKeyIdentifier=hash
+
+authorityKeyIdentifier=keyid:always,issuer:always
+
+# This is what PKIX recommends but some broken software chokes on critical
+# extensions.
+#basicConstraints = critical,CA:true
+# So we do this instead.
+basicConstraints = CA:true
+
+# Key usage: this is typical for a CA certificate. However since it will
+# prevent it being used as an test self-signed certificate it is best
+# left out by default.
+# keyUsage = cRLSign, keyCertSign
+
+# Some might want this also
+# nsCertType = sslCA, emailCA
+
+# Include email address in subject alt name: another PKIX recommendation
+# subjectAltName=email:copy
+# Copy issuer details
+# issuerAltName=issuer:copy
+
+# DER hex encoding of an extension: beware experts only!
+# obj=DER:02:03
+# Where 'obj' is a standard or added object
+# You can even override a supported extension:
+# basicConstraints= critical, DER:30:03:01:01:FF
+
+[ crl_ext ]
+
+# CRL extensions.
+# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
+
+# issuerAltName=issuer:copy
+authorityKeyIdentifier=keyid:always,issuer:always
+
+[ proxy_cert_ext ]
+# These extensions should be added when creating a proxy certificate
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType			= server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment			= "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+# This really needs to be in place for it to be a proxy certificate.
+proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/certs/clientA.sh	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+openssl req -newkey rsa:1024 -sha1 -keyout clientAkey.pem -out clientAreq.pem \
+  -nodes -config ./clientA.cnf -days 365 -batch
+
+openssl x509 -req -in clientAreq.pem -sha1 -extfile ./clientA.cnf \
+  -extensions usr_cert -CA rootA.pem -CAkey rootAkey.pem -CAcreateserial \
+  -out clientAcert.pem -days 365
+
+cat clientAcert.pem rootA.pem > clientA.pem
+
+openssl x509 -subject -issuer -noout -in clientA.pem
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/certs/clientB.cnf	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,316 @@
+#
+# OpenSSL example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+
+# This definition stops the following lines choking if HOME isn't
+# defined.
+HOME			= .
+RANDFILE		= $ENV::HOME/.rnd
+
+# Extra OBJECT IDENTIFIER info:
+#oid_file		= $ENV::HOME/.oid
+oid_section		= new_oids
+
+# To use this configuration file with the "-extfile" option of the
+# "openssl x509" utility, name here the section containing the
+# X.509v3 extensions to use:
+# extensions		= 
+# (Alternatively, use a configuration file that has only
+# X.509v3 extensions in its main [= default] section.)
+
+[ new_oids ]
+
+# We can add new OIDs in here for use by 'ca' and 'req'.
+# Add a simple OID like this:
+# testoid1=1.2.3.4
+# Or use config file substitution like this:
+# testoid2=${testoid1}.5.6
+
+####################################################################
+[ ca ]
+default_ca	= CA_default		# The default ca section
+
+####################################################################
+[ CA_default ]
+
+dir		= ./demoCA		# Where everything is kept
+certs		= $dir/certs		# Where the issued certs are kept
+crl_dir		= $dir/crl		# Where the issued crl are kept
+database	= $dir/index.txt	# database index file.
+#unique_subject	= no			# Set to 'no' to allow creation of
+					# several ctificates with same subject.
+new_certs_dir	= $dir/newcerts		# default place for new certs.
+
+certificate	= $dir/cacert.pem 	# The CA certificate
+serial		= $dir/serial 		# The current serial number
+crlnumber	= $dir/crlnumber	# the current crl number
+					# must be commented out to leave a V1 CRL
+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
+
+# Comment out the following two lines for the "traditional"
+# (and highly broken) format.
+name_opt 	= ca_default		# Subject Name options
+cert_opt 	= ca_default		# Certificate field options
+
+# Extension copying option: use with caution.
+# copy_extensions = copy
+
+# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
+# so this is commented out by default to leave a V1 CRL.
+# crlnumber must also be commented out to leave a V1 CRL.
+# crl_extensions	= crl_ext
+
+default_days	= 365			# how long to certify for
+default_crl_days= 30			# how long before next CRL
+default_md	= sha1			# which md to use.
+preserve	= no			# keep passed DN ordering
+
+# A few difference way of specifying how similar the request should look
+# For type CA, the listed attributes must be the same, and the optional
+# and supplied fields are just that :-)
+policy		= policy_match
+
+# For the CA policy
+[ policy_match ]
+countryName		= match
+stateOrProvinceName	= match
+organizationName	= match
+organizationalUnitName	= optional
+commonName		= supplied
+emailAddress		= optional
+
+# For the 'anything' policy
+# At this point in time, you must list all acceptable 'object'
+# types.
+[ policy_anything ]
+countryName		= optional
+stateOrProvinceName	= optional
+localityName		= optional
+organizationName	= optional
+organizationalUnitName	= optional
+commonName		= supplied
+emailAddress		= optional
+
+####################################################################
+[ req ]
+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
+
+# Passwords for private keys if not present they will be prompted for
+# input_password = secret
+# output_password = secret
+
+# This sets a mask for permitted string types. There are several options. 
+# default: PrintableString, T61String, BMPString.
+# pkix	 : PrintableString, BMPString.
+# utf8only: only UTF8Strings.
+# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
+# MASK:XXXX a literal mask value.
+# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
+# so use this option with caution!
+string_mask = nombstr
+
+# req_extensions = v3_req # The extensions to add to a certificate request
+
+[ req_distinguished_name ]
+countryName			= Country Name (2 letter code)
+countryName_default		= BR
+countryName_min			= 2
+countryName_max			= 2
+
+stateOrProvinceName		= State or Province Name (full name)
+stateOrProvinceName_default	= Some-State
+stateOrProvinceName_default	= Espirito Santo
+
+localityName			= Locality Name (eg, city)
+localityName_default		= Santo Antonio do Canaa
+
+0.organizationName		= Organization Name (eg, company)
+0.organizationName_default	= Sao Tonico Ltda
+
+# we can do this but it is not needed normally :-)
+#1.organizationName		= Second Organization Name (eg, company)
+#1.organizationName_default	= World Wide Web Pty Ltd
+
+organizationalUnitName		= Organizational Unit Name (eg, section)
+organizationalUnitName_default	= Department of Computer Science
+
+commonName			= Common Name (eg, YOUR name)
+commonName_default		= Client B
+commonName_max			= 64
+
+emailAddress			= Email Address
+emailAddress_max		= 64
+
+# SET-ex3			= SET extension number 3
+
+[ req_attributes ]
+challengePassword		= A challenge password
+challengePassword_min		= 4
+challengePassword_max		= 20
+
+unstructuredName		= An optional company name
+
+[ usr_cert ]
+
+# These extensions are added when 'ca' signs a request.
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType			= server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment			= "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+[ v3_req ]
+
+# Extensions to add to a certificate request
+
+basicConstraints = CA:FALSE
+keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+[ v3_ca ]
+
+
+# Extensions for a typical CA
+
+
+# PKIX recommendation.
+
+subjectKeyIdentifier=hash
+
+authorityKeyIdentifier=keyid:always,issuer:always
+
+# This is what PKIX recommends but some broken software chokes on critical
+# extensions.
+#basicConstraints = critical,CA:true
+# So we do this instead.
+basicConstraints = CA:true
+
+# Key usage: this is typical for a CA certificate. However since it will
+# prevent it being used as an test self-signed certificate it is best
+# left out by default.
+# keyUsage = cRLSign, keyCertSign
+
+# Some might want this also
+# nsCertType = sslCA, emailCA
+
+# Include email address in subject alt name: another PKIX recommendation
+# subjectAltName=email:copy
+# Copy issuer details
+# issuerAltName=issuer:copy
+
+# DER hex encoding of an extension: beware experts only!
+# obj=DER:02:03
+# Where 'obj' is a standard or added object
+# You can even override a supported extension:
+# basicConstraints= critical, DER:30:03:01:01:FF
+
+[ crl_ext ]
+
+# CRL extensions.
+# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
+
+# issuerAltName=issuer:copy
+authorityKeyIdentifier=keyid:always,issuer:always
+
+[ proxy_cert_ext ]
+# These extensions should be added when creating a proxy certificate
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType			= server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment			= "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+# This really needs to be in place for it to be a proxy certificate.
+proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/certs/clientB.sh	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+openssl req -newkey rsa:1024 -sha1 -keyout clientBkey.pem -out clientBreq.pem \
+  -nodes -config ./clientB.cnf -days 365 -batch
+
+openssl x509 -req -in clientBreq.pem -sha1 -extfile ./clientB.cnf \
+  -extensions usr_cert -CA rootB.pem -CAkey rootBkey.pem -CAcreateserial \
+  -out clientBcert.pem -days 365
+
+cat clientBcert.pem rootB.pem > clientB.pem
+
+openssl x509 -subject -issuer -noout -in clientB.pem
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/certs/rootA.cnf	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,315 @@
+#
+# OpenSSL example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+
+# This definition stops the following lines choking if HOME isn't
+# defined.
+HOME			= .
+RANDFILE		= $ENV::HOME/.rnd
+
+# Extra OBJECT IDENTIFIER info:
+#oid_file		= $ENV::HOME/.oid
+oid_section		= new_oids
+
+# To use this configuration file with the "-extfile" option of the
+# "openssl x509" utility, name here the section containing the
+# X.509v3 extensions to use:
+# extensions		= 
+# (Alternatively, use a configuration file that has only
+# X.509v3 extensions in its main [= default] section.)
+
+[ new_oids ]
+
+# We can add new OIDs in here for use by 'ca' and 'req'.
+# Add a simple OID like this:
+# testoid1=1.2.3.4
+# Or use config file substitution like this:
+# testoid2=${testoid1}.5.6
+
+####################################################################
+[ ca ]
+default_ca	= CA_default		# The default ca section
+
+####################################################################
+[ CA_default ]
+
+dir		= ./demoCA		# Where everything is kept
+certs		= $dir/certs		# Where the issued certs are kept
+crl_dir		= $dir/crl		# Where the issued crl are kept
+database	= $dir/index.txt	# database index file.
+#unique_subject	= no			# Set to 'no' to allow creation of
+					# several ctificates with same subject.
+new_certs_dir	= $dir/newcerts		# default place for new certs.
+
+certificate	= $dir/cacert.pem 	# The CA certificate
+serial		= $dir/serial 		# The current serial number
+crlnumber	= $dir/crlnumber	# the current crl number
+					# must be commented out to leave a V1 CRL
+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
+
+# Comment out the following two lines for the "traditional"
+# (and highly broken) format.
+name_opt 	= ca_default		# Subject Name options
+cert_opt 	= ca_default		# Certificate field options
+
+# Extension copying option: use with caution.
+# copy_extensions = copy
+
+# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
+# so this is commented out by default to leave a V1 CRL.
+# crlnumber must also be commented out to leave a V1 CRL.
+# crl_extensions	= crl_ext
+
+default_days	= 365			# how long to certify for
+default_crl_days= 30			# how long before next CRL
+default_md	= sha1			# which md to use.
+preserve	= no			# keep passed DN ordering
+
+# A few difference way of specifying how similar the request should look
+# For type CA, the listed attributes must be the same, and the optional
+# and supplied fields are just that :-)
+policy		= policy_match
+
+# For the CA policy
+[ policy_match ]
+countryName		= match
+stateOrProvinceName	= match
+organizationName	= match
+organizationalUnitName	= optional
+commonName		= supplied
+emailAddress		= optional
+
+# For the 'anything' policy
+# At this point in time, you must list all acceptable 'object'
+# types.
+[ policy_anything ]
+countryName		= optional
+stateOrProvinceName	= optional
+localityName		= optional
+organizationName	= optional
+organizationalUnitName	= optional
+commonName		= supplied
+emailAddress		= optional
+
+####################################################################
+[ req ]
+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
+
+# Passwords for private keys if not present they will be prompted for
+# input_password = secret
+# output_password = secret
+
+# This sets a mask for permitted string types. There are several options. 
+# default: PrintableString, T61String, BMPString.
+# pkix	 : PrintableString, BMPString.
+# utf8only: only UTF8Strings.
+# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
+# MASK:XXXX a literal mask value.
+# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
+# so use this option with caution!
+string_mask = nombstr
+
+# req_extensions = v3_req # The extensions to add to a certificate request
+
+[ req_distinguished_name ]
+countryName			= Country Name (2 letter code)
+countryName_default		= BR
+countryName_min			= 2
+countryName_max			= 2
+
+stateOrProvinceName		= State or Province Name (full name)
+stateOrProvinceName_default	= Espirito Santo
+
+localityName			= Locality Name (eg, city)
+localityName_default		= Santo Antonio do Canaa
+
+0.organizationName		= Organization Name (eg, company)
+0.organizationName_default	= Santo Tonico Ltda
+
+# we can do this but it is not needed normally :-)
+#1.organizationName		= Second Organization Name (eg, company)
+#1.organizationName_default	= World Wide Web Pty Ltd
+
+organizationalUnitName		= Organizational Unit Name (eg, section)
+organizationalUnitName_default	= Department of Computer Science
+
+commonName			= Common Name (eg, YOUR name)
+commonName_max			= 64
+commonName_default		= Root A
+
+emailAddress			= Email Address
+emailAddress_max		= 64
+
+# SET-ex3			= SET extension number 3
+
+[ req_attributes ]
+challengePassword		= A challenge password
+challengePassword_min		= 4
+challengePassword_max		= 20
+
+unstructuredName		= An optional company name
+
+[ usr_cert ]
+
+# These extensions are added when 'ca' signs a request.
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType			= server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment			= "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+[ v3_req ]
+
+# Extensions to add to a certificate request
+
+basicConstraints = CA:FALSE
+keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+[ v3_ca ]
+
+
+# Extensions for a typical CA
+
+
+# PKIX recommendation.
+
+subjectKeyIdentifier=hash
+
+authorityKeyIdentifier=keyid:always,issuer:always
+
+# This is what PKIX recommends but some broken software chokes on critical
+# extensions.
+#basicConstraints = critical,CA:true
+# So we do this instead.
+basicConstraints = CA:true
+
+# Key usage: this is typical for a CA certificate. However since it will
+# prevent it being used as an test self-signed certificate it is best
+# left out by default.
+# keyUsage = cRLSign, keyCertSign
+
+# Some might want this also
+# nsCertType = sslCA, emailCA
+
+# Include email address in subject alt name: another PKIX recommendation
+# subjectAltName=email:copy
+# Copy issuer details
+# issuerAltName=issuer:copy
+
+# DER hex encoding of an extension: beware experts only!
+# obj=DER:02:03
+# Where 'obj' is a standard or added object
+# You can even override a supported extension:
+# basicConstraints= critical, DER:30:03:01:01:FF
+
+[ crl_ext ]
+
+# CRL extensions.
+# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
+
+# issuerAltName=issuer:copy
+authorityKeyIdentifier=keyid:always,issuer:always
+
+[ proxy_cert_ext ]
+# These extensions should be added when creating a proxy certificate
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType			= server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment			= "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+# This really needs to be in place for it to be a proxy certificate.
+proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/certs/rootA.sh	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+openssl req -newkey rsa:1024 -sha1 -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 -subject -issuer -noout -in rootA.pem
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/certs/rootB.cnf	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,315 @@
+#
+# OpenSSL example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+
+# This definition stops the following lines choking if HOME isn't
+# defined.
+HOME			= .
+RANDFILE		= $ENV::HOME/.rnd
+
+# Extra OBJECT IDENTIFIER info:
+#oid_file		= $ENV::HOME/.oid
+oid_section		= new_oids
+
+# To use this configuration file with the "-extfile" option of the
+# "openssl x509" utility, name here the section containing the
+# X.509v3 extensions to use:
+# extensions		= 
+# (Alternatively, use a configuration file that has only
+# X.509v3 extensions in its main [= default] section.)
+
+[ new_oids ]
+
+# We can add new OIDs in here for use by 'ca' and 'req'.
+# Add a simple OID like this:
+# testoid1=1.2.3.4
+# Or use config file substitution like this:
+# testoid2=${testoid1}.5.6
+
+####################################################################
+[ ca ]
+default_ca	= CA_default		# The default ca section
+
+####################################################################
+[ CA_default ]
+
+dir		= ./demoCA		# Where everything is kept
+certs		= $dir/certs		# Where the issued certs are kept
+crl_dir		= $dir/crl		# Where the issued crl are kept
+database	= $dir/index.txt	# database index file.
+#unique_subject	= no			# Set to 'no' to allow creation of
+					# several ctificates with same subject.
+new_certs_dir	= $dir/newcerts		# default place for new certs.
+
+certificate	= $dir/cacert.pem 	# The CA certificate
+serial		= $dir/serial 		# The current serial number
+crlnumber	= $dir/crlnumber	# the current crl number
+					# must be commented out to leave a V1 CRL
+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
+
+# Comment out the following two lines for the "traditional"
+# (and highly broken) format.
+name_opt 	= ca_default		# Subject Name options
+cert_opt 	= ca_default		# Certificate field options
+
+# Extension copying option: use with caution.
+# copy_extensions = copy
+
+# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
+# so this is commented out by default to leave a V1 CRL.
+# crlnumber must also be commented out to leave a V1 CRL.
+# crl_extensions	= crl_ext
+
+default_days	= 365			# how long to certify for
+default_crl_days= 30			# how long before next CRL
+default_md	= sha1			# which md to use.
+preserve	= no			# keep passed DN ordering
+
+# A few difference way of specifying how similar the request should look
+# For type CA, the listed attributes must be the same, and the optional
+# and supplied fields are just that :-)
+policy		= policy_match
+
+# For the CA policy
+[ policy_match ]
+countryName		= match
+stateOrProvinceName	= match
+organizationName	= match
+organizationalUnitName	= optional
+commonName		= supplied
+emailAddress		= optional
+
+# For the 'anything' policy
+# At this point in time, you must list all acceptable 'object'
+# types.
+[ policy_anything ]
+countryName		= optional
+stateOrProvinceName	= optional
+localityName		= optional
+organizationName	= optional
+organizationalUnitName	= optional
+commonName		= supplied
+emailAddress		= optional
+
+####################################################################
+[ req ]
+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
+
+# Passwords for private keys if not present they will be prompted for
+# input_password = secret
+# output_password = secret
+
+# This sets a mask for permitted string types. There are several options. 
+# default: PrintableString, T61String, BMPString.
+# pkix	 : PrintableString, BMPString.
+# utf8only: only UTF8Strings.
+# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
+# MASK:XXXX a literal mask value.
+# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
+# so use this option with caution!
+string_mask = nombstr
+
+# req_extensions = v3_req # The extensions to add to a certificate request
+
+[ req_distinguished_name ]
+countryName			= Country Name (2 letter code)
+countryName_default		= BR
+countryName_min			= 2
+countryName_max			= 2
+
+stateOrProvinceName		= State or Province Name (full name)
+stateOrProvinceName_default	= Espirito Santo
+
+localityName			= Locality Name (eg, city)
+localityName_default		= Santo Antonio do Canaa
+
+0.organizationName		= Organization Name (eg, company)
+0.organizationName_default	= Sao Tonico Ltda
+
+# we can do this but it is not needed normally :-)
+#1.organizationName		= Second Organization Name (eg, company)
+#1.organizationName_default	= World Wide Web Pty Ltd
+
+organizationalUnitName		= Organizational Unit Name (eg, section)
+organizationalUnitName_default	= Department of Computer Science
+
+commonName			= Common Name (eg, YOUR name)
+commonName_default		= Root B
+commonName_max			= 64
+
+emailAddress			= Email Address
+emailAddress_max		= 64
+
+# SET-ex3			= SET extension number 3
+
+[ req_attributes ]
+challengePassword		= A challenge password
+challengePassword_min		= 4
+challengePassword_max		= 20
+
+unstructuredName		= An optional company name
+
+[ usr_cert ]
+
+# These extensions are added when 'ca' signs a request.
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType			= server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment			= "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+[ v3_req ]
+
+# Extensions to add to a certificate request
+
+basicConstraints = CA:FALSE
+keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+[ v3_ca ]
+
+
+# Extensions for a typical CA
+
+
+# PKIX recommendation.
+
+subjectKeyIdentifier=hash
+
+authorityKeyIdentifier=keyid:always,issuer:always
+
+# This is what PKIX recommends but some broken software chokes on critical
+# extensions.
+#basicConstraints = critical,CA:true
+# So we do this instead.
+basicConstraints = CA:true
+
+# Key usage: this is typical for a CA certificate. However since it will
+# prevent it being used as an test self-signed certificate it is best
+# left out by default.
+# keyUsage = cRLSign, keyCertSign
+
+# Some might want this also
+# nsCertType = sslCA, emailCA
+
+# Include email address in subject alt name: another PKIX recommendation
+# subjectAltName=email:copy
+# Copy issuer details
+# issuerAltName=issuer:copy
+
+# DER hex encoding of an extension: beware experts only!
+# obj=DER:02:03
+# Where 'obj' is a standard or added object
+# You can even override a supported extension:
+# basicConstraints= critical, DER:30:03:01:01:FF
+
+[ crl_ext ]
+
+# CRL extensions.
+# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
+
+# issuerAltName=issuer:copy
+authorityKeyIdentifier=keyid:always,issuer:always
+
+[ proxy_cert_ext ]
+# These extensions should be added when creating a proxy certificate
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType			= server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment			= "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+# This really needs to be in place for it to be a proxy certificate.
+proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/certs/rootB.sh	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+openssl req -newkey rsa:1024 -sha1 -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 -subject -issuer -noout -in rootB.pem
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/certs/serverA.cnf	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,316 @@
+#
+# OpenSSL example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+
+# This definition stops the following lines choking if HOME isn't
+# defined.
+HOME			= .
+RANDFILE		= $ENV::HOME/.rnd
+
+# Extra OBJECT IDENTIFIER info:
+#oid_file		= $ENV::HOME/.oid
+oid_section		= new_oids
+
+# To use this configuration file with the "-extfile" option of the
+# "openssl x509" utility, name here the section containing the
+# X.509v3 extensions to use:
+# extensions		= 
+# (Alternatively, use a configuration file that has only
+# X.509v3 extensions in its main [= default] section.)
+
+[ new_oids ]
+
+# We can add new OIDs in here for use by 'ca' and 'req'.
+# Add a simple OID like this:
+# testoid1=1.2.3.4
+# Or use config file substitution like this:
+# testoid2=${testoid1}.5.6
+
+####################################################################
+[ ca ]
+default_ca	= CA_default		# The default ca section
+
+####################################################################
+[ CA_default ]
+
+dir		= ./demoCA		# Where everything is kept
+certs		= $dir/certs		# Where the issued certs are kept
+crl_dir		= $dir/crl		# Where the issued crl are kept
+database	= $dir/index.txt	# database index file.
+#unique_subject	= no			# Set to 'no' to allow creation of
+					# several ctificates with same subject.
+new_certs_dir	= $dir/newcerts		# default place for new certs.
+
+certificate	= $dir/cacert.pem 	# The CA certificate
+serial		= $dir/serial 		# The current serial number
+crlnumber	= $dir/crlnumber	# the current crl number
+					# must be commented out to leave a V1 CRL
+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
+
+# Comment out the following two lines for the "traditional"
+# (and highly broken) format.
+name_opt 	= ca_default		# Subject Name options
+cert_opt 	= ca_default		# Certificate field options
+
+# Extension copying option: use with caution.
+# copy_extensions = copy
+
+# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
+# so this is commented out by default to leave a V1 CRL.
+# crlnumber must also be commented out to leave a V1 CRL.
+# crl_extensions	= crl_ext
+
+default_days	= 365			# how long to certify for
+default_crl_days= 30			# how long before next CRL
+default_md	= sha1			# which md to use.
+preserve	= no			# keep passed DN ordering
+
+# A few difference way of specifying how similar the request should look
+# For type CA, the listed attributes must be the same, and the optional
+# and supplied fields are just that :-)
+policy		= policy_match
+
+# For the CA policy
+[ policy_match ]
+countryName		= match
+stateOrProvinceName	= match
+organizationName	= match
+organizationalUnitName	= optional
+commonName		= supplied
+emailAddress		= optional
+
+# For the 'anything' policy
+# At this point in time, you must list all acceptable 'object'
+# types.
+[ policy_anything ]
+countryName		= optional
+stateOrProvinceName	= optional
+localityName		= optional
+organizationName	= optional
+organizationalUnitName	= optional
+commonName		= supplied
+emailAddress		= optional
+
+####################################################################
+[ req ]
+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
+
+# Passwords for private keys if not present they will be prompted for
+# input_password = secret
+# output_password = secret
+
+# This sets a mask for permitted string types. There are several options. 
+# default: PrintableString, T61String, BMPString.
+# pkix	 : PrintableString, BMPString.
+# utf8only: only UTF8Strings.
+# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
+# MASK:XXXX a literal mask value.
+# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
+# so use this option with caution!
+string_mask = nombstr
+
+# req_extensions = v3_req # The extensions to add to a certificate request
+
+[ req_distinguished_name ]
+countryName			= Country Name (2 letter code)
+countryName_default		= BR
+countryName_min			= 2
+countryName_max			= 2
+
+stateOrProvinceName		= State or Province Name (full name)
+stateOrProvinceName_default	= Some-State
+stateOrProvinceName_default	= Espirito Santo
+
+localityName			= Locality Name (eg, city)
+localityName_default		= Santo Antonio do Canaa
+
+0.organizationName		= Organization Name (eg, company)
+0.organizationName_default	= Sao Tonico Ltda
+
+# we can do this but it is not needed normally :-)
+#1.organizationName		= Second Organization Name (eg, company)
+#1.organizationName_default	= World Wide Web Pty Ltd
+
+organizationalUnitName		= Organizational Unit Name (eg, section)
+organizationalUnitName_default	= Department of Computer Science
+
+commonName			= Common Name (eg, YOUR name)
+commonName_default		= Server A
+commonName_max			= 64
+
+emailAddress			= Email Address
+emailAddress_max		= 64
+
+# SET-ex3			= SET extension number 3
+
+[ req_attributes ]
+challengePassword		= A challenge password
+challengePassword_min		= 4
+challengePassword_max		= 20
+
+unstructuredName		= An optional company name
+
+[ usr_cert ]
+
+# These extensions are added when 'ca' signs a request.
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType			= server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment			= "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+[ v3_req ]
+
+# Extensions to add to a certificate request
+
+basicConstraints = CA:FALSE
+keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+[ v3_ca ]
+
+
+# Extensions for a typical CA
+
+
+# PKIX recommendation.
+
+subjectKeyIdentifier=hash
+
+authorityKeyIdentifier=keyid:always,issuer:always
+
+# This is what PKIX recommends but some broken software chokes on critical
+# extensions.
+#basicConstraints = critical,CA:true
+# So we do this instead.
+basicConstraints = CA:true
+
+# Key usage: this is typical for a CA certificate. However since it will
+# prevent it being used as an test self-signed certificate it is best
+# left out by default.
+# keyUsage = cRLSign, keyCertSign
+
+# Some might want this also
+# nsCertType = sslCA, emailCA
+
+# Include email address in subject alt name: another PKIX recommendation
+# subjectAltName=email:copy
+# Copy issuer details
+# issuerAltName=issuer:copy
+
+# DER hex encoding of an extension: beware experts only!
+# obj=DER:02:03
+# Where 'obj' is a standard or added object
+# You can even override a supported extension:
+# basicConstraints= critical, DER:30:03:01:01:FF
+
+[ crl_ext ]
+
+# CRL extensions.
+# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
+
+# issuerAltName=issuer:copy
+authorityKeyIdentifier=keyid:always,issuer:always
+
+[ proxy_cert_ext ]
+# These extensions should be added when creating a proxy certificate
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType			= server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment			= "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+# This really needs to be in place for it to be a proxy certificate.
+proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/certs/serverA.sh	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+openssl req -newkey rsa:1024 -keyout serverAkey.pem -out serverAreq.pem \
+   -config ./serverA.cnf -nodes -days 365 -batch
+
+openssl x509 -req -in serverAreq.pem -sha1 -extfile ./serverA.cnf \
+   -extensions usr_cert -CA rootA.pem -CAkey rootAkey.pem -CAcreateserial \
+   -out serverAcert.pem -days 365
+
+cat serverAcert.pem rootA.pem > serverA.pem
+
+openssl x509 -subject -issuer -noout -in serverA.pem
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/certs/serverB.cnf	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,316 @@
+#
+# OpenSSL example configuration file.
+# This is mostly being used for generation of certificate requests.
+#
+
+# This definition stops the following lines choking if HOME isn't
+# defined.
+HOME			= .
+RANDFILE		= $ENV::HOME/.rnd
+
+# Extra OBJECT IDENTIFIER info:
+#oid_file		= $ENV::HOME/.oid
+oid_section		= new_oids
+
+# To use this configuration file with the "-extfile" option of the
+# "openssl x509" utility, name here the section containing the
+# X.509v3 extensions to use:
+# extensions		= 
+# (Alternatively, use a configuration file that has only
+# X.509v3 extensions in its main [= default] section.)
+
+[ new_oids ]
+
+# We can add new OIDs in here for use by 'ca' and 'req'.
+# Add a simple OID like this:
+# testoid1=1.2.3.4
+# Or use config file substitution like this:
+# testoid2=${testoid1}.5.6
+
+####################################################################
+[ ca ]
+default_ca	= CA_default		# The default ca section
+
+####################################################################
+[ CA_default ]
+
+dir		= ./demoCA		# Where everything is kept
+certs		= $dir/certs		# Where the issued certs are kept
+crl_dir		= $dir/crl		# Where the issued crl are kept
+database	= $dir/index.txt	# database index file.
+#unique_subject	= no			# Set to 'no' to allow creation of
+					# several ctificates with same subject.
+new_certs_dir	= $dir/newcerts		# default place for new certs.
+
+certificate	= $dir/cacert.pem 	# The CA certificate
+serial		= $dir/serial 		# The current serial number
+crlnumber	= $dir/crlnumber	# the current crl number
+					# must be commented out to leave a V1 CRL
+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
+
+# Comment out the following two lines for the "traditional"
+# (and highly broken) format.
+name_opt 	= ca_default		# Subject Name options
+cert_opt 	= ca_default		# Certificate field options
+
+# Extension copying option: use with caution.
+# copy_extensions = copy
+
+# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
+# so this is commented out by default to leave a V1 CRL.
+# crlnumber must also be commented out to leave a V1 CRL.
+# crl_extensions	= crl_ext
+
+default_days	= 365			# how long to certify for
+default_crl_days= 30			# how long before next CRL
+default_md	= sha1			# which md to use.
+preserve	= no			# keep passed DN ordering
+
+# A few difference way of specifying how similar the request should look
+# For type CA, the listed attributes must be the same, and the optional
+# and supplied fields are just that :-)
+policy		= policy_match
+
+# For the CA policy
+[ policy_match ]
+countryName		= match
+stateOrProvinceName	= match
+organizationName	= match
+organizationalUnitName	= optional
+commonName		= supplied
+emailAddress		= optional
+
+# For the 'anything' policy
+# At this point in time, you must list all acceptable 'object'
+# types.
+[ policy_anything ]
+countryName		= optional
+stateOrProvinceName	= optional
+localityName		= optional
+organizationName	= optional
+organizationalUnitName	= optional
+commonName		= supplied
+emailAddress		= optional
+
+####################################################################
+[ req ]
+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
+
+# Passwords for private keys if not present they will be prompted for
+# input_password = secret
+# output_password = secret
+
+# This sets a mask for permitted string types. There are several options. 
+# default: PrintableString, T61String, BMPString.
+# pkix	 : PrintableString, BMPString.
+# utf8only: only UTF8Strings.
+# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
+# MASK:XXXX a literal mask value.
+# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
+# so use this option with caution!
+string_mask = nombstr
+
+# req_extensions = v3_req # The extensions to add to a certificate request
+
+[ req_distinguished_name ]
+countryName			= Country Name (2 letter code)
+countryName_default		= BR
+countryName_min			= 2
+countryName_max			= 2
+
+stateOrProvinceName		= State or Province Name (full name)
+stateOrProvinceName_default	= Some-State
+stateOrProvinceName_default	= Espirito Santo
+
+localityName			= Locality Name (eg, city)
+localityName_default		= Santo Antonio do Canaa
+
+0.organizationName		= Organization Name (eg, company)
+0.organizationName_default	= Sao Tonico Ltda
+
+# we can do this but it is not needed normally :-)
+#1.organizationName		= Second Organization Name (eg, company)
+#1.organizationName_default	= World Wide Web Pty Ltd
+
+organizationalUnitName		= Organizational Unit Name (eg, section)
+organizationalUnitName_default	= Department of Computer Science
+
+commonName			= Common Name (eg, YOUR name)
+commonName_default		= Server B
+commonName_max			= 64
+
+emailAddress			= Email Address
+emailAddress_max		= 64
+
+# SET-ex3			= SET extension number 3
+
+[ req_attributes ]
+challengePassword		= A challenge password
+challengePassword_min		= 4
+challengePassword_max		= 20
+
+unstructuredName		= An optional company name
+
+[ usr_cert ]
+
+# These extensions are added when 'ca' signs a request.
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType			= server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment			= "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+[ v3_req ]
+
+# Extensions to add to a certificate request
+
+basicConstraints = CA:FALSE
+keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+[ v3_ca ]
+
+
+# Extensions for a typical CA
+
+
+# PKIX recommendation.
+
+subjectKeyIdentifier=hash
+
+authorityKeyIdentifier=keyid:always,issuer:always
+
+# This is what PKIX recommends but some broken software chokes on critical
+# extensions.
+#basicConstraints = critical,CA:true
+# So we do this instead.
+basicConstraints = CA:true
+
+# Key usage: this is typical for a CA certificate. However since it will
+# prevent it being used as an test self-signed certificate it is best
+# left out by default.
+# keyUsage = cRLSign, keyCertSign
+
+# Some might want this also
+# nsCertType = sslCA, emailCA
+
+# Include email address in subject alt name: another PKIX recommendation
+# subjectAltName=email:copy
+# Copy issuer details
+# issuerAltName=issuer:copy
+
+# DER hex encoding of an extension: beware experts only!
+# obj=DER:02:03
+# Where 'obj' is a standard or added object
+# You can even override a supported extension:
+# basicConstraints= critical, DER:30:03:01:01:FF
+
+[ crl_ext ]
+
+# CRL extensions.
+# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
+
+# issuerAltName=issuer:copy
+authorityKeyIdentifier=keyid:always,issuer:always
+
+[ proxy_cert_ext ]
+# These extensions should be added when creating a proxy certificate
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# Here are some examples of the usage of nsCertType. If it is omitted
+# the certificate can be used for anything *except* object signing.
+
+# This is OK for an SSL server.
+# nsCertType			= server
+
+# For an object signing certificate this would be used.
+# nsCertType = objsign
+
+# For normal client use this is typical
+# nsCertType = client, email
+
+# and for everything including object signing:
+# nsCertType = client, email, objsign
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# This will be displayed in Netscape's comment listbox.
+nsComment			= "OpenSSL Generated Certificate"
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer:always
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
+#nsBaseUrl
+#nsRevocationUrl
+#nsRenewalUrl
+#nsCaPolicyUrl
+#nsSslServerName
+
+# This really needs to be in place for it to be a proxy certificate.
+proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/certs/serverB.sh	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+openssl req -newkey rsa:1024 -keyout serverBkey.pem -out serverBreq.pem \
+   -config ./serverB.cnf -nodes -days 365 -batch
+
+openssl x509 -req -in serverBreq.pem -sha1 -extfile ./serverB.cnf \
+   -extensions usr_cert -CA rootB.pem -CAkey rootBkey.pem -CAcreateserial \
+   -out serverBcert.pem -days 365
+
+cat serverBcert.pem rootB.pem > serverB.pem
+
+openssl x509 -subject -issuer -noout -in serverB.pem
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/key/genkey.sh	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+openssl genrsa -des3 -out key.pem -passout pass:foobar 2048
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/key/loadkey.lua	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,29 @@
+--
+-- Public domain
+--
+require("ssl")
+
+local pass = "foobar"
+local cfg = {
+  protocol = "tlsv1",
+  mode = "client",
+  key = "key.pem",
+}
+
+-- Shell
+print(string.format("*** Hint: password is '%s' ***", pass))
+ctx, err = ssl.newcontext(cfg)
+assert(ctx, err)
+print("Shell: ok")
+
+-- Text password
+cfg.password = pass
+ctx, err = ssl.newcontext(cfg)
+assert(ctx, err)
+print("Text: ok")
+
+-- Callback
+cfg.password = function() return pass end
+ctx, err = ssl.newcontext(cfg)
+assert(ctx, err)
+print("Callback: ok")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/loop-gc/client.lua	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,27 @@
+--
+-- Public domain
+--
+require("socket")
+require("ssl")
+
+local params = {
+   mode = "client",
+   protocol = "sslv3",
+   key = "../certs/clientAkey.pem",
+   certificate = "../certs/clientA.pem",
+   cafile = "../certs/rootA.pem",
+   verify = {"peer", "fail_if_no_peer_cert"},
+   options = {"all", "no_sslv2"},
+}
+
+while true do
+   local peer = socket.tcp()
+   assert( peer:connect("127.0.0.1", 8888) )
+
+   -- [[ SSL wrapper
+   peer = assert( ssl.wrap(peer, params) )
+   assert( peer:dohandshake() )
+   --]]
+
+   print(peer:receive("*l"))
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/loop-gc/server.lua	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,35 @@
+--
+-- Public domain
+--
+require("socket")
+require("ssl")
+
+local params = {
+   mode = "server",
+   protocol = "sslv3",
+   key = "../certs/serverAkey.pem",
+   certificate = "../certs/serverA.pem",
+   cafile = "../certs/rootA.pem",
+   verify = {"peer", "fail_if_no_peer_cert"},
+   options = {"all", "no_sslv2"},
+}
+
+-- [[ 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()
+
+while true do
+   local peer = server:accept()
+ 
+   -- [[ SSL wrapper
+   peer = assert( ssl.wrap(peer, ctx) )
+   assert( peer:dohandshake() )
+   --]]
+
+   peer:send("loop test\n")
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/loop/client.lua	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,28 @@
+--
+-- Public domain
+--
+require("socket")
+require("ssl")
+
+local params = {
+   mode = "client",
+   protocol = "sslv3",
+   key = "../certs/clientAkey.pem",
+   certificate = "../certs/clientA.pem",
+   cafile = "../certs/rootA.pem",
+   verify = {"peer", "fail_if_no_peer_cert"},
+   options = {"all", "no_sslv2"},
+}
+
+while true do
+   local peer = socket.tcp()
+   assert( peer:connect("127.0.0.1", 8888) )
+
+   -- [[ SSL wrapper
+   peer = assert( ssl.wrap(peer, params) )
+   assert( peer:dohandshake() )
+   --]]
+
+   print(peer:receive("*l"))
+   peer:close()
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/loop/server.lua	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,36 @@
+--
+-- Public domain
+--
+require("socket")
+require("ssl")
+
+local params = {
+   mode = "server",
+   protocol = "sslv3",
+   key = "../certs/serverAkey.pem",
+   certificate = "../certs/serverA.pem",
+   cafile = "../certs/rootA.pem",
+   verify = {"peer", "fail_if_no_peer_cert"},
+   options = {"all", "no_sslv2"},
+}
+
+-- [[ 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()
+
+while true do
+   local peer = server:accept()
+ 
+   -- [[ SSL wrapper
+   peer = assert( ssl.wrap(peer, ctx) )
+   assert( peer:dohandshake() )
+   --]]
+
+   peer:send("loop test\n")
+   peer:close()
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/oneshot/client.lua	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,26 @@
+--
+-- Public domain
+--
+require("socket")
+require("ssl")
+
+local params = {
+   mode = "client",
+   protocol = "sslv3",
+   key = "../certs/clientAkey.pem",
+   certificate = "../certs/clientA.pem",
+   cafile = "../certs/rootA.pem",
+   verify = {"peer", "fail_if_no_peer_cert"},
+   options = {"all", "no_sslv2"},
+}
+
+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()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/oneshot/server.lua	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,35 @@
+--
+-- Public domain
+--
+require("socket")
+require("ssl")
+
+local params = {
+   mode = "server",
+   protocol = "sslv3",
+   key = "../certs/serverAkey.pem",
+   certificate = "../certs/serverA.pem",
+   cafile = "../certs/rootA.pem",
+   verify = {"peer", "fail_if_no_peer_cert"},
+   options = {"all", "no_sslv2"},
+}
+
+
+-- [[ 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()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/want/client.lua	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,66 @@
+--
+-- Test the conn:want() function
+--
+-- Public domain
+--
+require("socket")
+require("ssl")
+
+local params = {
+   mode = "client",
+   protocol = "sslv3",
+   key = "../certs/clientAkey.pem",
+   certificate = "../certs/clientA.pem",
+   cafile = "../certs/rootA.pem",
+   verify = {"peer", "fail_if_no_peer_cert"},
+   options = {"all", "no_sslv2"},
+}
+
+-- Wait until socket is ready (for reading or writing)
+local function wait(peer)
+   -- What event blocked us?
+   local err
+   if peer.want then  -- Is it an SSL connection?
+     err = peer:want()
+     print("Want? ", err)
+   else
+     -- No, it's a normal TCP connection...
+     err = "timeout"
+   end
+
+   if err == "read" or err == "timeout" then
+      socket.select({peer}, nil)
+   elseif err == "write" then
+      socket.select(nil, {peer})
+   else
+      peer:close()
+      os.exit(1)
+   end
+end
+
+-- Start the TCP connection
+local peer = socket.tcp()
+assert( peer:connect("127.0.0.1", 8888) )
+
+-- [[ SSL wrapper
+peer = assert( ssl.wrap(peer, params) )
+peer:settimeout(0.3)
+local succ = peer:dohandshake()
+while not succ do
+   wait(peer)
+   succ = peer:dohandshake()
+end
+print("** Handshake done")
+--]]
+
+-- If the section above is commented, the timeout is not set.
+-- We set it again for safetiness.
+peer:settimeout(0.3)
+
+-- Try to receive a line
+local str = peer:receive("*l")
+while not str do
+   wait(peer)
+   str = peer:receive("*l")
+end
+peer:close()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/want/server.lua	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,43 @@
+--
+-- Public domain
+--
+require("socket")
+require("ssl")
+
+local params = {
+   mode = "server",
+   protocol = "sslv3",
+   key = "../certs/serverAkey.pem",
+   certificate = "../certs/serverA.pem",
+   cafile = "../certs/rootA.pem",
+   verify = {"peer", "fail_if_no_peer_cert"},
+   options = {"all", "no_sslv2"},
+}
+
+-- [[ 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) )
+socket.sleep(2) -- force the timeout in the client dohandshake()
+assert( peer:dohandshake() )
+--]]
+
+for i = 1, 10 do
+   local v = tostring(i)
+   io.write(v)
+   io.flush()
+   peer:send(v)
+   socket.sleep(1) -- force the timeout in the client receive()
+end
+io.write("\n")
+peer:send("\n")
+peer:close()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/wantread/client.lua	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,55 @@
+--
+-- Public domain
+--
+require("socket")
+require("ssl")
+
+local params = {
+   mode = "client",
+   protocol = "sslv3",
+   key = "../certs/clientAkey.pem",
+   certificate = "../certs/clientA.pem",
+   cafile = "../certs/rootA.pem",
+   verify = {"peer", "fail_if_no_peer_cert"},
+   options = {"all", "no_sslv2"},
+}
+
+
+local function wait(peer, err)
+   if err == "timeout" or err == "wantread" then
+      socket.select({peer}, nil)
+   elseif err == "wantwrite" then
+      socket.select(nil, {peer})
+   else
+      peer:close()
+      os.exit(1)
+   end
+end
+
+
+local peer = socket.tcp()
+assert( peer:connect("127.0.0.1", 8888) )
+
+-- [[ SSL wrapper
+peer = assert( ssl.wrap(peer, params) )
+peer:settimeout(0.3)
+local succ, err = peer:dohandshake()
+while not succ do
+   print("handshake", err)
+   wait(peer, err)
+   succ, err = peer:dohandshake()
+end
+print("** Handshake done")
+--]]
+
+-- If the section above is commented, the timeout is not set.
+-- We set it again for safetiness.
+peer:settimeout(0.3)  
+
+local str, err, part = peer:receive("*l")
+while not str do
+   print(part, err)
+   wait(peer, err)
+   str, err, part = peer:receive("*l")
+end
+peer:close()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/wantread/server.lua	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,45 @@
+-- 
+-- Test the conn:want() function.
+--
+-- Public domain
+--
+require("socket")
+require("ssl")
+
+local params = {
+   mode = "server",
+   protocol = "sslv3",
+   key = "../certs/serverAkey.pem",
+   certificate = "../certs/serverA.pem",
+   cafile = "../certs/rootA.pem",
+   verify = {"peer", "fail_if_no_peer_cert"},
+   options = {"all", "no_sslv2"},
+}
+
+-- [[ 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) )
+socket.sleep(2) -- force the timeout in the client dohandshake()
+assert( peer:dohandshake() )
+--]]
+
+for i = 1, 10 do
+   local v = tostring(i)
+   io.write(v)
+   io.flush()
+   peer:send(v)
+   socket.sleep(1) -- force the timeout in the client receive()
+end
+io.write("\n")
+peer:send("\n")
+peer:close()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/wantwrite/client.lua	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,49 @@
+--
+-- Public domain
+--
+require("socket")
+require("ssl")
+
+local params = {
+   mode = "client",
+   protocol = "sslv3",
+   key = "../certs/clientAkey.pem",
+   certificate = "../certs/clientA.pem",
+   cafile = "../certs/rootA.pem",
+   verify = {"peer", "fail_if_no_peer_cert"},
+   options = {"all", "no_sslv2"},
+}
+
+local function wait(peer, err)
+   if err == "wantread" then
+      socket.select({peer}, nil)
+   elseif err == "timeout" or err == "wantwrite" then
+      socket.select(nil, {peer})
+   else
+      peer:close()
+      os.exit(1)
+   end
+end
+
+
+local peer = socket.tcp()
+assert( peer:connect("127.0.0.1", 8888) )
+
+-- [[ SSL wrapper
+peer = assert( ssl.wrap(peer, params) )
+assert( peer:dohandshake() )
+--]]
+
+peer:settimeout(0.3)
+
+local str = "a rose is a rose is a rose is a...\n"
+while true do
+   print("Sending...")
+   local succ, err = peer:send(str)
+   while succ do
+      succ, err = peer:send(str)
+   end
+   print("Waiting...", err)
+   wait(peer, err)
+end
+peer:close()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/wantwrite/server.lua	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,40 @@
+--
+-- Public domain
+--
+require("socket")
+require("ssl")
+
+print("Use Ctrl+S and Ctrl+Q to suspend and resume the server.")
+
+local params = {
+   mode = "server",
+   protocol = "sslv3",
+   key = "../certs/serverAkey.pem",
+   certificate = "../certs/serverA.pem",
+   cafile = "../certs/rootA.pem",
+   verify = {"peer", "fail_if_no_peer_cert"},
+   options = {"all", "no_sslv2"},
+}
+
+
+-- [[ 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() )
+--]]
+
+while true do
+   local str = peer:receive("*l")
+   print(str)
+end
+peer:close()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Makefile	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,62 @@
+CMOD=ssl.so
+LMOD=ssl.lua
+
+OBJS= \
+ timeout.o \
+ buffer.o \
+ io.o \
+ usocket.o \
+ context.o \
+ ssl.o
+
+LIBS=-lssl -lcrypto
+
+WARN=-Wall -pedantic
+
+BSD_CFLAGS=-O2 -fpic $(WARN) $(INCDIR) $(DEFS)
+BSD_LDFLAGS=-O -shared -fpic $(LIBDIR)
+
+LNX_CFLAGS=-O2 -fpic $(WARN) $(INCDIR) $(DEFS)
+LNX_LDFLAGS=-O -shared -fpic $(LIBDIR)
+
+MAC_ENV=env MACOSX_DEPLOYMENT_TARGET='$(MACVER)'
+MAC_CFLAGS=-O2 -fno-common $(WARN) $(INCDIR) $(DEFS)
+MAC_LDFLAGS=-bundle -undefined dynamic_lookup $(LIBDIR)
+
+CC=gcc
+LD=$(MYENV) gcc
+CFLAGS=$(MYCFLAGS)
+LDFLAGS=$(MYLDFLAGS)
+
+.PHONY: all clean install none linux bsd macosx
+
+all:
+
+install: $(CMOD) $(LMOD)
+	mkdir -p $(LUAPATH)/ssl
+	cp $(CMOD) $(LUACPATH)
+	cp $(LMOD) $(LUAPATH)
+	cp https.lua $(LUAPATH)/ssl
+
+linux:
+	@$(MAKE) $(CMOD) MYCFLAGS="$(LNX_CFLAGS)" MYLDFLAGS="$(LNX_LDFLAGS)"
+
+bsd:
+	@$(MAKE) $(CMOD) MYCFLAGS="$(BSD_CFLAGS)" MYLDFLAGS="$(BSD_LDFLAGS)"
+
+macosx:
+	@$(MAKE) $(CMOD) MYCFLAGS="$(MAC_CFLAGS)" MYLDFLAGS="$(MAC_LDFLAGS)" MYENV="$(MAC_ENV)"
+
+
+$(CMOD): $(OBJS)
+	$(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
+
+clean:
+	rm -f $(OBJS) $(CMOD)
+
+buffer.o: buffer.c buffer.h io.h timeout.h
+io.o: io.c io.h timeout.h
+timeout.o: timeout.c timeout.h
+usocket.o: usocket.c socket.h io.h timeout.h usocket.h
+context.o: context.c context.h
+ssl.o: ssl.c socket.h io.h timeout.h usocket.h buffer.h context.h context.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/buffer.c	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,237 @@
+/*=========================================================================*\
+* LuaSocket 2.0.2
+* Copyright (C) 2004-2007 Diego Nehab
+*
+* Input/Output interface for Lua programs
+*
+* RCS ID: $Id: buffer.c,v 1.28 2007/06/11 23:44:54 diego Exp $
+\*=========================================================================*/
+#include "lua.h"
+#include "lauxlib.h"
+
+#include "buffer.h"
+
+/*=========================================================================*\
+* Internal function prototypes
+\*=========================================================================*/
+static int recvraw(p_buffer buf, size_t wanted, luaL_Buffer *b);
+static int recvline(p_buffer buf, luaL_Buffer *b);
+static int recvall(p_buffer buf, luaL_Buffer *b);
+static int buffer_get(p_buffer buf, const char **data, size_t *count);
+static void buffer_skip(p_buffer buf, size_t count);
+static int sendraw(p_buffer buf, const char *data, size_t count, size_t *sent);
+
+/* min and max macros */
+#ifndef MIN
+#define MIN(x, y) ((x) < (y) ? x : y)
+#endif
+#ifndef MAX
+#define MAX(x, y) ((x) > (y) ? x : y)
+#endif
+
+/*=========================================================================*\
+* Exported functions
+\*=========================================================================*/
+/*-------------------------------------------------------------------------*\
+* Initializes C structure 
+\*-------------------------------------------------------------------------*/
+void buffer_init(p_buffer buf, p_io io, p_timeout tm) {
+    buf->first = buf->last = 0;
+    buf->io = io;
+    buf->tm = tm;
+}
+
+/*-------------------------------------------------------------------------*\
+* object:send() interface
+\*-------------------------------------------------------------------------*/
+int buffer_meth_send(lua_State *L, p_buffer buf) {
+    int top = lua_gettop(L);
+    int err = IO_DONE;
+    size_t size = 0, sent = 0;
+    const char *data = luaL_checklstring(L, 2, &size);
+    long start = (long) luaL_optnumber(L, 3, 1);
+    long end = (long) luaL_optnumber(L, 4, -1);
+    p_timeout tm = timeout_markstart(buf->tm);
+    if (start < 0) start = (long) (size+start+1);
+    if (end < 0) end = (long) (size+end+1);
+    if (start < 1) start = (long) 1;
+    if (end > (long) size) end = (long) size;
+    if (start <= end) err = sendraw(buf, data+start-1, end-start+1, &sent);
+    /* check if there was an error */
+    if (err != IO_DONE) {
+        lua_pushnil(L);
+        lua_pushstring(L, buf->io->error(buf->io->ctx, err)); 
+        lua_pushnumber(L, sent+start-1);
+    } else {
+        lua_pushnumber(L, sent+start-1);
+        lua_pushnil(L);
+        lua_pushnil(L);
+    }
+#ifdef BUFFER_DEBUG
+    /* push time elapsed during operation as the last return value */
+    lua_pushnumber(L, timeout_gettime() - timeout_getstart(tm));
+#endif
+    return lua_gettop(L) - top;
+}
+
+/*-------------------------------------------------------------------------*\
+* object:receive() interface
+\*-------------------------------------------------------------------------*/
+int buffer_meth_receive(lua_State *L, p_buffer buf) {
+    int err = IO_DONE, top = lua_gettop(L);
+    luaL_Buffer b;
+    size_t size;
+    const char *part = luaL_optlstring(L, 3, "", &size);
+    p_timeout tm = timeout_markstart(buf->tm);
+    /* initialize buffer with optional extra prefix 
+     * (useful for concatenating previous partial results) */
+    luaL_buffinit(L, &b);
+    luaL_addlstring(&b, part, size);
+    /* receive new patterns */
+    if (!lua_isnumber(L, 2)) {
+        const char *p= luaL_optstring(L, 2, "*l");
+        if (p[0] == '*' && p[1] == 'l') err = recvline(buf, &b);
+        else if (p[0] == '*' && p[1] == 'a') err = recvall(buf, &b); 
+        else luaL_argcheck(L, 0, 2, "invalid receive pattern");
+        /* get a fixed number of bytes (minus what was already partially 
+         * received) */
+    } else err = recvraw(buf, (size_t) lua_tonumber(L, 2)-size, &b);
+    /* check if there was an error */
+    if (err != IO_DONE) {
+        /* we can't push anyting 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)); 
+        lua_pushvalue(L, -2); 
+        lua_pushnil(L);
+        lua_replace(L, -4);
+    } else {
+        luaL_pushresult(&b);
+        lua_pushnil(L);
+        lua_pushnil(L);
+    }
+#ifdef BUFFER_DEBUG 
+    /* push time elapsed during operation as the last return value */
+    lua_pushnumber(L, timeout_gettime() - timeout_getstart(tm));
+#endif
+    return lua_gettop(L) - top;
+}
+
+/*-------------------------------------------------------------------------*\
+* Determines if there is any data in the read buffer
+\*-------------------------------------------------------------------------*/
+int buffer_isempty(p_buffer buf) {
+    return buf->first >= buf->last;
+}
+
+/*=========================================================================*\
+* Internal functions
+\*=========================================================================*/
+/*-------------------------------------------------------------------------*\
+* Sends a block of data (unbuffered)
+\*-------------------------------------------------------------------------*/
+#define STEPSIZE 8192
+static int sendraw(p_buffer buf, const char *data, size_t count, size_t *sent) {
+    p_io io = buf->io;
+    p_timeout tm = buf->tm;
+    size_t total = 0;
+    int err = IO_DONE;
+    while (total < count && err == IO_DONE) {
+        size_t done;
+        size_t step = (count-total <= STEPSIZE)? count-total: STEPSIZE;
+        err = io->send(io->ctx, data+total, step, &done, tm);
+        total += done;
+    }
+    *sent = total;
+    return err;
+}
+
+/*-------------------------------------------------------------------------*\
+* Reads a fixed number of bytes (buffered)
+\*-------------------------------------------------------------------------*/
+static int recvraw(p_buffer buf, size_t wanted, luaL_Buffer *b) {
+    int err = IO_DONE;
+    size_t total = 0;
+    while (err == IO_DONE) {
+        size_t count; const char *data;
+        err = buffer_get(buf, &data, &count);
+        count = MIN(count, wanted - total);
+        luaL_addlstring(b, data, count);
+        buffer_skip(buf, count);
+        total += count;
+        if (total >= wanted) break;
+    }
+    return err;
+}
+
+/*-------------------------------------------------------------------------*\
+* Reads everything until the connection is closed (buffered)
+\*-------------------------------------------------------------------------*/
+static int recvall(p_buffer buf, luaL_Buffer *b) {
+    int err = IO_DONE;
+    size_t total = 0;
+    while (err == IO_DONE) {
+        const char *data; size_t count;
+        err = buffer_get(buf, &data, &count);
+        total += count;
+        luaL_addlstring(b, data, count);
+        buffer_skip(buf, count);
+    }
+    if (err == IO_CLOSED) {
+        if (total > 0) return IO_DONE;
+        else return IO_CLOSED;
+    } else return err;
+}
+
+/*-------------------------------------------------------------------------*\
+* Reads a line terminated by a CR LF pair or just by a LF. The CR and LF 
+* are not returned by the function and are discarded from the buffer
+\*-------------------------------------------------------------------------*/
+static int recvline(p_buffer buf, luaL_Buffer *b) {
+    int err = IO_DONE;
+    while (err == IO_DONE) {
+        size_t count, pos; const char *data;
+        err = buffer_get(buf, &data, &count);
+        pos = 0;
+        while (pos < count && data[pos] != '\n') {
+            /* we ignore all \r's */
+            if (data[pos] != '\r') luaL_putchar(b, data[pos]);
+            pos++;
+        }
+        if (pos < count) { /* found '\n' */
+            buffer_skip(buf, pos+1); /* skip '\n' too */
+            break; /* we are done */
+        } else /* reached the end of the buffer */
+            buffer_skip(buf, pos);
+    }
+    return err;
+}
+
+/*-------------------------------------------------------------------------*\
+* Skips a given number of bytes from read buffer. No data is read from the
+* transport layer
+\*-------------------------------------------------------------------------*/
+static void buffer_skip(p_buffer buf, size_t count) {
+    buf->first += count;
+    if (buffer_isempty(buf)) 
+        buf->first = buf->last = 0;
+}
+
+/*-------------------------------------------------------------------------*\
+* Return any data available in buffer, or get more data from transport layer
+* if buffer is empty
+\*-------------------------------------------------------------------------*/
+static int buffer_get(p_buffer buf, const char **data, size_t *count) {
+    int err = IO_DONE;
+    p_io io = buf->io;
+    p_timeout tm = buf->tm;
+    if (buffer_isempty(buf)) {
+        size_t got;
+        err = io->recv(io->ctx, buf->data, BUF_SIZE, &got, tm);
+        buf->first = 0;
+        buf->last = got;
+    }
+    *count = buf->last - buf->first;
+    *data = buf->data + buf->first;
+    return err;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/buffer.h	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,45 @@
+#ifndef BUF_H
+#define BUF_H 
+/*=========================================================================*\
+* LuaSocket 2.0.2
+* Copyright (C) 2004-2007 Diego Nehab
+*
+* Input/Output interface for Lua programs
+*
+* Line patterns require buffering. Reading one character at a time involves
+* too many system calls and is very slow. This module implements the
+* LuaSocket interface for input/output on connected objects, as seen by 
+* Lua programs. 
+*
+* Input is buffered. Output is *not* buffered because there was no simple
+* way of making sure the buffered output data would ever be sent.
+*
+* The module is built on top of the I/O abstraction defined in io.h and the
+* timeout management is done with the timeout.h interface.
+*
+*
+* RCS ID: $Id: buffer.h,v 1.12 2005/10/07 04:40:59 diego Exp $
+\*=========================================================================*/
+#include <lua.h>
+
+#include "io.h"
+#include "timeout.h"
+
+/* buffer size in bytes */
+#define BUF_SIZE 8192
+
+/* buffer control structure */
+typedef struct t_buffer_ {
+    p_io io;                /* IO driver used for this buffer */
+    p_timeout tm;           /* timeout management for this buffer */
+    size_t first, last;     /* index of first and last bytes of stored data */
+    char data[BUF_SIZE];    /* storage space for buffer data */
+} t_buffer;
+typedef t_buffer *p_buffer;
+
+void buffer_init(p_buffer buf, p_io io, p_timeout tm);
+int buffer_meth_send(lua_State *L, p_buffer buf);
+int buffer_meth_receive(lua_State *L, p_buffer buf);
+int buffer_isempty(p_buffer buf);
+
+#endif /* BUF_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/context.c	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,438 @@
+/*--------------------------------------------------------------------------
+ * LuaSec 0.4
+ * Copyright (C) 2006-2009 Bruno Silvestre
+ *
+ *--------------------------------------------------------------------------*/
+
+#include <string.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "context.h"
+
+struct ssl_option_s {
+  const char *name;
+  unsigned long code;
+};
+typedef struct ssl_option_s ssl_option_t;
+
+
+static ssl_option_t ssl_options[] = {
+  /* OpenSSL 0.9.7 and 0.9.8 */
+  {"all",                              SSL_OP_ALL},
+  {"cipher_server_preference",         SSL_OP_CIPHER_SERVER_PREFERENCE},
+  {"dont_insert_empty_fragments",      SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS},
+  {"ephemeral_rsa",                    SSL_OP_EPHEMERAL_RSA},
+  {"netscape_ca_dn_bug",               SSL_OP_NETSCAPE_CA_DN_BUG},
+  {"netscape_challenge_bug",           SSL_OP_NETSCAPE_CHALLENGE_BUG},
+  {"microsoft_big_sslv3_buffer",       SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER},
+  {"microsoft_sess_id_bug",            SSL_OP_MICROSOFT_SESS_ID_BUG},
+  {"msie_sslv2_rsa_padding",           SSL_OP_MSIE_SSLV2_RSA_PADDING},
+  {"netscape_demo_cipher_change_bug",  SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG},
+  {"netscape_reuse_cipher_change_bug", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG},
+  {"no_session_resumption_on_renegotiation", 
+      SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION},
+  {"no_sslv2",                         SSL_OP_NO_SSLv2},
+  {"no_sslv3",                         SSL_OP_NO_SSLv3},
+  {"no_tlsv1",                         SSL_OP_NO_TLSv1},
+  {"pkcs1_check_1",                    SSL_OP_PKCS1_CHECK_1},
+  {"pkcs1_check_2",                    SSL_OP_PKCS1_CHECK_2},
+  {"single_dh_use",                    SSL_OP_SINGLE_DH_USE},
+  {"ssleay_080_client_dh_bug",         SSL_OP_SSLEAY_080_CLIENT_DH_BUG},
+  {"sslref2_reuse_cert_type_bug",      SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG},
+  {"tls_block_padding_bug",            SSL_OP_TLS_BLOCK_PADDING_BUG},
+  {"tls_d5_bug",                       SSL_OP_TLS_D5_BUG},
+  {"tls_rollback_bug",                 SSL_OP_TLS_ROLLBACK_BUG},
+  /* OpenSSL 0.9.8 only */
+#if OPENSSL_VERSION_NUMBER > 0x00908000L
+  {"cookie_exchange",                  SSL_OP_COOKIE_EXCHANGE},
+  {"no_query_mtu",                     SSL_OP_NO_QUERY_MTU},
+  {"single_ecdh_use",                  SSL_OP_SINGLE_ECDH_USE},
+#endif
+  /* OpenSSL 0.9.8f and above */
+#if defined(SSL_OP_NO_TICKET)
+  {"no_ticket",                        SSL_OP_NO_TICKET},
+#endif
+  {NULL, 0L}
+};
+
+/*--------------------------- Auxiliary Functions ----------------------------*/
+
+/**
+ * Return the context.
+ */
+static p_context checkctx(lua_State *L, int idx)
+{
+  return (p_context)luaL_checkudata(L, idx, "SSL:Context");
+}
+
+/**
+ * Prepare the SSL options flag.
+ */
+static int set_option_flag(const char *opt, unsigned long *flag)
+{
+  ssl_option_t *p;
+  for (p = ssl_options; p->name; p++) {
+    if (!strcmp(opt, p->name)) {
+      *flag |= p->code;
+      return 1;
+    }
+  }
+  return 0;
+}
+
+/**
+ * Find the protocol.
+ */
+static SSL_METHOD* str2method(const char *method)
+{
+  if (!strcmp(method, "sslv3"))  return SSLv3_method();
+  if (!strcmp(method, "tlsv1"))  return TLSv1_method();
+  if (!strcmp(method, "sslv23")) return SSLv23_method();
+  return NULL;
+}
+
+/**
+ * Prepare the SSL handshake verify flag.
+ */
+static int set_verify_flag(const char *str, int *flag)
+{
+  if (!strcmp(str, "none")) { 
+    *flag |= SSL_VERIFY_NONE;
+    return 1;
+  }
+  if (!strcmp(str, "peer")) {
+    *flag |= SSL_VERIFY_PEER;
+    return 1;
+  }
+  if (!strcmp(str, "client_once")) {
+    *flag |= SSL_VERIFY_CLIENT_ONCE;
+    return 1;
+  }
+  if (!strcmp(str, "fail_if_no_peer_cert")) { 
+    *flag |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+    return 1;
+  }
+  return 0;
+}
+
+/**
+ * Password callback for reading the private key.
+ */
+static int passwd_cb(char *buf, int size, int flag, void *udata)
+{
+  lua_State *L = (lua_State*)udata;
+  switch (lua_type(L, 3)) {
+  case LUA_TFUNCTION:
+    lua_pushvalue(L, 3);
+    lua_call(L, 0, 1);
+    if (lua_type(L, -1) != LUA_TSTRING)
+       return 0;
+    /* fallback */
+  case LUA_TSTRING:
+    strncpy(buf, lua_tostring(L, -1), size);
+    buf[size-1] = '\0';
+    return (int)strlen(buf);
+  }
+  return 0;
+}
+
+/*------------------------------ Lua Functions -------------------------------*/
+
+/**
+ * Create a SSL context.
+ */
+static int create(lua_State *L)
+{
+  p_context ctx;
+  SSL_METHOD *method;
+
+  method = str2method(luaL_checkstring(L, 1));
+  if (!method) {
+    lua_pushnil(L);
+    lua_pushstring(L, "invalid protocol");
+    return 2;
+  }
+  ctx = (p_context) lua_newuserdata(L, sizeof(t_context));
+  if (!ctx) {
+    lua_pushnil(L);
+    lua_pushstring(L, "error creating context");
+    return 2;
+  }  
+  ctx->context = SSL_CTX_new(method);
+  if (!ctx->context) {
+    lua_pushnil(L);
+    lua_pushstring(L, "error creating context");
+    return 2;
+  }
+  ctx->mode = MD_CTX_INVALID;
+  /* No session support */
+  SSL_CTX_set_session_cache_mode(ctx->context, SSL_SESS_CACHE_OFF);
+  luaL_getmetatable(L, "SSL:Context");
+  lua_setmetatable(L, -2);
+  return 1;
+}
+
+/**
+ * Load the trusting certificates.
+ */
+static int load_locations(lua_State *L)
+{
+  SSL_CTX *ctx = ctx_getcontext(L, 1);
+  const char *cafile = luaL_optstring(L, 2, NULL);
+  const char *capath = luaL_optstring(L, 3, NULL);
+  if (SSL_CTX_load_verify_locations(ctx, cafile, capath) != 1) {
+    lua_pushboolean(L, 0);
+    lua_pushfstring(L, "error loading CA locations (%s)",
+      ERR_reason_error_string(ERR_get_error()));
+    return 2;
+  }
+  lua_pushboolean(L, 1);
+  return 1;
+}
+
+/**
+ * Load the certificate file.
+ */
+static int load_cert(lua_State *L)
+{
+  SSL_CTX *ctx = ctx_getcontext(L, 1);
+  const char *filename = luaL_checkstring(L, 2);
+  if (SSL_CTX_use_certificate_chain_file(ctx, filename) != 1) {
+    lua_pushboolean(L, 0);
+    lua_pushfstring(L, "error loading certificate (%s)",
+      ERR_reason_error_string(ERR_get_error()));
+    return 2;
+  }
+  lua_pushboolean(L, 1);
+  return 1;
+}
+
+/**
+ * Load the key file -- only in PEM format.
+ */
+static int load_key(lua_State *L)
+{
+  int ret = 1;
+  SSL_CTX *ctx = ctx_getcontext(L, 1);
+  const char *filename = luaL_checkstring(L, 2);
+  switch (lua_type(L, 3)) {
+  case LUA_TSTRING:
+  case LUA_TFUNCTION:
+    SSL_CTX_set_default_passwd_cb(ctx, passwd_cb);
+    SSL_CTX_set_default_passwd_cb_userdata(ctx, L);
+    /* fallback */
+  case LUA_TNIL: 
+    if (SSL_CTX_use_PrivateKey_file(ctx, filename, SSL_FILETYPE_PEM) == 1)
+      lua_pushboolean(L, 1);
+    else {
+      ret = 2;
+      lua_pushboolean(L, 0);
+      lua_pushfstring(L, "error loading private key (%s)",
+        ERR_reason_error_string(ERR_get_error()));
+    }
+    SSL_CTX_set_default_passwd_cb(ctx, NULL);
+    SSL_CTX_set_default_passwd_cb_userdata(ctx, NULL);
+    break;
+  default:
+    lua_pushstring(L, "invalid callback value");
+    lua_error(L);
+  }
+  return ret;
+}
+
+/**
+ * Set the cipher list.
+ */
+static int set_cipher(lua_State *L)
+{
+  SSL_CTX *ctx = ctx_getcontext(L, 1);
+  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()));
+    return 2;
+  }
+  lua_pushboolean(L, 1);
+  return 1;
+}
+
+/**
+ * Set the depth for certificate checking.
+ */
+static int set_depth(lua_State *L)
+{
+  SSL_CTX *ctx = ctx_getcontext(L, 1);
+  SSL_CTX_set_verify_depth(ctx, luaL_checkint(L, 2));
+  lua_pushboolean(L, 1);
+  return 1;
+}
+
+/**
+ * Set the handshake verify options.
+ */
+static int set_verify(lua_State *L)
+{
+  int i;
+  int flag = 0;
+  SSL_CTX *ctx = ctx_getcontext(L, 1);
+  int max = lua_gettop(L);
+  /* any flag? */
+  if (max > 1) {
+    for (i = 2; i <= max; i++) {
+      if (!set_verify_flag(luaL_checkstring(L, i), &flag)) {
+        lua_pushboolean(L, 0);
+        lua_pushstring(L, "invalid verify option");
+        return 2;
+      }
+    }
+    SSL_CTX_set_verify(ctx, flag, NULL);
+  }
+  lua_pushboolean(L, 1);
+  return 1;
+}
+
+/**
+ * Set the protocol options.
+ */
+static int set_options(lua_State *L)
+{
+  int i;
+  unsigned long flag = 0L;
+  SSL_CTX *ctx = ctx_getcontext(L, 1);
+  int max = lua_gettop(L);
+  /* any option? */
+  if (max > 1) {
+    for (i = 2; i <= max; i++) {
+      if (!set_option_flag(luaL_checkstring(L, i), &flag)) {
+        lua_pushboolean(L, 0);
+        lua_pushstring(L, "invalid option");
+        return 2;
+      }
+    }
+    SSL_CTX_set_options(ctx, flag);
+  }
+  lua_pushboolean(L, 1);
+  return 1;
+}
+
+/**
+ * Set the context mode.
+ */
+static int set_mode(lua_State *L)
+{
+  p_context ctx = checkctx(L, 1);
+  const char *str = luaL_checkstring(L, 2);
+  if (!strcmp("server", str)) {
+    ctx->mode = MD_CTX_SERVER;
+    lua_pushboolean(L, 1);
+    return 1;
+  }
+  if(!strcmp("client", str)) {
+    ctx->mode = MD_CTX_CLIENT;
+    lua_pushboolean(L, 1);
+    return 1;
+  }
+  lua_pushboolean(L, 0);
+  lua_pushstring(L, "invalid mode");
+  return 1;
+}   
+
+/**
+ * Return a pointer to SSL_CTX structure.
+ */
+static int raw_ctx(lua_State *L)
+{
+  p_context ctx = checkctx(L, 1);
+  lua_pushlightuserdata(L, (void*)ctx->context);
+  return 1;
+}
+
+/**
+ * Package functions
+ */
+static luaL_Reg funcs[] = {
+  {"create",     create},
+  {"locations",  load_locations},
+  {"loadcert",   load_cert},
+  {"loadkey",    load_key},
+  {"setcipher",  set_cipher},
+  {"setdepth",   set_depth},
+  {"setverify",  set_verify},
+  {"setoptions", set_options},
+  {"setmode",    set_mode},
+  {"rawcontext", raw_ctx},
+  {NULL, NULL}
+};
+
+/*-------------------------------- Metamethods -------------------------------*/
+
+/**
+ * Collect SSL context -- GC metamethod.
+ */
+static int meth_destroy(lua_State *L)
+{
+  p_context ctx = checkctx(L, 1);
+  if (ctx->context) {
+    SSL_CTX_free(ctx->context);
+    ctx->context = NULL;
+  }
+  return 0;
+}
+
+/**
+ * Object information -- tostring metamethod.
+ */
+static int meth_tostring(lua_State *L)
+{
+  p_context ctx = checkctx(L, 1);
+  lua_pushfstring(L, "SSL context: %p", ctx);
+  return 1;
+}
+
+/**
+ * Context metamethods.
+ */
+static luaL_Reg meta[] = {
+  {"__gc",       meth_destroy},
+  {"__tostring", meth_tostring},
+  {NULL, NULL}
+};
+
+
+/*----------------------------- Public Functions  ---------------------------*/
+
+/**
+ * Retrieve the SSL context from the Lua stack.
+ */
+SSL_CTX* ctx_getcontext(lua_State *L, int idx)
+{
+  p_context ctx = checkctx(L, idx);
+  return ctx->context;
+}
+
+/**
+ * Retrieve the mode from the context in the Lua stack.
+ */
+char ctx_getmode(lua_State *L, int idx)
+{
+  p_context ctx = checkctx(L, idx);
+  return ctx->mode;
+}
+
+/*------------------------------ Initialization ------------------------------*/
+
+/**
+ * Registre the module.
+ */
+int luaopen_ssl_context(lua_State *L)
+{
+  luaL_newmetatable(L, "SSL:Context");
+  luaL_register(L, NULL, meta);
+  luaL_register(L, "ssl.context", funcs);
+  return 1;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/context.h	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,37 @@
+#ifndef __CONTEXT_H__
+#define __CONTEXT_H__
+
+/*--------------------------------------------------------------------------
+ * LuaSec 0.4
+ * Copyright (C) 2006-2009 Bruno Silvestre
+ *
+ *--------------------------------------------------------------------------*/
+
+#include <lua.h>
+#include <openssl/ssl.h>
+
+#if defined(_WIN32)
+#define LUASEC_API __declspec(dllexport) 
+#else
+#define LUASEC_API extern
+#endif
+
+#define MD_CTX_INVALID 0
+#define MD_CTX_SERVER 1
+#define MD_CTX_CLIENT 2
+
+typedef struct t_context_ {
+  SSL_CTX *context;
+  char mode;
+} t_context;
+typedef t_context* p_context;
+
+/* Retrieve the SSL context from the Lua stack */
+SSL_CTX *ctx_getcontext(lua_State *L, int idx);
+/* Retrieve the mode from the context in the Lua stack */
+char ctx_getmode(lua_State *L, int idx);
+
+/* Registre the module. */
+LUASEC_API int luaopen_ssl_context(lua_State *L);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/https.lua	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,138 @@
+----------------------------------------------------------------------------
+-- LuaSec 0.4
+-- Copyright (C) 2009 PUC-Rio
+--
+-- Author: Pablo Musa
+-- Author: Tomas Guisasola
+---------------------------------------------------------------------------
+
+local socket = require("socket")
+local ssl    = require("ssl")
+local ltn12  = require("ltn12")
+local http   = require("socket.http")
+local url    = require("socket.url")
+
+local table  = require("table")
+local string = require("string")
+
+local try          = socket.try
+local type         = type
+local pairs        = pairs
+local getmetatable = getmetatable
+
+module("ssl.https")
+
+_VERSION   = "0.4"
+_COPYRIGHT = "LuaSec 0.4 - Copyright (C) 2009 PUC-Rio"
+
+-- Default settings
+PORT = 443
+
+local cfg = {
+  protocol = "tlsv1",
+  options  = "all",
+  verify   = "none",
+}
+
+--------------------------------------------------------------------
+-- Auxiliar Functions
+--------------------------------------------------------------------
+
+-- Insert default HTTPS port.
+local function default_https_port(u)
+   return url.build(url.parse(u, {port = PORT}))
+end
+
+-- Convert an URL to a table according to Luasocket needs.
+local function urlstring_totable(url, body, result_table)
+   url = {
+      url = default_https_port(url),
+      method = body and "POST" or "GET",
+      sink = ltn12.sink.table(result_table)
+   }
+   if body then
+      url.source = ltn12.source.string(body)
+      url.headers = {
+         ["content-length"] = #body,
+         ["content-type"] = "application/x-www-form-urlencoded",
+      }
+   end
+   return url
+end
+
+-- Forward calls to the real connection object.
+local function reg(conn)
+   local mt = getmetatable(conn.sock).__index
+   for name, method in pairs(mt) do
+      if type(method) == "function" then
+         conn[name] = function (self, ...)
+                         return method(self.sock, ...)
+                      end
+      end
+   end
+end
+
+-- Return a function which performs the SSL/TLS connection.
+local function tcp(params)
+   params = params or {}
+   -- Default settings
+   for k, v in pairs(cfg) do 
+      params[k] = params[k] or v
+   end
+   -- Force client mode
+   params.mode = "client"
+   -- 'create' function for LuaSocket
+   return function ()
+      local conn = {}
+      conn.sock = try(socket.tcp())
+      local st = getmetatable(conn.sock).__index.settimeout
+      function conn:settimeout(...)
+         return st(self.sock, ...)
+      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))
+         try(self.sock:dohandshake())
+         reg(self, getmetatable(self.sock))
+         return 1
+      end
+      return conn
+  end
+end
+
+--------------------------------------------------------------------
+-- Main Function
+--------------------------------------------------------------------
+
+-- Make a HTTP request over secure connection.  This function receives
+--  the same parameters of LuaSocket's HTTP module (except 'proxy' and
+--  'redirect') plus LuaSec parameters.
+--
+-- @param url mandatory (string or table)
+-- @param body optional (string)
+-- @return (string if url == string or 1), code, headers, status
+--
+function request(url, body)
+  local result_table = {}
+  local stringrequest = type(url) == "string"
+  if stringrequest then
+    url = urlstring_totable(url, body, result_table)
+  else
+    url.url = default_https_port(url.url)
+  end
+  if http.PROXY or url.proxy then
+    return nil, "proxy not supported"
+  elseif url.redirect then
+    return nil, "redirect not supported"
+  elseif url.create then
+    return nil, "create function not permitted"
+  end
+  -- New 'create' function to establish a secure connection
+  url.create = tcp(url)
+  local res, code, headers, status = http.request(url)
+  if res and stringrequest then
+    return table.concat(result_table), code, headers, status
+  end
+  return res, code, headers, status
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/io.c	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,34 @@
+/*=========================================================================*\
+* LuaSocket 2.0.2
+* Copyright (C) 2004-2007 Diego Nehab
+* 
+* Input/Output abstraction
+*
+* RCS ID: $Id: io.c 2 2006-04-30 19:30:47Z brunoos $
+\*=========================================================================*/
+#include "io.h"
+
+/*=========================================================================*\
+* Exported functions
+\*=========================================================================*/
+/*-------------------------------------------------------------------------*\
+* Initializes C structure
+\*-------------------------------------------------------------------------*/
+void io_init(p_io io, p_send send, p_recv recv, p_error error, void *ctx) {
+    io->send = send;
+    io->recv = recv;
+    io->error = error;
+    io->ctx = ctx;
+}
+
+/*-------------------------------------------------------------------------*\
+* I/O error strings
+\*-------------------------------------------------------------------------*/
+const char *io_strerror(int err) {
+    switch (err) {
+        case IO_DONE: return NULL;
+        case IO_CLOSED: return "closed";
+        case IO_TIMEOUT: return "timeout";
+        default: return "unknown error"; 
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/io.h	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,70 @@
+#ifndef IO_H
+#define IO_H
+/*=========================================================================*\
+* LuaSocket 2.0.2
+* Copyright (C) 2004-2007 Diego Nehab
+*
+* Input/Output abstraction
+*
+* This module defines the interface that LuaSocket expects from the
+* transport layer for streamed input/output. The idea is that if any
+* transport implements this interface, then the buffer.c functions
+* automatically work on it.
+*
+* The module socket.h implements this interface, and thus the module tcp.h
+* is very simple.
+*
+* RCS ID: $Id: io.h 6 2006-04-30 20:33:05Z brunoos $
+\*=========================================================================*/
+#include <stdio.h>
+#include <lua.h>
+
+#include "timeout.h"
+
+/* IO error codes */
+enum {
+    IO_DONE = 0,      /* operation completed successfully */
+    IO_TIMEOUT = -1,  /* operation timed out */
+    IO_CLOSED = -2,   /* the connection has been closed */
+    IO_UNKNOWN = -3,  /* Unknown error */
+    IO_SSL = -4       /* SSL error */
+};
+
+/* interface to error message function */
+typedef const char *(*p_error) (
+    void *ctx,          /* context needed by send */
+    int err             /* error code */
+);
+
+/* interface to send function */
+typedef int (*p_send) (
+    void *ctx,          /* context needed by send */
+    const char *data,   /* pointer to buffer with data to send */
+    size_t count,       /* number of bytes to send from buffer */
+    size_t *sent,       /* number of bytes sent uppon return */
+    p_timeout tm        /* timeout control */
+);
+
+/* interface to recv function */
+typedef int (*p_recv) (
+    void *ctx,          /* context needed by recv */
+    char *data,         /* pointer to buffer where data will be writen */
+    size_t count,       /* number of bytes to receive into buffer */
+    size_t *got,        /* number of bytes received uppon return */
+    p_timeout tm        /* timeout control */
+);
+
+/* IO driver definition */
+typedef struct t_io_ {
+    void *ctx;          /* context needed by send/recv */
+    p_send send;        /* send function pointer */
+    p_recv recv;        /* receive function pointer */
+    p_error error;      /* strerror function */
+} t_io;
+typedef t_io *p_io;
+
+void io_init(p_io io, p_send send, p_recv recv, p_error error, void *ctx);
+const char *io_strerror(int err);
+
+#endif /* IO_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/socket.h	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,48 @@
+#ifndef SOCKET_H
+#define SOCKET_H
+/*=========================================================================*\
+* LuaSocket 2.0.2
+* Copyright (C) 2004-2007 Diego Nehab
+*
+* Socket compatibilization module
+*
+* BSD Sockets and WinSock are similar, but there are a few irritating
+* differences. Also, not all *nix platforms behave the same. This module
+* (and the associated usocket.h and wsocket.h) factor these differences and
+* creates a interface compatible with the io.h module.
+*
+* RCS ID: $Id: socket.h 2 2006-04-30 19:30:47Z brunoos $
+\*=========================================================================*/
+#include "io.h"
+
+/*=========================================================================*\
+* Platform specific compatibilization
+\*=========================================================================*/
+#ifdef _WIN32
+#include "wsocket.h"
+#else
+#include "usocket.h"
+#endif
+
+/*=========================================================================*\
+* The connect and accept functions accept a timeout and their
+* implementations are somewhat complicated. We chose to move
+* the timeout control into this module for these functions in
+* order to simplify the modules that use them. 
+\*=========================================================================*/
+#include "timeout.h"
+
+/*=========================================================================*\
+* Functions bellow implement a comfortable platform independent 
+* interface to sockets
+\*=========================================================================*/
+int socket_open(void);
+int socket_close(void);
+void socket_destroy(p_socket ps);
+void socket_setnonblocking(p_socket ps);
+void socket_setblocking(p_socket ps);
+int socket_waitfd(p_socket ps, int sw, p_timeout tm);
+const char *socket_strerror(int err);
+int socket_error();
+
+#endif /* SOCKET_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ssl.c	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,411 @@
+/*--------------------------------------------------------------------------
+ * LuaSec 0.4
+ * Copyright (C) 2006-2009 Bruno Silvestre
+ *
+ *--------------------------------------------------------------------------*/
+
+#include <string.h>
+
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "io.h"
+#include "buffer.h"
+#include "timeout.h"
+#include "socket.h"
+#include "ssl.h"
+
+/**
+ * Map error code into string.
+ */
+static const char *ssl_ioerror(void *ctx, int err)
+{
+  if (err == IO_SSL) {
+    p_ssl ssl = (p_ssl) ctx;
+    switch(ssl->error) {
+    case SSL_ERROR_NONE: return "No error";
+    case SSL_ERROR_ZERO_RETURN: return "closed";
+    case SSL_ERROR_WANT_READ: return "wantread";
+    case SSL_ERROR_WANT_WRITE: return "wantwrite";
+    case SSL_ERROR_WANT_CONNECT: return "'connect' not completed";
+    case SSL_ERROR_WANT_ACCEPT: return "'accept' not completed";
+    case SSL_ERROR_WANT_X509_LOOKUP: return "Waiting for callback";
+    case SSL_ERROR_SYSCALL: return "System error";
+    case SSL_ERROR_SSL: return ERR_reason_error_string(ERR_get_error());
+    default: return "Unknown SSL error";
+    }
+  }
+  return socket_strerror(err);
+}
+
+/**
+ * Close the connection before the GC collect the object.
+ */
+static int meth_destroy(lua_State *L)
+{
+  p_ssl ssl = (p_ssl) lua_touserdata(L, 1);
+  if (ssl->ssl) {
+    socket_setblocking(&ssl->sock);
+    SSL_shutdown(ssl->ssl);
+    socket_destroy(&ssl->sock);
+    SSL_free(ssl->ssl);
+    ssl->ssl = NULL;
+  }
+  return 0;
+}
+
+/**
+ * Perform the TLS/SSL handshake
+ */
+static int handshake(p_ssl ssl)
+{
+  int err;
+  p_timeout tm = timeout_markstart(&ssl->tm);
+  if (ssl->state == ST_SSL_CLOSED)
+    return IO_CLOSED;
+  for ( ; ; ) {
+    ERR_clear_error();
+    err = SSL_do_handshake(ssl->ssl);
+    ssl->error = SSL_get_error(ssl->ssl, err);
+    switch(ssl->error) {
+    case SSL_ERROR_NONE:
+      ssl->state = ST_SSL_CONNECTED;
+      return IO_DONE;
+    case SSL_ERROR_WANT_READ:
+      err = socket_waitfd(&ssl->sock, WAITFD_R, tm);
+      if (err == IO_TIMEOUT) return IO_SSL;
+      if (err != IO_DONE)    return err;
+      break;
+    case SSL_ERROR_WANT_WRITE:
+      err = socket_waitfd(&ssl->sock, WAITFD_W, tm);
+      if (err == IO_TIMEOUT) return IO_SSL;
+      if (err != IO_DONE)    return err;
+      break;
+    case SSL_ERROR_SYSCALL:
+      if (ERR_peek_error())  {
+        ssl->error = SSL_ERROR_SSL;
+        return IO_SSL;
+      }
+      if (err == 0)
+        return IO_CLOSED;
+      return socket_error();
+    default:
+      return IO_SSL;
+    }
+  }
+  return IO_UNKNOWN;
+}
+
+/**
+ * Send data
+ */
+static int ssl_send(void *ctx, const char *data, size_t count, size_t *sent,
+   p_timeout tm)
+{
+  int err;
+  p_ssl ssl = (p_ssl) ctx;
+  if (ssl->state == ST_SSL_CLOSED)
+    return IO_CLOSED;
+  *sent = 0;
+  for ( ; ; ) {
+    ERR_clear_error();
+    err = SSL_write(ssl->ssl, data, (int) count);
+    ssl->error = SSL_get_error(ssl->ssl, err);
+    switch(ssl->error) {
+    case SSL_ERROR_NONE:
+      *sent = err;
+      return IO_DONE;
+    case SSL_ERROR_WANT_READ: 
+      err = socket_waitfd(&ssl->sock, WAITFD_R, tm);
+      if (err == IO_TIMEOUT) return IO_SSL;
+      if (err != IO_DONE)    return err;
+      break;
+    case SSL_ERROR_WANT_WRITE:
+      err = socket_waitfd(&ssl->sock, WAITFD_W, tm);
+      if (err == IO_TIMEOUT) return IO_SSL;
+      if (err != IO_DONE)    return err;
+      break;
+    case SSL_ERROR_SYSCALL:
+      if (ERR_peek_error())  {
+        ssl->error = SSL_ERROR_SSL;
+        return IO_SSL;
+      }
+      if (err == 0)
+        return IO_CLOSED;
+      return socket_error();
+    default:
+      return IO_SSL;
+    }
+  }
+  return IO_UNKNOWN;
+}
+
+/**
+ * Receive data
+ */
+static int ssl_recv(void *ctx, char *data, size_t count, size_t *got,
+  p_timeout tm)
+{
+  int err;
+  p_ssl ssl = (p_ssl) ctx;
+  if (ssl->state == ST_SSL_CLOSED)
+    return IO_CLOSED;
+  *got = 0;
+  for ( ; ; ) {
+    ERR_clear_error();
+    err = SSL_read(ssl->ssl, data, (int) count);
+    ssl->error = SSL_get_error(ssl->ssl, err);
+    switch(ssl->error) {
+    case SSL_ERROR_NONE:
+      *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);
+      if (err == IO_TIMEOUT) return IO_SSL;
+      if (err != IO_DONE)    return err;
+      break;
+    case SSL_ERROR_WANT_WRITE:
+      err = socket_waitfd(&ssl->sock, WAITFD_W, tm);
+      if (err == IO_TIMEOUT) return IO_SSL;
+      if (err != IO_DONE)    return err;
+      break;
+    case SSL_ERROR_SYSCALL:
+      if (ERR_peek_error())  {
+        ssl->error = SSL_ERROR_SSL;
+        return IO_SSL;
+      }
+      if (err == 0)
+        return IO_CLOSED;
+      return socket_error();
+    default:
+      return IO_SSL;
+    }
+  }
+  return IO_UNKNOWN;
+}
+
+/**
+ * Create a new TLS/SSL object and mark it as new.
+ */
+static int meth_create(lua_State *L)
+{
+  p_ssl ssl;
+  int mode = ctx_getmode(L, 1);
+  SSL_CTX *ctx = ctx_getcontext(L, 1);
+
+  if (mode == MD_CTX_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;
+  }
+  ssl->ssl = SSL_new(ctx);
+  if (!ssl->ssl) {
+    lua_pushnil(L);
+    lua_pushstring(L, "error creating SSL object");
+    return 2;;
+  }
+  ssl->state = ST_SSL_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 (mode == MD_CTX_SERVER)
+    SSL_set_accept_state(ssl->ssl);
+  else
+    SSL_set_connect_state(ssl->ssl);
+
+  io_init(&ssl->io, (p_send) ssl_send, (p_recv) ssl_recv, 
+    (p_error) ssl_ioerror, ssl);
+  timeout_init(&ssl->tm, -1, -1);
+  buffer_init(&ssl->buf, &ssl->io, &ssl->tm);
+
+  luaL_getmetatable(L, "SSL:Connection");
+  lua_setmetatable(L, -2);
+  return 1;
+}
+
+/**
+ * Buffer send function
+ */
+static int meth_send(lua_State *L) {
+  p_ssl ssl = (p_ssl) luaL_checkudata(L, 1, "SSL:Connection");
+  return buffer_meth_send(L, &ssl->buf);
+}
+
+/**
+ * Buffer receive function
+ */
+static int meth_receive(lua_State *L) {
+  p_ssl ssl = (p_ssl) luaL_checkudata(L, 1, "SSL:Connection");
+  return buffer_meth_receive(L, &ssl->buf);
+}
+
+/**
+ * Select support methods
+ */
+static int meth_getfd(lua_State *L)
+{
+  p_ssl ssl = (p_ssl) luaL_checkudata(L, 1, "SSL:Connection");
+  lua_pushnumber(L, ssl->sock);
+  return 1;
+}
+
+/**
+ * Set the TLS/SSL file descriptor.
+ * This is done *before* the handshake.
+ */
+static int meth_setfd(lua_State *L)
+{
+  p_ssl ssl = (p_ssl) luaL_checkudata(L, 1, "SSL:Connection");
+  if (ssl->state != ST_SSL_NEW)
+    luaL_argerror(L, 1, "invalid SSL object state");
+  ssl->sock = luaL_checkint(L, 2);
+  socket_setnonblocking(&ssl->sock);
+  SSL_set_fd(ssl->ssl, (int)ssl->sock);
+  return 0;
+}
+
+/**
+ * Lua handshake function.
+ */
+static int meth_handshake(lua_State *L)
+{
+  p_ssl ssl = (p_ssl) luaL_checkudata(L, 1, "SSL:Connection");
+  int err = handshake(ssl);
+  if (err == IO_DONE) {
+    lua_pushboolean(L, 1);
+    return 1;
+  }
+  lua_pushboolean(L, 0);
+  lua_pushstring(L, ssl_ioerror((void*)ssl, err));
+  return 2;
+}
+
+/**
+ * Close the connection.
+ */
+static int meth_close(lua_State *L)
+{
+  p_ssl ssl = (p_ssl) luaL_checkudata(L, 1, "SSL:Connection");
+  meth_destroy(L);
+  ssl->state = ST_SSL_CLOSED;
+  return 0;
+}
+
+/**
+ * Set timeout.
+ */
+static int meth_settimeout(lua_State *L)
+{
+  p_ssl ssl = (p_ssl) luaL_checkudata(L, 1, "SSL:Connection");
+  return timeout_meth_settimeout(L, &ssl->tm);
+}
+
+/**
+ * Check if there is data in the buffer.
+ */
+static int meth_dirty(lua_State *L)
+{
+  int res = 0;
+  p_ssl ssl = (p_ssl) luaL_checkudata(L, 1, "SSL:Connection");
+  if (ssl->state != ST_SSL_CLOSED)
+    res = !buffer_isempty(&ssl->buf) || SSL_pending(ssl->ssl);
+  lua_pushboolean(L, res);
+  return 1;
+}
+
+/**
+ * Return the state information about the SSL object.
+ */
+static int meth_want(lua_State *L)
+{
+  p_ssl ssl = (p_ssl) luaL_checkudata(L, 1, "SSL:Connection");
+  int code = (ssl->state == ST_SSL_CLOSED) ? SSL_NOTHING : SSL_want(ssl->ssl);
+  switch(code) {
+  case SSL_NOTHING: lua_pushstring(L, "nothing"); break;
+  case SSL_READING: lua_pushstring(L, "read"); break;
+  case SSL_WRITING: lua_pushstring(L, "write"); break;
+  case SSL_X509_LOOKUP: lua_pushstring(L, "x509lookup"); break;
+  }
+  return 1;
+}
+  
+/**
+ * Return a pointer to SSL structure.
+ */
+static int meth_rawconn(lua_State *L)
+{
+  p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
+  lua_pushlightuserdata(L, (void*)ssl->ssl);
+  return 1;
+}
+
+/*---------------------------------------------------------------------------*/
+
+
+/**
+ * SSL metamethods 
+ */
+static luaL_Reg meta[] = {
+  {"close",       meth_close},
+  {"getfd",       meth_getfd},
+  {"dirty",       meth_dirty},
+  {"dohandshake", meth_handshake},
+  {"receive",     meth_receive},
+  {"send",        meth_send},
+  {"settimeout",  meth_settimeout},
+  {"want",        meth_want},
+  {NULL,          NULL}
+};
+
+/**
+ * SSL functions 
+ */
+static luaL_Reg funcs[] = {
+  {"create",        meth_create},
+  {"setfd",         meth_setfd},
+  {"rawconnection", meth_rawconn},
+  {NULL,            NULL}
+};
+
+/**
+ * Initialize modules
+ */
+LUASEC_API int luaopen_ssl_core(lua_State *L)
+{
+  /* Initialize SSL */
+  if (!SSL_library_init()) {
+    lua_pushstring(L, "unable to initialize SSL library");
+    lua_error(L);
+  }
+  SSL_load_error_strings();
+
+  /* Initialize internal library */
+  socket_open();
+   
+  /* Registre the functions and tables */
+  luaL_newmetatable(L, "SSL:Connection");
+  lua_newtable(L);
+  luaL_register(L, NULL, meta);
+  lua_setfield(L, -2, "__index");
+  lua_pushcfunction(L, meth_destroy);
+  lua_setfield(L, -2, "__gc");
+
+  luaL_register(L, "ssl.core", funcs);
+  lua_pushnumber(L, SOCKET_INVALID);
+  lua_setfield(L, -2, "invalidfd");
+
+  return 1;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ssl.h	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,35 @@
+#ifndef __SSL_H__
+#define __SSL_H__
+
+/*--------------------------------------------------------------------------
+ * LuaSec 0.4
+ * Copyright (C) 2006-2009 Bruno Silvestre
+ *
+ *--------------------------------------------------------------------------*/
+
+#include <openssl/ssl.h>
+#include <lua.h>
+
+#include "io.h"
+#include "buffer.h"
+#include "timeout.h"
+#include "context.h"
+
+#define ST_SSL_NEW       1
+#define ST_SSL_CONNECTED 2
+#define ST_SSL_CLOSED    3
+
+typedef struct t_ssl_ {
+  t_socket sock;
+  t_io io;
+  t_buffer buf;
+  t_timeout tm;
+  SSL *ssl;
+  char state;
+  int error;
+} t_ssl;
+typedef t_ssl* p_ssl;
+
+LUASEC_API int luaopen_ssl_core(lua_State *L);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ssl.lua	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,93 @@
+------------------------------------------------------------------------------
+-- LuaSec 0.4
+-- Copyright (C) 2006-2009 Bruno Silvestre
+--
+------------------------------------------------------------------------------
+
+module("ssl", package.seeall)
+
+require("ssl.core")
+require("ssl.context")
+
+
+_VERSION   = "0.4"
+_COPYRIGHT = "LuaSec 0.4 - Copyright (C) 2006-2009 Bruno Silvestre\n" .. 
+             "LuaSocket 2.0.2 - Copyright (C) 2004-2007 Diego Nehab"
+
+-- Export functions
+rawconnection = core.rawconnection
+rawcontext    = context.rawcontext
+
+--
+--
+--
+local function optexec(func, param, ctx)
+  if param then
+    if type(param) == "table" then
+      return func(ctx, unpack(param))
+    else
+      return func(ctx, param)
+    end
+  end
+  return true
+end
+
+--
+--
+--
+function newcontext(cfg)
+   local succ, msg, ctx
+   -- Create the context
+   ctx, msg = context.create(cfg.protocol)
+   if not ctx then return nil, msg end
+   -- Mode
+   succ, msg = context.setmode(ctx, cfg.mode)
+   if not succ then return nil, msg end
+   -- Load the key
+   if cfg.key then
+      succ, msg = context.loadkey(ctx, cfg.key, cfg.password)
+      if not succ then return nil, msg end
+   end
+   -- Load the certificate
+   if cfg.certificate then
+      succ, msg = context.loadcert(ctx, cfg.certificate)
+      if not succ then return nil, msg end
+   end
+   -- Load the CA certificates
+   if cfg.cafile or cfg.capath then
+      succ, msg = context.locations(ctx, cfg.cafile, cfg.capath)
+      if not succ then return nil, msg end
+   end
+   -- Set the verification options
+   succ, msg = optexec(context.setverify, cfg.verify, ctx)
+   if not succ then return nil, msg end
+   -- Set SSL options
+   succ, msg = optexec(context.setoptions, cfg.options, ctx)
+   if not succ then return nil, msg end
+   -- Set the depth for certificate verification
+   if cfg.depth then
+      succ, msg = context.setdepth(ctx, cfg.depth)
+      if not succ then return nil, msg end
+   end
+   return ctx
+end
+
+--
+--
+--
+function wrap(sock, cfg)
+   local ctx, msg
+   if type(cfg) == "table" then
+      ctx, msg = newcontext(cfg)
+      if not ctx then return nil, msg end
+   else
+      ctx = cfg
+   end
+   local s, msg = core.create(ctx)
+   if s then
+      core.setfd(s, sock:getfd())
+      sock:setfd(core.invalidfd)
+      return s
+   end
+   return nil, msg 
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/timeout.c	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,155 @@
+/*=========================================================================*\
+* LuaSocket 2.0.2
+* Copyright (C) 2004-2007 Diego Nehab
+*
+* Timeout management functions
+*
+* RCS ID: $Id: timeout.c,v 1.30 2005/10/07 04:40:59 diego Exp $
+\*=========================================================================*/
+#include <stdio.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <time.h>
+#include <sys/time.h>
+#endif
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "timeout.h"
+
+/* min and max macros */
+#ifndef MIN
+#define MIN(x, y) ((x) < (y) ? x : y)
+#endif
+#ifndef MAX
+#define MAX(x, y) ((x) > (y) ? x : y)
+#endif
+
+/*=========================================================================*\
+* Exported functions.
+\*=========================================================================*/
+/*-------------------------------------------------------------------------*\
+* Initialize structure
+\*-------------------------------------------------------------------------*/
+void timeout_init(p_timeout tm, double block, double total) {
+    tm->block = block;
+    tm->total = total;
+}
+
+/*-------------------------------------------------------------------------*\
+* Determines how much time we have left for the next system call,
+* if the previous call was successful 
+* Input
+*   tm: timeout control structure
+* Returns
+*   the number of ms left or -1 if there is no time limit
+\*-------------------------------------------------------------------------*/
+double timeout_get(p_timeout tm) {
+    if (tm->block < 0.0 && tm->total < 0.0) {
+        return -1;
+    } else if (tm->block < 0.0) {
+        double t = tm->total - timeout_gettime() + tm->start;
+        return MAX(t, 0.0);
+    } else if (tm->total < 0.0) {
+        return tm->block;
+    } else {
+        double t = tm->total - timeout_gettime() + tm->start;
+        return MIN(tm->block, MAX(t, 0.0));
+    }
+}
+
+/*-------------------------------------------------------------------------*\
+* Returns time since start of operation
+* Input
+*   tm: timeout control structure
+* Returns
+*   start field of structure
+\*-------------------------------------------------------------------------*/
+double timeout_getstart(p_timeout tm) {
+    return tm->start;
+}
+
+/*-------------------------------------------------------------------------*\
+* Determines how much time we have left for the next system call,
+* if the previous call was a failure
+* Input
+*   tm: timeout control structure
+* Returns
+*   the number of ms left or -1 if there is no time limit
+\*-------------------------------------------------------------------------*/
+double timeout_getretry(p_timeout tm) {
+    if (tm->block < 0.0 && tm->total < 0.0) {
+        return -1;
+    } else if (tm->block < 0.0) {
+        double t = tm->total - timeout_gettime() + tm->start;
+        return MAX(t, 0.0);
+    } else if (tm->total < 0.0) {
+        double t = tm->block - timeout_gettime() + tm->start;
+        return MAX(t, 0.0);
+    } else {
+        double t = tm->total - timeout_gettime() + tm->start;
+        return MIN(tm->block, MAX(t, 0.0));
+    }
+}
+
+/*-------------------------------------------------------------------------*\
+* Marks the operation start time in structure 
+* Input
+*   tm: timeout control structure
+\*-------------------------------------------------------------------------*/
+p_timeout timeout_markstart(p_timeout tm) {
+    tm->start = timeout_gettime();
+    return tm;
+}
+
+/*-------------------------------------------------------------------------*\
+* Gets time in s, relative to January 1, 1970 (UTC) 
+* Returns
+*   time in s.
+\*-------------------------------------------------------------------------*/
+#ifdef _WIN32
+double timeout_gettime(void) {
+    FILETIME ft;
+    double t;
+    GetSystemTimeAsFileTime(&ft);
+    /* Windows file time (time since January 1, 1601 (UTC)) */
+    t  = ft.dwLowDateTime/1.0e7 + ft.dwHighDateTime*(4294967296.0/1.0e7);
+    /* convert to Unix Epoch time (time since January 1, 1970 (UTC)) */
+    return (t - 11644473600.0);
+}
+#else
+double timeout_gettime(void) {
+    struct timeval v;
+    gettimeofday(&v, (struct timezone *) NULL);
+    /* Unix Epoch time (time since January 1, 1970 (UTC)) */
+    return v.tv_sec + v.tv_usec/1.0e6;
+}
+#endif
+
+/*-------------------------------------------------------------------------*\
+* Sets timeout values for IO operations
+* Lua Input: base, time [, mode]
+*   time: time out value in seconds
+*   mode: "b" for block timeout, "t" for total timeout. (default: b)
+\*-------------------------------------------------------------------------*/
+int timeout_meth_settimeout(lua_State *L, p_timeout tm) {
+    double t = luaL_optnumber(L, 2, -1);
+    const char *mode = luaL_optstring(L, 3, "b");
+    switch (*mode) {
+        case 'b':
+            tm->block = t; 
+            break;
+        case 'r': case 't':
+            tm->total = t;
+            break;
+        default:
+            luaL_argcheck(L, 0, 3, "invalid timeout mode");
+            break;
+    }
+    lua_pushnumber(L, 1);
+    return 1;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/timeout.h	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,32 @@
+#ifndef TIMEOUT_H
+#define TIMEOUT_H
+/*=========================================================================*\
+* LuaSocket 2.0.2
+* Copyright (C) 2004-2007 Diego Nehab
+*
+* Timeout management functions
+*
+* RCS ID: $Id: timeout.h 2 2006-04-30 19:30:47Z brunoos $
+\*=========================================================================*/
+#include <lua.h>
+
+/* timeout control structure */
+typedef struct t_timeout_ {
+    double block;          /* maximum time for blocking calls */
+    double total;          /* total number of miliseconds for operation */
+    double start;          /* time of start of operation */
+} t_timeout;
+typedef t_timeout *p_timeout;
+
+int timeout_open(lua_State *L);
+void timeout_init(p_timeout tm, double block, double total);
+double timeout_get(p_timeout tm);
+double timeout_getretry(p_timeout tm);
+p_timeout timeout_markstart(p_timeout tm);
+double timeout_getstart(p_timeout tm);
+double timeout_gettime(void);
+int timeout_meth_settimeout(lua_State *L, p_timeout tm);
+
+#define timeout_iszero(tm)   ((tm)->block == 0.0)
+
+#endif /* TIMEOUT_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/usocket.c	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,145 @@
+/*=========================================================================*\
+* LuaSocket 2.0.2
+* Copyright (C) 2004-2007 Diego Nehab
+*
+* Socket compatibilization module for Unix
+*
+* The code is now interrupt-safe.
+* The penalty of calling select to avoid busy-wait is only paid when
+* the I/O call fail in the first place. 
+*
+* RCS ID: $Id: usocket.c,v 1.38 2007/10/13 23:55:20 diego Exp $
+\*=========================================================================*/
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <string.h> 
+#include <signal.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "socket.h"
+#include "usocket.h"
+
+/*-------------------------------------------------------------------------*\
+* Wait for readable/writable/connected socket with timeout
+\*-------------------------------------------------------------------------*/
+#ifdef SOCKET_POLL
+int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
+    int ret;
+    struct pollfd pfd;
+    pfd.fd = *ps;
+    pfd.events = sw;
+    pfd.revents = 0;
+    if (timeout_iszero(tm)) return IO_TIMEOUT;  /* optimize timeout == 0 case */
+    do {
+        int t = (int)(timeout_getretry(tm)*1e3);
+        ret = poll(&pfd, 1, t >= 0? t: -1);
+    } while (ret == -1 && errno == EINTR);
+    if (ret == -1) return errno;
+    if (ret == 0) return IO_TIMEOUT;
+    if (sw == WAITFD_C && (pfd.revents & (POLLIN|POLLERR))) return IO_CLOSED;
+    return IO_DONE;
+}
+#else
+int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
+    int ret;
+    fd_set rfds, wfds, *rp, *wp;
+    struct timeval tv, *tp;
+    double t;
+    if (timeout_iszero(tm)) return IO_TIMEOUT;  /* optimize timeout == 0 case */
+    do {
+        /* must set bits within loop, because select may have modifed 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; }
+        t = timeout_getretry(tm);
+        tp = NULL;
+        if (t >= 0.0) {
+            tv.tv_sec = (int)t;
+            tv.tv_usec = (int)((t-tv.tv_sec)*1.0e6);
+            tp = &tv;
+        }
+        ret = select(*ps+1, rp, wp, NULL, tp);
+    } while (ret == -1 && errno == EINTR);
+    if (ret == -1) return errno;
+    if (ret == 0) return IO_TIMEOUT;
+    if (sw == WAITFD_C && FD_ISSET(*ps, &rfds)) return IO_CLOSED;
+    return IO_DONE;
+}
+#endif
+
+
+/*-------------------------------------------------------------------------*\
+* Initializes module 
+\*-------------------------------------------------------------------------*/
+int socket_open(void) {
+    /* instals a handler to ignore sigpipe or it will crash us */
+    signal(SIGPIPE, SIG_IGN);
+    return 1;
+}
+
+/*-------------------------------------------------------------------------*\
+* Close module 
+\*-------------------------------------------------------------------------*/
+int socket_close(void) {
+    return 1;
+}
+
+/*-------------------------------------------------------------------------*\
+* Close and inutilize socket
+\*-------------------------------------------------------------------------*/
+void socket_destroy(p_socket ps) {
+    if (*ps != SOCKET_INVALID) {
+        socket_setblocking(ps);
+        close(*ps);
+        *ps = SOCKET_INVALID;
+    }
+}
+
+/*-------------------------------------------------------------------------*\
+* Put socket into blocking mode
+\*-------------------------------------------------------------------------*/
+void socket_setblocking(p_socket ps) {
+    int flags = fcntl(*ps, F_GETFL, 0);
+    flags &= (~(O_NONBLOCK));
+    fcntl(*ps, F_SETFL, flags);
+}
+
+/*-------------------------------------------------------------------------*\
+* Put socket into non-blocking mode
+\*-------------------------------------------------------------------------*/
+void socket_setnonblocking(p_socket ps) {
+    int flags = fcntl(*ps, F_GETFL, 0);
+    flags |= O_NONBLOCK;
+    fcntl(*ps, F_SETFL, flags);
+}
+
+/*-------------------------------------------------------------------------*\
+* Error translation functions
+* Make sure important error messages are standard
+\*-------------------------------------------------------------------------*/
+const char *socket_strerror(int err) {
+    if (err <= 0) return io_strerror(err);
+    switch (err) {
+        case EADDRINUSE: return "address already in use";
+        case EISCONN: return "already connected";
+        case EACCES: return "permission denied";
+        case ECONNREFUSED: return "connection refused";
+        case ECONNABORTED: return "closed";
+        case ECONNRESET: return "closed";
+	case EPIPE: return "closed";
+        case ETIMEDOUT: return "timeout";
+        default: return strerror(errno);
+    }
+}
+
+/*-------------------------------------------------------------------------*\
+* Underline error code.
+\*-------------------------------------------------------------------------*/
+int socket_error()
+{
+  return errno;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/usocket.h	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,28 @@
+#ifndef USOCKET_H
+#define USOCKET_H
+/*=========================================================================*\
+* LuaSocket 2.0.2
+* Copyright (C) 2004-2007 Diego Nehab
+*
+* Socket compatibilization module for Unix
+*
+* RCS ID: $Id: usocket.h 6 2006-04-30 20:33:05Z brunoos $
+\*=========================================================================*/
+
+#ifdef SOCKET_POLL
+#include <sys/poll.h>
+#define WAITFD_R        POLLIN
+#define WAITFD_W        POLLOUT
+#define WAITFD_C        (POLLIN|POLLOUT)
+#else
+#define WAITFD_R        1
+#define WAITFD_W        2
+#define WAITFD_C        (WAITFD_R|WAITFD_W)
+#endif
+
+typedef int t_socket;
+typedef t_socket *p_socket;
+
+#define SOCKET_INVALID (-1)
+
+#endif /* USOCKET_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wsocket.c	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,169 @@
+/*=========================================================================*\
+* LuaSocket 2.0.2
+* Copyright (C) 2004-2007 Diego Nehab
+*
+* Socket compatibilization module for Win32
+*
+* The penalty of calling select to avoid busy-wait is only paid when
+* the I/O call fail in the first place. 
+*
+* RCS ID: $Id: wsocket.c,v 1.36 2007/06/11 23:44:54 diego Exp $
+\*=========================================================================*/
+#include <string.h>
+
+#include "socket.h"
+
+/*-------------------------------------------------------------------------*\
+* Initializes module 
+\*-------------------------------------------------------------------------*/
+int socket_open(void) {
+    WSADATA wsaData;
+    WORD wVersionRequested = MAKEWORD(2, 0); 
+    int err = WSAStartup(wVersionRequested, &wsaData );
+    if (err != 0) return 0;
+    if ((LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0) &&
+        (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)) {
+        WSACleanup();
+        return 0; 
+    }
+    return 1;
+}
+
+/*-------------------------------------------------------------------------*\
+* Close module 
+\*-------------------------------------------------------------------------*/
+int socket_close(void) {
+    WSACleanup();
+    return 1;
+}
+
+/*-------------------------------------------------------------------------*\
+* Wait for readable/writable/connected socket with timeout
+\*-------------------------------------------------------------------------*/
+int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
+    int ret;
+    fd_set rfds, wfds, efds, *rp = NULL, *wp = NULL, *ep = NULL;
+    struct timeval tv, *tp = NULL;
+    double t;
+    if (timeout_iszero(tm)) return IO_TIMEOUT;  /* optimize timeout == 0 case */
+    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; }
+    if (sw & WAITFD_C) { FD_ZERO(&efds); FD_SET(*ps, &efds); ep = &efds; }
+    if ((t = timeout_get(tm)) >= 0.0) {
+        tv.tv_sec = (int) t;
+        tv.tv_usec = (int) ((t-tv.tv_sec)*1.0e6);
+        tp = &tv;
+    }
+    ret = select(0, rp, wp, ep, tp);
+    if (ret == -1) return WSAGetLastError();
+    if (ret == 0) return IO_TIMEOUT;
+    if (sw == WAITFD_C && FD_ISSET(*ps, &efds)) return IO_CLOSED;
+    return IO_DONE;
+}
+
+/*-------------------------------------------------------------------------*\
+* Close and inutilize socket
+\*-------------------------------------------------------------------------*/
+void socket_destroy(p_socket ps) {
+    if (*ps != SOCKET_INVALID) {
+        socket_setblocking(ps); /* close can take a long time on WIN32 */
+        closesocket(*ps);
+        *ps = SOCKET_INVALID;
+    }
+}
+
+/*-------------------------------------------------------------------------*\
+* Put socket into blocking mode
+\*-------------------------------------------------------------------------*/
+void socket_setblocking(p_socket ps) {
+    u_long argp = 0;
+    ioctlsocket(*ps, FIONBIO, &argp);
+}
+
+/*-------------------------------------------------------------------------*\
+* Put socket into non-blocking mode
+\*-------------------------------------------------------------------------*/
+void socket_setnonblocking(p_socket ps) {
+    u_long argp = 1;
+    ioctlsocket(*ps, FIONBIO, &argp);
+}
+
+/*-------------------------------------------------------------------------*\
+* Error translation functions
+\*-------------------------------------------------------------------------*/
+
+/* WinSock doesn't have a strerror... */
+static const char *wstrerror(int err) {
+    switch (err) {
+        case WSAEINTR: return "Interrupted function call";
+        case WSAEACCES: return "Permission denied";
+        case WSAEFAULT: return "Bad address";
+        case WSAEINVAL: return "Invalid argument";
+        case WSAEMFILE: return "Too many open files";
+        case WSAEWOULDBLOCK: return "Resource temporarily unavailable";
+        case WSAEINPROGRESS: return "Operation now in progress";
+        case WSAEALREADY: return "Operation already in progress";
+        case WSAENOTSOCK: return "Socket operation on nonsocket";
+        case WSAEDESTADDRREQ: return "Destination address required";
+        case WSAEMSGSIZE: return "Message too long";
+        case WSAEPROTOTYPE: return "Protocol wrong type for socket";
+        case WSAENOPROTOOPT: return "Bad protocol option";
+        case WSAEPROTONOSUPPORT: return "Protocol not supported";
+        case WSAESOCKTNOSUPPORT: return "Socket type not supported";
+        case WSAEOPNOTSUPP: return "Operation not supported";
+        case WSAEPFNOSUPPORT: return "Protocol family not supported";
+        case WSAEAFNOSUPPORT: 
+            return "Address family not supported by protocol family"; 
+        case WSAEADDRINUSE: return "Address already in use";
+        case WSAEADDRNOTAVAIL: return "Cannot assign requested address";
+        case WSAENETDOWN: return "Network is down";
+        case WSAENETUNREACH: return "Network is unreachable";
+        case WSAENETRESET: return "Network dropped connection on reset";
+        case WSAECONNABORTED: return "Software caused connection abort";
+        case WSAECONNRESET: return "Connection reset by peer";
+        case WSAENOBUFS: return "No buffer space available";
+        case WSAEISCONN: return "Socket is already connected";
+        case WSAENOTCONN: return "Socket is not connected";
+        case WSAESHUTDOWN: return "Cannot send after socket shutdown";
+        case WSAETIMEDOUT: return "Connection timed out";
+        case WSAECONNREFUSED: return "Connection refused";
+        case WSAEHOSTDOWN: return "Host is down";
+        case WSAEHOSTUNREACH: return "No route to host";
+        case WSAEPROCLIM: return "Too many processes";
+        case WSASYSNOTREADY: return "Network subsystem is unavailable";
+        case WSAVERNOTSUPPORTED: return "Winsock.dll version out of range";
+        case WSANOTINITIALISED: 
+            return "Successful WSAStartup not yet performed";
+        case WSAEDISCON: return "Graceful shutdown in progress";
+        case WSAHOST_NOT_FOUND: return "Host not found";
+        case WSATRY_AGAIN: return "Nonauthoritative host not found";
+        case WSANO_RECOVERY: return "Nonrecoverable name lookup error"; 
+        case WSANO_DATA: return "Valid name, no data record of requested type";
+        default: return "Unknown error";
+    }
+}
+
+const char *socket_strerror(int err) {
+    if (err <= 0) return io_strerror(err);
+    switch (err) {
+        case WSAEADDRINUSE: return "address already in use";
+        case WSAECONNREFUSED: return "connection refused";
+        case WSAEISCONN: return "already connected";
+        case WSAEACCES: return "permission denied";
+        case WSAECONNABORTED: return "closed";
+        case WSAECONNRESET: return "closed";
+        case WSAETIMEDOUT: return "timeout";
+        default: return wstrerror(err);
+    }
+}
+
+/* Socket error code */
+int socket_error()
+{
+   return WSAGetLastError();
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wsocket.h	Sat Jul 24 13:40:16 2010 +0100
@@ -0,0 +1,28 @@
+#ifndef WSOCKET_H
+#define WSOCKET_H
+/*=========================================================================*\
+* LuaSocket 2.0.2
+* Copyright (C) 2004-2007 Diego Nehab
+*
+* Socket compatibilization module for Win32
+*
+* RCS ID: $Id: wsocket.h 2 2006-04-30 19:30:47Z brunoos $
+\*=========================================================================*/
+
+/*=========================================================================*\
+* WinSock include files
+\*=========================================================================*/
+#include <winsock.h>
+
+#define WAITFD_R        1
+#define WAITFD_W        2
+#define WAITFD_E        4
+#define WAITFD_C        (WAITFD_E|WAITFD_W)
+
+#define SOCKET_INVALID (INVALID_SOCKET)
+
+typedef int socklen_t;
+typedef SOCKET t_socket;
+typedef t_socket *p_socket;
+
+#endif /* WSOCKET_H */

mercurial