Skip to content

Commit

Permalink
crypto: require gnutls >= 3.1.18 for building QEMU
Browse files Browse the repository at this point in the history
gnutls 3.0.0 was released in 2011 and all the distros that are build
target platforms for QEMU [1] include it:

  RHEL-7: 3.1.18
  Debian (Stretch): 3.5.8
  Debian (Jessie): 3.3.8
  OpenBSD (ports): 3.5.18
  FreeBSD (ports): 3.5.18
  OpenSUSE Leap 15: 3.6.2
  Ubuntu (Xenial): 3.4.10
  macOS (Homebrew): 3.5.19

Based on this, it is reasonable to require gnutls >= 3.1.18 in QEMU
which allows for all conditional version checks in the code to be
removed.

[1] https://qemu.weilnetz.de/doc/qemu-doc.html#Supported-build-platforms

Reviewed-by: Eric Blake <[email protected]>
Signed-off-by: Daniel P. Berrangé <[email protected]>
  • Loading branch information
berrange committed Oct 19, 2018
1 parent 2ec24af commit a072240
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 153 deletions.
135 changes: 40 additions & 95 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,6 @@ gtk=""
gtk_gl="no"
tls_priority="NORMAL"
gnutls=""
gnutls_rnd=""
nettle=""
nettle_kdf="no"
gcrypt=""
Expand Down Expand Up @@ -2666,90 +2665,39 @@ fi
##########################################
# GNUTLS probe

gnutls_works() {
# Unfortunately some distros have bad pkg-config information for gnutls
# such that it claims to exist but you get a compiler error if you try
# to use the options returned by --libs. Specifically, Ubuntu for --static
# builds doesn't work:
# https://bugs.launchpad.net/ubuntu/+source/gnutls26/+bug/1478035
#
# So sanity check the cflags/libs before assuming gnutls can be used.
if ! $pkg_config --exists "gnutls"; then
return 1
fi

write_c_skeleton
compile_prog "$($pkg_config --cflags gnutls)" "$($pkg_config --libs gnutls)"
}

gnutls_gcrypt=no
gnutls_nettle=no
if test "$gnutls" != "no"; then
if gnutls_works; then
if $pkg_config --exists "gnutls >= 3.1.18"; then
gnutls_cflags=$($pkg_config --cflags gnutls)
gnutls_libs=$($pkg_config --libs gnutls)
libs_softmmu="$gnutls_libs $libs_softmmu"
libs_tools="$gnutls_libs $libs_tools"
QEMU_CFLAGS="$QEMU_CFLAGS $gnutls_cflags"
gnutls="yes"

# gnutls_rnd requires >= 2.11.0
if $pkg_config --exists "gnutls >= 2.11.0"; then
gnutls_rnd="yes"
else
gnutls_rnd="no"
fi

if $pkg_config --exists 'gnutls >= 3.0'; then
gnutls_gcrypt=no
gnutls_nettle=yes
elif $pkg_config --exists 'gnutls >= 2.12'; then
case $($pkg_config --libs --static gnutls) in
*gcrypt*)
gnutls_gcrypt=yes
gnutls_nettle=no
;;
*nettle*)
gnutls_gcrypt=no
gnutls_nettle=yes
;;
*)
gnutls_gcrypt=yes
gnutls_nettle=no
;;
esac
else
gnutls_gcrypt=yes
gnutls_nettle=no
fi
elif test "$gnutls" = "yes"; then
feature_not_found "gnutls" "Install gnutls devel"
feature_not_found "gnutls" "Install gnutls devel >= 3.1.18"
else
gnutls="no"
gnutls_rnd="no"
fi
else
gnutls_rnd="no"
fi


# If user didn't give a --disable/enable-gcrypt flag,
# then mark as disabled if user requested nettle
# explicitly, or if gnutls links to nettle
# explicitly
if test -z "$gcrypt"
then
if test "$nettle" = "yes" || test "$gnutls_nettle" = "yes"
if test "$nettle" = "yes"
then
gcrypt="no"
fi
fi

# If user didn't give a --disable/enable-nettle flag,
# then mark as disabled if user requested gcrypt
# explicitly, or if gnutls links to gcrypt
# explicitly
if test -z "$nettle"
then
if test "$gcrypt" = "yes" || test "$gnutls_gcrypt" = "yes"
if test "$gcrypt" = "yes"
then
nettle="no"
fi
Expand All @@ -2773,6 +2721,40 @@ has_libgcrypt_config() {
return 0
}


if test "$nettle" != "no"; then
if $pkg_config --exists "nettle"; then
nettle_cflags=$($pkg_config --cflags nettle)
nettle_libs=$($pkg_config --libs nettle)
nettle_version=$($pkg_config --modversion nettle)
libs_softmmu="$nettle_libs $libs_softmmu"
libs_tools="$nettle_libs $libs_tools"
QEMU_CFLAGS="$QEMU_CFLAGS $nettle_cflags"
nettle="yes"

