X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fsrc%2Ftls-gnu.c;h=34ebc0903114a5414ac8c0c48bc2a8b46cdf2a6c;hb=b1c673ddfac7f322a62786cd4aae8b5b30ba69e8;hp=6cd9bf75bf1eb3e4963549b83545c92a243aa135;hpb=d85cdeb5e554b59bf4c43c54461409c15c6ee9c5;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index 6cd9bf75b..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,8 @@ 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 tls_peerdn a string @@ -498,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; @@ -509,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 @@ -1754,11 +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 */ @@ -1778,6 +1801,8 @@ old_pool = store_pool; releases did return "TLS 1.0"; play it safe, just in case. */ for (uschar * p = state->ciphersuite; *p; p++) if (isspace(*p)) *p = '-'; + tlsp->ver = string_copyn(state->ciphersuite, + Ustrchr(state->ciphersuite, ':') - state->ciphersuite); #endif /* debug_printf("peer_status: ciphersuite %s\n", state->ciphersuite); */ @@ -2258,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); @@ -2281,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 } @@ -2503,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 @@ -2972,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) { @@ -3084,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); @@ -3298,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 */