From 8d91ac802732222ba1b775712543601137d2bf20 Mon Sep 17 00:00:00 2001
From: daurnimator <quae@daurnimator.com>
Date: Mon, 3 Apr 2017 11:01:54 +1000
Subject: openssl.ssl.context: Add ctx:setCurvesList

---
 doc/luaossl.tex | 6 ++++++
 1 file changed, 6 insertions(+)

(limited to 'doc/luaossl.tex')

diff --git a/doc/luaossl.tex b/doc/luaossl.tex
index 7db7463..72f4d06 100644
--- a/doc/luaossl.tex
+++ b/doc/luaossl.tex
@@ -883,6 +883,12 @@ Sets the private key \module{openssl.pkey} object $key$ for use during SSL conne
 
 Sets the allowed public key and private key algorithm(s). The string format is documented in the \href{http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT}{OpenSSL ciphers(1) utility documentation}.
 
+\subsubsection[\fn{context:setCurvesList}]{\fn{context:setCurvesList($string$ [, ...])}}
+
+Sets the supported curves. The string format is a list of colon separated curve names similar to \texttt{ctx:setCipherList(...)}. A list of supported curves can be found by running \texttt{openssl ecparam -list\_curves}.
+
+\emph{Only supported since OpenSSL 1.0.2.}
+
 \subsubsection[\fn{context:setEphemeralKey}]{\fn{context:setEphemeralKey($key$)}}
 
 Sets \module{openssl.pkey} object $key$ as the ephemeral key during key exchanges which use that particular key type. Typically $key$ will be either a Diffie-Hellman or Elliptic Curve key.
-- 
cgit v1.2.3-55-g6feb


From 70439fbea9ddd6acb942fc746bea9a522f940380 Mon Sep 17 00:00:00 2001
From: daurnimator <quae@daurnimator.com>
Date: Mon, 3 Apr 2017 12:52:39 +1000
Subject: doc/: Mention that OpenSSL < 1.0.2 only supports a single curve at a
 time

---
 doc/luaossl.tex | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'doc/luaossl.tex')

diff --git a/doc/luaossl.tex b/doc/luaossl.tex
index 72f4d06..32a4dba 100644
--- a/doc/luaossl.tex
+++ b/doc/luaossl.tex
@@ -893,7 +893,7 @@ Sets the supported curves. The string format is a list of colon separated curve
 
 Sets \module{openssl.pkey} object $key$ as the ephemeral key during key exchanges which use that particular key type. Typically $key$ will be either a Diffie-Hellman or Elliptic Curve key.
 
