#if GNUTLS_VERSION_NUMBER >= 0x03010a
# define SUPPORT_GNUTLS_SESS_DESC
#endif
+#if GNUTLS_VERSION_NUMBER >= 0x030300
+# define GNUTLS_AUTO_GLOBAL_INIT
+# define GNUTLS_AUTO_PKCS11_MANUAL
+#endif
#if GNUTLS_VERSION_NUMBER >= 0x030500
# define SUPPORT_GNUTLS_KEYLOG
#endif
{
DEBUG(D_tls) debug_printf("GnuTLS global init required.\n");
-#ifdef HAVE_GNUTLS_PKCS11
+#if defined(HAVE_GNUTLS_PKCS11) && !defined(GNUTLS_AUTO_PKCS11_MANUAL)
/* By default, gnutls_global_init will init PKCS11 support in auto mode,
which loads modules from a config file, which sounds good and may be wanted
by some sysadmin, but also means in common configurations that GNOME keyring
return tls_error_gnu(US"gnutls_pkcs11_init", rc, host, errstr);
#endif
+#ifndef GNUTLS_AUTO_GLOBAL_INIT
if ((rc = gnutls_global_init()))
return tls_error_gnu(US"gnutls_global_init", rc, host, errstr);
+#endif
#if EXIM_GNUTLS_LIBRARY_LOG_LEVEL >= 0
DEBUG(D_tls)
DEBUG(D_tls) debug_printf("initialising GnuTLS as a server\n");
-if ((rc = tls_init(NULL, tls_certificate, tls_privatekey,
- NULL, tls_verify_certificates, tls_crl,
- require_ciphers, &state, &tls_in, errstr)) != OK) return rc;
+ {
+#ifdef MEASURE_TIMING
+ struct timeval t0;
+ gettimeofday(&t0, NULL);
+#endif
+
+ if ((rc = tls_init(NULL, tls_certificate, tls_privatekey,
+ NULL, tls_verify_certificates, tls_crl,
+ require_ciphers, &state, &tls_in, errstr)) != OK) return rc;
+
+#ifdef MEASURE_TIMING
+ report_time_since(&t0, US"server tls_init (delta)");
+#endif
+ }
#ifdef EXPERIMENTAL_TLS_RESUME
tls_server_resume_prehandshake(state);
if (!cipher_list)
cipher_list = ob->tls_require_ciphers;
-if (tls_init(host, ob->tls_certificate, ob->tls_privatekey,
- ob->tls_sni, ob->tls_verify_certificates, ob->tls_crl,
- cipher_list, &state, tlsp, errstr) != OK)
- return FALSE;
+ {
+#ifdef MEASURE_TIMING
+ struct timeval t0;
+ gettimeofday(&t0, NULL);
+#endif
+
+ if (tls_init(host, ob->tls_certificate, ob->tls_privatekey,
+ ob->tls_sni, ob->tls_verify_certificates, ob->tls_crl,
+ cipher_list, &state, tlsp, errstr) != OK)
+ return FALSE;
+
+#ifdef MEASURE_TIMING
+ report_time_since(&t0, US"client tls_init (delta)");
+#endif
+ }
{
int dh_min_bits = ob->tls_dh_min_bits;
const char *errpos;
uschar * dummy_errstr;
-#define validate_check_rc(Label) do { \
+#ifdef GNUTLS_AUTO_GLOBAL_INIT
+# define validate_check_rc(Label) do { \
+ if (rc != GNUTLS_E_SUCCESS) { if (exim_gnutls_base_init_done) \
+ return string_sprintf("%s failed: %s", (Label), gnutls_strerror(rc)); } } while (0)
+# define return_deinit(Label) do { return (Label); } while (0)
+#else
+# define validate_check_rc(Label) do { \
if (rc != GNUTLS_E_SUCCESS) { if (exim_gnutls_base_init_done) gnutls_global_deinit(); \
- return string_sprintf("%s failed: %s", (Label), gnutls_strerror(rc)); } } while (0)
-#define return_deinit(Label) do { gnutls_global_deinit(); return (Label); } while (0)
+ return string_sprintf("%s failed: %s", (Label), gnutls_strerror(rc)); } } while (0)
+# define return_deinit(Label) do { gnutls_global_deinit(); return (Label); } while (0)
+#endif
if (exim_gnutls_base_init_done)
log_write(0, LOG_MAIN|LOG_PANIC,
"already initialised GnuTLS, Exim developer bug");
-#ifdef HAVE_GNUTLS_PKCS11
+#if defined(HAVE_GNUTLS_PKCS11) && !defined(GNUTLS_AUTO_PKCS11_MANUAL)
if (!gnutls_allow_auto_pkcs11)
{
rc = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL);
validate_check_rc(US"gnutls_pkcs11_init");
}
#endif
+#ifndef GNUTLS_AUTO_GLOBAL_INIT
rc = gnutls_global_init();
validate_check_rc(US"gnutls_global_init()");
+#endif
exim_gnutls_base_init_done = TRUE;
if (!(tls_require_ciphers && *tls_require_ciphers))
#undef return_deinit
#undef validate_check_rc
+#ifndef GNUTLS_AUTO_GLOBAL_INIT
gnutls_global_deinit();
+#endif
return NULL;
}