]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-3.10-20240923
authorWietse Z Venema <wietse@porcupine.org>
Mon, 23 Sep 2024 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <ietf-dane@dukhovni.org>
Tue, 24 Sep 2024 02:51:24 +0000 (12:51 +1000)
14 files changed:
postfix/HISTORY
postfix/WISHLIST
postfix/html/postconf.5.html
postfix/man/man5/postconf.5
postfix/proto/postconf.proto
postfix/proto/stop
postfix/proto/stop.double-history
postfix/proto/stop.spell-history
postfix/src/global/mail_params.h
postfix/src/global/mail_version.h
postfix/src/tls/Makefile.in
postfix/src/tls/tls.h
postfix/src/tls/tls_dh.c
postfix/src/tls/tls_misc.c

index d2b98f48c0d6811901dea27351d8ae2c518e2a98..616323f8be5d35c1455d46e8122f7adc8703e301 100644 (file)
@@ -28220,3 +28220,19 @@ Apologies for any names omitted.
        Minor feature: "postcat -f" option to prepend the filename
        to each output line. This simplifies test data development.
        File: postcat/postcat.c.
+
+20240919
+
+       Bitrot: With OpenSSL 3.0 additional key exchange algorithms
+       can be runtime loaded via "providers", and these don't have
+       short internal numeric ids (nids). We've been using numeric
+       ids to configure key exchange groups, and for logging the
+       negotiated group. We now need to switch to APIs that work
+       directly with string names. OpenSSL 3.0 supports not only
+       (EC)DH key exchange groups but also more general KEMs (Key
+       Encapsulation Mechanisms), in which the response from the
+       server to the client contains no server public key. So we
+       can no longer reliably deduce the negotiated group from a
+       "peer" key, and may need to fall back on the (new with
+       OpenSSL 3.2) SSL_get0_group_name() function. Viktor Dukhovni.
+       Files: src/tls/tls.h, src/tls/tls_dh.c, src/tls/tls_misc.c.
index f2112a779ba6c4fa0ac8aa3da179f05141a11c7f..baa23fdd1d1f0bc145cc115a8a9c41c49bb9432f 100644 (file)
@@ -8,6 +8,13 @@ Wish list:
 
        Add tests for Message-ID extraction in the cleanup daemon.
 
+       When debug logging is enabled, dict_db_open() logs a newline
+       character after the version info.
+
+       postsuper fails to write the maillog file while Postfix is down
+       (the fallback to 'direct write' happens after an irreversible
+       set_ugid() call).
+
        The postdrop code should be more explicit about what
        attrributes it will pass through. rec_attr_map() is not
        supposed to be an approver.
index 57b9b13901500ee7bb7032a5d867183d22fbd2de..988b6f4d9c32ef53489deb7d45a04b2471a80602 100644 (file)
@@ -20124,21 +20124,27 @@ be using 0.9.6! </dd>
 <DT><b><a name="tls_eecdh_auto_curves">tls_eecdh_auto_curves</a>
 (default: see "postconf -d" output)</b></DT><DD>
 
