Prereq: "3.0.13" diff -ur --new-file /var/tmp/postfix-3.0.13/src/global/mail_version.h ./src/global/mail_version.h --- /var/tmp/postfix-3.0.13/src/global/mail_version.h 2018-05-19 16:50:07.000000000 -0400 +++ ./src/global/mail_version.h 2018-11-24 17:38:19.000000000 -0500 @@ -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 "20180519" -#define MAIL_VERSION_NUMBER "3.0.13" +#define MAIL_RELEASE_DATE "20181124" +#define MAIL_VERSION_NUMBER "3.0.14" #ifdef SNAPSHOT #define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE diff -ur --new-file /var/tmp/postfix-3.0.13/.indent.pro ./.indent.pro --- /var/tmp/postfix-3.0.13/.indent.pro 2015-01-11 08:28:18.000000000 -0500 +++ ./.indent.pro 2018-11-17 18:30:19.000000000 -0500 @@ -342,6 +342,7 @@ -TTLS_PKEYS -TTLS_PRNG_SEED_INFO -TTLS_PRNG_SRC +-TTLS_ROLE -TTLS_SCACHE -TTLS_SCACHE_ENTRY -TTLS_SERVER_INIT_PROPS @@ -349,6 +350,7 @@ -TTLS_SESS_STATE -TTLS_TICKET_KEY -TTLS_TLSA +-TTLS_USAGE -TTLS_VINFO -TTLScontext_t -TTOK822 @@ -404,5 +406,4 @@ -Tssl_comp_stack_t -Ttime_t -Ttlsa_filter --Tx509_extension_stack_t -Tx509_stack_t diff -ur --new-file /var/tmp/postfix-3.0.13/HISTORY ./HISTORY --- /var/tmp/postfix-3.0.13/HISTORY 2018-05-19 09:45:27.000000000 -0400 +++ ./HISTORY 2018-11-17 18:44:05.000000000 -0500 @@ -21923,3 +21923,47 @@ error propagation in tlsproxy(8) resulting in segfault after TLS handshake error. Found during code maintenance. File: tlsproxy/tlsproxy.c. + +20180617 + + Bugfix (introduced: Postfix 2.11): minor memory leak when + minting issuer certs. This affects a tiny minority of use + cases. Viktor Dukhovni, based on a fix by Juan Altmayer + Pizzorno for the ssl_dane library. File: tls/tls_dane.c. + +20181104 + + Multiple 'bit rot' fixes for OpenSSL API changes, including + support to disable TLSv1.3, to avoid issuing multiple session + tickets, and to allow OpenSSL >= 1.1.0 run-time micro version + bumps without complaining about library version mismatches. + Viktor Dukhovni. Files: proto/postconf.proto, + proto/TLS_README.html, tls/tls.h, tls/tls_verify.c, + tls/tls_fprint.c, tls/tls_misc.c, tls/tls_server.c, + tls/tls_client.c, tls/tls_rsa.c, posttls-finger/posttls-finger.c, + .indent.pro. + +20181106 + + Bugfix (introduced: 3.0): smtpd_discard_ehlo_keywords could + not disable "SMTPUTF8". because the lookup table was using + "EHLO_MASK_SMTPUTF8" instead. File: global/ehlo_mask.c. + +20181110 + + More TLS updates for parity with Postfix 3.1 and later: + default DH parameters, and tls_set_eecdh_curve() memory + leak fix. Viktor Dukhovni. File: tls/tls_dh.c. + + Documentation: update documentation for Postfix versions + that support disabling TLS 1.3. File: proto/postconf.proto. + +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 -ur --new-file /var/tmp/postfix-3.0.13/README_FILES/AAAREADME ./README_FILES/AAAREADME --- /var/tmp/postfix-3.0.13/README_FILES/AAAREADME 2014-11-26 18:25:35.000000000 -0500 +++ ./README_FILES/AAAREADME 2018-11-18 08:34:33.000000000 -0500 @@ -12,7 +12,6 @@ * TLS_README: TLS Encryption and authentication * FORWARD_SECRECY_README: TLS Forward Secrecy * IPV6_README: IP Version 6 Support - * IPV6_README: IP Version 6 Support * SMTPUTF8_README: SMTPUTF8 Support * COMPATIBILITY_README: Backwards-Compatibility Safety Net * INSTALL: Installation from source code diff -ur --new-file /var/tmp/postfix-3.0.13/README_FILES/FORWARD_SECRECY_README ./README_FILES/FORWARD_SECRECY_README --- /var/tmp/postfix-3.0.13/README_FILES/FORWARD_SECRECY_README 2017-12-26 10:52:21.000000000 -0500 +++ ./README_FILES/FORWARD_SECRECY_README 2018-11-18 08:34:33.000000000 -0500 @@ -270,7 +270,8 @@ * With "smtp_tls_loglevel = 1" and "smtpd_tls_loglevel = 1", the Postfix SMTP client and server will log TLS connection information to the maillog file. - The general logfile format is: + The general logfile format is shown below. With TLS 1.3 there may be + additional properties logged after the cipher name and bits. postfix/smtp[process-id]: Untrusted TLS connection established to host.example.com[192.168.0.2]:25: TLSv1 with cipher cipher-name @@ -283,7 +284,8 @@ * With "smtpd_tls_received_header = yes", the Postfix SMTP server will record TLS connection information in the Received: header in the form of comments (text inside parentheses). The general format depends on the - smtpd_tls_ask_ccert setting: + smtpd_tls_ask_ccert setting. With TLS 1.3 there may be additional + properties logged after the cipher name and bits. Received: from host.example.com (host.example.com [192.168.0.2]) (using TLSv1 with cipher cipher-name @@ -296,6 +298,47 @@ (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. @@ -337,6 +380,51 @@ 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 diff -ur --new-file /var/tmp/postfix-3.0.13/README_FILES/TLS_README ./README_FILES/TLS_README --- /var/tmp/postfix-3.0.13/README_FILES/TLS_README 2015-07-20 19:00:12.000000000 -0400 +++ ./README_FILES/TLS_README 2018-11-04 17:55:37.000000000 -0500 @@ -657,11 +657,12 @@ smtpd_starttls_timeout = 300s With Postfix 2.8 and later, the tls_disable_workarounds parameter specifies a -list or bit-mask of OpenSSL bug work-arounds to disable. This may be necessary -if one of the work-arounds enabled by default in OpenSSL proves to pose a -security risk, or introduces an unexpected interoperability issue. Some bug -work-arounds known to be problematic are disabled in the default value of the -parameter when linked with an OpenSSL library that could be vulnerable. +list or bit-mask of default-enabled OpenSSL bug work-arounds to disable. This +may be necessary if one of the work-arounds enabled by default in OpenSSL +proves to pose a security risk, or introduces an unexpected interoperability +issue. The list of enabled bug work-arounds is OpenSSL-release-specific. See +the tls_disable_workarounds parameter documentation for the list of supported +values. Example: @@ -674,16 +675,9 @@ below, or a hexadecimal bitmask of options found in the ssl.h file corresponding to the run-time OpenSSL library. While it may be reasonable to turn off all bug workarounds (see above), it is not a good idea to attempt to -turn on all features. +turn on all features. See the tls_ssl_options parameter documentation for the +list of supported values. -LLEEGGAACCYY__SSEERRVVEERR__CCOONNNNEECCTT - See SSL_CTX_set_options(3). -NNOO__TTIICCKKEETT - See SSL_CTX_set_options(3). -NNOO__CCOOMMPPRREESSSSIIOONN - Disable SSL compression even if supported by the OpenSSL library. - Compression is CPU-intensive, and compression before encryption does not - always improve security. Example: /etc/postfix/main.cf: diff -ur --new-file /var/tmp/postfix-3.0.13/html/FORWARD_SECRECY_README.html ./html/FORWARD_SECRECY_README.html --- /var/tmp/postfix-3.0.13/html/FORWARD_SECRECY_README.html 2017-12-26 10:52:21.000000000 -0500 +++ ./html/FORWARD_SECRECY_README.html 2018-11-18 08:34:33.000000000 -0500 @@ -370,7 +370,9 @@
  • 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.

    @@ -387,7 +389,8 @@
     
  • 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.

    @@ -403,6 +406,46 @@
     
    +

    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, @@ -454,6 +497,58 @@ 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 -ur --new-file /var/tmp/postfix-3.0.13/html/TLS_README.html ./html/TLS_README.html --- /var/tmp/postfix-3.0.13/html/TLS_README.html 2015-07-20 19:00:12.000000000 -0400 +++ ./html/TLS_README.html 2018-11-04 17:55:34.000000000 -0500 @@ -917,12 +917,13 @@
  • With Postfix 2.8 and later, the tls_disable_workarounds parameter -specifies a list or bit-mask of OpenSSL bug work-arounds to disable. This -may be necessary if one of the work-arounds enabled by default in -OpenSSL proves to pose a security risk, or introduces an unexpected -interoperability issue. Some bug work-arounds known to be problematic -are disabled in the default value of the parameter when linked with -an OpenSSL library that could be vulnerable.

    +specifies a list or bit-mask of default-enabled OpenSSL bug +work-arounds to disable. This may be necessary if one of the +work-arounds enabled by default in OpenSSL proves to pose a security +risk, or introduces an unexpected interoperability issue. The list +of enabled bug work-arounds is OpenSSL-release-specific. See the +tls_disable_workarounds parameter documentation for the list of +supported values.

    Example:

    @@ -940,19 +941,8 @@ found in the ssl.h file corresponding to the run-time OpenSSL library. While it may be reasonable to turn off all bug workarounds (see above), it is not a good idea to attempt to turn on all features. -

    - -
    - -
    LEGACY_SERVER_CONNECT
    See SSL_CTX_set_options(3).
    - -
    NO_TICKET
    See SSL_CTX_set_options(3).
    - -
    NO_COMPRESSION
    Disable SSL compression even if -supported by the OpenSSL library. Compression is CPU-intensive, -and compression before encryption does not always improve security.
    - -
    +See the tls_ssl_options parameter documentation for the list of +supported values.

    Example:

    diff -ur --new-file /var/tmp/postfix-3.0.13/html/index.html ./html/index.html --- /var/tmp/postfix-3.0.13/html/index.html 2014-11-26 18:25:31.000000000 -0500 +++ ./html/index.html 2018-11-18 08:23:43.000000000 -0500 @@ -46,8 +46,6 @@
  • IP Version 6 Support -
  • IP Version 6 Support -
  • SMTPUTF8 Support
  • Backwards-Compatibility Safety Net diff -ur --new-file /var/tmp/postfix-3.0.13/html/postconf.5.html ./html/postconf.5.html --- /var/tmp/postfix-3.0.13/html/postconf.5.html 2016-02-04 19:29:25.000000000 -0500 +++ ./html/postconf.5.html 2018-11-10 18:54:17.000000000 -0500 @@ -12125,8 +12125,10 @@

    The range of protocols advertised by an SSL/TLS client must be contiguous. When a protocol version is enabled, disabling any -higher version implicitly disables all versions above that higher -version. Thus, for example:

    +higher version implicitly disables all versions above that higher version. +Thus, for example (assuming the OpenSSL library supports both SSLv2 +and SSLv3): +

     smtp_tls_mandatory_protocols = !SSLv2, !TLSv1
    @@ -12143,6 +12145,10 @@
     versions of Postfix ≥ 2.10 can explicitly disable support for
     "TLSv1.1" or "TLSv1.2". 

    +

    OpenSSL 1.1.1 introduces support for "TLSv1.3". With Postfix +≥ 3.4 (or patch releases ≥ 3.0.14, 3.1.10, 3.2.7 and 3.3.2) +this can be disabled, if need be, via "!TLSv1.3".

    +

    At the dane and dane-only security levels, when usable TLSA records are obtained for the remote SMTP @@ -12455,11 +12461,13 @@

    The range of protocols advertised by an SSL/TLS client must be contiguous. When a protocol version is enabled, disabling any -higher version implicitly disables all versions above that higher -version. Thus, for example:

    +higher version implicitly disables all versions above that higher version. +Thus, for example (assuming the OpenSSL library supports both SSLv2 +and SSLv3): +

    -smtp_tls_mandatory_protocols = !SSLv2, !TLSv1
    +smtp_tls_protocols = !SSLv2, !TLSv1
     

    also disables any protocols version higher than TLSv1 leaving @@ -12470,6 +12478,10 @@ versions of Postfix ≥ 2.10 can explicitly disable support for "TLSv1.1" or "TLSv1.2"

    +

    OpenSSL 1.1.1 introduces support for "TLSv1.3". With Postfix +≥ 3.4 (or patch releases ≥ 3.0.14, 3.1.10, 3.2.7 and 3.3.2) +this can be disabled, if need be, via "!TLSv1.3".

    +

    To include a protocol list its name, to exclude it, prefix the name with a "!" character. To exclude SSLv2 for opportunistic TLS set "smtp_tls_protocols = !SSLv2". To exclude both "SSLv2" and "SSLv3" set @@ -16487,6 +16499,10 @@ versions of Postfix ≥ 2.10 can disable support for "TLSv1.1" or "TLSv1.2".

    +

    OpenSSL 1.1.1 introduces support for "TLSv1.3". With Postfix +≥ 3.4 (or patch releases ≥ 3.0.14, 3.1.10, 3.2.7 and 3.3.2) +this can be disabled, if need be, via "!TLSv1.3".

    +

    Example:

    @@ -16518,6 +16534,10 @@
     versions of Postfix ≥ 2.10 can disable support for "TLSv1.1" or
     "TLSv1.2". 

    +

    OpenSSL 1.1.1 introduces support for "TLSv1.3". With Postfix +≥ 3.4 (or patch releases ≥ 3.0.14, 3.1.10, 3.2.7 and 3.3.2) +this can be disabled, if need be, via "!TLSv1.3".

    +

    To include a protocol list its name, to exclude it, prefix the name with a "!" character. To exclude SSLv2 for opportunistic TLS set "smtpd_tls_protocols = !SSLv2". To exclude both "SSLv2" and "SSLv3" set @@ -17324,44 +17344,46 @@

    -
    MICROSOFT_SESS_ID_BUG
    See SSL_CTX_set_options(3)
    +
    CRYPTOPRO_TLSEXT_BUG
    New with GOST support in +OpenSSL 1.0.0.
    -
    NETSCAPE_CHALLENGE_BUG
    See SSL_CTX_set_options(3)
    +
    DONT_INSERT_EMPTY_FRAGMENTS
    See +SSL_CTX_set_options(3)
    LEGACY_SERVER_CONNECT
    See SSL_CTX_set_options(3)
    -
    NETSCAPE_REUSE_CIPHER_CHANGE_BUG
    also aliased -as CVE-2010-4180. Postfix 2.8 disables this work-around by -default with OpenSSL versions that may predate the fix. Fixed in -OpenSSL 0.9.8q and OpenSSL 1.0.0c.
    - -
    SSLREF2_REUSE_CERT_TYPE_BUG
    See -SSL_CTX_set_options(3)
    -
    MICROSOFT_BIG_SSLV3_BUFFER
    See SSL_CTX_set_options(3)
    +
    MICROSOFT_SESS_ID_BUG
    See SSL_CTX_set_options(3)
    +
    MSIE_SSLV2_RSA_PADDING
    also aliased as CVE-2005-2969. Postfix 2.8 disables this work-around by default with OpenSSL versions that may predate the fix. Fixed in OpenSSL 0.9.7h and OpenSSL 0.9.8a.
    +
    NETSCAPE_CHALLENGE_BUG
    See SSL_CTX_set_options(3)
    + +
    NETSCAPE_REUSE_CIPHER_CHANGE_BUG
    also aliased +as CVE-2010-4180. Postfix 2.8 disables this work-around by +default with OpenSSL versions that may predate the fix. Fixed in +OpenSSL 0.9.8q and OpenSSL 1.0.0c.
    +
    SSLEAY_080_CLIENT_DH_BUG
    See SSL_CTX_set_options(3)
    -
    TLS_D5_BUG
    See SSL_CTX_set_options(3)
    +
    SSLREF2_REUSE_CERT_TYPE_BUG
    See +SSL_CTX_set_options(3)
    TLS_BLOCK_PADDING_BUG
    See SSL_CTX_set_options(3)
    +
    TLS_D5_BUG
    See SSL_CTX_set_options(3)
    +
    TLS_ROLLBACK_BUG
    See SSL_CTX_set_options(3). This is disabled in OpenSSL 0.9.7 and later. Nobody should still be using 0.9.6!
    -
    DONT_INSERT_EMPTY_FRAGMENTS
    See -SSL_CTX_set_options(3)
    - -
    CRYPTOPRO_TLSEXT_BUG
    New with GOST support in -OpenSSL 1.0.0.
    +
    TLSEXT_PADDING
    Postfix ≥ 3.4. See SSL_CTX_set_options(3).
    @@ -17708,18 +17730,39 @@ You can only enable options not already controlled by other Postfix settings. For example, you cannot disable protocols or enable server cipher preference. Do not attempt to turn all features by -specifying 0xFFFFFFFF, this is unlikely to be a good idea.

    +specifying 0xFFFFFFFF, this is unlikely to be a good idea. Some +bug work-arounds are also valid here, allowing them to be re-enabled +if/when they're no longer enabled by default. The supported values +include:

    +
    ENABLE_MIDDLEBOX_COMPAT
    Postfix ≥ 3.4. See +SSL_CTX_set_options(3).
    +
    LEGACY_SERVER_CONNECT
    See SSL_CTX_set_options(3).
    -
    NO_TICKET
    See SSL_CTX_set_options(3).
    +
    NO_TICKET
    Enabled by default when needed in +fully-patched Postfix ≥ 2.7. Not needed at all for Postfix ≥ +2.11, unless for some reason you do not want to support TLS session +resumption. Best not set explicitly. See SSL_CTX_set_options(3).
    NO_COMPRESSION
    Disable SSL compression even if supported by the OpenSSL library. Compression is CPU-intensive, and compression before encryption does not always improve security.
    +
    NO_RENEGOTIATION
    Postfix ≥ 3.4. This can +reduce opportunities for a potential CPU exhaustion attack. See +SSL_CTX_set_options(3).
    + +
    NO_SESSION_RESUMPTION_ON_RENEGOTIATION
    Postfix +≥ 3.4. See SSL_CTX_set_options(3).
    + +
    PRIORITIZE_CHACHA
    Postfix ≥ 3.4. See SSL_CTX_set_options(3).
    + +
    TLSEXT_PADDING
    Postfix ≥ 3.4. See +SSL_CTX_set_options(3).
    +

    This feature is available in Postfix 2.11 and later.

    diff -ur --new-file /var/tmp/postfix-3.0.13/man/man5/postconf.5 ./man/man5/postconf.5 --- /var/tmp/postfix-3.0.13/man/man5/postconf.5 2016-02-04 19:29:25.000000000 -0500 +++ ./man/man5/postconf.5 2018-11-10 18:54:17.000000000 -0500 @@ -7763,8 +7763,9 @@ .PP The range of protocols advertised by an SSL/TLS client must be contiguous. When a protocol version is enabled, disabling any -higher version implicitly disables all versions above that higher -version. Thus, for example: +higher version implicitly disables all versions above that higher version. +Thus, for example (assuming the OpenSSL library supports both SSLv2 +and SSLv3): .sp .in +4 .nf @@ -7786,6 +7787,10 @@ versions of Postfix >= 2.10 can explicitly disable support for "TLSv1.1" or "TLSv1.2". .PP +OpenSSL 1.1.1 introduces support for "TLSv1.3". With Postfix +>= 3.4 (or patch releases >= 3.0.14, 3.1.10, 3.2.7 and 3.3.2) +this can be disabled, if need be, via "!TLSv1.3". +.PP At the dane and dane\-only security levels, when usable TLSA records are obtained for the remote SMTP @@ -8081,14 +8086,15 @@ .PP The range of protocols advertised by an SSL/TLS client must be contiguous. When a protocol version is enabled, disabling any -higher version implicitly disables all versions above that higher -version. Thus, for example: +higher version implicitly disables all versions above that higher version. +Thus, for example (assuming the OpenSSL library supports both SSLv2 +and SSLv3): .sp .in +4 .nf .na .ft C -smtp_tls_mandatory_protocols = !SSLv2, !TLSv1 +smtp_tls_protocols = !SSLv2, !TLSv1 .fi .ad .ft R @@ -8101,6 +8107,10 @@ versions of Postfix >= 2.10 can explicitly disable support for "TLSv1.1" or "TLSv1.2" .PP +OpenSSL 1.1.1 introduces support for "TLSv1.3". With Postfix +>= 3.4 (or patch releases >= 3.0.14, 3.1.10, 3.2.7 and 3.3.2) +this can be disabled, if need be, via "!TLSv1.3". +.PP To include a protocol list its name, to exclude it, prefix the name with a "!" character. To exclude SSLv2 for opportunistic TLS set "smtp_tls_protocols = !SSLv2". To exclude both "SSLv2" and "SSLv3" set @@ -11306,6 +11316,10 @@ versions of Postfix >= 2.10 can disable support for "TLSv1.1" or "TLSv1.2". .PP +OpenSSL 1.1.1 introduces support for "TLSv1.3". With Postfix +>= 3.4 (or patch releases >= 3.0.14, 3.1.10, 3.2.7 and 3.3.2) +this can be disabled, if need be, via "!TLSv1.3". +.PP Example: .PP .nf @@ -11335,6 +11349,10 @@ versions of Postfix >= 2.10 can disable support for "TLSv1.1" or "TLSv1.2". .PP +OpenSSL 1.1.1 introduces support for "TLSv1.3". With Postfix +>= 3.4 (or patch releases >= 3.0.14, 3.1.10, 3.2.7 and 3.3.2) +this can be disabled, if need be, via "!TLSv1.3". +.PP To include a protocol list its name, to exclude it, prefix the name with a "!" character. To exclude SSLv2 for opportunistic TLS set "smtpd_tls_protocols = !SSLv2". To exclude both "SSLv2" and "SSLv3" set @@ -11911,57 +11929,60 @@ is possible that your OpenSSL version includes new bug work\-arounds added after your Postfix source code was last updated, in that case you can only disable one of these via the hexadecimal syntax above. -.IP "\fBMICROSOFT_SESS_ID_BUG\fR" -See SSL_CTX_\fBset_options\fR(3) +.IP "\fBCRYPTOPRO_TLSEXT_BUG\fR" +New with GOST support in +OpenSSL 1.0.0. .br -.IP "\fBNETSCAPE_CHALLENGE_BUG\fR" -See SSL_CTX_\fBset_options\fR(3) +.IP "\fBDONT_INSERT_EMPTY_FRAGMENTS\fR" +See +SSL_CTX_\fBset_options\fR(3) .br .IP "\fBLEGACY_SERVER_CONNECT\fR" See SSL_CTX_\fBset_options\fR(3) .br -.IP "\fBNETSCAPE_REUSE_CIPHER_CHANGE_BUG\fR" -also aliased -as \fBCVE\-2010\-4180\fR. Postfix 2.8 disables this work\-around by -default with OpenSSL versions that may predate the fix. Fixed in -OpenSSL 0.9.8q and OpenSSL 1.0.0c. -.br -.IP "\fBSSLREF2_REUSE_CERT_TYPE_BUG\fR" -See -SSL_CTX_\fBset_options\fR(3) -.br .IP "\fBMICROSOFT_BIG_SSLV3_BUFFER\fR" See SSL_CTX_\fBset_options\fR(3) .br +.IP "\fBMICROSOFT_SESS_ID_BUG\fR" +See SSL_CTX_\fBset_options\fR(3) +.br .IP "\fBMSIE_SSLV2_RSA_PADDING\fR" also aliased as \fBCVE\-2005\-2969\fR. Postfix 2.8 disables this work\-around by default with OpenSSL versions that may predate the fix. Fixed in OpenSSL 0.9.7h and OpenSSL 0.9.8a. .br +.IP "\fBNETSCAPE_CHALLENGE_BUG\fR" +See SSL_CTX_\fBset_options\fR(3) +.br +.IP "\fBNETSCAPE_REUSE_CIPHER_CHANGE_BUG\fR" +also aliased +as \fBCVE\-2010\-4180\fR. Postfix 2.8 disables this work\-around by +default with OpenSSL versions that may predate the fix. Fixed in +OpenSSL 0.9.8q and OpenSSL 1.0.0c. +.br .IP "\fBSSLEAY_080_CLIENT_DH_BUG\fR" See SSL_CTX_\fBset_options\fR(3) .br -.IP "\fBTLS_D5_BUG\fR" -See SSL_CTX_\fBset_options\fR(3) +.IP "\fBSSLREF2_REUSE_CERT_TYPE_BUG\fR" +See +SSL_CTX_\fBset_options\fR(3) .br .IP "\fBTLS_BLOCK_PADDING_BUG\fR" See SSL_CTX_\fBset_options\fR(3) .br +.IP "\fBTLS_D5_BUG\fR" +See SSL_CTX_\fBset_options\fR(3) +.br .IP "\fBTLS_ROLLBACK_BUG\fR" See SSL_CTX_\fBset_options\fR(3). This is disabled in OpenSSL 0.9.7 and later. Nobody should still be using 0.9.6! .br -.IP "\fBDONT_INSERT_EMPTY_FRAGMENTS\fR" -See -SSL_CTX_\fBset_options\fR(3) -.br -.IP "\fBCRYPTOPRO_TLSEXT_BUG\fR" -New with GOST support in -OpenSSL 1.0.0. +.IP "\fBTLSEXT_PADDING\fR" +Postfix >= 3.4. See SSL_CTX_\fBset_options\fR(3). .br .br .PP @@ -12206,18 +12227,44 @@ You can only enable options not already controlled by other Postfix settings. For example, you cannot disable protocols or enable server cipher preference. Do not attempt to turn all features by -specifying 0xFFFFFFFF, this is unlikely to be a good idea. +specifying 0xFFFFFFFF, this is unlikely to be a good idea. Some +bug work\-arounds are also valid here, allowing them to be re\-enabled +if/when they're no longer enabled by default. The supported values +include: +.IP "\fBENABLE_MIDDLEBOX_COMPAT\fR" +Postfix >= 3.4. See +SSL_CTX_\fBset_options\fR(3). +.br .IP "\fBLEGACY_SERVER_CONNECT\fR" See SSL_CTX_\fBset_options\fR(3). .br .IP "\fBNO_TICKET\fR" -See SSL_CTX_\fBset_options\fR(3). +Enabled by default when needed in +fully\-patched Postfix >= 2.7. Not needed at all for Postfix >= +2.11, unless for some reason you do not want to support TLS session +resumption. Best not set explicitly. See SSL_CTX_\fBset_options\fR(3). .br .IP "\fBNO_COMPRESSION\fR" Disable SSL compression even if supported by the OpenSSL library. Compression is CPU\-intensive, and compression before encryption does not always improve security. .br +.IP "\fBNO_RENEGOTIATION\fR" +Postfix >= 3.4. This can +reduce opportunities for a potential CPU exhaustion attack. See +SSL_CTX_\fBset_options\fR(3). +.br +.IP "\fBNO_SESSION_RESUMPTION_ON_RENEGOTIATION\fR" +Postfix +>= 3.4. See SSL_CTX_\fBset_options\fR(3). +.br +.IP "\fBPRIORITIZE_CHACHA\fR" +Postfix >= 3.4. See SSL_CTX_\fBset_options\fR(3). +.br +.IP "\fBTLSEXT_PADDING\fR" +Postfix >= 3.4. See +SSL_CTX_\fBset_options\fR(3). +.br .br .PP This feature is available in Postfix 2.11 and later. diff -ur --new-file /var/tmp/postfix-3.0.13/proto/FORWARD_SECRECY_README.html ./proto/FORWARD_SECRECY_README.html --- /var/tmp/postfix-3.0.13/proto/FORWARD_SECRECY_README.html 2017-12-26 10:51:58.000000000 -0500 +++ ./proto/FORWARD_SECRECY_README.html 2018-11-17 18:31:44.000000000 -0500 @@ -370,7 +370,9 @@
  • 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.

    @@ -387,7 +389,8 @@
     
  • 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.

    @@ -403,6 +406,46 @@
     
    +

    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, @@ -454,6 +497,58 @@ 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 -ur --new-file /var/tmp/postfix-3.0.13/proto/TLS_README.html ./proto/TLS_README.html --- /var/tmp/postfix-3.0.13/proto/TLS_README.html 2015-07-20 19:00:12.000000000 -0400 +++ ./proto/TLS_README.html 2018-11-04 17:46:47.000000000 -0500 @@ -917,12 +917,13 @@
  • With Postfix 2.8 and later, the tls_disable_workarounds parameter -specifies a list or bit-mask of OpenSSL bug work-arounds to disable. This -may be necessary if one of the work-arounds enabled by default in -OpenSSL proves to pose a security risk, or introduces an unexpected -interoperability issue. Some bug work-arounds known to be problematic -are disabled in the default value of the parameter when linked with -an OpenSSL library that could be vulnerable.

    +specifies a list or bit-mask of default-enabled OpenSSL bug +work-arounds to disable. This may be necessary if one of the +work-arounds enabled by default in OpenSSL proves to pose a security +risk, or introduces an unexpected interoperability issue. The list +of enabled bug work-arounds is OpenSSL-release-specific. See the +tls_disable_workarounds parameter documentation for the list of +supported values.

    Example:

    @@ -940,19 +941,8 @@ found in the ssl.h file corresponding to the run-time OpenSSL library. While it may be reasonable to turn off all bug workarounds (see above), it is not a good idea to attempt to turn on all features. -

    - -
    - -
    LEGACY_SERVER_CONNECT
    See SSL_CTX_set_options(3).
    - -
    NO_TICKET
    See SSL_CTX_set_options(3).
    - -
    NO_COMPRESSION
    Disable SSL compression even if -supported by the OpenSSL library. Compression is CPU-intensive, -and compression before encryption does not always improve security.
    - -
    +See the tls_ssl_options parameter documentation for the list of +supported values.

    Example:

    diff -ur --new-file /var/tmp/postfix-3.0.13/proto/postconf.proto ./proto/postconf.proto --- /var/tmp/postfix-3.0.13/proto/postconf.proto 2016-02-04 19:29:11.000000000 -0500 +++ ./proto/postconf.proto 2018-11-10 18:53:43.000000000 -0500 @@ -11073,8 +11073,10 @@

    The range of protocols advertised by an SSL/TLS client must be contiguous. When a protocol version is enabled, disabling any -higher version implicitly disables all versions above that higher -version. Thus, for example:

    +higher version implicitly disables all versions above that higher version. +Thus, for example (assuming the OpenSSL library supports both SSLv2 +and SSLv3): +

     smtp_tls_mandatory_protocols = !SSLv2, !TLSv1
    @@ -11091,6 +11093,10 @@
     versions of Postfix ≥ 2.10 can explicitly disable support for
     "TLSv1.1" or "TLSv1.2". 

    +

    OpenSSL 1.1.1 introduces support for "TLSv1.3". With Postfix +≥ 3.4 (or patch releases ≥ 3.0.14, 3.1.10, 3.2.7 and 3.3.2) +this can be disabled, if need be, via "!TLSv1.3".

    +

    At the dane and dane-only security levels, when usable TLSA records are obtained for the remote SMTP @@ -11288,6 +11294,10 @@ versions of Postfix ≥ 2.10 can disable support for "TLSv1.1" or "TLSv1.2".

    +

    OpenSSL 1.1.1 introduces support for "TLSv1.3". With Postfix +≥ 3.4 (or patch releases ≥ 3.0.14, 3.1.10, 3.2.7 and 3.3.2) +this can be disabled, if need be, via "!TLSv1.3".

    +

    Example:

    @@ -12415,11 +12425,13 @@
     
     

    The range of protocols advertised by an SSL/TLS client must be contiguous. When a protocol version is enabled, disabling any -higher version implicitly disables all versions above that higher -version. Thus, for example:

    +higher version implicitly disables all versions above that higher version. +Thus, for example (assuming the OpenSSL library supports both SSLv2 +and SSLv3): +

    -smtp_tls_mandatory_protocols = !SSLv2, !TLSv1
    +smtp_tls_protocols = !SSLv2, !TLSv1
     

    also disables any protocols version higher than TLSv1 leaving @@ -12430,6 +12442,10 @@ versions of Postfix ≥ 2.10 can explicitly disable support for "TLSv1.1" or "TLSv1.2"

    +

    OpenSSL 1.1.1 introduces support for "TLSv1.3". With Postfix +≥ 3.4 (or patch releases ≥ 3.0.14, 3.1.10, 3.2.7 and 3.3.2) +this can be disabled, if need be, via "!TLSv1.3".

    +

    To include a protocol list its name, to exclude it, prefix the name with a "!" character. To exclude SSLv2 for opportunistic TLS set "smtp_tls_protocols = !SSLv2". To exclude both "SSLv2" and "SSLv3" set @@ -12462,6 +12478,10 @@ versions of Postfix ≥ 2.10 can disable support for "TLSv1.1" or "TLSv1.2".

    +

    OpenSSL 1.1.1 introduces support for "TLSv1.3". With Postfix +≥ 3.4 (or patch releases ≥ 3.0.14, 3.1.10, 3.2.7 and 3.3.2) +this can be disabled, if need be, via "!TLSv1.3".

    +

    To include a protocol list its name, to exclude it, prefix the name with a "!" character. To exclude SSLv2 for opportunistic TLS set "smtpd_tls_protocols = !SSLv2". To exclude both "SSLv2" and "SSLv3" set @@ -14647,44 +14667,46 @@

    -
    MICROSOFT_SESS_ID_BUG
    See SSL_CTX_set_options(3)
    +
    CRYPTOPRO_TLSEXT_BUG
    New with GOST support in +OpenSSL 1.0.0.
    -
    NETSCAPE_CHALLENGE_BUG
    See SSL_CTX_set_options(3)
    +
    DONT_INSERT_EMPTY_FRAGMENTS
    See +SSL_CTX_set_options(3)
    LEGACY_SERVER_CONNECT
    See SSL_CTX_set_options(3)
    -
    NETSCAPE_REUSE_CIPHER_CHANGE_BUG
    also aliased -as CVE-2010-4180. Postfix 2.8 disables this work-around by -default with OpenSSL versions that may predate the fix. Fixed in -OpenSSL 0.9.8q and OpenSSL 1.0.0c.
    - -
    SSLREF2_REUSE_CERT_TYPE_BUG
    See -SSL_CTX_set_options(3)
    -
    MICROSOFT_BIG_SSLV3_BUFFER
    See SSL_CTX_set_options(3)
    +
    MICROSOFT_SESS_ID_BUG
    See SSL_CTX_set_options(3)
    +
    MSIE_SSLV2_RSA_PADDING
    also aliased as CVE-2005-2969. Postfix 2.8 disables this work-around by default with OpenSSL versions that may predate the fix. Fixed in OpenSSL 0.9.7h and OpenSSL 0.9.8a.
    +
    NETSCAPE_CHALLENGE_BUG
    See SSL_CTX_set_options(3)
    + +
    NETSCAPE_REUSE_CIPHER_CHANGE_BUG
    also aliased +as CVE-2010-4180. Postfix 2.8 disables this work-around by +default with OpenSSL versions that may predate the fix. Fixed in +OpenSSL 0.9.8q and OpenSSL 1.0.0c.
    +
    SSLEAY_080_CLIENT_DH_BUG
    See SSL_CTX_set_options(3)
    -
    TLS_D5_BUG
    See SSL_CTX_set_options(3)
    +
    SSLREF2_REUSE_CERT_TYPE_BUG
    See +SSL_CTX_set_options(3)
    TLS_BLOCK_PADDING_BUG
    See SSL_CTX_set_options(3)
    +
    TLS_D5_BUG
    See SSL_CTX_set_options(3)
    +
    TLS_ROLLBACK_BUG
    See SSL_CTX_set_options(3). This is disabled in OpenSSL 0.9.7 and later. Nobody should still be using 0.9.6!
    -
    DONT_INSERT_EMPTY_FRAGMENTS
    See -SSL_CTX_set_options(3)
    - -
    CRYPTOPRO_TLSEXT_BUG
    New with GOST support in -OpenSSL 1.0.0.
    +
    TLSEXT_PADDING
    Postfix ≥ 3.4. See SSL_CTX_set_options(3).
    @@ -15751,18 +15773,39 @@ You can only enable options not already controlled by other Postfix settings. For example, you cannot disable protocols or enable server cipher preference. Do not attempt to turn all features by -specifying 0xFFFFFFFF, this is unlikely to be a good idea.

    +specifying 0xFFFFFFFF, this is unlikely to be a good idea. Some +bug work-arounds are also valid here, allowing them to be re-enabled +if/when they're no longer enabled by default. The supported values +include:

    +
    ENABLE_MIDDLEBOX_COMPAT
    Postfix ≥ 3.4. See +SSL_CTX_set_options(3).
    +
    LEGACY_SERVER_CONNECT
    See SSL_CTX_set_options(3).
    -
    NO_TICKET
    See SSL_CTX_set_options(3).
    +
    NO_TICKET
    Enabled by default when needed in +fully-patched Postfix ≥ 2.7. Not needed at all for Postfix ≥ +2.11, unless for some reason you do not want to support TLS session +resumption. Best not set explicitly. See SSL_CTX_set_options(3).
    NO_COMPRESSION
    Disable SSL compression even if supported by the OpenSSL library. Compression is CPU-intensive, and compression before encryption does not always improve security.
    +
    NO_RENEGOTIATION
    Postfix ≥ 3.4. This can +reduce opportunities for a potential CPU exhaustion attack. See +SSL_CTX_set_options(3).
    + +
    NO_SESSION_RESUMPTION_ON_RENEGOTIATION
    Postfix +≥ 3.4. See SSL_CTX_set_options(3).
    + +
    PRIORITIZE_CHACHA
    Postfix ≥ 3.4. See SSL_CTX_set_options(3).
    + +
    TLSEXT_PADDING
    Postfix ≥ 3.4. See +SSL_CTX_set_options(3).
    +

    This feature is available in Postfix 2.11 and later.

    diff -ur --new-file /var/tmp/postfix-3.0.13/src/global/ehlo_mask.c ./src/global/ehlo_mask.c --- /var/tmp/postfix-3.0.13/src/global/ehlo_mask.c 2014-07-06 19:31:07.000000000 -0400 +++ ./src/global/ehlo_mask.c 2018-11-17 18:33:49.000000000 -0500 @@ -77,6 +77,7 @@ "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 -ur --new-file /var/tmp/postfix-3.0.13/src/global/mail_proto.h ./src/global/mail_proto.h --- /var/tmp/postfix-3.0.13/src/global/mail_proto.h 2014-07-14 19:53:14.000000000 -0400 +++ ./src/global/mail_proto.h 2018-11-17 18:25:09.000000000 -0500 @@ -290,6 +290,18 @@ #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 -ur --new-file /var/tmp/postfix-3.0.13/src/posttls-finger/posttls-finger.c ./src/posttls-finger/posttls-finger.c --- /var/tmp/postfix-3.0.13/src/posttls-finger/posttls-finger.c 2015-02-02 12:46:10.000000000 -0500 +++ ./src/posttls-finger/posttls-finger.c 2018-11-04 17:48:11.000000000 -0500 @@ -1484,7 +1484,7 @@ return (0); } -#ifdef USE_TLS +#if defined(USE_TLS) && OPENSSL_VERSION_NUMBER < 0x10100000L /* ssl_cleanup - free memory allocated in the OpenSSL library */ @@ -1502,7 +1502,8 @@ CRYPTO_cleanup_all_ex_data(); } -#endif +#endif /* USE_TLS && OPENSSL_VERSION_NUMBER + * < 0x10100000L */ /* run - do what we were asked to do. */ @@ -1917,7 +1918,9 @@ /* Be valgrind friendly and clean-up */ cleanup(&state); -#ifdef USE_TLS + + /* OpenSSL 1.1.0 and later (de)initialization is implicit */ +#if defined(USE_TLS) && OPENSSL_VERSION_NUMBER < 0x10100000L ssl_cleanup(); #endif diff -ur --new-file /var/tmp/postfix-3.0.13/src/smtpd/smtpd.c ./src/smtpd/smtpd.c --- /var/tmp/postfix-3.0.13/src/smtpd/smtpd.c 2017-01-01 11:35:27.000000000 -0500 +++ ./src/smtpd/smtpd.c 2018-11-17 18:25:09.000000000 -0500 @@ -3149,12 +3149,70 @@ #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 -ur --new-file /var/tmp/postfix-3.0.13/src/tls/tls.h ./src/tls/tls.h --- /var/tmp/postfix-3.0.13/src/tls/tls.h 2015-01-28 13:41:14.000000000 -0500 +++ ./src/tls/tls.h 2018-11-17 18:31:18.000000000 -0500 @@ -77,7 +77,6 @@ /* Appease indent(1) */ #define x509_stack_t STACK_OF(X509) -#define x509_extension_stack_t STACK_OF(X509_EXTENSION) #define general_name_stack_t STACK_OF(GENERAL_NAME) #define ssl_cipher_stack_t STACK_OF(SSL_CIPHER) #define ssl_comp_stack_t STACK_OF(SSL_COMP) @@ -86,6 +85,43 @@ #error "need OpenSSL version 0.9.7 or later" #endif + /* Backwards compatibility with OpenSSL < 1.1.0 */ +#if OPENSSL_VERSION_NUMBER < 0x10100000L +#define OpenSSL_version_num SSLeay +#define X509_up_ref(x) \ + CRYPTO_add(&((x)->references), 1, CRYPTO_LOCK_X509) +#define EVP_PKEY_up_ref(k) \ + CRYPTO_add(&((k)->references), 1, CRYPTO_LOCK_EVP_PKEY) +#define X509_STORE_CTX_get0_cert(ctx) ((ctx)->cert) +#define X509_STORE_CTX_get0_untrusted(ctx) ((ctx)->untrusted) +#define X509_STORE_CTX_set0_untrusted X509_STORE_CTX_set_chain +#define X509_STORE_CTX_set0_trusted_stack X509_STORE_CTX_trusted_stack +#define ASN1_STRING_get0_data ASN1_STRING_data +#define X509_getm_notBefore X509_get_notBefore +#define X509_getm_notAfter X509_get_notAfter +#endif + + /* 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 */ #if OPENSSL_VERSION_NUMBER >= 0x0090707fL /* constification */ #define SSL_CIPHER_const const @@ -113,6 +149,17 @@ #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. */ #define TLS_MGR_SCACHE_SMTPD "smtpd" @@ -211,6 +258,17 @@ 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 */ @@ -348,10 +406,15 @@ #define SSL_OP_NO_TLSv1_2 0L /* Noop */ #endif -#ifdef SSL_TXT_TLSV1_3 + /* + * OpenSSL 1.1.1 does not define a TXT macro for TLS 1.3, so we roll our + * own. + */ +#define TLS_PROTOCOL_TXT_TLSV1_3 "TLSv1.3" + +#if defined(TLS1_3_VERSION) && defined(SSL_OP_NO_TLSv1_3) #define TLS_PROTOCOL_TLSv1_3 (1<<5) /* TLSv1_3 */ #else -#define SSL_TXT_TLSV1_3 "TLSv1.3" #define TLS_PROTOCOL_TLSv1_3 0 /* Unknown */ #undef SSL_OP_NO_TLSv1_3 #define SSL_OP_NO_TLSv1_3 0L /* Noop */ @@ -359,7 +422,7 @@ #define TLS_KNOWN_PROTOCOLS \ ( TLS_PROTOCOL_SSLv2 | TLS_PROTOCOL_SSLv3 | TLS_PROTOCOL_TLSv1 \ - | TLS_PROTOCOL_TLSv1_1 | TLS_PROTOCOL_TLSv1_2 ) + | TLS_PROTOCOL_TLSv1_1 | TLS_PROTOCOL_TLSv1_2 | TLS_PROTOCOL_TLSv1_3 ) #define TLS_SSL_OP_PROTOMASK(m) \ ((((m) & TLS_PROTOCOL_SSLv2) ? SSL_OP_NO_SSLv2 : 0L) \ | (((m) & TLS_PROTOCOL_SSLv3) ? SSL_OP_NO_SSLv3 : 0L) \ @@ -400,7 +463,12 @@ 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 @@ -522,6 +590,11 @@ */ extern void tls_session_stop(TLS_APPL_STATE *, VSTREAM *, int, int, TLS_SESS_STATE *); + /* + * tls_misc.c + */ +extern void tls_log_summary(TLS_ROLE, TLS_USAGE, TLS_SESS_STATE *); + #ifdef TLS_INTERNAL #include diff -ur --new-file /var/tmp/postfix-3.0.13/src/tls/tls_client.c ./src/tls/tls_client.c --- /var/tmp/postfix-3.0.13/src/tls/tls_client.c 2015-01-22 09:47:02.000000000 -0500 +++ ./src/tls/tls_client.c 2018-11-17 18:25:09.000000000 -0500 @@ -299,6 +299,8 @@ */ tls_check_version(); +#if OPENSSL_VERSION_NUMBER < 0x10100000L + /* * Initialize the OpenSSL library by the book! To start with, we must * initialize the algorithms. We want cleartext error messages instead of @@ -306,6 +308,7 @@ */ SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); +#endif /* * Create an application data index for SSL objects, so that we can @@ -354,6 +357,10 @@ tls_print_errors(); return (0); } +#ifdef SSL_SECOP_PEER + /* Backwards compatible security as a base for opportunistic TLS. */ + SSL_CTX_set_security_level(client_ctx, 0); +#endif /* * See the verify callback in tls_verify.c @@ -423,11 +430,17 @@ } /* + * 2015-12-05: Ephemeral RSA removed from OpenSSL 1.1.0-dev + */ +#if OPENSSL_VERSION_NUMBER < 0x10100000L + + /* * According to the OpenSSL documentation, temporary RSA key is needed * export ciphers are in use. We have to provide one, so well, we just do * it. */ SSL_CTX_set_tmp_rsa_callback(client_ctx, tls_tmp_rsa_cb); +#endif /* * Finally, the setup for the server certificate checking, done "by the @@ -931,6 +944,12 @@ if (protomask != 0) SSL_set_options(TLScontext->con, TLS_SSL_OP_PROTOMASK(protomask)); +#ifdef SSL_SECOP_PEER + /* When authenticating the peer, use 80-bit plus OpenSSL security level */ + if (TLS_MUST_MATCH(props->tls_level)) + SSL_set_security_level(TLScontext->con, 1); +#endif + /* * XXX To avoid memory leaks we must always call SSL_SESSION_free() after * calling SSL_set_session(), regardless of whether or not the session @@ -1101,16 +1120,12 @@ tls_stream_start(props->stream, TLScontext); /* - * All the key facts in a single log entry. + * With the handshake done, extract TLS 1.3 signature metadata. */ + tls_get_signature_params(TLScontext); + if (log_mask & TLS_LOG_SUMMARY) - msg_info("%s TLS connection established to %s: %s with cipher %s " - "(%d/%d bits)", - !TLS_CERT_IS_PRESENT(TLScontext) ? "Anonymous" : - TLS_CERT_IS_MATCHED(TLScontext) ? "Verified" : - TLS_CERT_IS_TRUSTED(TLScontext) ? "Trusted" : "Untrusted", - props->namaddr, TLScontext->protocol, TLScontext->cipher_name, - TLScontext->cipher_usebits, TLScontext->cipher_algbits); + tls_log_summary(TLS_ROLE_CLIENT, TLS_USAGE_NEW, TLScontext); tls_int_seed(); diff -ur --new-file /var/tmp/postfix-3.0.13/src/tls/tls_dane.c ./src/tls/tls_dane.c --- /var/tmp/postfix-3.0.13/src/tls/tls_dane.c 2015-04-01 08:46:02.000000000 -0400 +++ ./src/tls/tls_dane.c 2018-11-04 17:48:11.000000000 -0500 @@ -551,7 +551,7 @@ { TLS_CERTS *new = (TLS_CERTS *) mymalloc(sizeof(*new)); - CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); + X509_up_ref(x); new->cert = x; new->next = d->certs; d->certs = new; @@ -573,7 +573,7 @@ { TLS_PKEYS *new = (TLS_PKEYS *) mymalloc(sizeof(*new)); - CRYPTO_add(&k->references, 1, CRYPTO_LOCK_EVP_PKEY); + EVP_PKEY_up_ref(k); new->pkey = k; new->next = d->pkeys; d->pkeys = new; @@ -1402,30 +1402,20 @@ return (matched); } -/* push_ext - push extension onto certificate's stack, else free it */ - -static int push_ext(X509 *cert, X509_EXTENSION *ext) -{ - x509_extension_stack_t *exts; - - if (ext) { - if ((exts = cert->cert_info->extensions) == 0) - exts = cert->cert_info->extensions = sk_X509_EXTENSION_new_null(); - if (exts && sk_X509_EXTENSION_push(exts, ext)) - return 1; - X509_EXTENSION_free(ext); - } - return 0; -} - /* add_ext - add simple extension (no config section references) */ static int add_ext(X509 *issuer, X509 *subject, int ext_nid, char *ext_val) { + int ret = 0; X509V3_CTX v3ctx; + X509_EXTENSION *ext; X509V3_set_ctx(&v3ctx, issuer, subject, 0, 0, 0); - return push_ext(subject, X509V3_EXT_conf_nid(0, &v3ctx, ext_nid, ext_val)); + if ((ext = X509V3_EXT_conf_nid(0, &v3ctx, ext_nid, ext_val)) != 0) { + ret = X509_add_ext(subject, ext, -1); + X509_EXTENSION_free(ext); + } + return ret; } /* set_serial - set serial number to match akid or use subject's plus 1 */ @@ -1469,7 +1459,7 @@ * self-signature checks! */ id = ((akid && akid->keyid) ? akid->keyid : 0); - if (id && ASN1_STRING_length(id) == 1 && *ASN1_STRING_data(id) == c) + if (id && ASN1_STRING_length(id) == 1 && *ASN1_STRING_get0_data(id) == c) c = 1; if ((akid = AUTHORITY_KEYID_new()) != 0 @@ -1542,7 +1532,7 @@ if (cert) { if (trusted && !X509_add1_trust_object(cert, serverAuth)) msg_fatal("out of memory"); - CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509); + X509_up_ref(cert); if (!sk_X509_push(*xs, cert)) msg_fatal("out of memory"); } @@ -1587,10 +1577,10 @@ */ if (!X509_set_version(cert, 2) || !set_serial(cert, akid, subject) - || !X509_set_subject_name(cert, name) || !set_issuer_name(cert, akid) - || !X509_gmtime_adj(X509_get_notBefore(cert), -30 * 86400L) - || !X509_gmtime_adj(X509_get_notAfter(cert), 30 * 86400L) + || !X509_gmtime_adj(X509_getm_notBefore(cert), -30 * 86400L) + || !X509_gmtime_adj(X509_getm_notAfter(cert), 30 * 86400L) + || !X509_set_subject_name(cert, name) || !X509_set_pubkey(cert, key ? key : signkey) || !add_ext(0, cert, NID_basic_constraints, "CA:TRUE") || (key && !add_akid(cert, akid)) @@ -1724,8 +1714,8 @@ int depth = 0; EVP_PKEY *takey; X509 *ca; - X509 *cert = ctx->cert; /* XXX: Accessor? */ - x509_stack_t *in = ctx->untrusted; /* XXX: Accessor? */ + X509 *cert = X509_STORE_CTX_get0_cert(ctx); + x509_stack_t *in = X509_STORE_CTX_get0_untrusted(ctx); /* shallow copy */ if ((in = sk_X509_dup(in)) == 0) @@ -1806,7 +1796,7 @@ { const char *myname = "dane_cb"; TLS_SESS_STATE *TLScontext = (TLS_SESS_STATE *) app_ctx; - X509 *cert = ctx->cert; /* XXX: accessor? */ + X509 *cert = X509_STORE_CTX_get0_cert(ctx); /* * Degenerate case: depth 0 self-signed cert. @@ -1836,9 +1826,9 @@ * Check that setting the untrusted chain updates the expected structure * member at the expected offset. */ - X509_STORE_CTX_trusted_stack(ctx, TLScontext->trusted); - X509_STORE_CTX_set_chain(ctx, TLScontext->untrusted); - if (ctx->untrusted != TLScontext->untrusted) + X509_STORE_CTX_set0_trusted_stack(ctx, TLScontext->trusted); + X509_STORE_CTX_set0_untrusted(ctx, TLScontext->untrusted); + if (X509_STORE_CTX_get0_untrusted(ctx) != TLScontext->untrusted) msg_panic("%s: OpenSSL ABI change", myname); return X509_verify_cert(ctx); @@ -2167,8 +2157,10 @@ tls_param_init(); tls_check_version(); +#if OPENSSL_VERSION_NUMBER < 0x10100000L SSL_load_error_strings(); SSL_library_init(); +#endif if (!tls_validate_digest(LN_sha1)) msg_fatal("%s digest algorithm not available", LN_sha1); diff -ur --new-file /var/tmp/postfix-3.0.13/src/tls/tls_dh.c ./src/tls/tls_dh.c --- /var/tmp/postfix-3.0.13/src/tls/tls_dh.c 2015-01-15 19:25:21.000000000 -0500 +++ ./src/tls/tls_dh.c 2018-11-10 18:56:47.000000000 -0500 @@ -87,44 +87,66 @@ /* Application-specific. */ /* - * Compiled-in EDH primes (the compiled-in generator is always 2). These are - * used when no parameters are explicitly loaded from a site-specific file. + * Compiled-in DH parameters. Used when no parameters are explicitly loaded + * from a site-specific file. Using an ASN.1 DER encoding avoids the need + * to explicitly manipulate the internal representation of DH parameter + * objects. * - * 512-bit parameters are used for export ciphers, and 1024-bit parameters are - * used for non-export ciphers. An ~80-bit strong EDH key exchange is really - * too weak to protect 128+ bit keys, but larger DH primes are - * computationally expensive. When greater security is required, use EECDH. + * 512-bit parameters are used for export ciphers, and 2048-bit parameters are + * used for non-export ciphers. The non-export group is now 2048-bit, as + * 1024 bits is increasingly considered to weak by clients. When greater + * security is required, use EECDH. */ - /* - * Generated via "openssl dhparam -2 -noout -C 512 2>/dev/null" TODO: - * generate at compile-time. + /*- + * Generated via: + * $ openssl dhparam -2 -outform DER 512 2>/dev/null | + * hexdump -ve '/1 "0x%02x, "' | fmt + * TODO: generate at compile-time. But that is no good for the majority of + * sites that install pre-compiled binaries, and breaks reproducible builds. + * Instead, generate at installation time and use main.cf configuration. */ -static unsigned char dh512_p[] = { - 0x88, 0x3F, 0x00, 0xAF, 0xFC, 0x0C, 0x8A, 0xB8, 0x35, 0xCD, 0xE5, 0xC2, - 0x0F, 0x55, 0xDF, 0x06, 0x3F, 0x16, 0x07, 0xBF, 0xCE, 0x13, 0x35, 0xE4, - 0x1C, 0x1E, 0x03, 0xF3, 0xAB, 0x17, 0xF6, 0x63, 0x50, 0x63, 0x67, 0x3E, - 0x10, 0xD7, 0x3E, 0xB4, 0xEB, 0x46, 0x8C, 0x40, 0x50, 0xE6, 0x91, 0xA5, - 0x6E, 0x01, 0x45, 0xDE, 0xC9, 0xB1, 0x1F, 0x64, 0x54, 0xFA, 0xD9, 0xAB, - 0x4F, 0x70, 0xBA, 0x5B, +static unsigned char dh512_der[] = { + 0x30, 0x46, 0x02, 0x41, 0x00, 0xd8, 0xbf, 0x11, 0xd6, 0x41, 0x2a, 0x7a, + 0x9c, 0x78, 0xb2, 0xaa, 0x41, 0x23, 0x0a, 0xdc, 0xcf, 0xb7, 0x19, 0xc5, + 0x16, 0x4c, 0xcb, 0x4a, 0xd0, 0xd2, 0x1f, 0x1f, 0x70, 0x24, 0x86, 0x6f, + 0x51, 0x52, 0xc6, 0x5b, 0x28, 0xbb, 0x82, 0xe1, 0x24, 0x91, 0x3d, 0x4d, + 0x95, 0x56, 0xf8, 0x0b, 0x2c, 0xe0, 0x36, 0x67, 0x88, 0x64, 0x15, 0x1f, + 0x45, 0xd5, 0xb8, 0x0a, 0x00, 0x03, 0x76, 0x32, 0x0b, 0x02, 0x01, 0x02, }; - /* - * Generated via "openssl dhparam -2 -noout -C 1024 2>/dev/null" TODO: - * generate at compile-time. + /*- + * Generated via: + * $ openssl dhparam -2 -outform DER 2048 2>/dev/null | + * hexdump -ve '/1 "0x%02x, "' | fmt + * TODO: generate at compile-time. But that is no good for the majority of + * sites that install pre-compiled binaries, and breaks reproducible builds. + * Instead, generate at installation time and use main.cf configuration. */ -static unsigned char dh1024_p[] = { - 0xB0, 0xFE, 0xB4, 0xCF, 0xD4, 0x55, 0x07, 0xE7, 0xCC, 0x88, 0x59, 0x0D, - 0x17, 0x26, 0xC5, 0x0C, 0xA5, 0x4A, 0x92, 0x23, 0x81, 0x78, 0xDA, 0x88, - 0xAA, 0x4C, 0x13, 0x06, 0xBF, 0x5D, 0x2F, 0x9E, 0xBC, 0x96, 0xB8, 0x51, - 0x00, 0x9D, 0x0C, 0x0D, 0x75, 0xAD, 0xFD, 0x3B, 0xB1, 0x7E, 0x71, 0x4F, - 0x3F, 0x91, 0x54, 0x14, 0x44, 0xB8, 0x30, 0x25, 0x1C, 0xEB, 0xDF, 0x72, - 0x9C, 0x4C, 0xF1, 0x89, 0x0D, 0x68, 0x3F, 0x94, 0x8E, 0xA4, 0xFB, 0x76, - 0x89, 0x18, 0xB2, 0x91, 0x16, 0x90, 0x01, 0x99, 0x66, 0x8C, 0x53, 0x81, - 0x4E, 0x27, 0x3D, 0x99, 0xE7, 0x5A, 0x7A, 0xAF, 0xD5, 0xEC, 0xE2, 0x7E, - 0xFA, 0xED, 0x01, 0x18, 0xC2, 0x78, 0x25, 0x59, 0x06, 0x5C, 0x39, 0xF6, - 0xCD, 0x49, 0x54, 0xAF, 0xC1, 0xB1, 0xEA, 0x4A, 0xF9, 0x53, 0xD0, 0xDF, - 0x6D, 0xAF, 0xD4, 0x93, 0xE7, 0xBA, 0xAE, 0x9B, +static unsigned char dh2048_der[] = { + 0x30, 0x82, 0x01, 0x08, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbf, 0x28, 0x1b, + 0x68, 0x69, 0x90, 0x2f, 0x37, 0x9f, 0x5a, 0x50, 0x23, 0x73, 0x2c, 0x11, + 0xf2, 0xac, 0x7c, 0x3e, 0x58, 0xb9, 0x23, 0x3e, 0x02, 0x07, 0x4d, 0xba, + 0xd9, 0x2c, 0xc1, 0x9e, 0xf9, 0xc4, 0x2f, 0xbc, 0x8d, 0x86, 0x4b, 0x2a, + 0x87, 0x86, 0x93, 0x32, 0x0f, 0x72, 0x40, 0xfe, 0x7e, 0xa2, 0xc1, 0x32, + 0xf0, 0x65, 0x9c, 0xc3, 0x19, 0x25, 0x2d, 0xeb, 0x6a, 0x49, 0x94, 0x79, + 0x2d, 0xa1, 0xbe, 0x05, 0x26, 0xac, 0x8d, 0x69, 0xdc, 0x2e, 0x7e, 0xb5, + 0xfd, 0x3c, 0x2b, 0x7d, 0x43, 0x22, 0x53, 0xf6, 0x1e, 0x04, 0x45, 0xd7, + 0x53, 0x84, 0xfd, 0x6b, 0x12, 0x72, 0x47, 0x04, 0xaf, 0xa4, 0xac, 0x4b, + 0x55, 0xb6, 0x79, 0x42, 0x40, 0x88, 0x54, 0x48, 0xd5, 0x4d, 0x3a, 0xb2, + 0xbf, 0x6c, 0x26, 0x95, 0x29, 0xdd, 0x8b, 0x9e, 0xed, 0xb8, 0x60, 0x8e, + 0xb5, 0x35, 0xb6, 0x22, 0x44, 0x1f, 0xfb, 0x56, 0x74, 0xfe, 0xf0, 0x2c, + 0xe6, 0x0c, 0x22, 0xc9, 0x35, 0xb3, 0x1b, 0x96, 0xbb, 0x0a, 0x5a, 0xc3, + 0x09, 0xa0, 0xcc, 0xa5, 0x40, 0x90, 0x0f, 0x59, 0xa2, 0x89, 0x69, 0x2a, + 0x69, 0x79, 0xe4, 0xd3, 0x24, 0xc6, 0x8c, 0xda, 0xbc, 0x98, 0x3a, 0x5b, + 0x16, 0xae, 0x63, 0x6c, 0x0b, 0x43, 0x4f, 0xf3, 0x2e, 0xc8, 0xa9, 0x6b, + 0x58, 0x6a, 0xa9, 0x8e, 0x64, 0x09, 0x3d, 0x88, 0x44, 0x4f, 0x97, 0x2c, + 0x1d, 0x98, 0xb0, 0xa9, 0xc0, 0xb6, 0x8d, 0x19, 0x37, 0x1f, 0xb7, 0xc9, + 0x86, 0xa8, 0xdc, 0x37, 0x4d, 0x64, 0x27, 0xf3, 0xf5, 0x2b, 0x7b, 0x6b, + 0x76, 0x84, 0x3f, 0xc1, 0x23, 0x97, 0x2d, 0x71, 0xf7, 0xb6, 0xc2, 0x35, + 0x28, 0x10, 0x96, 0xd6, 0x69, 0x0c, 0x2e, 0x1f, 0x9f, 0xdf, 0x82, 0x81, + 0x57, 0x57, 0x39, 0xa5, 0xf2, 0x81, 0x29, 0x57, 0xf9, 0x2f, 0xd0, 0x03, + 0xab, 0x02, 0x01, 0x02, }; /* @@ -151,6 +173,14 @@ msg_panic("Invalid DH parameters size %d, file %s", bits, path); } + /* + * This function is the first to set the DH parameters, but free any + * prior value just in case the call sequence changes some day. + */ + if (*dhPtr) { + DH_free(*dhPtr); + *dhPtr = 0; + } if ((paramfile = fopen(path, "r")) != 0) { if ((*dhPtr = PEM_read_DHparams(paramfile, 0, 0, 0)) == 0) { msg_warn("cannot load %d-bit DH parameters from file %s" @@ -166,24 +196,18 @@ /* tls_get_dh - get compiled-in DH parameters */ -static DH *tls_get_dh(const unsigned char *p, int plen) +static DH *tls_get_dh(const unsigned char *p, size_t plen) { - DH *dh; - static unsigned char g[] = {0x02,}; + const unsigned char *endp = p; + DH *dh = 0; - /* Use the compiled-in parameters. */ - if ((dh = DH_new()) == 0) { - msg_warn("cannot create DH parameter set: %m"); /* 200411 */ - return (0); - } - dh->p = BN_bin2bn(p, plen, (BIGNUM *) 0); - dh->g = BN_bin2bn(g, 1, (BIGNUM *) 0); - if ((dh->p == 0) || (dh->g == 0)) { - msg_warn("cannot load compiled-in DH parameters"); /* 200411 */ - DH_free(dh); /* 200411 */ - return (0); - } - return (dh); + if (d2i_DHparams(&dh, &endp, plen) && plen == endp - p) + return (dh); + + msg_warn("cannot load compiled-in DH parameters"); + if (dh) + DH_free(dh); + return (0); } /* tls_tmp_dh_cb - call-back for Diffie-Hellman parameters */ @@ -194,11 +218,11 @@ if (export && keylength == 512) { /* 40-bit export cipher */ if (dh_512 == 0) - dh_512 = tls_get_dh(dh512_p, (int) sizeof(dh512_p)); + dh_512 = tls_get_dh(dh512_der, sizeof(dh512_der)); dh_tmp = dh_512; } else { /* ADH, DHE-RSA or DSA */ if (dh_1024 == 0) - dh_1024 = tls_get_dh(dh1024_p, (int) sizeof(dh1024_p)); + dh_1024 = tls_get_dh(dh2048_der, sizeof(dh2048_der)); dh_tmp = dh_1024; } return (dh_tmp); @@ -255,10 +279,12 @@ ERR_clear_error(); if ((ecdh = EC_KEY_new_by_curve_name(nid)) == 0 || SSL_CTX_set_tmp_ecdh(server_ctx, ecdh) == 0) { + EC_KEY_free(ecdh); /* OK if NULL */ msg_warn("unable to use curve \"%s\": disabling EECDH support", curve); tls_print_errors(); return (0); } + EC_KEY_free(ecdh); #endif return (1); } diff -ur --new-file /var/tmp/postfix-3.0.13/src/tls/tls_fprint.c ./src/tls/tls_fprint.c --- /var/tmp/postfix-3.0.13/src/tls/tls_fprint.c 2015-01-18 15:15:46.000000000 -0500 +++ ./src/tls/tls_fprint.c 2018-11-04 17:48:11.000000000 -0500 @@ -188,7 +188,7 @@ msg_panic("digest algorithm \"%s\" not found", mdalg); /* Salt the session lookup key with the OpenSSL runtime version. */ - sslversion = SSLeay(); + sslversion = OpenSSL_version_num(); mdctx = EVP_MD_CTX_create(); checkok(EVP_DigestInit_ex(mdctx, md, NULL)); diff -ur --new-file /var/tmp/postfix-3.0.13/src/tls/tls_misc.c ./src/tls/tls_misc.c --- /var/tmp/postfix-3.0.13/src/tls/tls_misc.c 2015-01-15 19:25:21.000000000 -0500 +++ ./src/tls/tls_misc.c 2018-11-17 18:25:09.000000000 -0500 @@ -4,6 +4,19 @@ /* 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; +/* +/* .SH Internal functions +/* .nf +/* .na /* #define TLS_INTERNAL /* #include /* @@ -60,6 +73,9 @@ /* int grade; /* const char *exclusions; /* +/* void tls_get_signature_params(TLScontext) +/* TLS_SESS_STATE *TLScontext; +/* /* void tls_print_errors() /* /* void tls_info_callback(ssl, where, ret) @@ -86,8 +102,13 @@ /* int tls_validate_digest(dgst) /* const char *dgst; /* DESCRIPTION -/* This module implements routines that support the TLS client -/* and server internals. +/* This module implements public and internal routines that +/* support the TLS client and server. +/* +/* tls_log_summary() logs a summary of a completed TLS connection. +/* The "role" argument must be TLS_ROLE_CLIENT for outgoing client +/* connections, or TLS_ROLE_SERVER for incoming server connections, +/* and the "usage" must be TLS_USAGE_NEW or TLS_USAGE_USED. /* /* tls_alloc_app_context() creates an application context that /* holds the SSL context for the application and related cached state. @@ -135,6 +156,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. /* @@ -254,7 +281,7 @@ SSL_TXT_TLSV1, TLS_PROTOCOL_TLSv1, SSL_TXT_TLSV1_1, TLS_PROTOCOL_TLSv1_1, SSL_TXT_TLSV1_2, TLS_PROTOCOL_TLSv1_2, - SSL_TXT_TLSV1_3, TLS_PROTOCOL_TLSv1_3, + TLS_PROTOCOL_TXT_TLSV1_3, TLS_PROTOCOL_TLSv1_3, 0, TLS_PROTOCOL_INVALID, }; @@ -330,6 +357,29 @@ #define SSL_OP_CRYPTOPRO_TLSEXT_BUG 0 #endif NAMEBUG(CRYPTOPRO_TLSEXT_BUG), + +#ifndef SSL_OP_TLSEXT_PADDING +#define SSL_OP_TLSEXT_PADDING 0 +#endif + NAMEBUG(TLSEXT_PADDING), + +#if 0 + + /* + * 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 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 +#endif + NAMEBUG(ENABLE_MIDDLEBOX_COMPAT), +#endif + 0, 0, }; @@ -355,10 +405,43 @@ #define SSL_OP_NO_COMPRESSION 0 #endif NAME_SSL_OP(NO_COMPRESSION), + +#ifndef SSL_OP_NO_RENEGOTIATION +#define SSL_OP_NO_RENEGOTIATION 0 +#endif + NAME_SSL_OP(NO_RENEGOTIATION), + +#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION +#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0 +#endif + NAME_SSL_OP(NO_SESSION_RESUMPTION_ON_RENEGOTIATION), + +#ifndef SSL_OP_PRIORITIZE_CHACHA +#define SSL_OP_PRIORITIZE_CHACHA 0 +#endif + NAME_SSL_OP(PRIORITIZE_CHACHA), + +#ifndef SSL_OP_ENABLE_MIDDLEBOX_COMPAT +#define SSL_OP_ENABLE_MIDDLEBOX_COMPAT 0 +#endif + NAME_SSL_OP(ENABLE_MIDDLEBOX_COMPAT), + 0, 0, }; /* + * Once these have been a NOOP long enough, they might some day be removed + * from OpenSSL. The defines below will avoid bitrot issues if/when that + * happens. + */ +#ifndef SSL_OP_SINGLE_DH_USE +#define SSL_OP_SINGLE_DH_USE 0 +#endif +#ifndef SSL_OP_SINGLE_ECDH_USE +#define SSL_OP_SINGLE_ECDH_USE 0 +#endif + + /* * Ciphersuite name <=> code conversion. */ const NAME_CODE tls_cipher_grade_table[] = { @@ -461,7 +544,7 @@ static ARGV *exclude; /* Cached */ SSL *s = 0; ssl_cipher_stack_t *ciphers; - SSL_CIPHER *c; + const SSL_CIPHER *c; const cipher_probe_t *probe; int alg_bits; int num; @@ -743,6 +826,224 @@ return (app_ctx->cipher_list = mystrdup(new_list)); } +/* tls_get_signature_params - TLS 1.3 signature details */ + +void tls_get_signature_params(TLS_SESS_STATE *TLScontext) +{ +#if OPENSSL_VERSION_NUMBER >= 0x1010100fUL && defined(TLS1_3_VERSION) + const char *kex_name = 0; + const char *kex_curve = 0; + const char *locl_sig_name = 0; + const char *locl_sig_curve = 0; + const char *locl_sig_dgst = 0; + const char *peer_sig_name = 0; + const char *peer_sig_curve = 0; + const char *peer_sig_dgst = 0; + int nid; + int got_kex_key; + SSL *ssl = TLScontext->con; + int srvr = SSL_is_server(ssl); + X509 *cert; + EVP_PKEY *pkey = 0; + +#ifndef OPENSSL_NO_EC + EC_KEY *eckey; + +#endif + +#define SIG_PROP(c, s, p) (*((s) ? &c->srvr_sig_##p : &c->clnt_sig_##p)) + + if (SSL_version(ssl) < TLS1_3_VERSION) + return; + + if (tls_get_peer_dh_pubkey(ssl, &pkey)) { + switch (nid = EVP_PKEY_id(pkey)) { + default: + kex_name = OBJ_nid2sn(EVP_PKEY_type(nid)); + break; + + case EVP_PKEY_DH: + kex_name = "DHE"; + TLScontext->kex_bits = EVP_PKEY_bits(pkey); + break; + +#ifndef OPENSSL_NO_EC + case EVP_PKEY_EC: + kex_name = "ECDHE"; + eckey = EVP_PKEY_get0_EC_KEY(pkey); + nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey)); + kex_curve = EC_curve_nid2nist(nid); + if (!kex_curve) + kex_curve = OBJ_nid2sn(nid); + break; +#endif + } + EVP_PKEY_free(pkey); + } + + /* + * On the client end, the certificate may be preset, but not used, so we + * check via SSL_get_signature_nid(). This means that local signature + * data on clients requires at least 1.1.1a. + */ + if (srvr || SSL_get_signature_nid(ssl, &nid)) + cert = SSL_get_certificate(ssl); + else + cert = 0; + + /* Signature algorithms for the local end of the connection */ + if (cert) { + pkey = X509_get0_pubkey(cert); + + /* + * Override the built-in name for the "ECDSA" algorithms OID, with + * the more familiar name. For "RSA" keys report "RSA-PSS", which + * must be used with TLS 1.3. + */ + if ((nid = EVP_PKEY_type(EVP_PKEY_id(pkey))) != NID_undef) { + switch (nid) { + default: + locl_sig_name = OBJ_nid2sn(nid); + break; + + case EVP_PKEY_RSA: + /* For RSA, TLS 1.3 mandates PSS signatures */ + locl_sig_name = "RSA-PSS"; + SIG_PROP(TLScontext, srvr, bits) = EVP_PKEY_bits(pkey); + break; + +#ifndef OPENSSL_NO_EC + case EVP_PKEY_EC: + locl_sig_name = "ECDSA"; + eckey = EVP_PKEY_get0_EC_KEY(pkey); + nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey)); + locl_sig_curve = EC_curve_nid2nist(nid); + if (!locl_sig_curve) + locl_sig_curve = OBJ_nid2sn(nid); + break; +#endif + } + } + + /* + * With Ed25519 and Ed448 there is no pre-signature digest, but the + * accessor does not fail, rather we get NID_undef. + */ + if (SSL_get_signature_nid(ssl, &nid) && nid != NID_undef) + locl_sig_dgst = OBJ_nid2sn(nid); + } + /* Signature algorithms for the peer end of the connection */ + if ((cert = SSL_get_peer_certificate(ssl)) != 0) { + pkey = X509_get0_pubkey(cert); + + /* + * Override the built-in name for the "ECDSA" algorithms OID, with + * the more familiar name. For "RSA" keys report "RSA-PSS", which + * must be used with TLS 1.3. + */ + if ((nid = EVP_PKEY_type(EVP_PKEY_id(pkey))) != NID_undef) { + switch (nid) { + default: + peer_sig_name = OBJ_nid2sn(nid); + break; + + case EVP_PKEY_RSA: + /* For RSA, TLS 1.3 mandates PSS signatures */ + peer_sig_name = "RSA-PSS"; + SIG_PROP(TLScontext, !srvr, bits) = EVP_PKEY_bits(pkey); + break; + +#ifndef OPENSSL_NO_EC + case EVP_PKEY_EC: + peer_sig_name = "ECDSA"; + eckey = EVP_PKEY_get0_EC_KEY(pkey); + nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey)); + peer_sig_curve = EC_curve_nid2nist(nid); + if (!peer_sig_curve) + peer_sig_curve = OBJ_nid2sn(nid); + break; +#endif + } + } + + /* + * With Ed25519 and Ed448 there is no pre-signature digest, but the + * accessor does not fail, rather we get NID_undef. + */ + if (SSL_get_peer_signature_nid(ssl, &nid) && nid != NID_undef) + peer_sig_dgst = OBJ_nid2sn(nid); + } + if (kex_name) { + TLScontext->kex_name = mystrdup(kex_name); + if (kex_curve) + TLScontext->kex_curve = mystrdup(kex_curve); + } + if (locl_sig_name) { + SIG_PROP(TLScontext, srvr, name) = mystrdup(locl_sig_name); + if (locl_sig_curve) + SIG_PROP(TLScontext, srvr, curve) = mystrdup(locl_sig_curve); + if (locl_sig_dgst) + SIG_PROP(TLScontext, srvr, dgst) = mystrdup(locl_sig_dgst); + } + if (peer_sig_name) { + SIG_PROP(TLScontext, !srvr, name) = mystrdup(peer_sig_name); + if (peer_sig_curve) + SIG_PROP(TLScontext, !srvr, curve) = mystrdup(peer_sig_curve); + if (peer_sig_dgst) + SIG_PROP(TLScontext, !srvr, dgst) = mystrdup(peer_sig_dgst); + } +#endif /* OPENSSL_VERSION_NUMBER ... */ +} + +/* tls_log_summary - TLS loglevel 1 one-liner, embellished with TLS 1.3 details */ + +void tls_log_summary(TLS_ROLE role, TLS_USAGE usage, TLS_SESS_STATE *ctx) +{ + VSTRING *msg = vstring_alloc(100); + const char *direction = (role == TLS_ROLE_CLIENT) ? "to" : "from"; + + vstring_sprintf(msg, "%s TLS connection %s %s %s: %s" + " with cipher %s (%d/%d bits)", + !TLS_CERT_IS_PRESENT(ctx) ? "Anonymous" : + TLS_CERT_IS_MATCHED(ctx) ? "Verified" : + TLS_CERT_IS_TRUSTED(ctx) ? "Trusted" : "Untrusted", + usage == TLS_USAGE_NEW ? "established" : "reused", + direction, ctx->namaddr, ctx->protocol, ctx->cipher_name, + ctx->cipher_usebits, ctx->cipher_algbits); + + if (ctx->kex_name && *ctx->kex_name) { + vstring_sprintf_append(msg, " key-exchange %s", ctx->kex_name); + if (ctx->kex_curve && *ctx->kex_curve) + vstring_sprintf_append(msg, " (%s)", ctx->kex_curve); + else if (ctx->kex_bits > 0) + vstring_sprintf_append(msg, " (%d bits)", ctx->kex_bits); + } + if (ctx->srvr_sig_name && *ctx->srvr_sig_name) { + vstring_sprintf_append(msg, " server-signature %s", + ctx->srvr_sig_name); + if (ctx->srvr_sig_curve && *ctx->srvr_sig_curve) + vstring_sprintf_append(msg, " (%s)", ctx->srvr_sig_curve); + else if (ctx->srvr_sig_bits > 0) + vstring_sprintf_append(msg, " (%d bits)", ctx->srvr_sig_bits); + if (ctx->srvr_sig_dgst && *ctx->srvr_sig_dgst) + vstring_sprintf_append(msg, " server-digest %s", + ctx->srvr_sig_dgst); + } + if (ctx->clnt_sig_name && *ctx->clnt_sig_name) { + vstring_sprintf_append(msg, " client-signature %s", + ctx->clnt_sig_name); + if (ctx->clnt_sig_curve && *ctx->clnt_sig_curve) + vstring_sprintf_append(msg, " (%s)", ctx->clnt_sig_curve); + else if (ctx->clnt_sig_bits > 0) + vstring_sprintf_append(msg, " (%d bits)", ctx->clnt_sig_bits); + if (ctx->clnt_sig_dgst && *ctx->clnt_sig_dgst) + vstring_sprintf_append(msg, " client-digest %s", + ctx->clnt_sig_dgst); + } + msg_info("%s", vstring_str(msg)); + vstring_free(msg); +} + /* tls_alloc_app_context - allocate TLS application context */ TLS_APPL_STATE *tls_alloc_app_context(SSL_CTX *ssl_ctx, int log_mask) @@ -810,6 +1111,14 @@ 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 */ @@ -935,11 +1244,18 @@ TLS_VINFO lib_info; tls_version_split(OPENSSL_VERSION_NUMBER, &hdr_info); - tls_version_split(SSLeay(), &lib_info); + tls_version_split(OpenSSL_version_num(), &lib_info); + /* + * Warn if run-time library is different from compile-time library, + * allowing later run-time "micro" versions starting with 1.1.0. + */ if (lib_info.major != hdr_info.major || lib_info.minor != hdr_info.minor - || lib_info.micro != hdr_info.micro) + || (lib_info.micro != hdr_info.micro + && (lib_info.micro < hdr_info.micro + || hdr_info.major == 0 + || (hdr_info.major == 1 && hdr_info.minor == 0)))) msg_warn("run-time library vs. compile-time header version mismatch: " "OpenSSL %d.%d.%d may not be compatible with OpenSSL %d.%d.%d", lib_info.major, lib_info.minor, lib_info.micro, @@ -954,7 +1270,7 @@ #if OPENSSL_VERSION_NUMBER >= 0x00908000L && \ OPENSSL_VERSION_NUMBER < 0x10000000L - long lib_version = SSLeay(); + long lib_version = OpenSSL_version_num(); /* * In OpenSSL 0.9.8[ab], enabling zlib compression breaks the padding bug @@ -998,6 +1314,14 @@ enable &= ~(SSL_OP_ALL | TLS_SSL_OP_MANAGED_BITS); bits |= enable; } + + /* + * We unconditionally avoid re-use of ephemeral keys, note that we set DH + * keys via a callback, so reuse was never possible, but the ECDH key is + * set statically, so that is potentially subject to reuse. Set both + * options just in case. + */ + bits |= SSL_OP_SINGLE_ECDH_USE | SSL_OP_SINGLE_DH_USE; return (bits); } diff -ur --new-file /var/tmp/postfix-3.0.13/src/tls/tls_proxy_clnt.c ./src/tls/tls_proxy_clnt.c --- /var/tmp/postfix-3.0.13/src/tls/tls_proxy_clnt.c 2014-12-25 11:47:17.000000000 -0500 +++ ./src/tls/tls_proxy_clnt.c 2018-11-17 18:25:09.000000000 -0500 @@ -239,6 +239,24 @@ 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 -ur --new-file /var/tmp/postfix-3.0.13/src/tls/tls_proxy_print.c ./src/tls/tls_proxy_print.c --- /var/tmp/postfix-3.0.13/src/tls/tls_proxy_print.c 2014-12-14 13:22:06.000000000 -0500 +++ ./src/tls/tls_proxy_print.c 2018-11-17 18:25:09.000000000 -0500 @@ -79,6 +79,30 @@ 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 -ur --new-file /var/tmp/postfix-3.0.13/src/tls/tls_proxy_scan.c ./src/tls/tls_proxy_scan.c --- /var/tmp/postfix-3.0.13/src/tls/tls_proxy_scan.c 2014-12-14 13:22:06.000000000 -0500 +++ ./src/tls/tls_proxy_scan.c 2018-11-17 18:25:09.000000000 -0500 @@ -63,6 +63,15 @@ 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 @@ &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 @@ 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 -ur --new-file /var/tmp/postfix-3.0.13/src/tls/tls_rsa.c ./src/tls/tls_rsa.c --- /var/tmp/postfix-3.0.13/src/tls/tls_rsa.c 2015-01-15 19:25:21.000000000 -0500 +++ ./src/tls/tls_rsa.c 2018-11-04 17:48:11.000000000 -0500 @@ -54,6 +54,11 @@ #include #include + /* + * 2015-12-05: Ephemeral RSA removed from OpenSSL 1.1.0-dev + */ +#if OPENSSL_VERSION_NUMBER < 0x10100000L + /* tls_tmp_rsa_cb - call-back to generate ephemeral RSA key */ RSA *tls_tmp_rsa_cb(SSL *unused_ssl, int export, int keylength) @@ -91,14 +96,21 @@ return (rsa_tmp); } +#endif /* OPENSSL_VERSION_NUMBER */ + #ifdef TEST #include int main(int unused_argc, char *const argv[]) { + int ok = 0; + + /* + * 2015-12-05: Ephemeral RSA removed from OpenSSL 1.1.0-dev + */ +#if OPENSSL_VERSION_NUMBER < 0x10100000L RSA *rsa; - int ok; msg_vstream_init(argv[0], VSTREAM_ERR); @@ -111,6 +123,7 @@ /* Non-export or unexpected bit length should fail */ ok = ok && tls_tmp_rsa_cb(0, 0, 512) == 0; ok = ok && tls_tmp_rsa_cb(0, 1, 1024) == 0; +#endif return ok ? 0 : 1; } diff -ur --new-file /var/tmp/postfix-3.0.13/src/tls/tls_server.c ./src/tls/tls_server.c --- /var/tmp/postfix-3.0.13/src/tls/tls_server.c 2015-01-15 19:25:21.000000000 -0500 +++ ./src/tls/tls_server.c 2018-11-17 18:25:09.000000000 -0500 @@ -173,9 +173,18 @@ #endif /* OPENSSL_VERSION_NUMBER */ + /* OpenSSL 1.1.0 bitrot */ +#if OPENSSL_VERSION_NUMBER >= 0x10100000L +typedef const unsigned char *session_id_t; + +#else +typedef unsigned char *session_id_t; + +#endif + /* get_server_session_cb - callback to retrieve session from server cache */ -static SSL_SESSION *get_server_session_cb(SSL *ssl, unsigned char *session_id, +static SSL_SESSION *get_server_session_cb(SSL *ssl, session_id_t session_id, int session_id_length, int *unused_copy) { @@ -193,7 +202,7 @@ buf = vstring_alloc(2 * (len + strlen(service))); \ hex_encode(buf, (char *) (id), (len)); \ vstring_sprintf_append(buf, "&s=%s", (service)); \ - vstring_sprintf_append(buf, "&l=%ld", (long) SSLeay()); \ + vstring_sprintf_append(buf, "&l=%ld", (long) OpenSSL_version_num()); \ } while (0) @@ -368,6 +377,8 @@ */ tls_check_version(); +#if OPENSSL_VERSION_NUMBER < 0x10100000L + /* * Initialize the OpenSSL library by the book! To start with, we must * initialize the algorithms. We want cleartext error messages instead of @@ -375,6 +386,7 @@ */ SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); +#endif /* * First validate the protocols. If these are invalid, we can't continue. @@ -436,6 +448,10 @@ tls_print_errors(); return (0); } +#ifdef SSL_SECOP_PEER + /* Backwards compatible security as a base for opportunistic TLS. */ + SSL_CTX_set_security_level(server_ctx, 0); +#endif /* * See the verify callback in tls_verify.c @@ -485,8 +501,23 @@ ticketable = 0; } } - if (ticketable) + if (ticketable) { SSL_CTX_set_tlsext_ticket_key_cb(server_ctx, ticket_cb); + + /* + * OpenSSL 1.1.1 introduces support for TLS 1.3, which can issue more + * than one ticket per handshake. While this may be appropriate for + * communication between browsers and webservers, it is not terribly + * useful for MTAs, many of which other than Postfix don't do TLS + * session caching at all, and Postfix has no mechanism for storing + * multiple session tickets, if more than one sent, the second + * clobbers the first. OpenSSL 1.1.1 servers default to issuing two + * tickets for non-resumption handshakes, we reduce this to one. Our + * ticket decryption callback already (since 2.11) asks OpenSSL to + * avoid issuing new tickets when the presented ticket is re-usable. + */ + SSL_CTX_set_num_tickets(server_ctx, 1); + } #endif if (!ticketable) off |= SSL_OP_NO_TICKET; @@ -561,11 +592,17 @@ } /* + * 2015-12-05: Ephemeral RSA removed from OpenSSL 1.1.0-dev + */ +#if OPENSSL_VERSION_NUMBER < 0x10100000L + + /* * According to OpenSSL documentation, a temporary RSA key is needed when * export ciphers are in use, because the certified key cannot be * directly used. */ SSL_CTX_set_tmp_rsa_callback(server_ctx, tls_tmp_rsa_cb); +#endif /* * Diffie-Hellman key generation parameters can either be loaded from @@ -738,6 +775,11 @@ tls_free_context(TLScontext); return (0); } +#ifdef SSL_SECOP_PEER + /* When authenticating the peer, use 80-bit plus OpenSSL security level */ + if (props->requirecert) + SSL_set_security_level(TLScontext->con, 1); +#endif /* * Before really starting anything, try to seed the PRNG a little bit @@ -868,6 +910,22 @@ TLScontext->peer_pkey_fprint); } X509_free(peer); + + /* + * Give them a clue. Problems with trust chain verification are + * logged when the session is first negotiated, before the session is + * stored into the cache. We don't want mystery failures, so log the + * fact the real problem is to be found in the past. + */ + if (!TLS_CERT_IS_TRUSTED(TLScontext) + && (TLScontext->log_mask & TLS_LOG_UNTRUSTED)) { + if (TLScontext->session_reused == 0) + tls_log_verify_error(TLScontext); + else + msg_info("%s: re-using session with untrusted certificate, " + "look for details earlier in the log", + TLScontext->namaddr); + } } else { TLScontext->peer_CN = mystrdup(""); TLScontext->issuer_CN = mystrdup(""); @@ -894,14 +952,12 @@ 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(); diff -ur --new-file /var/tmp/postfix-3.0.13/src/tls/tls_verify.c ./src/tls/tls_verify.c --- /var/tmp/postfix-3.0.13/src/tls/tls_verify.c 2013-06-16 18:49:37.000000000 -0400 +++ ./src/tls/tls_verify.c 2018-11-04 17:48:11.000000000 -0500 @@ -138,7 +138,7 @@ if (TLScontext->errorcert != 0) X509_free(TLScontext->errorcert); if (errorcert != 0) - CRYPTO_add(&errorcert->references, 1, CRYPTO_LOCK_X509); + X509_up_ref(errorcert); TLScontext->errorcert = errorcert; TLScontext->errorcode = errorcode; TLScontext->errordepth = depth; @@ -440,7 +440,7 @@ /* * Safe to treat as an ASCII string possibly holding a DNS name */ - dnsname = (char *) ASN1_STRING_data(gn->d.ia5); + dnsname = (const char *) ASN1_STRING_get0_data(gn->d.ia5); len = ASN1_STRING_length(gn->d.ia5); TRIM0(dnsname, len);