From: Wietse Venema Date: Sat, 17 Nov 2018 05:00:00 +0000 (-0500) Subject: postfix-3.1.10-RC3 X-Git-Tag: v3.1.10-RC3^0 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c98ae3217a71547eb3afe15768e56217e5eee419;p=thirdparty%2Fpostfix.git postfix-3.1.10-RC3 --- diff --git a/postfix/.indent.pro b/postfix/.indent.pro index 5502f64db..13c628c34 100644 --- a/postfix/.indent.pro +++ b/postfix/.indent.pro @@ -343,6 +343,7 @@ -TTLS_PKEYS -TTLS_PRNG_SEED_INFO -TTLS_PRNG_SRC +-TTLS_ROLE -TTLS_SCACHE -TTLS_SCACHE_ENTRY -TTLS_SERVER_INIT_PROPS @@ -350,6 +351,7 @@ -TTLS_SESS_STATE -TTLS_TICKET_KEY -TTLS_TLSA +-TTLS_USAGE -TTLS_VINFO -TTLScontext_t -TTOK822 diff --git a/postfix/HISTORY b/postfix/HISTORY index c8181dcb0..e143546f9 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -22438,7 +22438,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. diff --git a/postfix/README_FILES/FORWARD_SECRECY_README b/postfix/README_FILES/FORWARD_SECRECY_README index fb40e4d58..88066f87d 100644 --- a/postfix/README_FILES/FORWARD_SECRECY_README +++ b/postfix/README_FILES/FORWARD_SECRECY_README @@ -14,7 +14,7 @@ is easily subverted by a state-funded adversary. OOvveerrvviieeww Postfix supports forward secrecy of TLS network communication since version -2.2. This support was adopted from Lutz Jänicke's "Postfix TLS patch" for +2.2. This support was adopted from Lutz Ja"nicke's "Postfix TLS patch" for earlier Postfix versions. This document will focus on TLS Forward Secrecy in the Postfix SMTP client and server. See TLS_README for a general description of Postfix TLS support. @@ -279,7 +279,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 @@ -292,7 +293,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 @@ -305,6 +307,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. @@ -346,6 +389,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 aallwwaayyss 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 + WWhhaatt ddoo ""AAnnoonnyymmoouuss"",, ""UUnnttrruusstteedd"",, eettcc.. iinn PPoossttffiixx llooggggiinngg mmeeaann?? The verification levels below are subject to man-in-the-middle attacks to @@ -421,8 +509,8 @@ peer certificate with expected public-key or certificate fingerprint) CCrreeddiittss - * TLS support for Postfix was originally developed by Lutz Jänicke at Cottbus - Technical University. + * TLS support for Postfix was originally developed by Lutz Ja"nicke at + Cottbus Technical University. * Wietse Venema adopted and restructured the code and documentation. * Viktor Dukhovni implemented support for many subsequent TLS features, including EECDH, and authored the initial version of this document. diff --git a/postfix/html/FORWARD_SECRECY_README.html b/postfix/html/FORWARD_SECRECY_README.html index d1364ef54..55da1464b 100644 --- a/postfix/html/FORWARD_SECRECY_README.html +++ b/postfix/html/FORWARD_SECRECY_README.html @@ -378,7 +378,9 @@ peer certificate or public-key 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:

    +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.

    @@ -395,7 +397,8 @@ from host.example.com[192.168.0.2]: TLSv1 with cipher cipher-name
     
  • With "smtpd_tls_received_header = yes", the Postfix SMTP server will record TLS connection information in the Received: header in the form of comments (text inside parentheses). The general -format depends on the smtpd_tls_ask_ccert setting: +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.

    @@ -411,6 +414,46 @@ Received: from host.example.com (host.example.com [192.168.0.2])
     
    +

    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))
    +
    +
    + +
      +
    • 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.

      + +
    • 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.

      + +
    • 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.

      + +
    • 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, @@ -462,6 +505,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.

    +

    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 always 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
    +
    +
    +

    What do "Anonymous", "Untrusted", etc. in Postfix logging mean?

    diff --git a/postfix/proto/FORWARD_SECRECY_README.html b/postfix/proto/FORWARD_SECRECY_README.html index 3db4ee843..a57486c65 100644 --- a/postfix/proto/FORWARD_SECRECY_README.html +++ b/postfix/proto/FORWARD_SECRECY_README.html @@ -378,7 +378,9 @@ peer certificate or public-key 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:

    +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.

    @@ -395,7 +397,8 @@ from host.example.com[192.168.0.2]: TLSv1 with cipher cipher-name
     
  • With "smtpd_tls_received_header = yes", the Postfix SMTP server will record TLS connection information in the Received: header in the form of comments (text inside parentheses). The general -format depends on the smtpd_tls_ask_ccert setting: +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.

    @@ -411,6 +414,46 @@ Received: from host.example.com (host.example.com [192.168.0.2])
     
    +

    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))
    +
    +
    + +
      +
    • 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.

      + +
    • 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.

      + +
    • 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.

      + +
    • 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, @@ -462,6 +505,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.

    +

    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 always 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
    +
    +
    +

    What do "Anonymous", "Untrusted", etc. in Postfix logging mean?

    diff --git a/postfix/src/global/ehlo_mask.c b/postfix/src/global/ehlo_mask.c index 1671beb3e..d5cb67b0a 100644 --- a/postfix/src/global/ehlo_mask.c +++ b/postfix/src/global/ehlo_mask.c @@ -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, }; diff --git a/postfix/src/global/mail_proto.h b/postfix/src/global/mail_proto.h index 1e427975a..6e541864b 100644 --- a/postfix/src/global/mail_proto.h +++ b/postfix/src/global/mail_proto.h @@ -291,6 +291,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" /* diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 2aff2d3f9..4d98162a2 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -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.1.10-RC2" +#define MAIL_RELEASE_DATE "20181117" +#define MAIL_VERSION_NUMBER "3.1.10-RC3" #ifdef SNAPSHOT #define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index 38fa90205..b54a7f094 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -3207,12 +3207,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); diff --git a/postfix/src/tls/tls.h b/postfix/src/tls/tls.h index 200e3485d..9232a1c11 100644 --- a/postfix/src/tls/tls.h +++ b/postfix/src/tls/tls.h @@ -109,6 +109,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 */ @@ -137,6 +153,17 @@ extern const char *str_tls_level(int); */ #include + /* + * 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. */ @@ -236,6 +263,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 */ @@ -431,7 +469,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 @@ -559,6 +602,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 diff --git a/postfix/src/tls/tls_client.c b/postfix/src/tls/tls_client.c index deb24f5ee..a006484b4 100644 --- a/postfix/src/tls/tls_client.c +++ b/postfix/src/tls/tls_client.c @@ -1141,16 +1141,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(); diff --git a/postfix/src/tls/tls_misc.c b/postfix/src/tls/tls_misc.c index 1f1dc24f2..5774175af 100644 --- a/postfix/src/tls/tls_misc.c +++ b/postfix/src/tls/tls_misc.c @@ -4,6 +4,25 @@ /* SUMMARY /* miscellaneous TLS support routines /* SYNOPSIS +/* .SH Public functions +/* .nf +/* .na +/* #include +/* +/* 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 /* @@ -61,6 +80,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) @@ -86,15 +108,24 @@ /* /* 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. @@ -142,6 +173,12 @@ /* 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. /* @@ -162,16 +199,6 @@ /* /* 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 @@ -364,11 +391,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 @@ -811,6 +838,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) @@ -878,6 +1123,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 */ diff --git a/postfix/src/tls/tls_proxy_clnt.c b/postfix/src/tls/tls_proxy_clnt.c index ea10fbda4..62f37992c 100644 --- a/postfix/src/tls/tls_proxy_clnt.c +++ b/postfix/src/tls/tls_proxy_clnt.c @@ -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); } diff --git a/postfix/src/tls/tls_proxy_print.c b/postfix/src/tls/tls_proxy_print.c index e30e8be88..ed08ed8b1 100644 --- a/postfix/src/tls/tls_proxy_print.c +++ b/postfix/src/tls/tls_proxy_print.c @@ -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); } diff --git a/postfix/src/tls/tls_proxy_scan.c b/postfix/src/tls/tls_proxy_scan.c index 29a0cd9f9..256781fa8 100644 --- a/postfix/src/tls/tls_proxy_scan.c +++ b/postfix/src/tls/tls_proxy_scan.c @@ -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 diff --git a/postfix/src/tls/tls_server.c b/postfix/src/tls/tls_server.c index 4bc6c08c7..5a3870403 100644 --- a/postfix/src/tls/tls_server.c +++ b/postfix/src/tls/tls_server.c @@ -961,14 +961,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();