Copyright year bumps for substantive changes 2017
[exim.git] / src / src / tls-openssl.c
index 452452df2a40c5ff3c3e58d66f7933e010ab6864..392d59dd5ac28223a9475203963a3a5473795ff4 100644 (file)
@@ -2,7 +2,7 @@
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2016 */
+/* Copyright (c) University of Cambridge 1995 - 2017 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* Portions Copyright (c) The OpenSSL Project 1999 */
@@ -83,9 +83,6 @@ functions from the OpenSSL library. */
 #   define EXIM_HAVE_ECDH
 #  endif
 #  if OPENSSL_VERSION_NUMBER >= 0x10002000L
-#   if OPENSSL_VERSION_NUMBER < 0x10100000L
-#    define EXIM_HAVE_OPENSSL_ECDH_AUTO
-#   endif
 #   define EXIM_HAVE_OPENSSL_EC_NIST2NID
 #  endif
 # endif
@@ -464,7 +461,7 @@ else
        if (rc < 0)
          {
          log_write(0, LOG_MAIN, "[%s] SSL verify error: internal error",
-               tlsp == &tls_out ? deliver_host_address : sender_host_address);
+               deliver_host_address);
          name = NULL;
          }
        break;
@@ -475,9 +472,9 @@ else
 #endif
       {
       log_write(0, LOG_MAIN,
-               "[%s] SSL verify error: certificate name mismatch: \"%s\"",
-               tlsp == &tls_out ? deliver_host_address : sender_host_address,
-               dn);
+               "[%s] SSL verify error: certificate name mismatch: "
+               "DN=\"%s\" H=\"%s\"",
+               deliver_host_address, dn, verify_cert_hostnames);
       *calledp = TRUE;
       if (!*optionalp)
        {
@@ -529,8 +526,8 @@ verify_callback_client_dane(int preverify_ok, X509_STORE_CTX * x509ctx)
 {
 X509 * cert = X509_STORE_CTX_get_current_cert(x509ctx);
 uschar dn[256];
-#ifndef DISABLE_EVENT
 int depth = X509_STORE_CTX_get_error_depth(x509ctx);
+#ifndef DISABLE_EVENT
 BOOL dummy_called, optional = FALSE;
 #endif
 
@@ -729,16 +726,32 @@ if (!expand_check(tls_eccurve, US"tls_eccurve", &exp_curve))
 if (!exp_curve || !*exp_curve)
   return TRUE;
 
-#  ifdef EXIM_HAVE_OPENSSL_ECDH_AUTO
-/* check if new enough library to support auto ECDH temp key parameter selection */
+/* "auto" needs to be handled carefully.
+ * OpenSSL <  1.0.2: we do not select anything, but fallback to prime256v1
+ * OpenSSL <  1.1.0: we have to call SSL_CTX_set_ecdh_auto
+ *                   (openssl/ssl.h defines SSL_CTRL_SET_ECDH_AUTO)
+ * OpenSSL >= 1.1.0: we do not set anything, the libray does autoselection
+ *                   https://github.com/openssl/openssl/commit/fe6ef2472db933f01b59cad82aa925736935984b
+ */
 if (Ustrcmp(exp_curve, "auto") == 0)
   {
+#if OPENSSL_VERSION_NUMBER < 0x10002000L
+  DEBUG(D_tls) debug_printf(
+    "ECDH OpenSSL < 1.0.2: temp key parameter settings: overriding \"auto\" with \"prime256v1\"\n");
+  exp_curve = "prime256v1";
+#else
+# if defined SSL_CTRL_SET_ECDH_AUTO
   DEBUG(D_tls) debug_printf(
-    "ECDH temp key parameter settings: OpenSSL 1.2+ autoselection\n");
+    "ECDH OpenSSL 1.0.2+ temp key parameter settings: autoselection\n");
   SSL_CTX_set_ecdh_auto(sctx, 1);
   return TRUE;
+# else
+  DEBUG(D_tls) debug_printf(
+    "ECDH OpenSSL 1.1.0+ temp key parameter settings: default selection\n");
+  return TRUE;
+# endif
+#endif
   }
-#  endif
 
 DEBUG(D_tls) debug_printf("ECDH: curve '%s'\n", exp_curve);
 if (  (nid = OBJ_sn2nid       (CCS exp_curve)) == NID_undef
@@ -849,7 +862,7 @@ verify_flags = OCSP_NOVERIFY; /* check sigs, but not purpose */
 OCSP_NOSIGS OCSP_NOVERIFY OCSP_NOCHAIN OCSP_NOCHECKS OCSP_NOEXPLICIT
 OCSP_TRUSTOTHER OCSP_NOINTERN */
 
-/* This does a full verify on the OCSP proof before we load it for serviing
+/* This does a full verify on the OCSP proof before we load it for serving
 up; possibly overkill - just date-checks might be nice enough.
 
 OCSP_basic_verify takes a "store" arg, but does not
@@ -866,10 +879,10 @@ function for getting a stack from a store.
 We do not free the stack since it could be needed a second time for
 SNI handling.
 
-Seperately we might try to replace using OCSP_basic_verify() - which seems to not
+Separately we might try to replace using OCSP_basic_verify() - which seems to not
 be a public interface into the OpenSSL library (there's no manual entry) - 
 But what with?  We also use OCSP_basic_verify in the client stapling callback.
-And there we NEED it; we miust verify that status... unless the
+And there we NEED it; we must verify that status... unless the
 library does it for us anyway?  */
 
 if ((i = OCSP_basic_verify(basic_response, sk, NULL, verify_flags)) < 0)
@@ -959,7 +972,7 @@ where = US"generating pkey";
 if (!(rsa = RSA_generate_key(1024, RSA_F4, NULL, NULL)))
   goto err;
 
-where = US"assiging pkey";
+where = US"assigning pkey";
 if (!EVP_PKEY_assign_RSA(pkey, rsa))
   goto err;
 
@@ -1751,7 +1764,7 @@ if (expcerts && *expcerts)
       variant.
       If a list isn't loaded into the server, but
       some verify locations are set, the server end appears to make
-      a wildcard reqest for client certs.
+      a wildcard request for client certs.
       Meanwhile, the client library as default behaviour *ignores* the list
       we send over the wire - see man SSL_CTX_set_client_cert_cb.
       Because of this, and that the dir variant is likely only used for
@@ -1846,7 +1859,7 @@ Arguments:
 
 Returns:            OK on success
                     DEFER for errors before the start of the negotiation
-                    FAIL for errors during the negotation; the server can't
+                    FAIL for errors during the negotiation; the server can't
                       continue running.
 */
 
@@ -2347,14 +2360,14 @@ return OK;
 /* This gets the next byte from the TLS input buffer. If the buffer is empty,
 it refills the buffer via the SSL reading function.
 
-Arguments:  none
+Arguments:  lim                Maximum amount to read/buffer
 Returns:    the next character or EOF
 
 Only used by the server-side TLS.
 */
 
 int
-tls_getc(void)
+tls_getc(unsigned lim)
 {
 if (ssl_xfer_buffer_lwm >= ssl_xfer_buffer_hwm)
   {
@@ -2365,7 +2378,8 @@ if (ssl_xfer_buffer_lwm >= ssl_xfer_buffer_hwm)
     ssl_xfer_buffer, ssl_xfer_buffer_size);
 
   if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
-  inbytes = SSL_read(server_ssl, CS ssl_xfer_buffer, ssl_xfer_buffer_size);
+  inbytes = SSL_read(server_ssl, CS ssl_xfer_buffer,
+                   MIN(ssl_xfer_buffer_size, lim));
   error = SSL_get_error(server_ssl, inbytes);
   alarm(0);
 
@@ -2392,7 +2406,7 @@ if (ssl_xfer_buffer_lwm >= ssl_xfer_buffer_hwm)
     tls_in.peerdn = NULL;
     tls_in.sni = NULL;
 
-    return smtp_getc();
+    return smtp_getc(lim);
     }
 
   /* Handle genuine errors */