]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-3.9-20230807
authorWietse Venema <wietse@porcupine.org>
Mon, 7 Aug 2023 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Mon, 7 Aug 2023 21:31:11 +0000 (17:31 -0400)
45 files changed:
postfix/HISTORY
postfix/README_FILES/TLS_README
postfix/RELEASE_NOTES
postfix/html/TLS_README.html
postfix/html/lmtp.8.html
postfix/html/postconf.5.html
postfix/html/posttls-finger.1.html
postfix/html/smtp.8.html
postfix/html/smtpd.8.html
postfix/html/tlsproxy.8.html
postfix/man/man1/posttls-finger.1
postfix/man/man5/postconf.5
postfix/man/man8/smtp.8
postfix/man/man8/smtpd.8
postfix/man/man8/tlsproxy.8
postfix/mantools/postlink
postfix/proto/TLS_README.html
postfix/proto/postconf.proto
postfix/proto/stop
postfix/proto/stop.double-history
postfix/proto/stop.spell-cc
postfix/src/global/mail_params.h
postfix/src/global/mail_version.h
postfix/src/posttls-finger/posttls-finger.c
postfix/src/smtp/lmtp_params.c
postfix/src/smtp/smtp.c
postfix/src/smtp/smtp.h
postfix/src/smtp/smtp_params.c
postfix/src/smtp/smtp_proto.c
postfix/src/smtp/smtp_tls_policy.c
postfix/src/smtpd/smtpd.c
postfix/src/smtpd/smtpd_check.c
postfix/src/tls/tls.h
postfix/src/tls/tls_client.c
postfix/src/tls/tls_dane.c
postfix/src/tls/tls_fprint.c
postfix/src/tls/tls_misc.c
postfix/src/tls/tls_proxy.h
postfix/src/tls/tls_proxy_client_print.c
postfix/src/tls/tls_proxy_client_scan.c
postfix/src/tls/tls_proxy_context_print.c
postfix/src/tls/tls_proxy_context_scan.c
postfix/src/tls/tls_server.c
postfix/src/tls/tls_verify.c
postfix/src/tlsproxy/tlsproxy.c

index b00b396fec54aaad7e0c962fda184a2255c06ddc..d3ec99658996c15fdc442b0290f6d115120185b5 100644 (file)
@@ -27274,3 +27274,21 @@ Apologies for any names omitted.
 20240703
 
        Typo fix by Trent W. Buck. Files: proto/postconf.proto, proto/stop.
+
+20230807
+
+       Feature: optional support to request a raw public key instead
+       of a public-key certificate when a) the Postfix SMTP server
+       requests TLS authentication from a remote SMTP client, or
+       b) when the Postfix SMTP client initiates a TLS handshake
+       with a remote SMTP server. See RELEASE_NOTES for details.
+       Viktor Dukhovni. Files: mantools/postlink, proto/TLS_README.html,
+       proto/postconf.proto, global/mail_params.h,
+       posttls-finger/posttls-finger.c, smtp/lmtp_params.c,
+       smtp/smtp.c, smtp/smtp.h, smtp/smtp_params.c, smtp/smtp_proto.c,
+       smtp/smtp_tls_policy.c, smtpd/smtpd.c, smtpd/smtpd_check.c,
+       tls/tls.h, tls/tls_client.c, tls/tls_dane.c, tls/tls_fprint.c,
+       tls/tls_misc.c, tls/tls_proxy.h, tls/tls_proxy_client_print.c,
+       tls/tls_proxy_client_scan.c, tls/tls_proxy_context_print.c,
+       tls/tls_proxy_context_scan.c, tls/tls_server.c, tls/tls_verify.c,
+       tlsproxy/tlsproxy.c.
index e7fd25910accefaa9ca1ae5dc6600a552710763e..5e635549f99d6d5ab9c1ffd7b39228f4f7bec178 100644 (file)
@@ -1726,73 +1726,109 @@ describe the corresponding table syntax:
 n\bno\bon\bne\be
     No TLS. No additional attributes are supported at this level.
 m\bma\bay\by
-    Opportunistic TLS. The optional "ciphers", "exclude" and "protocols"
-    attributes (available for opportunistic TLS with Postfix >= 2.6) override
-    the "smtp_tls_ciphers", "smtp_tls_exclude_ciphers" and "smtp_tls_protocols"
-    configuration parameters. At this level and higher, the optional
-    "servername" attribute (available with Postfix >= 3.4) overrides the global
-    "smtp_tls_servername" parameter, enabling per-destination configuration of
-    the SNI extension sent to the remote SMTP server.
+    Opportunistic TLS. The optional "ciphers", "exclude", and "protocols"
+    attributes (available for opportunistic TLS with Postfix >= 2.6) and
+    "connection_reuse" attribute (Postfix >= 3.4) override the
+    "smtp_tls_ciphers", "smtp_tls_exclude_ciphers", "smtp_tls_protocols", and
+    "smtp_tls_connection_reuse" configuration parameters. At this level and
+    higher, the optional "servername" attribute (available with Postfix >= 3.4)
+    overrides the global "smtp_tls_servername" parameter, enabling per-
+    destination configuration of the SNI extension sent to the remote SMTP
+    server. The optional "enable_rpk" attribute (Postfix >= 3.9) overrides the
+    main.cf smtp_tls_enable_rpk parameter. When opportunistic TLS handshakes
+    fail, Postfix retries the connection with TLS disabled. This allows mail
+    delivery to sites with non-interoperable TLS implementations.
 e\ben\bnc\bcr\bry\byp\bpt\bt
     Mandatory encryption. Mail is delivered only if the remote SMTP server
     offers STARTTLS and the TLS handshake succeeds. At this level and higher,
     the optional "protocols" attribute overrides the main.cf
     smtp_tls_mandatory_protocols parameter, the optional "ciphers" attribute
-    overrides the main.cf smtp_tls_mandatory_ciphers parameter, and the
-    optional "exclude" attribute (Postfix >= 2.6) overrides the main.cf
-    smtp_tls_mandatory_exclude_ciphers parameter.
+    overrides the main.cf smtp_tls_mandatory_ciphers parameter, the optional
+    "exclude" attribute (Postfix >= 2.6) overrides the main.cf
+    smtp_tls_mandatory_exclude_ciphers parameter, and the optional
+    "connection_reuse" attribute (Postfix >= 3.4) overrides the main.cf
+    smtp_tls_connection_reuse parameter. The optional "enable_rpk" attribute
+    (Postfix >= 3.9) overrides the main.cf smtp_tls_enable_rpk parameter.
 d\bda\ban\bne\be
     Opportunistic DANE TLS. The TLS policy for the destination is obtained via
     TLSA records in DNSSEC. If no TLSA records are found, the effective
     security level used is may. If TLSA records are found, but none are usable,
     the effective security level is encrypt. When usable TLSA records are
-    obtained for the remote SMTP server, SSLv2+3 are automatically disabled
-    (see smtp_tls_mandatory_protocols), and the server certificate must match
-    the TLSA records. RFC 7672 (DANE) TLS authentication and DNSSEC support is
-    available with Postfix 2.11 and later.
+    obtained for the remote SMTP server, the server certificate must match the
+    TLSA records (and the SNI name is unconditionally set to the TLSA base
+    domain). RFC 7672 (DANE) TLS authentication and DNSSEC support is available
+    with Postfix 2.11 and later. The optional "connection_reuse" attribute
+    (Postfix >= 3.4) overrides the main.cf smtp_tls_connection_reuse parameter.
+    When the effective security level used is may, the optional "ciphers",
+    "exclude", and "protocols" attributes (Postfix >= 2.6) override the
+    "smtp_tls_ciphers", "smtp_tls_exclude_ciphers", and "smtp_tls_protocols"
+    configuration parameters. When the effective security level used is
+    encrypt, the optional "ciphers", "exclude", and "protocols" attributes
+    (Postfix >= 2.6) override the "smtp_tls_mandatory_ciphers",
+    "smtp_tls_mandatory_exclude_ciphers", and "smtp_tls_mandatory_protocols"
+    configuration parameters.
 d\bda\ban\bne\be-\b-o\bon\bnl\bly\by
     Mandatory DANE TLS. The TLS policy for the destination is obtained via TLSA
     records in DNSSEC. If no TLSA records are found, or none are usable, no
     connection is made to the server. When usable TLSA records are obtained for
-    the remote SMTP server, SSLv2+3 are automatically disabled (see
-    smtp_tls_mandatory_protocols), and the server certificate must match the
-    TLSA records. RFC 7672 (DANE) TLS authentication and DNSSEC support is
-    available with Postfix 2.11 and later.
+    the remote SMTP server, the server certificate must match the TLSA records.
+    RFC 7672 (DANE) TLS authentication and DNSSEC support is available with
+    Postfix 2.11 and later. The optional "ciphers", "exclude", and "protocols"
+    attributes (Postfix >= 2.6) override the "smtp_tls_mandatory_ciphers",
+    "smtp_tls_mandatory_exclude_ciphers", and "smtp_tls_mandatory_protocols"
+    configuration parameters. The optional "connection_reuse" attribute
+    (Postfix >= 3.4) overrides the main.cf smtp_tls_connection_reuse parameter.
 f\bfi\bin\bng\bge\ber\brp\bpr\bri\bin\bnt\bt
     Certificate fingerprint verification. Available with Postfix 2.5 and later.
     At this security level, there are no trusted Certification Authorities. The
     certificate trust chain, expiration date, ... are not checked. Instead, the
-    optional m\bma\bat\btc\bch\bh attribute, or else the main.cf
-    s\bsm\bmt\btp\bp_\b_t\btl\bls\bs_\b_f\bfi\bin\bng\bge\ber\brp\bpr\bri\bin\bnt\bt_\b_c\bce\ber\brt\bt_\b_m\bma\bat\btc\bch\bh parameter, lists the server certificate
-    fingerprints or public key fingerprints (Postfix 2.9 and later). The digest
-    algorithm used to calculate fingerprints is selected by the
-    s\bsm\bmt\btp\bp_\b_t\btl\bls\bs_\b_f\bfi\bin\bng\bge\ber\brp\bpr\bri\bin\bnt\bt_\b_d\bdi\big\bge\bes\bst\bt parameter. Multiple fingerprints can be
-    combined with a "|" delimiter in a single match attribute, or multiple
-    match attributes can be employed. The ":" character is not used as a
-    delimiter as it occurs between each pair of fingerprint (hexadecimal)
-    digits.
+    optional "match" attribute, or else the main.cf
+    s\bsm\bmt\btp\bp_\b_t\btl\bls\bs_\b_f\bfi\bin\bng\bge\ber\brp\bpr\bri\bin\bnt\bt_\b_c\bce\ber\brt\bt_\b_m\bma\bat\btc\bch\bh parameter, lists the certificate
+    fingerprints or the public key fingerprints (Postfix 2.9 and later) of
+    acceptable server certificates. The digest algorithm used to calculate the
+    fingerprint is selected by the s\bsm\bmt\btp\bp_\b_t\btl\bls\bs_\b_f\bfi\bin\bng\bge\ber\brp\bpr\bri\bin\bnt\bt_\b_d\bdi\big\bge\bes\bst\bt parameter.
+    Multiple fingerprints can be combined with a "|" delimiter in a single
+    match attribute, or multiple match attributes can be employed. The ":
+    " character is not used as a delimiter as it occurs between each pair of
+    fingerprint (hexadecimal) digits. The optional "ciphers", "exclude", and
+    "protocols" attributes (Postfix >= 2.6) override the
+    "smtp_tls_mandatory_ciphers", "smtp_tls_mandatory_exclude_ciphers", and
+    "smtp_tls_mandatory_protocols" configuration parameters. The optional
+    "connection_reuse" attribute (Postfix >= 3.4) overrides the main.cf
+    smtp_tls_connection_reuse parameter. The optional "enable_rpk" attribute
+    (Postfix >= 3.9) overrides the main.cf smtp_tls_enable_rpk parameter.
 v\bve\ber\bri\bif\bfy\by
     Mandatory server certificate verification. Mail is delivered only if the
-    TLS handshake succeeds, if the remote SMTP server certificate can be
-    validated (not expired or revoked, and signed by a trusted Certification
-    Authority), and if the server certificate name matches the optional "match"
-    attribute (or the main.cf smtp_tls_verify_cert_match parameter value when
-    no optional "match" attribute is specified). With Postfix >= 2.11 the
+    TLS handshake succeeds, the remote SMTP server certificate chain can be
+    validated, and a DNS name in the certificate matches the specified match
+    criteria. At this security level, DNS MX lookups are presumed to be secure
+    enough, and the name verified in the server certificate is potentially
+    obtained via unauthenticated DNS MX lookups. The server certificate name
+    must match either the optional "match" attribute, or else the main.cf
+    smtp_tls_verify_cert_match parameter value. With Postfix >= 2.11 the
     "tafile" attribute optionally modifies trust chain verification in the same
     manner as the "smtp_tls_trust_anchor_file" parameter. The "tafile"
     attribute may be specified multiple times to load multiple trust-anchor
-    files.
+    files. The optional "connection_reuse" attribute (Postfix >= 3.4) overrides
+    the main.cf smtp_tls_connection_reuse parameter.
 s\bse\bec\bcu\bur\bre\be
     Secure certificate verification. Mail is delivered only if the TLS
-    handshake succeeds, and DNS forgery resistant remote SMTP certificate
-    verification succeeds (not expired or revoked, and signed by a trusted
-    Certification Authority), and if the server certificate name matches the
-    optional "match" attribute (or the main.cf smtp_tls_secure_cert_match
-    parameter value when no optional "match" attribute is specified). With
-    Postfix >= 2.11 the "tafile" attribute optionally modifies trust chain
-    verification in the same manner as the "smtp_tls_trust_anchor_file"
-    parameter. The "tafile" attribute may be specified multiple times to load
-    multiple trust-anchor files.
+    handshake succeeds, the remote SMTP server certificate chain can be
+    validated, and a DNS name in the certificate matches the specified match
+    criteria. At this security level, DNS MX lookups, though potentially used
+    to determine the candidate next-hop gateway IP addresses, are n\bno\bot\bt presumed
+    to be secure enough for TLS peername verification. Instead, the default
+    name verified in the server certificate is obtained directly from the next-
+    hop, or is explicitly specified via the optional "match" attribute which
+    overrides the main.cf smtp_tls_secure_cert_match parameter. The optional
+    "ciphers", "exclude", and "protocols" attributes (Postfix >= 2.6) override
+    the "smtp_tls_mandatory_ciphers", "smtp_tls_mandatory_exclude_ciphers", and
+    "smtp_tls_mandatory_protocols" configuration parameters. With Postfix >=
+    2.11 the "tafile" attribute optionally modifies trust chain verification in
+    the same manner as the "smtp_tls_trust_anchor_file" parameter. The "tafile"
+    attribute may be specified multiple times to load multiple trust-anchor
+    files. The optional "connection_reuse" attribute (Postfix >= 3.4) overrides
+    the main.cf smtp_tls_connection_reuse parameter.
 Notes:
 
   * The "match" attribute is especially useful to verify TLS certificates for
index c41d91711ef7b48fe527905a704def34dd30f64b..d4f2c1a5c12b40faf8cc483dcdcaaaccb5941ce6 100644 (file)
@@ -26,6 +26,61 @@ now also distributed with the more recent Eclipse Public License
 license of their choice. Those who are more comfortable with the
 IPL can continue with that license.
 
+Major changes with snapshot 20230807
+====================================
+
+Optional Postfix TLS support to request an RFC7250 raw public key
+instead of an X.509 public-key certificate. The configuration
+settings for raw key public support will be ignored when there is
+no raw public key support in the local TLS implementation (i.e.
+Postfix with OpenSSL versions before 3.2).
+
+- With "smtpd_tls_enable_rpk = yes", the Postfix SMTP server will
+  request that a remote SMTP client sends an RFC7250 raw public key
+  instead of an X.509 certificate when asking for or requiring TLS
+  client authentication. The Postfix SMTP server will still accept
+  a client public-key certificate instead of a public key.
+
+- With "smtp_tls_enable_rpk = yes" (or "enable_rpk = yes" in an
+  smtp policy table) at the security levels "may", "encrypt" or
+  "fingerprint", the Postfix SMTP client will request that a remote
+  SMTP server sends an RFC7250 raw public key instead of an X.509
+  certificate. The Postfix SMTP client will still accept a server
+  public key certificate instead of a public key.
+
+- At the "dane" security level, the Postfix SMTP client will ignore
+  smtp_tls_enable_rpk or enable_rpk settings, and will request that
+  a remote SMTP server sends an RFC7250 raw public key instead of
+  an X.509 certificate when all valid TLSA records specify only
+  server public keys (no certificates). The Postfix SMTP client
+  will still accept a server public key certificate.
+
+- The Postfix SMTP client and server always send a raw public key
+  instead of a certificate, if solicited by the remote SMTP peer
+  and the local TLS implementation supports raw public keys.
+
+- If a remote SMTP client sends a server name indication with an
+  SNI TLS extension, and tls_server_sni_maps is configured, the
+  Postfix SMTP server will extract a raw public key from the indicated
+  certificate.
+
+Caution: enabling Postfix raw key support will break authentication
+based on certificate fingerprints in check_ccert_access or
+smtp_policy_maps, when a remote peer's TLS implementation starts
+to send a raw public key instead of a certificate. The solution is
+to always use public key fingerprint patterns; these will match
+not only a "raw" public key, but also the public key in a certificate.
+
+To detect such problems before they happen, the Postfix SMTP client
+and server will log a warning when they request an RFC7250 raw
+public key instead of an X.509 certificate, the remote peer sends
+a certificate instead of a public key, and check_ccert_access or
+smtp_policy_maps has a matching fingerprint for the certificate but
+not for the public key in that certificate.
+
+For instructions to generate public-key fingerprints, see the
+postconf(5) man pages for smtp_tls_enable_rpk and smtpd_tls_enable_rpk.
+
 Incompatible changes with snapshot 20230603
 ===========================================
 
index eb9965ade4c46c208a104d05cbb888efcd22fa67..a77f69d47136a61f0cf767724b0245632054bf8c 100644 (file)
@@ -2266,82 +2266,124 @@ describe the corresponding table syntax: </p>
 additional attributes are supported at this level. </dd>
 
 <dt><b>may</b></dt> <dd><a href="#client_tls_may">Opportunistic TLS</a>.
-The optional "ciphers", "exclude" and "protocols" attributes
-(available for opportunistic TLS with Postfix &ge; 2.6) override the
-"<a href="postconf.5.html#smtp_tls_ciphers">smtp_tls_ciphers</a>", "<a href="postconf.5.html#smtp_tls_exclude_ciphers">smtp_tls_exclude_ciphers</a>" and "<a href="postconf.5.html#smtp_tls_protocols">smtp_tls_protocols</a>"
-configuration parameters.  At this level and higher, the optional
-"servername" attribute (available with Postfix &ge; 3.4) overrides the
-global "<a href="postconf.5.html#smtp_tls_servername">smtp_tls_servername</a>" parameter, enabling per-destination
-configuration of the SNI extension sent to the remote SMTP server. </dd>
+The optional "ciphers", "exclude", and "protocols" attributes (available
+for opportunistic TLS with Postfix &ge; 2.6) and "connection_reuse"
+attribute (Postfix &ge; 3.4) override the "<a href="postconf.5.html#smtp_tls_ciphers">smtp_tls_ciphers</a>",
+"<a href="postconf.5.html#smtp_tls_exclude_ciphers">smtp_tls_exclude_ciphers</a>", "<a href="postconf.5.html#smtp_tls_protocols">smtp_tls_protocols</a>", and
+"<a href="postconf.5.html#smtp_tls_connection_reuse">smtp_tls_connection_reuse</a>" configuration parameters.  At this level and
+higher, the optional "servername" attribute (available with Postfix &ge;
+3.4) overrides the global "<a href="postconf.5.html#smtp_tls_servername">smtp_tls_servername</a>" parameter, enabling
+per-destination configuration of the SNI extension sent to the remote
+SMTP server.  The optional "enable_rpk" attribute (Postfix &ge; 3.9)
+overrides the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_enable_rpk">smtp_tls_enable_rpk</a> parameter.  When opportunistic
+TLS handshakes fail, Postfix retries the connection with TLS disabled.
+This allows mail delivery to sites with non-interoperable TLS
+implementations.</dd>
 
 <dt><b>encrypt</b></dt> <dd><a href="#client_tls_encrypt"> Mandatory encryption</a>.
-Mail is delivered only if the remote SMTP server offers STARTTLS
-and the TLS handshake succeeds. At this level and higher, the optional
+Mail is delivered only if the remote SMTP server offers STARTTLS and the
+TLS handshake succeeds. At this level and higher, the optional
 "protocols" attribute overrides the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a>
-parameter, the optional "ciphers" attribute overrides the
-<a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_mandatory_ciphers">smtp_tls_mandatory_ciphers</a> parameter, and the optional
-"exclude" attribute (Postfix &ge; 2.6) overrides the <a href="postconf.5.html">main.cf</a>
-<a href="postconf.5.html#smtp_tls_mandatory_exclude_ciphers">smtp_tls_mandatory_exclude_ciphers</a> parameter.  </dd>
+parameter, the optional "ciphers" attribute overrides the <a href="postconf.5.html">main.cf</a>
+<a href="postconf.5.html#smtp_tls_mandatory_ciphers">smtp_tls_mandatory_ciphers</a> parameter, the optional "exclude" attribute
+(Postfix &ge; 2.6) overrides the <a href="postconf.5.html">main.cf</a>
+<a href="postconf.5.html#smtp_tls_mandatory_exclude_ciphers">smtp_tls_mandatory_exclude_ciphers</a> parameter, and the optional
+"connection_reuse" attribute (Postfix &ge; 3.4) overrides the <a href="postconf.5.html">main.cf</a>
+<a href="postconf.5.html#smtp_tls_connection_reuse">smtp_tls_connection_reuse</a> parameter. The optional "enable_rpk" attribute
+(Postfix &ge; 3.9) overrides the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_enable_rpk">smtp_tls_enable_rpk</a> parameter.
+</dd>
 
 <dt><b>dane</b></dt> <dd><a href="#client_tls_dane">Opportunistic DANE TLS</a>.
 The TLS policy for the destination is obtained via TLSA records in
-DNSSEC.  If no TLSA records are found, the effective security level
-used is <a href="#client_tls_may">may</a>.  If TLSA records are
-found, but none are usable, the effective security level is <a
-href="#client_tls_encrypt">encrypt</a>.  When usable TLSA records
-are obtained for the remote SMTP server, SSLv2+3 are automatically
-disabled (see <a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a>), and the server certificate
-must match the TLSA records.  <a href="https://tools.ietf.org/html/rfc7672">RFC 7672</a> (DANE) TLS authentication
-and DNSSEC support is available with Postfix 2.11 and later.  </dd>
+DNSSEC.  If no TLSA records are found, the effective security level used
+is <a href="#client_tls_may">may</a>.  If TLSA records are found, but
+none are usable, the effective security level is <a
+href="#client_tls_encrypt">encrypt</a>.  When usable TLSA records are
+obtained for the remote SMTP server, the server certificate must match
+the TLSA records (and the SNI name is unconditionally set to the TLSA
+<i>base domain</i>).  <a href="https://tools.ietf.org/html/rfc7672">RFC 7672</a> (DANE) TLS authentication and DNSSEC
+support is available with Postfix 2.11 and later. The optional
+"connection_reuse" attribute (Postfix &ge; 3.4) overrides the <a href="postconf.5.html">main.cf</a>
+<a href="postconf.5.html#smtp_tls_connection_reuse">smtp_tls_connection_reuse</a> parameter.  When the effective security level
+used is <a href="#client_tls_may">may</a>, the optional "ciphers",
+"exclude", and "protocols" attributes (Postfix &ge; 2.6) override the
+"<a href="postconf.5.html#smtp_tls_ciphers">smtp_tls_ciphers</a>", "<a href="postconf.5.html#smtp_tls_exclude_ciphers">smtp_tls_exclude_ciphers</a>", and "<a href="postconf.5.html#smtp_tls_protocols">smtp_tls_protocols</a>"
+configuration parameters.  When the effective security level used is <a
+href="#client_tls_encrypt">encrypt</a>, the optional "ciphers",
+"exclude", and "protocols" attributes (Postfix &ge; 2.6) override the
+"<a href="postconf.5.html#smtp_tls_mandatory_ciphers">smtp_tls_mandatory_ciphers</a>", "<a href="postconf.5.html#smtp_tls_mandatory_exclude_ciphers">smtp_tls_mandatory_exclude_ciphers</a>", and
+"<a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a>" configuration parameters.  </dd>
 
 <dt><b>dane-only</b></dt> <dd><a href="#client_tls_dane">Mandatory DANE TLS</a>.
 The TLS policy for the destination is obtained via TLSA records in
-DNSSEC.  If no TLSA records are found, or none are usable, no
-connection is made to the server.  When usable TLSA records are
-obtained for the remote SMTP server, SSLv2+3 are automatically disabled
-(see <a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a>), and the server certificate must
-match the TLSA records.  <a href="https://tools.ietf.org/html/rfc7672">RFC 7672</a> (DANE) TLS authentication and
-DNSSEC support is available with Postfix 2.11 and later.  </dd>
+DNSSEC.  If no TLSA records are found, or none are usable, no connection
+is made to the server.  When usable TLSA records are obtained for the
+remote SMTP server, the server certificate must match the TLSA records.
+<a href="https://tools.ietf.org/html/rfc7672">RFC 7672</a> (DANE) TLS authentication and DNSSEC support is available with
+Postfix 2.11 and later. The optional "ciphers", "exclude", and
+"protocols" attributes (Postfix &ge; 2.6) override the
+"<a href="postconf.5.html#smtp_tls_mandatory_ciphers">smtp_tls_mandatory_ciphers</a>", "<a href="postconf.5.html#smtp_tls_mandatory_exclude_ciphers">smtp_tls_mandatory_exclude_ciphers</a>", and
+"<a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a>" configuration parameters. The optional
+"connection_reuse" attribute (Postfix &ge; 3.4) overrides the <a href="postconf.5.html">main.cf</a>
+<a href="postconf.5.html#smtp_tls_connection_reuse">smtp_tls_connection_reuse</a> parameter.  </dd>
 
 <dt><b>fingerprint</b></dt> <dd><a href="#client_tls_fprint">Certificate
-fingerprint verification.</a> Available with Postfix 2.5 and
-later. At this security level, there are no trusted Certification
-Authorities. The certificate trust chain, expiration date, ... are
-not checked. Instead, the optional <b>match</b> attribute, or else
-the <a href="postconf.5.html">main.cf</a> <b><a href="postconf.5.html#smtp_tls_fingerprint_cert_match">smtp_tls_fingerprint_cert_match</a></b> parameter, lists
-the server certificate fingerprints or public key fingerprints
-(Postfix 2.9 and later).  The
-digest algorithm used to calculate fingerprints is selected by the
-<b><a href="postconf.5.html#smtp_tls_fingerprint_digest">smtp_tls_fingerprint_digest</a></b> parameter. Multiple fingerprints can
-be combined with a "|" delimiter in a single match attribute, or multiple
-match attributes can be employed. The ":" character is not used as a
-delimiter as it occurs between each pair of fingerprint (hexadecimal)
-digits. </dd>
+fingerprint verification.</a> Available with Postfix 2.5 and later. At
+this security level, there are no trusted Certification Authorities. The
+certificate trust chain, expiration date, ... are not checked. Instead,
+the optional "match" attribute, or else the <a href="postconf.5.html">main.cf</a>
+<b><a href="postconf.5.html#smtp_tls_fingerprint_cert_match">smtp_tls_fingerprint_cert_match</a></b> parameter, lists the certificate
+fingerprints or the public key fingerprints (Postfix 2.9 and later) of
+acceptable server certificates. The digest algorithm used to calculate
+the fingerprint is selected by the <b><a href="postconf.5.html#smtp_tls_fingerprint_digest">smtp_tls_fingerprint_digest</a></b>
+parameter. Multiple fingerprints can be combined with a "|" delimiter in
+a single match attribute, or multiple match attributes can be employed.
+The ":" character is not used as a delimiter as it occurs between each
+pair of fingerprint (hexadecimal) digits. The optional "ciphers",
+"exclude", and "protocols" attributes (Postfix &ge; 2.6) override the
+"<a href="postconf.5.html#smtp_tls_mandatory_ciphers">smtp_tls_mandatory_ciphers</a>", "<a href="postconf.5.html#smtp_tls_mandatory_exclude_ciphers">smtp_tls_mandatory_exclude_ciphers</a>", and
+"<a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a>" configuration parameters. The optional
+"connection_reuse" attribute (Postfix &ge; 3.4) overrides the <a href="postconf.5.html">main.cf</a>
+<a href="postconf.5.html#smtp_tls_connection_reuse">smtp_tls_connection_reuse</a> parameter.  The optional "enable_rpk"
+attribute (Postfix &ge; 3.9) overrides the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_enable_rpk">smtp_tls_enable_rpk</a>
+parameter. </dd>
 
 <dt><b>verify</b></dt> <dd><a href="#client_tls_verify">Mandatory
-server certificate verification</a>.  Mail is delivered only if the
-TLS handshake succeeds, if the remote SMTP server certificate can
-be validated (not expired or revoked, and signed by a trusted
-Certification Authority), and if the server certificate name matches
-the optional "match" attribute (or the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_verify_cert_match">smtp_tls_verify_cert_match</a>
-parameter value when no optional "match" attribute is specified).
-With Postfix &ge; 2.11 the "tafile" attribute optionally modifies
-trust chain verification in the same manner as the
-"<a href="postconf.5.html#smtp_tls_trust_anchor_file">smtp_tls_trust_anchor_file</a>" parameter.  The "tafile" attribute
-may be specified multiple times to load multiple trust-anchor
-files.  </dd>
+server certificate verification</a>.  Mail is delivered only if the TLS
+handshake succeeds, the remote SMTP server certificate chain can be
+validated, and a DNS name in the certificate matches the specified match
+criteria. At this security level, DNS MX lookups are presumed to be
+secure enough, and the name verified in the server certificate is
+potentially obtained via unauthenticated DNS MX lookups.  The server
+certificate name must match either the optional "match" attribute, or
+else the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_verify_cert_match">smtp_tls_verify_cert_match</a> parameter value.  With
+Postfix &ge; 2.11 the "tafile" attribute optionally modifies trust chain
+verification in the same manner as the "<a href="postconf.5.html#smtp_tls_trust_anchor_file">smtp_tls_trust_anchor_file</a>"
+parameter.  The "tafile" attribute may be specified multiple times to
+load multiple trust-anchor files. The optional "connection_reuse"
+attribute (Postfix &ge; 3.4) overrides the <a href="postconf.5.html">main.cf</a>
+<a href="postconf.5.html#smtp_tls_connection_reuse">smtp_tls_connection_reuse</a> parameter.  </dd>
 
 <dt><b>secure</b></dt> <dd><a href="#client_tls_secure">Secure certificate
