Hi Dirkjan, I finally merged your patch after discussing with Emeric. He's fine with it as well. Both of us think that the breakage of openssl 0.9.8 is not a showstopper at the moment and that the best way to know if/how it needs to be fixed is to let it go in the wild. Given that openssl 1.1.0 was released 3 months ago and 0.9.8 has been dead for almost a year, I prefer that our new haproxy version focuses on the future than on the past, especially with the reduced life of new versions (eg: 1.0.2 only has two more years left).
I got two annoying warnings affecting either older versions or newer ones, each time due to a const being put at the right place in a function prototype. So I added another patch to deal with this, it defines a new macro called __OPENSSL_110_CONST__ which equals "const" on 1.1.0 and nothing on older versions. I also moved the include file to include/proto/openssl-compat.h since it only defines prototypes. But the main reason I must confess is that the previous choice (include/compat/openssl.h) was causing me a lot of pain by breaking my auto-completion, and after spending a few hours on it, I had to forfeit on trying to get my fingers to switch "comm<tab>" instead of the shorter "c<tab>" they've been trained to for a decade :-/ I'm appending the 3 patches I added on top of yours and that I merged as one single patch. As you said, 1.1.0 builds with a few "deprecated" warnings which are still OK for now as the affected functions are part of the API and that we can clean later. I tested 1.0.1 and 1.0.2 and they were OK as well. Now if anyone is interested in trying to port the code to 0.9.8 (should not be too hard, just a few more #ifdef to add), proposals are welcome. Thanks! Willy
>From 334cffc47313355e2f7573919b790be5d2e95d43 Mon Sep 17 00:00:00 2001 From: Willy Tarreau <[email protected]> Date: Tue, 8 Nov 2016 19:53:01 +0100 Subject: WIP: ssl-1.1.0: protect compat/openssl.h against multiple inclusion X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 --- include/compat/openssl.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/compat/openssl.h b/include/compat/openssl.h index 269df33..930f16f 100644 --- a/include/compat/openssl.h +++ b/include/compat/openssl.h @@ -1,3 +1,5 @@ +#ifndef _COMPAT_OPENSSL_H +#define _COMPAT_OPENSSL_H #include <openssl/crypto.h> #include <openssl/ssl.h> #include <openssl/x509.h> @@ -130,3 +132,5 @@ static inline X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x) } #endif + +#endif /* _COMPAT_OPENSSL_H */ -- 1.7.12.1
>From 25858b36486ff3278851c27a2903a670f2bd51e1 Mon Sep 17 00:00:00 2001 From: Willy Tarreau <[email protected]> Date: Tue, 8 Nov 2016 19:56:48 +0100 Subject: WIP: ssl-1.1.0: add a const type modifier only for 1.1.0 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 --- include/compat/openssl.h | 6 ++++++ src/shctx.c | 2 +- src/ssl_sock.c | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/include/compat/openssl.h b/include/compat/openssl.h index 930f16f..7f86836 100644 --- a/include/compat/openssl.h +++ b/include/compat/openssl.h @@ -133,4 +133,10 @@ static inline X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x) #endif +#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) +#define __OPENSSL_110_CONST__ const +#else +#define __OPENSSL_110_CONST__ +#endif + #endif /* _COMPAT_OPENSSL_H */ diff --git a/src/shctx.c b/src/shctx.c index 39ca450..8485057 100644 --- a/src/shctx.c +++ b/src/shctx.c @@ -434,7 +434,7 @@ err: } /* SSL callback used on lookup an existing session cause none found in internal cache */ -SSL_SESSION *shctx_get_cb(SSL *ssl, unsigned char *key, int key_len, int *do_copy) +SSL_SESSION *shctx_get_cb(SSL *ssl, __OPENSSL_110_CONST__ unsigned char *key, int key_len, int *do_copy) { struct shared_session *shsess; unsigned char data[SHSESS_MAX_DATA_LEN], *p; diff --git a/src/ssl_sock.c b/src/ssl_sock.c index d23bd87..1a02291 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -4643,7 +4643,7 @@ smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char * { int cert_peer = (kw[4] == 'c') ? 1 : 0; X509 *crt; - ASN1_OBJECT *algorithm; + __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm; int nid; struct connection *conn; -- 1.7.12.1
>From ff9a0172ea7f5468cfcf89452dfe6c129f27a96b Mon Sep 17 00:00:00 2001 From: Willy Tarreau <[email protected]> Date: Tue, 8 Nov 2016 20:52:44 +0100 Subject: WIP: ssl-1.1.0: move include to proto/openssl-compat.h X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 it's really only prototypes, and the real reason is that having this new "compat" subdirectory makes my auto-completion really painful now :-( --- include/compat/openssl.h | 142 ----------------------------------------- include/proto/openssl-compat.h | 142 +++++++++++++++++++++++++++++++++++++++++ src/shctx.c | 2 +- src/ssl_sock.c | 3 +- 4 files changed, 144 insertions(+), 145 deletions(-) delete mode 100644 include/compat/openssl.h create mode 100644 include/proto/openssl-compat.h diff --git a/include/compat/openssl.h b/include/compat/openssl.h deleted file mode 100644 index 7f86836..0000000 --- a/include/compat/openssl.h +++ /dev/null @@ -1,142 +0,0 @@ -#ifndef _COMPAT_OPENSSL_H -#define _COMPAT_OPENSSL_H -#include <openssl/crypto.h> -#include <openssl/ssl.h> -#include <openssl/x509.h> -#include <openssl/x509v3.h> -#include <openssl/x509.h> -#include <openssl/err.h> -#include <openssl/rand.h> -#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP) -#include <openssl/ocsp.h> -#endif -#ifndef OPENSSL_NO_DH -#include <openssl/dh.h> -#endif - -#if (OPENSSL_VERSION_NUMBER < 0x1000000fL) -/* - * Functions introduced in OpenSSL 1.0.1 - */ -static inline int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx, unsigned int sid_ctx_len) -{ - s->sid_ctx_length = sid_ctx_len; - memcpy(s->sid_ctx, sid_ctx, sid_ctx_len); - return 1; -} - -static inline int EVP_PKEY_base_id(const EVP_PKEY *pkey) -{ - return EVP_PKEY_type(pkey->type); -} - -static inline const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *sess, unsigned int *sid_length) -{ - *sid_length = sess->session_id_length; - return sess->session_id; -} - -static inline X509_NAME_ENTRY *X509_NAME_get_entry(const X509_NAME *name, int loc) -{ - return sk_X509_NAME_ENTRY_value(name->entries, loc); -} - -static inline ASN1_OBJECT *X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne) -{ - return ne->object; -} - -static inline ASN1_STRING *X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne) -{ - return ne->value; -} - -static inline int ASN1_STRING_length(const ASN1_STRING *x) -{ - return x->length; -} - -static inline int X509_NAME_entry_count(X509_NAME *name) -{ - return sk_X509_NAME_ENTRY_num(name->entries) -} - -int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, const unsigned char **pk, int *ppklen, X509_ALGOR **pa, X509_PUBKEY *pub) -{ - *ppkalg = pub->algor->algorithm; - return 1; -} - -static inline void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, const void **ppval, const X509_ALGOR *algor) -{ - *paobj = algor->algorithm; -} - -#ifndef X509_get_X509_PUBKEY -#define X509_get_X509_PUBKEY(x) ((x)->cert_info->key -#endif - -#endif - -#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) -/* - * Functions introduced in OpenSSL 1.1.0 - */ - -static inline const unsigned char *SSL_SESSION_get0_id_context(const SSL_SESSION *sess, unsigned int *sid_ctx_length) -{ - *sid_ctx_length = sess->sid_ctx_length; - return sess->sid_ctx; -} - -static inline int SSL_SESSION_set1_id(SSL_SESSION *s, const unsigned char *sid, unsigned int sid_len) -{ - s->session_id_length = sid_len; - memcpy(s->session_id, sid, sid_len); - return 1; -} - -static inline const OCSP_CERTID *OCSP_SINGLERESP_get0_id(const OCSP_SINGLERESP *single) -{ - return single->certId; -} - -static inline pem_password_cb *SSL_CTX_get_default_passwd_cb(SSL_CTX *ctx) -{ - return ctx->default_passwd_callback; -} - -static inline void *SSL_CTX_get_default_passwd_cb_userdata(SSL_CTX *ctx) -{ - return ctx->default_passwd_callback_userdata; -} - -#ifndef OPENSSL_NO_DH -static inline int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) -{ - /* Implements only the bare necessities for HAProxy */ - dh->p = p; - dh->g = g; - return 1; -} -#endif - -static inline const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x) -{ - return x->data; -} - -static inline X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x) -{ - return x->cert_info->signature; -} - -#endif - -#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) -#define __OPENSSL_110_CONST__ const -#else -#define __OPENSSL_110_CONST__ -#endif - -#endif /* _COMPAT_OPENSSL_H */ diff --git a/include/proto/openssl-compat.h b/include/proto/openssl-compat.h new file mode 100644 index 0000000..17b491f --- /dev/null +++ b/include/proto/openssl-compat.h @@ -0,0 +1,142 @@ +#ifndef _PROTO_OPENSSL_COMPAT_H +#define _PROTO_OPENSSL_COMPAT_H +#include <openssl/crypto.h> +#include <openssl/ssl.h> +#include <openssl/x509.h> +#include <openssl/x509v3.h> +#include <openssl/x509.h> +#include <openssl/err.h> +#include <openssl/rand.h> +#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP) +#include <openssl/ocsp.h> +#endif +#ifndef OPENSSL_NO_DH +#include <openssl/dh.h> +#endif + +#if (OPENSSL_VERSION_NUMBER < 0x1000000fL) +/* + * Functions introduced in OpenSSL 1.0.1 + */ +static inline int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx, unsigned int sid_ctx_len) +{ + s->sid_ctx_length = sid_ctx_len; + memcpy(s->sid_ctx, sid_ctx, sid_ctx_len); + return 1; +} + +static inline int EVP_PKEY_base_id(const EVP_PKEY *pkey) +{ + return EVP_PKEY_type(pkey->type); +} + +static inline const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *sess, unsigned int *sid_length) +{ + *sid_length = sess->session_id_length; + return sess->session_id; +} + +static inline X509_NAME_ENTRY *X509_NAME_get_entry(const X509_NAME *name, int loc) +{ + return sk_X509_NAME_ENTRY_value(name->entries, loc); +} + +static inline ASN1_OBJECT *X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne) +{ + return ne->object; +} + +static inline ASN1_STRING *X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne) +{ + return ne->value; +} + +static inline int ASN1_STRING_length(const ASN1_STRING *x) +{ + return x->length; +} + +static inline int X509_NAME_entry_count(X509_NAME *name) +{ + return sk_X509_NAME_ENTRY_num(name->entries) +} + +int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, const unsigned char **pk, int *ppklen, X509_ALGOR **pa, X509_PUBKEY *pub) +{ + *ppkalg = pub->algor->algorithm; + return 1; +} + +static inline void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, const void **ppval, const X509_ALGOR *algor) +{ + *paobj = algor->algorithm; +} + +#ifndef X509_get_X509_PUBKEY +#define X509_get_X509_PUBKEY(x) ((x)->cert_info->key +#endif + +#endif + +#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) +/* + * Functions introduced in OpenSSL 1.1.0 + */ + +static inline const unsigned char *SSL_SESSION_get0_id_context(const SSL_SESSION *sess, unsigned int *sid_ctx_length) +{ + *sid_ctx_length = sess->sid_ctx_length; + return sess->sid_ctx; +} + +static inline int SSL_SESSION_set1_id(SSL_SESSION *s, const unsigned char *sid, unsigned int sid_len) +{ + s->session_id_length = sid_len; + memcpy(s->session_id, sid, sid_len); + return 1; +} + +static inline const OCSP_CERTID *OCSP_SINGLERESP_get0_id(const OCSP_SINGLERESP *single) +{ + return single->certId; +} + +static inline pem_password_cb *SSL_CTX_get_default_passwd_cb(SSL_CTX *ctx) +{ + return ctx->default_passwd_callback; +} + +static inline void *SSL_CTX_get_default_passwd_cb_userdata(SSL_CTX *ctx) +{ + return ctx->default_passwd_callback_userdata; +} + +#ifndef OPENSSL_NO_DH +static inline int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) +{ + /* Implements only the bare necessities for HAProxy */ + dh->p = p; + dh->g = g; + return 1; +} +#endif + +static inline const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x) +{ + return x->data; +} + +static inline X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x) +{ + return x->cert_info->signature; +} + +#endif + +#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) +#define __OPENSSL_110_CONST__ const +#else +#define __OPENSSL_110_CONST__ +#endif + +#endif /* _PROTO_OPENSSL_COMPAT_H */ diff --git a/src/shctx.c b/src/shctx.c index 8485057..988832f 100644 --- a/src/shctx.c +++ b/src/shctx.c @@ -27,7 +27,7 @@ #include <ebmbtree.h> #include <types/global.h> #include "proto/shctx.h" -#include <compat/openssl.h> +#include <proto/openssl-compat.h> struct shsess_packet_hdr { unsigned int eol; diff --git a/src/ssl_sock.c b/src/ssl_sock.c index 1a02291..b14bb8a 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -53,8 +53,6 @@ #include <openssl/dh.h> #endif -#include <compat/openssl.h> - #include <import/lru.h> #include <import/xxhash.h> @@ -81,6 +79,7 @@ #include <proto/freq_ctr.h> #include <proto/frontend.h> #include <proto/listener.h> +#include <proto/openssl-compat.h> #include <proto/pattern.h> #include <proto/proto_tcp.h> #include <proto/server.h> -- 1.7.12.1

