{
static uschar cipherbuf[256];
uschar *ver;
-int bits, c, kx, mac;
+int c, kx, mac;
+#ifdef GNUTLS_CB_TLS_UNIQUE
+int rc;
+gnutls_datum_t channel;
+#endif
ver = string_copy(
US gnutls_protocol_get_name(gnutls_protocol_get_version(session)));
if (Ustrncmp(ver, "TLS ", 4) == 0) ver[3] = '-'; /* Don't want space */
c = gnutls_cipher_get(session);
-bits = gnutls_cipher_get_key_size(c);
+/* returns size in "bytes" */
+tls_bits = gnutls_cipher_get_key_size(c) * 8;
mac = gnutls_mac_get(session);
kx = gnutls_kx_get(session);
string_format(cipherbuf, sizeof(cipherbuf), "%s:%s:%u", ver,
- gnutls_cipher_suite_get_name(kx, c, mac), bits);
+ gnutls_cipher_suite_get_name(kx, c, mac), tls_bits);
tls_cipher = cipherbuf;
DEBUG(D_tls) debug_printf("cipher: %s\n", cipherbuf);
+
+if (tls_channelbinding_b64)
+ free(tls_channelbinding_b64);
+tls_channelbinding_b64 = NULL;
+
+#ifdef GNUTLS_CB_TLS_UNIQUE
+channel = { NULL, 0 };
+rc = gnutls_session_channel_binding(session, GNUTLS_CB_TLS_UNIQUE, &channel);
+if (rc) {
+ DEBUG(D_tls) debug_printf("Channel binding error: %s\n", gnutls_strerror(rc));
+} else {
+ tls_channelbinding_b64 = auth_b64encode(channel.data, (int)channel.size);
+ DEBUG(D_tls) debug_printf("Have channel bindings cached for possible auth usage.\n");
+}
+#endif
}
dhparam DH parameter file
certificate certificate file
privatekey private key file
+ sni TLS SNI to send to remote host
verify_certs file for certificate verify
verify_crl CRL for verify
require_ciphers list of allowed ciphers or NULL
int
tls_client_start(int fd, host_item *host, address_item *addr, uschar *dhparam,
- uschar *certificate, uschar *privatekey, uschar *verify_certs,
- uschar *verify_crl, uschar *require_ciphers, uschar *require_mac,
+ uschar *certificate, uschar *privatekey, uschar *sni ARG_UNUSED,
+ uschar *verify_certs, uschar *verify_crl,
+ uschar *require_ciphers, uschar *require_mac,
uschar *require_kx, uschar *require_proto, int timeout)
{
const gnutls_datum *server_certs;