cat > $TMPC << EOF
#include <stddef.h>
#include <nettle/pbkdf2.h>
int main(void) {
pbkdf2_hmac_sha256(8, NULL, 1000, 8, NULL, 8, NULL);
return 0;
}
EOF
if test -z "$gcrypt"; then
gcrypt="no"
fi
if compile_prog "$nettle_cflags" "$nettle_libs" ; then
nettle_kdf=yes
fi
else
if test "$nettle" = "yes"; then
feature_not_found "nettle" "Install nettle devel"
else
nettle="no"
fi
fi
fi

if test "$gcrypt" != "no"; then
if has_libgcrypt_config; then
gcrypt_cflags=$(libgcrypt-config --cflags)
Expand All @@ -2788,9 +2770,6 @@ if test "$gcrypt" != "no"; then
libs_tools="$gcrypt_libs $libs_tools"
QEMU_CFLAGS="$QEMU_CFLAGS $gcrypt_cflags"
gcrypt="yes"
if test -z "$nettle"; then
nettle="no"
fi

cat > $TMPC << EOF
#include <gcrypt.h>
Expand Down Expand Up @@ -2827,36 +2806,6 @@ EOF
fi


if test "$nettle" != "no"; then
if $pkg_config --exists "nettle"; then
nettle_cflags=$($pkg_config --cflags nettle)
nettle_libs=$($pkg_config --libs nettle)
nettle_version=$($pkg_config --modversion nettle)
libs_softmmu="$nettle_libs $libs_softmmu"
libs_tools="$nettle_libs $libs_tools"
QEMU_CFLAGS="$QEMU_CFLAGS $nettle_cflags"
nettle="yes"

cat > $TMPC << EOF
#include <stddef.h>
#include <nettle/pbkdf2.h>
int main(void) {
pbkdf2_hmac_sha256(8, NULL, 1000, 8, NULL, 8, NULL);
return 0;
}
EOF
if compile_prog "$nettle_cflags" "$nettle_libs" ; then
nettle_kdf=yes
fi
else
if test "$nettle" = "yes"; then
feature_not_found "nettle" "Install nettle devel"
else
nettle="no"
fi
fi
fi

if test "$gcrypt" = "yes" && test "$nettle" = "yes"
then
error_exit "Only one of gcrypt & nettle can be enabled"
Expand Down Expand Up @@ -5961,7 +5910,6 @@ echo "GTK GL support $gtk_gl"
echo "VTE support $vte $(echo_version $vte $vteversion)"
echo "TLS priority $tls_priority"
echo "GNUTLS support $gnutls"
echo "GNUTLS rnd $gnutls_rnd"
echo "libgcrypt $gcrypt"
echo "libgcrypt kdf $gcrypt_kdf"
echo "nettle $nettle $(echo_version $nettle $nettle_version)"
Expand Down Expand Up @@ -6401,9 +6349,6 @@ echo "CONFIG_TLS_PRIORITY=\"$tls_priority\"" >> $config_host_mak
if test "$gnutls" = "yes" ; then
echo "CONFIG_GNUTLS=y" >> $config_host_mak
fi
if test "$gnutls_rnd" = "yes" ; then
echo "CONFIG_GNUTLS_RND=y" >> $config_host_mak
fi
if test "$gcrypt" = "yes" ; then
echo "CONFIG_GCRYPT=y" >> $config_host_mak
if test "$gcrypt_hmac" = "yes" ; then
Expand Down
4 changes: 2 additions & 2 deletions crypto/Makefile.objs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ crypto-obj-y += tlscredsx509.o
crypto-obj-y += tlssession.o
crypto-obj-y += secret.o
crypto-obj-$(CONFIG_GCRYPT) += random-gcrypt.o
crypto-obj-$(if $(CONFIG_GCRYPT),n,$(CONFIG_GNUTLS_RND)) += random-gnutls.o
crypto-obj-$(if $(CONFIG_GCRYPT),n,$(if $(CONFIG_GNUTLS_RND),n,y)) += random-platform.o
crypto-obj-$(if $(CONFIG_GCRYPT),n,$(CONFIG_GNUTLS)) += random-gnutls.o
crypto-obj-$(if $(CONFIG_GCRYPT),n,$(if $(CONFIG_GNUTLS),n,y)) += random-platform.o
crypto-obj-y += pbkdf.o
crypto-obj-$(CONFIG_NETTLE_KDF) += pbkdf-nettle.o
crypto-obj-$(if $(CONFIG_NETTLE_KDF),n,$(CONFIG_GCRYPT_KDF)) += pbkdf-gcrypt.o
Expand Down
20 changes: 1 addition & 19 deletions crypto/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,31 +37,13 @@
/* #define DEBUG_GNUTLS */

/*
* If GNUTLS is built against GCrypt then
*
* - When GNUTLS >= 2.12, we must not initialize gcrypt threading
* because GNUTLS will do that itself
* - When GNUTLS < 2.12 we must always initialize gcrypt threading
* - When GNUTLS is disabled we must always initialize gcrypt threading
*
* But....
*
* When gcrypt >= 1.6.0 we must not initialize gcrypt threading
* because gcrypt will do that itself.
*
* So we need to init gcrypt threading if
* We need to init gcrypt threading if
*
* - gcrypt < 1.6.0
* AND
* - gnutls < 2.12
* OR
* - gnutls is disabled
*
*/