-verification.</a> Mail is delivered only if the TLS handshake succeeds,
-and DNS forgery resistant remote SMTP certificate verification succeeds
-(not expired or revoked, and signed by a trusted Certification Authority),
-and if the server certificate name matches the optional "match" attribute
-(or the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_secure_cert_match">smtp_tls_secure_cert_match</a> parameter value when no optional
-"match" attribute is specified).  With Postfix &ge; 2.11 the "tafile"
-attribute optionally modifies trust chain verification in the same manner
-as the "<a href="postconf.5.html#smtp_tls_trust_anchor_file">smtp_tls_trust_anchor_file</a>" parameter.  The "tafile" attribute
-may be specified multiple times to load multiple trust-anchor
-files.  </dd>
+verification.</a>
+Mail is delivered only if the TLS handshake succeeds, the remote SMTP
+server certificate chain can be validated, and a DNS name in the
+certificate matches the specified match criteria.  At this security
+level, DNS MX lookups, though potentially used to determine the
+candidate next-hop gateway IP addresses, are <b>not</b> presumed to be
+secure enough for TLS peername verification.  Instead, the default name
+verified in the server certificate is obtained directly from the
+next-hop, or is explicitly specified via the optional "match" attribute
+which overrides the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_secure_cert_match">smtp_tls_secure_cert_match</a> parameter.  The
+optional "ciphers", "exclude", and "protocols" attributes (Postfix &ge;
+2.6) override the "<a href="postconf.5.html#smtp_tls_mandatory_ciphers">smtp_tls_mandatory_ciphers</a>",
+"<a href="postconf.5.html#smtp_tls_mandatory_exclude_ciphers">smtp_tls_mandatory_exclude_ciphers</a>", and "<a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a>"
+configuration parameters.  With Postfix &ge; 2.11 the "tafile" attribute
+optionally modifies trust chain verification in the same manner as the
+"<a href="postconf.5.html#smtp_tls_trust_anchor_file">smtp_tls_trust_anchor_file</a>" parameter.  The "tafile" attribute may be
+specified multiple times to load multiple trust-anchor files. The
+optional "connection_reuse" attribute (Postfix &ge; 3.4) overrides the
+<a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_connection_reuse">smtp_tls_connection_reuse</a> parameter.  </dd>
 
 </dl>
 
index c3f7074849fb69ce43bc5211746707fa700b8c02..4469e07d704fafc472b5a1e99accc895051e6281 100644 (file)
@@ -724,41 +724,47 @@ SMTP(8)                                                                SMTP(8)
               The application name passed by Postfix to OpenSSL  library  ini-
               tialization functions.
 
+       Available in Postfix version 3.9 and later:
+
+       <b><a href="postconf.5.html#smtp_tls_enable_rpk">smtp_tls_enable_rpk</a> (no)</b>
+              Request  that remote SMTP servers send an <a href="https://tools.ietf.org/html/rfc7250">RFC7250</a> raw public key
+              instead of an X.509 certificate.
+
 <b>OBSOLETE STARTTLS CONTROLS</b>
-       The  following  configuration  parameters  exist for compatibility with
-       Postfix versions before 2.3. Support for these will  be  removed  in  a
+       The following configuration parameters  exist  for  compatibility  with
+       Postfix  versions  before  2.3.  Support for these will be removed in a
        future release.
 
        <b><a href="postconf.5.html#smtp_use_tls">smtp_use_tls</a> (no)</b>
-              Opportunistic  mode: use TLS when a remote SMTP server announces
+              Opportunistic mode: use TLS when a remote SMTP server  announces
               STARTTLS support, otherwise send the mail in the clear.
 
        <b><a href="postconf.5.html#smtp_enforce_tls">smtp_enforce_tls</a> (no)</b>
-              Enforcement mode: require  that  remote  SMTP  servers  use  TLS
+              Enforcement  mode:  require  that  remote  SMTP  servers use TLS
               encryption, and never send mail in the clear.
 
        <b><a href="postconf.5.html#smtp_tls_enforce_peername">smtp_tls_enforce_peername</a> (yes)</b>
-              With  mandatory  TLS  encryption,  require  that the remote SMTP
-              server hostname matches  the  information  in  the  remote  SMTP
+              With mandatory TLS encryption,  require  that  the  remote  SMTP
+              server  hostname  matches  the  information  in  the remote SMTP
               server certificate.
 
        <b><a href="postconf.5.html#smtp_tls_per_site">smtp_tls_per_site</a> (empty)</b>
-              Optional  lookup  tables  with the Postfix SMTP client TLS usage
-              policy by next-hop destination and by remote SMTP  server  host-
+              Optional lookup tables with the Postfix SMTP  client  TLS  usage
+              policy  by  next-hop destination and by remote SMTP server host-
               name.
 
        <b><a href="postconf.5.html#smtp_tls_cipherlist">smtp_tls_cipherlist</a> (empty)</b>
-              Obsolete  Postfix  &lt; 2.3 control for the Postfix SMTP client TLS
+              Obsolete Postfix &lt; 2.3 control for the Postfix SMTP  client  TLS
               cipher list.
 
 <b>RESOURCE AND RATE CONTROLS</b>
        <b><a href="postconf.5.html#smtp_connect_timeout">smtp_connect_timeout</a> (30s)</b>
-              The Postfix SMTP client time limit for completing a TCP  connec-
+              The  Postfix SMTP client time limit for completing a TCP connec-
               tion, or zero (use the operating system built-in time limit).
 
        <b><a href="postconf.5.html#smtp_helo_timeout">smtp_helo_timeout</a> (300s)</b>
-              The  Postfix SMTP client time limit for sending the HELO or EHLO
-              command, and  for  receiving  the  initial  remote  SMTP  server
+              The Postfix SMTP client time limit for sending the HELO or  EHLO
+              command,  and  for  receiving  the  initial  remote  SMTP server
               response.
 
        <b><a href="postconf.5.html#lmtp_lhlo_timeout">lmtp_lhlo_timeout</a> (300s)</b>
@@ -770,19 +776,19 @@ SMTP(8)                                                                SMTP(8)
               mand, and for receiving the remote SMTP server response.
 
        <b><a href="postconf.5.html#smtp_mail_timeout">smtp_mail_timeout</a> (300s)</b>
-              The  Postfix  SMTP  client  time limit for sending the MAIL FROM
+              The Postfix SMTP client time limit for  sending  the  MAIL  FROM
               command, and for receiving the remote SMTP server response.
 
        <b><a href="postconf.5.html#smtp_rcpt_timeout">smtp_rcpt_timeout</a> (300s)</b>
-              The Postfix SMTP client time limit for sending the SMTP RCPT  TO
+              The  Postfix SMTP client time limit for sending the SMTP RCPT TO
               command, and for receiving the remote SMTP server response.
 
        <b><a href="postconf.5.html#smtp_data_init_timeout">smtp_data_init_timeout</a> (120s)</b>
-              The  Postfix  SMTP  client  time limit for sending the SMTP DATA
+              The Postfix SMTP client time limit for  sending  the  SMTP  DATA
               command, and for receiving the remote SMTP server response.
 
        <b><a href="postconf.5.html#smtp_data_xfer_timeout">smtp_data_xfer_timeout</a> (180s)</b>
-              The Postfix SMTP client time limit for sending the SMTP  message
+              The  Postfix SMTP client time limit for sending the SMTP message
               content.
 
        <b><a href="postconf.5.html#smtp_data_done_timeout">smtp_data_done_timeout</a> (600s)</b>
@@ -796,13 +802,13 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.1 and later:
 
        <b><a href="postconf.5.html#smtp_mx_address_limit">smtp_mx_address_limit</a> (5)</b>
-              The  maximal number of MX (mail exchanger) IP addresses that can
-              result from Postfix SMTP client mail exchanger lookups, or  zero
+              The maximal number of MX (mail exchanger) IP addresses that  can
+              result  from Postfix SMTP client mail exchanger lookups, or zero
               (no limit).
 
        <b><a href="postconf.5.html#smtp_mx_session_limit">smtp_mx_session_limit</a> (2)</b>
-              The  maximal number of SMTP sessions per delivery request before
-              the Postfix SMTP client gives up  or  delivers  to  a  fall-back
+              The maximal number of SMTP sessions per delivery request  before
+              the  Postfix  SMTP  client  gives  up or delivers to a fall-back
               <a href="postconf.5.html#relayhost">relay host</a>, or zero (no limit).
 
        <b><a href="postconf.5.html#smtp_rset_timeout">smtp_rset_timeout</a> (20s)</b>
@@ -812,17 +818,17 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.2 and earlier:
 
        <b><a href="postconf.5.html#lmtp_cache_connection">lmtp_cache_connection</a> (yes)</b>
-              Keep Postfix LMTP client connections open for  up  to  $<a href="postconf.5.html#max_idle">max_idle</a>
+              Keep  Postfix  LMTP  client connections open for up to $<a href="postconf.5.html#max_idle">max_idle</a>
               seconds.
 
        Available in Postfix version 2.2 and later:
 
        <b><a href="postconf.5.html#smtp_connection_cache_destinations">smtp_connection_cache_destinations</a> (empty)</b>
-              Permanently  enable  SMTP  connection  caching for the specified
+              Permanently enable SMTP connection  caching  for  the  specified
               destinations.
 
        <b><a href="postconf.5.html#smtp_connection_cache_on_demand">smtp_connection_cache_on_demand</a> (yes)</b>
-              Temporarily enable SMTP connection caching while  a  destination
+              Temporarily  enable  SMTP connection caching while a destination
               has a high volume of mail in the <a href="QSHAPE_README.html#active_queue">active queue</a>.
 
        <b><a href="postconf.5.html#smtp_connection_reuse_time_limit">smtp_connection_reuse_time_limit</a> (300s)</b>
@@ -836,23 +842,23 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.3 and later:
 
        <b><a href="postconf.5.html#connection_cache_protocol_timeout">connection_cache_protocol_timeout</a> (5s)</b>
-              Time  limit for connection cache connect, send or receive opera-
+              Time limit for connection cache connect, send or receive  opera-
               tions.
 
        Available in Postfix version 2.9 - 3.6:
 
        <b><a href="postconf.5.html#smtp_per_record_deadline">smtp_per_record_deadline</a> (no)</b>