-<p> The prioritized list of elliptic curves supported by the Postfix
-SMTP client and server.  These curves are used by the Postfix SMTP
-server when "<a href="postconf.5.html#smtpd_tls_eecdh_grade">smtpd_tls_eecdh_grade</a> = auto".  The selected curves must be
-implemented by OpenSSL and be standardized for use in TLS (<a href="https://tools.ietf.org/html/rfc8422">RFC 8422</a>).
-It is unwise to list only "bleeding-edge" curves supported by a small
-subset of clients.  The default list is suitable for most users. </p>
-
-<p> Postfix skips curve names that are unknown to OpenSSL, or that
-are known but not yet implemented.  This makes it possible to
-"anticipate" support for curves that should be used once they become
-available.  In particular, in some OpenSSL versions, the new <a href="https://tools.ietf.org/html/rfc8031">RFC</a>
-<a href="https://tools.ietf.org/html/rfc8031">8031</a> curves "X25519" and "X448" may be known by name, but ECDH
-support for either or both may be missing.  These curves may appear
-in the default value of this parameter, even though they'll only
-be usable with later versions of OpenSSL.  </p>
+<p> The prioritized list of elliptic curves, that should be enabled in the
+Postfix SMTP client and server.  These are used by the Postfix SMTP server when
+"<a href="postconf.5.html#smtpd_tls_eecdh_grade">smtpd_tls_eecdh_grade</a> = auto".  The selected curves should be implemented
+by OpenSSL and be standardized for use in the TLS "supported groups" extension
+(<a href="https://tools.ietf.org/html/rfc8422">RFC8422</a>, <a href="https://tools.ietf.org/html/rfc8446">RFC8446</a> and <a href="https://tools.ietf.org/html/rfc8447">RFC8447</a>).  Be sure to include at least "x25519" and
+"prime256v1" (the OpenSSL name for "secp256r1", a.k.a. "P-256").  The default
+list is suitable for most users. </p>
+
+<p> On the client side, the first curve listed will be used to construct the
+client's initial TLS 1.3 "keyshare".  If this is not supported by the server,
+the TLS handshake may require an additional round-trip after the server issues
+a HelloRetryRequest (HRR) indicating a suitable mutually supported curve. </p>
+
+<p> Postfix skips curve names that are unknown to OpenSSL, or that are known
+but not yet implemented.  This makes it possible to "anticipate" support for
+curves that should be used once they become available, or to deploy the same
+setting on a server "farm" where not all servers support the same curves.  </p>
+
+<p> As of Postfix 3.10, when compiled with OpenSSL 3.0 or later, the "curve"
+names can be more general key encapsulation mechanisms (KEMs), and/or may be
+loaded from an external "provider" (via a suitable <a href="postconf.5.html#tls_config_file">tls_config_file</a>).  </p>
 
 <p> See also the "<a href="postconf.5.html#tls_ffdhe_auto_groups">tls_ffdhe_auto_groups</a>" parameter, which supports
 customizing the list of FFDHE groups enabled with TLS 1.3.  That setting
@@ -20293,10 +20299,10 @@ EC key agreement in OpenSSL 3.0 and later.  Note that at least one of
 this is required by OpenSSL 3.0.  If both are inadvertently set empty,
 Postfix will fall back to the compiled-in defaults. </p>
 
-<p> All the default groups and EC curves should sufficiently strong
-to make "pruning" the defaults unwise.  At a minimum, "X25519" and
-"P-256" (a.k.a. "prime256v1") should be among the enabled EC curves,
-while "dhe2048" and "dhe3072" should be among the FFDHE groups. </p>
+<p> All the default groups and EC curves should sufficiently strong to make
+"pruning" the defaults unwise.  At a minimum, "x25519" and "prime256v1" (the
+OpenSSL name for "secp256r1", a.k.a. "P-256") should be among the enabled EC
+curves, while "dhe2048" and "dhe3072" should be among the FFDHE groups. </p>
 
 <p> This feature is available in Postfix 3.8 and later, when it is
 compiled and linked with OpenSSL 3.0 or later. </p>
index 91beac06d168c397ed2f28fa5bcba5d2e430c2df..7e367f164ccd93f756aa73caf3152f39f89d01b7 100644 (file)
@@ -13984,21 +13984,27 @@ Postfix >= 3.4. See \fBSSL_CTX_set_options\fR(3).
 .PP
 This feature is available in Postfix 2.8 and later.
 .SH tls_eecdh_auto_curves (default: see "postconf \-d" output)
