Skip to contentSkip to conversation

Do not assume that SSL_CTX_get/set_min/max_proto_version are macros

PATCH In review [email protected]... 5 participants 9 messages Mar 4, 2018 – Oct 10, 2018

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Do not assume that SSL_CTX_get/set_min/max_proto_version are macros

From: Selva Nair <[email protected]...>

Openssl docs do not explicitly state these to be macros although they are currently defined as such. Use AC_CHECK_DECLS to test for these so that both function and macro forms could be detected.

---
Though not meant as a fixup for libressl, as a side effect this also makes 2.4.5 build with newer libressl versions. (built on freebsd 11 using libressl 2.6.4 while testing patch 238)
Notes: (i) libressl defines only the set functions and neither are macros. So get functions will get used from the compat layer.

 configure.ac                 | 12 ++++++++++++
 src/openvpn/openssl_compat.h |  8 ++++----
 2 files changed, 16 insertions(+), 4 deletions(-)
configure.ac +12 -0
index 626b4dd..2a8e87f 100644
@@ -948,6 +948,18 @@ if test "${with_crypto_library}" = "openssl"; then
 			EC_GROUP_order_bits
 		]
 	)
+	AC_CHECK_DECLS(
+		[
+			SSL_CTX_get_min_proto_version,
+			SSL_CTX_get_max_proto_version,
+			SSL_CTX_set_min_proto_version,
+			SSL_CTX_set_max_proto_version,
+		],
+		,
+		,
+		[[#include <openssl/ssl.h>]]
+
+	)
 
 	CFLAGS="${saved_CFLAGS}"
 	LIBS="${saved_LIBS}"
src/openvpn/openssl_compat.h +4 -4
index d375fab..340d452 100644
@@ -661,7 +661,7 @@ EC_GROUP_order_bits(const EC_GROUP *group)
 #define RSA_F_RSA_OSSL_PRIVATE_ENCRYPT       RSA_F_RSA_EAY_PRIVATE_ENCRYPT
 #endif
 
-#ifndef SSL_CTX_get_min_proto_version
+#if !HAVE_DECL_SSL_CTX_GET_MIN_PROTO_VERSION
 /** Return the min SSL protocol version currently enabled in the context.
  *  If no valid version >= TLS1.0 is found, return 0. */
 static inline int
@@ -684,7 +684,7 @@ SSL_CTX_get_min_proto_version(SSL_CTX *ctx)
 }
 #endif /* SSL_CTX_get_min_proto_version */
 
-#ifndef SSL_CTX_get_max_proto_version
+#if !HAVE_DECL_SSL_CTX_GET_MAX_PROTO_VERSION
 /** Return the max SSL protocol version currently enabled in the context.
  *  If no valid version >= TLS1.0 is found, return 0. */
 static inline int
@@ -707,7 +707,7 @@ SSL_CTX_get_max_proto_version(SSL_CTX *ctx)
 }
 #endif /* SSL_CTX_get_max_proto_version */
 
-#ifndef SSL_CTX_set_min_proto_version
+#if !HAVE_DECL_SSL_CTX_SET_MIN_PROTO_VERSION
 /** Mimics SSL_CTX_set_min_proto_version for OpenSSL < 1.1 */
 static inline int
 SSL_CTX_set_min_proto_version(SSL_CTX *ctx, long tls_ver_min)
@@ -736,7 +736,7 @@ SSL_CTX_set_min_proto_version(SSL_CTX *ctx, long tls_ver_min)
 }
 #endif /* SSL_CTX_set_min_proto_version */
 
-#ifndef SSL_CTX_set_max_proto_version
+#if !HAVE_DECL_SSL_CTX_SET_MAX_PROTO_VERSION
 /** Mimics SSL_CTX_set_max_proto_version for OpenSSL < 1.1 */
 static inline int
 SSL_CTX_set_max_proto_version(SSL_CTX *ctx, long tls_ver_max)
Signature · 1 line
2.1.4
#2 lore raw
In reply to [email protected]...
Quoted 4 lines · On Sun, Mar 04 2018, [email protected]... wrote:

From: Selva Nair <[email protected]...>

Openssl docs do not explicitly state these to be macros although they are currently defined as such.

