-TTLS_PKEYS
-TTLS_PRNG_SEED_INFO
-TTLS_PRNG_SRC
+-TTLS_ROLE
-TTLS_SCACHE
-TTLS_SCACHE_ENTRY
-TTLS_SERVER_INIT_PROPS
-TTLS_SESS_STATE
-TTLS_TICKET_KEY
-TTLS_TLSA
+-TTLS_USAGE
-TTLS_VINFO
-TTLScontext_t
-TTOK822
proto/TLS_README.html, tls/tls.h, tls/tls_server.c,
tls/tls_misc.c.
+20181106
+
+ Bugfix (introduced: 3.0): smtpd_discard_ehlo_keywords could
+ not disable "SMTPUTF8". because the lookup table was using
+ "EHLO_MASK_SMTPUTF8" instead. File: global/ehlo_mask.c.
+
20181110
Documentation: update documentation for Postfix versions
that support disabling TLS 1.3. File: proto/postconf.proto.
+
+20181117
+
+ Improved logging of TLS 1.3 summary information, and improved
+ reporting of the same info in Received: message headers.
+ Viktor Dukhovni. Files: proto/FORWARD_SECRECY_README.html,
+ posttls-finger/posttls-finger.c, smtpd/smtpd.c, tls/tls.h,
+ tls/tls_client.c, tls/tls_misc.c, tls/tls_proxy.h,
+ tls/tls_proxy_context_print.c, tls/tls_proxy_context_scan.c,
+ tls/tls_server.c.
O\bOv\bve\ber\brv\bvi\bie\bew\bw
Postfix supports forward secrecy of TLS network communication since version
-2.2. This support was adopted from Lutz Jänicke's "Postfix TLS patch" for
+2.2. This support was adopted from Lutz Ja"nicke's "Postfix TLS patch" for
earlier Postfix versions. This document will focus on TLS Forward Secrecy in
the Postfix SMTP client and server. See TLS_README for a general description of
Postfix TLS support.
* With "smtp_tls_loglevel = 1" and "smtpd_tls_loglevel = 1", the Postfix SMTP
client and server will log TLS connection information to the maillog file.
- The general logfile format is:
+ The general logfile format is shown below. With TLS 1.3 there may be
+ additional properties logged after the cipher name and bits.
postfix/smtp[process-id]: Untrusted TLS connection established
to host.example.com[192.168.0.2]:25: TLSv1 with cipher cipher-name
* With "smtpd_tls_received_header = yes", the Postfix SMTP server will record
TLS connection information in the Received: header in the form of comments
(text inside parentheses). The general format depends on the
- smtpd_tls_ask_ccert setting:
+ smtpd_tls_ask_ccert setting. With TLS 1.3 there may be additional
+ properties logged after the cipher name and bits.
Received: from host.example.com (host.example.com [192.168.0.2])
(using TLSv1 with cipher cipher-name
(actual-key-size/raw-key-size bits))
(No client certificate requested)
+ TLS 1.3 examples. Some of the new attributes may not appear when not
+ applicable or not available in older versions of the OpenSSL library.
+
+ Received: from localhost (localhost [127.0.0.1])
+ (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256
+ bits)
+ key-exchange X25519 server-signature RSA-PSS (2048 bits)
+ server-digest SHA256)
+ (No client certificate requested)
+
+ Received: from localhost (localhost [127.0.0.1])
+ (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256
+ bits)
+ key-exchange X25519 server-signature RSA-PSS (2048 bits)
+ server-digest SHA256
+ client-signature ECDSA (P-256) client-digest SHA256)
+ (Client CN "example.org", Issuer "example.org" (not verified))
+
+ o The "key-exchange" attribute records the type of "Diffie-Hellman" group
+ used for key agreement. Possible values include "DHE", "ECDHE",
+ "X25519" and "X448". With "DHE", the bit size of the prime will be
+ reported in parentheses after the algorithm name, with "ECDHE", the
+ curve name.
+
+ o The "server-signature" attribute shows the public key signature
+ algorithm used by the server. With "RSA-PSS", the bit size of the
+ modulus will be reported in parentheses. With "ECDSA", the curve name.
+ If, for example, the server has both an RSA and an ECDSA private key
+ and certificate, it will be possible to track which one was used for a
+ given connection.
+
+ o The new "server-digest" attribute records the digest algorithm used by
+ the server to prepare handshake messages for signing. The Ed25519 and
+ Ed448 signature algorithms do not make use of such a digest, so no
+ "server-digest" will be shown for these signature algorithms.
+
+ o When a client certificate is requested with "smtpd_tls_ask_ccert" and
+ the client uses a TLS client-certificate, the "client-signature" and
+ "client-digest" attributes will record the corresponding properties of
+ the client's TLS handshake signature.
+
The next sections will explain what cipher-name, key-size, and peer
verification status information to expect.
non-export ciphers, but may they differ for the legacy export ciphers where the
actual key is artificially shortened.
+Starting with TLS 1.3 the cipher name no longer contains enough information to
+determine which forward-secrecy scheme was employed, but TLS 1.3 a\bal\blw\bwa\bay\bys\bs uses
+forward-secrecy. On the client side, up-to-date Postfix releases log additional
+information for TLS 1.3 connections, reporting the signature and key exchange
+algorithms. Two examples below (the long single line messages are folded across
+multiple lines for readability):
+
+ postfix/smtp[process-id]:
+ Untrusted TLS connection established to 127.0.0.1[127.0.0.1]:25:
+ TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
+ key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest
+ SHA256
+ client-signature ECDSA (P-256) client-digest SHA256
+
+ postfix/smtp[process-id]:
+ Untrusted TLS connection established to 127.0.0.1[127.0.0.1]:25:
+ TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
+ key-exchange ECDHE (P-256) server-signature ECDSA (P-256) server-digest
+ SHA256
+
+In the above connections, the "key-exchange" value records the "Diffie-Hellman"
+algorithm used for key agreement. The "server-signature" value records the
+public key algoritm used by the server to sign the key exchange. The "server-
+digest" value records any hash algorithm used to prepare the data for signing.
+With "ED25519" and "ED448", no separate hash algorithm is used.
+
+Examples of Postfix SMTP server logging:
+
+ postfix/smtpd[process-id]:
+ Untrusted TLS connection established from localhost[127.0.0.1]:25:
+ TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
+ key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest
+ SHA256
+ client-signature ECDSA (P-256) client-digest SHA256
+
+ postfix/smtpd[process-id]:
+ Anonymous TLS connection established from localhost[127.0.0.1]:
+ TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
+ server-signature RSA-PSS (2048 bits) server-digest SHA256
+
+ postfix/smtpd[process-id]:
+ Anonymous TLS connection established from localhost[127.0.0.1]:
+ TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
+ server-signature ED25519
+
W\bWh\bha\bat\bt d\bdo\bo "\b"A\bAn\bno\bon\bny\bym\bmo\bou\bus\bs"\b",\b, "\b"U\bUn\bnt\btr\bru\bus\bst\bte\bed\bd"\b",\b, e\bet\btc\bc.\b. i\bin\bn P\bPo\bos\bst\btf\bfi\bix\bx l\blo\bog\bgg\bgi\bin\bng\bg m\bme\bea\ban\bn?\b?
The verification levels below are subject to man-in-the-middle attacks to
C\bCr\bre\bed\bdi\bit\bts\bs
- * TLS support for Postfix was originally developed by Lutz Jänicke at Cottbus
- Technical University.
+ * TLS support for Postfix was originally developed by Lutz Ja"nicke at
+ Cottbus Technical University.
* Wietse Venema adopted and restructured the code and documentation.
* Viktor Dukhovni implemented support for many subsequent TLS features,
including EECDH, and authored the initial version of this document.
<li> <p> With "<a href="postconf.5.html#smtp_tls_loglevel">smtp_tls_loglevel</a> = 1" and "<a href="postconf.5.html#smtpd_tls_loglevel">smtpd_tls_loglevel</a> = 1",
the Postfix SMTP client and server will log TLS connection information
-to the maillog file. The general logfile format is: </p>
+to the maillog file. The general logfile format is shown below.
+With TLS 1.3 there may be additional properties logged after the
+cipher name and bits. </p>
<blockquote>
<pre>
<li> <p> With "<a href="postconf.5.html#smtpd_tls_received_header">smtpd_tls_received_header</a> = yes", the Postfix SMTP
server will record TLS connection information in the Received:
header in the form of comments (text inside parentheses). The general
-format depends on the <a href="postconf.5.html#smtpd_tls_ask_ccert">smtpd_tls_ask_ccert</a> setting:
+format depends on the <a href="postconf.5.html#smtpd_tls_ask_ccert">smtpd_tls_ask_ccert</a> setting. With TLS 1.3 there
+may be additional properties logged after the cipher name and bits. </p>
<blockquote>
<pre>
</pre>
</blockquote>
+<p> TLS 1.3 examples. Some of the new attributes may not appear when not
+applicable or not available in older versions of the OpenSSL library. </p>
+
+<blockquote>
+<pre>
+Received: from localhost (localhost [127.0.0.1])
+ (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
+ key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256)
+ (No client certificate requested)
+
+Received: from localhost (localhost [127.0.0.1])
+ (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
+ key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
+ client-signature ECDSA (P-256) client-digest SHA256)
+ (Client CN "example.org", Issuer "example.org" (not verified))
+</pre>
+</blockquote>
+
+<ul>
+<li> <p> The "key-exchange" attribute records the type of "Diffie-Hellman"
+group used for key agreement. Possible values include "DHE", "ECDHE", "X25519"
+and "X448". With "DHE", the bit size of the prime will be reported in
+parentheses after the algorithm name, with "ECDHE", the curve name. </p>
+
+<li> <p> The "server-signature" attribute shows the public key signature
+algorithm used by the server. With "RSA-PSS", the bit size of the modulus will
+be reported in parentheses. With "ECDSA", the curve name. If, for example,
+the server has both an RSA and an ECDSA private key and certificate, it will be
+possible to track which one was used for a given connection. </p>
+
+<li> <p> The new "server-digest" attribute records the digest algorithm used by
+the server to prepare handshake messages for signing. The Ed25519 and Ed448
+signature algorithms do not make use of such a digest, so no "server-digest"
+will be shown for these signature algorithms. </p>
+
+<li> <p> When a client certificate is requested with "<a href="postconf.5.html#smtpd_tls_ask_ccert">smtpd_tls_ask_ccert</a>" and
+the client uses a TLS client-certificate, the "client-signature" and
+"client-digest" attributes will record the corresponding properties of the
+client's TLS handshake signature. </p> </ul>
+
</ul>
<p> The next sections will explain what <i>cipher-name</i>,
differ for the legacy export ciphers where the actual key
is artificially shortened. </p>
+<p> Starting with TLS 1.3 the cipher name no longer contains enough
+information to determine which forward-secrecy scheme was employed,
+but TLS 1.3 <b>always</b> uses forward-secrecy. On the client side,
+up-to-date Postfix releases log additional information for TLS 1.3
+connections, reporting the signature and key exchange algorithms.
+Two examples below (the long single line messages are folded across
+multiple lines for readability): </p>
+
+<blockquote>
+<pre>
+postfix/smtp[<i>process-id</i>]:
+ Untrusted TLS connection established to 127.0.0.1[127.0.0.1]:25:
+ TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
+ key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
+ client-signature ECDSA (P-256) client-digest SHA256
+
+postfix/smtp[<i>process-id</i>]:
+ Untrusted TLS connection established to 127.0.0.1[127.0.0.1]:25:
+ TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
+ key-exchange ECDHE (P-256) server-signature ECDSA (P-256) server-digest SHA256
+</pre>
+</blockquote>
+
+<p> In the above connections, the "key-exchange" value records the
+"Diffie-Hellman" algorithm used for key agreement. The "server-signature" value
+records the public key algoritm used by the server to sign the key exchange.
+The "server-digest" value records any hash algorithm used to prepare the data
+for signing. With "ED25519" and "ED448", no separate hash algorithm is used.
+</p>
+
+<p> Examples of Postfix SMTP server logging: </p>
+
+<blockquote>
+<pre>
+postfix/smtpd[<i>process-id</i>]:
+ Untrusted TLS connection established from localhost[127.0.0.1]:25:
+ TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
+ key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
+ client-signature ECDSA (P-256) client-digest SHA256
+
+postfix/smtpd[<i>process-id</i>]:
+ Anonymous TLS connection established from localhost[127.0.0.1]:
+ TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
+ server-signature RSA-PSS (2048 bits) server-digest SHA256
+
+postfix/smtpd[<i>process-id</i>]:
+ Anonymous TLS connection established from localhost[127.0.0.1]:
+ TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
+ server-signature ED25519
+</pre>
+</blockquote>
+
<h2><a name="status"> What do "Anonymous", "Untrusted", etc. in
Postfix logging mean? </a> </h2>
<li> <p> With "smtp_tls_loglevel = 1" and "smtpd_tls_loglevel = 1",
the Postfix SMTP client and server will log TLS connection information
-to the maillog file. The general logfile format is: </p>
+to the maillog file. The general logfile format is shown below.
+With TLS 1.3 there may be additional properties logged after the
+cipher name and bits. </p>
<blockquote>
<pre>
<li> <p> With "smtpd_tls_received_header = yes", the Postfix SMTP
server will record TLS connection information in the Received:
header in the form of comments (text inside parentheses). The general
-format depends on the smtpd_tls_ask_ccert setting:
+format depends on the smtpd_tls_ask_ccert setting. With TLS 1.3 there
+may be additional properties logged after the cipher name and bits. </p>
<blockquote>
<pre>
</pre>
</blockquote>
+<p> TLS 1.3 examples. Some of the new attributes may not appear when not
+applicable or not available in older versions of the OpenSSL library. </p>
+
+<blockquote>
+<pre>
+Received: from localhost (localhost [127.0.0.1])
+ (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
+ key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256)
+ (No client certificate requested)
+
+Received: from localhost (localhost [127.0.0.1])
+ (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
+ key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
+ client-signature ECDSA (P-256) client-digest SHA256)
+ (Client CN "example.org", Issuer "example.org" (not verified))
+</pre>
+</blockquote>
+
+<ul>
+<li> <p> The "key-exchange" attribute records the type of "Diffie-Hellman"
+group used for key agreement. Possible values include "DHE", "ECDHE", "X25519"
+and "X448". With "DHE", the bit size of the prime will be reported in
+parentheses after the algorithm name, with "ECDHE", the curve name. </p>
+
+<li> <p> The "server-signature" attribute shows the public key signature
+algorithm used by the server. With "RSA-PSS", the bit size of the modulus will
+be reported in parentheses. With "ECDSA", the curve name. If, for example,
+the server has both an RSA and an ECDSA private key and certificate, it will be
+possible to track which one was used for a given connection. </p>
+
+<li> <p> The new "server-digest" attribute records the digest algorithm used by
+the server to prepare handshake messages for signing. The Ed25519 and Ed448
+signature algorithms do not make use of such a digest, so no "server-digest"
+will be shown for these signature algorithms. </p>
+
+<li> <p> When a client certificate is requested with "smtpd_tls_ask_ccert" and
+the client uses a TLS client-certificate, the "client-signature" and
+"client-digest" attributes will record the corresponding properties of the
+client's TLS handshake signature. </p> </ul>
+
</ul>
<p> The next sections will explain what <i>cipher-name</i>,
differ for the legacy export ciphers where the actual key
is artificially shortened. </p>
+<p> Starting with TLS 1.3 the cipher name no longer contains enough
+information to determine which forward-secrecy scheme was employed,
+but TLS 1.3 <b>always</b> uses forward-secrecy. On the client side,
+up-to-date Postfix releases log additional information for TLS 1.3
+connections, reporting the signature and key exchange algorithms.
+Two examples below (the long single line messages are folded across
+multiple lines for readability): </p>
+
+<blockquote>
+<pre>
+postfix/smtp[<i>process-id</i>]:
+ Untrusted TLS connection established to 127.0.0.1[127.0.0.1]:25:
+ TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
+ key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
+ client-signature ECDSA (P-256) client-digest SHA256
+
+postfix/smtp[<i>process-id</i>]:
+ Untrusted TLS connection established to 127.0.0.1[127.0.0.1]:25:
+ TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
+ key-exchange ECDHE (P-256) server-signature ECDSA (P-256) server-digest SHA256
+</pre>
+</blockquote>
+
+<p> In the above connections, the "key-exchange" value records the
+"Diffie-Hellman" algorithm used for key agreement. The "server-signature" value
+records the public key algoritm used by the server to sign the key exchange.
+The "server-digest" value records any hash algorithm used to prepare the data
+for signing. With "ED25519" and "ED448", no separate hash algorithm is used.
+</p>
+
+<p> Examples of Postfix SMTP server logging: </p>
+
+<blockquote>
+<pre>
+postfix/smtpd[<i>process-id</i>]:
+ Untrusted TLS connection established from localhost[127.0.0.1]:25:
+ TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
+ key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
+ client-signature ECDSA (P-256) client-digest SHA256
+
+postfix/smtpd[<i>process-id</i>]:
+ Anonymous TLS connection established from localhost[127.0.0.1]:
+ TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
+ server-signature RSA-PSS (2048 bits) server-digest SHA256
+
+postfix/smtpd[<i>process-id</i>]:
+ Anonymous TLS connection established from localhost[127.0.0.1]:
+ TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
+ server-signature ED25519
+</pre>
+</blockquote>
+
<h2><a name="status"> What do "Anonymous", "Untrusted", etc. in
Postfix logging mean? </a> </h2>
"ENHANCEDSTATUSCODES", EHLO_MASK_ENHANCEDSTATUSCODES,
"DSN", EHLO_MASK_DSN,
"EHLO_MASK_SMTPUTF8", EHLO_MASK_SMTPUTF8,
+ "SMTPUTF8", EHLO_MASK_SMTPUTF8,
"SILENT-DISCARD", EHLO_MASK_SILENT, /* XXX In-band signaling */
0,
};
#define MAIL_ATTR_CIPHER_NAME "cipher_name"
#define MAIL_ATTR_CIPHER_USEBITS "cipher_usebits"
#define MAIL_ATTR_CIPHER_ALGBITS "cipher_algbits"
+#define MAIL_ATTR_KEX_NAME "key_exchange"
+#define MAIL_ATTR_KEX_CURVE "key_exchange_curve"
+#define MAIL_ATTR_KEX_BITS "key_exchange_bits"
+#define MAIL_ATTR_CLNT_SIG_NAME "clnt_signature"
+#define MAIL_ATTR_CLNT_SIG_CURVE "clnt_signature_curve"
+#define MAIL_ATTR_CLNT_SIG_BITS "clnt_signature_bits"
+#define MAIL_ATTR_CLNT_SIG_DGST "clnt_signature_digest"
+#define MAIL_ATTR_SRVR_SIG_NAME "srvr_signature"
+#define MAIL_ATTR_SRVR_SIG_CURVE "srvr_signature_curve"
+#define MAIL_ATTR_SRVR_SIG_BITS "srvr_signature_bits"
+#define MAIL_ATTR_SRVR_SIG_DGST "srvr_signature_digest"
+#define MAIL_ATTR_NAMADDR "namaddr"
#define MAIL_ATTR_SERVER_ID "server_id"
/*
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20181110"
-#define MAIL_VERSION_NUMBER "3.1.10-RC2"
+#define MAIL_RELEASE_DATE "20181117"
+#define MAIL_VERSION_NUMBER "3.1.10-RC3"
#ifdef SNAPSHOT
#define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE
#ifdef USE_TLS
if (var_smtpd_tls_received_header && state->tls_context) {
- out_fprintf(out_stream, REC_TYPE_NORM,
- "\t(using %s with cipher %s (%d/%d bits))",
- state->tls_context->protocol,
- state->tls_context->cipher_name,
- state->tls_context->cipher_usebits,
- state->tls_context->cipher_algbits);
+ int cont = 0;
+
+ vstring_sprintf(state->buffer,
+ "\t(using %s with cipher %s (%d/%d bits)",
+ state->tls_context->protocol,
+ state->tls_context->cipher_name,
+ state->tls_context->cipher_usebits,
+ state->tls_context->cipher_algbits);
+ if (state->tls_context->kex_name && *state->tls_context->kex_name) {
+ out_record(out_stream, REC_TYPE_NORM, STR(state->buffer),
+ LEN(state->buffer));
+ vstring_sprintf(state->buffer, "\t key-exchange %s",
+ state->tls_context->kex_name);
+ if (state->tls_context->kex_curve
+ && *state->tls_context->kex_curve)
+ vstring_sprintf_append(state->buffer, " (%s)",
+ state->tls_context->kex_curve);
+ else if (state->tls_context->kex_bits > 0)
+ vstring_sprintf_append(state->buffer, " (%d bits)",
+ state->tls_context->kex_bits);
+ cont = 1;
+ }
+ if (state->tls_context->srvr_sig_name
+ && *state->tls_context->srvr_sig_name) {
+ if (cont) {
+ vstring_sprintf_append(state->buffer, " server-signature %s",
+ state->tls_context->srvr_sig_name);
+ } else {
+ out_record(out_stream, REC_TYPE_NORM, STR(state->buffer),
+ LEN(state->buffer));
+ vstring_sprintf(state->buffer, "\t server-signature %s",
+ state->tls_context->srvr_sig_name);
+ }
+ if (state->tls_context->srvr_sig_curve
+ && *state->tls_context->srvr_sig_curve)
+ vstring_sprintf_append(state->buffer, " (%s)",
+ state->tls_context->srvr_sig_curve);
+ else if (state->tls_context->srvr_sig_bits > 0)
+ vstring_sprintf_append(state->buffer, " (%d bits)",
+ state->tls_context->srvr_sig_bits);
+ if (state->tls_context->srvr_sig_dgst
+ && *state->tls_context->srvr_sig_dgst)
+ vstring_sprintf_append(state->buffer, " server-digest %s",
+ state->tls_context->srvr_sig_dgst);
+ }
+ if (state->tls_context->clnt_sig_name
+ && *state->tls_context->clnt_sig_name) {
+ out_record(out_stream, REC_TYPE_NORM, STR(state->buffer),
+ LEN(state->buffer));
+ vstring_sprintf(state->buffer, "\t client-signature %s",
+ state->tls_context->clnt_sig_name);
+ if (state->tls_context->clnt_sig_curve
+ && *state->tls_context->clnt_sig_curve)
+ vstring_sprintf_append(state->buffer, " (%s)",
+ state->tls_context->clnt_sig_curve);
+ else if (state->tls_context->clnt_sig_bits > 0)
+ vstring_sprintf_append(state->buffer, " (%d bits)",
+ state->tls_context->clnt_sig_bits);
+ if (state->tls_context->clnt_sig_dgst
+ && *state->tls_context->clnt_sig_dgst)
+ vstring_sprintf_append(state->buffer, " client-digest %s",
+ state->tls_context->clnt_sig_dgst);
+ }
+ out_fprintf(out_stream, REC_TYPE_NORM, "%s)", STR(state->buffer));
if (TLS_CERT_IS_PRESENT(state->tls_context)) {
peer_CN = VSTRING_STRDUP(state->tls_context->peer_CN);
comment_sanitize(peer_CN);
/* Backwards compatibility with OpenSSL < 1.1.1 */
#if OPENSSL_VERSION_NUMBER < 0x1010100fUL
#define SSL_CTX_set_num_tickets(ctx, num) ((void)0)
+#endif
+
+ /*-
+ * Backwards compatibility with OpenSSL < 1.1.1a.
+ *
+ * In OpenSSL 1.1.1a the client-only interface SSL_get_server_tmp_key() was
+ * updated to work on both the client and the server, and was renamed to
+ * SSL_get_peer_tmp_key(), with the original name left behind as an alias. We
+ * use the new name when available.
+ */
+#if OPENSSL_VERSION_NUMBER < 0x1010101fUL
+#undef SSL_get_signature_nid
+#define SSL_get_signature_nid(ssl, pnid) (NID_undef)
+#define tls_get_peer_dh_pubkey SSL_get_server_tmp_key
+#else
+#define tls_get_peer_dh_pubkey SSL_get_peer_tmp_key
#endif
/* SSL_CIPHER_get_name() got constified in 0.9.7g */
*/
#include <dns.h>
+ /*
+ * TLS role, presently for logging.
+ */
+typedef enum {
+ TLS_ROLE_CLIENT, TLS_ROLE_SERVER,
+} TLS_ROLE;
+
+typedef enum {
+ TLS_USAGE_NEW, TLS_USAGE_USED,
+} TLS_USAGE;
+
/*
* Names of valid tlsmgr(8) session caches.
*/
const char *cipher_name;
int cipher_usebits;
int cipher_algbits;
+ const char *kex_name; /* shared key-exchange algorithm */
+ const char *kex_curve; /* shared key-exchange ECDHE curve */
+ int kex_bits; /* shared FFDHE key exchange bits */
+ const char *clnt_sig_name; /* client's signature key algorithm */
+ const char *clnt_sig_curve; /* client's ECDSA curve name */
+ int clnt_sig_bits; /* client's RSA signature key bits */
+ const char *clnt_sig_dgst; /* client's signature digest */
+ const char *srvr_sig_name; /* server's signature key algorithm */
+ const char *srvr_sig_curve; /* server's ECDSA curve name */
+ int srvr_sig_bits; /* server's RSA signature key bits */
+ const char *srvr_sig_dgst; /* server's signature digest */
/* Private. */
SSL *con;
char *cache_type; /* tlsmgr(8) cache type if enabled */
extern const char *tls_set_ciphers(TLS_APPL_STATE *, const char *,
const char *, const char *);
-#endif
+ /*
+ * Populate TLS context with TLS 1.3-related signature parameters.
+ */
+extern void tls_get_signature_params(TLS_SESS_STATE *);
+
+#endif /* TLS_INTERNAL */
/*
* tls_client.c
extern const char *tls_compile_version(void);
extern const char *tls_run_version(void);
extern const char **tls_pkey_algorithms(void);
+extern void tls_log_summary(TLS_ROLE, TLS_USAGE, TLS_SESS_STATE *);
#ifdef TLS_INTERNAL
TLScontext->peer_status |= TLS_CERT_FLAG_SECURED;
/*
- * All the key facts in a single log entry.
+ * With the handshake done, extract TLS 1.3 signature metadata.
*/
+ tls_get_signature_params(TLScontext);
+
if (log_mask & TLS_LOG_SUMMARY)
- msg_info("%s TLS connection established to %s: %s with cipher %s "
- "(%d/%d bits)",
- !TLS_CERT_IS_PRESENT(TLScontext) ? "Anonymous" :
- TLS_CERT_IS_SECURED(TLScontext) ? "Verified" :
- TLS_CERT_IS_TRUSTED(TLScontext) ? "Trusted" : "Untrusted",
- props->namaddr, TLScontext->protocol, TLScontext->cipher_name,
- TLScontext->cipher_usebits, TLScontext->cipher_algbits);
+ tls_log_summary(TLS_ROLE_CLIENT, TLS_USAGE_NEW, TLScontext);
tls_int_seed();
/* SUMMARY
/* miscellaneous TLS support routines
/* SYNOPSIS
+/* .SH Public functions
+/* .nf
+/* .na
+/* #include <tls.h>
+/*
+/* void tls_log_summary(role, usage, TLScontext)
+/* TLS_ROLE role;
+/* TLS_USAGE usage;
+/* TLS_SESS_STATE *TLScontext;
+/*
+/* const char *tls_compile_version(void)
+/*
+/* const char *tls_run_version(void)
+/*
+/* const char **tls_pkey_algorithms(void)
+/*
+/* .SH Internal functions
+/* .nf
+/* .na
/* #define TLS_INTERNAL
/* #include <tls.h>
/*
/* int grade;
/* const char *exclusions;
/*
+/* void tls_get_signature_params(TLScontext)
+/* TLS_SESS_STATE *TLScontext;
+/*
/* void tls_print_errors()
/*
/* void tls_info_callback(ssl, where, ret)
/*
/* int tls_validate_digest(dgst)
/* const char *dgst;
+/* DESCRIPTION
+/* This module implements public and internal routines that
+/* support the TLS client and server.
/*
-/* const char *tls_compile_version(void)
+/* tls_log_summary() logs a summary of a completed TLS connection.
+/* The "role" argument must be TLS_ROLE_CLIENT for outgoing client
+/* connections, or TLS_ROLE_SERVER for incoming server connections,
+/* and the "usage" must be TLS_USAGE_NEW or TLS_USAGE_USED.
/*
-/* const char *tls_run_version(void)
+/* tls_compile_version() returns a text string description of
+/* the compile-time TLS library.
/*
-/* const char **tls_pkey_algorithms(void)
-/* DESCRIPTION
-/* This module implements routines that support the TLS client
-/* and server internals.
+/* tls_run_version() is just tls_compile_version() but with the runtime
+/* version instead of the compile-time version.
+/*
+/* tls_pkey_algorithms() returns a pointer to null-terminated
+/* array of string constants with the names of the supported
+/* public-key algorithms.
/*
/* tls_alloc_app_context() creates an application context that
/* holds the SSL context for the application and related cached state.
/* When the input is invalid, tls_set_ciphers() logs a warning with
/* the specified context, and returns a null pointer result.
/*
+/* tls_get_signature_params() updates the "TLScontext" with handshake
+/* signature parameters pertaining to TLS 1.3, where the ciphersuite
+/* no longer describes the asymmetric algorithms employed in the
+/* handshake, which are negotiated separately. This function
+/* has no effect for TLS 1.2 and earlier.
+/*
/* tls_print_errors() queries the OpenSSL error stack,
/* logs the error messages, and clears the error stack.
/*
/*
/* tls_validate_digest() returns non-zero if the named digest
/* is usable and zero otherwise.
-/*
-/* tls_compile_version() returns a text string description of
-/* the compile-time TLS library.
-/*
-/* tls_run_version() is just tls_compile_version() but with the runtime
-/* version instead of the compile-time version.
-/*
-/* tls_pkey_algorithms() returns a pointer to null-terminated
-/* array of string constants with the names of the supported
-/* public-key algorithms.
/* LICENSE
/* .ad
/* .fi
/*
* XXX: New with OpenSSL 1.1.1, this is turned on implicitly in
* SSL_CTX_new() and is not included in SSL_OP_ALL. Allowing users to
- * disable this would thus a code change that would clearing bug
- * work-around bits in SSL_CTX, after setting SSL_OP_ALL. Since this is
- * presumably required for TLS 1.3 on today's Internet, the code change
- * will be done separately later. For now this implicit bug work-around
- * cannot be disabled via supported Postfix mechanisms.
+ * disable this would thus be a code change that would require clearing
+ * bug work-around bits in SSL_CTX, after setting SSL_OP_ALL. Since this
+ * is presumably required for TLS 1.3 on today's Internet, the code
+ * change will be done separately later. For now this implicit bug
+ * work-around cannot be disabled via supported Postfix mechanisms.
*/
#ifndef SSL_OP_ENABLE_MIDDLEBOX_COMPAT
#define SSL_OP_ENABLE_MIDDLEBOX_COMPAT 0
return (app_ctx->cipher_list = mystrdup(new_list));
}
+/* tls_get_signature_params - TLS 1.3 signature details */
+
+void tls_get_signature_params(TLS_SESS_STATE *TLScontext)
+{
+#if OPENSSL_VERSION_NUMBER >= 0x1010100fUL && defined(TLS1_3_VERSION)
+ const char *kex_name = 0;
+ const char *kex_curve = 0;
+ const char *locl_sig_name = 0;
+ const char *locl_sig_curve = 0;
+ const char *locl_sig_dgst = 0;
+ const char *peer_sig_name = 0;
+ const char *peer_sig_curve = 0;
+ const char *peer_sig_dgst = 0;
+ int nid;
+ int got_kex_key;
+ SSL *ssl = TLScontext->con;
+ int srvr = SSL_is_server(ssl);
+ X509 *cert;
+ EVP_PKEY *pkey = 0;
+
+#ifndef OPENSSL_NO_EC
+ EC_KEY *eckey;
+
+#endif
+
+#define SIG_PROP(c, s, p) (*((s) ? &c->srvr_sig_##p : &c->clnt_sig_##p))
+
+ if (SSL_version(ssl) < TLS1_3_VERSION)
+ return;
+
+ if (tls_get_peer_dh_pubkey(ssl, &pkey)) {
+ switch (nid = EVP_PKEY_id(pkey)) {
+ default:
+ kex_name = OBJ_nid2sn(EVP_PKEY_type(nid));
+ break;
+
+ case EVP_PKEY_DH:
+ kex_name = "DHE";
+ TLScontext->kex_bits = EVP_PKEY_bits(pkey);
+ break;
+
+#ifndef OPENSSL_NO_EC
+ case EVP_PKEY_EC:
+ kex_name = "ECDHE";
+ eckey = EVP_PKEY_get0_EC_KEY(pkey);
+ nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey));
+ kex_curve = EC_curve_nid2nist(nid);
+ if (!kex_curve)
+ kex_curve = OBJ_nid2sn(nid);
+ break;
+#endif
+ }
+ EVP_PKEY_free(pkey);
+ }
+
+ /*
+ * On the client end, the certificate may be preset, but not used, so we
+ * check via SSL_get_signature_nid(). This means that local signature
+ * data on clients requires at least 1.1.1a.
+ */
+ if (srvr || SSL_get_signature_nid(ssl, &nid))
+ cert = SSL_get_certificate(ssl);
+ else
+ cert = 0;
+
+ /* Signature algorithms for the local end of the connection */
+ if (cert) {
+ pkey = X509_get0_pubkey(cert);
+
+ /*
+ * Override the built-in name for the "ECDSA" algorithms OID, with
+ * the more familiar name. For "RSA" keys report "RSA-PSS", which
+ * must be used with TLS 1.3.
+ */
+ if ((nid = EVP_PKEY_type(EVP_PKEY_id(pkey))) != NID_undef) {
+ switch (nid) {
+ default:
+ locl_sig_name = OBJ_nid2sn(nid);
+ break;
+
+ case EVP_PKEY_RSA:
+ /* For RSA, TLS 1.3 mandates PSS signatures */
+ locl_sig_name = "RSA-PSS";
+ SIG_PROP(TLScontext, srvr, bits) = EVP_PKEY_bits(pkey);
+ break;
+
+#ifndef OPENSSL_NO_EC
+ case EVP_PKEY_EC:
+ locl_sig_name = "ECDSA";
+ eckey = EVP_PKEY_get0_EC_KEY(pkey);
+ nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey));
+ locl_sig_curve = EC_curve_nid2nist(nid);
+ if (!locl_sig_curve)
+ locl_sig_curve = OBJ_nid2sn(nid);
+ break;
+#endif
+ }
+ }
+
+ /*
+ * With Ed25519 and Ed448 there is no pre-signature digest, but the
+ * accessor does not fail, rather we get NID_undef.
+ */
+ if (SSL_get_signature_nid(ssl, &nid) && nid != NID_undef)
+ locl_sig_dgst = OBJ_nid2sn(nid);
+ }
+ /* Signature algorithms for the peer end of the connection */
+ if ((cert = SSL_get_peer_certificate(ssl)) != 0) {
+ pkey = X509_get0_pubkey(cert);
+
+ /*
+ * Override the built-in name for the "ECDSA" algorithms OID, with
+ * the more familiar name. For "RSA" keys report "RSA-PSS", which
+ * must be used with TLS 1.3.
+ */
+ if ((nid = EVP_PKEY_type(EVP_PKEY_id(pkey))) != NID_undef) {
+ switch (nid) {
+ default:
+ peer_sig_name = OBJ_nid2sn(nid);
+ break;
+
+ case EVP_PKEY_RSA:
+ /* For RSA, TLS 1.3 mandates PSS signatures */
+ peer_sig_name = "RSA-PSS";
+ SIG_PROP(TLScontext, !srvr, bits) = EVP_PKEY_bits(pkey);
+ break;
+
+#ifndef OPENSSL_NO_EC
+ case EVP_PKEY_EC:
+ peer_sig_name = "ECDSA";
+ eckey = EVP_PKEY_get0_EC_KEY(pkey);
+ nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey));
+ peer_sig_curve = EC_curve_nid2nist(nid);
+ if (!peer_sig_curve)
+ peer_sig_curve = OBJ_nid2sn(nid);
+ break;
+#endif
+ }
+ }
+
+ /*
+ * With Ed25519 and Ed448 there is no pre-signature digest, but the
+ * accessor does not fail, rather we get NID_undef.
+ */
+ if (SSL_get_peer_signature_nid(ssl, &nid) && nid != NID_undef)
+ peer_sig_dgst = OBJ_nid2sn(nid);
+ }
+ if (kex_name) {
+ TLScontext->kex_name = mystrdup(kex_name);
+ if (kex_curve)
+ TLScontext->kex_curve = mystrdup(kex_curve);
+ }
+ if (locl_sig_name) {
+ SIG_PROP(TLScontext, srvr, name) = mystrdup(locl_sig_name);
+ if (locl_sig_curve)
+ SIG_PROP(TLScontext, srvr, curve) = mystrdup(locl_sig_curve);
+ if (locl_sig_dgst)
+ SIG_PROP(TLScontext, srvr, dgst) = mystrdup(locl_sig_dgst);
+ }
+ if (peer_sig_name) {
+ SIG_PROP(TLScontext, !srvr, name) = mystrdup(peer_sig_name);
+ if (peer_sig_curve)
+ SIG_PROP(TLScontext, !srvr, curve) = mystrdup(peer_sig_curve);
+ if (peer_sig_dgst)
+ SIG_PROP(TLScontext, !srvr, dgst) = mystrdup(peer_sig_dgst);
+ }
+#endif /* OPENSSL_VERSION_NUMBER ... */
+}
+
+/* tls_log_summary - TLS loglevel 1 one-liner, embellished with TLS 1.3 details */
+
+void tls_log_summary(TLS_ROLE role, TLS_USAGE usage, TLS_SESS_STATE *ctx)
+{
+ VSTRING *msg = vstring_alloc(100);
+ const char *direction = (role == TLS_ROLE_CLIENT) ? "to" : "from";
+
+ vstring_sprintf(msg, "%s TLS connection %s %s %s: %s"
+ " with cipher %s (%d/%d bits)",
+ !TLS_CERT_IS_PRESENT(ctx) ? "Anonymous" :
+ TLS_CERT_IS_SECURED(ctx) ? "Verified" :
+ TLS_CERT_IS_TRUSTED(ctx) ? "Trusted" : "Untrusted",
+ usage == TLS_USAGE_NEW ? "established" : "reused",
+ direction, ctx->namaddr, ctx->protocol, ctx->cipher_name,
+ ctx->cipher_usebits, ctx->cipher_algbits);
+
+ if (ctx->kex_name && *ctx->kex_name) {
+ vstring_sprintf_append(msg, " key-exchange %s", ctx->kex_name);
+ if (ctx->kex_curve && *ctx->kex_curve)
+ vstring_sprintf_append(msg, " (%s)", ctx->kex_curve);
+ else if (ctx->kex_bits > 0)
+ vstring_sprintf_append(msg, " (%d bits)", ctx->kex_bits);
+ }
+ if (ctx->srvr_sig_name && *ctx->srvr_sig_name) {
+ vstring_sprintf_append(msg, " server-signature %s",
+ ctx->srvr_sig_name);
+ if (ctx->srvr_sig_curve && *ctx->srvr_sig_curve)
+ vstring_sprintf_append(msg, " (%s)", ctx->srvr_sig_curve);
+ else if (ctx->srvr_sig_bits > 0)
+ vstring_sprintf_append(msg, " (%d bits)", ctx->srvr_sig_bits);
+ if (ctx->srvr_sig_dgst && *ctx->srvr_sig_dgst)
+ vstring_sprintf_append(msg, " server-digest %s",
+ ctx->srvr_sig_dgst);
+ }
+ if (ctx->clnt_sig_name && *ctx->clnt_sig_name) {
+ vstring_sprintf_append(msg, " client-signature %s",
+ ctx->clnt_sig_name);
+ if (ctx->clnt_sig_curve && *ctx->clnt_sig_curve)
+ vstring_sprintf_append(msg, " (%s)", ctx->clnt_sig_curve);
+ else if (ctx->clnt_sig_bits > 0)
+ vstring_sprintf_append(msg, " (%d bits)", ctx->clnt_sig_bits);
+ if (ctx->clnt_sig_dgst && *ctx->clnt_sig_dgst)
+ vstring_sprintf_append(msg, " client-digest %s",
+ ctx->clnt_sig_dgst);
+ }
+ msg_info("%s", vstring_str(msg));
+ vstring_free(msg);
+}
+
/* tls_alloc_app_context - allocate TLS application context */
TLS_APPL_STATE *tls_alloc_app_context(SSL_CTX *ssl_ctx, int log_mask)
TLScontext->peer_pkey_fprint = 0;
TLScontext->protocol = 0;
TLScontext->cipher_name = 0;
+ TLScontext->kex_name = 0;
+ TLScontext->kex_curve = 0;
+ TLScontext->clnt_sig_name = 0;
+ TLScontext->clnt_sig_curve = 0;
+ TLScontext->clnt_sig_dgst = 0;
+ TLScontext->srvr_sig_name = 0;
+ TLScontext->srvr_sig_curve = 0;
+ TLScontext->srvr_sig_dgst = 0;
TLScontext->log_mask = log_mask;
TLScontext->namaddr = lowercase(mystrdup(namaddr));
TLScontext->mdalg = 0; /* Alias for props->mdalg */
myfree((void *) tls_context->protocol);
if (tls_context->cipher_name)
myfree((void *) tls_context->cipher_name);
+ if (tls_context->kex_name)
+ myfree((void *) tls_context->kex_name);
+ if (tls_context->kex_curve)
+ myfree((void *) tls_context->kex_curve);
+ if (tls_context->clnt_sig_name)
+ myfree((void *) tls_context->clnt_sig_name);
+ if (tls_context->clnt_sig_curve)
+ myfree((void *) tls_context->clnt_sig_curve);
+ if (tls_context->clnt_sig_dgst)
+ myfree((void *) tls_context->clnt_sig_dgst);
+ if (tls_context->srvr_sig_name)
+ myfree((void *) tls_context->srvr_sig_name);
+ if (tls_context->srvr_sig_curve)
+ myfree((void *) tls_context->srvr_sig_curve);
+ if (tls_context->srvr_sig_dgst)
+ myfree((void *) tls_context->srvr_sig_dgst);
+ if (tls_context->namaddr)
+ myfree((void *) tls_context->namaddr);
myfree((void *) tls_context);
}
tp->cipher_usebits),
SEND_ATTR_INT(MAIL_ATTR_CIPHER_ALGBITS,
tp->cipher_algbits),
+ SEND_ATTR_STR(MAIL_ATTR_KEX_NAME,
+ STRING_OR_EMPTY(tp->kex_name)),
+ SEND_ATTR_STR(MAIL_ATTR_KEX_CURVE,
+ STRING_OR_EMPTY(tp->kex_curve)),
+ SEND_ATTR_INT(MAIL_ATTR_KEX_BITS,
+ tp->kex_bits),
+ SEND_ATTR_STR(MAIL_ATTR_CLNT_SIG_NAME,
+ STRING_OR_EMPTY(tp->clnt_sig_name)),
+ SEND_ATTR_STR(MAIL_ATTR_CLNT_SIG_CURVE,
+ STRING_OR_EMPTY(tp->clnt_sig_curve)),
+ SEND_ATTR_INT(MAIL_ATTR_CLNT_SIG_BITS,
+ tp->clnt_sig_bits),
+ SEND_ATTR_STR(MAIL_ATTR_CLNT_SIG_DGST,
+ STRING_OR_EMPTY(tp->clnt_sig_dgst)),
+ SEND_ATTR_STR(MAIL_ATTR_SRVR_SIG_NAME,
+ STRING_OR_EMPTY(tp->srvr_sig_name)),
+ SEND_ATTR_STR(MAIL_ATTR_SRVR_SIG_CURVE,
+ STRING_OR_EMPTY(tp->srvr_sig_curve)),
+ SEND_ATTR_INT(MAIL_ATTR_SRVR_SIG_BITS,
+ tp->srvr_sig_bits),
+ SEND_ATTR_STR(MAIL_ATTR_SRVR_SIG_DGST,
+ STRING_OR_EMPTY(tp->srvr_sig_dgst)),
+ SEND_ATTR_STR(MAIL_ATTR_NAMADDR,
+ STRING_OR_EMPTY(tp->namaddr)),
ATTR_TYPE_END);
return (ret);
}
VSTRING *peer_pkey_fprint = vstring_alloc(60); /* 60 for SHA-1 */
VSTRING *protocol = vstring_alloc(25);
VSTRING *cipher_name = vstring_alloc(25);
+ VSTRING *kex_name = vstring_alloc(25);
+ VSTRING *kex_curve = vstring_alloc(25);
+ VSTRING *clnt_sig_name = vstring_alloc(25);
+ VSTRING *clnt_sig_curve = vstring_alloc(25);
+ VSTRING *clnt_sig_dgst = vstring_alloc(25);
+ VSTRING *srvr_sig_name = vstring_alloc(25);
+ VSTRING *srvr_sig_curve = vstring_alloc(25);
+ VSTRING *srvr_sig_dgst = vstring_alloc(25);
+ VSTRING *namaddr = vstring_alloc(100);
/*
* Note: memset() is not a portable way to initialize non-integer types.
&tls_context->cipher_usebits),
RECV_ATTR_INT(MAIL_ATTR_CIPHER_ALGBITS,
&tls_context->cipher_algbits),
+ RECV_ATTR_STR(MAIL_ATTR_KEX_NAME, kex_name),
+ RECV_ATTR_STR(MAIL_ATTR_KEX_CURVE, kex_curve),
+ RECV_ATTR_INT(MAIL_ATTR_KEX_BITS, &tls_context->kex_bits),
+ RECV_ATTR_STR(MAIL_ATTR_CLNT_SIG_NAME, clnt_sig_name),
+ RECV_ATTR_STR(MAIL_ATTR_CLNT_SIG_CURVE, clnt_sig_curve),
+ RECV_ATTR_INT(MAIL_ATTR_CLNT_SIG_BITS, &tls_context->clnt_sig_bits),
+ RECV_ATTR_STR(MAIL_ATTR_CLNT_SIG_DGST, clnt_sig_dgst),
+ RECV_ATTR_STR(MAIL_ATTR_SRVR_SIG_NAME, srvr_sig_name),
+ RECV_ATTR_STR(MAIL_ATTR_SRVR_SIG_CURVE, srvr_sig_curve),
+ RECV_ATTR_INT(MAIL_ATTR_SRVR_SIG_BITS, &tls_context->srvr_sig_bits),
+ RECV_ATTR_STR(MAIL_ATTR_SRVR_SIG_DGST, srvr_sig_dgst),
+ RECV_ATTR_STR(MAIL_ATTR_NAMADDR, namaddr),
ATTR_TYPE_END);
tls_context->peer_CN = vstring_export(peer_CN);
tls_context->issuer_CN = vstring_export(issuer_CN);
tls_context->peer_pkey_fprint = vstring_export(peer_pkey_fprint);
tls_context->protocol = vstring_export(protocol);
tls_context->cipher_name = vstring_export(cipher_name);
- return (ret == 9 ? 1 : -1);
+ tls_context->kex_name = vstring_export(kex_name);
+ tls_context->kex_curve = vstring_export(kex_curve);
+ tls_context->clnt_sig_name = vstring_export(clnt_sig_name);
+ tls_context->clnt_sig_curve = vstring_export(clnt_sig_curve);
+ tls_context->clnt_sig_dgst = vstring_export(clnt_sig_dgst);
+ tls_context->srvr_sig_name = vstring_export(srvr_sig_name);
+ tls_context->srvr_sig_curve = vstring_export(srvr_sig_curve);
+ tls_context->srvr_sig_dgst = vstring_export(srvr_sig_dgst);
+ tls_context->namaddr = vstring_export(namaddr);
+ return (ret == 21 ? 1 : -1);
}
#endif
tls_stream_start(TLScontext->stream, TLScontext);
/*
- * All the key facts in a single log entry.
+ * With the handshake done, extract TLS 1.3 signature metadata.
*/
+ tls_get_signature_params(TLScontext);
+
if (TLScontext->log_mask & TLS_LOG_SUMMARY)
- msg_info("%s TLS connection established from %s: %s with cipher %s "
- "(%d/%d bits)", !TLS_CERT_IS_PRESENT(TLScontext) ? "Anonymous"
- : TLS_CERT_IS_TRUSTED(TLScontext) ? "Trusted" : "Untrusted",
- TLScontext->namaddr, TLScontext->protocol, TLScontext->cipher_name,
- TLScontext->cipher_usebits, TLScontext->cipher_algbits);
+ tls_log_summary(TLS_ROLE_SERVER, TLS_USAGE_NEW, TLScontext);
tls_int_seed();