-The prioritized list of elliptic curves supported by the Postfix
-SMTP client and server.  These curves are used by the Postfix SMTP
-server when "smtpd_tls_eecdh_grade = auto".  The selected curves must be
-implemented by OpenSSL and be standardized for use in TLS (RFC 8422).
-It is unwise to list only "bleeding\-edge" curves supported by a small
-subset of clients.  The default list is suitable for most users.
-.PP
-Postfix skips curve names that are unknown to OpenSSL, or that
-are known but not yet implemented.  This makes it possible to
-"anticipate" support for curves that should be used once they become
-available.  In particular, in some OpenSSL versions, the new RFC
-8031 curves "X25519" and "X448" may be known by name, but ECDH
-support for either or both may be missing.  These curves may appear
-in the default value of this parameter, even though they'll only
-be usable with later versions of OpenSSL.
+The prioritized list of elliptic curves, that should be enabled in the
+Postfix SMTP client and server.  These are used by the Postfix SMTP server when
+"smtpd_tls_eecdh_grade = auto".  The selected curves should be implemented
+by OpenSSL and be standardized for use in the TLS "supported groups" extension
+(RFC8422, RFC8446 and RFC8447).  Be sure to include at least "x25519" and
+"prime256v1" (the OpenSSL name for "secp256r1", a.k.a. "P\-256").  The default
+list is suitable for most users.
+.PP
+On the client side, the first curve listed will be used to construct the
+client's initial TLS 1.3 "keyshare".  If this is not supported by the server,
+the TLS handshake may require an additional round\-trip after the server issues
+a HelloRetryRequest (HRR) indicating a suitable mutually supported curve.
+.PP
+Postfix skips curve names that are unknown to OpenSSL, or that are known
+but not yet implemented.  This makes it possible to "anticipate" support for
+curves that should be used once they become available, or to deploy the same
+setting on a server "farm" where not all servers support the same curves.
+.PP
+As of Postfix 3.10, when compiled with OpenSSL 3.0 or later, the "curve"
+names can be more general key encapsulation mechanisms (KEMs), and/or may be
+loaded from an external "provider" (via a suitable tls_config_file).
 .PP
 See also the "tls_ffdhe_auto_groups" parameter, which supports
 customizing the list of FFDHE groups enabled with TLS 1.3.  That setting
@@ -14115,10 +14121,10 @@ EC key agreement in OpenSSL 3.0 and later.  Note that at least one of
 this is required by OpenSSL 3.0.  If both are inadvertently set empty,
 Postfix will fall back to the compiled\-in defaults.
 .PP
-All the default groups and EC curves should sufficiently strong
-to make "pruning" the defaults unwise.  At a minimum, "X25519" and
-"P\-256" (a.k.a. "prime256v1") should be among the enabled EC curves,
-while "dhe2048" and "dhe3072" should be among the FFDHE groups.
+All the default groups and EC curves should sufficiently strong to make
+"pruning" the defaults unwise.  At a minimum, "x25519" and "prime256v1" (the
+OpenSSL name for "secp256r1", a.k.a. "P\-256") should be among the enabled EC
+curves, while "dhe2048" and "dhe3072" should be among the FFDHE groups.
 .PP
 This feature is available in Postfix 3.8 and later, when it is
 compiled and linked with OpenSSL 3.0 or later.
index 24b8295f2c03c34d4335332e318209fb5cfc9fa2..d0f3bd14549741da511039349c489633f203cbba 100644 (file)
@@ -13364,21 +13364,27 @@ parameter. See there for details. </p>
 
 %PARAM tls_eecdh_auto_curves see "postconf -d" output
 
-<p> The prioritized list of elliptic curves supported by the Postfix
-SMTP client and server.  These curves are used by the Postfix SMTP
-server when "smtpd_tls_eecdh_grade = auto".  The selected curves must be
-implemented by OpenSSL and be standardized for use in TLS (RFC 8422).
-It is unwise to list only "bleeding-edge" curves supported by a small
-subset of clients.  The default list is suitable for most users. </p>
-
-<p> Postfix skips curve names that are unknown to OpenSSL, or that
-are known but not yet implemented.  This makes it possible to
-"anticipate" support for curves that should be used once they become
-available.  In particular, in some OpenSSL versions, the new RFC
-8031 curves "X25519" and "X448" may be known by name, but ECDH
-support for either or both may be missing.  These curves may appear
-in the default value of this parameter, even though they'll only
-be usable with later versions of OpenSSL.  </p>
+<p> The prioritized list of elliptic curves, that should be enabled in the
+Postfix SMTP client and server.  These are used by the Postfix SMTP server when
+"smtpd_tls_eecdh_grade = auto".  The selected curves should be implemented
+by OpenSSL and be standardized for use in the TLS "supported groups" extension
+(RFC8422, RFC8446 and RFC8447).  Be sure to include at least "x25519" and
+"prime256v1" (the OpenSSL name for "secp256r1", a.k.a. "P-256").  The default
+list is suitable for most users. </p>
+
+<p> On the client side, the first curve listed will be used to construct the
+client's initial TLS 1.3 "keyshare".  If this is not supported by the server,
+the TLS handshake may require an additional round-trip after the server issues
+a HelloRetryRequest (HRR) indicating a suitable mutually supported curve. </p>
+
+<p> Postfix skips curve names that are unknown to OpenSSL, or that are known
+but not yet implemented.  This makes it possible to "anticipate" support for
+curves that should be used once they become available, or to deploy the same
+setting on a server "farm" where not all servers support the same curves.  </p>
+
+<p> As of Postfix 3.10, when compiled with OpenSSL 3.0 or later, the "curve"
+names can be more general key encapsulation mechanisms (KEMs), and/or may be
+loaded from an external "provider" (via a suitable tls_config_file).  </p>
 
 <p> See also the "tls_ffdhe_auto_groups" parameter, which supports
 customizing the list of FFDHE groups enabled with TLS 1.3.  That setting
