]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-3.0.14-RC3 v3.0.14-RC3
authorWietse Venema <wietse@porcupine.org>
Sat, 17 Nov 2018 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Sun, 18 Nov 2018 00:11:21 +0000 (19:11 -0500)
16 files changed:
postfix/.indent.pro
postfix/HISTORY
postfix/README_FILES/FORWARD_SECRECY_README
postfix/html/FORWARD_SECRECY_README.html
postfix/proto/FORWARD_SECRECY_README.html
postfix/src/global/ehlo_mask.c
postfix/src/global/mail_proto.h
postfix/src/global/mail_version.h
postfix/src/smtpd/smtpd.c
postfix/src/tls/tls.h
postfix/src/tls/tls_client.c
postfix/src/tls/tls_misc.c
postfix/src/tls/tls_proxy_clnt.c
postfix/src/tls/tls_proxy_print.c
postfix/src/tls/tls_proxy_scan.c
postfix/src/tls/tls_server.c

index 0e9462f1912127ff19ddf2e925d28e017734d728..8febd003bfaae5c57cf4919a4a1c685a16d434ef 100644 (file)
 -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
index 7f0e6d2b5da14ad4d804130bd816b95c19d9a8ff..a5a36b6edf885936c7459eb0beb686fd26493793 100644 (file)
@@ -21943,7 +21943,27 @@ Apologies for any names omitted.
        tls/tls_client.c, tls/tls_rsa.c, posttls-finger/posttls-finger.c,
        .indent.pro.
 
+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 
 
+       More TLS updates for parity with Postfix 3.1 and later:
+       default DH parameters, and tls_set_eecdh_curve() memory
+       leak fix. Viktor Dukhovni. File: tls/tls_dh.c.
+
        Documentation: update documentation for Postfix versions
-       that support disabling TLS 1.3. File: proto/postconf.proto
+       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.
index 8d6fa3dac84f598f2976685b0004c8b2af288d81..6f39fbc18678da12bfe6463b27be8bd68690513b 100644 (file)
@@ -270,7 +270,8 @@ verification status.
 
   * 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
@@ -283,7 +284,8 @@ verification status.
   * 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
