From e8ca0c5e16a6887691ee3db739abfdba25e0d578 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 3 Aug 2017 17:57:24 -0700 Subject: [PATCH] Fix version numbers for some GnuTLS features Problem reported by Glenn Morris (Bug#27708#58). * src/gnutls.c (HAVE_GNUTLS_X509_SYSTEM_TRUST): New macro. Use it instead of low-level version number checks. (HAVE_GNUTLS_AEAD): Move here from gnutls.h, and rename from HAVE_GNUTLS3_AEAD. All uses changed. Indent preprocessor lines. * src/gnutls.h (HAVE_GNUTLS3_CIPHER, HAVE_GNUTLS3_DIGEST) (HAVE_GNUTLS3_HMAC): Remove, since these were available before GnuTLS 3.0.0 and the code checks them only if HAVE_GNUTLS3 is defined. Remove all uses; this simplifies the code a bit. --- src/gnutls.c | 370 ++++++++++++++++++++++++--------------------------- src/gnutls.h | 16 --- 2 files changed, 171 insertions(+), 215 deletions(-) diff --git a/src/gnutls.c b/src/gnutls.c index 59694074e16..188f995979e 100644 --- a/src/gnutls.c +++ b/src/gnutls.c @@ -26,22 +26,36 @@ along with GNU Emacs. If not, see . */ #include "coding.h" #include "buffer.h" -#ifdef HAVE_GNUTLS +#if 0x030014 <= GNUTLS_VERSION_NUMBER +# define HAVE_GNUTLS_X509_SYSTEM_TRUST +#endif -#ifdef WINDOWSNT -#include -#include "w32.h" +/* Although AEAD support started in GnuTLS 3.4.0 and works in 3.5.14, + it was broken through at least GnuTLS 3.4.10; see: + https://lists.gnu.org/archive/html/emacs-devel/2017-07/msg00992.html + The relevant fix seems to have been made in GnuTLS 3.5.1; see: + https://gitlab.com/gnutls/gnutls/commit/568935848dd6b82b9315d8b6c529d00e2605e03d + So, require 3.5.1. */ +#if 0x030501 <= GNUTLS_VERSION_NUMBER +# define HAVE_GNUTLS_AEAD #endif +#ifdef HAVE_GNUTLS + +# ifdef WINDOWSNT +# include +# include "w32.h" +# endif + static bool emacs_gnutls_handle_error (gnutls_session_t, int); static bool gnutls_global_initialized; static void gnutls_log_function (int, const char *); static void gnutls_log_function2 (int, const char *, const char *); -#ifdef HAVE_GNUTLS3 +# ifdef HAVE_GNUTLS3 static void gnutls_audit_log_function (gnutls_session_t, const char *); -#endif +# endif enum extra_peer_verification { @@ -49,7 +63,7 @@ enum extra_peer_verification }; -#ifdef WINDOWSNT +# ifdef WINDOWSNT DEF_DLL_FN (gnutls_alert_description_t, gnutls_alert_get, (gnutls_session_t)); @@ -74,12 +88,10 @@ DEF_DLL_FN (int, gnutls_certificate_set_x509_crl_file, DEF_DLL_FN (int, gnutls_certificate_set_x509_key_file, (gnutls_certificate_credentials_t, const char *, const char *, gnutls_x509_crt_fmt_t)); -# if ((GNUTLS_VERSION_MAJOR \ - + (GNUTLS_VERSION_MINOR > 0 || GNUTLS_VERSION_PATCH >= 20)) \ - > 3) +# ifdef HAVE_GNUTLS_X509_SYSTEM_TRUST DEF_DLL_FN (int, gnutls_certificate_set_x509_system_trust, (gnutls_certificate_credentials_t)); -# endif +# endif DEF_DLL_FN (int, gnutls_certificate_set_x509_trust_file, (gnutls_certificate_credentials_t, const char *, gnutls_x509_crt_fmt_t)); @@ -96,9 +108,9 @@ DEF_DLL_FN (int, gnutls_dh_get_prime_bits, (gnutls_session_t)); DEF_DLL_FN (int, gnutls_error_is_fatal, (int)); DEF_DLL_FN (int, gnutls_global_init, (void)); DEF_DLL_FN (void, gnutls_global_set_log_function, (gnutls_log_func)); -# ifdef HAVE_GNUTLS3 +# ifdef HAVE_GNUTLS3 DEF_DLL_FN (void, gnutls_global_set_audit_log_function, (gnutls_audit_log_func)); -# endif +# endif DEF_DLL_FN (void, gnutls_global_set_log_level, (int)); DEF_DLL_FN (int, gnutls_handshake, (gnutls_session_t)); DEF_DLL_FN (int, gnutls_init, (gnutls_session_t *, unsigned int)); @@ -172,14 +184,13 @@ DEF_DLL_FN (const char *, gnutls_cipher_get_name, DEF_DLL_FN (gnutls_mac_algorithm_t, gnutls_mac_get, (gnutls_session_t)); DEF_DLL_FN (const char *, gnutls_mac_get_name, (gnutls_mac_algorithm_t)); -# ifdef HAVE_GNUTLS3 +# ifdef HAVE_GNUTLS3 DEF_DLL_FN (int, gnutls_rnd, (gnutls_rnd_level_t, void *, size_t)); DEF_DLL_FN (const gnutls_mac_algorithm_t *, gnutls_mac_list, (void)); DEF_DLL_FN (size_t, gnutls_mac_get_nonce_size, (gnutls_mac_algorithm_t)); DEF_DLL_FN (size_t, gnutls_mac_get_key_size, (gnutls_mac_algorithm_t)); DEF_DLL_FN (const gnutls_digest_algorithm_t *, gnutls_digest_list, (void)); DEF_DLL_FN (const char *, gnutls_digest_get_name, (gnutls_digest_algorithm_t)); -# ifdef HAVE_GNUTLS3_CIPHER DEF_DLL_FN (gnutls_cipher_algorithm_t *, gnutls_cipher_list, (void)); DEF_DLL_FN (int, gnutls_cipher_get_iv_size, (gnutls_cipher_algorithm_t)); DEF_DLL_FN (size_t, gnutls_cipher_get_key_size, (gnutls_cipher_algorithm_t)); @@ -194,7 +205,7 @@ DEF_DLL_FN (int, gnutls_cipher_encrypt2, DEF_DLL_FN (void, gnutls_cipher_deinit, (gnutls_cipher_hd_t)); DEF_DLL_FN (int, gnutls_cipher_decrypt2, (gnutls_cipher_hd_t, const void *, size_t, void *, size_t)); -# ifdef HAVE_GNUTLS3_AEAD +# ifdef HAVE_GNUTLS_AEAD DEF_DLL_FN (int, gnutls_aead_cipher_init, (gnutls_aead_cipher_hd_t *, gnutls_cipher_algorithm_t, const gnutls_datum_t *)); @@ -205,25 +216,20 @@ DEF_DLL_FN (int, gnutls_aead_cipher_encrypt, DEF_DLL_FN (int, gnutls_aead_cipher_decrypt, (gnutls_aead_cipher_hd_t, const void *, size_t, const void *, size_t, size_t, const void *, size_t, void *, size_t *)); -# endif /* HAVE_GNUTLS3_AEAD */ -# ifdef HAVE_GNUTLS3_HMAC +# endif DEF_DLL_FN (int, gnutls_hmac_init, (gnutls_hmac_hd_t *, gnutls_mac_algorithm_t, const void *, size_t)); DEF_DLL_FN (int, gnutls_hmac_get_len, (gnutls_mac_algorithm_t)); DEF_DLL_FN (int, gnutls_hmac, (gnutls_hmac_hd_t, const void *, size_t)); DEF_DLL_FN (void, gnutls_hmac_deinit, (gnutls_hmac_hd_t, void *)); DEF_DLL_FN (void, gnutls_hmac_output, (gnutls_hmac_hd_t, void *)); -# endif /* HAVE_GNUTLS3_HMAC */ -# endif /* HAVE_GNUTLS3_CIPHER */ -# ifdef HAVE_GNUTLS3_DIGEST DEF_DLL_FN (int, gnutls_hash_init, (gnutls_hash_hd_t *, gnutls_digest_algorithm_t)); DEF_DLL_FN (int, gnutls_hash_get_len, (gnutls_digest_algorithm_t)); DEF_DLL_FN (int, gnutls_hash, (gnutls_hash_hd_t, const void *, size_t)); DEF_DLL_FN (void, gnutls_hash_deinit, (gnutls_hash_hd_t, void *)); DEF_DLL_FN (void, gnutls_hash_output, (gnutls_hash_hd_t, void *)); -# endif /* HAVE_GNUTLS3_DIGEST */ -# endif /* HAVE_GNUTLS3 */ +# endif /* HAVE_GNUTLS3 */ static bool @@ -249,11 +255,9 @@ init_gnutls_functions (void) LOAD_DLL_FN (library, gnutls_certificate_set_verify_flags); LOAD_DLL_FN (library, gnutls_certificate_set_x509_crl_file); LOAD_DLL_FN (library, gnutls_certificate_set_x509_key_file); -# if ((GNUTLS_VERSION_MAJOR \ - + (GNUTLS_VERSION_MINOR > 0 || GNUTLS_VERSION_PATCH >= 20)) \ - > 3) +# ifdef HAVE_GNUTLS_X509_SYSTEM_TRUST LOAD_DLL_FN (library, gnutls_certificate_set_x509_system_trust); -# endif +# endif LOAD_DLL_FN (library, gnutls_certificate_set_x509_trust_file); LOAD_DLL_FN (library, gnutls_certificate_type_get); LOAD_DLL_FN (library, gnutls_certificate_verify_peers2); @@ -264,9 +268,9 @@ init_gnutls_functions (void) LOAD_DLL_FN (library, gnutls_error_is_fatal); LOAD_DLL_FN (library, gnutls_global_init); LOAD_DLL_FN (library, gnutls_global_set_log_function); -# ifdef HAVE_GNUTLS3 +# ifdef HAVE_GNUTLS3 LOAD_DLL_FN (library, gnutls_global_set_audit_log_function); -# endif +# endif LOAD_DLL_FN (library, gnutls_global_set_log_level); LOAD_DLL_FN (library, gnutls_handshake); LOAD_DLL_FN (library, gnutls_init); @@ -309,14 +313,13 @@ init_gnutls_functions (void) LOAD_DLL_FN (library, gnutls_cipher_get_name); LOAD_DLL_FN (library, gnutls_mac_get); LOAD_DLL_FN (library, gnutls_mac_get_name); -# ifdef HAVE_GNUTLS3 +# ifdef HAVE_GNUTLS3 LOAD_DLL_FN (library, gnutls_rnd); LOAD_DLL_FN (library, gnutls_mac_list); LOAD_DLL_FN (library, gnutls_mac_get_nonce_size); LOAD_DLL_FN (library, gnutls_mac_get_key_size); LOAD_DLL_FN (library, gnutls_digest_list); LOAD_DLL_FN (library, gnutls_digest_get_name); -# ifdef HAVE_GNUTLS3_CIPHER LOAD_DLL_FN (library, gnutls_cipher_list); LOAD_DLL_FN (library, gnutls_cipher_get_iv_size); LOAD_DLL_FN (library, gnutls_cipher_get_key_size); @@ -327,28 +330,23 @@ init_gnutls_functions (void) LOAD_DLL_FN (library, gnutls_cipher_encrypt2); LOAD_DLL_FN (library, gnutls_cipher_deinit); LOAD_DLL_FN (library, gnutls_cipher_decrypt2); -# ifdef HAVE_GNUTLS3_AEAD +# ifdef HAVE_GNUTLS_AEAD LOAD_DLL_FN (library, gnutls_aead_cipher_init); LOAD_DLL_FN (library, gnutls_aead_cipher_deinit); LOAD_DLL_FN (library, gnutls_aead_cipher_encrypt); LOAD_DLL_FN (library, gnutls_aead_cipher_decrypt); # endif -# ifdef HAVE_GNUTLS3_HMAC LOAD_DLL_FN (library, gnutls_hmac_init); LOAD_DLL_FN (library, gnutls_hmac_get_len); LOAD_DLL_FN (library, gnutls_hmac); LOAD_DLL_FN (library, gnutls_hmac_deinit); LOAD_DLL_FN (library, gnutls_hmac_output); -# endif /* HAVE_GNUTLS3_HMAC */ -# endif /* HAVE_GNUTLS3_CIPHER */ -# ifdef HAVE_GNUTLS3_DIGEST LOAD_DLL_FN (library, gnutls_hash_init); LOAD_DLL_FN (library, gnutls_hash_get_len); LOAD_DLL_FN (library, gnutls_hash); LOAD_DLL_FN (library, gnutls_hash_deinit); LOAD_DLL_FN (library, gnutls_hash_output); -# endif -# endif /* HAVE_GNUTLS3 */ +# endif /* HAVE_GNUTLS3 */ max_log_level = global_gnutls_log_level; @@ -361,111 +359,105 @@ init_gnutls_functions (void) return 1; } -# define gnutls_alert_get fn_gnutls_alert_get -# define gnutls_alert_get_name fn_gnutls_alert_get_name -# define gnutls_anon_allocate_client_credentials fn_gnutls_anon_allocate_client_credentials -# define gnutls_anon_free_client_credentials fn_gnutls_anon_free_client_credentials -# define gnutls_bye fn_gnutls_bye -# define gnutls_certificate_allocate_credentials fn_gnutls_certificate_allocate_credentials -# define gnutls_certificate_free_credentials fn_gnutls_certificate_free_credentials -# define gnutls_certificate_get_peers fn_gnutls_certificate_get_peers -# define gnutls_certificate_set_verify_flags fn_gnutls_certificate_set_verify_flags -# define gnutls_certificate_set_x509_crl_file fn_gnutls_certificate_set_x509_crl_file -# define gnutls_certificate_set_x509_key_file fn_gnutls_certificate_set_x509_key_file -# define gnutls_certificate_set_x509_system_trust fn_gnutls_certificate_set_x509_system_trust -# define gnutls_certificate_set_x509_trust_file fn_gnutls_certificate_set_x509_trust_file -# define gnutls_certificate_type_get fn_gnutls_certificate_type_get -# define gnutls_certificate_verify_peers2 fn_gnutls_certificate_verify_peers2 -# define gnutls_cipher_get fn_gnutls_cipher_get -# define gnutls_cipher_get_name fn_gnutls_cipher_get_name -# define gnutls_credentials_set fn_gnutls_credentials_set -# define gnutls_deinit fn_gnutls_deinit -# define gnutls_dh_get_prime_bits fn_gnutls_dh_get_prime_bits -# define gnutls_dh_set_prime_bits fn_gnutls_dh_set_prime_bits -# define gnutls_error_is_fatal fn_gnutls_error_is_fatal -# define gnutls_global_init fn_gnutls_global_init -# define gnutls_global_set_audit_log_function fn_gnutls_global_set_audit_log_function -# define gnutls_global_set_log_function fn_gnutls_global_set_log_function -# define gnutls_global_set_log_level fn_gnutls_global_set_log_level -# define gnutls_handshake fn_gnutls_handshake -# define gnutls_init fn_gnutls_init -# define gnutls_kx_get fn_gnutls_kx_get -# define gnutls_kx_get_name fn_gnutls_kx_get_name -# define gnutls_mac_get fn_gnutls_mac_get -# define gnutls_mac_get_name fn_gnutls_mac_get_name -# define gnutls_pk_algorithm_get_name fn_gnutls_pk_algorithm_get_name -# define gnutls_pk_bits_to_sec_param fn_gnutls_pk_bits_to_sec_param -# define gnutls_priority_set_direct fn_gnutls_priority_set_direct -# define gnutls_protocol_get_name fn_gnutls_protocol_get_name -# define gnutls_protocol_get_version fn_gnutls_protocol_get_version -# define gnutls_record_check_pending fn_gnutls_record_check_pending -# define gnutls_record_recv fn_gnutls_record_recv -# define gnutls_record_send fn_gnutls_record_send -# define gnutls_sec_param_get_name fn_gnutls_sec_param_get_name -# define gnutls_server_name_set fn_gnutls_server_name_set -# define gnutls_sign_get_name fn_gnutls_sign_get_name -# define gnutls_strerror fn_gnutls_strerror -# define gnutls_transport_set_errno fn_gnutls_transport_set_errno -# define gnutls_transport_set_ptr2 fn_gnutls_transport_set_ptr2 -# define gnutls_transport_set_pull_function fn_gnutls_transport_set_pull_function -# define gnutls_transport_set_push_function fn_gnutls_transport_set_push_function -# define gnutls_x509_crt_check_hostname fn_gnutls_x509_crt_check_hostname -# define gnutls_x509_crt_check_issuer fn_gnutls_x509_crt_check_issuer -# define gnutls_x509_crt_deinit fn_gnutls_x509_crt_deinit -# define gnutls_x509_crt_get_activation_time fn_gnutls_x509_crt_get_activation_time -# define gnutls_x509_crt_get_dn fn_gnutls_x509_crt_get_dn -# define gnutls_x509_crt_get_expiration_time fn_gnutls_x509_crt_get_expiration_time -# define gnutls_x509_crt_get_fingerprint fn_gnutls_x509_crt_get_fingerprint -# define gnutls_x509_crt_get_issuer_dn fn_gnutls_x509_crt_get_issuer_dn -# define gnutls_x509_crt_get_issuer_unique_id fn_gnutls_x509_crt_get_issuer_unique_id -# define gnutls_x509_crt_get_key_id fn_gnutls_x509_crt_get_key_id -# define gnutls_x509_crt_get_pk_algorithm fn_gnutls_x509_crt_get_pk_algorithm -# define gnutls_x509_crt_get_serial fn_gnutls_x509_crt_get_serial -# define gnutls_x509_crt_get_signature_algorithm fn_gnutls_x509_crt_get_signature_algorithm -# define gnutls_x509_crt_get_subject_unique_id fn_gnutls_x509_crt_get_subject_unique_id -# define gnutls_x509_crt_get_version fn_gnutls_x509_crt_get_version -# define gnutls_x509_crt_import fn_gnutls_x509_crt_import -# define gnutls_x509_crt_init fn_gnutls_x509_crt_init -# ifdef HAVE_GNUTLS3 -# define gnutls_rnd fn_gnutls_rnd -# define gnutls_mac_list fn_gnutls_mac_list -# define gnutls_mac_get_nonce_size fn_gnutls_mac_get_nonce_size -# define gnutls_mac_get_key_size fn_gnutls_mac_get_key_size -# define gnutls_digest_list fn_gnutls_digest_list -# define gnutls_digest_get_name fn_gnutls_digest_get_name -# ifdef HAVE_GNUTLS3_CIPHER -# define gnutls_cipher_list fn_gnutls_cipher_list -# define gnutls_cipher_get_iv_size fn_gnutls_cipher_get_iv_size -# define gnutls_cipher_get_key_size fn_gnutls_cipher_get_key_size -# define gnutls_cipher_get_block_size fn_gnutls_cipher_get_block_size -# define gnutls_cipher_get_tag_size fn_gnutls_cipher_get_tag_size -# define gnutls_cipher_init fn_gnutls_cipher_init -# define gnutls_cipher_set_iv fn_gnutls_cipher_set_iv -# define gnutls_cipher_encrypt2 fn_gnutls_cipher_encrypt2 -# define gnutls_cipher_decrypt2 fn_gnutls_cipher_decrypt2 -# define gnutls_cipher_deinit fn_gnutls_cipher_deinit -# ifdef HAVE_GNUTLS3_AEAD -# define gnutls_aead_cipher_encrypt fn_gnutls_aead_cipher_encrypt -# define gnutls_aead_cipher_decrypt fn_gnutls_aead_cipher_decrypt -# define gnutls_aead_cipher_init fn_gnutls_aead_cipher_init -# define gnutls_aead_cipher_deinit fn_gnutls_aead_cipher_deinit -# endif /* HAVE_GNUTLS3_AEAD */ -# ifdef HAVE_GNUTLS3_HMAC -# define gnutls_hmac_init fn_gnutls_hmac_init -# define gnutls_hmac_get_len fn_gnutls_hmac_get_len -# define gnutls_hmac fn_gnutls_hmac -# define gnutls_hmac_deinit fn_gnutls_hmac_deinit -# define gnutls_hmac_output fn_gnutls_hmac_output -# endif /* HAVE_GNUTLS3_HMAC */ -# endif /* HAVE_GNUTLS3_CIPHER */ -# ifdef HAVE_GNUTLS3_DIGEST -# define gnutls_hash_init fn_gnutls_hash_init -# define gnutls_hash_get_len fn_gnutls_hash_get_len -# define gnutls_hash fn_gnutls_hash -# define gnutls_hash_deinit fn_gnutls_hash_deinit -# define gnutls_hash_output fn_gnutls_hash_output -# endif -# endif /* HAVE_GNUTLS3 */ +# define gnutls_alert_get fn_gnutls_alert_get +# define gnutls_alert_get_name fn_gnutls_alert_get_name +# define gnutls_anon_allocate_client_credentials fn_gnutls_anon_allocate_client_credentials +# define gnutls_anon_free_client_credentials fn_gnutls_anon_free_client_credentials +# define gnutls_bye fn_gnutls_bye +# define gnutls_certificate_allocate_credentials fn_gnutls_certificate_allocate_credentials +# define gnutls_certificate_free_credentials fn_gnutls_certificate_free_credentials +# define gnutls_certificate_get_peers fn_gnutls_certificate_get_peers +# define gnutls_certificate_set_verify_flags fn_gnutls_certificate_set_verify_flags +# define gnutls_certificate_set_x509_crl_file fn_gnutls_certificate_set_x509_crl_file +# define gnutls_certificate_set_x509_key_file fn_gnutls_certificate_set_x509_key_file +# define gnutls_certificate_set_x509_system_trust fn_gnutls_certificate_set_x509_system_trust +# define gnutls_certificate_set_x509_trust_file fn_gnutls_certificate_set_x509_trust_file +# define gnutls_certificate_type_get fn_gnutls_certificate_type_get +# define gnutls_certificate_verify_peers2 fn_gnutls_certificate_verify_peers2 +# define gnutls_cipher_get fn_gnutls_cipher_get +# define gnutls_cipher_get_name fn_gnutls_cipher_get_name +# define gnutls_credentials_set fn_gnutls_credentials_set +# define gnutls_deinit fn_gnutls_deinit +# define gnutls_dh_get_prime_bits fn_gnutls_dh_get_prime_bits +# define gnutls_dh_set_prime_bits fn_gnutls_dh_set_prime_bits +# define gnutls_error_is_fatal fn_gnutls_error_is_fatal +# define gnutls_global_init fn_gnutls_global_init +# define gnutls_global_set_audit_log_function fn_gnutls_global_set_audit_log_function +# define gnutls_global_set_log_function fn_gnutls_global_set_log_function +# define gnutls_global_set_log_level fn_gnutls_global_set_log_level +# define gnutls_handshake fn_gnutls_handshake +# define gnutls_init fn_gnutls_init +# define gnutls_kx_get fn_gnutls_kx_get +# define gnutls_kx_get_name fn_gnutls_kx_get_name +# define gnutls_mac_get fn_gnutls_mac_get +# define gnutls_mac_get_name fn_gnutls_mac_get_name +# define gnutls_pk_algorithm_get_name fn_gnutls_pk_algorithm_get_name +# define gnutls_pk_bits_to_sec_param fn_gnutls_pk_bits_to_sec_param +# define gnutls_priority_set_direct fn_gnutls_priority_set_direct +# define gnutls_protocol_get_name fn_gnutls_protocol_get_name +# define gnutls_protocol_get_version fn_gnutls_protocol_get_version +# define gnutls_record_check_pending fn_gnutls_record_check_pending +# define gnutls_record_recv fn_gnutls_record_recv +# define gnutls_record_send fn_gnutls_record_send +# define gnutls_sec_param_get_name fn_gnutls_sec_param_get_name +# define gnutls_server_name_set fn_gnutls_server_name_set +# define gnutls_sign_get_name fn_gnutls_sign_get_name +# define gnutls_strerror fn_gnutls_strerror +# define gnutls_transport_set_errno fn_gnutls_transport_set_errno +# define gnutls_transport_set_ptr2 fn_gnutls_transport_set_ptr2 +# define gnutls_transport_set_pull_function fn_gnutls_transport_set_pull_function +# define gnutls_transport_set_push_function fn_gnutls_transport_set_push_function +# define gnutls_x509_crt_check_hostname fn_gnutls_x509_crt_check_hostname +# define gnutls_x509_crt_check_issuer fn_gnutls_x509_crt_check_issuer +# define gnutls_x509_crt_deinit fn_gnutls_x509_crt_deinit +# define gnutls_x509_crt_get_activation_time fn_gnutls_x509_crt_get_activation_time +# define gnutls_x509_crt_get_dn fn_gnutls_x509_crt_get_dn +# define gnutls_x509_crt_get_expiration_time fn_gnutls_x509_crt_get_expiration_time +# define gnutls_x509_crt_get_fingerprint fn_gnutls_x509_crt_get_fingerprint +# define gnutls_x509_crt_get_issuer_dn fn_gnutls_x509_crt_get_issuer_dn +# define gnutls_x509_crt_get_issuer_unique_id fn_gnutls_x509_crt_get_issuer_unique_id +# define gnutls_x509_crt_get_key_id fn_gnutls_x509_crt_get_key_id +# define gnutls_x509_crt_get_pk_algorithm fn_gnutls_x509_crt_get_pk_algorithm +# define gnutls_x509_crt_get_serial fn_gnutls_x509_crt_get_serial +# define gnutls_x509_crt_get_signature_algorithm fn_gnutls_x509_crt_get_signature_algorithm +# define gnutls_x509_crt_get_subject_unique_id fn_gnutls_x509_crt_get_subject_unique_id +# define gnutls_x509_crt_get_version fn_gnutls_x509_crt_get_version +# define gnutls_x509_crt_import fn_gnutls_x509_crt_import +# define gnutls_x509_crt_init fn_gnutls_x509_crt_init +# ifdef HAVE_GNUTLS3 +# define gnutls_rnd fn_gnutls_rnd +# define gnutls_mac_list fn_gnutls_mac_list +# define gnutls_mac_get_nonce_size fn_gnutls_mac_get_nonce_size +# define gnutls_mac_get_key_size fn_gnutls_mac_get_key_size +# define gnutls_digest_list fn_gnutls_digest_list +# define gnutls_digest_get_name fn_gnutls_digest_get_name +# define gnutls_cipher_list fn_gnutls_cipher_list +# define gnutls_cipher_get_iv_size fn_gnutls_cipher_get_iv_size +# define gnutls_cipher_get_key_size fn_gnutls_cipher_get_key_size +# define gnutls_cipher_get_block_size fn_gnutls_cipher_get_block_size +# define gnutls_cipher_get_tag_size fn_gnutls_cipher_get_tag_size +# define gnutls_cipher_init fn_gnutls_cipher_init +# define gnutls_cipher_set_iv fn_gnutls_cipher_set_iv +# define gnutls_cipher_encrypt2 fn_gnutls_cipher_encrypt2 +# define gnutls_cipher_decrypt2 fn_gnutls_cipher_decrypt2 +# define gnutls_cipher_deinit fn_gnutls_cipher_deinit +# ifdef HAVE_GNUTLS_AEAD +# define gnutls_aead_cipher_encrypt fn_gnutls_aead_cipher_encrypt +# define gnutls_aead_cipher_decrypt fn_gnutls_aead_cipher_decrypt +# define gnutls_aead_cipher_init fn_gnutls_aead_cipher_init +# define gnutls_aead_cipher_deinit fn_gnutls_aead_cipher_deinit +# endif +# define gnutls_hmac_init fn_gnutls_hmac_init +# define gnutls_hmac_get_len fn_gnutls_hmac_get_len +# define gnutls_hmac fn_gnutls_hmac +# define gnutls_hmac_deinit fn_gnutls_hmac_deinit +# define gnutls_hmac_output fn_gnutls_hmac_output +# define gnutls_hash_init fn_gnutls_hash_init +# define gnutls_hash_get_len fn_gnutls_hash_get_len +# define gnutls_hash fn_gnutls_hash +# define gnutls_hash_deinit fn_gnutls_hash_deinit +# define gnutls_hash_output fn_gnutls_hash_output +# endif /* HAVE_GNUTLS3 */ /* This wrapper is called from fns.c, which doesn't know about the LOAD_DLL_FN stuff above. */ @@ -475,7 +467,7 @@ w32_gnutls_rnd (gnutls_rnd_level_t level, void *data, size_t len) return gnutls_rnd (level, data, len); } -#endif /* WINDOWSNT */ +# endif /* WINDOWSNT */ /* Report memory exhaustion if ERR is an out-of-memory indication. */ @@ -489,7 +481,7 @@ check_memory_full (int err) memory_full (0); } -#ifdef HAVE_GNUTLS3 +# ifdef HAVE_GNUTLS3 /* Log a simple audit message. */ static void gnutls_audit_log_function (gnutls_session_t session, const char *string) @@ -499,7 +491,7 @@ gnutls_audit_log_function (gnutls_session_t session, const char *string) message ("gnutls.c: [audit] %s", string); } } -#endif +# endif /* Log a simple message. */ static void @@ -552,7 +544,7 @@ gnutls_try_handshake (struct Lisp_Process *proc) return ret; } -#ifndef WINDOWSNT +# ifndef WINDOWSNT static int emacs_gnutls_nonblock_errno (gnutls_transport_ptr_t ptr) { @@ -560,13 +552,13 @@ emacs_gnutls_nonblock_errno (gnutls_transport_ptr_t ptr) switch (err) { -# ifdef _AIX +# ifdef _AIX /* This is taken from the GnuTLS system_errno function circa 2016; see . */ case 0: errno = EAGAIN; /* Fall through. */ -# endif +# endif case EINPROGRESS: case ENOTCONN: return EAGAIN; @@ -575,7 +567,7 @@ emacs_gnutls_nonblock_errno (gnutls_transport_ptr_t ptr) return err; } } -#endif /* !WINDOWSNT */ +# endif /* !WINDOWSNT */ static int emacs_gnutls_handshake (struct Lisp_Process *proc) @@ -587,7 +579,7 @@ emacs_gnutls_handshake (struct Lisp_Process *proc) if (proc->gnutls_initstage < GNUTLS_STAGE_TRANSPORT_POINTERS_SET) { -#ifdef WINDOWSNT +# ifdef WINDOWSNT /* On W32 we cannot transfer socket handles between different runtime libraries, so we tell GnuTLS to use our special push/pull functions. */ @@ -596,7 +588,7 @@ emacs_gnutls_handshake (struct Lisp_Process *proc) (gnutls_transport_ptr_t) proc); gnutls_transport_set_push_function (state, &emacs_gnutls_push); gnutls_transport_set_pull_function (state, &emacs_gnutls_pull); -#else +# else /* This is how GnuTLS takes sockets: as file descriptors passed in. For an Emacs process socket, infd and outfd are the same but we use this two-argument version for clarity. */ @@ -606,7 +598,7 @@ emacs_gnutls_handshake (struct Lisp_Process *proc) if (proc->is_non_blocking_client) gnutls_transport_set_errno_function (state, emacs_gnutls_nonblock_errno); -#endif +# endif proc->gnutls_initstage = GNUTLS_STAGE_TRANSPORT_POINTERS_SET; } @@ -620,13 +612,13 @@ emacs_gnutls_record_check_pending (gnutls_session_t state) return gnutls_record_check_pending (state); } -#ifdef WINDOWSNT +# ifdef WINDOWSNT void emacs_gnutls_transport_set_errno (gnutls_session_t state, int err) { gnutls_transport_set_errno (state, err); } -#endif +# endif ptrdiff_t emacs_gnutls_write (struct Lisp_Process *proc, const char *buf, ptrdiff_t nbyte) @@ -732,10 +724,10 @@ emacs_gnutls_handle_error (gnutls_session_t session, int err) /* Mostly ignore "The TLS connection was non-properly terminated" message which just means that the peer closed the connection. */ -#ifdef HAVE_GNUTLS3 +# ifdef HAVE_GNUTLS3 if (err == GNUTLS_E_PREMATURE_TERMINATION) level = 3; -#endif +# endif GNUTLS_LOG2 (level, max_log_level, "fatal error:", str); ret = false; @@ -1300,7 +1292,7 @@ gnutls_ip_address_p (char *string) return true; } -#if 0 +# if 0 /* Deinitialize global GnuTLS state. See also `gnutls-global-init'. */ static Lisp_Object @@ -1313,7 +1305,7 @@ emacs_gnutls_global_deinit (void) return gnutls_make_error (GNUTLS_E_SUCCESS); } -#endif +# endif static void ATTRIBUTE_FORMAT_PRINTF (2, 3) boot_error (struct Lisp_Process *p, const char *m, ...) @@ -1585,9 +1577,9 @@ one trustfile (usually a CA bundle). */) if (TYPE_RANGED_INTEGERP (int, loglevel)) { gnutls_global_set_log_function (gnutls_log_function); -#ifdef HAVE_GNUTLS3 +# ifdef HAVE_GNUTLS3 gnutls_global_set_audit_log_function (gnutls_audit_log_function); -#endif +# endif gnutls_global_set_log_level (XINT (loglevel)); max_log_level = XINT (loglevel); XPROCESS (proc)->gnutls_log_level = max_log_level; @@ -1649,8 +1641,7 @@ one trustfile (usually a CA bundle). */) int file_format = GNUTLS_X509_FMT_PEM; Lisp_Object tail; -#if GNUTLS_VERSION_MAJOR + \ - (GNUTLS_VERSION_MINOR > 0 || GNUTLS_VERSION_PATCH >= 20) > 3 +# ifdef HAVE_GNUTLS_X509_SYSTEM_TRUST ret = gnutls_certificate_set_x509_system_trust (x509_cred); if (ret < GNUTLS_E_SUCCESS) { @@ -1658,7 +1649,7 @@ one trustfile (usually a CA bundle). */) GNUTLS_LOG2i (4, max_log_level, "setting system trust failed with code ", ret); } -#endif +# endif for (tail = trustfiles; CONSP (tail); tail = XCDR (tail)) { @@ -1668,12 +1659,12 @@ one trustfile (usually a CA bundle). */) GNUTLS_LOG2 (1, max_log_level, "setting the trustfile: ", SSDATA (trustfile)); trustfile = ENCODE_FILE (trustfile); -#ifdef WINDOWSNT +# ifdef WINDOWSNT /* Since GnuTLS doesn't support UTF-8 or UTF-16 encoded file names on Windows, we need to re-encode the file name using the current ANSI codepage. */ trustfile = ansi_encode_filename (trustfile); -#endif +# endif ret = gnutls_certificate_set_x509_trust_file (x509_cred, SSDATA (trustfile), @@ -1698,9 +1689,9 @@ one trustfile (usually a CA bundle). */) GNUTLS_LOG2 (1, max_log_level, "setting the CRL file: ", SSDATA (crlfile)); crlfile = ENCODE_FILE (crlfile); -#ifdef WINDOWSNT +# ifdef WINDOWSNT crlfile = ansi_encode_filename (crlfile); -#endif +# endif ret = gnutls_certificate_set_x509_crl_file (x509_cred, SSDATA (crlfile), file_format); @@ -1727,10 +1718,10 @@ one trustfile (usually a CA bundle). */) SSDATA (certfile)); keyfile = ENCODE_FILE (keyfile); certfile = ENCODE_FILE (certfile); -#ifdef WINDOWSNT +# ifdef WINDOWSNT keyfile = ansi_encode_filename (keyfile); certfile = ansi_encode_filename (certfile); -#endif +# endif ret = gnutls_certificate_set_x509_key_file (x509_cred, SSDATA (certfile), SSDATA (keyfile), file_format); @@ -1755,10 +1746,10 @@ one trustfile (usually a CA bundle). */) GNUTLS_LOG (1, max_log_level, "gnutls_init"); int gnutls_flags = GNUTLS_CLIENT; -#ifdef GNUTLS_NONBLOCK +# ifdef GNUTLS_NONBLOCK if (XPROCESS (proc)->is_non_blocking_client) gnutls_flags |= GNUTLS_NONBLOCK; -#endif +# endif ret = gnutls_init (&state, gnutls_flags); XPROCESS (proc)->gnutls_state = state; if (ret < GNUTLS_E_SUCCESS) @@ -1852,7 +1843,6 @@ The alist key is the cipher name. */) { Lisp_Object ciphers = Qnil; -#ifdef HAVE_GNUTLS3_CIPHER const gnutls_cipher_algorithm_t *gciphers = gnutls_cipher_list (); for (ptrdiff_t pos = 0; gciphers[pos] != 0; pos++) { @@ -1886,7 +1876,6 @@ The alist key is the cipher name. */) ciphers = Fcons (cp, ciphers); } -#endif return ciphers; } @@ -1899,7 +1888,7 @@ gnutls_symmetric_aead (bool encrypting, gnutls_cipher_algorithm_t gca, const char *idata, ptrdiff_t isize, Lisp_Object aead_auth) { -#ifdef HAVE_GNUTLS3_AEAD +# ifdef HAVE_GNUTLS_AEAD const char *desc = encrypting ? "encrypt" : "decrypt"; Lisp_Object actual_iv = make_unibyte_string (vdata, vsize); @@ -1969,10 +1958,10 @@ gnutls_symmetric_aead (bool encrypting, gnutls_cipher_algorithm_t gca, SAFE_FREE (); return list2 (output, actual_iv); -#else +# else printmax_t print_gca = gca; error ("GnuTLS AEAD cipher %"pMd" is invalid or not found", print_gca); -#endif +# endif } static Lisp_Object @@ -2181,7 +2170,6 @@ name. */) (void) { Lisp_Object mac_algorithms = Qnil; -#ifdef HAVE_GNUTLS3_HMAC const gnutls_mac_algorithm_t *macs = gnutls_mac_list (); for (ptrdiff_t pos = 0; macs[pos] != 0; pos++) { @@ -2204,7 +2192,6 @@ name. */) make_number (gnutls_mac_get_nonce_size (gma))); mac_algorithms = Fcons (mp, mac_algorithms); } -#endif return mac_algorithms; } @@ -2218,7 +2205,6 @@ method name. */) (void) { Lisp_Object digest_algorithms = Qnil; -#ifdef HAVE_GNUTLS3_DIGEST const gnutls_digest_algorithm_t *digests = gnutls_digest_list (); for (ptrdiff_t pos = 0; digests[pos] != 0; pos++) { @@ -2236,7 +2222,6 @@ method name. */) digest_algorithms = Fcons (mp, digest_algorithms); } -#endif return digest_algorithms; } @@ -2423,25 +2408,17 @@ GnuTLS AEAD ciphers : the list will contain `AEAD-ciphers'. */) # ifdef HAVE_GNUTLS3 capabilities = Fcons (intern("gnutls3"), capabilities); - -# ifdef HAVE_GNUTLS3_DIGEST capabilities = Fcons (intern("digests"), capabilities); -# endif - -# ifdef HAVE_GNUTLS3_CIPHER capabilities = Fcons (intern("ciphers"), capabilities); -# ifdef HAVE_GNUTLS3_AEAD +# ifdef HAVE_GNUTLS_AEAD capabilities = Fcons (intern("AEAD-ciphers"), capabilities); -# endif +# endif -# ifdef HAVE_GNUTLS3_HMAC capabilities = Fcons (intern("macs"), capabilities); -# endif -# endif /* HAVE_GNUTLS3_CIPHER */ # endif /* HAVE_GNUTLS3 */ -#ifdef WINDOWSNT +# ifdef WINDOWSNT Lisp_Object found = Fassq (Qgnutls, Vlibrary_cache); if (CONSP (found)) return XCDR (found); @@ -2452,15 +2429,10 @@ GnuTLS AEAD ciphers : the list will contain `AEAD-ciphers'. */) Vlibrary_cache = Fcons (Fcons (Qgnutls, status), Vlibrary_cache); return status; } -#else /* !WINDOWSNT */ +# endif /* WINDOWSNT */ +#endif /* HAVE_GNUTLS */ return capabilities; - -#endif /* WINDOWSNT */ - -#else /* !HAVE_GNUTLS */ - return Qnil; -#endif /* HAVE_GNUTLS */ } void diff --git a/src/gnutls.h b/src/gnutls.h index 8fe4ac3e427..9323cd1aeff 100644 --- a/src/gnutls.h +++ b/src/gnutls.h @@ -28,22 +28,6 @@ along with GNU Emacs. If not, see . */ # include #endif -#if 0x030400 <= GNUTLS_VERSION_NUMBER -# define HAVE_GNUTLS3_CIPHER -# define HAVE_GNUTLS3_DIGEST -# define HAVE_GNUTLS3_HMAC -#endif - -/* Although AEAD support started in GnuTLS 3.4.0 and works in 3.5.14, - it was broken through at least GnuTLS 3.4.10; see: - https://lists.gnu.org/archive/html/emacs-devel/2017-07/msg00992.html - The relevant fix seems to have been made in GnuTLS 3.5.1; see: - https://gitlab.com/gnutls/gnutls/commit/568935848dd6b82b9315d8b6c529d00e2605e03d - So use 3.5.1 for now. */ -#if 0x030501 <= GNUTLS_VERSION_NUMBER -# define HAVE_GNUTLS3_AEAD -#endif - #include "lisp.h" /* This limits the attempts to handshake per process (connection). It -- 2.39.2