Actually they are documented as macros by OpenSSL since day 1, see NOTES.

Quoted 2 lines

Use AC_CHECK_DECLS to test for these so that
both function and macro forms could be detected.

Looks like the right way to handle such a situation. Your diff looks good, and works for me against LibreSSL HEAD on OpenBSD-current:

checking whether SSL_CTX_get_min_proto_version is declared... no checking whether SSL_CTX_get_max_proto_version is declared... no checking whether SSL_CTX_set_min_proto_version is declared... yes checking whether SSL_CTX_set_max_proto_version is declared... yes

PASS: t_lpback.sh
The following test will take about two minutes.
If the addresses are in use, this test will retry up to two times.
PASS: t_cltsrv.sh
====================
All 2 tests passed
(1 test was not run)
====================

Quoted 7 lines

---
Though not meant as a fixup for libressl, as a side effect this also makes 2.4.5 build with newer libressl versions. (built on freebsd 11 using libressl 2.6.4 while testing patch 238)
Notes: (i) libressl defines only the set functions and neither are macros. So get functions will get used from the compat layer.

More notes, possibly relevant:
- LibreSSL implement those as functions to provide better type checking. IIUC this is inspired by the same choice done in BoringSSL.
- yesterday I added macros for compatibility in LibreSSL HEAD, see
https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libssl/ssl.h
This should land in LibreSSL 2.7.0.
- adding the getters part is planned

Quoted 67 lines
 configure.ac                 | 12 ++++++++++++
 src/openvpn/openssl_compat.h |  8 ++++----
 2 files changed, 16 insertions(+), 4 deletions(-)
configure.ac +12 -0
index 626b4dd..2a8e87f 100644
@@ -948,6 +948,18 @@ if test "${with_crypto_library}" = "openssl"; then
 			EC_GROUP_order_bits
 		]
 	)
+	AC_CHECK_DECLS(
+		[
+			SSL_CTX_get_min_proto_version,
+			SSL_CTX_get_max_proto_version,
+			SSL_CTX_set_min_proto_version,
+			SSL_CTX_set_max_proto_version,
+		],
+		,
+		,
+		[[#include <openssl/ssl.h>]]
+
+	)
 
 	CFLAGS="${saved_CFLAGS}"
 	LIBS="${saved_LIBS}"
src/openvpn/openssl_compat.h +4 -4
index d375fab..340d452 100644
@@ -661,7 +661,7 @@ EC_GROUP_order_bits(const EC_GROUP *group)
 #define RSA_F_RSA_OSSL_PRIVATE_ENCRYPT       RSA_F_RSA_EAY_PRIVATE_ENCRYPT
 #endif
 
-#ifndef SSL_CTX_get_min_proto_version
+#if !HAVE_DECL_SSL_CTX_GET_MIN_PROTO_VERSION
 /** Return the min SSL protocol version currently enabled in the context.
  *  If no valid version >= TLS1.0 is found, return 0. */
 static inline int
@@ -684,7 +684,7 @@ SSL_CTX_get_min_proto_version(SSL_CTX *ctx)
 }
 #endif /* SSL_CTX_get_min_proto_version */
 
-#ifndef SSL_CTX_get_max_proto_version
+#if !HAVE_DECL_SSL_CTX_GET_MAX_PROTO_VERSION
 /** Return the max SSL protocol version currently enabled in the context.
  *  If no valid version >= TLS1.0 is found, return 0. */
 static inline int
@@ -707,7 +707,7 @@ SSL_CTX_get_max_proto_version(SSL_CTX *ctx)
 }
 #endif /* SSL_CTX_get_max_proto_version */
 
-#ifndef SSL_CTX_set_min_proto_version
+#if !HAVE_DECL_SSL_CTX_SET_MIN_PROTO_VERSION
 /** Mimics SSL_CTX_set_min_proto_version for OpenSSL < 1.1 */
 static inline int
 SSL_CTX_set_min_proto_version(SSL_CTX *ctx, long tls_ver_min)
@@ -736,7 +736,7 @@ SSL_CTX_set_min_proto_version(SSL_CTX *ctx, long tls_ver_min)
 }
 #endif /* SSL_CTX_set_min_proto_version */
 
