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.
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.
<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
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>
.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
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.
%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
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>
canonicalization
Orlitzky
Typofix
+Deduplicate
+KEM
+HelloRetryRequest
+HRR
+KEMs
+kex
+keyshare
+pkg
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
Dilyan
Palauzov
pkgconf
+testfiles
#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
* 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
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
#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
/*
/*
* Global library
*/
+#include <been_here.h>
#include <mail_params.h>
/* TLS library. */
{
#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);
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);
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