@@ -13420,10 +13426,10 @@ EC key agreement in OpenSSL 3.0 and later.  Note that at least one of
 this is required by OpenSSL 3.0.  If both are inadvertently set empty,
 Postfix will fall back to the compiled-in defaults. </p>
 
-<p> All the default groups and EC curves should sufficiently strong
-to make "pruning" the defaults unwise.  At a minimum, "X25519" and
-"P-256" (a.k.a. "prime256v1") should be among the enabled EC curves,
-while "dhe2048" and "dhe3072" should be among the FFDHE groups. </p>
+<p> All the default groups and EC curves should sufficiently strong to make
+"pruning" the defaults unwise.  At a minimum, "x25519" and "prime256v1" (the
+OpenSSL name for "secp256r1", a.k.a. "P-256") should be among the enabled EC
+curves, while "dhe2048" and "dhe3072" should be among the FFDHE groups. </p>
 
 <p> This feature is available in Postfix 3.8 and later, when it is
 compiled and linked with OpenSSL 3.0 or later. </p>
index ec9542f1c9c7f0688ac9f3cffbb54e841949a96e..03c799cfa3b250f552f02eb5b8b33e3c4e45fa8d 100644 (file)
@@ -1615,3 +1615,11 @@ milterfrom
 canonicalization
 Orlitzky
 Typofix
+Deduplicate
+KEM
+HelloRetryRequest
+HRR
+KEMs
+kex
+keyshare
+pkg
index 3e1bff20c4039871fe8df002ba9e2e7a39773024..70a09313adf692da0e1ccde8b9b572ac02d245c0 100644 (file)
@@ -130,3 +130,4 @@ proto  proto mysql_table proto pgsql_table proto ldap_table
  unimplemented commands in the SMTP server File smtpd smtpd c 
  cleanup cleanup h cleanup cleanup_extracted c 
  File postcat postcat c 
+ Files src tls tls h src tls tls_dh c src tls tls_misc c 
index e28ab4175d57cce8055c98d4024f451ea2eff68d..0b5f5be48c705759f3b94c04d75cf796778062a6 100644 (file)
@@ -82,3 +82,4 @@ mozilla
 Dilyan
 Palauzov
 pkgconf
+testfiles
index 1f03b0b34e7db79dc42f7557b701864ccbee0d0c..1d61fde533839d8f87bc8c6f04e57e8d5624be7d 100644 (file)
@@ -3409,13 +3409,13 @@ extern char *var_tls_null_clist;
 #else
 #define DEF_TLS_EECDH_AUTO_3 ""
 #endif
-#if defined(SN_secp521r1) && defined(NID_secp521r1)
-#define DEF_TLS_EECDH_AUTO_4 SN_secp521r1 " "
+#if defined(SN_secp384r1) && defined(NID_secp384r1)
+#define DEF_TLS_EECDH_AUTO_4 SN_secp384r1
 #else
 #define DEF_TLS_EECDH_AUTO_4 ""
 #endif
-#if defined(SN_secp384r1) && defined(NID_secp384r1)
-#define DEF_TLS_EECDH_AUTO_5 SN_secp384r1
+#if defined(SN_secp521r1) && defined(NID_secp521r1)
+#define DEF_TLS_EECDH_AUTO_5 SN_secp521r1 " "
 #else
 #define DEF_TLS_EECDH_AUTO_5 ""
 #endif