-#ifndef SSL_CTX_set_max_proto_version
+#if !HAVE_DECL_SSL_CTX_SET_MAX_PROTO_VERSION
 /** Mimics SSL_CTX_set_max_proto_version for OpenSSL < 1.1 */
 static inline int
 SSL_CTX_set_max_proto_version(SSL_CTX *ctx, long tls_ver_max)
Signature · 1 line
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE
author
#3 lore raw

Hi,

Quoted 8 lines · Jeremie Courreges-Anglas
Quoted 4 lines · On Sun, Mar 04 2018, [email protected]... wrote:

From: Selva Nair <[email protected]...>

Openssl docs do not explicitly state these to be macros although they are currently defined as such.

Actually they are documented as macros by OpenSSL since day 1, see NOTES.

You are right, I missed that in the docs. In that case my patch is not needed especially so if libressl will provide those macros.

I'm still concerned about set and get functions coming from different sources and may be we should fix that by requiring that if set is defined we need get too. But that will once again break libressl compatibility.

Selva

#4 lore raw
Quoted 6 lines · Selva Nair

Hi,

Quoted 3 lines · Jeremie Courreges-Anglas
Quoted 2 lines · On Sun, Mar 04 2018, [email protected]... wrote:

From: Selva Nair <[email protected]...>

Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

Openssl docs do not explicitly state these to be macros although they are currently defined as such.

Actually they are documented as macros by OpenSSL since day 1, see NOTES.

You are right, I missed that in the docs. In that case my patch is not needed especially so if libressl will provide those macros.

It all depends if you want to support LibreSSL 2.6.x installations, as I'm not sure I'll be able to backport this in the 2.6 branch (which is supposed to receive security/reliability fixes only).

Quoted 2 lines

I'm still concerned about set and get functions coming from different sources

Indeed. A diff is floating to also add the getters to LibreSSL, hopefully this will make it in the upcoming 2.7.x release.

Quoted 3 lines

and may be we should fix that by requiring that if set is defined we need get too. But that will once again break libressl compatibility.

#5 lore raw
Quoted 15 lines · Jeremie Courreges-Anglas

On Sun, Mar 04 2018, Selva Nair <[email protected]...> wrote:
--8<--
[...]. OpenSSL itself only provided said setters (since 2015)[2]. The
getters were added to OpenSSL later (Sep 2017)[3].

[2] https://github.com/openssl/openssl/commit/7946ab33cecce60afcc00afc8fc18f31f9e66bff
[3] https://github.com/openssl/openssl/commit/3edabd3ccb7aac89af5a63cfb2378e33a8be05d7
-->8--

IIUC there are OpenSSL 1.1.0 releases out there that provide only the setters, and that would also be affected by the requirement you propose.

Github suggests that besides the master branch, the following tags have the setters[2]:

Quoted 8 lines
    OpenSSL_1_1_1-pre2 OpenSSL_1_1_1-pre1 OpenSSL_1_1_0 OpenSSL_1_1_0g
    OpenSSL_1_1_0f OpenSSL_1_1_0e OpenSSL_1_1_0d OpenSSL_1_1_0c
    OpenSSL_1_1_0b OpenSSL_1_1_0a OpenSSL_1_1_0-pre6 OpenSSL_1_1_0-pre5
    OpenSSL_1_1_0-pre4 OpenSSL_1_1_0-pre3 OpenSSL_1_1_0-pre2

while support for getters[3] is only in:

    OpenSSL_1_1_1-pre2 OpenSSL_1_1_1-pre1

That commit was cherry-picked to the OpenSSL_1_1_0-stable branch, and is available int 1.1.0g+:
https://github.com/openssl/openssl/commit/af51a74ade8bbab5ed49a3560dcb70d89896dc29

But yeah, that's still something we might need to think about.

-Steffan

author
#6 lore raw

Hi,

Quoted 24 lines · Steffan Karger
Quoted 22 lines · Jeremie Courreges-Anglas

On Sun, Mar 04 2018, Selva Nair <[email protected]...> wrote:
--8<--
[...]. OpenSSL itself only provided said setters (since 2015)[2]. The
getters were added to OpenSSL later (Sep 2017)[3].