-\emph{In order to configure an SSL server to support an ephemeral key exchange cipher suite (i.e. DHE-* and ECDHE-*), the application must explicitly set the ephemeral keys. Simply enabling the cipher suite is not sufficient. The application can statically generate Diffie-Hellman public key parameters, and many servers ship with such a key compiled into the software. Elliptic curve keys are necessarily static, and instantiated by curve name\footnote{\href{http://en.wikipedia.org/w/index.php?title=Comparison\_of\_TLS\_implementations&oldid=629779090\#Supported\_elliptic\_curves}{According to Wikipedia} the most widely supported curve is prime256v1, so to enable ECDHE-* applications can simply do \texttt{ctx:setEphemeralKey(pkey.new\{ type = ``EC'', curve = ``prime256v1'' \})}. To achieve Perfect Forward Secrecy for ECDHE-*, applications must also do \texttt{ctx:setOptions(context.OP\_SINGLE\_ECDH\_USE)}. The \texttt{ctx} object must then be used to configure each SSL session, such as by passing it to \fn{cqueues.socket:starttls()}.}.}
+\emph{In order to configure an SSL server to support an ephemeral key exchange cipher suite (i.e. DHE-* and ECDHE-*), the application must explicitly set the ephemeral keys. Simply enabling the cipher suite is not sufficient. The application can statically generate Diffie-Hellman public key parameters, and many servers ship with such a key compiled into the software. Elliptic curve keys are necessarily static, and instantiated by curve name\footnote{OpenSSL < 1.0.2 only supports a single curve, \href{http://en.wikipedia.org/w/index.php?title=Comparison\_of\_TLS\_implementations&oldid=629779090\#Supported\_elliptic\_curves}{according to Wikipedia} the most widely supported curve is prime256v1, so to enable ECDHE-*, applications can simply do \texttt{ctx:setEphemeralKey(pkey.new\{ type = ``EC'', curve = ``prime256v1'' \})}. To achieve Perfect Forward Secrecy for ECDHE-*, applications must also do \texttt{ctx:setOptions(context.OP\_SINGLE\_ECDH\_USE)}. The \texttt{ctx} object must then be used to configure each SSL session, such as by passing it to \fn{cqueues.socket:starttls()}.}.}
 
 \emph{In addition, to attain Perfect Forward Secrecy the options \texttt{OP\_SINGLE\_DH\_USE} and \texttt{OP\_SINGLE\_ECDH\_USE} must be set so that OpenSSL discards and regenerates the secret keying parameters for each key exchange.}
 
-- 
cgit v1.2.3-55-g6feb


From f92ced1a1448c07ae19c3832a278867859371f76 Mon Sep 17 00:00:00 2001
From: daurnimator <quae@daurnimator.com>
Date: Thu, 6 Apr 2017 14:51:22 +1000
Subject: openssl.ssl: Bind SSL_set1_curves_list as ssl:setCurvesList()

---
 doc/luaossl.tex     |  6 ++++++
 src/openssl.c       | 22 ++++++++++++++++++++++
 src/openssl.ssl.lua | 20 ++++++++++++++++++--
 3 files changed, 46 insertions(+), 2 deletions(-)

(limited to 'doc/luaossl.tex')

diff --git a/doc/luaossl.tex b/doc/luaossl.tex
index 32a4dba..76821a1 100644
--- a/doc/luaossl.tex
+++ b/doc/luaossl.tex
@@ -978,6 +978,12 @@ TLS1\_2\_VERSION & 16-bit TLSv1.2 identifier (0x0303).  \\
 
 Returns the SSL/TLS version supported by the client, which should be greater than or equal to the negotiated version. See \fn{ssl:getVersion}.
 
+\subsubsection[\fn{ssl:setCurvesList}]{\fn{ssl:setCurvesList($string$ [, ...])}}
+
+Sets the supported curves for this SSL connection instance. See \fn{openssl.ssl.context:setCurvesList}.
+
+\emph{Only supported since OpenSSL 1.0.2.}
+
 \subsubsection[\fn{ssl:getAlpnSelected}]{\fn{ssl:getAlpnSelected()}}
 
 Returns the negotiated ALPN protocol as a string.
diff --git a/src/openssl.c b/src/openssl.c
index 652e38a..8217deb 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -294,6 +294,10 @@
 #define HAVE_SSL_SET_ALPN_PROTOS HAVE_SSL_CTX_SET_ALPN_PROTOS
 #endif
 
+#ifndef HAVE_SSL_SET_CURVES_LIST
+#define HAVE_SSL_SET_CURVES_LIST (OPENSSL_PREREQ(1,0,2) || LIBRESSL_PREREQ(2,5,1))
+#endif
+
 #ifndef HAVE_SSL_SET1_PARAM
 #define HAVE_SSL_SET1_PARAM OPENSSL_PREREQ(1,0,2)
 #endif
@@ -8214,6 +8218,21 @@ static int ssl_getCipherInfo(lua_State *L) {
 } /* ssl_getCipherInfo() */
 
 
+#if HAVE_SSL_SET_CURVES_LIST
+static int ssl_setCurvesList(lua_State *L) {
+	SSL *ssl = checksimple(L, 1, SSL_CLASS);
+	const char *curves = luaL_checkstring(L, 2);
+
+	if (!SSL_set1_curves_list(ssl, curves))
+		return auxL_error(L, auxL_EOPENSSL, "ssl:setCurvesList");
+
+	lua_pushboolean(L, 1);
+
+	return 1;
+} /* ssl_setCurvesList() */
+#endif
+
+
 static int ssl_getHostName(lua_State *L) {
 	SSL *ssl = checksimple(L, 1, SSL_CLASS);
 	const char *host;
@@ -8357,6 +8376,9 @@ static const auxL_Reg ssl_methods[] = {
 	{ "getPeerCertificate", &ssl_getPeerCertificate },
 	{ "getPeerChain",     &ssl_getPeerChain },
 	{ "getCipherInfo",    &ssl_getCipherInfo },
+#if HAVE_SSL_SET_CURVES_LIST
+	{ "setCurvesList",    &ssl_setCurvesList },
+#endif
 	{ "getHostName",      &ssl_getHostName },
 	{ "setHostName",      &ssl_setHostName },
 	{ "getVersion",       &ssl_getVersion },
diff --git a/src/openssl.ssl.lua b/src/openssl.ssl.lua
index 3c348f6..bf90f29 100644
--- a/src/openssl.ssl.lua
+++ b/src/openssl.ssl.lua
@@ -1,3 +1,19 @@
-local ctx = require"_openssl.ssl"
+local ssl = require"_openssl.ssl"
 
-return ctx
+local pack = table.pack or function(...) return { n = select("#", ...); ... } end
+
+-- Allow passing a vararg of curves, or an array
+local setCurvesList = ssl.interpose("setCurvesList", nil)
+if setCurvesList then
+	ssl.interpose("setCurvesList", function (self, curves, ...)
+		if (...) then
+			local curves_t = pack(curves, ...)
+			curves = table.concat(curves_t, ":", 1, curves_t.n)
+		elseif type(curves) == "table" then
+			curves = table.concat(curves, ":")
+		end
+		return setCurvesList(self, curves)
+	end)
+end
+
+return ssl
-- 
cgit v1.2.3-55-g6feb