@@ -296,6 +298,47 @@ verification status.
                 (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 an 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.
 
@@ -337,6 +380,51 @@ The actual key length and raw algorithm key length are generally the same with
 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
index d395344a9210230827bb7edc91066b39689b97ae..08faf0281647679295257f6118067d992963c097 100644 (file)
@@ -370,7 +370,9 @@ peer certificate or public-key verification status.  </p>
 
 <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>
@@ -387,7 +389,8 @@ from host.example.com[192.168.0.2]: TLSv1 with cipher <i>cipher-name</i>
 <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>
@@ -403,6 +406,46 @@ Received: from host.example.com (host.example.com [192.168.0.2])
 </pre>
 </blockquote>
 
+<p> TLS 1.3 examples.  Some of the new attributes may not appear when not
+applicable or not available in an 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>,
@@ -454,6 +497,58 @@ are generally the same with non-export ciphers, but may they
 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>
 
index faf6a7b35293948069a65b50fe825c4f52a6ed6d..0a1d220d34cdd1cb21c7d49c6215b16e2b5f9dce 100644 (file)
@@ -370,7 +370,9 @@ peer certificate or public-key verification status.  </p>
 
 <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>
@@ -387,7 +389,8 @@ from host.example.com[192.168.0.2]: TLSv1 with cipher <i>cipher-name</i>
 <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>
@@ -403,6 +406,46 @@ Received: from host.example.com (host.example.com [192.168.0.2])
 </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>,
@@ -454,6 +497,58 @@ are generally the same with non-export ciphers, but may they
 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>
 
index 1671beb3ec0121bacbc02a93906e396852385576..d5cb67b0a7bd51d2ef4c29f51c2da36a3211b035 100644 (file)
@@ -77,6 +77,7 @@ static const NAME_MASK ehlo_mask_table[] = {
     "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,
 };
index c36090602481a4c46beff9829c26ce9462824f44..9b3171e5bab2cb848ce3a664ddb373945091306a 100644 (file)
@@ -290,6 +290,18 @@ extern char *mail_pathname(const char *, const char *);
 #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"
 
  /*
index 558eaa2f248f91e86547902d1b26608bafeeaaf3..99dd9e0bada577d0250e6138596065bb07dd2c6d 100644 (file)
@@ -20,8 +20,8 @@
   * 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.0.14-RC2"
+#define MAIL_RELEASE_DATE      "20181117"
+#define MAIL_VERSION_NUMBER    "3.0.14-RC3"
 
 #ifdef SNAPSHOT
 #define MAIL_VERSION_DATE      "-" MAIL_RELEASE_DATE
index 12360af186d7e2fed442414fbbf0ee9792129729..dd90b425e3fcb1baf1e432f182f6f391a4249027 100644 (file)
@@ -3149,12 +3149,70 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
 
 #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);
index 289b238d643b2f0e9c8304b752a2e02702ca519d..5c685a918b0c29d9a5af56c25eb5aaf79c254c3d 100644 (file)
@@ -104,6 +104,22 @@ extern const NAME_CODE tls_level_table[];
  /* 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 */
@@ -132,6 +148,17 @@ extern const NAME_CODE tls_level_table[];
   */
 #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.
   */
@@ -231,6 +258,17 @@ typedef struct {
     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 */
@@ -425,7 +463,12 @@ extern const NAME_CODE tls_cipher_grade_table[];
 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
@@ -547,6 +590,11 @@ extern TLS_SESS_STATE *tls_server_post_accept(TLS_SESS_STATE *);
   */
 extern void tls_session_stop(TLS_APPL_STATE *, VSTREAM *, int, int, TLS_SESS_STATE *);
 
+ /*
+  * tls_misc.c
+  */
+extern void tls_log_summary(TLS_ROLE, TLS_USAGE, TLS_SESS_STATE *);
+
 #ifdef TLS_INTERNAL
 
 #include <vstring.h>
index 9dd8eaa3b2af1cfc316266edaf70e9878d3433ef..0734d92a7db5608d66f92d9282e5130ae57dabd1 100644 (file)
@@ -1120,16 +1120,12 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props)
     tls_stream_start(props->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 (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_MATCHED(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();
 
index 4be5a1983ea3c59378ea9f2adbca448538ce1206..05afad26c312b2ab004d906d962331e17bfafd06 100644 (file)
@@ -4,6 +4,19 @@
 /* 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;
+/*
+/* .SH Internal functions
+/* .nf
+/* .na
 /*     #define TLS_INTERNAL
 /*     #include <tls.h>
 /*
@@ -60,6 +73,9 @@
 /*     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 routines that support the TLS client
-/*     and server internals.
+/*     This module implements public and internal routines that
+/*     support the TLS client and server.
+/*
+/*     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.
 /*
 /*     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.
 /*
@@ -341,11 +368,11 @@ static const LONG_NAME_MASK ssl_bug_tweaks[] = {
     /*
      * 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
@@ -799,6 +826,224 @@ const char *tls_set_ciphers(TLS_APPL_STATE *app_ctx, const char *context,
     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_MATCHED(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)
@@ -866,6 +1111,14 @@ TLS_SESS_STATE *tls_alloc_sess_context(int log_mask, const char *namaddr)
     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 */
index ea10fbda409531d847ab8b035677fae869b58f9e..62f37992cb38207937919cd3901e05a784ab9dc4 100644 (file)
@@ -239,6 +239,24 @@ void    tls_proxy_context_free(TLS_SESS_STATE *tls_context)
        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);
 }
 
index e30e8be88beea626dd26ef4e108f98ebed450354..ed08ed8b12dadf35024fd2a954c2c7281b336a20 100644 (file)
@@ -79,6 +79,30 @@ int     tls_proxy_context_print(ATTR_PRINT_MASTER_FN print_fn, VSTREAM *fp,
                                 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);
 }
index 29a0cd9f97ebaa5101f00f339915f4a5e670641c..256781fa816e8e37e92d36d4b00f72dd07f99c8e 100644 (file)
@@ -63,6 +63,15 @@ int     tls_proxy_context_scan(ATTR_SCAN_MASTER_FN scan_fn, VSTREAM *fp,
     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.
@@ -81,6 +90,18 @@ int     tls_proxy_context_scan(ATTR_SCAN_MASTER_FN scan_fn, VSTREAM *fp,
                                &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);
@@ -88,7 +109,16 @@ int     tls_proxy_context_scan(ATTR_SCAN_MASTER_FN scan_fn, VSTREAM *fp,
     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
index b076af2cb66281d71cd1611dcfc82cb919a00084..a3c71bf174bb50c1c4d985de86e686528be7415e 100644 (file)
@@ -952,14 +952,12 @@ TLS_SESS_STATE *tls_server_post_accept(TLS_SESS_STATE *TLScontext)
        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();