Tidy input buffer handling
[exim.git] / src / src / tls-openssl.c
index 678288ca380a9a3163fabcf11fdda7ca2f01474d..830978e042bf54aa58f555feafb21a47d27a6fe2 100644 (file)
@@ -3,7 +3,7 @@
 *************************************************/
 
 /* Copyright (c) University of Cambridge 1995 - 2019 */
-/* Copyright (c) The Exim Maintainers 2020 */
+/* Copyright (c) The Exim Maintainers 2020 - 2021 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* Portions Copyright (c) The OpenSSL Project 1999 */
@@ -48,7 +48,6 @@ functions from the OpenSSL library. */
 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
 # define EXIM_HAVE_OCSP_RESP_COUNT
 # define OPENSSL_AUTO_SHA256
-# define EXIM_HAVE_ALPN
 #else
 # define EXIM_HAVE_EPHEM_RSA_KEX
 # define EXIM_HAVE_RAND_PSEUDO
@@ -81,6 +80,7 @@ change this guard and punt the issue for a while longer. */
 #  ifndef DISABLE_OCSP
 #   define EXIM_HAVE_OCSP
 #  endif
+#  define EXIM_HAVE_ALPN /* fail ret from hshake-cb is ignored by LibreSSL */
 # else
 #  define EXIM_NEED_OPENSSL_INIT
 # endif
@@ -90,6 +90,10 @@ change this guard and punt the issue for a while longer. */
 # endif
 #endif
 
+#if LIBRESSL_VERSION_NUMBER >= 0x3040000fL
+# define EXIM_HAVE_OPENSSL_CIPHER_GET_ID
+#endif
+
 #if !defined(LIBRESSL_VERSION_NUMBER) \
     || LIBRESSL_VERSION_NUMBER >= 0x20010000L
 # if !defined(OPENSSL_NO_ECDH)
@@ -307,6 +311,9 @@ builtin_macro_create(US"_TLS_BAD_MULTICERT_IN_OURCERT");
 builtin_macro_create(US"_HAVE_TLS_OCSP");
 builtin_macro_create(US"_HAVE_TLS_OCSP_LIST");
 # endif
+# ifdef EXIM_HAVE_ALPN
+builtin_macro_create(US"_HAVE_TLS_ALPN");
+# endif
 }
 #else
 
@@ -2151,8 +2158,6 @@ static int
 tls_server_alpn_cb(SSL *ssl, const uschar ** out, uschar * outlen,
   const uschar * in, unsigned int inlen, void * arg)
 {
-const exim_openssl_state_st * state = arg;
-
 server_seen_alpn = TRUE;
 DEBUG(D_tls)
   {
@@ -2177,7 +2182,7 @@ if (  inlen > 1           /* at least one name */
   for (uschar * name; name = string_nextinlist(&list, &sep, NULL, 0); )
     if (Ustrncmp(in+1, name, in[0]) == 0)
       {
-      *out = in;                       /* we checked for exactly one, so can just point to it */
+      *out = in+1;                     /* we checked for exactly one, so can just point to it */
       *outlen = inlen;
       return SSL_TLSEXT_ERR_OK;                /* use ALPN */
       }
@@ -2230,9 +2235,6 @@ if (!olist)
   const X509 * cert_sent = SSL_get_certificate(s);
   const ASN1_INTEGER * cert_serial = X509_get0_serialNumber(cert_sent);
   const BIGNUM * cert_bn = ASN1_INTEGER_to_BN(cert_serial, NULL);
-  const X509_NAME * cert_issuer = X509_get_issuer_name(cert_sent);
-  uschar * chash;
-  uint chash_len;
 
   for (; olist; olist = olist->next)
     {
@@ -2837,7 +2839,6 @@ chain_from_pem_file(const uschar * file, STACK_OF(X509) ** vp)
 {
 BIO * bp;
 STACK_OF(X509) * verify_stack = *vp;
-X509 * x;
 
 if (verify_stack)
   while (sk_X509_num(verify_stack) > 0)
@@ -3270,7 +3271,10 @@ else DEBUG(D_tls)
   const uschar * name;
   unsigned len;
   SSL_get0_alpn_selected(ssl, &name, &len);
-  debug_printf("ALPN negotiated: '%.*s'\n", (int)*name, name+1);
+  if (len && name)
+    debug_printf("ALPN negotiated: '%.*s'\n", (int)*name, name+1);
+  else
+    debug_printf("ALPN: no protocol negotiated\n");
   }
 #endif
 
@@ -3343,10 +3347,10 @@ ssl_xfer_eof = ssl_xfer_error = FALSE;
 receive_getc = tls_getc;
 receive_getbuf = tls_getbuf;
 receive_get_cache = tls_get_cache;
+receive_hasc = tls_hasc;
 receive_ungetc = tls_ungetc;
 receive_feof = tls_feof;
 receive_ferror = tls_ferror;
-receive_smtp_buffered = tls_smtp_buffered;
 
 tls_in.active.sock = fileno(smtp_out);
 tls_in.active.tls_ctx = NULL;  /* not using explicit ctx for server-side */
@@ -3887,7 +3891,7 @@ if (ob->tls_alpn)
   }
 #else
   log_write(0, LOG_MAIN, "ALPN unusable with this OpenSSL library version; ignoring \"%s\"\n",
-          ob->alpn);
+          ob->tls_alpn);
 #endif
 
 #ifdef SUPPORT_DANE
@@ -4119,6 +4123,12 @@ if (ssl_xfer_buffer_lwm >= ssl_xfer_buffer_hwm)
 return ssl_xfer_buffer[ssl_xfer_buffer_lwm++];
 }
 
+BOOL
+tls_hasc(void)
+{
+return ssl_xfer_buffer_lwm < ssl_xfer_buffer_hwm;
+}
+
 uschar *
 tls_getbuf(unsigned * len)
 {
@@ -4143,10 +4153,13 @@ return buf;
 
 
 void
-tls_get_cache(void)
+tls_get_cache(unsigned lim)
 {
 #ifndef DISABLE_DKIM
 int n = ssl_xfer_buffer_hwm - ssl_xfer_buffer_lwm;
+debug_printf("tls_get_cache\n");
+if (n > lim)
+  n = lim;
 if (n > 0)
   dkim_exim_verify_feed(ssl_xfer_buffer+ssl_xfer_buffer_lwm, n);
 #endif
@@ -4154,7 +4167,7 @@ if (n > 0)
 
 
 BOOL
-tls_could_read(void)
+tls_could_getc(void)
 {
 return ssl_xfer_buffer_lwm < ssl_xfer_buffer_hwm
     || SSL_pending(state_server.lib_state.lib_ssl) > 0;
@@ -4405,10 +4418,10 @@ if (!o_ctx)             /* server side */
   receive_getc =       smtp_getc;
   receive_getbuf =     smtp_getbuf;
   receive_get_cache =  smtp_get_cache;
+  receive_hasc =       smtp_hasc;
   receive_ungetc =     smtp_ungetc;
   receive_feof =       smtp_feof;
   receive_ferror =     smtp_ferror;
-  receive_smtp_buffered = smtp_buffered;
   tls_in.active.tls_ctx = NULL;
   tls_in.sni = NULL;
   /* Leave bits, peercert, cipher, peerdn, certificate_verified set, for logging */