static BOOL
verify_certificate(gnutls_session session, const char **error)
{
-int verify;
+int rc = -1;
uschar *dn_string = US"";
const gnutls_datum *cert;
-unsigned int cert_size = 0;
+unsigned int verify, cert_size = 0;
*error = NULL;
dn_string = string_copy_malloc(buff);
}
- verify = gnutls_certificate_verify_peers(session);
+ rc = gnutls_certificate_verify_peers2(session, &verify);
}
else
{
/* Handle the result of verification. INVALID seems to be set as well
as REVOKED, but leave the test for both. */
-if ((verify & (GNUTLS_CERT_INVALID|GNUTLS_CERT_REVOKED)) != 0)
+if ((rc < 0) || (verify & (GNUTLS_CERT_INVALID|GNUTLS_CERT_REVOKED)) != 0)
{
tls_certificate_verified = FALSE;
if (*error == NULL) *error = ((verify & GNUTLS_CERT_REVOKED) != 0)?
{
static uschar cipherbuf[256];
uschar *ver;
-int bits, c, kx, mac;
+int bits, c, kx, mac, rc;
+#ifdef GNUTLS_CB_TLS_UNIQUE
+gnutls_datum_t channel;
+#endif
ver = string_copy(
US gnutls_protocol_get_name(gnutls_protocol_get_version(session)));
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
}