Le 16/10/2015 22:42, Willy Tarreau a écrit :
Hi Christopher,

Marcus (in CC) reported that 1.6 doesn't build anymore on SuSE 11
(which uses openssl 0.9.8). After some digging, we found that it
is caused by the absence of EVP_PKEY_get_default_digest_nid()
which was introduced in 1.0.0 and which was introduced by this
patch :

   commit 7969a33a01c3a70e48cddf36ea5a66710bd7a995
   Author: Christopher Faulet <cfau...@qualys.com>
   Date:   Fri Oct 9 11:15:03 2015 +0200

     MINOR: ssl: Add support for EC for the CA used to sign generated 
certificate

     This is done by adding EVP_PKEY_EC type in supported types for the CA 
privat
     key when we get the message digest used to sign a generated X509 
certificate
     So now, we support DSA, RSA and EC private keys.

     And to be sure, when the type of the private key is not directly supported,
     get its default message digest using the function
     'EVP_PKEY_get_default_digest_nid'.

     We also use the key of the default certificate instead of generated it. So 
w
     are sure to use the same key type instead of always using a RSA key.

Interestingly, not all 0.9.8 will see the same problem since SNI is not
enabled by default, it requires a build option. This explains why on my
old PC I didn't get this problem with the same version.

I initially thought it would just be a matter of adding a #if on the
openssl version but it doesn't appear that easy given that the previous
code was different, so I have no idea how to fix this. Do you have any
idea ? Probably we can have a block of code instead of EVP_PKEY_... on
older versions and that will be fine. I even wonder if EC was supported
on 0.9.8.

It's unfortunate that we managed to break things just a few days before
the release with code that looked obviously right :-(

Thanks for any insight.


Hi Willy,

Damned! I generated a huge amount of disturbances with my paches! Really sorry for that.

Add a #ifdef to check the OpenSSL version seems to be a good fix. I don't know if there is a workaround to do the same than EVP_PKEY_get_default_digest_nid() for old OpenSSL versions.

This function is used to get default signature digest associated to the private key used to sign generated X509 certificates. It is called when the private key differs than EVP_PKEY_RSA, EVP_PKEY_DSA and EVP_PKEY_EC. It should be enough for most of cases (maybe all cases ?).

By the way, I attached a patch to fix the bug.

Regards,
--
Christopher Faulet
>From 76e79a8c8a98474f3caf701b75370f50729516b2 Mon Sep 17 00:00:00 2001
From: Christopher Faulet <cfau...@qualys.com>
Date: Mon, 19 Oct 2015 13:59:24 +0200
Subject: [PATCH 2/2] BUILD: ssl: fix build error introduced in commit 7969a3
 with OpenSSL < 1.0.0

The function 'EVP_PKEY_get_default_digest_nid()' was introduced in OpenSSL
1.0.0. So for older version of OpenSSL, compiled with the SNI support, the
HAProxy compilation fails with the following error:

src/ssl_sock.c: In function 'ssl_sock_do_create_cert':
src/ssl_sock.c:1096:7: warning: implicit declaration of function 'EVP_PKEY_get_default_digest_nid'
   if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
[...]
src/ssl_sock.c:1096: undefined reference to `EVP_PKEY_get_default_digest_nid'
collect2: error: ld returned 1 exit status
Makefile:760: recipe for target 'haproxy' failed
make: *** [haproxy] Error 1

So we must add a #ifdef to check the OpenSSL version (>= 1.0.0) to use this
function. It is used to get default signature digest associated to the private
key used to sign generated X509 certificates. It is called when the private key
differs than EVP_PKEY_RSA, EVP_PKEY_DSA and EVP_PKEY_EC. It should be enough for
most of cases.
---
 src/ssl_sock.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 35a3edf..7c82464 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -1091,12 +1091,16 @@ ssl_sock_do_create_cert(const char *servername, unsigned int serial,
 	else if (EVP_PKEY_type (capkey->type) == EVP_PKEY_EC)
 		digest = EVP_sha256();
 	else {
+#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
 		int nid;
 
 		if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
 			goto mkcert_error;
 		if (!(digest = EVP_get_digestbynid(nid)))
 			goto mkcert_error;
+#else
+		goto mkcert_error;
+#endif
 	}
 
 	if (!(X509_sign(newcrt, capkey, digest)))
-- 
2.4.3

Reply via email to