[2] https://github.com/openssl/openssl/commit/7946ab33cecce60afcc00afc8fc18f31f9e66bff
[3] https://github.com/openssl/openssl/commit/3edabd3ccb7aac89af5a63cfb2378e33a8be05d7
-->8--

IIUC there are OpenSSL 1.1.0 releases out there that provide only the setters, and that would also be affected by the requirement you propose.

Github suggests that besides the master branch, the following tags have the setters[2]:

    OpenSSL_1_1_1-pre2 OpenSSL_1_1_1-pre1 OpenSSL_1_1_0 OpenSSL_1_1_0g
    OpenSSL_1_1_0f OpenSSL_1_1_0e OpenSSL_1_1_0d OpenSSL_1_1_0c
    OpenSSL_1_1_0b OpenSSL_1_1_0a OpenSSL_1_1_0-pre6 OpenSSL_1_1_0-pre5
    OpenSSL_1_1_0-pre4 OpenSSL_1_1_0-pre3 OpenSSL_1_1_0-pre2

while support for getters[3] is only in:

Quoted 7 lines
Quoted 1 line
    OpenSSL_1_1_1-pre2 OpenSSL_1_1_1-pre1

That commit was cherry-picked to the OpenSSL_1_1_0-stable branch, and is available int 1.1.0g+:
https://github.com/openssl/openssl/commit/af51a74ade8bbab5ed49a3560dcb70d89896dc29

But yeah, that's still something we might need to think about.

Yes this is troubling. I had tested Windows build using 1.1.0g, but our release is built with 1.1.0f. So, for example, --tls-version-min 1.2 will not get read back as 1.2. Most likely it'll only lead to less than ideal UX in some corner cases (e.g. the error check min <= max in cryptoapi.c will not work as expected).

Selva

#7 lore raw
In reply to [email protected]...

Hi,

Quoted 6 lines · On Sun, Mar 04, 2018 at 12:44:02PM -0500, [email protected]... wrote:

From: Selva Nair <[email protected]...>

Openssl docs do not explicitly state these to be macros although they are currently defined as such. Use AC_CHECK_DECLS to test for these so that both function and macro forms could be detected.

Quoted 7 lines

---
Though not meant as a fixup for libressl, as a side effect this also makes 2.4.5 build with newer libressl versions. (built on freebsd 11 using libressl 2.6.4 while testing patch 238)
Notes: (i) libressl defines only the set functions and neither are macros. So get functions will get used from the compat layer.

So, going through open patches in patchwork I came to this one.

Reading through the thread, I'm not sure what the final outcome on the patch and the problem was? LibreSSL seems to be fixed (thanks, Jeremie :-) ) and if we build with OpenSSL 1.1.0g+, all is good?

Phrased differently: does anything need to be done with this patch or should I click on "superceded" in patchwork now?

gert

Signature · 6 lines
"If was one thing all people took for granted, was conviction that if you 
 feed honest figures into a computer, honest figures come out. Never doubted 
 it myself till I met a computer with a sense of humor."
                             Robert A. Heinlein, The Moon is a Harsh Mistress

Gert Doering - Munich, Germany                             [email protected]...
author
#8 lore raw

Hi,

Quoted 18 lines · Gert Doering

Hi,

Quoted 4 lines · On Sun, Mar 04, 2018 at 12:44:02PM -0500, [email protected]... wrote:

From: Selva Nair <[email protected]...>

Openssl docs do not explicitly state these to be macros although they are currently defined as such. Use AC_CHECK_DECLS to test for these so

that

Quoted 9 lines

both function and macro forms could be detected.

---
Though not meant as a fixup for libressl, as a side effect this also makes 2.4.5 build with newer libressl versions. (built on freebsd 11 using libressl 2.6.4 while testing patch 238)
Notes: (i) libressl defines only the set functions and neither are macros. So get functions will get used from the compat layer.

Quoted 9 lines

So, going through open patches in patchwork I came to this one.

Reading through the thread, I'm not sure what the final outcome on the patch and the problem was? LibreSSL seems to be fixed (thanks, Jeremie :-) ) and if we build with OpenSSL 1.1.0g+, all is good?

Phrased differently: does anything need to be done with this patch or should I click on "superceded" in patchwork now?

Agreed, if LibreSSL has got those macros defined now, we should just drop this patch.

I'm marking these as superseded.

Selva