index 52a5cc1adf9aeb0bf1998cc7154e97e973ced7e7..95fbd9bfdf18ee3bc1a8af031bc78aadddef70a6 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20240917"
+#define MAIL_RELEASE_DATE      "20240923"
 #define MAIL_VERSION_NUMBER    "3.10"
 
 #ifdef SNAPSHOT
index 4b562b3fb92f2e96d0507607c33dc618cc918b5b..2e5bbd3d8fa0beb6637f9dc4e2fbc0912277ae23 100644 (file)
@@ -207,6 +207,7 @@ tls_dane.o: ../../include/vstring.h
 tls_dane.o: tls.h
 tls_dane.o: tls_dane.c
 tls_dh.o: ../../include/argv.h
+tls_dh.o: ../../include/been_here.h
 tls_dh.o: ../../include/check_arg.h
 tls_dh.o: ../../include/dns.h
 tls_dh.o: ../../include/mail_params.h
index 3ec41ba369510486ae25db62ddf774077726911b..406246fd543631a386e47ccd2c9849fe88703ff6 100644 (file)
@@ -123,6 +123,15 @@ extern const char *str_tls_level(int);
 #define TLS_PEEK_PEER_CERT(ssl) SSL_get_peer_certificate(ssl)
 #define TLS_FREE_PEER_CERT(x)   X509_free(x)
 #define tls_set_bio_callback    BIO_set_callback
+#endif
+
+#if OPENSSL_VERSION_PREREQ(3,2)
+#define TLS_GROUP_NAME(ssl) SSL_get0_group_name(ssl)
+#elif OPENSSL_VERSION_PREREQ(3,0)
+#define TLS_GROUP_NAME(ssl) \
+    SSL_group_to_name((ssl), SSL_get_negotiated_group(ssl))
+#else
+#define TLS_GROUP_NAME(ssl) ((const char *)0)
 #endif
 
  /*
index f47b954617271c5adbcb93086e8708da4573583a..6165b9390099cae9847b2759e172fbe584338112 100644 (file)
@@ -75,6 +75,7 @@
  /*
   * Global library
   */
+#include <been_here.h>
 #include <mail_params.h>
 
 /* TLS library. */