-              Change the behavior of the smtp_*_timeout time  limits,  from  a
-              time  limit  per  read  or write system call, to a time limit to
-              send or receive a complete record (an SMTP  command  line,  SMTP
-              response  line,  SMTP message content line, or TLS protocol mes-
+              Change  the  behavior  of the smtp_*_timeout time limits, from a
+              time limit per read or write system call, to  a  time  limit  to
+              send  or  receive  a complete record (an SMTP command line, SMTP
+              response line, SMTP message content line, or TLS  protocol  mes-
               sage).
 
        Available in Postfix version 2.11 and later:
 
        <b><a href="postconf.5.html#smtp_connection_reuse_count_limit">smtp_connection_reuse_count_limit</a> (0)</b>
-              When SMTP connection caching is enabled,  the  number  of  times
-              that  an SMTP session may be reused before it is closed, or zero
+              When  SMTP  connection  caching  is enabled, the number of times
+              that an SMTP session may be reused before it is closed, or  zero
               (no limit).
 
        Available in Postfix version 3.4 and later:
@@ -863,13 +869,13 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 3.7 and later:
 
        <b><a href="postconf.5.html#smtp_per_request_deadline">smtp_per_request_deadline</a> (no)</b>
-              Change the behavior of the smtp_*_timeout time  limits,  from  a
-              time  limit  per  plaintext or TLS read or write call, to a com-
-              bined time limit for sending a complete  SMTP  request  and  for
+              Change  the  behavior  of the smtp_*_timeout time limits, from a
+              time limit per plaintext or TLS read or write call,  to  a  com-
+              bined  time  limit  for  sending a complete SMTP request and for
               receiving a complete SMTP response.
 
        <b><a href="postconf.5.html#smtp_min_data_rate">smtp_min_data_rate</a> (500)</b>
-              The  minimum  plaintext  data  transfer rate in bytes/second for
+              The minimum plaintext data transfer  rate  in  bytes/second  for
               DATA    requests,    when    deadlines    are    enabled    with
               <a href="postconf.5.html#smtp_per_request_deadline">smtp_per_request_deadline</a>.
 
@@ -877,54 +883,54 @@ SMTP(8)                                                                SMTP(8)
 
        <b><a href="postconf.5.html#transport_destination_concurrency_limit">transport_destination_concurrency_limit</a>   ($<a href="postconf.5.html#default_destination_concurrency_limit">default_destination_concur</a>-</b>
        <b><a href="postconf.5.html#default_destination_concurrency_limit">rency_limit</a>)</b>
-              A  transport-specific  override for the <a href="postconf.5.html#default_destination_concurrency_limit">default_destination_con</a>-
+              A transport-specific override for  the  <a href="postconf.5.html#default_destination_concurrency_limit">default_destination_con</a>-
               <a href="postconf.5.html#default_destination_concurrency_limit">currency_limit</a> parameter value, where <i>transport</i> is the <a href="master.5.html">master.cf</a>
               name of the message delivery transport.
 
        <b><a href="postconf.5.html#transport_destination_recipient_limit">transport_destination_recipient_limit</a>     ($<a href="postconf.5.html#default_destination_recipient_limit">default_destination_recipi</a>-</b>
        <b><a href="postconf.5.html#default_destination_recipient_limit">ent_limit</a>)</b>
               A transport-specific override for the <a href="postconf.5.html#default_destination_recipient_limit">default_destination_recip</a>-
-              <a href="postconf.5.html#default_destination_recipient_limit">ient_limit</a> parameter value, where  <i>transport</i>  is  the  <a href="master.5.html">master.cf</a>
+              <a href="postconf.5.html#default_destination_recipient_limit">ient_limit</a>  parameter  value,  where  <i>transport</i> is the <a href="master.5.html">master.cf</a>
               name of the message delivery transport.
 
 <b>SMTPUTF8 CONTROLS</b>
        Preliminary SMTPUTF8 support is introduced with Postfix 3.0.
 
        <b><a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> (yes)</b>
-              Enable  preliminary SMTPUTF8 support for the protocols described
+              Enable preliminary SMTPUTF8 support for the protocols  described
               in <a href="https://tools.ietf.org/html/rfc6531">RFC 6531</a>, <a href="https://tools.ietf.org/html/rfc6532">RFC 6532</a>, and <a href="https://tools.ietf.org/html/rfc6533">RFC 6533</a>.
 
        <b><a href="postconf.5.html#smtputf8_autodetect_classes">smtputf8_autodetect_classes</a> (sendmail, verify)</b>
-              Detect that a message requires SMTPUTF8 support for  the  speci-
+              Detect  that  a message requires SMTPUTF8 support for the speci-
               fied mail origin classes.
 
        Available in Postfix version 3.2 and later:
 
        <b><a href="postconf.5.html#enable_idna2003_compatibility">enable_idna2003_compatibility</a> (no)</b>
-              Enable   'transitional'   compatibility   between  IDNA2003  and
-              IDNA2008, when converting UTF-8 domain names to/from  the  ASCII
+              Enable  'transitional'  compatibility   between   IDNA2003   and
+              IDNA2008,  when  converting UTF-8 domain names to/from the ASCII
               form that is used for DNS lookups.
 
 <b>TROUBLE SHOOTING CONTROLS</b>
        <b><a href="postconf.5.html#debug_peer_level">debug_peer_level</a> (2)</b>
-              The  increment  in verbose logging level when a nexthop destina-
-              tion, remote client or server name or network address matches  a
+              The increment in verbose logging level when a  nexthop  destina-
+              tion,  remote client or server name or network address matches a
               pattern given with the <a href="postconf.5.html#debug_peer_list">debug_peer_list</a> parameter.
 
        <b><a href="postconf.5.html#debug_peer_list">debug_peer_list</a> (empty)</b>
-              Optional  list  of  nexthop destination, remote client or server
-              name or network address patterns that,  if  matched,  cause  the
-              verbose  logging  level  to  increase by the amount specified in
+              Optional list of nexthop destination, remote  client  or  server
+              name  or  network  address  patterns that, if matched, cause the
+              verbose logging level to increase by  the  amount  specified  in
               $<a href="postconf.5.html#debug_peer_level">debug_peer_level</a>.
 
        <b><a href="postconf.5.html#error_notice_recipient">error_notice_recipient</a> (postmaster)</b>
-              The recipient of postmaster notifications  about  mail  delivery
+              The  recipient  of  postmaster notifications about mail delivery
               problems that are caused by policy, resource, software or proto-
               col errors.
 
        <b><a href="postconf.5.html#internal_mail_filter_classes">internal_mail_filter_classes</a> (empty)</b>
-              What  categories  of  Postfix-generated  mail  are  subject   to
-              before-queue    content    inspection    by   <a href="postconf.5.html#non_smtpd_milters">non_smtpd_milters</a>,
+              What   categories  of  Postfix-generated  mail  are  subject  to
+              before-queue   content    inspection    by    <a href="postconf.5.html#non_smtpd_milters">non_smtpd_milters</a>,
               <a href="postconf.5.html#header_checks">header_checks</a> and <a href="postconf.5.html#body_checks">body_checks</a>.
 
        <b><a href="postconf.5.html#notify_classes">notify_classes</a> (resource, software)</b>
@@ -932,46 +938,46 @@ SMTP(8)                                                                SMTP(8)
 
 <b>MISCELLANEOUS CONTROLS</b>
        <b><a href="postconf.5.html#best_mx_transport">best_mx_transport</a> (empty)</b>
-              Where the Postfix  SMTP  client  should  deliver  mail  when  it
+              Where  the  Postfix  SMTP  client  should  deliver  mail when it
               detects a "mail loops back to myself" error condition.
 
        <b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
-              The  default  location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
+              The default location of the Postfix <a href="postconf.5.html">main.cf</a> and  <a href="master.5.html">master.cf</a>  con-
               figuration files.
 
        <b><a href="postconf.5.html#daemon_timeout">daemon_timeout</a> (18000s)</b>
-              How much time a Postfix daemon process  may  take  to  handle  a
+              How  much  time  a  Postfix  daemon process may take to handle a
               request before it is terminated by a built-in watchdog timer.
 
        <b><a href="postconf.5.html#delay_logging_resolution_limit">delay_logging_resolution_limit</a> (2)</b>
-              The  maximal  number of digits after the decimal point when log-
+              The maximal number of digits after the decimal point  when  log-
               ging sub-second delay values.
 
        <b><a href="postconf.5.html#disable_dns_lookups">disable_dns_lookups</a> (no)</b>
               Disable DNS lookups in the Postfix SMTP and LMTP clients.
 
        <b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a> (all)</b>
-              The local network interface  addresses  that  this  mail  system
+              The  local  network  interface  addresses  that this mail system
               receives mail on.
 
        <b><a href="postconf.5.html#inet_protocols">inet_protocols</a> (see 'postconf -d output')</b>
-              The  Internet  protocols Postfix will attempt to use when making
+              The Internet protocols Postfix will attempt to use  when  making
               or accepting connections.
 
        <b><a href="postconf.5.html#ipc_timeout">ipc_timeout</a> (3600s)</b>
-              The time limit for sending  or  receiving  information  over  an
+              The  time  limit  for  sending  or receiving information over an
               internal communication channel.
 
        <b><a href="postconf.5.html#lmtp_assume_final">lmtp_assume_final</a> (no)</b>
-              When  a remote LMTP server announces no DSN support, assume that
-              the server performs final delivery, and send "delivered"  deliv-
+              When a remote LMTP server announces no DSN support, assume  that
+              the  server performs final delivery, and send "delivered" deliv-
               ery status notifications instead of "relayed".
 
        <b><a href="postconf.5.html#lmtp_tcp_port">lmtp_tcp_port</a> (24)</b>
               The default TCP port that the Postfix LMTP client connects to.
 
        <b><a href="postconf.5.html#max_idle">max_idle</a> (100s)</b>
-              The  maximum  amount of time that an idle Postfix daemon process
+              The maximum amount of time that an idle Postfix  daemon  process
               waits for an incoming connection before terminating voluntarily.
 
        <b><a href="postconf.5.html#max_use">max_use</a> (100)</b>
@@ -985,21 +991,21 @@ SMTP(8)                                                                SMTP(8)
               The process name of a Postfix command or daemon process.
 
        <b><a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a> (empty)</b>
-              The remote network interface addresses  that  this  mail  system
-              receives  mail  on by way of a proxy or network address transla-
+              The  remote  network  interface  addresses that this mail system
+              receives mail on by way of a proxy or network  address  transla-
               tion unit.
 
        <b><a href="postconf.5.html#smtp_address_preference">smtp_address_preference</a> (any)</b>
               The address type ("ipv6", "ipv4" or "any") that the Postfix SMTP
-              client  will  try  first,  when  a destination has IPv6 and IPv4
+              client will try first, when a  destination  has  IPv6  and  IPv4
               addresses with equal MX preference.
 
        <b><a href="postconf.5.html#smtp_bind_address">smtp_bind_address</a> (empty)</b>
-              An optional numerical network  address  that  the  Postfix  SMTP
+              An  optional  numerical  network  address  that the Postfix SMTP
               client should bind to when making an IPv4 connection.
 
        <b><a href="postconf.5.html#smtp_bind_address6">smtp_bind_address6</a> (empty)</b>
-              An  optional  numerical  network  address  that the Postfix SMTP
+              An optional numerical network  address  that  the  Postfix  SMTP
               client should bind to when making an IPv6 connection.
 
        <b><a href="postconf.5.html#smtp_helo_name">smtp_helo_name</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
@@ -1019,7 +1025,7 @@ SMTP(8)                                                                SMTP(8)
               The syslog facility of Postfix logging.
 
        <b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
-              A  prefix  that  is  prepended  to  the  process  name in syslog
+              A prefix that  is  prepended  to  the  process  name  in  syslog
               records, so that, for example, "smtpd" becomes "prefix/smtpd".
 
        Available with Postfix 2.2 and earlier:
@@ -1031,14 +1037,14 @@ SMTP(8)                                                                SMTP(8)
        Available with Postfix 2.3 and later:
 
        <b><a href="postconf.5.html#smtp_fallback_relay">smtp_fallback_relay</a> ($<a href="postconf.5.html#fallback_relay">fallback_relay</a>)</b>
-              Optional  list  of  relay destinations that will be used when an
-              SMTP destination is not found, or when delivery fails due  to  a
+              Optional list of relay destinations that will be  used  when  an
+              SMTP  destination  is not found, or when delivery fails due to a
               non-permanent error.
 
        Available with Postfix 3.0 and later:
 
        <b><a href="postconf.5.html#smtp_address_verify_target">smtp_address_verify_target</a> (rcpt)</b>
-              In  the context of email address verification, the SMTP protocol
+              In the context of email address verification, the SMTP  protocol
               stage that determines whether an email address is deliverable.
 
        Available with Postfix 3.1 and later:
@@ -1060,7 +1066,7 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix 3.7 and later:
 
        <b><a href="postconf.5.html#smtp_bind_address_enforce">smtp_bind_address_enforce</a> (no)</b>
-              Defer  delivery  when  the  Postfix SMTP client cannot apply the
+              Defer delivery when the Postfix SMTP  client  cannot  apply  the
               <a href="postconf.5.html#smtp_bind_address">smtp_bind_address</a> or <a href="postconf.5.html#smtp_bind_address6">smtp_bind_address6</a> setting.
 
 <b>SEE ALSO</b>
index 4b636827279f257ce4e08d7da2b570dc70189b8a..84d7d093a92d89963995a23a6f76d70f3c56e804 100644 (file)
@@ -5599,6 +5599,17 @@ parameter.  See there for details. </p>
 compiled and linked with OpenSSL 1.0.0 or later. </p>
 
 
+</DD>
+
+<DT><b><a name="lmtp_tls_enable_rpk">lmtp_tls_enable_rpk</a>
+(default: yes)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_tls_enable_rpk">smtp_tls_enable_rpk</a>
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 3.9 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="lmtp_tls_enforce_peername">lmtp_tls_enforce_peername</a>
@@ -13122,6 +13133,72 @@ to anyone else. </p>
 compiled and linked with OpenSSL 1.0.0 or later. </p>
 
 
+</DD>
+
+<DT><b><a name="smtp_tls_enable_rpk">smtp_tls_enable_rpk</a>
+(default: no)</b></DT><DD>
+
+<p> Request that remote SMTP servers send an <a href="https://tools.ietf.org/html/rfc7250">RFC7250</a> raw public key
+instead of an X.509 certificate. This feature and the enable_rpk
+policy attribute are ignored when there is no raw public key support
+in the local TLS implementation.  </p>
+
+<ul>
+
+<li> <p> At the "may", "encrypt" and "fingerprint" security levels,
+with parameter setting "<a href="postconf.5.html#smtp_tls_enable_rpk">smtp_tls_enable_rpk</a> = yes" or with "enable_rpk
+= yes" in a policy entry, the Postfix SMTP client will indicate in
+the TLS handshake that it prefers to receive a raw server public
+key, but it will still accept a server public key certificate. </p>
+
+<li> <p> At the "fingerprint" security level, with parameter setting
+"<a href="postconf.5.html#smtp_tls_enable_rpk">smtp_tls_enable_rpk</a> = yes" or with "enable_rpk = yes" in a policy entry,
+server authentication based on certificate fingerprints becomes more
+fragile.  Even if the server private key and certificate remain
+unchanged, the remote SMTP server will fail fingerprint authentication
+(won't match the configured list of fingerprints) when it starts sending
+a raw public key instead of a certificate, after its TLS implementation
+is updated with raw public key support.  Therefore, <b>DO NOT</b>
+enable raw public keys to remote destinations authenticated by server
+<b>certificate</b> fingerprints.  You should enable raw public keys
+only for servers matched via their public key fingerprint.  </p>
+
+<li> <p> At the "dane" security level, the Postfix SMTP client
+always ignores the parameter setting <a href="postconf.5.html#smtp_tls_enable_rpk">smtp_tls_enable_rpk</a> or the
+enable_rpk policy attribute. When all valid TLSA records specify
+only server public keys (no certificates) and the local TLS
+implementation supports raw public keys, the client will indicate
+in the TLS handshake that it prefers to receive a raw public key,
+but it will still accept a public key certificate. </p>
+
+</ul>
+
+<p>The Postfix SMTP client is always willing to send raw public keys
+to servers that solicit them when a client certificate is configured
+and the local TLS implementation supports raw public keys. </p>
+
+<p> Sample commands to compute certificate and public key SHA256 digests: </p>
+
+<pre>
+# SHA256 digest of the first certificate in "cert.pem"
+$ openssl x509 -in cert.pem -outform DER | openssl dgst -sha256 -c
+</pre>
+
+<pre>
+# SHA256 digest of the SPKI of the first certificate in "cert.pem"
+$ openssl x509 -in cert.pem -pubkey -noout |
+    openssl pkey -pubin -outform DER | openssl dgst -sha256 -c
+</pre>
+
+<pre>
+# SHA256 digest of the SPKI of the first private key in "pkey.pem"
+$ openssl pkey -in pkey.pem -pubout -outform DER |
+    openssl dgst -sha256 -c
+</pre>
+
+<p> This feature is available in Postfix 3.9 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="smtp_tls_enforce_peername">smtp_tls_enforce_peername</a>
@@ -13732,28 +13809,35 @@ security are: </p>
 <dd>Opportunistic TLS. Since sending in the clear is acceptable,
 demanding stronger than default TLS security merely reduces
 interoperability. The optional "ciphers", "exclude", and "protocols"
-attributes (available for opportunistic TLS with Postfix &ge; 2.6)
-and "connection_reuse" attribute (Postfix &ge; 3.4) override the
+attributes (available for opportunistic TLS with Postfix &ge; 2.6) and
+"connection_reuse" attribute (Postfix &ge; 3.4) override the
 "<a href="postconf.5.html#smtp_tls_ciphers">smtp_tls_ciphers</a>", "<a href="postconf.5.html#smtp_tls_exclude_ciphers">smtp_tls_exclude_ciphers</a>", "<a href="postconf.5.html#smtp_tls_protocols">smtp_tls_protocols</a>",
-and
-"<a href="postconf.5.html#smtp_tls_connection_reuse">smtp_tls_connection_reuse</a>" configuration parameters. In the policy table,
-multiple ciphers, protocols or excluded ciphers must be separated by colons,
-as attribute values may not contain whitespace or commas. When opportunistic
-TLS handshakes fail, Postfix retries the connection with TLS disabled.
-This allows mail delivery to sites with non-interoperable TLS
-implementations.</dd>
+and "<a href="postconf.5.html#smtp_tls_connection_reuse">smtp_tls_connection_reuse</a>" configuration parameters. In the policy
+table, multiple ciphers, protocols or excluded ciphers must be separated
+by colons, as attribute values may not contain whitespace or commas.  At
+this level and higher, the optional "servername" attribute (available
+with Postfix &ge; 3.4) overrides the global "<a href="postconf.5.html#smtp_tls_servername">smtp_tls_servername</a>"
+parameter, enabling per-destination configuration of the SNI extension
+sent to the remote SMTP server.  The optional "enable_rpk" attribute
+(Postfix &ge; 3.9) overrides the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_enable_rpk">smtp_tls_enable_rpk</a> parameter.
+When opportunistic TLS handshakes fail, Postfix retries the connection
+with TLS disabled.  This allows mail delivery to sites with
+non-interoperable TLS implementations.</dd>
 
 <dt><b><a href="TLS_README.html#client_tls_encrypt">encrypt</a></b></dt>
-<dd>Mandatory TLS encryption. At this level
-and higher, the optional "protocols" attribute overrides the <a href="postconf.5.html">main.cf</a>
+<dd>Mandatory TLS encryption. Mail is delivered only if the remote SMTP
+server offers STARTTLS and the TLS handshake succeeds. At this level and
+higher, the optional "protocols" attribute overrides the <a href="postconf.5.html">main.cf</a>
 <a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a> parameter, the optional "ciphers" attribute
-overrides the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_mandatory_ciphers">smtp_tls_mandatory_ciphers</a> parameter, the
-optional "exclude" attribute (Postfix &ge; 2.6) overrides the <a href="postconf.5.html">main.cf</a>
+overrides the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_mandatory_ciphers">smtp_tls_mandatory_ciphers</a> parameter, the optional
+"exclude" attribute (Postfix &ge; 2.6) overrides the <a href="postconf.5.html">main.cf</a>
 <a href="postconf.5.html#smtp_tls_mandatory_exclude_ciphers">smtp_tls_mandatory_exclude_ciphers</a> parameter, and the optional
-"connection_reuse" attribute (Postfix &ge; 3.4) overrides the
-<a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_connection_reuse">smtp_tls_connection_reuse</a> parameter. In the policy table,
-multiple ciphers, protocols or excluded ciphers must be separated by colons,
-as attribute values may not contain whitespace or commas. </dd>
+"connection_reuse" attribute (Postfix &ge; 3.4) overrides the <a href="postconf.5.html">main.cf</a>
+<a href="postconf.5.html#smtp_tls_connection_reuse">smtp_tls_connection_reuse</a> parameter. In the policy table, multiple
+ciphers, protocols or excluded ciphers must be separated by colons, as
+attribute values may not contain whitespace or commas.  The optional
+"enable_rpk" attribute (Postfix &ge; 3.9) overrides the <a href="postconf.5.html">main.cf</a>
+<a href="postconf.5.html#smtp_tls_enable_rpk">smtp_tls_enable_rpk</a> parameter. </dd>
 
 <dt><b><a href="TLS_README.html#client_tls_dane">dane</a></b></dt>
 <dd>Opportunistic DANE TLS.  The TLS policy for the destination is
@@ -13798,10 +13882,10 @@ configuration parameters. The optional "connection_reuse" attribute
 verification. Available with Postfix 2.5 and later. At this security
 level, there are no trusted Certification Authorities. The certificate
 trust chain, expiration date, ... are not checked. Instead,
-the optional "match" attribute, or else the <a href="postconf.5.html">main.cf</a>
+the optional policy table "match" attribute, or else the <a href="postconf.5.html">main.cf</a>
 <b><a href="postconf.5.html#smtp_tls_fingerprint_cert_match">smtp_tls_fingerprint_cert_match</a></b> parameter, lists the certificate
-fingerprints or the public key fingerprint (Postfix 2.9 and later)
-of the valid server certificate. The digest
+fingerprints or the public key fingerprints (Postfix 2.9 and later)
+of acceptable server certificates. The digest
 algorithm used to calculate the fingerprint is selected by the
 <b><a href="postconf.5.html#smtp_tls_fingerprint_digest">smtp_tls_fingerprint_digest</a></b> parameter. Multiple fingerprints can
 be combined with a "|" delimiter in a single match attribute, or multiple
@@ -13812,45 +13896,58 @@ digits. The optional "ciphers", "exclude", and "protocols" attributes
 "<a href="postconf.5.html#smtp_tls_mandatory_exclude_ciphers">smtp_tls_mandatory_exclude_ciphers</a>", and "<a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a>"
 configuration parameters. The optional "connection_reuse" attribute
 (Postfix &ge; 3.4) overrides the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_connection_reuse">smtp_tls_connection_reuse</a>
-parameter. </dd>
+parameter.  The optional "enable_rpk" attribute (Postfix &ge; 3.9)
+overrides the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_enable_rpk">smtp_tls_enable_rpk</a> parameter. </dd>
 
 <dt><b><a href="TLS_README.html#client_tls_verify">verify</a></b></dt>
-<dd>Mandatory TLS verification.  At this security
-level, DNS MX lookups are trusted to be secure enough, and the name
-verified in the server certificate is usually obtained indirectly via
-unauthenticated DNS MX lookups.  The optional "match" attribute overrides
-the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_verify_cert_match">smtp_tls_verify_cert_match</a> parameter. In the policy table,
-multiple match patterns and strategies must be separated by colons.
-In practice explicit control over matching is more common with the
-"secure" policy, described below. The optional "ciphers", "exclude",
-and "protocols" attributes (Postfix &ge; 2.6) override the
-"<a href="postconf.5.html#smtp_tls_mandatory_ciphers">smtp_tls_mandatory_ciphers</a>", "<a href="postconf.5.html#smtp_tls_mandatory_exclude_ciphers">smtp_tls_mandatory_exclude_ciphers</a>", and
-"<a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a>" configuration parameters. The optional
-"connection_reuse" attribute (Postfix &ge; 3.4) overrides the <a href="postconf.5.html">main.cf</a>
-<a href="postconf.5.html#smtp_tls_connection_reuse">smtp_tls_connection_reuse</a> parameter. </dd>
+<dd>Mandatory TLS verification.  Mail is delivered only if the TLS
+handshake succeeds, the remote SMTP server certificate chain can be
+validated, and a DNS name in the certificate matches the specified match
+criteria. At this security level, DNS MX lookups are presumed to be
+secure enough, and the name verified in the server certificate is
+potentially obtained via unauthenticated DNS MX lookups.  The optional
+"match" attribute overrides the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_verify_cert_match">smtp_tls_verify_cert_match</a>
+parameter. In the policy table, multiple match patterns and strategies
+must be separated by colons.  In practice explicit control over matching
+is more common with the "secure" policy, described below. The optional
+"ciphers", "exclude", and "protocols" attributes (Postfix &ge; 2.6)
+override the "<a href="postconf.5.html#smtp_tls_mandatory_ciphers">smtp_tls_mandatory_ciphers</a>",
+"<a href="postconf.5.html#smtp_tls_mandatory_exclude_ciphers">smtp_tls_mandatory_exclude_ciphers</a>", and "<a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a>"
+configuration parameters. With Postfix &ge; 2.11 the optional "tafile"
+policy table attribute modifies trust chain verification in the same
+manner as the "<a href="postconf.5.html#smtp_tls_trust_anchor_file">smtp_tls_trust_anchor_file</a>" parameter. The "tafile"
+attribute may be specified multiple times to load multiple trust-anchor
+files. The optional "connection_reuse" attribute (Postfix &ge; 3.4)
+overrides the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_connection_reuse">smtp_tls_connection_reuse</a> parameter. </dd>
 
 <dt><b><a href="TLS_README.html#client_tls_secure">secure</a></b></dt>
-<dd>Secure-channel TLS. At this security level, DNS
-MX lookups, though potentially used to determine the candidate next-hop
-gateway IP addresses, are <b>not</b> trusted to be secure enough for TLS
-peername verification. Instead, the default name verified in the server
-certificate is obtained directly from the next-hop, or is explicitly
-specified via the optional "match" attribute which overrides the
-<a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_secure_cert_match">smtp_tls_secure_cert_match</a> parameter. In the policy table,
-multiple match patterns and strategies must be separated by colons.
-The match attribute is most useful when multiple domains are supported by
-a common server: the policy entries for additional domains specify matching
-rules for the primary domain certificate. While transport table overrides
-that route the secondary domains to the primary nexthop also allow secure
-verification, they risk delivery to the wrong destination when domains
-change hands or are re-assigned to new gateways. With the "match"
-attribute approach, routing is not perturbed, and mail is deferred if
-verification of a new MX host fails. The optional "ciphers", "exclude",
-and "protocols" attributes (Postfix &ge; 2.6) override the
-"<a href="postconf.5.html#smtp_tls_mandatory_ciphers">smtp_tls_mandatory_ciphers</a>", "<a href="postconf.5.html#smtp_tls_mandatory_exclude_ciphers">smtp_tls_mandatory_exclude_ciphers</a>", and
-"<a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a>" configuration parameters. The optional
-"connection_reuse" attribute (Postfix &ge; 3.4) overrides the <a href="postconf.5.html">main.cf</a>
-<a href="postconf.5.html#smtp_tls_connection_reuse">smtp_tls_connection_reuse</a> parameter. </dd>
+<dd>Secure certificate verification. Mail is delivered only if the TLS
+handshake succeeds, the remote SMTP server certificate chain can be
+validated, and a DNS name in the certificate matches the specified match
+criteria.  At this security level, DNS MX lookups, though potentially
+used to determine the candidate next-hop gateway IP addresses, are
+<b>not</b> presumed to be secure enough for TLS peername verification.
+Instead, the default name verified in the server certificate is obtained
+directly from the next-hop, or is explicitly specified via the optional
+"match" attribute which overrides the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_secure_cert_match">smtp_tls_secure_cert_match</a>
+parameter. In the policy table, multiple match patterns and strategies
+must be separated by colons.  The match attribute is most useful when
+multiple domains are supported by a common server: the policy entries
+for additional domains specify matching rules for the primary domain
+certificate. While transport table overrides that route the secondary
+domains to the primary nexthop also allow secure verification, they risk
+delivery to the wrong destination when domains change hands or are
+re-assigned to new gateways. With the "match" attribute approach,
+routing is not perturbed, and mail is deferred if verification of a new
+MX host fails. The optional "ciphers", "exclude", and "protocols"
+attributes (Postfix &ge; 2.6) override the "<a href="postconf.5.html#smtp_tls_mandatory_ciphers">smtp_tls_mandatory_ciphers</a>",
+"<a href="postconf.5.html#smtp_tls_mandatory_exclude_ciphers">smtp_tls_mandatory_exclude_ciphers</a>", and "<a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a>"
+configuration parameters. With Postfix &ge; 2.11 the "tafile" attribute
+optionally modifies trust chain verification in the same manner as the
+"<a href="postconf.5.html#smtp_tls_trust_anchor_file">smtp_tls_trust_anchor_file</a>" parameter.  The "tafile" attribute may be
+specified multiple times to load multiple trust-anchor files. The
+optional "connection_reuse" attribute (Postfix &ge; 3.4) overrides the
+<a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#smtp_tls_connection_reuse">smtp_tls_connection_reuse</a> parameter. </dd>
 
 </dl>
 
@@ -18256,6 +18353,53 @@ compiled and linked with OpenSSL 1.0.0 or later on platforms
 where EC algorithms have not been disabled by the vendor. </p>
 
 
+</DD>
+
+<DT><b><a name="smtpd_tls_enable_rpk">smtpd_tls_enable_rpk</a>
+(default: no)</b></DT><DD>
+
+<p> Request that remote SMTP clients send an <a href="https://tools.ietf.org/html/rfc7250">RFC7250</a> raw public key
+instead of an X.509 certificate, when asking for or requiring client
+authentication. This feature is ignored when there is no raw public
+key support in the local TLS implementation. </p>
+
+<p> The Postfix SMTP server will log a warning when "<a href="postconf.5.html#smtpd_tls_enable_rpk">smtpd_tls_enable_rpk</a>
+= yes", but the remote SMTP client sends a certificate, the
+certificate's public key fingerprint does not match a <a href="postconf.5.html#check_ccert_access">check_ccert_access</a>
+table, while the certificate fingerprint does match a <a href="postconf.5.html#check_ccert_access">check_ccert_access</a>
+table. The remote SMTP client would lose access when it starts
+sending a raw public key instead of a certificate, after its TLS
+implementation is updated with raw public key support. </p>
+
+<p> The Postfix SMTP server always sends a raw public key instead
+of a certificate, if solicited by the remote SMTP client and the
+local TLS implementation supports raw public keys. If the client
+sends a server name indication with an SNI TLS extension, and
+<a href="postconf.5.html#tls_server_sni_maps">tls_server_sni_maps</a> is configured, the server will extract a raw
+public key from the indicated certificate. </p>
+
+<p> Sample commands to compute certificate and public key SHA256 digests: </p>
+
+<pre>
+# SHA256 digest of the first certificate in "cert.pem"
+$ openssl x509 -in cert.pem -outform DER | openssl dgst -sha256 -c
+</pre>
+
+<pre>
+# SHA256 digest of the SPKI of the first certificate in "cert.pem"
+$ openssl x509 -in cert.pem -pubkey -noout |
+    openssl pkey -pubin -outform DER | openssl dgst -sha256 -c
+</pre>
+
+<pre>
+# SHA256 digest of the SPKI of the first private key in "pkey.pem"
+$ openssl pkey -in pkey.pem -pubout -outform DER |
+    openssl dgst -sha256 -c
+</pre>
+
+<p> This feature is available in Postfix 3.9 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="smtpd_tls_exclude_ciphers">smtpd_tls_exclude_ciphers</a>
@@ -20648,6 +20792,18 @@ elliptic-curve Diffie-Hellman (EECDH) key exchange. See
 <p> This feature is available in Postfix 2.8 and later. </p>
 
 
+</DD>
+
+<DT><b><a name="tlsproxy_tls_enable_rpk">tlsproxy_tls_enable_rpk</a>
+(default: $<a href="postconf.5.html#smtpd_tls_enable_rpk">smtpd_tls_enable_rpk</a>)</b></DT><DD>
+
+<p> Request that remote SMTP clients send an <a href="https://tools.ietf.org/html/rfc7250">RFC7250</a> raw public key
+instead of an X.509 certificate, when asking or requiring client
+authentication. See $<a href="postconf.5.html#smtpd_tls_enable_rpk">smtpd_tls_enable_rpk</a> for details. </p>
+
+<p> This feature is available in Postfix 3.9 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="tlsproxy_tls_exclude_ciphers">tlsproxy_tls_exclude_ciphers</a>
index 2ed629a8672ab11c879b0a9a65b7069d0b300fb7..a1475ca8cb379c7222a7502262b8848c24ef0064 100644 (file)
@@ -112,7 +112,7 @@ POSTTLS-FINGER(1)                                            POSTTLS-FINGER(1)
               ified in the DNS).   In  Postfix  versions  prior  to  3.6,  the
               default value was "md5".
 
-       <b>-f</b>     Lookup  the  associated  DANE TLSA RRset even when a hostname is
+       <b>-f</b>     Look  up  the associated DANE TLSA RRset even when a hostname is
               not an alias and its address records lie in  an  unsigned  zone.
               See <a href="postconf.5.html#smtp_tls_force_insecure_host_tlsa_lookup">smtp_tls_force_insecure_host_tlsa_lookup</a> for details.
 
@@ -302,6 +302,16 @@ POSTTLS-FINGER(1)                                            POSTTLS-FINGER(1)
               protocol.   The  destination  <i>domain</i>:<i>port</i> must of course provide
               such a service.
 
+       <b>-x</b>     Prefer <a href="https://tools.ietf.org/html/rfc7250">RFC7250</a> non-X.509 raw public  key  (RPK)  server  creden-
+              tials.   By  default only X.509 certificates are accepted.  This
+              is analogous to setting <b><a href="postconf.5.html#smtp_tls_enable_rpk">smtp_tls_enable_rpk</a> = yes</b> in the <a href="smtp.8.html">smtp(8)</a>
+              client.  At the fingerprint security level, when raw public keys
+              are enabled, only public key (and not certificate)  fingerprints
+              will  be compared against the specified list of <i>match</i> arguments.
+              Certificate fingerprints are fragile when raw  public  keys  are
+              solicited,  the server may at some point in time start returning
+              only the public key.
+
        <b>-X</b>     Enable <a href="tlsproxy.8.html"><b>tlsproxy</b>(8)</a> mode. This is an unsupported mode,  for  pro-
               gram development only.
 
index c3f7074849fb69ce43bc5211746707fa700b8c02..4469e07d704fafc472b5a1e99accc895051e6281 100644 (file)
@@ -724,41 +724,47 @@ SMTP(8)                                                                SMTP(8)
               The application name passed by Postfix to OpenSSL  library  ini-
               tialization functions.
 
+       Available in Postfix version 3.9 and later:
+
+       <b><a href="postconf.5.html#smtp_tls_enable_rpk">smtp_tls_enable_rpk</a> (no)</b>
+              Request  that remote SMTP servers send an <a href="https://tools.ietf.org/html/rfc7250">RFC7250</a> raw public key
+              instead of an X.509 certificate.
+
 <b>OBSOLETE STARTTLS CONTROLS</b>
-       The  following  configuration  parameters  exist for compatibility with
-       Postfix versions before 2.3. Support for these will  be  removed  in  a
+       The following configuration parameters  exist  for  compatibility  with
+       Postfix  versions  before  2.3.  Support for these will be removed in a
        future release.
 
        <b><a href="postconf.5.html#smtp_use_tls">smtp_use_tls</a> (no)</b>
-              Opportunistic  mode: use TLS when a remote SMTP server announces
+              Opportunistic mode: use TLS when a remote SMTP server  announces
               STARTTLS support, otherwise send the mail in the clear.
 
        <b><a href="postconf.5.html#smtp_enforce_tls">smtp_enforce_tls</a> (no)</b>
-              Enforcement mode: require  that  remote  SMTP  servers  use  TLS
+              Enforcement  mode:  require  that  remote  SMTP  servers use TLS
               encryption, and never send mail in the clear.
 
        <b><a href="postconf.5.html#smtp_tls_enforce_peername">smtp_tls_enforce_peername</a> (yes)</b>
-              With  mandatory  TLS  encryption,  require  that the remote SMTP
-              server hostname matches  the  information  in  the  remote  SMTP
+              With mandatory TLS encryption,  require  that  the  remote  SMTP
+              server  hostname  matches  the  information  in  the remote SMTP
               server certificate.
 
        <b><a href="postconf.5.html#smtp_tls_per_site">smtp_tls_per_site</a> (empty)</b>
-              Optional  lookup  tables  with the Postfix SMTP client TLS usage
-              policy by next-hop destination and by remote SMTP  server  host-
+              Optional lookup tables with the Postfix SMTP  client  TLS  usage
+              policy  by  next-hop destination and by remote SMTP server host-
               name.
 
        <b><a href="postconf.5.html#smtp_tls_cipherlist">smtp_tls_cipherlist</a> (empty)</b>
-              Obsolete  Postfix  &lt; 2.3 control for the Postfix SMTP client TLS
+              Obsolete Postfix &lt; 2.3 control for the Postfix SMTP  client  TLS
               cipher list.
 
 <b>RESOURCE AND RATE CONTROLS</b>
        <b><a href="postconf.5.html#smtp_connect_timeout">smtp_connect_timeout</a> (30s)</b>
-              The Postfix SMTP client time limit for completing a TCP  connec-
+              The  Postfix SMTP client time limit for completing a TCP connec-
               tion, or zero (use the operating system built-in time limit).
 
        <b><a href="postconf.5.html#smtp_helo_timeout">smtp_helo_timeout</a> (300s)</b>
-              The  Postfix SMTP client time limit for sending the HELO or EHLO
-              command, and  for  receiving  the  initial  remote  SMTP  server
+              The Postfix SMTP client time limit for sending the HELO or  EHLO
+              command,  and  for  receiving  the  initial  remote  SMTP server
               response.
 
        <b><a href="postconf.5.html#lmtp_lhlo_timeout">lmtp_lhlo_timeout</a> (300s)</b>
@@ -770,19 +776,19 @@ SMTP(8)                                                                SMTP(8)
               mand, and for receiving the remote SMTP server response.
 
        <b><a href="postconf.5.html#smtp_mail_timeout">smtp_mail_timeout</a> (300s)</b>
-              The  Postfix  SMTP  client  time limit for sending the MAIL FROM
+              The Postfix SMTP client time limit for  sending  the  MAIL  FROM
               command, and for receiving the remote SMTP server response.
 
        <b><a href="postconf.5.html#smtp_rcpt_timeout">smtp_rcpt_timeout</a> (300s)</b>
-              The Postfix SMTP client time limit for sending the SMTP RCPT  TO
+              The  Postfix SMTP client time limit for sending the SMTP RCPT TO
               command, and for receiving the remote SMTP server response.
 
        <b><a href="postconf.5.html#smtp_data_init_timeout">smtp_data_init_timeout</a> (120s)</b>
-              The  Postfix  SMTP  client  time limit for sending the SMTP DATA
+              The Postfix SMTP client time limit for  sending  the  SMTP  DATA
               command, and for receiving the remote SMTP server response.
 
        <b><a href="postconf.5.html#smtp_data_xfer_timeout">smtp_data_xfer_timeout</a> (180s)</b>
-              The Postfix SMTP client time limit for sending the SMTP  message
+              The  Postfix SMTP client time limit for sending the SMTP message
               content.
 
        <b><a href="postconf.5.html#smtp_data_done_timeout">smtp_data_done_timeout</a> (600s)</b>
@@ -796,13 +802,13 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.1 and later:
 
        <b><a href="postconf.5.html#smtp_mx_address_limit">smtp_mx_address_limit</a> (5)</b>
-              The  maximal number of MX (mail exchanger) IP addresses that can
-              result from Postfix SMTP client mail exchanger lookups, or  zero
+              The maximal number of MX (mail exchanger) IP addresses that  can
+              result  from Postfix SMTP client mail exchanger lookups, or zero
               (no limit).
 
        <b><a href="postconf.5.html#smtp_mx_session_limit">smtp_mx_session_limit</a> (2)</b>
-              The  maximal number of SMTP sessions per delivery request before
-              the Postfix SMTP client gives up  or  delivers  to  a  fall-back
+              The maximal number of SMTP sessions per delivery request  before
+              the  Postfix  SMTP  client  gives  up or delivers to a fall-back
               <a href="postconf.5.html#relayhost">relay host</a>, or zero (no limit).
 
        <b><a href="postconf.5.html#smtp_rset_timeout">smtp_rset_timeout</a> (20s)</b>
@@ -812,17 +818,17 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.2 and earlier:
 
        <b><a href="postconf.5.html#lmtp_cache_connection">lmtp_cache_connection</a> (yes)</b>
-              Keep Postfix LMTP client connections open for  up  to  $<a href="postconf.5.html#max_idle">max_idle</a>
+              Keep  Postfix  LMTP  client connections open for up to $<a href="postconf.5.html#max_idle">max_idle</a>
               seconds.
 
        Available in Postfix version 2.2 and later:
 
        <b><a href="postconf.5.html#smtp_connection_cache_destinations">smtp_connection_cache_destinations</a> (empty)</b>
-              Permanently  enable  SMTP  connection  caching for the specified
+              Permanently enable SMTP connection  caching  for  the  specified
               destinations.
 
        <b><a href="postconf.5.html#smtp_connection_cache_on_demand">smtp_connection_cache_on_demand</a> (yes)</b>
-              Temporarily enable SMTP connection caching while  a  destination
+              Temporarily  enable  SMTP connection caching while a destination
               has a high volume of mail in the <a href="QSHAPE_README.html#active_queue">active queue</a>.
 
        <b><a href="postconf.5.html#smtp_connection_reuse_time_limit">smtp_connection_reuse_time_limit</a> (300s)</b>
@@ -836,23 +842,23 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.3 and later:
 
        <b><a href="postconf.5.html#connection_cache_protocol_timeout">connection_cache_protocol_timeout</a> (5s)</b>
-              Time  limit for connection cache connect, send or receive opera-
+              Time limit for connection cache connect, send or receive  opera-
               tions.
 
        Available in Postfix version 2.9 - 3.6:
 
        <b><a href="postconf.5.html#smtp_per_record_deadline">smtp_per_record_deadline</a> (no)</b>
-              Change the behavior of the smtp_*_timeout time  limits,  from  a
-              time  limit  per  read  or write system call, to a time limit to
-              send or receive a complete record (an SMTP  command  line,  SMTP
-              response  line,  SMTP message content line, or TLS protocol mes-
+              Change  the  behavior  of the smtp_*_timeout time limits, from a
+              time limit per read or write system call, to  a  time  limit  to
+              send  or  receive  a complete record (an SMTP command line, SMTP
+              response line, SMTP message content line, or TLS  protocol  mes-
               sage).
 
        Available in Postfix version 2.11 and later:
 
        <b><a href="postconf.5.html#smtp_connection_reuse_count_limit">smtp_connection_reuse_count_limit</a> (0)</b>
-              When SMTP connection caching is enabled,  the  number  of  times
-              that  an SMTP session may be reused before it is closed, or zero
+              When  SMTP  connection  caching  is enabled, the number of times
+              that an SMTP session may be reused before it is closed, or  zero
               (no limit).
 
        Available in Postfix version 3.4 and later:
@@ -863,13 +869,13 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 3.7 and later:
 
        <b><a href="postconf.5.html#smtp_per_request_deadline">smtp_per_request_deadline</a> (no)</b>
-              Change the behavior of the smtp_*_timeout time  limits,  from  a
-              time  limit  per  plaintext or TLS read or write call, to a com-
-              bined time limit for sending a complete  SMTP  request  and  for
+              Change  the  behavior  of the smtp_*_timeout time limits, from a
+              time limit per plaintext or TLS read or write call,  to  a  com-
+              bined  time  limit  for  sending a complete SMTP request and for
               receiving a complete SMTP response.
 
        <b><a href="postconf.5.html#smtp_min_data_rate">smtp_min_data_rate</a> (500)</b>
-              The  minimum  plaintext  data  transfer rate in bytes/second for
+              The minimum plaintext data transfer  rate  in  bytes/second  for
               DATA    requests,    when    deadlines    are    enabled    with
               <a href="postconf.5.html#smtp_per_request_deadline">smtp_per_request_deadline</a>.
 
@@ -877,54 +883,54 @@ SMTP(8)                                                                SMTP(8)
 
        <b><a href="postconf.5.html#transport_destination_concurrency_limit">transport_destination_concurrency_limit</a>   ($<a href="postconf.5.html#default_destination_concurrency_limit">default_destination_concur</a>-</b>
        <b><a href="postconf.5.html#default_destination_concurrency_limit">rency_limit</a>)</b>
-              A  transport-specific  override for the <a href="postconf.5.html#default_destination_concurrency_limit">default_destination_con</a>-
+              A transport-specific override for  the  <a href="postconf.5.html#default_destination_concurrency_limit">default_destination_con</a>-
               <a href="postconf.5.html#default_destination_concurrency_limit">currency_limit</a> parameter value, where <i>transport</i> is the <a href="master.5.html">master.cf</a>
               name of the message delivery transport.
 
        <b><a href="postconf.5.html#transport_destination_recipient_limit">transport_destination_recipient_limit</a>     ($<a href="postconf.5.html#default_destination_recipient_limit">default_destination_recipi</a>-</b>
        <b><a href="postconf.5.html#default_destination_recipient_limit">ent_limit</a>)</b>
               A transport-specific override for the <a href="postconf.5.html#default_destination_recipient_limit">default_destination_recip</a>-
-              <a href="postconf.5.html#default_destination_recipient_limit">ient_limit</a> parameter value, where  <i>transport</i>  is  the  <a href="master.5.html">master.cf</a>
+              <a href="postconf.5.html#default_destination_recipient_limit">ient_limit</a>  parameter  value,  where  <i>transport</i> is the <a href="master.5.html">master.cf</a>
               name of the message delivery transport.
 
 <b>SMTPUTF8 CONTROLS</b>
        Preliminary SMTPUTF8 support is introduced with Postfix 3.0.
 
        <b><a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> (yes)</b>
-              Enable  preliminary SMTPUTF8 support for the protocols described
+              Enable preliminary SMTPUTF8 support for the protocols  described
               in <a href="https://tools.ietf.org/html/rfc6531">RFC 6531</a>, <a href="https://tools.ietf.org/html/rfc6532">RFC 6532</a>, and <a href="https://tools.ietf.org/html/rfc6533">RFC 6533</a>.
 
        <b><a href="postconf.5.html#smtputf8_autodetect_classes">smtputf8_autodetect_classes</a> (sendmail, verify)</b>
-              Detect that a message requires SMTPUTF8 support for  the  speci-
+              Detect  that  a message requires SMTPUTF8 support for the speci-
               fied mail origin classes.
 
        Available in Postfix version 3.2 and later:
 
        <b><a href="postconf.5.html#enable_idna2003_compatibility">enable_idna2003_compatibility</a> (no)</b>
-              Enable   'transitional'   compatibility   between  IDNA2003  and
-              IDNA2008, when converting UTF-8 domain names to/from  the  ASCII
+              Enable  'transitional'  compatibility   between   IDNA2003   and
+              IDNA2008,  when  converting UTF-8 domain names to/from the ASCII
               form that is used for DNS lookups.
 
 <b>TROUBLE SHOOTING CONTROLS</b>
        <b><a href="postconf.5.html#debug_peer_level">debug_peer_level</a> (2)</b>
-              The  increment  in verbose logging level when a nexthop destina-
-              tion, remote client or server name or network address matches  a
+              The increment in verbose logging level when a  nexthop  destina-
+              tion,  remote client or server name or network address matches a
               pattern given with the <a href="postconf.5.html#debug_peer_list">debug_peer_list</a> parameter.
 
        <b><a href="postconf.5.html#debug_peer_list">debug_peer_list</a> (empty)</b>
-              Optional  list  of  nexthop destination, remote client or server
-              name or network address patterns that,  if  matched,  cause  the
-              verbose  logging  level  to  increase by the amount specified in
+              Optional list of nexthop destination, remote  client  or  server
+              name  or  network  address  patterns that, if matched, cause the
+              verbose logging level to increase by  the  amount  specified  in
               $<a href="postconf.5.html#debug_peer_level">debug_peer_level</a>.
 
        <b><a href="postconf.5.html#error_notice_recipient">error_notice_recipient</a> (postmaster)</b>
-              The recipient of postmaster notifications  about  mail  delivery
+              The  recipient  of  postmaster notifications about mail delivery
               problems that are caused by policy, resource, software or proto-
               col errors.
 
        <b><a href="postconf.5.html#internal_mail_filter_classes">internal_mail_filter_classes</a> (empty)</b>
-              What  categories  of  Postfix-generated  mail  are  subject   to
-              before-queue    content    inspection    by   <a href="postconf.5.html#non_smtpd_milters">non_smtpd_milters</a>,
+              What   categories  of  Postfix-generated  mail  are  subject  to
+              before-queue   content    inspection    by    <a href="postconf.5.html#non_smtpd_milters">non_smtpd_milters</a>,
               <a href="postconf.5.html#header_checks">header_checks</a> and <a href="postconf.5.html#body_checks">body_checks</a>.
 
        <b><a href="postconf.5.html#notify_classes">notify_classes</a> (resource, software)</b>
@@ -932,46 +938,46 @@ SMTP(8)                                                                SMTP(8)
 
 <b>MISCELLANEOUS CONTROLS</b>
        <b><a href="postconf.5.html#best_mx_transport">best_mx_transport</a> (empty)</b>
-              Where the Postfix  SMTP  client  should  deliver  mail  when  it
+              Where  the  Postfix  SMTP  client  should  deliver  mail when it
               detects a "mail loops back to myself" error condition.
 
        <b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
-              The  default  location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
+              The default location of the Postfix <a href="postconf.5.html">main.cf</a> and  <a href="master.5.html">master.cf</a>  con-
               figuration files.
 
        <b><a href="postconf.5.html#daemon_timeout">daemon_timeout</a> (18000s)</b>
-              How much time a Postfix daemon process  may  take  to  handle  a
+              How  much  time  a  Postfix  daemon process may take to handle a
               request before it is terminated by a built-in watchdog timer.
 
        <b><a href="postconf.5.html#delay_logging_resolution_limit">delay_logging_resolution_limit</a> (2)</b>
-              The  maximal  number of digits after the decimal point when log-
+              The maximal number of digits after the decimal point  when  log-
               ging sub-second delay values.
 
        <b><a href="postconf.5.html#disable_dns_lookups">disable_dns_lookups</a> (no)</b>
               Disable DNS lookups in the Postfix SMTP and LMTP clients.
 
        <b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a> (all)</b>
-              The local network interface  addresses  that  this  mail  system
+              The  local  network  interface  addresses  that this mail system
               receives mail on.
 
        <b><a href="postconf.5.html#inet_protocols">inet_protocols</a> (see 'postconf -d output')</b>
-              The  Internet  protocols Postfix will attempt to use when making
+              The Internet protocols Postfix will attempt to use  when  making
               or accepting connections.
 
        <b><a href="postconf.5.html#ipc_timeout">ipc_timeout</a> (3600s)</b>
-              The time limit for sending  or  receiving  information  over  an
+              The  time  limit  for  sending  or receiving information over an
               internal communication channel.
 
        <b><a href="postconf.5.html#lmtp_assume_final">lmtp_assume_final</a> (no)</b>
-              When  a remote LMTP server announces no DSN support, assume that
-              the server performs final delivery, and send "delivered"  deliv-
+              When a remote LMTP server announces no DSN support, assume  that
+              the  server performs final delivery, and send "delivered" deliv-
               ery status notifications instead of "relayed".
 
        <b><a href="postconf.5.html#lmtp_tcp_port">lmtp_tcp_port</a> (24)</b>
               The default TCP port that the Postfix LMTP client connects to.
 
        <b><a href="postconf.5.html#max_idle">max_idle</a> (100s)</b>
-              The  maximum  amount of time that an idle Postfix daemon process
+              The maximum amount of time that an idle Postfix  daemon  process
               waits for an incoming connection before terminating voluntarily.
 
        <b><a href="postconf.5.html#max_use">max_use</a> (100)</b>
@@ -985,21 +991,21 @@ SMTP(8)                                                                SMTP(8)
               The process name of a Postfix command or daemon process.
 
        <b><a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a> (empty)</b>
-              The remote network interface addresses  that  this  mail  system
-              receives  mail  on by way of a proxy or network address transla-
+              The  remote  network  interface  addresses that this mail system
+              receives mail on by way of a proxy or network  address  transla-
               tion unit.
 
        <b><a href="postconf.5.html#smtp_address_preference">smtp_address_preference</a> (any)</b>
               The address type ("ipv6", "ipv4" or "any") that the Postfix SMTP
-              client  will  try  first,  when  a destination has IPv6 and IPv4
+              client will try first, when a  destination  has  IPv6  and  IPv4
               addresses with equal MX preference.
 
        <b><a href="postconf.5.html#smtp_bind_address">smtp_bind_address</a> (empty)</b>
-              An optional numerical network  address  that  the  Postfix  SMTP
+              An  optional  numerical  network  address  that the Postfix SMTP
               client should bind to when making an IPv4 connection.
 
        <b><a href="postconf.5.html#smtp_bind_address6">smtp_bind_address6</a> (empty)</b>
-              An  optional  numerical  network  address  that the Postfix SMTP
+              An optional numerical network  address  that  the  Postfix  SMTP
               client should bind to when making an IPv6 connection.
 
        <b><a href="postconf.5.html#smtp_helo_name">smtp_helo_name</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
@@ -1019,7 +1025,7 @@ SMTP(8)                                                                SMTP(8)
               The syslog facility of Postfix logging.
 
        <b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
-              A  prefix  that  is  prepended  to  the  process  name in syslog
+              A prefix that  is  prepended  to  the  process  name  in  syslog
               records, so that, for example, "smtpd" becomes "prefix/smtpd".
 
        Available with Postfix 2.2 and earlier:
@@ -1031,14 +1037,14 @@ SMTP(8)                                                                SMTP(8)
        Available with Postfix 2.3 and later:
 
        <b><a href="postconf.5.html#smtp_fallback_relay">smtp_fallback_relay</a> ($<a href="postconf.5.html#fallback_relay">fallback_relay</a>)</b>
-              Optional  list  of  relay destinations that will be used when an
-              SMTP destination is not found, or when delivery fails due  to  a
+              Optional list of relay destinations that will be  used  when  an
+              SMTP  destination  is not found, or when delivery fails due to a
               non-permanent error.
 
        Available with Postfix 3.0 and later:
 
        <b><a href="postconf.5.html#smtp_address_verify_target">smtp_address_verify_target</a> (rcpt)</b>
-              In  the context of email address verification, the SMTP protocol
+              In the context of email address verification, the SMTP  protocol
               stage that determines whether an email address is deliverable.
 
        Available with Postfix 3.1 and later:
@@ -1060,7 +1066,7 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix 3.7 and later:
 
        <b><a href="postconf.5.html#smtp_bind_address_enforce">smtp_bind_address_enforce</a> (no)</b>
-              Defer  delivery  when  the  Postfix SMTP client cannot apply the
+              Defer delivery when the Postfix SMTP  client  cannot  apply  the
               <a href="postconf.5.html#smtp_bind_address">smtp_bind_address</a> or <a href="postconf.5.html#smtp_bind_address6">smtp_bind_address6</a> setting.
 
 <b>SEE ALSO</b>
index 77b954d59b0f18f7a582fb5f69474d53750cf311..c0d76e1968c0e9345b5f2d9d796acfa961c6ee8d 100644 (file)
@@ -648,6 +648,13 @@ SMTPD(8)                                                              SMTPD(8)
               The application name passed by Postfix to OpenSSL  library  ini-
               tialization functions.
 
+       Available in Postfix version 3.9 and later:
+
+       <b><a href="postconf.5.html#smtpd_tls_enable_rpk">smtpd_tls_enable_rpk</a> (no)</b>
+              Request  that remote SMTP clients send an <a href="https://tools.ietf.org/html/rfc7250">RFC7250</a> raw public key
+              instead of an X.509 certificate, when asking  for  or  requiring
+              client authentication.
+
 <b>OBSOLETE STARTTLS CONTROLS</b>
        The  following  configuration  parameters  exist for compatibility with
        Postfix versions before 2.3. Support for these will  be  removed  in  a
index c5e4a7b5ecd0dc434d37d0c951d3dcc2a5706cee..615a2222cb6408a24cd0948014a0aae3613df15d 100644 (file)
@@ -280,6 +280,13 @@ TLSPROXY(8)                                                        TLSPROXY(8)
               Files  with  the Postfix <a href="tlsproxy.8.html"><b>tlsproxy</b>(8)</a> server keys and certificate
               chains in PEM format.
 
+       Available in Postfix version 3.9 and later:
+
+       <b><a href="postconf.5.html#tlsproxy_tls_enable_rpk">tlsproxy_tls_enable_rpk</a> ($<a href="postconf.5.html#smtpd_tls_enable_rpk">smtpd_tls_enable_rpk</a>)</b>
+              Request that remote SMTP clients send an <a href="https://tools.ietf.org/html/rfc7250">RFC7250</a> raw public  key
+              instead of an X.509 certificate, when asking or requiring client
+              authentication.
+
 <b>STARTTLS CLIENT CONTROLS</b>
        These settings are clones of Postfix SMTP client settings.  They  allow
        <a href="tlsproxy.8.html"><b>tlsproxy</b>(8)</a> to load the same certificate and private key information as
index 1e22a03d9e58bab92787c4381723bdf760c9164b..3cba97253c83b4b72efbe2cb6806cf4ead1c9e68 100644 (file)
@@ -109,7 +109,7 @@ fingerprints (with DANE TLSA records the algorithm is specified
 in the DNS).  In Postfix versions prior to 3.6, the default value
 was "md5".
 .IP "\fB\-f\fR"
-Lookup the associated DANE TLSA RRset even when a hostname is not an
+Look up the associated DANE TLSA RRset even when a hostname is not an
 alias and its address records lie in an unsigned zone.  See
 smtp_tls_force_insecure_host_tlsa_lookup for details.
 .IP "\fB\-F \fICAfile.pem\fR (default: none)"
@@ -270,6 +270,15 @@ is typically provided on port 465 by servers that are compatible with
 the SMTP\-in\-SSL protocol, rather than the STARTTLS protocol.
 The destination \fIdomain\fR:\fIport\fR must of course provide such
 a service.
+.IP "\fB\-x\fR"
+Prefer RFC7250 non\-X.509 raw public key (RPK) server credentials.  By
+default only X.509 certificates are accepted.  This is analogous to
+setting \fBsmtp_tls_enable_rpk = yes\fR in the smtp(8) client.  At the
+fingerprint security level, when raw public keys are enabled, only
+public key (and not certificate) fingerprints will be compared against
+the specified list of \fImatch\fR arguments.  Certificate fingerprints
+are fragile when raw public keys are solicited, the server may at some
+point in time start returning only the public key.
 .IP "\fB\-X\fR"
 Enable \fBtlsproxy\fR(8) mode. This is an unsupported mode,
 for program development only.
index a93f671921374da8c9a1283b0534cc2ca6760648..f8de63cf6d49c0d13528483f1f31fd28a58cc5a0 100644 (file)
@@ -3446,6 +3446,11 @@ parameter.  See there for details.
 .PP
 This feature is available in Postfix 2.6 and later, when Postfix is
 compiled and linked with OpenSSL 1.0.0 or later.
+.SH lmtp_tls_enable_rpk (default: yes)
+The LMTP\-specific version of the smtp_tls_enable_rpk
+configuration parameter.  See there for details.
+.PP
+This feature is available in Postfix 3.9 and later.
 .SH lmtp_tls_enforce_peername (default: yes)
 The LMTP\-specific version of the smtp_tls_enforce_peername
 configuration parameter.  See there for details.
@@ -8579,6 +8584,75 @@ to anyone else.
 .PP
 This feature is available in Postfix 2.6 and later, when Postfix is
 compiled and linked with OpenSSL 1.0.0 or later.
+.SH smtp_tls_enable_rpk (default: no)
+Request that remote SMTP servers send an RFC7250 raw public key
+instead of an X.509 certificate. This feature and the enable_rpk
+policy attribute are ignored when there is no raw public key support
+in the local TLS implementation.
+.IP \(bu
+At the "may", "encrypt" and "fingerprint" security levels,
+with parameter setting "smtp_tls_enable_rpk = yes" or with "enable_rpk
+= yes" in a policy entry, the Postfix SMTP client will indicate in
+the TLS handshake that it prefers to receive a raw server public
+key, but it will still accept a server public key certificate.
+.IP \(bu
+At the "fingerprint" security level, with parameter setting
+"smtp_tls_enable_rpk = yes" or with "enable_rpk = yes" in a policy entry,
+server authentication based on certificate fingerprints becomes more
+fragile.  Even if the server private key and certificate remain
+unchanged, the remote SMTP server will fail fingerprint authentication
+(won't match the configured list of fingerprints) when it starts sending
+a raw public key instead of a certificate, after its TLS implementation
+is updated with raw public key support.  Therefore, \fBDO NOT\fR
+enable raw public keys to remote destinations authenticated by server
+\fBcertificate\fR fingerprints.  You should enable raw public keys
+only for servers matched via their public key fingerprint.
+.IP \(bu
+At the "dane" security level, the Postfix SMTP client
+always ignores the parameter setting smtp_tls_enable_rpk or the
+enable_rpk policy attribute. When all valid TLSA records specify
+only server public keys (no certificates) and the local TLS
+implementation supports raw public keys, the client will indicate
+in the TLS handshake that it prefers to receive a raw public key,
+but it will still accept a public key certificate.
+.br
+.PP
+The Postfix SMTP client is always willing to send raw public keys
+to servers that solicit them when a client certificate is configured
+and the local TLS implementation supports raw public keys.
+.PP
+Sample commands to compute certificate and public key SHA256 digests:
+.PP
+.nf
+.na
+.ft C
+# SHA256 digest of the first certificate in "cert.pem"
+$ openssl x509 \-in cert.pem \-outform DER | openssl dgst \-sha256 \-c
+.fi
+.ad
+.ft R
+.PP
+.nf
+.na
+.ft C
+# SHA256 digest of the SPKI of the first certificate in "cert.pem"
+$ openssl x509 \-in cert.pem \-pubkey \-noout |
+    openssl pkey \-pubin \-outform DER | openssl dgst \-sha256 \-c
+.fi
+.ad
+.ft R
+.PP
+.nf
+.na
+.ft C
+# SHA256 digest of the SPKI of the first private key in "pkey.pem"
+$ openssl pkey \-in pkey.pem \-pubout \-outform DER |
+    openssl dgst \-sha256 \-c
+.fi
+.ad
+.ft R
+.PP
+This feature is available in Postfix 3.9 and later.
 .SH smtp_tls_enforce_peername (default: yes)
 With mandatory TLS encryption, require that the remote SMTP
 server hostname matches the information in the remote SMTP server
@@ -9156,28 +9230,35 @@ No TLS. No additional attributes are supported at this level.
 Opportunistic TLS. Since sending in the clear is acceptable,
 demanding stronger than default TLS security merely reduces
 interoperability. The optional "ciphers", "exclude", and "protocols"
-attributes (available for opportunistic TLS with Postfix >= 2.6)
-and "connection_reuse" attribute (Postfix >= 3.4) override the
+attributes (available for opportunistic TLS with Postfix >= 2.6) and
+"connection_reuse" attribute (Postfix >= 3.4) override the
 "smtp_tls_ciphers", "smtp_tls_exclude_ciphers", "smtp_tls_protocols",
-and
-"smtp_tls_connection_reuse" configuration parameters. In the policy table,
-multiple ciphers, protocols or excluded ciphers must be separated by colons,
-as attribute values may not contain whitespace or commas. When opportunistic
-TLS handshakes fail, Postfix retries the connection with TLS disabled.
-This allows mail delivery to sites with non\-interoperable TLS
-implementations.
+and "smtp_tls_connection_reuse" configuration parameters. In the policy
+table, multiple ciphers, protocols or excluded ciphers must be separated
+by colons, as attribute values may not contain whitespace or commas.  At
+this level and higher, the optional "servername" attribute (available
+with Postfix >= 3.4) overrides the global "smtp_tls_servername"
+parameter, enabling per\-destination configuration of the SNI extension
+sent to the remote SMTP server.  The optional "enable_rpk" attribute
+(Postfix >= 3.9) overrides the main.cf smtp_tls_enable_rpk parameter.
+When opportunistic TLS handshakes fail, Postfix retries the connection
+with TLS disabled.  This allows mail delivery to sites with
+non\-interoperable TLS implementations.
 .br
 .IP "\fBencrypt\fR"
-Mandatory TLS encryption. At this level
-and higher, the optional "protocols" attribute overrides the main.cf
+Mandatory TLS encryption. Mail is delivered only if the remote SMTP
+server offers STARTTLS and the TLS handshake succeeds. At this level and
+higher, the optional "protocols" attribute overrides the main.cf
 smtp_tls_mandatory_protocols parameter, the optional "ciphers" attribute
-overrides the main.cf smtp_tls_mandatory_ciphers parameter, the
-optional "exclude" attribute (Postfix >= 2.6) overrides the main.cf
+overrides the main.cf smtp_tls_mandatory_ciphers parameter, the optional
+"exclude" attribute (Postfix >= 2.6) overrides the main.cf
 smtp_tls_mandatory_exclude_ciphers parameter, and the optional
-"connection_reuse" attribute (Postfix >= 3.4) overrides the
-main.cf smtp_tls_connection_reuse parameter. In the policy table,
-multiple ciphers, protocols or excluded ciphers must be separated by colons,
-as attribute values may not contain whitespace or commas.
+"connection_reuse" attribute (Postfix >= 3.4) overrides the main.cf
+smtp_tls_connection_reuse parameter. In the policy table, multiple
+ciphers, protocols or excluded ciphers must be separated by colons, as
+attribute values may not contain whitespace or commas.  The optional
+"enable_rpk" attribute (Postfix >= 3.9) overrides the main.cf
+smtp_tls_enable_rpk parameter.
 .br
 .IP "\fBdane\fR"
 Opportunistic DANE TLS.  The TLS policy for the destination is
@@ -9216,10 +9297,10 @@ Certificate fingerprint
 verification. Available with Postfix 2.5 and later. At this security
 level, there are no trusted Certification Authorities. The certificate
 trust chain, expiration date, ... are not checked. Instead,
-the optional "match" attribute, or else the main.cf
+the optional policy table "match" attribute, or else the main.cf
 \fBsmtp_tls_fingerprint_cert_match\fR parameter, lists the certificate
-fingerprints or the public key fingerprint (Postfix 2.9 and later)
-of the valid server certificate. The digest
+fingerprints or the public key fingerprints (Postfix 2.9 and later)
+of acceptable server certificates. The digest
 algorithm used to calculate the fingerprint is selected by the
 \fBsmtp_tls_fingerprint_digest\fR parameter. Multiple fingerprints can
 be combined with a "|" delimiter in a single match attribute, or multiple
@@ -9230,45 +9311,58 @@ digits. The optional "ciphers", "exclude", and "protocols" attributes
 "smtp_tls_mandatory_exclude_ciphers", and "smtp_tls_mandatory_protocols"
 configuration parameters. The optional "connection_reuse" attribute
 (Postfix >= 3.4) overrides the main.cf smtp_tls_connection_reuse
-parameter.
+parameter.  The optional "enable_rpk" attribute (Postfix >= 3.9)
+overrides the main.cf smtp_tls_enable_rpk parameter.
 .br
 .IP "\fBverify\fR"
-Mandatory TLS verification.  At this security
-level, DNS MX lookups are trusted to be secure enough, and the name
-verified in the server certificate is usually obtained indirectly via
-unauthenticated DNS MX lookups.  The optional "match" attribute overrides
-the main.cf smtp_tls_verify_cert_match parameter. In the policy table,
-multiple match patterns and strategies must be separated by colons.
-In practice explicit control over matching is more common with the
-"secure" policy, described below. The optional "ciphers", "exclude",
-and "protocols" attributes (Postfix >= 2.6) override the
-"smtp_tls_mandatory_ciphers", "smtp_tls_mandatory_exclude_ciphers", and
-"smtp_tls_mandatory_protocols" configuration parameters. The optional
-"connection_reuse" attribute (Postfix >= 3.4) overrides the main.cf
-smtp_tls_connection_reuse parameter.
+Mandatory TLS verification.  Mail is delivered only if the TLS
+handshake succeeds, the remote SMTP server certificate chain can be
+validated, and a DNS name in the certificate matches the specified match
+criteria. At this security level, DNS MX lookups are presumed to be
+secure enough, and the name verified in the server certificate is
+potentially obtained via unauthenticated DNS MX lookups.  The optional
+"match" attribute overrides the main.cf smtp_tls_verify_cert_match
+parameter. In the policy table, multiple match patterns and strategies
+must be separated by colons.  In practice explicit control over matching
+is more common with the "secure" policy, described below. The optional
+"ciphers", "exclude", and "protocols" attributes (Postfix >= 2.6)
+override the "smtp_tls_mandatory_ciphers",
+"smtp_tls_mandatory_exclude_ciphers", and "smtp_tls_mandatory_protocols"
+configuration parameters. With Postfix >= 2.11 the optional "tafile"
+policy table attribute modifies trust chain verification in the same
+manner as the "smtp_tls_trust_anchor_file" parameter. The "tafile"
+attribute may be specified multiple times to load multiple trust\-anchor
+files. The optional "connection_reuse" attribute (Postfix >= 3.4)
+overrides the main.cf smtp_tls_connection_reuse parameter.
 .br
 .IP "\fBsecure\fR"
-Secure\-channel TLS. At this security level, DNS
-MX lookups, though potentially used to determine the candidate next\-hop
-gateway IP addresses, are \fBnot\fR trusted to be secure enough for TLS
-peername verification. Instead, the default name verified in the server
-certificate is obtained directly from the next\-hop, or is explicitly
-specified via the optional "match" attribute which overrides the
-main.cf smtp_tls_secure_cert_match parameter. In the policy table,
-multiple match patterns and strategies must be separated by colons.
-The match attribute is most useful when multiple domains are supported by
-a common server: the policy entries for additional domains specify matching
-rules for the primary domain certificate. While transport table overrides
-that route the secondary domains to the primary nexthop also allow secure
-verification, they risk delivery to the wrong destination when domains
-change hands or are re\-assigned to new gateways. With the "match"
-attribute approach, routing is not perturbed, and mail is deferred if
-verification of a new MX host fails. The optional "ciphers", "exclude",
-and "protocols" attributes (Postfix >= 2.6) override the
-"smtp_tls_mandatory_ciphers", "smtp_tls_mandatory_exclude_ciphers", and
-"smtp_tls_mandatory_protocols" configuration parameters. The optional
-"connection_reuse" attribute (Postfix >= 3.4) overrides the main.cf
-smtp_tls_connection_reuse parameter.
+Secure certificate verification. Mail is delivered only if the TLS
+handshake succeeds, the remote SMTP server certificate chain can be
+validated, and a DNS name in the certificate matches the specified match
+criteria.  At this security level, DNS MX lookups, though potentially
+used to determine the candidate next\-hop gateway IP addresses, are
+\fBnot\fR presumed to be secure enough for TLS peername verification.
+Instead, the default name verified in the server certificate is obtained
+directly from the next\-hop, or is explicitly specified via the optional
+"match" attribute which overrides the main.cf smtp_tls_secure_cert_match
+parameter. In the policy table, multiple match patterns and strategies
+must be separated by colons.  The match attribute is most useful when
+multiple domains are supported by a common server: the policy entries
+for additional domains specify matching rules for the primary domain
+certificate. While transport table overrides that route the secondary
+domains to the primary nexthop also allow secure verification, they risk
+delivery to the wrong destination when domains change hands or are
+re\-assigned to new gateways. With the "match" attribute approach,
+routing is not perturbed, and mail is deferred if verification of a new
+MX host fails. The optional "ciphers", "exclude", and "protocols"
+attributes (Postfix >= 2.6) override the "smtp_tls_mandatory_ciphers",
+"smtp_tls_mandatory_exclude_ciphers", and "smtp_tls_mandatory_protocols"
+configuration parameters. With Postfix >= 2.11 the "tafile" attribute
+optionally modifies trust chain verification in the same manner as the
+"smtp_tls_trust_anchor_file" parameter.  The "tafile" attribute may be
+specified multiple times to load multiple trust\-anchor files. The
+optional "connection_reuse" attribute (Postfix >= 3.4) overrides the
+main.cf smtp_tls_connection_reuse parameter.
 .br
 .br
 .PP
@@ -12826,6 +12920,59 @@ Postfix uses ciphers with forward secrecy.
 This feature is available in Postfix 2.6 and later, when it is
 compiled and linked with OpenSSL 1.0.0 or later on platforms
 where EC algorithms have not been disabled by the vendor.
+.SH smtpd_tls_enable_rpk (default: no)
+Request that remote SMTP clients send an RFC7250 raw public key
+instead of an X.509 certificate, when asking for or requiring client
+authentication. This feature is ignored when there is no raw public
+key support in the local TLS implementation.
+.PP
+The Postfix SMTP server will log a warning when "smtpd_tls_enable_rpk
+= yes", but the remote SMTP client sends a certificate, the
+certificate's public key fingerprint does not match a check_ccert_access
+table, while the certificate fingerprint does match a check_ccert_access
+table. The remote SMTP client would lose access when it starts
+sending a raw public key instead of a certificate, after its TLS
+implementation is updated with raw public key support.
+.PP
+The Postfix SMTP server always sends a raw public key instead
+of a certificate, if solicited by the remote SMTP client and the
+local TLS implementation supports raw public keys. If the client
+sends a server name indication with an SNI TLS extension, and
+tls_server_sni_maps is configured, the server will extract a raw
+public key from the indicated certificate.
+.PP
+Sample commands to compute certificate and public key SHA256 digests:
+.PP
+.nf
+.na
+.ft C
+# SHA256 digest of the first certificate in "cert.pem"
+$ openssl x509 \-in cert.pem \-outform DER | openssl dgst \-sha256 \-c
+.fi
+.ad
+.ft R
+.PP
+.nf
+.na
+.ft C
+# SHA256 digest of the SPKI of the first certificate in "cert.pem"
+$ openssl x509 \-in cert.pem \-pubkey \-noout |
+    openssl pkey \-pubin \-outform DER | openssl dgst \-sha256 \-c
+.fi
+.ad
+.ft R
+.PP
+.nf
+.na
+.ft C
+# SHA256 digest of the SPKI of the first private key in "pkey.pem"
+$ openssl pkey \-in pkey.pem \-pubout \-outform DER |
+    openssl dgst \-sha256 \-c
+.fi
+.ad
+.ft R
+.PP
+This feature is available in Postfix 3.9 and later.
 .SH smtpd_tls_exclude_ciphers (default: empty)
 List of ciphers or cipher types to exclude from the SMTP server
 cipher list at all TLS security levels. Excluding valid ciphers
@@ -14643,6 +14790,12 @@ elliptic\-curve Diffie\-Hellman (EECDH) key exchange. See
 smtpd_tls_eecdh_grade for further details.
 .PP
 This feature is available in Postfix 2.8 and later.
+.SH tlsproxy_tls_enable_rpk (default: $smtpd_tls_enable_rpk)
+Request that remote SMTP clients send an RFC7250 raw public key
+instead of an X.509 certificate, when asking or requiring client
+authentication. See $smtpd_tls_enable_rpk for details.
+.PP
+This feature is available in Postfix 3.9 and later.
 .SH tlsproxy_tls_exclude_ciphers (default: $smtpd_tls_exclude_ciphers)
 List of ciphers or cipher types to exclude from the \fBtlsproxy\fR(8)
 server cipher list at all TLS security levels. See
index a4509d8e372e0434ac34b3dd3f8049392c88198b..8d1994d43f469b34d4bcf2b865fe00d6c875ba68 100644 (file)
@@ -647,6 +647,11 @@ Optional configuration file with baseline OpenSSL settings.
 .IP "\fBtls_config_name (empty)\fR"
 The application name passed by Postfix to OpenSSL library
 initialization functions.
+.PP
+Available in Postfix version 3.9 and later:
+.IP "\fBsmtp_tls_enable_rpk (no)\fR"
+Request that remote SMTP servers send an RFC7250 raw public key
+instead of an X.509 certificate.
 .SH "OBSOLETE STARTTLS CONTROLS"
 .na
 .nf
index 06d9be3c58016175f778988a8e2e76f77cac3191..2ccdba99dd84fac890451b34c6037fdf72ee7405 100644 (file)
@@ -571,6 +571,12 @@ Optional configuration file with baseline OpenSSL settings.
 .IP "\fBtls_config_name (empty)\fR"
 The application name passed by Postfix to OpenSSL library
 initialization functions.
+.PP
+Available in Postfix version 3.9 and later:
+.IP "\fBsmtpd_tls_enable_rpk (no)\fR"
+Request that remote SMTP clients send an RFC7250 raw public key
+instead of an X.509 certificate, when asking for or requiring client
+authentication.
 .SH "OBSOLETE STARTTLS CONTROLS"
 .na
 .nf
index 6913b7bbfdfbe9fce6d920d0f7286b4612d05e36..4677dc4f15a9237becea514e8030c28a8c88b497 100644 (file)
@@ -255,6 +255,12 @@ parameters smtpd_use_tls and smtpd_enforce_tls.
 .IP "\fBtlsproxy_tls_chain_files ($smtpd_tls_chain_files)\fR"
 Files with the Postfix \fBtlsproxy\fR(8) server keys and certificate
 chains in PEM format.
+.PP
+Available in Postfix version 3.9 and later:
+.IP "\fBtlsproxy_tls_enable_rpk ($smtpd_tls_enable_rpk)\fR"
+Request that remote SMTP clients send an RFC7250 raw public key
+instead of an X.509 certificate, when asking or requiring client
+authentication.
 .SH "STARTTLS CLIENT CONTROLS"
 .na
 .nf
index ca75c31f42cfa9d1c7e091d9df8420d74b0e4f80..279fea69d05ec9d92a7f873362e0a91204b2d20e 100755 (executable)
@@ -273,6 +273,7 @@ while (<>) {
     s;\blmtp_tls_loglevel\b;<a href="postconf.5.html#lmtp_tls_loglevel">$&</a>;g;
     s;\blmtp_tls_session_cache_database\b;<a href="postconf.5.html#lmtp_tls_session_cache_database">$&</a>;g;
     s;\blmtp_tls_session_cache_timeout\b;<a href="postconf.5.html#lmtp_tls_session_cache_timeout">$&</a>;g;
+    s;\blmtp_tls_enable_rpk\b;<a href="postconf.5.html#lmtp_tls_enable_rpk">$&</a>;g;
     s;\blmtp_tls_wrappermode\b;<a href="postconf.5.html#lmtp_tls_wrappermode">$&</a>;g;
     s;\blmtp_generic_maps\b;<a href="postconf.5.html#lmtp_generic_maps">$&</a>;g;
     s;\blmtp_pix_workaround_threshold_time\b;<a href="postconf.5.html#lmtp_pix_workaround_threshold_time">$&</a>;g;
@@ -695,6 +696,7 @@ while (<>) {
     s;\bsmtp_tls_block_early_mail_reply\b;<a href="postconf.5.html#smtp_tls_block_early_mail_reply">$&</a>;g;
     s;\bsmtp_tls_dane_insecure_mx_policy\b;<a href="postconf.5.html#smtp_tls_dane_insecure_mx_policy">$&</a>;g;
     s;\bsmtp_tls_force_insecure_host_tlsa_lookup\b;<a href="postconf.5.html#smtp_tls_force_insecure_host_tlsa_lookup">$&</a>;g;
+    s;\bsmtp_tls_enable_rpk\b;<a href="postconf.5.html#smtp_tls_enable_rpk">$&</a>;g;
     s;\bsmtp_tls_wrappermode\b;<a href="postconf.5.html#smtp_tls_wrappermode">$&</a>;g;
     s;\bsmtp_use_tls\b;<a href="postconf.5.html#smtp_use_tls">$&</a>;g;
     s;\bsmtp_header_checks\b;<a href="postconf.5.html#smtp_header_checks">$&</a>;g;
@@ -748,6 +750,7 @@ while (<>) {
     s;\bsmtpd_tls_ses[-</bB>]*\n*[ <bB>]*sion_cache_database\b;<a href="postconf.5.html#smtpd_tls_session_cache_database">$&</a>;g;
     s;\bsmtpd_tls_ses[-</bB>]*\n*[ <bB>]*sion_cache_timeout\b;<a href="postconf.5.html#smtpd_tls_session_cache_timeout">$&</a>;g;
     s;\bsmtpd_tls_always_issue_ses[-</bB>]*\n*[ <bB>]*sion_ids\b;<a href="postconf.5.html#smtpd_tls_always_issue_session_ids">$&</a>;g;
+    s;\bsmtpd_tls_enable_rpk\b;<a href="postconf.5.html#smtpd_tls_enable_rpk">$&</a>;g;
     s;\bsmtpd_tls_wrappermode\b;<a href="postconf.5.html#smtpd_tls_wrappermode">$&</a>;g;
     s;\bsmtpd_use_tls\b;<a href="postconf.5.html#smtpd_use_tls">$&</a>;g;
     s;\bsmtpd_reject_footer\b;<a href="postconf.5.html#smtpd_reject_footer">$&</a>;g;
@@ -1120,6 +1123,7 @@ while (<>) {
     s;\btlsproxy_tls_protocols\b;<a href="postconf.5.html#tlsproxy_tls_protocols">$&</a>;g;
     s;\btlsproxy_tls_req_ccert\b;<a href="postconf.5.html#tlsproxy_tls_req_ccert">$&</a>;g;
     s;\btlsproxy_tls_security_level\b;<a href="postconf.5.html#tlsproxy_tls_security_level">$&</a>;g;
+    s;\btlsproxy_tls_enable_rpk\b;<a href="postconf.5.html#tlsproxy_tls_enable_rpk">$&</a>;g;
     s;\btlsproxy_use_tls\b;<a href="postconf.5.html#tlsproxy_use_tls">$&</a>;g;
 
     s;\btlsproxy_client_CAfile\b;<a href="postconf.5.html#tlsproxy_client_CAfile">$&</a>;g;
index a3905662a318dbcc69d24e3a4d280973786dc744..d6fe51b52225ba43698b613614122f0057871ac8 100644 (file)
@@ -2266,82 +2266,124 @@ describe the corresponding table syntax: </p>
 additional attributes are supported at this level. </dd>
 
 <dt><b>may</b></dt> <dd><a href="#client_tls_may">Opportunistic TLS</a>.
-The optional "ciphers", "exclude" and "protocols" attributes
-(available for opportunistic TLS with Postfix &ge; 2.6) override the
-"smtp_tls_ciphers", "smtp_tls_exclude_ciphers" and "smtp_tls_protocols"
-configuration parameters.  At this level and higher, the optional
-"servername" attribute (available with Postfix &ge; 3.4) overrides the
-global "smtp_tls_servername" parameter, enabling per-destination
-configuration of the SNI extension sent to the remote SMTP server. </dd>
+The optional "ciphers", "exclude", and "protocols" attributes (available
+for opportunistic TLS with Postfix &ge; 2.6) and "connection_reuse"
+attribute (Postfix &ge; 3.4) override the "smtp_tls_ciphers",
+"smtp_tls_exclude_ciphers", "smtp_tls_protocols", and
+"smtp_tls_connection_reuse" configuration parameters.  At this level and
+higher, the optional "servername" attribute (available with Postfix &ge;
+3.4) overrides the global "smtp_tls_servername" parameter, enabling
+per-destination configuration of the SNI extension sent to the remote
+SMTP server.  The optional "enable_rpk" attribute (Postfix &ge; 3.9)
+overrides the main.cf smtp_tls_enable_rpk parameter.  When opportunistic
+TLS handshakes fail, Postfix retries the connection with TLS disabled.
+This allows mail delivery to sites with non-interoperable TLS
+implementations.</dd>
 
 <dt><b>encrypt</b></dt> <dd><a href="#client_tls_encrypt"> Mandatory encryption</a>.
-Mail is delivered only if the remote SMTP server offers STARTTLS
-and the TLS handshake succeeds. At this level and higher, the optional
+Mail is delivered only if the remote SMTP server offers STARTTLS and the
+TLS handshake succeeds. At this level and higher, the optional
 "protocols" attribute overrides the main.cf smtp_tls_mandatory_protocols
-parameter, the optional "ciphers" attribute overrides the
-main.cf smtp_tls_mandatory_ciphers parameter, and the optional
-"exclude" attribute (Postfix &ge; 2.6) overrides the main.cf
-smtp_tls_mandatory_exclude_ciphers parameter.  </dd>
+parameter, the optional "ciphers" attribute overrides the main.cf
+smtp_tls_mandatory_ciphers parameter, the optional "exclude" attribute
+(Postfix &ge; 2.6) overrides the main.cf
+smtp_tls_mandatory_exclude_ciphers parameter, and the optional
+"connection_reuse" attribute (Postfix &ge; 3.4) overrides the main.cf
+smtp_tls_connection_reuse parameter. The optional "enable_rpk" attribute
+(Postfix &ge; 3.9) overrides the main.cf smtp_tls_enable_rpk parameter.
+</dd>
 
 <dt><b>dane</b></dt> <dd><a href="#client_tls_dane">Opportunistic DANE TLS</a>.
 The TLS policy for the destination is obtained via TLSA records in
-DNSSEC.  If no TLSA records are found, the effective security level
-used is <a href="#client_tls_may">may</a>.  If TLSA records are
-found, but none are usable, the effective security level is <a
-href="#client_tls_encrypt">encrypt</a>.  When usable TLSA records
-are obtained for the remote SMTP server, SSLv2+3 are automatically
-disabled (see smtp_tls_mandatory_protocols), and the server certificate
-must match the TLSA records.  RFC 7672 (DANE) TLS authentication
-and DNSSEC support is available with Postfix 2.11 and later.  </dd>
+DNSSEC.  If no TLSA records are found, the effective security level used
+is <a href="#client_tls_may">may</a>.  If TLSA records are found, but
+none are usable, the effective security level is <a
+href="#client_tls_encrypt">encrypt</a>.  When usable TLSA records are
+obtained for the remote SMTP server, the server certificate must match
+the TLSA records (and the SNI name is unconditionally set to the TLSA
+<i>base domain</i>).  RFC 7672 (DANE) TLS authentication and DNSSEC
+support is available with Postfix 2.11 and later. The optional
+"connection_reuse" attribute (Postfix &ge; 3.4) overrides the main.cf
+smtp_tls_connection_reuse parameter.  When the effective security level
+used is <a href="#client_tls_may">may</a>, the optional "ciphers",
+"exclude", and "protocols" attributes (Postfix &ge; 2.6) override the
+"smtp_tls_ciphers", "smtp_tls_exclude_ciphers", and "smtp_tls_protocols"
+configuration parameters.  When the effective security level used is <a
+href="#client_tls_encrypt">encrypt</a>, the optional "ciphers",
+"exclude", and "protocols" attributes (Postfix &ge; 2.6) override the
+"smtp_tls_mandatory_ciphers", "smtp_tls_mandatory_exclude_ciphers", and
+"smtp_tls_mandatory_protocols" configuration parameters.  </dd>
 
 <dt><b>dane-only</b></dt> <dd><a href="#client_tls_dane">Mandatory DANE TLS</a>.
 The TLS policy for the destination is obtained via TLSA records in
-DNSSEC.  If no TLSA records are found, or none are usable, no
-connection is made to the server.  When usable TLSA records are
-obtained for the remote SMTP server, SSLv2+3 are automatically disabled
-(see smtp_tls_mandatory_protocols), and the server certificate must
-match the TLSA records.  RFC 7672 (DANE) TLS authentication and
-DNSSEC support is available with Postfix 2.11 and later.  </dd>
+DNSSEC.  If no TLSA records are found, or none are usable, no connection
+is made to the server.  When usable TLSA records are obtained for the
+remote SMTP server, the server certificate must match the TLSA records.
+RFC 7672 (DANE) TLS authentication and DNSSEC support is available with
+Postfix 2.11 and later. The optional "ciphers", "exclude", and
+"protocols" attributes (Postfix &ge; 2.6) override the
+"smtp_tls_mandatory_ciphers", "smtp_tls_mandatory_exclude_ciphers", and
+"smtp_tls_mandatory_protocols" configuration parameters. The optional
+"connection_reuse" attribute (Postfix &ge; 3.4) overrides the main.cf
+smtp_tls_connection_reuse parameter.  </dd>
 
 <dt><b>fingerprint</b></dt> <dd><a href="#client_tls_fprint">Certificate
-fingerprint verification.</a> Available with Postfix 2.5 and
-later. At this security level, there are no trusted Certification
-Authorities. The certificate trust chain, expiration date, ... are
-not checked. Instead, the optional <b>match</b> attribute, or else
-the main.cf <b>smtp_tls_fingerprint_cert_match</b> parameter, lists
-the server certificate fingerprints or public key fingerprints
-(Postfix 2.9 and later).  The
-digest algorithm used to calculate fingerprints is selected by the
-<b>smtp_tls_fingerprint_digest</b> parameter. Multiple fingerprints can
-be combined with a "|" delimiter in a single match attribute, or multiple
-match attributes can be employed. The ":" character is not used as a
-delimiter as it occurs between each pair of fingerprint (hexadecimal)
-digits. </dd>
+fingerprint verification.</a> Available with Postfix 2.5 and later. At
+this security level, there are no trusted Certification Authorities. The
+certificate trust chain, expiration date, ... are not checked. Instead,
+the optional "match" attribute, or else the main.cf
+<b>smtp_tls_fingerprint_cert_match</b> parameter, lists the certificate
+fingerprints or the public key fingerprints (Postfix 2.9 and later) of
+acceptable server certificates. The digest algorithm used to calculate
+the fingerprint is selected by the <b>smtp_tls_fingerprint_digest</b>
+parameter. Multiple fingerprints can be combined with a "|" delimiter in
+a single match attribute, or multiple match attributes can be employed.
+The ":" character is not used as a delimiter as it occurs between each
+pair of fingerprint (hexadecimal) digits. The optional "ciphers",
+"exclude", and "protocols" attributes (Postfix &ge; 2.6) override the
+"smtp_tls_mandatory_ciphers", "smtp_tls_mandatory_exclude_ciphers", and
+"smtp_tls_mandatory_protocols" configuration parameters. The optional
+"connection_reuse" attribute (Postfix &ge; 3.4) overrides the main.cf
+smtp_tls_connection_reuse parameter.  The optional "enable_rpk"
+attribute (Postfix &ge; 3.9) overrides the main.cf smtp_tls_enable_rpk
+parameter. </dd>
 
 <dt><b>verify</b></dt> <dd><a href="#client_tls_verify">Mandatory
-server certificate verification</a>.  Mail is delivered only if the
-TLS handshake succeeds, if the remote SMTP server certificate can
-be validated (not expired or revoked, and signed by a trusted
-Certification Authority), and if the server certificate name matches
-the optional "match" attribute (or the main.cf smtp_tls_verify_cert_match
-parameter value when no optional "match" attribute is specified).
-With Postfix &ge; 2.11 the "tafile" attribute optionally modifies
-trust chain verification in the same manner as the
-"smtp_tls_trust_anchor_file" parameter.  The "tafile" attribute
-may be specified multiple times to load multiple trust-anchor
-files.  </dd>
+server certificate verification</a>.  Mail is delivered only if the TLS
+handshake succeeds, the remote SMTP server certificate chain can be
+validated, and a DNS name in the certificate matches the specified match
+criteria. At this security level, DNS MX lookups are presumed to be
+secure enough, and the name verified in the server certificate is
+potentially obtained via unauthenticated DNS MX lookups.  The server
+certificate name must match either the optional "match" attribute, or
+else the main.cf smtp_tls_verify_cert_match parameter value.  With
+Postfix &ge; 2.11 the "tafile" attribute optionally modifies trust chain
+verification in the same manner as the "smtp_tls_trust_anchor_file"
+parameter.  The "tafile" attribute may be specified multiple times to
+load multiple trust-anchor files. The optional "connection_reuse"
+attribute (Postfix &ge; 3.4) overrides the main.cf
+smtp_tls_connection_reuse parameter.  </dd>
 
 <dt><b>secure</b></dt> <dd><a href="#client_tls_secure">Secure certificate
-verification.</a> Mail is delivered only if the TLS handshake succeeds,
-and DNS forgery resistant remote SMTP certificate verification succeeds
-(not expired or revoked, and signed by a trusted Certification Authority),
-and if the server certificate name matches the optional "match" attribute
-(or the main.cf smtp_tls_secure_cert_match parameter value when no optional
-"match" attribute is specified).  With Postfix &ge; 2.11 the "tafile"
-attribute optionally modifies trust chain verification in the same manner
-as the "smtp_tls_trust_anchor_file" parameter.  The "tafile" attribute
-may be specified multiple times to load multiple trust-anchor
-files.  </dd>
+verification.</a>
+Mail is delivered only if the TLS handshake succeeds, the remote SMTP
+server certificate chain can be validated, and a DNS name in the
+certificate matches the specified match criteria.  At this security
+level, DNS MX lookups, though potentially used to determine the
+candidate next-hop gateway IP addresses, are <b>not</b> presumed to be
+secure enough for TLS peername verification.  Instead, the default name
+verified in the server certificate is obtained directly from the
+next-hop, or is explicitly specified via the optional "match" attribute
+which overrides the main.cf smtp_tls_secure_cert_match parameter.  The
+optional "ciphers", "exclude", and "protocols" attributes (Postfix &ge;
+2.6) override the "smtp_tls_mandatory_ciphers",
+"smtp_tls_mandatory_exclude_ciphers", and "smtp_tls_mandatory_protocols"
+configuration parameters.  With Postfix &ge; 2.11 the "tafile" attribute
+optionally modifies trust chain verification in the same manner as the
+"smtp_tls_trust_anchor_file" parameter.  The "tafile" attribute may be
+specified multiple times to load multiple trust-anchor files. The
+optional "connection_reuse" attribute (Postfix &ge; 3.4) overrides the
+main.cf smtp_tls_connection_reuse parameter.  </dd>
 
 </dl>
 
index 348ca68316e50cb118f3624ecf2a34afc845b00a..1b60a97652b3a24b3df9cde302b7e24a8cab91e2 100644 (file)
@@ -11448,28 +11448,35 @@ security are: </p>
 <dd>Opportunistic TLS. Since sending in the clear is acceptable,
 demanding stronger than default TLS security merely reduces
 interoperability. The optional "ciphers", "exclude", and "protocols"
-attributes (available for opportunistic TLS with Postfix &ge; 2.6)
-and "connection_reuse" attribute (Postfix &ge; 3.4) override the
+attributes (available for opportunistic TLS with Postfix &ge; 2.6) and
+"connection_reuse" attribute (Postfix &ge; 3.4) override the
 "smtp_tls_ciphers", "smtp_tls_exclude_ciphers", "smtp_tls_protocols",
-and
-"smtp_tls_connection_reuse" configuration parameters. In the policy table,
-multiple ciphers, protocols or excluded ciphers must be separated by colons,
-as attribute values may not contain whitespace or commas. When opportunistic
-TLS handshakes fail, Postfix retries the connection with TLS disabled.
-This allows mail delivery to sites with non-interoperable TLS
-implementations.</dd>
+and "smtp_tls_connection_reuse" configuration parameters. In the policy
+table, multiple ciphers, protocols or excluded ciphers must be separated
+by colons, as attribute values may not contain whitespace or commas.  At
+this level and higher, the optional "servername" attribute (available
+with Postfix &ge; 3.4) overrides the global "smtp_tls_servername"
+parameter, enabling per-destination configuration of the SNI extension
+sent to the remote SMTP server.  The optional "enable_rpk" attribute
+(Postfix &ge; 3.9) overrides the main.cf smtp_tls_enable_rpk parameter.
+When opportunistic TLS handshakes fail, Postfix retries the connection
+with TLS disabled.  This allows mail delivery to sites with
+non-interoperable TLS implementations.</dd>
 
 <dt><b><a href="TLS_README.html#client_tls_encrypt">encrypt</a></b></dt>
-<dd>Mandatory TLS encryption. At this level
-and higher, the optional "protocols" attribute overrides the main.cf
+<dd>Mandatory TLS encryption. Mail is delivered only if the remote SMTP
+server offers STARTTLS and the TLS handshake succeeds. At this level and
+higher, the optional "protocols" attribute overrides the main.cf
 smtp_tls_mandatory_protocols parameter, the optional "ciphers" attribute
-overrides the main.cf smtp_tls_mandatory_ciphers parameter, the
-optional "exclude" attribute (Postfix &ge; 2.6) overrides the main.cf
+overrides the main.cf smtp_tls_mandatory_ciphers parameter, the optional
+"exclude" attribute (Postfix &ge; 2.6) overrides the main.cf
 smtp_tls_mandatory_exclude_ciphers parameter, and the optional
-"connection_reuse" attribute (Postfix &ge; 3.4) overrides the
-main.cf smtp_tls_connection_reuse parameter. In the policy table,
-multiple ciphers, protocols or excluded ciphers must be separated by colons,
-as attribute values may not contain whitespace or commas. </dd>
+"connection_reuse" attribute (Postfix &ge; 3.4) overrides the main.cf
+smtp_tls_connection_reuse parameter. In the policy table, multiple
+ciphers, protocols or excluded ciphers must be separated by colons, as
+attribute values may not contain whitespace or commas.  The optional
+"enable_rpk" attribute (Postfix &ge; 3.9) overrides the main.cf
+smtp_tls_enable_rpk parameter. </dd>
 
 <dt><b><a href="TLS_README.html#client_tls_dane">dane</a></b></dt>
 <dd>Opportunistic DANE TLS.  The TLS policy for the destination is
@@ -11514,10 +11521,10 @@ configuration parameters. The optional "connection_reuse" attribute
 verification. Available with Postfix 2.5 and later. At this security
 level, there are no trusted Certification Authorities. The certificate
 trust chain, expiration date, ... are not checked. Instead,
-the optional "match" attribute, or else the main.cf
+the optional policy table "match" attribute, or else the main.cf
 <b>smtp_tls_fingerprint_cert_match</b> parameter, lists the certificate
-fingerprints or the public key fingerprint (Postfix 2.9 and later)
-of the valid server certificate. The digest
+fingerprints or the public key fingerprints (Postfix 2.9 and later)
+of acceptable server certificates. The digest
 algorithm used to calculate the fingerprint is selected by the
 <b>smtp_tls_fingerprint_digest</b> parameter. Multiple fingerprints can
 be combined with a "|" delimiter in a single match attribute, or multiple
@@ -11528,45 +11535,58 @@ digits. The optional "ciphers", "exclude", and "protocols" attributes
 "smtp_tls_mandatory_exclude_ciphers", and "smtp_tls_mandatory_protocols"
 configuration parameters. The optional "connection_reuse" attribute
 (Postfix &ge; 3.4) overrides the main.cf smtp_tls_connection_reuse
-parameter. </dd>
+parameter.  The optional "enable_rpk" attribute (Postfix &ge; 3.9)
+overrides the main.cf smtp_tls_enable_rpk parameter. </dd>
 
 <dt><b><a href="TLS_README.html#client_tls_verify">verify</a></b></dt>
-<dd>Mandatory TLS verification.  At this security
-level, DNS MX lookups are trusted to be secure enough, and the name
-verified in the server certificate is usually obtained indirectly via
-unauthenticated DNS MX lookups.  The optional "match" attribute overrides
-the main.cf smtp_tls_verify_cert_match parameter. In the policy table,
-multiple match patterns and strategies must be separated by colons.
-In practice explicit control over matching is more common with the
-"secure" policy, described below. The optional "ciphers", "exclude",
-and "protocols" attributes (Postfix &ge; 2.6) override the
-"smtp_tls_mandatory_ciphers", "smtp_tls_mandatory_exclude_ciphers", and
-"smtp_tls_mandatory_protocols" configuration parameters. The optional
-"connection_reuse" attribute (Postfix &ge; 3.4) overrides the main.cf
-smtp_tls_connection_reuse parameter. </dd>
+<dd>Mandatory TLS verification.  Mail is delivered only if the TLS
+handshake succeeds, the remote SMTP server certificate chain can be
+validated, and a DNS name in the certificate matches the specified match
+criteria. At this security level, DNS MX lookups are presumed to be
+secure enough, and the name verified in the server certificate is
+potentially obtained via unauthenticated DNS MX lookups.  The optional
+"match" attribute overrides the main.cf smtp_tls_verify_cert_match
+parameter. In the policy table, multiple match patterns and strategies
+must be separated by colons.  In practice explicit control over matching
+is more common with the "secure" policy, described below. The optional
+"ciphers", "exclude", and "protocols" attributes (Postfix &ge; 2.6)
+override the "smtp_tls_mandatory_ciphers",
+"smtp_tls_mandatory_exclude_ciphers", and "smtp_tls_mandatory_protocols"
+configuration parameters. With Postfix &ge; 2.11 the optional "tafile"
+policy table attribute modifies trust chain verification in the same
+manner as the "smtp_tls_trust_anchor_file" parameter. The "tafile"
+attribute may be specified multiple times to load multiple trust-anchor
+files. The optional "connection_reuse" attribute (Postfix &ge; 3.4)
+overrides the main.cf smtp_tls_connection_reuse parameter. </dd>
 
 <dt><b><a href="TLS_README.html#client_tls_secure">secure</a></b></dt>
-<dd>Secure-channel TLS. At this security level, DNS
-MX lookups, though potentially used to determine the candidate next-hop
-gateway IP addresses, are <b>not</b> trusted to be secure enough for TLS
-peername verification. Instead, the default name verified in the server
-certificate is obtained directly from the next-hop, or is explicitly
-specified via the optional "match" attribute which overrides the
-main.cf smtp_tls_secure_cert_match parameter. In the policy table,
-multiple match patterns and strategies must be separated by colons.
-The match attribute is most useful when multiple domains are supported by
-a common server: the policy entries for additional domains specify matching
-rules for the primary domain certificate. While transport table overrides
-that route the secondary domains to the primary nexthop also allow secure
-verification, they risk delivery to the wrong destination when domains
-change hands or are re-assigned to new gateways. With the "match"
-attribute approach, routing is not perturbed, and mail is deferred if
-verification of a new MX host fails. The optional "ciphers", "exclude",
-and "protocols" attributes (Postfix &ge; 2.6) override the
-"smtp_tls_mandatory_ciphers", "smtp_tls_mandatory_exclude_ciphers", and
-"smtp_tls_mandatory_protocols" configuration parameters. The optional
-"connection_reuse" attribute (Postfix &ge; 3.4) overrides the main.cf
-smtp_tls_connection_reuse parameter. </dd>
+<dd>Secure certificate verification. Mail is delivered only if the TLS
+handshake succeeds, the remote SMTP server certificate chain can be
+validated, and a DNS name in the certificate matches the specified match
+criteria.  At this security level, DNS MX lookups, though potentially
+used to determine the candidate next-hop gateway IP addresses, are
+<b>not</b> presumed to be secure enough for TLS peername verification.
+Instead, the default name verified in the server certificate is obtained
+directly from the next-hop, or is explicitly specified via the optional
+"match" attribute which overrides the main.cf smtp_tls_secure_cert_match
+parameter. In the policy table, multiple match patterns and strategies
+must be separated by colons.  The match attribute is most useful when
+multiple domains are supported by a common server: the policy entries
+for additional domains specify matching rules for the primary domain
+certificate. While transport table overrides that route the secondary
+domains to the primary nexthop also allow secure verification, they risk
+delivery to the wrong destination when domains change hands or are
+re-assigned to new gateways. With the "match" attribute approach,
+routing is not perturbed, and mail is deferred if verification of a new
+MX host fails. The optional "ciphers", "exclude", and "protocols"
+attributes (Postfix &ge; 2.6) override the "smtp_tls_mandatory_ciphers",
+"smtp_tls_mandatory_exclude_ciphers", and "smtp_tls_mandatory_protocols"
+configuration parameters. With Postfix &ge; 2.11 the "tafile" attribute
+optionally modifies trust chain verification in the same manner as the
+"smtp_tls_trust_anchor_file" parameter.  The "tafile" attribute may be
+specified multiple times to load multiple trust-anchor files. The
+optional "connection_reuse" attribute (Postfix &ge; 3.4) overrides the
+main.cf smtp_tls_connection_reuse parameter. </dd>
 
 </dl>
 
@@ -18624,6 +18644,126 @@ configuration parameter. See there for details. </p>
 
 <p> This feature is available in Postfix 3.7 and later. </p>
 
+%PARAM smtpd_tls_enable_rpk no
+
+<p> Request that remote SMTP clients send an RFC7250 raw public key
+instead of an X.509 certificate, when asking for or requiring client
+authentication. This feature is ignored when there is no raw public
+key support in the local TLS implementation. </p>
+
+<p> The Postfix SMTP server will log a warning when "smtpd_tls_enable_rpk
+= yes", but the remote SMTP client sends a certificate, the
+certificate's public key fingerprint does not match a check_ccert_access
+table, while the certificate fingerprint does match a check_ccert_access
+table. The remote SMTP client would lose access when it starts
+sending a raw public key instead of a certificate, after its TLS
+implementation is updated with raw public key support. </p>
+
+<p> The Postfix SMTP server always sends a raw public key instead
+of a certificate, if solicited by the remote SMTP client and the
+local TLS implementation supports raw public keys. If the client
+sends a server name indication with an SNI TLS extension, and
+tls_server_sni_maps is configured, the server will extract a raw
+public key from the indicated certificate. </p>
+
+<p> Sample commands to compute certificate and public key SHA256 digests: </p>
+
+<pre>
+# SHA256 digest of the first certificate in "cert.pem"
+$ openssl x509 -in cert.pem -outform DER | openssl dgst -sha256 -c
+</pre>
+
+<pre>
+# SHA256 digest of the SPKI of the first certificate in "cert.pem"
+$ openssl x509 -in cert.pem -pubkey -noout |
+    openssl pkey -pubin -outform DER | openssl dgst -sha256 -c
+</pre>
+
+<pre>
+# SHA256 digest of the SPKI of the first private key in "pkey.pem"
+$ openssl pkey -in pkey.pem -pubout -outform DER |
+    openssl dgst -sha256 -c
+</pre>
+
+<p> This feature is available in Postfix 3.9 and later. </p>
+
+%PARAM tlsproxy_tls_enable_rpk $smtpd_tls_enable_rpk
+
+<p> Request that remote SMTP clients send an RFC7250 raw public key
+instead of an X.509 certificate, when asking or requiring client
+authentication. See $smtpd_tls_enable_rpk for details. </p>
+
+<p> This feature is available in Postfix 3.9 and later. </p>
+
+%PARAM smtp_tls_enable_rpk no
+
+<p> Request that remote SMTP servers send an RFC7250 raw public key
+instead of an X.509 certificate. This feature and the enable_rpk
+policy attribute are ignored when there is no raw public key support
+in the local TLS implementation.  </p>
+
+<ul>
+
+<li> <p> At the "may", "encrypt" and "fingerprint" security levels,
+with parameter setting "smtp_tls_enable_rpk = yes" or with "enable_rpk
+= yes" in a policy entry, the Postfix SMTP client will indicate in
+the TLS handshake that it prefers to receive a raw server public
+key, but it will still accept a server public key certificate. </p>
+
+<li> <p> At the "fingerprint" security level, with parameter setting
+"smtp_tls_enable_rpk = yes" or with "enable_rpk = yes" in a policy entry,
+server authentication based on certificate fingerprints becomes more
+fragile.  Even if the server private key and certificate remain
+unchanged, the remote SMTP server will fail fingerprint authentication
+(won't match the configured list of fingerprints) when it starts sending
+a raw public key instead of a certificate, after its TLS implementation
+is updated with raw public key support.  Therefore, <b>DO NOT</b>
+enable raw public keys to remote destinations authenticated by server
+<b>certificate</b> fingerprints.  You should enable raw public keys
+only for servers matched via their public key fingerprint.  </p>
+
+<li> <p> At the "dane" security level, the Postfix SMTP client
+always ignores the parameter setting smtp_tls_enable_rpk or the
+enable_rpk policy attribute. When all valid TLSA records specify
+only server public keys (no certificates) and the local TLS
+implementation supports raw public keys, the client will indicate
+in the TLS handshake that it prefers to receive a raw public key,
+but it will still accept a public key certificate. </p>
+
+</ul>
+
+<p>The Postfix SMTP client is always willing to send raw public keys
+to servers that solicit them when a client certificate is configured
+and the local TLS implementation supports raw public keys. </p>
+
+<p> Sample commands to compute certificate and public key SHA256 digests: </p>
+
+<pre>
+# SHA256 digest of the first certificate in "cert.pem"
+$ openssl x509 -in cert.pem -outform DER | openssl dgst -sha256 -c
+</pre>
+
+<pre>
+# SHA256 digest of the SPKI of the first certificate in "cert.pem"
+$ openssl x509 -in cert.pem -pubkey -noout |
+    openssl pkey -pubin -outform DER | openssl dgst -sha256 -c
+</pre>
+
+<pre>
+# SHA256 digest of the SPKI of the first private key in "pkey.pem"
+$ openssl pkey -in pkey.pem -pubout -outform DER |
+    openssl dgst -sha256 -c
+</pre>
+
+<p> This feature is available in Postfix 3.9 and later. </p>
+
+%PARAM lmtp_tls_enable_rpk yes
+
+<p> The LMTP-specific version of the smtp_tls_enable_rpk
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 3.9 and later. </p>
+
 %PARAM use_srv_lookup
 
 <p> Enables discovery for the specified service(s) using DNS SRV
index 72cecf446144c517200f9da82f3995052f1f9877..ae0f37b8bf8c964fd5d220eb16f642de4d07888c 100644 (file)
@@ -1580,3 +1580,8 @@ charset
 latin
 utf
 mb
+SPKI
+certificate's
+pubout
+rpk
+sni
index bfa589c3df186f6e8fbf0c261293d902da01c5dc..40178180d62651b61ea5d2dabe4e82e45556b17c 100644 (file)
@@ -59,3 +59,6 @@ proto  proto aliases proto virtual proto ADDRESS_REWRITING_README html
  before the server greeting File smtpd smtpd c 
  global mail_params h smtpd smtpd c proto postconf proto 
  Typo fix by Trent W Buck Files proto postconf proto proto stop 
+ smtp smtp c smtp smtp h smtp smtp_params c smtp smtp_proto c 
+ smtp smtp_tls_policy c smtpd smtpd c smtpd smtpd_check c 
+ tls tls h tls tls_client c tls tls_dane c tls tls_fprint c 
index 2bd163eb276b04adc1911b9dc31683c7b2180fb6..5af0b0e8164b3c3e0107e2e8b86533ff05422876 100644 (file)
@@ -1803,3 +1803,9 @@ ipproto
 cw
 uncreate
 MFLAGS
+CRED
+RPK
+RPKs
+SPKI
+peerpkey
+rpk
index c8101c530152d11959720654d8bb00281c88b7f4..028b6a2c6ee9c34028ab22fedd605c974a37fe6c 100644 (file)
@@ -1321,6 +1321,10 @@ extern bool var_smtpd_tls_ask_ccert;
 #define DEF_SMTPD_TLS_RCERT    0
 extern bool var_smtpd_tls_req_ccert;
 
+#define VAR_SMTPD_TLS_ENABLE_RPK       "smtpd_tls_enable_rpk"
+#define DEF_SMTPD_TLS_ENABLE_RPK       0
+extern bool var_smtpd_tls_enable_rpk;
+
 #define VAR_SMTPD_TLS_CCERT_VD "smtpd_tls_ccert_verifydepth"
 #define DEF_SMTPD_TLS_CCERT_VD 9
 extern int var_smtpd_tls_ccert_vd;
@@ -1555,6 +1559,12 @@ extern char *var_smtp_tls_mand_excl;
                                 "{md5} : {sha256}}"
 extern char *var_smtp_tls_fpt_dgst;
 
+#define VAR_SMTP_TLS_ENABLE_RPK        "smtp_tls_enable_rpk"
+#define DEF_SMTP_TLS_ENABLE_RPK        0
+#define VAR_LMTP_TLS_ENABLE_RPK        "lmtp_tls_enable_rpk"
+#define DEF_LMTP_TLS_ENABLE_RPK        0
+extern bool var_smtp_tls_enable_rpk;
+
 #define VAR_SMTP_TLS_TAFILE    "smtp_tls_trust_anchor_file"
 #define DEF_SMTP_TLS_TAFILE    ""
 #define VAR_LMTP_TLS_TAFILE    "lmtp_tls_trust_anchor_file"
@@ -3982,6 +3992,10 @@ extern bool var_tlsp_tls_ask_ccert;
 #define DEF_TLSP_TLS_RCERT     "$" VAR_SMTPD_TLS_RCERT
 extern bool var_tlsp_tls_req_ccert;
 
+#define VAR_TLSP_TLS_ENABLE_RPK        "tlsproxy_tls_enable_rpk"
+#define DEF_TLSP_TLS_ENABLE_RPK        "$" VAR_SMTPD_TLS_ENABLE_RPK
+extern bool var_tlsp_tls_enable_rpk;
+
 #define VAR_TLSP_TLS_CCERT_VD  "tlsproxy_tls_ccert_verifydepth"
 #define DEF_TLSP_TLS_CCERT_VD  "$" VAR_SMTPD_TLS_CCERT_VD
 extern int var_tlsp_tls_ccert_vd;
index 25c36229f84a830b46ccd91b80bd2768db8779dd..de4dce043c10bf120a790015a313efed7c2c2d08 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20230723"
+#define MAIL_RELEASE_DATE      "20230807"
 #define MAIL_VERSION_NUMBER    "3.9"
 
 #ifdef SNAPSHOT
index b9a46999d25c7cc47b49bc069a6435cb839f4531..29c17e396d807d4b83eb5c2c4f0873a8c02fe999 100644 (file)
 /*     in the DNS).  In Postfix versions prior to 3.6, the default value
 /*     was "md5".
 /* .IP "\fB-f\fR"
-/*     Lookup the associated DANE TLSA RRset even when a hostname is not an
+/*     Look up the associated DANE TLSA RRset even when a hostname is not an
 /*     alias and its address records lie in an unsigned zone.  See
 /*     smtp_tls_force_insecure_host_tlsa_lookup for details.
 /* .IP "\fB-F \fICAfile.pem\fR (default: none)"
 /*     the SMTP-in-SSL protocol, rather than the STARTTLS protocol.
 /*     The destination \fIdomain\fR:\fIport\fR must of course provide such
 /*     a service.
+/* .IP "\fB-x\fR"
+/*     Prefer RFC7250 non-X.509 raw public key (RPK) server credentials.  By
+/*     default only X.509 certificates are accepted.  This is analogous to
+/*     setting \fBsmtp_tls_enable_rpk = yes\fR in the smtp(8) client.  At the
+/*     fingerprint security level, when raw public keys are enabled, only
+/*     public key (and not certificate) fingerprints will be compared against
+/*     the specified list of \fImatch\fR arguments.  Certificate fingerprints
+/*     are fragile when raw public keys are solicited, the server may at some
+/*     point in time start returning only the public key.
 /* .IP "\fB-X\fR"
 /*     Enable \fBtlsproxy\fR(8) mode. This is an unsupported mode,
 /*     for program development only.
@@ -441,6 +450,9 @@ typedef struct OPTIONS {
     ARGV   *tas;
     char   *host_lookup;
     char   *addr_pref;
+#ifdef USE_TLS
+    int     enable_rpk;
+#endif
 } OPTIONS;
 
  /*
@@ -696,7 +708,7 @@ static void print_stack(STATE *state, x509_stack_t *sk, int trustout)
        BIO_printf(state->tls_bio, "   cert digest=%s\n", digest);
        myfree(digest);
 
-       digest = tls_pkey_fprint(cert, state->mdalg);
+       digest = tls_pkey_fprint(X509_get0_pubkey(cert), state->mdalg);
        BIO_printf(state->tls_bio, "   pkey digest=%s\n", digest);
        myfree(digest);
 
@@ -809,6 +821,7 @@ static int starttls(STATE *state)
                                    mdalg = state->mdalg);
        TLS_PROXY_CLIENT_START_PROPS(&start_props,
                                     timeout = smtp_tmout,
+                                    enable_rpk = state->options.enable_rpk,
                                     tls_level = state->level,
                                     nexthop = state->nexthop,
                                     host = state->hostname,
@@ -886,13 +899,19 @@ static int starttls(STATE *state)
            state->tls_context = tls_proxy_context_receive(state->stream);
            if (state->tls_context) {
                if (state->log_mask &
-                   (TLS_LOG_CERTMATCH | TLS_LOG_VERBOSE | TLS_LOG_PEERCERT))
-                   msg_info("%s: subject_CN=%s, issuer_CN=%s, "
-                            "fingerprint=%s, pkey_fingerprint=%s",
-                            state->namaddrport, state->tls_context->peer_CN,
-                            state->tls_context->issuer_CN,
-                            state->tls_context->peer_cert_fprint,
-                            state->tls_context->peer_pkey_fprint);
+                   (TLS_LOG_CERTMATCH | TLS_LOG_VERBOSE | TLS_LOG_PEERCERT)) {
+                    if (state->tls_context->stoc_rpk)
+                       msg_info("%s: pkey_fingerprint=%s", state->namaddrport,
+                                state->tls_context->peer_pkey_fprint);
+                   else
+                       msg_info("%s: subject_CN=%s, issuer_CN=%s, "
+                                "fingerprint=%s, pkey_fingerprint=%s",
+                                state->namaddrport,
+                                state->tls_context->peer_CN,
+                                state->tls_context->issuer_CN,
+                                state->tls_context->peer_cert_fprint,
+                                state->tls_context->peer_pkey_fprint);
+                }
                tls_log_summary(TLS_ROLE_CLIENT, TLS_USAGE_NEW,
                                state->tls_context);
            } else {
@@ -906,6 +925,7 @@ static int starttls(STATE *state)
                             stream = stream,
                             fd = -1,
                             timeout = smtp_tmout,
+                            enable_rpk = state->options.enable_rpk,
                             tls_level = state->level,
                             nexthop = state->nexthop,
                             host = state->hostname,
@@ -938,7 +958,7 @@ static int starttls(STATE *state)
 
     if (state->pass == 1) {
        ehlo(state);
-       if (!TLS_CERT_IS_PRESENT(state->tls_context))
+       if (!TLS_CRED_IS_PRESENT(state->tls_context))
            msg_info("Server is anonymous");
        else if (state->tlsproxy_mode == 0) {
            if (state->print_trust)
@@ -1829,14 +1849,14 @@ static void usage(void)
 #ifdef USE_TLS
     fprintf(stderr, "usage: %s %s \\\n\t%s \\\n\t%s \\\n\t%s \\\n\t%s"
            " destination [match ...]\n", var_procname,
-           "[-acCfSvw] [-t conn_tmout] [-T cmd_tmout] [-L logopts]",
+           "[-acCfRSvwx] [-t conn_tmout] [-T cmd_tmout] [-L logopts]",
         "[-h host_lookup] [-l level] [-d mdalg] [-g grade] [-p protocols]",
            "[-A tafile] [-F CAfile.pem] [-P CApath/] [-s servername]",
            "[ [-H chainfiles] | [-k certfile [-K keyfile]] ]",
            "[-m count] [-r delay] [-o name=value]");
 #else
-    fprintf(stderr, "usage: %s [-acStTv] [-h host_lookup] [-o name=value] destination\n",
-           var_procname);
+    fprintf(stderr, "usage: %s [-acRStTv] [-h host_lookup] [-o name=value]"
+           " destination\n", var_procname);
 #endif
     exit(1);
 }
@@ -1906,7 +1926,7 @@ static void parse_options(STATE *state, int argc, char *argv[])
 
 #define OPTS "a:ch:o:RSt:T:v"
 #ifdef USE_TLS
-#define TLSOPTS "A:Cd:fF:g:H:k:K:l:L:m:M:p:P:r:s:wX"
+#define TLSOPTS "A:Cd:fF:g:H:k:K:l:L:m:M:p:P:r:s:wxX"
 
     state->mdalg = 0;
     state->CApath = mystrdup("");
@@ -1917,6 +1937,7 @@ static void parse_options(STATE *state, int argc, char *argv[])
     state->sni = mystrdup("");
     state->options.tas = argv_alloc(1);
     state->options.logopts = 0;
+    state->options.enable_rpk = 0;
     state->level = TLS_LEV_DANE;
     state->mxinsec_level = TLS_LEV_DANE;
     state->tlsproxy_mode = 0;
@@ -2050,6 +2071,9 @@ static void parse_options(STATE *state, int argc, char *argv[])
        case 'w':
            state->wrapper_mode = 1;
            break;
+       case 'x':
+           state->options.enable_rpk = 1;
+           break;
        case 'X':
            state->tlsproxy_mode = 1;
            break;
@@ -2132,8 +2156,8 @@ static void parse_match(STATE *state, int argc, char *argv[])
     case TLS_LEV_FPRINT:
        state->dane = tls_dane_alloc();
        while (*argv)
-           tls_dane_add_fpt_digests((TLS_DANE *) state->dane, *argv++, "",
-                                    smtp_mode);
+           tls_dane_add_fpt_digests(state->dane, state->options.enable_rpk,
+                                    *argv++, "", smtp_mode);
        break;
     case TLS_LEV_DANE:
     case TLS_LEV_DANE_ONLY:
index bca7cd494b5ff522f4e9397e11c37316513e3fcb..ed567e6ecde4f6c202b436cd21d25bf6166517b8 100644 (file)
        VAR_LMTP_TLS_NOTEOFFER, DEF_LMTP_TLS_NOTEOFFER, &var_smtp_tls_note_starttls_offer,
        VAR_LMTP_TLS_BLK_EARLY_MAIL_REPLY, DEF_LMTP_TLS_BLK_EARLY_MAIL_REPLY, &var_smtp_tls_blk_early_mail_reply,
        VAR_LMTP_TLS_FORCE_TLSA, DEF_LMTP_TLS_FORCE_TLSA, &var_smtp_tls_force_tlsa,
+       VAR_LMTP_TLS_ENABLE_RPK, DEF_LMTP_TLS_ENABLE_RPK, &var_smtp_tls_enable_rpk,
 #endif
        VAR_LMTP_TLS_WRAPPER, DEF_LMTP_TLS_WRAPPER, &var_smtp_tls_wrappermode,
        VAR_LMTP_SENDER_AUTH, DEF_LMTP_SENDER_AUTH, &var_smtp_sender_auth,
index ba014919e56ee2dd0263096644b39b7cbf1ef6fd..2f93a79e7ee4b5742a9fcc55f90ac4442c93bf38 100644 (file)
 /* .IP "\fBtls_config_name (empty)\fR"
 /*     The application name passed by Postfix to OpenSSL library
 /*     initialization functions.
+/* .PP
+/*     Available in Postfix version 3.9 and later:
+/* .IP "\fBsmtp_tls_enable_rpk (no)\fR"
+/*     Request that remote SMTP servers send an RFC7250 raw public key
+/*     instead of an X.509 certificate.
 /* OBSOLETE STARTTLS CONTROLS
 /* .ad
 /* .fi
@@ -1090,6 +1095,7 @@ char   *var_smtp_tls_sni;
 bool    var_smtp_tls_blk_early_mail_reply;
 bool    var_smtp_tls_force_tlsa;
 char   *var_smtp_tls_insecure_mx_policy;
+bool    var_smtp_tls_enable_rpk;
 
 #endif
 
index 35d97da2ac96393a0adff0f542699438c0be5c28..29e8efbd768c1ec55bfe3d892510669822b40ef9 100644 (file)
@@ -107,6 +107,7 @@ typedef struct SMTP_TLS_POLICY {
     TLS_DANE *dane;                    /* DANE TLSA digests */
     char   *sni;                       /* Optional SNI name when not DANE */
     int     conn_reuse;                        /* enable connection reuse */
+    int     enable_rpk;                        /* Enable server->client RPK */
 } SMTP_TLS_POLICY;
 
  /*
@@ -142,6 +143,7 @@ extern void smtp_tls_policy_cache_flush(void);
        _tls_policy_init_tmp->dane = 0; \
        _tls_policy_init_tmp->sni = 0; \
        _tls_policy_init_tmp->conn_reuse = 0; \
+       _tls_policy_init_tmp->enable_rpk = 0; \
     } while (0)
 
 #endif
index 22f4709c18bea5a85eaf733824536b90d658e286..b4fafbeb4b06e98054fefbbbdcb9c90cea875871 100644 (file)
        VAR_SMTP_TLS_NOTEOFFER, DEF_SMTP_TLS_NOTEOFFER, &var_smtp_tls_note_starttls_offer,
        VAR_SMTP_TLS_BLK_EARLY_MAIL_REPLY, DEF_SMTP_TLS_BLK_EARLY_MAIL_REPLY, &var_smtp_tls_blk_early_mail_reply,
        VAR_SMTP_TLS_FORCE_TLSA, DEF_SMTP_TLS_FORCE_TLSA, &var_smtp_tls_force_tlsa,
+       VAR_SMTP_TLS_ENABLE_RPK, DEF_SMTP_TLS_ENABLE_RPK, &var_smtp_tls_enable_rpk,
 #endif
        VAR_SMTP_TLS_WRAPPER, DEF_SMTP_TLS_WRAPPER, &var_smtp_tls_wrappermode,
        VAR_SMTP_SENDER_AUTH, DEF_SMTP_SENDER_AUTH, &var_smtp_sender_auth,
index 097d51842351f441e09f3ac86e13eb92bb20b6c8..e022bc2cff262e14a2a43e8c4eb9372c90f3a1c9 100644 (file)
@@ -929,6 +929,7 @@ static int smtp_start_tls(SMTP_STATE *state)
        TLS_PROXY_CLIENT_START_PROPS(&start_props,
                                     timeout = var_smtp_starttls_tmout,
                                     tls_level = state->tls->level,
+                                    enable_rpk = state->tls->enable_rpk,
                                     nexthop = session->tls_nexthop,
                                     host = STR(iter->host),
                                     namaddr = session->namaddrport,
@@ -1051,6 +1052,7 @@ static int smtp_start_tls(SMTP_STATE *state)
                             fd = -1,
                             timeout = var_smtp_starttls_tmout,
                             tls_level = state->tls->level,
+                            enable_rpk = state->tls->enable_rpk,
                             nexthop = session->tls_nexthop,
                             host = STR(iter->host),
                             namaddr = session->namaddrport,
index 92a231df5fba83bf1be899b4ef484b33f025bb8a..f407d65798ab30d17e2558672199e89d408087bb 100644 (file)
@@ -334,9 +334,10 @@ static void tls_policy_lookup_one(SMTP_TLS_POLICY *tls, int *site_level,
                INVALID_RETURN(tls->why, site_level);
                break;
            case TLS_LEV_FPRINT:
-               if (!tls->dane)
-                   tls->dane = tls_dane_alloc();
-               tls_dane_add_fpt_digests(tls->dane, val, "|", smtp_mode);
+               if (tls->matchargv == 0)
+                   tls->matchargv = argv_split(val, "|");
+               else
+                   argv_split_append(tls->matchargv, val, "|");
                break;
            case TLS_LEV_VERIFY:
            case TLS_LEV_SECURE:
@@ -390,6 +391,19 @@ static void tls_policy_lookup_one(SMTP_TLS_POLICY *tls, int *site_level,
            }
            continue;
        }
+       if (!strcasecmp(name, "enable_rpk")) {
+           /* Ultimately ignored at some security levels */
+           if (strcasecmp(val, "yes") == 0) {
+               tls->enable_rpk = 1;
+           } else if (strcasecmp(val, "no") == 0) {
+               tls->enable_rpk = 0;
+           } else {
+               msg_warn("%s: attribute \"%s\" has bad value: \"%s\"",
+                        WHERE, name, val);
+               INVALID_RETURN(tls->why, site_level);
+           }
+           continue;
+       }
        msg_warn("%s: invalid attribute name: \"%s\"", WHERE, name);
        INVALID_RETURN(tls->why, site_level);
     }
@@ -518,6 +532,7 @@ static void *policy_create(const char *unused_key, void *context)
 
     smtp_tls_policy_init(tls, dsb_create());
     tls->conn_reuse = var_smtp_tls_conn_reuse;
+    tls->enable_rpk = var_smtp_tls_enable_rpk;
 
     /*
      * Compute the per-site TLS enforcement level. For compatibility with the
@@ -602,6 +617,13 @@ static void *policy_create(const char *unused_key, void *context)
      */
     set_cipher_grade(tls);
 
+/*
+ * Even when soliciting raw public keys, synthesize TLSA RRs that also match
+ * certificates.  Though this is fragile, it maintains compatibility with
+ * servers that never return RPKs.
+ */
+#define DONT_SUPPRESS_CERT_MATCH       0
+
     /*
      * Use main.cf cert_match setting if not set in per-destination table.
      */
@@ -617,16 +639,26 @@ static void *policy_create(const char *unused_key, void *context)
     case TLS_LEV_FPRINT:
        if (tls->dane == 0)
            tls->dane = tls_dane_alloc();
-       if (tls->dane->tlsa == 0) {
-           tls_dane_add_fpt_digests(tls->dane, var_smtp_tls_fpt_cmatch,
-                                    CHARS_COMMA_SP, smtp_mode);
-           if (tls->dane->tlsa == 0) {
-               msg_warn("nexthop domain %s: configured at fingerprint "
-                      "security level, but with no fingerprints to match.",
-                        dest);
-               MARK_INVALID(tls->why, &tls->level);
-               return ((void *) tls);
+       /* Process the specified fingerprint match patterns */
+       if (tls->matchargv) {
+           int     i;
+
+           for (i = 0; i < tls->matchargv->argc; ++i) {
+               tls_dane_add_fpt_digests(tls->dane, DONT_SUPPRESS_CERT_MATCH,
+                                        tls->matchargv->argv[i], "",
+                                        smtp_mode);
            }
+       } else {
+           tls_dane_add_fpt_digests(tls->dane, DONT_SUPPRESS_CERT_MATCH,
+                                    var_smtp_tls_fpt_cmatch, CHARS_COMMA_SP,
+                                    smtp_mode);
+       }
+       if (tls->dane->tlsa == 0) {
+           msg_warn("nexthop domain %s: configured at fingerprint "
+                    "security level, but with no fingerprints to match.",
+                    dest);
+           MARK_INVALID(tls->why, &tls->level);
+           return ((void *) tls);
        }
        break;
     case TLS_LEV_VERIFY:
index 06dd86d99d00e5818059a158be40067453cbb328..f6ade16e388edaef2573e2d3bd6328cd31c0c344 100644 (file)
 /* .IP "\fBtls_config_name (empty)\fR"
 /*     The application name passed by Postfix to OpenSSL library
 /*     initialization functions.
+/* .PP
+/*     Available in Postfix version 3.9 and later:
+/* .IP "\fBsmtpd_tls_enable_rpk (no)\fR"
+/*     Request that remote SMTP clients send an RFC7250 raw public key
+/*     instead of an X.509 certificate, when asking for or requiring client
+/*     authentication.
 /* OBSOLETE STARTTLS CONTROLS
 /* .ad
 /* .fi
@@ -1479,6 +1485,7 @@ char   *var_smtpd_tls_eecdh;
 char   *var_smtpd_tls_eccert_file;
 char   *var_smtpd_tls_eckey_file;
 char   *var_smtpd_tls_chain_files;
+int    var_smtpd_tls_enable_rpk;
 
 #endif
 
@@ -3494,6 +3501,11 @@ static void common_pre_message_handling(SMTPD_STATE *state,
                            "verified OK" : "not verified");
                vstring_free(issuer_CN);
                vstring_free(peer_CN);
+           } else if (TLS_RPK_IS_PRESENT(state->tls_context)) {
+               out_fprintf(out_stream, REC_TYPE_NORM,
+                           "\t(Client RPK %s digest %s)",
+                           var_smtpd_tls_fpt_dgst,
+                           state->tls_context->peer_pkey_fprint);
            } else if (var_smtpd_tls_ask_ccert)
                out_fprintf(out_stream, REC_TYPE_NORM,
                            "\t(Client did not present a certificate)");
@@ -5143,6 +5155,7 @@ static void smtpd_start_tls(SMTPD_STATE *state)
                         stream = state->client,
                         fd = -1,
                         timeout = var_smtpd_starttls_tmout,
+                        enable_rpk = var_smtpd_tls_enable_rpk,
                         requirecert = requirecert,
                         serverid = state->service,
                         namaddr = state->namaddr,
@@ -6292,7 +6305,6 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
                no_server_cert_ok = 0;
                cert_file = var_smtpd_tls_cert_file;
            }
-
            have_server_cert = *cert_file != 0;
            have_server_cert |= *var_smtpd_tls_eccert_file != 0;
            have_server_cert |= *var_smtpd_tls_dcert_file != 0;
@@ -6541,6 +6553,7 @@ int     main(int argc, char **argv)
 #ifdef USE_TLS
        VAR_SMTPD_TLS_ACERT, DEF_SMTPD_TLS_ACERT, &var_smtpd_tls_ask_ccert,
        VAR_SMTPD_TLS_RCERT, DEF_SMTPD_TLS_RCERT, &var_smtpd_tls_req_ccert,
+       VAR_SMTPD_TLS_ENABLE_RPK, DEF_SMTPD_TLS_ENABLE_RPK, &var_smtpd_tls_enable_rpk,
        VAR_SMTPD_TLS_RECHEAD, DEF_SMTPD_TLS_RECHEAD, &var_smtpd_tls_received_header,
        VAR_SMTPD_TLS_SET_SESSID, DEF_SMTPD_TLS_SET_SESSID, &var_smtpd_tls_set_sessid,
 #endif
index b5ce4a94fc9834d86a12311e3b68b396e7fd7e8e..fd63f6813f24c35e87a0a64c1463dd02faf3e7c4 100644 (file)
@@ -1588,6 +1588,7 @@ static int permit_auth_destination(SMTPD_STATE *state, char *recipient);
 static int permit_tls_clientcerts(SMTPD_STATE *state, int permit_all_certs)
 {
 #ifdef USE_TLS
+    const char *myname = "permit_tls_clientcerts";
     const char *found = 0;
 
     if (!state->tls_context)
@@ -1602,9 +1603,9 @@ static int permit_tls_clientcerts(SMTPD_STATE *state, int permit_all_certs)
 
     /*
      * When directly checking the fingerprint, it is OK if the issuing CA is
-     * not trusted.
+     * not trusted.  Raw public keys are also acceptable.
      */
-    if (TLS_CERT_IS_PRESENT(state->tls_context)) {
+    if (TLS_CRED_IS_PRESENT(state->tls_context)) {
        int     i;
        char   *prints[2];
 
@@ -1613,12 +1614,24 @@ static int permit_tls_clientcerts(SMTPD_STATE *state, int permit_all_certs)
                     VAR_SMTPD_TLS_FPT_DGST "=md5 to compute certificate "
                     "fingerprints");
 
-       prints[0] = state->tls_context->peer_cert_fprint;
-       prints[1] = state->tls_context->peer_pkey_fprint;
+       prints[0] = state->tls_context->peer_pkey_fprint;
+       prints[1] = state->tls_context->peer_cert_fprint;
 
        /* After lookup error, leave relay_ccerts->error at non-zero value. */
        for (i = 0; i < 2; ++i) {
+           /* With RFC7250 RPK, no certificate may be available */
+           if (!*prints[i])
+               continue;
            found = maps_find(relay_ccerts, prints[i], DICT_FLAG_NONE);
+           if (var_smtpd_tls_enable_rpk && i > 0 && found) {
+               msg_warn("%s: %s: %s: Fragile access policy: %s=yes, but"
+                        " public key fingerprint \"%s\" not matched, while"
+                        " certificate fingerprint \"%s\" matched",
+                        myname, state->namaddr, relay_ccerts->title,
+                        VAR_SMTPD_TLS_ENABLE_RPK,
+                        state->tls_context->peer_cert_fprint,
+                        state->tls_context->peer_pkey_fprint);
+           }
            if (found != 0) {
                if (msg_verbose)
                    msg_info("Relaying allowed for certified client: %s", found);
@@ -3165,6 +3178,9 @@ static int check_ccert_access(SMTPD_STATE *state, const char *acl_spec,
 
 #ifdef USE_TLS
     const char *myname = "check_ccert_access";
+    int     cert_result = SMTPD_CHECK_DUNNO;
+    int     pkey_result = SMTPD_CHECK_DUNNO;
+    int    *respt;
     int     found;
     const MAP_SEARCH *acl;
     const char default_search[] = {
@@ -3191,9 +3207,9 @@ static int check_ccert_access(SMTPD_STATE *state, const char *acl_spec,
 
     /*
      * When directly checking the fingerprint, it is OK if the issuing CA is
-     * not trusted.
+     * not trusted.  Raw public keys are also acceptable.
      */
-    if (TLS_CERT_IS_PRESENT(state->tls_context)) {
+    if (TLS_CRED_IS_PRESENT(state->tls_context)) {
        const char *action;
        const char *match_this;
        const char *known_action;
@@ -3202,17 +3218,19 @@ static int check_ccert_access(SMTPD_STATE *state, const char *acl_spec,
            switch (*action) {
            case SMTPD_ACL_SEARCH_CODE_CERT_FPRINT:
                match_this = state->tls_context->peer_cert_fprint;
-               if (warn_compat_break_smtpd_tls_fpt_dgst)
+               if (*match_this && warn_compat_break_smtpd_tls_fpt_dgst)
                    msg_info("using backwards-compatible default setting "
                             VAR_SMTPD_TLS_FPT_DGST "=md5 to compute "
                             "certificate fingerprints");
+               respt = &cert_result;
                break;
            case SMTPD_ACL_SEARCH_CODE_PKEY_FPRINT:
                match_this = state->tls_context->peer_pkey_fprint;
-               if (warn_compat_break_smtpd_tls_fpt_dgst)
+               if (*match_this && warn_compat_break_smtpd_tls_fpt_dgst)
                    msg_info("using backwards-compatible default setting "
                             VAR_SMTPD_TLS_FPT_DGST "=md5 to compute "
-                            "certificate fingerprints");
+                            "public key fingerprints");
+               respt = &pkey_result;
                break;
            default:
                known_action = str_name_code(search_actions, *action);
@@ -3225,6 +3243,9 @@ static int check_ccert_access(SMTPD_STATE *state, const char *acl_spec,
                                           451, "4.3.5",
                                           "Server configuration error"));
            }
+           /* With RFC7250 RPK, no certificate may be available */
+           if (!*match_this)
+               continue;
            if (msg_verbose)
                msg_info("%s: look up %s %s",
                         myname, str_name_code(search_actions, *action),
@@ -3237,11 +3258,16 @@ static int check_ccert_access(SMTPD_STATE *state, const char *acl_spec,
             * "reject" event. XXX Should log the thing that is rejected
             * (fingerprint etc.) or would that give away too much?
             */
-           result = check_access(state, acl->map_type_name, match_this,
+           *respt = check_access(state, acl->map_type_name, match_this,
                                  DICT_FLAG_NONE, &found,
                                  state->tls_context->peer_CN,
                                  SMTPD_NAME_CCERT, def_acl);
-           if (result != SMTPD_CHECK_DUNNO)
+           if (*respt == SMTPD_CHECK_DUNNO)
+               continue;
+           if (result == SMTPD_CHECK_DUNNO)
+               result = *respt;
+           if (!var_smtpd_tls_enable_rpk
+               || *action == SMTPD_ACL_SEARCH_CODE_PKEY_FPRINT)
                break;
        }
     } else if (!var_smtpd_tls_ask_ccert) {
@@ -3251,6 +3277,17 @@ static int check_ccert_access(SMTPD_STATE *state, const char *acl_spec,
        if (msg_verbose)
            msg_info("%s: no client certificate", myname);
     }
+    if (var_smtpd_tls_enable_rpk
+       && cert_result != SMTPD_CHECK_DUNNO
+       && cert_result != pkey_result) {
+       msg_warn("%s: %s: %s: Fragile access policy: %s=yes, but"
+                " the action for certificate fingerprint \"%s\" !="
+                " the action for public key fingerprint \"%s\"",
+                myname, state->namaddr, acl->map_type_name,
+                VAR_SMTPD_TLS_ENABLE_RPK,
+                state->tls_context->peer_cert_fprint,
+                state->tls_context->peer_pkey_fprint);
+    }
 #endif
     return (result);
 }
@@ -4015,6 +4052,7 @@ static int check_policy_service(SMTPD_STATE *state, const char *server,
     ENCODE_CN(subject, subject_buf, state->tls_context->peer_CN);
     ENCODE_CN(issuer, issuer_buf, state->tls_context->issuer_CN);
 
+#define NONEMPTY(x) ((x) != 0 && (*x) != 0)
     /*
      * XXX: Too noisy to warn for each policy lookup, especially because we
      * don't even know whether the policy server will use the fingerprint. So
@@ -4024,12 +4062,12 @@ static int check_policy_service(SMTPD_STATE *state, const char *server,
     if (!warned
        && warn_compat_break_smtpd_tls_fpt_dgst
        && state->tls_context
-       && state->tls_context->peer_cert_fprint
-       && *state->tls_context->peer_cert_fprint) {
+       && (NONEMPTY(state->tls_context->peer_cert_fprint)
+           || NONEMPTY(state->tls_context->peer_pkey_fprint))) {
        warned = 1;
        msg_info("using backwards-compatible default setting "
                 VAR_SMTPD_TLS_FPT_DGST "=md5 to compute certificate "
-                "fingerprints");
+                "and public key fingerprints");
     }
 #endif
 
@@ -6386,7 +6424,7 @@ int     main(int argc, char **argv)
                    state.tls_context->peer_cert_fprint =
                        state.tls_context->peer_pkey_fprint = 0;
                }
-               state.tls_context->peer_status |= TLS_CERT_FLAG_PRESENT;
+               state.tls_context->peer_status |= TLS_CRED_FLAG_CERT;
                UPDATE_STRING(state.tls_context->peer_cert_fprint,
                              args->argv[1]);
                state.tls_context->peer_pkey_fprint =
index 73eebaeda9fc01c231cc5e56d8bb6cd7d195b130..3ec41ba369510486ae25db62ddf774077726911b 100644 (file)
@@ -78,6 +78,7 @@ extern const char *str_tls_level(int);
 #include <openssl/opensslv.h>          /* OPENSSL_VERSION_NUMBER */
 #include <openssl/ssl.h>
 #include <openssl/conf.h>
+#include <openssl/tls1.h>              /* TLS extensions */
 
  /* Appease indent(1) */
 #define x509_stack_t STACK_OF(X509)
@@ -203,8 +204,8 @@ extern void tls_dane_flush(void);
 extern TLS_DANE *tls_dane_alloc(void);
 extern void tls_tlsa_free(TLS_TLSA *);
 extern void tls_dane_free(TLS_DANE *);
-extern void tls_dane_add_fpt_digests(TLS_DANE *, const char *, const char *,
-                                            int);
+extern void tls_dane_add_fpt_digests(TLS_DANE *, int, const char *,
+                                           const char *, int);
 extern TLS_DANE *tls_dane_resolve(unsigned, const char *, DNS_RR *, int);
 extern int tls_dane_load_trustfile(TLS_DANE *, const char *);
 
@@ -232,6 +233,8 @@ typedef struct {
     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 */
+    int     ctos_rpk;                  /* Did the client send an RPK? */
+    int     stoc_rpk;                  /* Did the server send an RPK? */
     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 */
@@ -264,13 +267,17 @@ typedef struct {
   * Peer status bits. TLS_CERT_FLAG_MATCHED implies TLS_CERT_FLAG_TRUSTED
   * only in the case of a hostname match.
   */
-#define TLS_CERT_FLAG_PRESENT          (1<<0)
+#define TLS_CRED_FLAG_CERT             (1<<0)
 #define TLS_CERT_FLAG_ALTNAME          (1<<1)
 #define TLS_CERT_FLAG_TRUSTED          (1<<2)
 #define TLS_CERT_FLAG_MATCHED          (1<<3)
 #define TLS_CERT_FLAG_SECURED          (1<<4)
+#define TLS_CRED_FLAG_RPK              (1<<5)
+#define TLS_CRED_FLAG_ANY      (TLS_CRED_FLAG_CERT|TLS_CRED_FLAG_RPK)
 
-#define TLS_CERT_IS_PRESENT(c) ((c) && ((c)->peer_status&TLS_CERT_FLAG_PRESENT))
+#define TLS_CRED_IS_PRESENT(c) ((c) && ((c)->peer_status&TLS_CRED_FLAG_ANY))
+#define TLS_CERT_IS_PRESENT(c) ((c) && ((c)->peer_status&TLS_CRED_FLAG_CERT))
+#define TLS_RPK_IS_PRESENT(c)  ((c) && ((c)->peer_status&TLS_CRED_FLAG_RPK))
 #define TLS_CERT_IS_ALTNAME(c) ((c) && ((c)->peer_status&TLS_CERT_FLAG_ALTNAME))
 #define TLS_CERT_IS_TRUSTED(c) ((c) && ((c)->peer_status&TLS_CERT_FLAG_TRUSTED))
 #define TLS_CERT_IS_MATCHED(c) ((c) && ((c)->peer_status&TLS_CERT_FLAG_MATCHED))
@@ -472,6 +479,7 @@ typedef struct {
     VSTREAM *stream;
     int     fd;                                /* Event-driven file descriptor */
     int     timeout;
+    int     enable_rpk;                        /* Solicit server raw public keys */
     int     tls_level;                 /* Security level */
     const char *nexthop;               /* destination domain */
     const char *host;                  /* MX hostname */
@@ -508,12 +516,12 @@ extern TLS_SESS_STATE *tls_client_post_connect(TLS_SESS_STATE *,
     a6, a7, a8, a9, a10, a11, a12, a13, a14))
 
 #define TLS_CLIENT_START(props, a1, a2, a3, a4, a5, a6, a7, a8, a9, \
-    a10, a11, a12, a13, a14, a15, a16, a17) \
+    a10, a11, a12, a13, a14, a15, a16, a17, a18) \
     tls_client_start((((props)->a1), ((props)->a2), ((props)->a3), \
     ((props)->a4), ((props)->a5), ((props)->a6), ((props)->a7), \
     ((props)->a8), ((props)->a9), ((props)->a10), ((props)->a11), \
     ((props)->a12), ((props)->a13), ((props)->a14), ((props)->a15), \
-    ((props)->a16), ((props)->a17), (props)))
+    ((props)->a16), ((props)->a17), ((props)->a18), (props)))
 
  /*
   * tls_server.c
@@ -546,6 +554,7 @@ typedef struct {
     VSTREAM *stream;                   /* Client stream */
     int     fd;                                /* Event-driven file descriptor */
     int     timeout;                   /* TLS handshake timeout */
+    int     enable_rpk;                        /* Solicit client raw public keys */
     int     requirecert;               /* Insist on client cert? */
     const char *serverid;              /* Server instance (salt cache key) */
     const char *namaddr;               /* Client nam[addr] for logging */
@@ -570,10 +579,12 @@ extern TLS_SESS_STATE *tls_server_post_accept(TLS_SESS_STATE *);
     ((props)->a16), ((props)->a17), ((props)->a18), ((props)->a19), \
     ((props)->a20), (props)))
 
-#define TLS_SERVER_START(props, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) \
+#define TLS_SERVER_START(props, a1, a2, a3, a4, a5, a6, a7, a8, a9, \
+    a10, a11) \
     tls_server_start((((props)->a1), ((props)->a2), ((props)->a3), \
     ((props)->a4), ((props)->a5), ((props)->a6), ((props)->a7), \
-    ((props)->a8), ((props)->a9), ((props)->a10), (props)))
+    ((props)->a8), ((props)->a9), ((props)->a10), ((props)->a11), \
+    (props)))
 
  /*
   * tls_session.c
@@ -660,7 +671,7 @@ extern TLS_TLSA *tlsa_prepend(TLS_TLSA *, uint8_t, uint8_t, uint8_t,
 extern const EVP_MD *tls_digest_byname(const char *, EVP_MD_CTX **);
 extern char *tls_digest_encode(const unsigned char *, int);
 extern char *tls_cert_fprint(X509 *, const char *);
-extern char *tls_pkey_fprint(X509 *, const char *);
+extern char *tls_pkey_fprint(EVP_PKEY *, const char *);
 extern char *tls_serverid_digest(TLS_SESS_STATE *,
                              const TLS_CLIENT_START_PROPS *, const char *);
 
@@ -696,6 +707,8 @@ extern long tls_bio_dump_cb(BIO *, int, const char *, int, long, long);
 
 #endif
 extern const EVP_MD *tls_validate_digest(const char *);
+extern void tls_enable_client_rpk(SSL_CTX *, SSL *);
+extern void tls_enable_server_rpk(SSL_CTX *, SSL *);
 
  /*
   * tls_seed.c
index e0dfe15e90a26eefaa37f6603fe92add478467c0..3eda859cc0d039b49d4e39ea1a6d6c864c8a08cf 100644 (file)
@@ -86,8 +86,9 @@
 /*     available as:
 /* .IP TLScontext->peer_status
 /*     A bitmask field that records the status of the peer certificate
-/*     verification. This consists of one or more of TLS_CERT_FLAG_PRESENT,
-/*     TLS_CERT_FLAG_TRUSTED, TLS_CERT_FLAG_MATCHED and TLS_CERT_FLAG_SECURED.
+/*     verification. This consists of one or more of TLS_CRED_FLAG_CERT,
+/*     TLS_CRED_FLAG_RPK, TLS_CERT_FLAG_TRUSTED, TLS_CERT_FLAG_MATCHED and
+/*     TLS_CERT_FLAG_SECURED.
 /* .IP TLScontext->peer_CN
 /*     Extracted CommonName of the peer, or zero-length string if the
 /*     information could not be extracted.
@@ -303,15 +304,11 @@ static void uncache_session(SSL_CTX *ctx, TLS_SESS_STATE *TLScontext)
     tls_mgr_delete(TLScontext->cache_type, TLScontext->serverid);
 }
 
-/* verify_extract_name - verify peer name and extract peer information */
+/* verify_x509 - process X.509 certificate verification status */
 
-static void verify_extract_name(TLS_SESS_STATE *TLScontext, X509 *peercert,
-                                       const TLS_CLIENT_START_PROPS *props)
+static void verify_x509(TLS_SESS_STATE *TLScontext, X509 *peercert,
+                               const TLS_CLIENT_START_PROPS *props)
 {
-    int     verbose;
-
-    verbose = TLScontext->log_mask &
-       (TLS_LOG_CERTMATCH | TLS_LOG_VERBOSE | TLS_LOG_PEERCERT);
 
     /*
      * On exit both peer_CN and issuer_CN should be set.
@@ -345,7 +342,8 @@ static void verify_extract_name(TLS_SESS_STATE *TLScontext, X509 *peercert,
                TLScontext->peer_status |= TLS_CERT_FLAG_SECURED;
            TLScontext->peer_status |= TLS_CERT_FLAG_MATCHED;
 
-           if (verbose) {
+           if (TLScontext->log_mask &
+               (TLS_LOG_CERTMATCH | TLS_LOG_VERBOSE | TLS_LOG_PEERCERT)) {
                const char *peername = SSL_get0_peername(TLScontext->con);
 
                if (peername)
@@ -356,6 +354,50 @@ static void verify_extract_name(TLS_SESS_STATE *TLScontext, X509 *peercert,
        }
     }
 
+    /*
+     * 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_MATCHED(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 peer credential, "
+                    "look for details earlier in the log", props->namaddr);
+    }
+}
+
+/* verify_rpk - process RFC7250 raw public key verification status */
+
+static void verify_rpk(TLS_SESS_STATE *TLScontext, EVP_PKEY *peerpkey,
+                              const TLS_CLIENT_START_PROPS *props)
+{
+    /* Was the raw public key (type of cert) matched? */
+    if (SSL_get_verify_result(TLScontext->con) == X509_V_OK) {
+       TLScontext->peer_status |= TLS_CERT_FLAG_TRUSTED;
+       if (TLScontext->must_fail) {
+           msg_panic("%s: raw public key valid despite trust init failure",
+                     TLScontext->namaddr);
+       } else if (TLS_MUST_MATCH(TLScontext->level)) {
+
+           /*
+            * Fully secured only if not insecure like half-dane.  We use
+            * TLS_CERT_FLAG_MATCHED to satisfy policy, but
+            * TLS_CERT_FLAG_SECURED to log the effective security.
+            */
+           if (!TLS_NEVER_SECURED(TLScontext->level))
+               TLScontext->peer_status |= TLS_CERT_FLAG_SECURED;
+           TLScontext->peer_status |= TLS_CERT_FLAG_MATCHED;
+
+           if (TLScontext->log_mask &
+               (TLS_LOG_CERTMATCH | TLS_LOG_VERBOSE | TLS_LOG_PEERCERT))
+               tls_dane_log(TLScontext);
+       }
+    }
+
     /*
      * Give them a clue. Problems with trust chain verification are logged
      * when the session is first negotiated, before the session is stored
@@ -792,6 +834,30 @@ TLS_APPL_STATE *tls_client_init(const TLS_CLIENT_INIT_PROPS *props)
        return (0);
     }
 
+    /*
+     * Enable support for client->server raw public keys, provided we actually
+     * have keys to send.  They'll only be used if the server also enables
+     * client RPKs.
+     *
+     * XXX: When the server requests client auth, the TLS 1.2 protocol does not
+     * provide an unambiguous mechanism for the client to not send an RPK (as
+     * it can with client X.509 certs or TLS 1.3).  This is why we don't just
+     * enable client RPK also with no keys in hand.
+     *
+     * A very unlikely scenario is that the server allows clients to not send
+     * keys, but only accepts keys for a set of algorithms we don't have.  Then
+     * we still can't send a key, but have agreed to RPK.  OpenSSL will attempt
+     * to send an empty RPK even with TLS 1.2 (and will accept such a message),
+     * but other implementations may be more strict.
+     *
+     * We could limit client RPK support to connections that support only TLS
+     * 1.3 and up, but that's practical only decades in the future, and the
+     * risk scenario is contrived and very unlikely.
+     */
+    if (SSL_CTX_get0_certificate(client_ctx) != NULL &&
+        SSL_CTX_get0_privatekey(client_ctx) != NULL)
+        tls_enable_client_rpk(client_ctx, NULL);
+
     /*
      * With OpenSSL 1.0.2 and later the client EECDH curve list becomes
      * configurable with the preferred curve negotiated via the supported
@@ -1007,6 +1073,24 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props)
        return (0);
     }
 
+    /*
+     * Possibly enable RFC7250 raw public keys in non-DANE/non-PKI levels
+     * when the fingerprint mask includes only public keys.  For "may" and
+     * "encrypt" this is a heuristic, since we don't use the fingerprints
+     * beyond reporting them in verbose logging.  If you always want certs
+     * with "may" and "encrypt" you'll have to tolerate them with
+     * "fingerprint", or use a separate transport.
+     */
+    switch (props->tls_level) {
+    case TLS_LEV_MAY:
+    case TLS_LEV_ENCRYPT:
+    case TLS_LEV_FPRINT:
+       if (props->enable_rpk)
+           tls_enable_server_rpk(NULL, TLScontext->con);
+    default:
+       break;
+    }
+
     /*
      * Try to convey the configured TLSA records for this connection to the
      * OpenSSL library.  If none are "usable", we'll fall back to "encrypt"
@@ -1175,6 +1259,7 @@ TLS_SESS_STATE *tls_client_post_connect(TLS_SESS_STATE *TLScontext,
 {
     const SSL_CIPHER *cipher;
     X509   *peercert;
+    EVP_PKEY *peerpkey = 0;
 
     /* Turn off packet dump if only dumping the handshake */
     if ((TLScontext->log_mask & TLS_LOG_ALLPKTS) == 0)
@@ -1192,31 +1277,61 @@ TLS_SESS_STATE *tls_client_post_connect(TLS_SESS_STATE *TLScontext,
      * Do peername verification if requested and extract useful information
      * from the certificate for later use.
      */
-    if ((peercert = TLS_PEEK_PEER_CERT(TLScontext->con)) != 0) {
-       TLScontext->peer_status |= TLS_CERT_FLAG_PRESENT;
+    peercert = TLS_PEEK_PEER_CERT(TLScontext->con);
+    if (peercert != 0) {
+       peerpkey = X509_get0_pubkey(peercert);
+    }
+#if OPENSSL_VERSION_PREREQ(3,2)
+    else {
+       peerpkey = SSL_get0_peer_rpk(TLScontext->con);
+    }
+#endif
+
+    if (peercert != 0) {
+       TLScontext->peer_status |= TLS_CRED_FLAG_CERT;
 
        /*
         * Peer name or fingerprint verification as requested.
         * Unconditionally set peer_CN, issuer_CN and peer_cert_fprint. Check
         * fingerprint first, and avoid logging verified as untrusted in the
-        * call to verify_extract_name().
+        * call to verify_x509().
         */
-       TLScontext->peer_cert_fprint = tls_cert_fprint(peercert, props->mdalg);
-       TLScontext->peer_pkey_fprint = tls_pkey_fprint(peercert, props->mdalg);
-       verify_extract_name(TLScontext, peercert, props);
+       TLScontext->peer_cert_fprint =
+           tls_cert_fprint(peercert, props->mdalg);
+       TLScontext->peer_pkey_fprint =
+           tls_pkey_fprint(peerpkey, props->mdalg);
+       verify_x509(TLScontext, peercert, props);
 
        if (TLScontext->log_mask &
            (TLS_LOG_CERTMATCH | TLS_LOG_VERBOSE | TLS_LOG_PEERCERT))
-           msg_info("%s: subject_CN=%s, issuer_CN=%s, "
-                    "fingerprint=%s, pkey_fingerprint=%s", props->namaddr,
+           msg_info("%s: subject_CN=%s, issuer=%s%s%s%s%s",
+                    TLScontext->namaddr,
                     TLScontext->peer_CN, TLScontext->issuer_CN,
-                    TLScontext->peer_cert_fprint,
-                    TLScontext->peer_pkey_fprint);
+                    *TLScontext->peer_cert_fprint ?
+                    ", cert fingerprint=" : "",
+                    *TLScontext->peer_cert_fprint ?
+                    TLScontext->peer_cert_fprint : "",
+                    *TLScontext->peer_pkey_fprint ?
+                    ", pkey fingerprint=" : "",
+                    *TLScontext->peer_pkey_fprint ?
+                    TLScontext->peer_pkey_fprint : "");
     } else {
        TLScontext->issuer_CN = mystrdup("");
        TLScontext->peer_CN = mystrdup("");
        TLScontext->peer_cert_fprint = mystrdup("");
-       TLScontext->peer_pkey_fprint = mystrdup("");
+
+       if (!peerpkey) {
+           TLScontext->peer_pkey_fprint = mystrdup("");
+       } else {
+           TLScontext->peer_status |= TLS_CRED_FLAG_RPK;
+           TLScontext->peer_pkey_fprint =
+               tls_pkey_fprint(peerpkey, props->mdalg);
+           if (TLScontext->log_mask &
+               (TLS_LOG_CERTMATCH | TLS_LOG_VERBOSE | TLS_LOG_PEERCERT))
+               msg_info("%s: raw public key fingerprint=%s", props->namaddr,
+                        TLScontext->peer_pkey_fprint);
+           verify_rpk(TLScontext, peerpkey, props);
+       }
     }
 
     /*
index a2b9b80d383de66d4077f46e5e47cd582c36d9ec..ac7f05f94ba53241d9b4a3f06ed7e02f551aeef9 100644 (file)
@@ -22,8 +22,9 @@
 /*     void    tls_dane_free(dane)
 /*     TLS_DANE *dane;
 /*
-/*     void    tls_dane_add_fpt_digests(dane, digest, delim, smtp_mode)
+/*     void    tls_dane_add_fpt_digests(dane, pkey_only, digest, delim, smtp_mode)
 /*     TLS_DANE *dane;
+/*     int     pkey_only;
 /*     const char *digest;
 /*     const char *delim;
 /*     int     smtp_mode;
 /*     SSL context to be configured with the chosen digest algorithms.
 /* .IP  fpt_alg
 /*     The OpenSSL EVP digest algorithm handle for the fingerprint digest.
+/* .IP  pkey_only
+/*     When true, generate "fingerprint" TLSA records for just the public
+/*     keys.  Otherwise, for both certificates and public keys.
 /* .IP  tlsa
 /*     TLSA record linked list head, initially NULL.
 /* .IP  usage
@@ -415,8 +419,9 @@ static void dane_free(void *dane, void *unused_context)
 
 /* tls_dane_add_fpt_digests - map fingerprint list to DANE TLSA RRset */
 
-void    tls_dane_add_fpt_digests(TLS_DANE *dane, const char *digest,
-                                        const char *delim, int smtp_mode)
+void    tls_dane_add_fpt_digests(TLS_DANE *dane, int pkey_only,
+                                     const char *digest, const char *delim,
+                                        int smtp_mode)
 {
     ARGV   *values = argv_split(digest, delim);
     ssize_t i;
@@ -455,31 +460,41 @@ void    tls_dane_add_fpt_digests(TLS_DANE *dane, const char *digest,
            continue;
        }
 
+#define USTR_LEN(raw) (unsigned char *) STR(raw), VSTRING_LEN(raw)
+
        /*
         * At the "fingerprint" security level certificate digests and public
-        * key digests are interchangeable.  Each leaf certificate is matched
-        * via either the public key digest or full certificate digest.  The
-        * DER encoding of a certificate is not a valid public key, and
-        * conversely, the DER encoding of a public key is not a valid
-        * certificate.  An attacker would need a 2nd-preimage that is
+        * key digests are by default interchangeable.  Each leaf certificate
+        * is matched via either the public key digest or full certificate
+        * digest.  The DER encoding of a certificate is not a valid public
+        * key, and conversely, the DER encoding of a public key is not a
+        * valid certificate.  An attacker would need a 2nd-preimage that is
         * feasible across types (given cert digest == some pkey digest) and
         * yet presumably difficult within a type (e.g. given cert digest ==
         * some other cert digest).  No such attacks are known at this time,
         * and it is expected that if any are found they would work within as
         * well as across the cert/pkey data types.
+        *
+        * That said, when `pkey_only` is true, we match only public keys.
         * 
         * The private-use matching type "255" is mapped to the configured
         * fingerprint digest, which may (harmlessly) coincide with one of
         * the standard DANE digest algorithms.  The private code point is
         * however unconditionally enabled.
         */
+       if (!pkey_only) {
+           dane->tlsa = tlsa_prepend(dane->tlsa, 3, 0, 255, USTR_LEN(raw));
+           if (log_mask & (TLS_LOG_VERBOSE | TLS_LOG_DANE))
+               tlsa_info("fingerprint", "digest as private-use TLSA record",
+                         3, 0, 255, USTR_LEN(raw));
+       }
+
+       /* The public key match is unconditional */
+       dane->tlsa = tlsa_prepend(dane->tlsa, 3, 1, 255, USTR_LEN(raw));
        if (log_mask & (TLS_LOG_VERBOSE | TLS_LOG_DANE))
            tlsa_info("fingerprint", "digest as private-use TLSA record",
-                  3, 0, 255, (unsigned char *) STR(raw), VSTRING_LEN(raw));
-       dane->tlsa = tlsa_prepend(dane->tlsa, 3, 0, 255,
-                             (unsigned char *) STR(raw), VSTRING_LEN(raw));
-       dane->tlsa = tlsa_prepend(dane->tlsa, 3, 1, 255,
-                             (unsigned char *) STR(raw), VSTRING_LEN(raw));
+                     3, 1, 255, USTR_LEN(raw));
+
        vstring_free(raw);
     }
     argv_free(values);
@@ -798,12 +813,21 @@ int     tls_dane_enable(TLS_SESS_STATE *TLScontext)
     SSL    *ssl = TLScontext->con;
     int     usable = 0;
     int     ret;
+    int     rpk_compat = 1;
 
     for (tp = dane->tlsa; tp != 0; tp = tp->next) {
        ret = SSL_dane_tlsa_add(ssl, tp->usage, tp->selector,
                                tp->mtype, tp->data, tp->length);
        if (ret > 0) {
            ++usable;
+           /*
+            * Disable use of RFC7250 raw public keys if any TLSA record
+            * depends on X.509 certificates.  Only DANE-EE(3) SPKI(1) records
+            * can get by with just a public key.
+            */
+           if (tp->usage != DNS_TLSA_USAGE_DOMAIN_ISSUED_CERTIFICATE
+               || tp->selector != DNS_TLSA_SELECTOR_SUBJECTPUBLICKEYINFO)
+               rpk_compat = 0;
            continue;
        }
        if (ret == 0) {
@@ -818,6 +842,9 @@ int     tls_dane_enable(TLS_SESS_STATE *TLScontext)
        tls_print_errors();
        return (-1);
     }
+    if (rpk_compat)
+       tls_enable_server_rpk(NULL, ssl);
+
     return (usable);
 }
 
@@ -964,8 +991,9 @@ void    tls_dane_log(TLS_SESS_STATE *TLScontext)
 {
     static VSTRING *top;
     static VSTRING *bot;
+    X509   *mcert = 0;
     EVP_PKEY *mspki = 0;
-    int     depth = SSL_get0_dane_authority(TLScontext->con, NULL, &mspki);
+    int     depth = SSL_get0_dane_authority(TLScontext->con, &mcert, &mspki);
     uint8_t u, s, m;
     unsigned const char *data;
     size_t  dlen;
@@ -994,22 +1022,27 @@ void    tls_dane_log(TLS_SESS_STATE *TLScontext)
        hex_encode(top, (char *) data, dlen);
     }
 
-    switch (TLScontext->level) {
-    case TLS_LEV_FPRINT:
+    if (TLScontext->level == TLS_LEV_FPRINT) {
        msg_info("%s: Matched fingerprint: %s%s%s", TLScontext->namaddr,
                 STR(top), dlen > MAX_DUMP_BYTES ? "..." : "",
                 dlen > MAX_DUMP_BYTES ? STR(bot) : "");
        return;
-
-    default:
-       msg_info("%s: Matched DANE %s at depth %d: %u %u %u %s%s%s",
-                TLScontext->namaddr, mspki ?
-                "TA public key verified certificate" : depth ?
-                "TA certificate" : "EE certificate", depth, u, s, m,
+    }
+#if OPENSSL_VERSION_PREREQ(3,2)
+    if (SSL_get0_peer_rpk(TLScontext->con) != NULL) {
+       msg_info("%s: Matched DANE raw public key: %u %u %u %s%s%s",
+                TLScontext->namaddr, u, s, m,
                 STR(top), dlen > MAX_DUMP_BYTES ? "..." : "",
                 dlen > MAX_DUMP_BYTES ? STR(bot) : "");
        return;
     }
+#endif
+    msg_info("%s: Matched DANE %s at depth %d: %u %u %u %s%s%s",
+            TLScontext->namaddr, mspki ?
+            "TA public key verified certificate" : depth ?
+            "TA certificate" : "EE certificate", depth, u, s, m,
+            STR(top), dlen > MAX_DUMP_BYTES ? "..." : "",
+            dlen > MAX_DUMP_BYTES ? STR(bot) : "");
 }
 
 #ifdef TEST
index 39b5a5219299bbc3a1941ce41bbe0522b57e18a3..dc3f99e8eb6dcf007cfeb9f9bbd8183e1e2a32c8 100644 (file)
@@ -24,7 +24,7 @@
 /*     const char *mdalg;
 /*
 /*     char    *tls_pkey_fprint(peercert, mdalg)
-/*     X509    *peercert;
+/*     EVP_PKEY *peerpkey;
 /*     const char *mdalg;
 /* DESCRIPTION
 /*     tls_digest_byname() constructs, and optionally returns, an EVP_MD_CTX
@@ -48,8 +48,6 @@
 /*
 /*     tls_pkey_fprint() returns a public-key fingerprint; in all
 /*     other respects the function behaves as tls_cert_fprint().
-/*     The var_tls_bc_pkey_fprint variable enables an incorrect
-/*     algorithm that was used in Postfix versions 2.9.[0-5].
 /*     The return value is dynamically allocated with mymalloc(),
 /*     and the caller must eventually free it with myfree().
 /*
@@ -274,6 +272,9 @@ char   *tls_serverid_digest(TLS_SESS_STATE *TLScontext,
     CHECK_OK_AND_DIGEST_CHARS(mdctx, props->protocols);
     CHECK_OK_AND_DIGEST_CHARS(mdctx, ciphers);
 
+    /* Just in case we make this destination-policy specific */
+    CHECK_OK_AND_DIGEST_OBJECT(mdctx, &props->enable_rpk);
+
     /*
      * Ensure separation of caches for sessions where DANE trust
      * configuration succeeded from those where it did not.  The latter
@@ -398,38 +399,24 @@ char   *tls_cert_fprint(X509 *peercert, const char *mdalg)
     return (result);
 }
 
-/* tls_pkey_fprint - extract public key fingerprint from certificate */
+/* tls_pkey_fprint - extract public key fingerprint */
 
-char   *tls_pkey_fprint(X509 *peercert, const char *mdalg)
+char   *tls_pkey_fprint(EVP_PKEY *peerpkey, const char *mdalg)
 {
-    if (var_tls_bc_pkey_fprint) {
-       const char *myname = "tls_pkey_fprint";
-       ASN1_BIT_STRING *key;
-       char   *result;
-
-       key = X509_get0_pubkey_bitstr(peercert);
-       if (key == 0)
-           msg_fatal("%s: error extracting legacy public-key fingerprint: %m",
-                     myname);
-
-       result = tls_data_fprint(key->data, key->length, mdalg);
-       return (result);
-    } else {
-       int     len;
-       unsigned char *buf;
-       unsigned char *buf2;
-       char   *result;
-
-       len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(peercert), NULL);
-       buf2 = buf = mymalloc(len);
-       i2d_X509_PUBKEY(X509_get_X509_PUBKEY(peercert), &buf2);
-       if (buf2 - buf != len)
-           msg_panic("i2d_X509_PUBKEY invalid result length");
-
-       result = tls_data_fprint(buf, len, mdalg);
-       myfree(buf);
-       return (result);
-    }
+    int     len;
+    unsigned char *buf;
+    unsigned char *buf2;
+    char   *result;
+
+    len = i2d_PUBKEY(peerpkey, NULL);
+    buf2 = buf = mymalloc(len);
+    i2d_PUBKEY(peerpkey, &buf2);
+    if (buf2 - buf != len)
+       msg_panic("i2d_PUBKEY invalid result length");
+
+    result = tls_data_fprint(buf, len, mdalg);
+    myfree(buf);
+    return (result);
 }
 
 #endif
index c7712b8d09feeb239694a6bb123dc7cd060d69ca..cf8f6fa709008b20c06a16b0740c1613e6fb12c4 100644 (file)
 /*
 /*     const EVP_MD *tls_validate_digest(dgst)
 /*     const char *dgst;
+/*
+/*     void tls_enable_client_rpk(ctx, ssl)
+/*     SSL_CTX *ctx;
+/*     SSL     *ssl;
+/*
+/*     void tls_enable_server_rpk(ctx, ssl)
+/*     SSL_CTX *ctx;
+/*     SSL     *ssl;
 /* DESCRIPTION
 /*     This module implements public and internal routines that
 /*     support the TLS client and server.
 /*
 /*     tls_validate_digest() returns a static handle for the named
 /*     digest algorithm, or NULL on error.
+/*
+/*     tls_enable_client_rpk() enables the use of raw public keys in the
+/*     client to server direction, if supported by the OpenSSL library.
+/*
+/*     tls_enable_server_rpk() enables the use of raw public keys in the
+/*     server to client direction, if supported by the OpenSSL library.
 /* LICENSE
 /* .ad
 /* .fi
@@ -1028,7 +1042,6 @@ void    tls_get_signature_params(TLS_SESS_STATE *TLScontext)
     SSL    *ssl = TLScontext->con;
     int     srvr = SSL_is_server(ssl);
     EVP_PKEY *dh_pkey = 0;
-    X509   *local_cert;
     EVP_PKEY *local_pkey = 0;
     X509   *peer_cert;
     EVP_PKEY *peer_pkey = 0;
@@ -1060,18 +1073,23 @@ void    tls_get_signature_params(TLS_SESS_STATE *TLScontext)
     }
 
     /*
-     * On the client end, the certificate may be preset, but not used, so we
+     * On the client end, the certificate may be present, 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))
-       local_cert = SSL_get_certificate(ssl);
-    else
-       local_cert = 0;
-
+    if (srvr || SSL_get_signature_nid(ssl, &nid)) {
+       local_pkey = SSL_get_privatekey(ssl);
+    }
     /* Signature algorithms for the local end of the connection */
-    if (local_cert) {
-       local_pkey = X509_get0_pubkey(local_cert);
+    if (local_pkey) {
+#if OPENSSL_VERSION_PREREQ(3,2)
+       if (srvr)
+           TLScontext->stoc_rpk = TLSEXT_cert_type_rpk ==
+               SSL_get_negotiated_server_cert_type(ssl);
+       else
+           TLScontext->ctos_rpk = TLSEXT_cert_type_rpk ==
+               SSL_get_negotiated_client_cert_type(ssl);
+#endif
 
        /*
         * Override the built-in name for the "ECDSA" algorithms OID, with
@@ -1097,7 +1115,6 @@ void    tls_get_signature_params(TLS_SESS_STATE *TLScontext)
                break;
 #endif
            }
-           /* No X509_free(local_cert) */
        }
 
        /*
@@ -1107,9 +1124,26 @@ void    tls_get_signature_params(TLS_SESS_STATE *TLScontext)
        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 ((peer_cert = TLS_PEEK_PEER_CERT(ssl)) != 0) {
+    peer_cert = TLS_PEEK_PEER_CERT(ssl);
+    if (peer_cert != 0) {
        peer_pkey = X509_get0_pubkey(peer_cert);
+    }
+#if OPENSSL_VERSION_PREREQ(3,2)
+    else {
+       peer_pkey = SSL_get0_peer_rpk(ssl);
+    }
+#endif
+
+    /* Signature algorithms for the peer end of the connection */
+    if (peer_pkey != 0) {
+#if OPENSSL_VERSION_PREREQ(3,2)
+       if (srvr)
+           TLScontext->ctos_rpk = TLSEXT_cert_type_rpk ==
+               SSL_get_negotiated_client_cert_type(ssl);
+       else
+           TLScontext->stoc_rpk = TLSEXT_cert_type_rpk ==
+               SSL_get_negotiated_server_cert_type(ssl);
+#endif
 
        /*
         * Override the built-in name for the "ECDSA" algorithms OID, with
@@ -1144,8 +1178,9 @@ void    tls_get_signature_params(TLS_SESS_STATE *TLScontext)
        if (SSL_get_peer_signature_nid(ssl, &nid) && nid != NID_undef)
            peer_sig_dgst = OBJ_nid2sn(nid);
 
-       TLS_FREE_PEER_CERT(peer_cert);
     }
+    TLS_FREE_PEER_CERT(peer_cert);
+
     if (kex_name) {
        TLScontext->kex_name = mystrdup(kex_name);
        TLScontext->kex_curve = kex_curve;
@@ -1180,7 +1215,7 @@ void    tls_log_summary(TLS_ROLE role, TLS_USAGE usage, TLS_SESS_STATE *ctx)
      */
     vstring_sprintf(msg, "%s TLS connection %s %s %s%s%s: %s"
                    " with cipher %s (%d/%d bits)",
-                   !TLS_CERT_IS_PRESENT(ctx) ? "Anonymous" :
+                   !TLS_CRED_IS_PRESENT(ctx) ? "Anonymous" :
                    TLS_CERT_IS_SECURED(ctx) ? "Verified" :
                    TLS_CERT_IS_TRUSTED(ctx) ? "Trusted" : "Untrusted",
                    usage == TLS_USAGE_NEW ? "established" : "reused",
@@ -1199,9 +1234,13 @@ void    tls_log_summary(TLS_ROLE role, TLS_USAGE usage, TLS_SESS_STATE *ctx)
        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);
+           vstring_sprintf_append(msg, " (%s%s)", ctx->srvr_sig_curve,
+                                  ctx->stoc_rpk ? " raw public key" : "");
        else if (ctx->srvr_sig_bits > 0)
-           vstring_sprintf_append(msg, " (%d bits)", ctx->srvr_sig_bits);
+           vstring_sprintf_append(msg, " (%d bit%s)", ctx->srvr_sig_bits,
+                                  ctx->stoc_rpk ? " raw public key" : "s");
+       else if (ctx->stoc_rpk)
+           vstring_sprintf_append(msg, " (raw public key)");
        if (ctx->srvr_sig_dgst && *ctx->srvr_sig_dgst)
            vstring_sprintf_append(msg, " server-digest %s",
                                   ctx->srvr_sig_dgst);
@@ -1210,9 +1249,13 @@ void    tls_log_summary(TLS_ROLE role, TLS_USAGE usage, TLS_SESS_STATE *ctx)
        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);
+           vstring_sprintf_append(msg, " (%s%s)", ctx->clnt_sig_curve,
+                                  ctx->ctos_rpk ? " raw public key" : "");
        else if (ctx->clnt_sig_bits > 0)
-           vstring_sprintf_append(msg, " (%d bits)", ctx->clnt_sig_bits);
+           vstring_sprintf_append(msg, " (%d bit%s)", ctx->clnt_sig_bits,
+                                  ctx->ctos_rpk ? " raw public key" : "s");
+       else if (ctx->ctos_rpk)
+           vstring_sprintf_append(msg, " (raw public key)");
        if (ctx->clnt_sig_dgst && *ctx->clnt_sig_dgst)
            vstring_sprintf_append(msg, " client-digest %s",
                                   ctx->clnt_sig_dgst);
@@ -1288,6 +1331,8 @@ TLS_SESS_STATE *tls_alloc_sess_context(int log_mask, const char *namaddr)
     TLScontext->cipher_name = 0;
     TLScontext->kex_name = 0;
     TLScontext->kex_curve = 0;
+    TLScontext->ctos_rpk = 0;
+    TLScontext->stoc_rpk = 0;
     TLScontext->clnt_sig_name = 0;
     TLScontext->clnt_sig_curve = 0;
     TLScontext->clnt_sig_dgst = 0;
@@ -1702,6 +1747,52 @@ const EVP_MD *tls_validate_digest(const char *dgst)
     return md_alg;
 }
 
+void    tls_enable_client_rpk(SSL_CTX *ctx, SSL *ssl)
+{
+#if OPENSSL_VERSION_PREREQ(3,2)
+    static int warned = 0;
+    static const unsigned char cert_types_rpk[] = {
+       TLSEXT_cert_type_rpk,
+       TLSEXT_cert_type_x509
+    };
+
+    if ((ctx && !SSL_CTX_set1_client_cert_type(ctx, cert_types_rpk,
+                                              sizeof(cert_types_rpk))) ||
+       (ssl && !SSL_set1_client_cert_type(ssl, cert_types_rpk,
+                                          sizeof(cert_types_rpk)))) {
+       if (warned++) {
+           ERR_clear_error();
+           return;
+       }
+       msg_warn("Failed to enable client to server raw public key support");
+       tls_print_errors();
+    }
+#endif
+}
+
+void    tls_enable_server_rpk(SSL_CTX *ctx, SSL *ssl)
+{
+#if OPENSSL_VERSION_PREREQ(3,2)
+    static int warned = 0;
+    static const unsigned char cert_types_rpk[] = {
+       TLSEXT_cert_type_rpk,
+       TLSEXT_cert_type_x509
+    };
+
+    if ((ctx && !SSL_CTX_set1_server_cert_type(ctx, cert_types_rpk,
+                                              sizeof(cert_types_rpk))) ||
+       (ssl && !SSL_set1_server_cert_type(ssl, cert_types_rpk,
+                                          sizeof(cert_types_rpk)))) {
+       if (warned++) {
+           ERR_clear_error();
+           return;
+       }
+       msg_warn("Failed to enable server to client raw public key support");
+       tls_print_errors();
+    }
+#endif
+}
+
 #else
 
  /*
index 9bb94769ac8f0f93ea803990b06f465199fdb655..65286398f2d526166e3d25ba364d68c2bb99e216 100644 (file)
@@ -108,11 +108,11 @@ extern VSTREAM *tls_proxy_open(const char *, int, VSTREAM *, const char *,
     ((props)->a12), ((props)->a13), ((props)->a14))
 
 #define TLS_PROXY_CLIENT_START_PROPS(props, a1, a2, a3, a4, a5, a6, a7, a8, \
-    a9, a10, a11, a12, a13, a14) \
+    a9, a10, a11, a12, a13, a14, a15) \
     (((props)->a1), ((props)->a2), ((props)->a3), \
     ((props)->a4), ((props)->a5), ((props)->a6), ((props)->a7), \
     ((props)->a8), ((props)->a9), ((props)->a10), ((props)->a11), \
-    ((props)->a12), ((props)->a13), ((props)->a14))
+    ((props)->a12), ((props)->a13), ((props)->a14), ((props)->a15))
 
 extern TLS_SESS_STATE *tls_proxy_context_receive(VSTREAM *);
 extern void tls_proxy_context_free(TLS_SESS_STATE *);
@@ -170,6 +170,8 @@ extern void tls_proxy_server_start_free(TLS_SERVER_START_PROPS *);
 #define TLS_ATTR_KEX_NAME      "key_exchange"
 #define TLS_ATTR_KEX_CURVE     "key_exchange_curve"
 #define TLS_ATTR_KEX_BITS      "key_exchange_bits"
+#define TLS_ATTR_CTOS_RPK      "ctos_rpk"
+#define TLS_ATTR_STOC_RPK      "stoc_rpk"
 #define TLS_ATTR_CLNT_SIG_NAME "clnt_signature"
 #define TLS_ATTR_CLNT_SIG_CURVE        "clnt_signature_curve"
 #define TLS_ATTR_CLNT_SIG_BITS "clnt_signature_bits"
@@ -239,6 +241,7 @@ extern void tls_proxy_server_start_free(TLS_SERVER_START_PROPS *);
   * TLS_CLIENT_START_PROPS attributes.
   */
 #define TLS_ATTR_TIMEOUT       "timeout"
+#define TLS_ATTR_ENABLE_RPK    "enable_rpk"
 #define TLS_ATTR_TLS_LEVEL     "tls_level"
 #define TLS_ATTR_NEXTHOP       "nexthop"
 #define TLS_ATTR_HOST          "host"
index 1cc5778ebb1061d34a0639e2b525463e91c299e5..81e50b9246fff80a6952e7646c5119b9f36e603d 100644 (file)
@@ -257,6 +257,7 @@ int     tls_proxy_client_start_print(ATTR_PRINT_COMMON_FN print_fn,
 
     ret = print_fn(fp, flags | ATTR_FLAG_MORE,
                   SEND_ATTR_INT(TLS_ATTR_TIMEOUT, props->timeout),
+                  SEND_ATTR_INT(TLS_ATTR_ENABLE_RPK, props->enable_rpk),
                   SEND_ATTR_INT(TLS_ATTR_TLS_LEVEL, props->tls_level),
                   SEND_ATTR_STR(TLS_ATTR_NEXTHOP,
                                 STRING_OR_EMPTY(props->nexthop)),
index a69388c962bb020ea99a064b2c52c84387a02538..d36cf4d7e593a6314f6e12ae9f53d746ac87b971 100644 (file)
@@ -451,6 +451,7 @@ int     tls_proxy_client_start_scan(ATTR_SCAN_COMMON_FN scan_fn, VSTREAM *fp,
     props->dane = 0;                           /* scan_fn may return early */
     ret = scan_fn(fp, flags | ATTR_FLAG_MORE,
                  RECV_ATTR_INT(TLS_ATTR_TIMEOUT, &props->timeout),
+                 RECV_ATTR_INT(TLS_ATTR_ENABLE_RPK, &props->enable_rpk),
                  RECV_ATTR_INT(TLS_ATTR_TLS_LEVEL, &props->tls_level),
                  RECV_ATTR_STR(TLS_ATTR_NEXTHOP, nexthop),
                  RECV_ATTR_STR(TLS_ATTR_HOST, host),
@@ -478,7 +479,7 @@ int     tls_proxy_client_start_scan(ATTR_SCAN_COMMON_FN scan_fn, VSTREAM *fp,
     props->cipher_grade = vstring_export(cipher_grade);
     props->cipher_exclusions = vstring_export(cipher_exclusions);
     props->mdalg = vstring_export(mdalg);
-    ret = (ret == 14 ? 1 : -1);
+    ret = (ret == 15 ? 1 : -1);
     if (ret != 1) {
        tls_proxy_client_start_free(props);
        props = 0;
index 04123cb023e9f865a200684aae3bae896be5a47a..930410a4661c5cda5db5fba9be4095ce65e81c13 100644 (file)
@@ -88,6 +88,10 @@ int     tls_proxy_context_print(ATTR_PRINT_COMMON_FN print_fn, VSTREAM *fp,
                                 STRING_OR_EMPTY(tp->kex_curve)),
                   SEND_ATTR_INT(TLS_ATTR_KEX_BITS,
                                 tp->kex_bits),
+                  SEND_ATTR_INT(TLS_ATTR_CTOS_RPK,
+                                tp->ctos_rpk),
+                  SEND_ATTR_INT(TLS_ATTR_STOC_RPK,
+                                tp->stoc_rpk),
                   SEND_ATTR_STR(TLS_ATTR_CLNT_SIG_NAME,
                                 STRING_OR_EMPTY(tp->clnt_sig_name)),
                   SEND_ATTR_STR(TLS_ATTR_CLNT_SIG_CURVE,
index 1d463ada93375a767c2f8ef9d4a32a07fac9b737..48aaff627460759975e4a8ce5891794823bb51a7 100644 (file)
@@ -113,6 +113,8 @@ int     tls_proxy_context_scan(ATTR_SCAN_COMMON_FN scan_fn, VSTREAM *fp,
                  RECV_ATTR_STR(TLS_ATTR_KEX_NAME, kex_name),
                  RECV_ATTR_STR(TLS_ATTR_KEX_CURVE, kex_curve),
                  RECV_ATTR_INT(TLS_ATTR_KEX_BITS, &tls_context->kex_bits),
+                 RECV_ATTR_INT(TLS_ATTR_CTOS_RPK, &tls_context->ctos_rpk),
+                 RECV_ATTR_INT(TLS_ATTR_STOC_RPK, &tls_context->stoc_rpk),
                  RECV_ATTR_STR(TLS_ATTR_CLNT_SIG_NAME, clnt_sig_name),
                  RECV_ATTR_STR(TLS_ATTR_CLNT_SIG_CURVE, clnt_sig_curve),
         RECV_ATTR_INT(TLS_ATTR_CLNT_SIG_BITS, &tls_context->clnt_sig_bits),
@@ -139,7 +141,7 @@ int     tls_proxy_context_scan(ATTR_SCAN_COMMON_FN scan_fn, VSTREAM *fp,
     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);
-    ret = (ret == 22 ? 1 : -1);
+    ret = (ret == 24 ? 1 : -1);
     if (ret != 1) {
        tls_proxy_context_free(tls_context);
        tls_context = 0;
index 262cda95272cae6d5b3c57e90844327fb4dc69cc..88b33264208122b727b9979682aad1e2e898de7f 100644 (file)
@@ -62,8 +62,8 @@
 /*     available as:
 /* .IP TLScontext->peer_status
 /*     A bitmask field that records the status of the peer certificate
-/*     verification. One or more of TLS_CERT_FLAG_PRESENT and
-/*     TLS_CERT_FLAG_TRUSTED.
+/*     verification. One or more of TLS_CRED_FLAG_CERT, TLS_CRED_FLAG_RPK
+/*     and TLS_CERT_FLAG_TRUSTED.
 /* .IP TLScontext->peer_CN
 /*     Extracted CommonName of the peer, or zero-length string
 /*     when information could not be extracted.
@@ -636,6 +636,13 @@ TLS_APPL_STATE *tls_server_init(const TLS_SERVER_INIT_PROPS *props)
        return (0);
     }
 
+    /*
+     * Always support server->client raw public keys, if they're good enough
+     * for the client, they're good enough for us.
+     */
+    tls_enable_server_rpk(server_ctx, NULL);
+    tls_enable_server_rpk(sni_ctx, NULL);
+
     /*
      * Upref and share the cert store.  Sadly we can't yet use
      * SSL_CTX_set1_cert_store(3) which was added in OpenSSL 1.1.0.
@@ -865,11 +872,19 @@ TLS_SESS_STATE *tls_server_start(const TLS_SERVER_START_PROPS *props)
        tls_free_context(TLScontext);
        return (0);
     }
-#ifdef SSL_SECOP_PEER
-    /* When authenticating the peer, use 80-bit plus OpenSSL security level */
+
+    /*
+     * When encryption is mandatory use the 80-bit plus OpenSSL security level.
+     */
     if (props->requirecert)
        SSL_set_security_level(TLScontext->con, 1);
-#endif
+
+    /*
+     * Also enable client->server raw public keys, provided we're not
+     * interested in client certificate fingerprints.
+     */
+    if (props->enable_rpk)
+       tls_enable_client_rpk(NULL, TLScontext->con);
 
     /*
      * Before really starting anything, try to seed the PRNG a little bit
@@ -946,6 +961,7 @@ TLS_SESS_STATE *tls_server_post_accept(TLS_SESS_STATE *TLScontext)
 {
     const SSL_CIPHER *cipher;
     X509   *peer;
+    EVP_PKEY *pkey = 0;
     char    buf[CCERT_BUFSIZ];
 
     /* Turn off packet dump if only dumping the handshake */
@@ -966,8 +982,17 @@ TLS_SESS_STATE *tls_server_post_accept(TLS_SESS_STATE *TLScontext)
      * actual information. We want to save it for later use.
      */
     peer = TLS_PEEK_PEER_CERT(TLScontext->con);
+    if (peer) {
+       pkey = X509_get0_pubkey(peer);
+    }
+#if OPENSSL_VERSION_PREREQ(3,2)
+    else {
+       pkey = SSL_get0_peer_rpk(TLScontext->con);
+    }
+#endif
+
     if (peer != NULL) {
-       TLScontext->peer_status |= TLS_CERT_FLAG_PRESENT;
+       TLScontext->peer_status |= TLS_CRED_FLAG_CERT;
        if (SSL_get_verify_result(TLScontext->con) == X509_V_OK)
            TLScontext->peer_status |= TLS_CERT_FLAG_TRUSTED;
 
@@ -981,16 +1006,23 @@ TLS_SESS_STATE *tls_server_post_accept(TLS_SESS_STATE *TLScontext)
        }
        TLScontext->peer_CN = tls_peer_CN(peer, TLScontext);
        TLScontext->issuer_CN = tls_issuer_CN(peer, TLScontext);
-       TLScontext->peer_cert_fprint = tls_cert_fprint(peer, TLScontext->mdalg);
-       TLScontext->peer_pkey_fprint = tls_pkey_fprint(peer, TLScontext->mdalg);
+       TLScontext->peer_cert_fprint =
+           tls_cert_fprint(peer, TLScontext->mdalg);
+       TLScontext->peer_pkey_fprint =
+           tls_pkey_fprint(pkey, TLScontext->mdalg);
 
        if (TLScontext->log_mask & (TLS_LOG_VERBOSE | TLS_LOG_PEERCERT)) {
-           msg_info("%s: subject_CN=%s, issuer=%s, fingerprint=%s"
-                    ", pkey_fingerprint=%s",
+           msg_info("%s: subject_CN=%s, issuer=%s%s%s%s%s",
                     TLScontext->namaddr,
                     TLScontext->peer_CN, TLScontext->issuer_CN,
-                    TLScontext->peer_cert_fprint,
-                    TLScontext->peer_pkey_fprint);
+                    *TLScontext->peer_cert_fprint ?
+                    ", cert fingerprint=" : "",
+                    *TLScontext->peer_cert_fprint ?
+                    TLScontext->peer_cert_fprint : "",
+                    *TLScontext->peer_pkey_fprint ?
+                    ", pkey fingerprint=" : "",
+                    *TLScontext->peer_pkey_fprint ?
+                    TLScontext->peer_pkey_fprint : "");
        }
        TLS_FREE_PEER_CERT(peer);
 
@@ -1013,7 +1045,22 @@ TLS_SESS_STATE *tls_server_post_accept(TLS_SESS_STATE *TLScontext)
        TLScontext->peer_CN = mystrdup("");
        TLScontext->issuer_CN = mystrdup("");
        TLScontext->peer_cert_fprint = mystrdup("");
-       TLScontext->peer_pkey_fprint = mystrdup("");
+       if (!pkey) {
+           TLScontext->peer_pkey_fprint = mystrdup("");
+       } else {
+
+           /*
+            * Raw public keys don't involve CA trust, and we don't have a
+            * way to associate DANE TLSA RRs with clients just yet, we just
+            * make the fingerprint available to the access(5) layer.
+            */
+            TLScontext->peer_status |= TLS_CRED_FLAG_RPK;
+           TLScontext->peer_pkey_fprint =
+               tls_pkey_fprint(pkey, TLScontext->mdalg);
+           if (TLScontext->log_mask & (TLS_LOG_VERBOSE | TLS_LOG_PEERCERT))
+               msg_info("%s: raw public key fingerprint=%s",
+                        TLScontext->namaddr, TLScontext->peer_pkey_fprint);
+       }
     }
 
     /*
index f32f32b4a71690f0d5c38d36eaecad31a5bc980f..c643f18382ba2407a066ccf9b28fc1b3ba997e84 100644 (file)
@@ -144,6 +144,7 @@ int     tls_verify_certificate_callback(int ok, X509_STORE_CTX *ctx)
     int     depth;
     SSL    *con;
     TLS_SESS_STATE *TLScontext;
+    EVP_PKEY *rpk = 0;
 
     /* May be NULL as of OpenSSL 1.0, thanks for the API change! */
     cert = X509_STORE_CTX_get_current_cert(ctx);
@@ -151,6 +152,10 @@ int     tls_verify_certificate_callback(int ok, X509_STORE_CTX *ctx)
     con = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
     TLScontext = SSL_get_ex_data(con, TLScontext_index);
     depth = X509_STORE_CTX_get_error_depth(ctx);
+#if OPENSSL_VERSION_PREREQ(3,2)
+    if (cert == 0)
+       rpk = X509_STORE_CTX_get0_rpk(ctx);
+#endif
 
     /*
      * Transient failures to load the (DNS or synthetic TLSA) trust settings
@@ -174,12 +179,15 @@ int     tls_verify_certificate_callback(int ok, X509_STORE_CTX *ctx)
        update_error_state(TLScontext, depth, cert, err);
 
     if (TLScontext->log_mask & TLS_LOG_VERBOSE) {
-       if (cert)
+       if (cert) {
            X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf));
-       else
-           strcpy(buf, "<unknown>");
-       msg_info("%s: depth=%d verify=%d subject=%s",
-                TLScontext->namaddr, depth, ok, printable(buf, '?'));
+           msg_info("%s: depth=%d verify=%d subject=%s",
+                    TLScontext->namaddr, depth, ok, printable(buf, '?'));
+       } else if (rpk) {
+           msg_info("%s: verify=%d raw public key", TLScontext->namaddr, ok);
+       } else {
+           msg_info("%s: depth=%d verify=%d", TLScontext->namaddr, depth, ok);
+       }
     }
     return (1);
 }
index 7c0d8147b4411420d3b52177ad1354ad30b6cb54..0ebf52c68ec81444690f8813a58504b551fb5835 100644 (file)
 /* .IP "\fBtlsproxy_tls_chain_files ($smtpd_tls_chain_files)\fR"
 /*     Files with the Postfix \fBtlsproxy\fR(8) server keys and certificate
 /*     chains in PEM format.
+/* .PP
+/*     Available in Postfix version 3.9 and later:
+/* .IP "\fBtlsproxy_tls_enable_rpk ($smtpd_tls_enable_rpk)\fR"
+/*     Request that remote SMTP clients send an RFC7250 raw public key
+/*     instead of an X.509 certificate, when asking or requiring client
+/*     authentication.
 /* STARTTLS CLIENT CONTROLS
 /* .ad
 /* .fi
@@ -436,6 +442,7 @@ bool    var_smtpd_use_tls;
 bool    var_smtpd_enforce_tls;
 bool    var_smtpd_tls_ask_ccert;
 bool    var_smtpd_tls_req_ccert;
+bool    var_smtpd_tls_enable_rpk;
 bool    var_smtpd_tls_set_sessid;
 char   *var_smtpd_relay_ccerts;
 char   *var_smtpd_tls_chain_files;
@@ -465,6 +472,7 @@ bool    var_tlsp_use_tls;
 bool    var_tlsp_enforce_tls;
 bool    var_tlsp_tls_ask_ccert;
 bool    var_tlsp_tls_req_ccert;
+bool    var_tlsp_tls_enable_rpk;
 bool    var_tlsp_tls_set_sessid;
 char   *var_tlsp_tls_chain_files;
 char   *var_tlsp_tls_cert_file;
@@ -1081,6 +1089,7 @@ static int tlsp_server_start_pre_handshake(TLSP_STATE *state)
                         timeout = 0,           /* unused */
                         requirecert = (var_tlsp_tls_req_ccert
                                        && var_tlsp_enforce_tls),
+                        enable_rpk = var_tlsp_tls_enable_rpk,
                         serverid = state->server_id,
                         namaddr = state->remote_endpt,
                         cipher_grade = cipher_grade,
@@ -1827,6 +1836,7 @@ int     main(int argc, char **argv)
        VAR_SMTPD_ENFORCE_TLS, DEF_SMTPD_ENFORCE_TLS, &var_smtpd_enforce_tls,
        VAR_SMTPD_TLS_ACERT, DEF_SMTPD_TLS_ACERT, &var_smtpd_tls_ask_ccert,
        VAR_SMTPD_TLS_RCERT, DEF_SMTPD_TLS_RCERT, &var_smtpd_tls_req_ccert,
+       VAR_SMTPD_TLS_ENABLE_RPK, DEF_SMTPD_TLS_ENABLE_RPK, &var_smtpd_tls_enable_rpk,
        VAR_SMTPD_TLS_SET_SESSID, DEF_SMTPD_TLS_SET_SESSID, &var_smtpd_tls_set_sessid,
        VAR_SMTP_USE_TLS, DEF_SMTP_USE_TLS, &var_smtp_use_tls,
        VAR_SMTP_ENFORCE_TLS, DEF_SMTP_ENFORCE_TLS, &var_smtp_enforce_tls,
@@ -1837,6 +1847,7 @@ int     main(int argc, char **argv)
        VAR_TLSP_ENFORCE_TLS, DEF_TLSP_ENFORCE_TLS, &var_tlsp_enforce_tls,
        VAR_TLSP_TLS_ACERT, DEF_TLSP_TLS_ACERT, &var_tlsp_tls_ask_ccert,
        VAR_TLSP_TLS_RCERT, DEF_TLSP_TLS_RCERT, &var_tlsp_tls_req_ccert,
+       VAR_TLSP_TLS_ENABLE_RPK, DEF_TLSP_TLS_ENABLE_RPK, &var_tlsp_tls_enable_rpk,
        VAR_TLSP_TLS_SET_SESSID, DEF_TLSP_TLS_SET_SESSID, &var_tlsp_tls_set_sessid,
        VAR_TLSP_CLNT_USE_TLS, DEF_TLSP_CLNT_USE_TLS, &var_tlsp_clnt_use_tls,
        VAR_TLSP_CLNT_ENFORCE_TLS, DEF_TLSP_CLNT_ENFORCE_TLS, &var_tlsp_clnt_enforce_tls,