#if (defined(CONFIG_GCRYPT) && \
(!defined(CONFIG_GNUTLS) || \
(LIBGNUTLS_VERSION_NUMBER < 0x020c00)) && \
(!defined(GCRYPT_VERSION_NUMBER) || \
(GCRYPT_VERSION_NUMBER < 0x010600)))
#define QCRYPTO_INIT_GCRYPT_THREADS
Expand Down
21 changes: 0 additions & 21 deletions crypto/tlscredsx509.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,6 @@ qcrypto_tls_creds_check_cert_times(gnutls_x509_crt_t cert,
}


#if LIBGNUTLS_VERSION_NUMBER >= 2
/*
* The gnutls_x509_crt_get_basic_constraints function isn't
* available in GNUTLS 1.0.x branches. This isn't critical
* though, since gnutls_certificate_verify_peers2 will do
* pretty much the same check at runtime, so we can just
* disable this code
*/
static int
qcrypto_tls_creds_check_cert_basic_constraints(QCryptoTLSCredsX509 *creds,
gnutls_x509_crt_t cert,
Expand Down Expand Up @@ -130,7 +122,6 @@ qcrypto_tls_creds_check_cert_basic_constraints(QCryptoTLSCredsX509 *creds,

return 0;
}
#endif


static int
Expand Down Expand Up @@ -299,14 +290,12 @@ qcrypto_tls_creds_check_cert(QCryptoTLSCredsX509 *creds,
return -1;
}

#if LIBGNUTLS_VERSION_NUMBER >= 2
if (qcrypto_tls_creds_check_cert_basic_constraints(creds,
cert, certFile,
isServer, isCA,
errp) < 0) {
return -1;
}
#endif

if (qcrypto_tls_creds_check_cert_key_usage(creds,
cert, certFile,
Expand Down Expand Up @@ -615,7 +604,6 @@ qcrypto_tls_creds_x509_load(QCryptoTLSCredsX509 *creds,
}

if (cert != NULL && key != NULL) {
#if LIBGNUTLS_VERSION_NUMBER >= 0x030111
char *password = NULL;
if (creds->passwordid) {
password = qcrypto_secret_lookup_as_utf8(creds->passwordid,
Expand All @@ -630,15 +618,6 @@ qcrypto_tls_creds_x509_load(QCryptoTLSCredsX509 *creds,
password,
0);
g_free(password);
#else /* LIBGNUTLS_VERSION_NUMBER < 0x030111 */
if (creds->passwordid) {
error_setg(errp, "PKCS8 decryption requires GNUTLS >= 3.1.11");
goto cleanup;
}
ret = gnutls_certificate_set_x509_key_file(creds->data,
cert, key,
GNUTLS_X509_FMT_PEM);
#endif
if (ret < 0) {
error_setg(errp, "Cannot load certificate '%s' & key '%s': %s",
cert, key, gnutls_strerror(ret));
Expand Down
8 changes: 1 addition & 7 deletions crypto/tlssession.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,7 @@ qcrypto_tls_session_pull(void *opaque, void *buf, size_t len)
}

#define TLS_PRIORITY_ADDITIONAL_ANON "+ANON-DH"

#if GNUTLS_VERSION_MAJOR >= 3
#define TLS_ECDHE_PSK "+ECDHE-PSK:"
#else
#define TLS_ECDHE_PSK ""
#endif
#define TLS_PRIORITY_ADDITIONAL_PSK TLS_ECDHE_PSK "+DHE-PSK:+PSK"
#define TLS_PRIORITY_ADDITIONAL_PSK "+ECDHE-PSK:+DHE-PSK:+PSK"

QCryptoTLSSession *
qcrypto_tls_session_new(QCryptoTLSCreds *creds,
Expand Down
3 changes: 1 addition & 2 deletions tests/crypto-tls-x509-helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@
#include <gnutls/x509.h>

#if !(defined WIN32) && \
defined(CONFIG_TASN1) && \
(LIBGNUTLS_VERSION_NUMBER >= 0x020600)
defined(CONFIG_TASN1)
# define QCRYPTO_HAVE_TLS_TEST_SUPPORT
#endif

Expand Down
8 changes: 1 addition & 7 deletions tests/test-crypto-tlscredsx509.c
Original file line number Diff line number Diff line change
Expand Up @@ -283,14 +283,8 @@ int main(int argc, char **argv)
true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL,
0, 0);

/* Technically a CA cert with basic constraints
* key purpose == key signing + non-critical should
* be rejected. GNUTLS < 3.1 does not reject it and
* we don't anticipate them changing this behaviour
*/
TLS_TEST_REG(badca1, true, cacert4req.filename, servercert4req.filename,
(GNUTLS_VERSION_MAJOR == 3 && GNUTLS_VERSION_MINOR >= 1) ||
GNUTLS_VERSION_MAJOR > 3);
true);
TLS_TEST_REG(badca2, true,
cacert5req.filename, servercert5req.filename, true);
TLS_TEST_REG(badca3, true,
Expand Down

0 comments on commit a072240

Please sign in to comment.