+ DEBUG(D_tls) debug_printf("TLS: not preloading CRL for server\n");
+ }
+ }
+else
+ DEBUG(D_tls) debug_printf("TLS: not preloading CA bundle for server\n");
+#endif /* EXIM_HAVE_INOTIFY */
+
+/* If tls_require_ciphers is non-empty and has no $, load the
+ciphers priority cache. If unset, load with the default.
+(server-only as the client one depends on non/DANE) */
+
+if (!tls_require_ciphers || opt_set_and_noexpand(tls_require_ciphers))
+ {
+ const char * dummy_errpos;
+ DEBUG(D_tls) debug_printf("TLS: preloading cipher list for server: %s\n",
+ tls_require_ciphers);
+ if ( creds_load_pristring(&state_server, tls_require_ciphers, &dummy_errpos)
+ == OK)
+ state_server.lib_state.pri_string = TRUE;
+ }
+else
+ DEBUG(D_tls) debug_printf("TLS: not preloading cipher list for server\n");
+return lifetime;
+}
+
+
+/* Preload whatever creds are static, onto a transport. The client can then
+just copy the pointer as it starts up. */
+
+static void
+tls_client_creds_init(transport_instance * t, BOOL watch)
+{
+smtp_transport_options_block * ob = t->options_block;
+exim_gnutls_state_st tpt_dummy_state;
+host_item * dummy_host = (host_item *)1;
+uschar * dummy_errstr;
+
+if ( !exim_gnutls_base_init_done
+ && tls_g_init(&dummy_errstr) != OK)
+ return;
+
+ob->tls_preload = null_tls_preload;
+if (gnutls_certificate_allocate_credentials(
+ (struct gnutls_certificate_credentials_st **)&ob->tls_preload.x509_cred))
+ {
+ ob->tls_preload.x509_cred = NULL;
+ return;
+ }
+creds_basic_init(ob->tls_preload.x509_cred, FALSE);
+
+tpt_dummy_state.session = NULL;
+tpt_dummy_state.lib_state = ob->tls_preload;
+
+#if defined(EXIM_HAVE_INOTIFY) || defined(EXIM_HAVE_KEVENT)
+if ( opt_set_and_noexpand(ob->tls_certificate)
+ && opt_unset_or_noexpand(ob->tls_privatekey))
+ {
+ if ( !watch
+ || ( tls_set_watch(ob->tls_certificate, FALSE)
+ && tls_set_watch(ob->tls_privatekey, FALSE)
+ ) )
+ {
+ const uschar * pkey = ob->tls_privatekey;
+
+ DEBUG(D_tls)
+ debug_printf("TLS: preloading client certs for transport '%s'\n", t->name);
+
+ /* The state->lib_state.x509_cred is used for the certs load, and is the sole
+ structure element used. So we can set up a dummy. The hoat arg only
+ selects a retcode in case of fail, so any value */
+
+ if (creds_load_client_certs(&tpt_dummy_state, dummy_host,
+ ob->tls_certificate, pkey ? pkey : ob->tls_certificate,
+ &dummy_errstr) == OK)
+ ob->tls_preload.conn_certs = TRUE;
+ }
+ }
+else
+ DEBUG(D_tls)
+ debug_printf("TLS: not preloading client certs, for transport '%s'\n", t->name);
+
+/* If tls_verify_certificates is non-empty and has no $, load CAs.
+If none was configured and we can't handle "system", treat as empty. */
+
+if ( opt_set_and_noexpand(ob->tls_verify_certificates)
+#ifndef SUPPORT_SYSDEFAULT_CABUNDLE
+ && Ustrcmp(ob->tls_verify_certificates, "system") != 0
+#endif
+ )
+ {
+ if (!watch || tls_set_watch(ob->tls_verify_certificates, FALSE))
+ {
+ DEBUG(D_tls)
+ debug_printf("TLS: preloading CA bundle for transport '%s'\n", t->name);
+ if (creds_load_cabundle(&tpt_dummy_state, ob->tls_verify_certificates,
+ dummy_host, &dummy_errstr) != OK)
+ return;
+ ob->tls_preload.cabundle = TRUE;
+
+ if (opt_set_and_noexpand(ob->tls_crl))