X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/5b195d6b9592fcef09b0b3b31390e73226deffc9..17ba0f52b8df4e6ece849deac1b9d6b88bdc26c6:/src/src/tls-gnu.c diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index eaec862aa..34ebc0903 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -74,6 +74,12 @@ require current GnuTLS, then we'll drop support for the ancient libraries). # define GNUTLS_AUTO_GLOBAL_INIT # define GNUTLS_AUTO_PKCS11_MANUAL #endif +#if (GNUTLS_VERSION_NUMBER >= 0x030404) \ + || (GNUTLS_VERSION_NUMBER >= 0x030311) && (GNUTLS_VERSION_NUMBER & 0xffff00 == 0x030300) +# ifndef DISABLE_OCSP +# define EXIM_HAVE_OCSP +# endif +#endif #if GNUTLS_VERSION_NUMBER >= 0x030500 # define SUPPORT_GNUTLS_KEYLOG #endif @@ -127,6 +133,12 @@ builtin_macro_create_var(US"_RESUME_DECODE", RESUME_DECODE_STRING ); # ifdef EXIM_HAVE_TLS1_3 builtin_macro_create(US"_HAVE_TLS1_3"); # endif +# ifdef EXIM_HAVE_OCSP +builtin_macro_create(US"_HAVE_TLS_OCSP"); +# endif +# ifdef SUPPORT_SRV_OCSP_STACK +builtin_macro_create(US"_HAVE_TLS_OCSP_LIST"); +# endif } #else @@ -155,7 +167,7 @@ Some of these correspond to variables in globals.c; those variables will be set to point to content in one of these instances, as appropriate for the stage of the process lifetime. -Not handled here: global tls_channelbinding_b64. +Not handled here: global tlsp->tls_channelbinding. */ typedef struct exim_gnutls_state { @@ -467,7 +479,7 @@ Sets: tls_active fd tls_bits strength indicator tls_certificate_verified bool indicator - tls_channelbinding_b64 for some SASL mechanisms + tls_channelbinding for some SASL mechanisms tls_ver a string tls_cipher a string tls_peercert pointer to library internal @@ -499,10 +511,10 @@ tlsp->certificate_verified = state->peer_cert_verified; tlsp->dane_verified = state->peer_dane_verified; #endif -/* note that tls_channelbinding_b64 is not saved to the spool file, since it's +/* note that tls_channelbinding is not saved to the spool file, since it's only available for use for authenticators while this TLS session is running. */ -tls_channelbinding_b64 = NULL; +tlsp->channelbinding = NULL; #ifdef HAVE_GNUTLS_SESSION_CHANNEL_BINDING channel.data = NULL; channel.size = 0; @@ -510,11 +522,15 @@ if ((rc = gnutls_session_channel_binding(state->session, GNUTLS_CB_TLS_UNIQUE, & { DEBUG(D_tls) debug_printf("Channel binding error: %s\n", gnutls_strerror(rc)); } else { + /* Declare the taintedness of the binding info. On server, untainted; on + client, tainted - being the Finish msg from the server. */ + old_pool = store_pool; store_pool = POOL_PERM; - tls_channelbinding_b64 = b64encode(CUS channel.data, (int)channel.size); + tlsp->channelbinding = b64encode_taint(CUS channel.data, (int)channel.size, + !!state->host); store_pool = old_pool; - DEBUG(D_tls) debug_printf("Have channel bindings cached for possible auth usage.\n"); + DEBUG(D_tls) debug_printf("Have channel bindings cached for possible auth usage\n"); } #endif @@ -1755,12 +1771,17 @@ old_pool = store_pool; /* debug_printf("peer_status: gnutls_session_get_desc %s\n", s); */ for (s++; (c = *s) && c != ')'; s++) g = string_catn(g, s, 1); + tlsp->ver = string_copyn(g->s, g->ptr); + for (uschar * p = US tlsp->ver; *p; p++) + if (*p == '-') { *p = '\0'; break; } /* TLS1.0-PKIX -> TLS1.0 */ + g = string_catn(g, US":", 1); if (*s) s++; /* now on _ between groups */ while ((c = *s)) { - for (*++s && ++s; (c = *s) && c != ')'; s++) g = string_catn(g, c == '-' ? US"_" : s, 1); + for (*++s && ++s; (c = *s) && c != ')'; s++) + g = string_catn(g, c == '-' ? US"_" : s, 1); /* now on ) closing group */ if ((c = *s) && *++s == '-') g = string_catn(g, US"__", 2); /* now on _ between groups */ @@ -2262,17 +2283,17 @@ post_handshake_debug(exim_gnutls_state_st * state) #ifdef SUPPORT_GNUTLS_SESS_DESC debug_printf("%s\n", gnutls_session_get_desc(state->session)); #endif -#ifdef SUPPORT_GNUTLS_KEYLOG +#ifdef SUPPORT_GNUTLS_KEYLOG # ifdef EXIM_HAVE_TLS1_3 if (gnutls_protocol_get_version(state->session) < GNUTLS_TLS1_3) -#else +# else if (TRUE) -#endif +# endif { gnutls_datum_t c, s; gstring * gc, * gs; - /* we only want the client random and the master secret */ + /* For TLS1.2 we only want the client random and the master secret */ gnutls_session_get_random(state->session, &c, &s); gnutls_session_get_master_secret(state->session, &s); gc = ddump(&c); @@ -2285,7 +2306,8 @@ else " add SSLKEYLOGFILE to keep_environment in the exim config\n" " run exim as root\n" " if using sudo, add SSLKEYLOGFILE to env_keep in /etc/sudoers\n" - " (works for TLS1.2 also, and saves cut-paste into file)\n"); + " (works for TLS1.2 also, and saves cut-paste into file)" + " Trying to use add_environment for this will not work\n"); #endif } @@ -2507,6 +2529,11 @@ if (rc != GNUTLS_E_SUCCESS) return FAIL; } +#ifdef GNUTLS_SFLAGS_EXT_MASTER_SECRET +if (gnutls_session_get_flags(state->session) & GNUTLS_SFLAGS_EXT_MASTER_SECRET) + tls_in.ext_master_secret = TRUE; +#endif + #ifdef EXPERIMENTAL_TLS_RESUME tls_server_resume_posthandshake(state); #endif @@ -2976,6 +3003,11 @@ if (!verify_certificate(state, errstr)) return FALSE; } +#ifdef GNUTLS_SFLAGS_EXT_MASTER_SECRET +if (gnutls_session_get_flags(state->session) & GNUTLS_SFLAGS_EXT_MASTER_SECRET) + tlsp->ext_master_secret = TRUE; +#endif + #ifndef DISABLE_OCSP if (request_ocsp) { @@ -3088,7 +3120,7 @@ gnutls_certificate_free_credentials(state->x509_cred); tlsp->active.sock = -1; tlsp->active.tls_ctx = NULL; /* Leave bits, peercert, cipher, peerdn, certificate_verified set, for logging */ -tls_channelbinding_b64 = NULL; +tlsp->channelbinding = NULL; if (state->xfer_buffer) store_free(state->xfer_buffer); @@ -3302,6 +3334,9 @@ Arguments: len number of bytes more more data expected soon +Calling with len zero and more unset will flush buffered writes. The buff +argument can be null for that case. + Returns: the number of bytes after a successful write, -1 after a failed write */