BUG/MEDIUM: ssl: fix several bad pointer aliases in a few sample fetch functions

Sample fetch functions ssl_x_sha1(), ssl_fc_npn(), ssl_fc_alpn(),
ssl_fc_session_id(), as well as the CLI's "show cert details" handler
used to dereference the output buffer's <data> field by casting it to
"unsigned *". But while doing this could work before 1.9, it broke
starting with commit 843b7cbe9d ("MEDIUM: chunks: make the chunk struct's
fields match the buffer struct") which merged chunks and buffers, causing
the <data> field to become a size_t. The impact is only on 64-bit platform
and depends on the endianness: on little endian, there should never be any
non-zero bits in the field as it is supposed to have been zeroed before the
call, so it shouldbe harmless; on big endian, the high part of the value
only is written instead of the lower one, often making the result appear
4 billion times larger, and making such values dropped everywhere due to
being larger than a buffer.

It seems that it would be wise to try to re-enable strict-aliasing to
catch such errors.

This must be backported till 1.9.

(cherry picked from commit 105599c1bab84f67e013a266fd846799c7075b69)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 5282c302991cb7b9fe5250c4bc7a50ca82daf49e)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 63178b8..8e5d1a2 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -6805,6 +6805,7 @@
 	X509 *crt = NULL;
 	const EVP_MD *digest;
 	int ret = 0;
+	unsigned int len = 0;
 	struct buffer *smp_trash;
 	struct connection *conn;
 	struct ssl_sock_ctx *ctx;
@@ -6828,9 +6829,8 @@
 
 	smp_trash = get_trash_chunk();
 	digest = EVP_sha1();
-	X509_digest(crt, digest, (unsigned char *) smp_trash->area,
-		    (unsigned int *)&smp_trash->data);
-
+	X509_digest(crt, digest, (unsigned char *) smp_trash->area, &len);
+	smp_trash->data = len;
 	smp->data.u.str = *smp_trash;
 	smp->data.type = SMP_T_BIN;
 	ret = 1;
@@ -7356,6 +7356,7 @@
 {
 	struct connection *conn;
 	struct ssl_sock_ctx *ctx;
+	unsigned int len = 0;
 
 	smp->flags = SMP_F_CONST;
 	smp->data.type = SMP_T_STR;
@@ -7368,12 +7369,13 @@
 
 	smp->data.u.str.area = NULL;
 	SSL_get0_next_proto_negotiated(ctx->ssl,
-	                                (const unsigned char **)&smp->data.u.str.area,
-	                                (unsigned *)&smp->data.u.str.data);
+	                               (const unsigned char **)&smp->data.u.str.area,
+	                               &len);
 
 	if (!smp->data.u.str.area)
 		return 0;
 
+	smp->data.u.str.data = len;
 	return 1;
 }
 #endif
@@ -7384,6 +7386,7 @@
 {
 	struct connection *conn;
 	struct ssl_sock_ctx *ctx;
+	unsigned int len = 0;
 
 	smp->flags = SMP_F_CONST;
 	smp->data.type = SMP_T_STR;
@@ -7397,12 +7400,13 @@
 
 	smp->data.u.str.area = NULL;
 	SSL_get0_alpn_selected(ctx->ssl,
-	                         (const unsigned char **)&smp->data.u.str.area,
-	                         (unsigned *)&smp->data.u.str.data);
+	                       (const unsigned char **)&smp->data.u.str.area,
+	                       &len);
 
 	if (!smp->data.u.str.area)
 		return 0;
 
+	smp->data.u.str.data = len;
 	return 1;
 }
 #endif
@@ -7446,6 +7450,7 @@
 	                                    smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
 	SSL_SESSION *ssl_sess;
 	struct ssl_sock_ctx *ctx;
+	unsigned int len = 0;
 
 	smp->flags = SMP_F_CONST;
 	smp->data.type = SMP_T_BIN;
@@ -7458,11 +7463,11 @@
 	if (!ssl_sess)
 		return 0;
 
-	smp->data.u.str.area = (char *)SSL_SESSION_get_id(ssl_sess,
-							  (unsigned int *)&smp->data.u.str.data);
+	smp->data.u.str.area = (char *)SSL_SESSION_get_id(ssl_sess, &len);
 	if (!smp->data.u.str.area || !smp->data.u.str.data)
 		return 0;
 
+	smp->data.u.str.data = len;
 	return 1;
 }
 #endif