summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordaurnimator <quae@daurnimator.com>2017-08-30 23:36:06 +1000
committerdaurnimator <quae@daurnimator.com>2017-08-30 23:37:13 +1000
commit24c947d934703c5b59edfe8229f9fa5202ffc86d (patch)
tree62786babbb8f4e7f0f6a747909809e16c2bf4c63
parent71c54169bb96543a50f90767d351702f63fa0220 (diff)
parentf92ced1a1448c07ae19c3832a278867859371f76 (diff)
downloadluaossl-24c947d934703c5b59edfe8229f9fa5202ffc86d.tar.gz
luaossl-24c947d934703c5b59edfe8229f9fa5202ffc86d.tar.bz2
luaossl-24c947d934703c5b59edfe8229f9fa5202ffc86d.zip
Merge branch 'curves_list'
-rw-r--r--doc/luaossl.pdfbin276077 -> 300041 bytes
-rw-r--r--doc/luaossl.tex14
-rw-r--r--src/openssl.c57
-rw-r--r--src/openssl.ssl.context.lua14
-rw-r--r--src/openssl.ssl.lua20
5 files changed, 102 insertions, 3 deletions
diff --git a/doc/luaossl.pdf b/doc/luaossl.pdf
index 25c58ca..81142cb 100644
--- a/doc/luaossl.pdf
+++ b/doc/luaossl.pdf
Binary files differ
diff --git a/doc/luaossl.tex b/doc/luaossl.tex
index 5e19e66..7bb85df 100644
--- a/doc/luaossl.tex
+++ b/doc/luaossl.tex
@@ -933,11 +933,17 @@ Sets the private key \module{openssl.pkey} object $key$ for use during SSL conne
933 933
934Sets 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}. 934Sets 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}.
935 935
936\subsubsection[\fn{context:setCurvesList}]{\fn{context:setCurvesList($string$ [, ...])}}
937
938Sets 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}.
939
940\emph{Only supported since OpenSSL 1.0.2.}
941
936\subsubsection[\fn{context:setEphemeralKey}]{\fn{context:setEphemeralKey($key$)}} 942\subsubsection[\fn{context:setEphemeralKey}]{\fn{context:setEphemeralKey($key$)}}
937 943
938Sets \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. 944Sets \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.
939 945
940\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()}.}.} 946\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()}.}.}
941 947
942\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.} 948\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.}
943 949
@@ -1070,6 +1076,12 @@ TLS1\_2\_VERSION & 16-bit TLSv1.2 identifier (0x0303). \\
1070 1076
1071Returns the SSL/TLS version supported by the client, which should be greater than or equal to the negotiated version. See \fn{ssl:getVersion}. 1077Returns the SSL/TLS version supported by the client, which should be greater than or equal to the negotiated version. See \fn{ssl:getVersion}.
1072 1078
1079\subsubsection[\fn{ssl:setCurvesList}]{\fn{ssl:setCurvesList($string$ [, ...])}}
1080
1081Sets the supported curves for this SSL connection instance. See \fn{openssl.ssl.context:setCurvesList}.
1082
1083\emph{Only supported since OpenSSL 1.0.2.}
1084
1073\subsubsection[\fn{ssl:getAlpnSelected}]{\fn{ssl:getAlpnSelected()}} 1085\subsubsection[\fn{ssl:getAlpnSelected}]{\fn{ssl:getAlpnSelected()}}
1074 1086
1075Returns the negotiated ALPN protocol as a string. 1087Returns the negotiated ALPN protocol as a string.
diff --git a/src/openssl.c b/src/openssl.c
index ac053fd..a3e5637 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -253,6 +253,14 @@
253#define HAVE_SSL_CTX_GET0_PARAM OPENSSL_PREREQ(1,0,2) 253#define HAVE_SSL_CTX_GET0_PARAM OPENSSL_PREREQ(1,0,2)
254#endif 254#endif
255 255
256#ifndef HAVE_SSL_CTX_SET_CURVES_LIST
257#define HAVE_SSL_CTX_SET_CURVES_LIST (OPENSSL_PREREQ(1,0,2) || LIBRESSL_PREREQ(2,5,1))
258#endif
259
260#ifndef HAVE_SSL_CTX_SET_ECDH_AUTO
261#define HAVE_SSL_CTX_SET_ECDH_AUTO ((OPENSSL_PREREQ(1,0,2) && !OPENSSL_PREREQ(1,1,0)) || LIBRESSL_PREREQ(2,1,2))
262#endif
263
256#ifndef HAVE_SSL_CTX_SET_ALPN_PROTOS 264#ifndef HAVE_SSL_CTX_SET_ALPN_PROTOS
257#define HAVE_SSL_CTX_SET_ALPN_PROTOS (OPENSSL_PREREQ(1,0,2) || LIBRESSL_PREREQ(2,1,3)) 265#define HAVE_SSL_CTX_SET_ALPN_PROTOS (OPENSSL_PREREQ(1,0,2) || LIBRESSL_PREREQ(2,1,3))
258#endif 266#endif
@@ -297,6 +305,10 @@
297#define HAVE_SSL_SET_ALPN_PROTOS HAVE_SSL_CTX_SET_ALPN_PROTOS 305#define HAVE_SSL_SET_ALPN_PROTOS HAVE_SSL_CTX_SET_ALPN_PROTOS
298#endif 306#endif
299 307
308#ifndef HAVE_SSL_SET_CURVES_LIST
309#define HAVE_SSL_SET_CURVES_LIST (OPENSSL_PREREQ(1,0,2) || LIBRESSL_PREREQ(2,5,1))
310#endif
311
300#ifndef HAVE_SSL_SET1_PARAM 312#ifndef HAVE_SSL_SET1_PARAM
301#define HAVE_SSL_SET1_PARAM OPENSSL_PREREQ(1,0,2) 313#define HAVE_SSL_SET1_PARAM OPENSSL_PREREQ(1,0,2)
302#endif 314#endif
@@ -7824,6 +7836,15 @@ static int sx_new(lua_State *L) {
7824 7836
7825 SSL_CTX_set_options(*ud, options); 7837 SSL_CTX_set_options(*ud, options);
7826 7838
7839#if HAVE_SSL_CTX_SET_ECDH_AUTO
7840 /* OpenSSL 1.0.2 introduced SSL_CTX_set_ecdh_auto to automatically select
7841 * from the curves set via SSL_CTX_set1_curves_list. However as of OpenSSL
7842 * 1.1.0, the functionality was turned on permanently and the option
7843 * removed. */
7844 if (!SSL_CTX_set_ecdh_auto(*ud, 1))
7845 return auxL_error(L, auxL_EOPENSSL, "ssl.context.new");
7846#endif
7847
7827 return 1; 7848 return 1;
7828} /* sx_new() */ 7849} /* sx_new() */
7829 7850
@@ -7999,6 +8020,21 @@ static int sx_setCipherList(lua_State *L) {
7999} /* sx_setCipherList() */ 8020} /* sx_setCipherList() */
8000 8021
8001 8022
8023#if HAVE_SSL_CTX_SET_CURVES_LIST
8024static int sx_setCurvesList(lua_State *L) {
8025 SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS);
8026 const char *curves = luaL_checkstring(L, 2);
8027
8028 if (!SSL_CTX_set1_curves_list(ctx, curves))
8029 return auxL_error(L, auxL_EOPENSSL, "ssl.context:setCurvesList");
8030
8031 lua_pushboolean(L, 1);
8032
8033 return 1;
8034} /* sx_setCurvesList() */
8035#endif
8036
8037
8002static int sx_setEphemeralKey(lua_State *L) { 8038static int sx_setEphemeralKey(lua_State *L) {
8003 SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS); 8039 SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS);
8004 EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS); 8040 EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS);
@@ -8303,6 +8339,9 @@ static const auxL_Reg sx_methods[] = {
8303 { "setCertificate", &sx_setCertificate }, 8339 { "setCertificate", &sx_setCertificate },
8304 { "setPrivateKey", &sx_setPrivateKey }, 8340 { "setPrivateKey", &sx_setPrivateKey },
8305 { "setCipherList", &sx_setCipherList }, 8341 { "setCipherList", &sx_setCipherList },
8342#if HAVE_SSL_CTX_SET_CURVES_LIST
8343 { "setCurvesList", &sx_setCurvesList },
8344#endif
8306 { "setEphemeralKey", &sx_setEphemeralKey }, 8345 { "setEphemeralKey", &sx_setEphemeralKey },
8307#if HAVE_SSL_CTX_SET_ALPN_PROTOS 8346#if HAVE_SSL_CTX_SET_ALPN_PROTOS
8308 { "setAlpnProtos", &sx_setAlpnProtos }, 8347 { "setAlpnProtos", &sx_setAlpnProtos },
@@ -8627,6 +8666,21 @@ static int ssl_getCipherInfo(lua_State *L) {
8627} /* ssl_getCipherInfo() */ 8666} /* ssl_getCipherInfo() */
8628 8667
8629 8668
8669#if HAVE_SSL_SET_CURVES_LIST
8670static int ssl_setCurvesList(lua_State *L) {
8671 SSL *ssl = checksimple(L, 1, SSL_CLASS);
8672 const char *curves = luaL_checkstring(L, 2);
8673
8674 if (!SSL_set1_curves_list(ssl, curves))
8675 return auxL_error(L, auxL_EOPENSSL, "ssl:setCurvesList");
8676
8677 lua_pushboolean(L, 1);
8678
8679 return 1;
8680} /* ssl_setCurvesList() */
8681#endif
8682
8683
8630static int ssl_getHostName(lua_State *L) { 8684static int ssl_getHostName(lua_State *L) {
8631 SSL *ssl = checksimple(L, 1, SSL_CLASS); 8685 SSL *ssl = checksimple(L, 1, SSL_CLASS);
8632 const char *host; 8686 const char *host;
@@ -8881,6 +8935,9 @@ static const auxL_Reg ssl_methods[] = {
8881 { "getPeerCertificate", &ssl_getPeerCertificate }, 8935 { "getPeerCertificate", &ssl_getPeerCertificate },
8882 { "getPeerChain", &ssl_getPeerChain }, 8936 { "getPeerChain", &ssl_getPeerChain },
8883 { "getCipherInfo", &ssl_getCipherInfo }, 8937 { "getCipherInfo", &ssl_getCipherInfo },
8938#if HAVE_SSL_SET_CURVES_LIST
8939 { "setCurvesList", &ssl_setCurvesList },
8940#endif
8884 { "getHostName", &ssl_getHostName }, 8941 { "getHostName", &ssl_getHostName },
8885 { "setHostName", &ssl_setHostName }, 8942 { "setHostName", &ssl_setHostName },
8886 { "getVersion", &ssl_getVersion }, 8943 { "getVersion", &ssl_getVersion },
diff --git a/src/openssl.ssl.context.lua b/src/openssl.ssl.context.lua
index 2098b54..3263fb1 100644
--- a/src/openssl.ssl.context.lua
+++ b/src/openssl.ssl.context.lua
@@ -13,4 +13,18 @@ local setCipherList; setCipherList = ctx.interpose("setCipherList", function (se
13 return setCipherList(self, ciphers) 13 return setCipherList(self, ciphers)
14end) 14end)
15 15
16-- Allow passing a vararg of curves, or an array
17local setCurvesList = ctx.interpose("setCurvesList", nil)
18if setCurvesList then
19 ctx.interpose("setCurvesList", function (self, curves, ...)
20 if (...) then
21 local curves_t = pack(curves, ...)
22 curves = table.concat(curves_t, ":", 1, curves_t.n)
23 elseif type(curves) == "table" then
24 curves = table.concat(curves, ":")
25 end
26 return setCurvesList(self, curves)
27 end)
28end
29
16return ctx 30return ctx
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 @@
1local ctx = require"_openssl.ssl" 1local ssl = require"_openssl.ssl"
2 2
3return ctx 3local pack = table.pack or function(...) return { n = select("#", ...); ... } end
4
5-- Allow passing a vararg of curves, or an array
6local setCurvesList = ssl.interpose("setCurvesList", nil)
7if setCurvesList then
8 ssl.interpose("setCurvesList", function (self, curves, ...)
9 if (...) then
10 local curves_t = pack(curves, ...)
11 curves = table.concat(curves_t, ":", 1, curves_t.n)
12 elseif type(curves) == "table" then
13 curves = table.concat(curves, ":")
14 end
15 return setCurvesList(self, curves)
16 end)
17end
18
19return ssl