]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-3.3.2-RC3 v3.3.2-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:24:12 +0000 (19:24 -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 6a98ec87e09507af9b4bc0cb17f8f1d0c191dcdd..ec8d3b6d36601c003927c53d2d075e97ceafe2fe 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 71c6c50ad264e69785160abfbb3b9a2941305dc0..b84fbcab7f4e5ea28a01f9c352cd4087038dd89c 100644 (file)
@@ -23389,7 +23389,23 @@ Apologies for any names omitted.
        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.
index 13c161832f33e872818ddeb4ab7b433cf6a1828c..d59b99e92e5a7861c9893472e98c6f5e6b0a3743 100644 (file)
@@ -294,7 +294,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
@@ -307,7 +308,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
@@ -320,6 +322,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 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.
 
@@ -361,6 +404,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 eb183c10eb63981b39351a78a9b7e54b52b0356b..18a83818b7845d52ed337d43b110ac3821d61c4e 100644 (file)
@@ -397,7 +397,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>
@@ -414,7 +416,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>
@@ -430,6 +433,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 "<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>,
@@ -481,6 +524,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 b0d96bd9e1247083e7cc7d3f5d93ea94712516a9..f549e4a1c89174c962ed7d727f05365b665c2fc7 100644 (file)
@@ -397,7 +397,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>
@@ -414,7 +416,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>
@@ -430,6 +433,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>,
@@ -481,6 +524,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 363bc71ec84d0510ada614ea91217846ead322cc..3b18333ab128f6fa615b9c7be82744fba0644abf 100644 (file)
@@ -293,6 +293,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 20ae5674d4ceb505174a11569680491fc83f5b4e..48474e614accc59813412f1de20c33f89f60d542 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.3.2-RC2"
+#define MAIL_RELEASE_DATE      "20181117"
+#define MAIL_VERSION_NUMBER    "3.3.2-RC3"
 
 #ifdef SNAPSHOT
 #define MAIL_VERSION_DATE      "-" MAIL_RELEASE_DATE
index 20598992b7db35f94be471f65066fd21b61b1f72..7dc4b69281ea10f09e388c7501037329d498ea48 100644 (file)
@@ -3244,12 +3244,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 dfd2cbc75f0509b1bc45c37b4af7c09395a15beb..2cd1b5b968e42093b171161969bebfab2717f81d 100644 (file)
@@ -112,6 +112,22 @@ extern const char *str_tls_level(int);
  /* 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 */
@@ -140,6 +156,17 @@ extern const char *str_tls_level(int);
   */
 #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.
   */
@@ -239,6 +266,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 */
@@ -434,7 +472,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
@@ -562,6 +605,7 @@ extern void tls_session_stop(TLS_APPL_STATE *, VSTREAM *, int, int, TLS_SESS_STA
 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
 
index bbe18f9050fba1cd5aff8ce8842914567b6f919e..6bc1c3acd0f8fb4e5536bc548b56f9cb98a1cb66 100644 (file)
@@ -1140,16 +1140,12 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props)
        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();
 
index 351f576cc7b48c2a50e22516a7e98b6205a81a91..9460d9fd605f1f8876977c39d4141434be25a3a5 100644 (file)
@@ -4,6 +4,25 @@
 /* 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>
 /*
@@ -62,6 +81,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 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
@@ -366,11 +393,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
@@ -826,6 +853,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_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)
@@ -893,6 +1138,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 ee715c07f9fa73a57de49525987682a7c8e11630..9c25c2fe28cce33e454a9a49f681281c00409ada 100644 (file)
@@ -953,14 +953,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();