[Uta] MTA-STS-03 review

Viktor Dukhovni <ietf-dane@dukhovni.org> Wed, 22 March 2017 05:04 UTC

Return-Path: <ietf-dane@dukhovni.org>
X-Original-To: uta@ietfa.amsl.com
Delivered-To: uta@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id D87F6129459 for <uta@ietfa.amsl.com>; Tue, 21 Mar 2017 22:04:51 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.9
X-Spam-Level:
X-Spam-Status: No, score=-1.9 tagged_above=-999 required=5 tests=[BAYES_00=-1.9] autolearn=ham autolearn_force=no
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id UONQBC3h8bGx for <uta@ietfa.amsl.com>; Tue, 21 Mar 2017 22:04:48 -0700 (PDT)
Received: from mournblade.imrryr.org (mournblade.imrryr.org [108.5.242.66]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id D93D412944E for <uta@ietf.org>; Tue, 21 Mar 2017 22:04:47 -0700 (PDT)
Received: from vpro.lan (cpe-74-71-8-253.nyc.res.rr.com [74.71.8.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mournblade.imrryr.org (Postfix) with ESMTPSA id 978BB7A32F1 for <uta@ietf.org>; Wed, 22 Mar 2017 05:04:46 +0000 (UTC) (envelope-from ietf-dane@dukhovni.org)
From: Viktor Dukhovni <ietf-dane@dukhovni.org>
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Reply-To: uta@ietf.org
Mime-Version: 1.0 (Mac OS X Mail 10.2 \(3259\))
Message-Id: <4C0807DA-4852-4DAC-80ED-8A25371CFFAA@dukhovni.org>
Date: Wed, 22 Mar 2017 01:04:45 -0400
To: uta@ietf.org
X-Mailer: Apple Mail (2.3259)
Archived-At: <https://mailarchive.ietf.org/arch/msg/uta/BmQXxR9AS7Gbmnuro-uAYz5g0VA>
Subject: [Uta] MTA-STS-03 review
X-BeenThere: uta@ietf.org
X-Mailman-Version: 2.1.22
Precedence: list
List-Id: UTA working group mailing list <uta.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/uta>, <mailto:uta-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/uta/>
List-Post: <mailto:uta@ietf.org>
List-Help: <mailto:uta-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/uta>, <mailto:uta-request@ietf.org?subject=subscribe>
X-List-Received-Date: Wed, 22 Mar 2017 05:04:52 -0000

[ I've pasted in the entire draft, and "quoted" it as though it
  were a post to trim an reply to. ]

>               SMTP MTA Strict Transport Security (MTA-STS)
>                        draft-ietf-uta-mta-sts-03
> 
> Abstract
> 
>    SMTP Mail Transfer Agent Strict Transport Security (SMTP STS) is a
>    mechanism enabling mail service providers to declare their ability to
>    receive TLS-secured connections and an expected validity of
>    certificates presented by their MX hosts, and to specify whether
>    sending SMTP servers should refuse to deliver to MX hosts that do not
>    offer TLS with a trusted server certificate.

In the abstract I think that "TLS-secured" already covers certificate
validity (which makes for a clumsy insertion into the text anyway).
Also instead of "TLS-secured connections" say "TLS-secure SMTP connections".

See https://www.rfc-editor.org/materials/abbrev.expansion.txt for the
list of common IETF acronyms, and which are sufficiently widely used
to not need to be expanded on first use.  Thus SMTP and ESMTP are fine
with expansion, but apparently we've not yet reached similar familiarity
with TLS. :-)

> 1.  Introduction
> 
>    The STARTTLS extension to SMTP [RFC3207] allows SMTP clients and
>    hosts to negotiate the use of a TLS channel for secure mail
>    transmission.

I would drop "secure" above, or replace it with "encrypted".


>    While such _opportunistic_ encryption protocols provide a high

While "_" may work as italics in MarkDown, you'll need to change all
these to RFC XML (where IIRC <i>...</i> may be supported, but don't
take my word for it, check).

More importantly, you've made quite a leap here from talking about
RFC 3207, which merely defines an SMTP extension mechanism, to assuming
that the reader knows how the extension is typically used.  It also
important to recall that opportunistic security (as defined in RFC7435)
subsumes both MTA best-effort unauthenticated encryption, and the new
opportunistically authenticated DANE and STS use-cases.  With DANE and
STS transmission is protected only when and as receiving system publishes
the requisite policy records.  DANE offers stronger downgrade protection,
at the cost of requiring DNSSEC to achieve that goal.

>    barrier against passive man-in-the-middle traffic interception,

therefore the "passive-only" protection is a feature of unauthenticated
opportunistic security, as practiced by most MTAs at present.

>    This document defines a mechanism for recipient domains to publish
>    policies specifying:
> 
>    o  whether MTAs sending mail to this domain can expect TLS support
> 
>    o  expected validity of server certificates presented by the domain's
>       MX hosts

It seems to me that STS does not provide any means to signal
unauthenticated TLS support.  And so, as in the abstract, the
above two bullets are really just one, "WebPKI TLS security".

> 1.1.  Terminology
> 
>    We also define the following terms for further use in this document:
> 
>    o  STS Policy: A committment by the Policy Domain to support PKIX
>       authenticated TLS for the specified MX hosts.

Which I think confirms my point about "authenticated TLS" as the
only available commitment.

>    o  Policy Domain: The domain for which an STS Policy is defined.
>       (For example, when sending mail to "alice@example.com", the policy
>       domain is "example.com".)

Perhaps this should mention that more generally this is the nexthop
domain for SMTP delivery, and when mail routing is preƫmpted by
by explicit relays via local policy, the Policy domain is the
domain name of the explicit relay (prior to any MX lookups if
applicable).

>    o  Policy Authentication: Authentication of the STS policy retrieved
>       for a recipient domain by the sender.

This definition seems all too circular.  What does it actually mean?

> 2.  Related Technologies
> 
>    The DANE TLSA record [RFC7672] is similar, in that DANE is also
>    designed to upgrade opportunistic, unauthenticated encryption into
>    required, authenticated encryption.

Opportunistic DANE TLS upgrades unauthenticated encryption or even
cleartext delivery to downgrade-resistant authenticated TLS.  (Side
note, not for the draft, for actually non-opportunistic TLS see
Jim Fenton's REQUIRETLS proposal).  STS aims to do the same, but
without requiring TLS at the cost of losing some downgrade protection.

>  DANE requires DNSSEC [RFC4033]
>    for authentication; the mechanism described here instead relies on
>    certificate authorities (CAs) and does not require DNSSEC.  For a
>    thorough discussion of this trade-off, see the section _Security_
>    _Considerations_.

The Security Considerations section (once again this is not MarkDown)
will need to properly discuss the downgrade exposure of STS on first
contact, and this trade-off probably should be mentioned here up-front.

>    In addition, SMTP STS provides an optional report-only mode, enabling
>    soft deployments to detect policy failures.

It is easy to define a couple of new "certificate usage" code-points
for DANE that similarly signal "soft-fail" (with reporting).  Would
the group strongly support a draft along those lines?  I am not sure
that a merely "tamper-evident" operating mode is a good idea as a
persistent operating state, and I think that the ability to have
one or more (backup, i.e. worse preference) MX hosts without TLSA
records adequately addresses the need for incremental deployment.

> 3.  Policy Discovery
> 
>    To discover if a recipient domain implements MTA-STS, a sender need
>    only resolve a single TXT record.  To see if an updated policy is
>    available for a domain for which the sender has a previously cached
>    policy, the sender need only check the TXT record's version "id"
>    against the cached value.

Given earlier discussion on the list, while new "id" values can give
expedited signals to refresh the policy, it may be appropriate here,
(but perhaps later in the document as you see fit) to describe a
recommended approach to proactively refresh policies prior to their
pending expiration, this reduces the probability of "gaps" in policy
coverage if the remote HTTPS service is unavailable just as a policy
is expiring.

In practice (say in Postfix, if/when STS is implemented) I wouldn't
go looking through the cache for policies to refresh except when
delivering mail to the destination in question.  I don't want the
cache to become a roach motel for policies to destinations I never
again send mail to.  If communication with a destination ceases
completely, it is not unreasonable to let its STS policy simply
age out.  Google et. al. may of course choose indefinite data
retension (data retentiveness is Google's business), but for
SOHO and enterprise MTAs, the above may be more appropriate.

> 3.2.  MTA-STS Policies
> 
>    This JSON object contains the following key/value pairs:
> 
>    o  "version": (plain-text, required).  Currently only "STSv1" is
>       supported.
> 
>    o  "mode": (plain-text, required).  Either "enforce" or "report",
>       indicating the expected behavior of a sending MTA in the case of a
>       policy validation failure.
> 
>    o  "max_age": Max lifetime of the policy (plain-text non-negative
>       integer seconds, required).  Well-behaved clients SHOULD cache a
>       policy for up to this value from last policy fetch time.  To
>       mitigate the risks of attacks at policy refresh time, it is
>       expected that this value typically be in the range of weeks or
>       greater.

A more comprehensive mitigation for attacks "at policy refresh time"
would entail not just a long lifetime, but proactive refresh as mentioned
above.

>    o  "mx": MX patterns (list of plain-text MX match strings, required).
>       One or more patterns matching the expected MX for this domain.
>       For example, "["*.example.com", "*.example.net"]" indicates that
>       mail for this domain might be handled by any MX with a hostname at
>       "example.com" or "example.net".  Valid patterns can be either
>       hostname literals (e.g. "mx1.example.com") or wildcard matches, so
>       long as the wildcard occupies the full left-most label in the
>       pattern.  (Thus "*.example.com" is valid but "mx*.example.com" is
>       not.)

Here, as discussed on the list, serious consideration should be given
to changing the semantics from validating the MX hostname to specifying
the names allowed in the server's certificate.  This simplifies MX processing
(which remains unmodified) and merely changes the conditions under which an
MX host is considered suitably authenticated per the policy.

Which, for example, allows the MX hosts to share a single certificate
with the destination domain (and not the MX hostname) as its DNS SAN.
If the policy lists that (shared) name as what's expected in the certificate,
then authentication succeeds when the MX host's certificate matches one of
the allowed names.

It should be made clear that the names here are always in A-label form
and not U-label form (as they also are in DNS names in certificates).

Furthermore, I think that using "*.example.com" in what are essentially
(rfc6125) reference identifiers creates confusion with similar-looking, but
semantically distinct wildcard names in certificates.  My suggestion was
".example.com" for sub-domain matching, with the policy optionally specifying
whether only single-label prefixes are accepted, or whether in fact multi-label
prefixes are also valid.

>    An example JSON policy is as below:
> 
>                       {
>                         "version": "STSv1",
>                         "mode": "enforce",
>                         "mx": ["*.mail.example.com"],
>                         "max_age": 123456
>                       }

FWIW, I would have chosen something less fancy than JSON for
what is clearly a simple array of attribute/value pairs. ESMTP
already encodes such optional A/V pairs as space separated lists
of attr=value with xtext encoding as needed (it is not needed for
any plausible value of the above attributes).

We're not going to add a JSON decoder to the Postfix SMTP client,
but if this specification retains JSON, then the code that does
background policy retrieval will need to transform JSON into
something more friendly to traditional C-based MTA implementations.

> 4.  Policy Validation

Are we validating the policy or using the policy to authenticate
the MX host?  I think the name of this section is suboptimal.

>    When sending to an MX at a domain for which the sender has a valid
>    and non-expired SMTP MTA-STS policy, a sending MTA honoring SMTP STS
>    MUST validate:

s/validate/check/ or /ensure/.

>    1.  That the recipient MX matches the "mx" pattern from the recipient
>        domain's policy.

See above, perhaps "mx" becomes "san" and the check is deferred until
it is time to verify the host's certificate.

>    2.  That the recipient MX supports STARTTLS and offers a valid PKIX
>        based TLS certificate.

Here, it would be prudent to mention rfc6125, and be explicit about
the acceptable wildcard patterns in that certificate.  See, for example:

   https://tools.ietf.org/html/rfc7672#section-3.2.3

which limits certificate wildcards to the entire first label only.  I
would like to avoid supporting more general wildcards in new
specifications.

>    This section does not dictate the behavior of sending MTAs when
>    policies fail to validate; in particular, validation failures of
>    policies which specify "report" mode MUST NOT be interpreted as
>    delivery failures, as described in the section _Policy_
>    _Application_.

The first sentence is unfortunate, you are in fact specifying behaviour,
in the very next sentence.  It might be better to add a forward-reference
to a section that provides a detailed explanation and not start with a
disclaimer.

> 4.1.  MX Matching
> 
>    When delivering mail for the Policy Domain to a recipient MX host,
>    the sender validates the MX match against the "mx" pattern from the
>    applied policy.  The semantics for these patterns are those found in
>    section 6.4 of [RFC6125].

Assuming this text survives, replace:

 	validates the MX match against the "mx" pattern

with something like

	ensures that the MX host name is consistent with the "mx"
	property of the STS policy (only matching MX hosts are
	used in delivery attempts).

The reference to rfc6125 is rather unfortunate here, since it defines
semantics for presented identifiers, not reference identifiers.

> 4.2.  MX Certificate Validation
> 
>    The certificate presented by the receiving MX MUST be valid for the
>    MX hostname and chain to a root CA that is trusted by the sending
>    MTA.  The certificate MUST have a CN or SAN matching the MX hostname
>    (as described in [RFC6125]) and be non-expired.

Here, if the proposal to switch from "mx" to "san" is taken up, the
peer certificate is no longer restricted to authenticate the MX hostname,
rather, one its presented identifiers needs to match one of the reference
identifiers fro the "san" policy attribute.  Either way some discussion
is appropriate of how to perform matching when both the reference and
the presented identifiers are "wildcards".

> 5.  Policy Application

This is an appropriate target for the afore-mentioned forward-reference.

>    When sending to an MX at a domain for which the sender has a valid,
>    non-expired STS policy, a sending MTA honoring SMTP STS applies the
>    result of a policy validation one of two ways, depending on the value
>    of the policy "mode" field:
> 
>    1.  "report": In this mode, sending MTAs merely send a report (as
>        described in the TLSRPT specification (TODO: add ref)) indicating
>        policy application failures.
> 
>    2.  "enforce": In this mode, sending MTAs treat STS policy failures
>        as a mail delivery error, and MUST NOT deliver the message to
>        this host.

We should not confuse "delivery error" with "authentication failure".
When one MX host fails authentication, the next MX host should be
tried.  And, I think it should be mentioned that if all the MX
hosts (that the sender is willing to try) fail authentication, the
message should be deferred, not bounced.

>    When a message fails to deliver due to an "enforce" policy, a
>    compliant MTA MUST check for the presence of an updated policy at the
>    Policy Domain before permanently failing to deliver the message.
>    This allows implementing domains to update long-lived policies on the
>    fly.

This seems to suggest the contrary, i.e. that it might be appropriate
to bounce on policy failure when a more fresh policy still fails.
However certificate problems (expiration most typically) are transient,
and a receiving system operator should/may notice the problem before
outstanding messages expire and bounce.  So I would urge implementors
to queue, rather than bounce, on authentication failure.

> 5.1.  MX Preference

This section would go if a switch from "mx" to "san" takes place.

> 5.2.  Policy Application Control Flow
> 
>    An example control flow for a compliant sender consists of the
>    following steps:

Step 0:  If the sending MTA is DANE-capable, the destination is
DNSSEC signed, and one or more of the MX hosts have DANE TLSA
records, then DANE TLSA preempts STS (more downgrade-resistant,
works on first contact, ...).

This is another reason to avoid STS-based MX filtering, with DNSSEC
signed destinations the security of the MX records is sufficiently
established, and we need to be able to proceed with DANE MX by MX,
using STS policy only for MX hosts with no TLSA records.

>    1.  Check for a cached policy whose time-since-fetch has not exceeded
>        its "max_age".  If none exists, attempt to fetch a new policy.
>        (Optionally, sending MTAs may unconditionally check for a new
>        policy at this step.)

Is "attempt to fetch" well understood at this point?  The attempt only
happens if the DNS TXT record is in place...

>    2.  Filter candidate MXs against the current policy.

See "san" vs. "mx" issue above.  Also proceed with non-STS delivery
absent any policy.

>    3.  If no candidate MXs are valid and the policy mode is "enforce",
>        temporarily fail the message.  (Otherwise, generate a failure
>        report but deliver as though MTA STS were not implemented.)

Ditto.

>    4.  For each candidate MX, in order of MX priority, attempt to
>        deliver the message, enforcing STARTTLS and the MX host's PKIX
>        certificate validation.

Well, no so much enforcing as performing, authentication may be allowed
to fail in "report" mode.  And of course only if there is an STS policy
to use.

>    5.  Upon message retries, a message MAY be permanently failed
>        following first checking for the presence of a new policy (as
>        indicated by the "id" field in the "mta-sts" TXT record).

I think this is a mistake.  Please do not turn transient errors into
permanent failures.

> 6.1.  Policy Updates
> 
>    Updating the policy requires that the owner make changes in two
>    places: the "mta-sts" TXT record in the Policy Domain's DNS zone and
>    at the corresponding HTTPS endpoint.  In the case where the HTTPS
>    endpoint has been updated but the TXT record has not yet been,
>    senders will not know there is a new policy released and may thus
>    continue to use old, previously cached versions.  Recipients should
>    thus expect a policy will continue to be used by senders until both
>    the HTTPS and TXT endpoints are updated and the TXT record's TTL has
>    passed.

The lifetime could be longer.  Some MTAs may initiate *background* refresh
of unexpired policies after the DNS TXT record is found to have changed,
which may not happen until the first message to the destination is sent
after that change, and *that* message may well go out based on the already
cached policy while the refresh is in process.  If the policy no longer
matches reality, the message may be deferred, and would perhaps succeed
on retry with a more current policy.

So the TXT record will not guarantee refresh in any particular timeframe.
If no mail is sent to the destination, the policy may expire unused despite
the TXT record change.

> 8.  Security Considerations
> 
>    Since we use DNS TXT records for policy discovery, an attacker who is
>    able to block DNS responses can suppress the discovery of an STS
>    Policy, making the Policy Domain appear not to have an STS Policy.
>    The sender policy cache is designed to resist this attack.

Well, not "resist" so much as reduce the effectiveness, since it will
now only be effective on first contact, or perhaps when no mail is sent
to the destination for a long time and the cached policy expired.

>    We additionally consider the Denial of Service risk posed by an
>    attacker who can modify the DNS records for a victim domain.  Absent
>    SMTP STS, such an attacker can cause a sending MTA to cache invalid
>    MX records for a long TTL.  With SMTP STS, the attacker can
>    additionally advertise a new, long-"max_age" SMTP STS policy with
>    "mx" constraints that validate the malicious MX record, causing
>    senders to cache the policy and refuse to deliver messages once the
>    victim has resecured the MX records.

Many DNS resolvers have sensible upper-bounds on record TTLs.  It the
attacker can obtain a certificate for the victim domain, they may
indeed inject a long-lived policy, but the TXT record affords the
victim the opportunity of recovery.  This paragraph needs work.

Finally, some discussion is appropriate of the fact that given weaker
downgrade-resistance of STS viz. DANE, implementations that support
both should apply DANE first and STS only in its absence.  Indeed with
the MX RRset validated via DNSSEC the "mx" policy element is not really
needed to prevent MX record forgery, however that depends on the outcome
of the "mx" vs. "san" discussion.

There should probably be a recommendation that sending systems implement
DANE in addition to STS.  It is much easier to use a validating resolver
than to sign one's own domain, and so the barrier to option of outbound
DANE is significantly lower.  I'll have some additional implementation
news to report shortly...

> 10.1.  Example 1
> 
>    The owner of "example.com" wishes to begin using STS with a policy
>    that will solicit reports from receivers without affecting how the
>    messages are processed, in order to verify the identity of MXs that
>    handle mail for "example.com", confirm that TLS is correctly used,
>    and ensure that certificates presented by the recipient MX validate.
> 
>    STS policy indicator TXT RR:
> 
>         mta-sts.example.com.  IN TXT "v=STSv1; id=20160831085700Z;"
> 
>    STS Policy JSON served as the response body at [1]
> 
>               {
>                 "version": "STSv1",
>                 "mode": "report",
>                 "mx": ["mx1.example.com", "mx2.example.com"],
>                 "max_age": 123456
>               }

Note, the "max_age" here is barely over a day, which is not consistent with
the recommended policy lifetimes.  Even "report" policies should probably
have better downgrade protection through longer lifetimes (say a week or more).

> 11.  Appendix 2: Message delivery pseudocode
> 
>    Below is pseudocode demonstrating the logic of a complaint sending
>    MTA.  This implements the "two-pass" approach, first attempting
>    delivery with a newly fetched policy (if present) before falling back
>    to a cached policy (if present).

Should that be "complaint" or "compliant"? :-)  I would expect that
sane implementations will use cached policies first, and only both
refreshes based on TXT record changes or refresh timers, with updates
in the background.  Synchronous updates of policy at message delivery
time are exceedingly unappealing at least to me.

> func certMatches(connection, mx) {
>   // Return if the server certificate from "connection" matches the "mx" host.

This could use a detailed discussion of what "matches" means, or a
back-reference to a section that does.  Covering wildcard use in
either or both of the reference and presented identifiers, and
possible additional text if "mx" becomes "san".

> func getMxsForPolicy(domain, policy) {
>   // Sort the MXs by priority, filtering out those which are invalid according
>   // to "policy".
> }

[ "mx" vs. "san" ]

> func tryGetNewPolicy(domain) {
>   // Check for an MTA STS TXT record for "domain" in DNS, and return the
>   // indicated policy (or a local cache of the unvalidated policy).
> }

The DNS lookup may succeed, and the HTTPS lookup may tempfail, what
happens in that case?  What happens with an authenticated 404 HTTPS
response?  Let's avoid "unvalidated" here, or else avoid its use
in the context of "peer authentication".

> func cachePolicy(domain, policy) {
>   // Store "policy" as the cached policy for "domain".
> }

Along with the policy one should generally store the time
at which it was last retrieved, and the time of any unsuccessful
refresh attempts since then.  This supports both eventual 
expiration, and proactive refresh, with multiple retries, as
the policy approaches expiration.

> func tryMxAccordingTo(message, mx, policy) {
>   connection := connect(mx)
>   if !connection {
>     return false  // Can't connect to the MX so it's not an STS error.
>   }
>   status := !(tryStartTls(mx, &connection) && certMatches(connection, mx))
>   status = true

What's happening with "status" here?  I think the first assignment goes...

>   if !tryStartTls(mx, &connection) {
>     status = false
>     reportError(E_NO_VALID_TLS)
>   } else if certMatches(connection, mx) {

Missing negation?

>     status = false
>     reportError(E_CERT_MISMATCH)
>   }
>   if status || !isEnforce(policy) {
>     return tryDeliverMail(connection, message)

There are potential complications when an MX host
accepts a proper subset of the envelope recipients
and tempfails the rest, or fails for reasons unrelated
to policy, ... So a simple boolean here is not enough.
Delivery to backup MX hosts continues so long as
recipients that are neither delivered nor permanently
rejected remain.  STS policy failure is just one way
that (all the) recipients may remain unresolved.

>   }
>   return false
> }
> 
> func tryWithPolicy(message, domain, policy) {
>   mxes := getMxesForPolicy(domain, policy)
>   if mxs is empty {
>     reportError(E_NO_VALID_MXES)
>   }
>   for mx in mxes {
>     if tryMxAccordingTo(message, mx, policy) {
>       return true
>     }
>   }
>   return false
> }
> 
> func handleMessage(message) {
>   domain := ... // domain part after '@' from recipient
>   oldPolicy := tryGetCachedPolicy(domain)
>   newPolicy := tryGetNewPolicy(domain)

In practice, the cached policie's DNS id will be compared with
the current DNS value and if identical, no new policy will be
fetched.  If different, a new policy should be fetched, but
perhaps in the backround, with delivery continuing per the
cached policy.

>   if newPolicy {
>     cachePolicy(domain, newPolicy)
>     oldPolicy = newPolicy
>   }
>   if oldPolicy {
>     return tryWithPolicy(message, oldPolicy)
>   }
>   // There is no policy or there's a new policy that did not work.
>   // Try to deliver the message normally (i.e. without STS).
> }

-- 
	Viktor.