@@ -313,68 +314,75 @@ static int setup_auto_groups(SSL_CTX *ctx, const char *origin,
 {
 #ifndef OPENSSL_NO_ECDH
     SSL_CTX *tmpctx;
-    int    *nids;
-    int     space = 10;
-    int     n = 0;
+    BH_TABLE *seen;
     char   *save;
     char   *groups;
     char   *group;
+    static VSTRING *names;
 
     if ((tmpctx = SSL_CTX_new(TLS_method())) == 0) {
        msg_warn("cannot allocate temp SSL_CTX");
        tls_print_errors();
        return (AG_STAT_NO_RETRY);
     }
-    nids = mymalloc(space * sizeof(int));
 
+    if (!names)
+       names = vstring_alloc(sizeof DEF_TLS_EECDH_AUTO +
+                             sizeof DEF_TLS_FFDHE_AUTO);
+    VSTRING_RESET(names);
+    /*
+     * OpenSSL does not tolerate duplicate groups in the requested list.
+     * Deduplicate case-insensitively, just in case OpenSSL some day supports
+     * case-insensitive group lookup.  Users who specify the group name twice
+     * and get the case wrong the first time deserve to be unhappy. :-)
+     *
+     * OpenSSL 3.3 supports "?<name>" as a syntax for optionally ignoring
+     * unsupported groups, so we could skip checking against the throw-away
+     * CTX when linked against 3.3 or higher, but the cost savings don't
+     * justify the #ifdef overhead for now.
+     */
+    seen = been_here_init(0, BH_FLAG_FOLD);
+
+#define GROUPS_SEP CHARS_COMMA_SP ":"
 #define SETUP_AG_RETURN(val) do { \
+       been_here_free(seen); \
        myfree(save); \
-       myfree(nids); \
        SSL_CTX_free(tmpctx); \
        return (val); \
     } while (0)
 
     groups = save = concatenate(eecdh, " ", ffdhe, NULL);
-    if ((group = mystrtok(&groups, CHARS_COMMA_SP)) == 0) {
+    if ((group = mystrtok(&groups, GROUPS_SEP)) == 0) {
        msg_warn("no %s key exchange group - OpenSSL requires at least one",
                 origin);
        SETUP_AG_RETURN(AG_STAT_NO_GROUP);
     }
-    for (; group != 0; group = mystrtok(&groups, CHARS_COMMA_SP)) {
-       int     nid = EC_curve_nist2nid(group);
-
-       if (nid == NID_undef)
-           nid = OBJ_sn2nid(group);
-       if (nid == NID_undef)
-           nid = OBJ_ln2nid(group);
-       if (nid == NID_undef) {
-           msg_warn("ignoring unknown key exchange group \"%s\"", group);
+    for (; group != 0; group = mystrtok(&groups, GROUPS_SEP)) {
+       if (been_here_fixed(seen, group))
            continue;
-       }
-
        /*
-        * Validate the NID by trying it as the group for a throw-away SSL
-        * context. Silently skip unsupported code points. This way, we can
-        * list X25519 and X448 as soon as the nids are assigned, and before
-        * the supporting code is implemented. They'll be silently skipped
-        * when not yet supported.
+        * Validate the group name by trying it as the group for a throw-away
+        * SSL context. This way, we can ask for new groups that may not yet be
+        * supported by the underlying OpenSSL runtime.  Unsupported groups are
+        * silently ignored.
         */
-       if (SSL_CTX_set1_curves(tmpctx, &nid, 1) <= 0) {
-           continue;
+       ERR_set_mark();
+       if (SSL_CTX_set1_curves_list(tmpctx, group) > 0) {
+           if (VSTRING_LEN(names) > 0)
+               VSTRING_ADDCH(names, ':');
+           vstring_strcat(names, group);
        }
-       if (++n > space) {
-           space *= 2;
-           nids = myrealloc(nids, space * sizeof(int));
-       }
-       nids[n - 1] = nid;
+       ERR_pop_to_mark();
     }
 
-    if (n == 0) {
+    if (VSTRING_LEN(names) == 0) {
        /* The names may be case-sensitive */
        msg_warn("none of the %s key exchange groups are supported", origin);
        SETUP_AG_RETURN(AG_STAT_NO_GROUP);
     }
-    if (SSL_CTX_set1_curves(ctx, nids, n) <= 0) {
+    VSTRING_TERMINATE(names);
+
+    if (SSL_CTX_set1_curves_list(ctx, vstring_str(names)) <= 0) {
        msg_warn("failed to set up the %s key exchange groups", origin);
        tls_print_errors();
        SETUP_AG_RETURN(AG_STAT_NO_RETRY);
index f77d778acd52528bce30c4f3865276d1cf2f91c6..5e34f7a24b81aba20795ca49632de591d9d86934 100644 (file)
@@ -1057,6 +1057,13 @@ void    tls_get_signature_params(TLS_SESS_STATE *TLScontext)
            kex_name = OBJ_nid2sn(EVP_PKEY_type(nid));
            break;
 
+#if defined(EVP_PKEY_KEYMGMT)
+       case EVP_PKEY_KEYMGMT:
+           kex_name = EVP_PKEY_get0_type_name(dh_pkey);
+           TLScontext->kex_bits = 0;
+           break;
+#endif
+
        case EVP_PKEY_DH:
            kex_name = "DHE";
            TLScontext->kex_bits = EVP_PKEY_bits(dh_pkey);
@@ -1072,6 +1079,16 @@ void    tls_get_signature_params(TLS_SESS_STATE *TLScontext)
        EVP_PKEY_free(dh_pkey);
     }
 
+    /*
+     * On the client side, a TLS 1.3 KEM has no server key, just ciphertext to
+     * decapsulate, but, as of OpenSSL 3.0, the client can still obtain the
+     * negotiated group name directly.  We nevertheless still try to get the
+     * group details from the peer key first, which works with OpenSSL 1.1.1
+     * and retains the original output format for the (EC)DH groups.
+     */
+    if (!kex_name)
+       kex_name = TLS_GROUP_NAME(ssl);
+
     /*
      * On the client end, the certificate may be present, but not used, so we
      * check via SSL_get_signature_nid().  This means that local signature