diff options
| author | daurnimator <quae@daurnimator.com> | 2017-08-30 23:36:06 +1000 |
|---|---|---|
| committer | daurnimator <quae@daurnimator.com> | 2017-08-30 23:37:13 +1000 |
| commit | 24c947d934703c5b59edfe8229f9fa5202ffc86d (patch) | |
| tree | 62786babbb8f4e7f0f6a747909809e16c2bf4c63 | |
| parent | 71c54169bb96543a50f90767d351702f63fa0220 (diff) | |
| parent | f92ced1a1448c07ae19c3832a278867859371f76 (diff) | |
| download | luaossl-24c947d934703c5b59edfe8229f9fa5202ffc86d.tar.gz luaossl-24c947d934703c5b59edfe8229f9fa5202ffc86d.tar.bz2 luaossl-24c947d934703c5b59edfe8229f9fa5202ffc86d.zip | |
Merge branch 'curves_list'
| -rw-r--r-- | doc/luaossl.pdf | bin | 276077 -> 300041 bytes | |||
| -rw-r--r-- | doc/luaossl.tex | 14 | ||||
| -rw-r--r-- | src/openssl.c | 57 | ||||
| -rw-r--r-- | src/openssl.ssl.context.lua | 14 | ||||
| -rw-r--r-- | src/openssl.ssl.lua | 20 |
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 | ||
| 934 | 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}. | 934 | 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}. |
| 935 | 935 | ||
| 936 | \subsubsection[\fn{context:setCurvesList}]{\fn{context:setCurvesList($string$ [, ...])}} | ||
| 937 | |||
| 938 | 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}. | ||
| 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 | ||
| 938 | 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. | 944 | 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. |
| 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 | ||
| 1071 | Returns the SSL/TLS version supported by the client, which should be greater than or equal to the negotiated version. See \fn{ssl:getVersion}. | 1077 | Returns 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 | |||
| 1081 | Sets 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 | ||
| 1075 | Returns the negotiated ALPN protocol as a string. | 1087 | Returns 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 | ||
| 8024 | static 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 | |||
| 8002 | static int sx_setEphemeralKey(lua_State *L) { | 8038 | static 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 | ||
| 8670 | static 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 | |||
| 8630 | static int ssl_getHostName(lua_State *L) { | 8684 | static 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) |
| 14 | end) | 14 | end) |
| 15 | 15 | ||
| 16 | -- Allow passing a vararg of curves, or an array | ||
| 17 | local setCurvesList = ctx.interpose("setCurvesList", nil) | ||
| 18 | if 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) | ||
| 28 | end | ||
| 29 | |||
| 16 | return ctx | 30 | return 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 @@ | |||
| 1 | local ctx = require"_openssl.ssl" | 1 | local ssl = require"_openssl.ssl" |
| 2 | 2 | ||
| 3 | return ctx | 3 | local pack = table.pack or function(...) return { n = select("#", ...); ... } end |
| 4 | |||
| 5 | -- Allow passing a vararg of curves, or an array | ||
| 6 | local setCurvesList = ssl.interpose("setCurvesList", nil) | ||
| 7 | if 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) | ||
| 17 | end | ||
| 18 | |||
| 19 | return ssl | ||
