Re: [Uta] Eric Rescorla's Discuss on draft-ietf-uta-mta-sts-17: (with DISCUSS and COMMENT)

Viktor Dukhovni <viktor@dukhovni.org> Fri, 04 May 2018 05:19 UTC

Return-Path: <viktor@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 64587127342; Thu, 3 May 2018 22:19:50 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -4.201
X-Spam-Level:
X-Spam-Status: No, score=-4.201 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, SPF_PASS=-0.001] 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 8zzs8WT9PTCS; Thu, 3 May 2018 22:19:48 -0700 (PDT)
Received: from mournblade.imrryr.org (mournblade.imrryr.org [108.5.242.66]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id E272E124BAC; Thu, 3 May 2018 22:19:47 -0700 (PDT)
Received: by mournblade.imrryr.org (Postfix, from userid 1034) id 9FDF57A330A; Fri, 4 May 2018 05:19:46 +0000 (UTC)
Date: Fri, 04 May 2018 05:19:46 +0000
From: Viktor Dukhovni <viktor@dukhovni.org>
To: uta@ietf.org
Cc: The IESG <iesg@ietf.org>, draft-ietf-uta-mta-sts@ietf.org, uta-chairs@ietf.org
Message-ID: <20180504051945.GS3322@mournblade.imrryr.org>
References: <152539648489.11713.7895583526344282774.idtracker@ietfa.amsl.com>
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Disposition: inline
In-Reply-To: <152539648489.11713.7895583526344282774.idtracker@ietfa.amsl.com>
User-Agent: Mutt/1.7.2 (2016-11-26)
Archived-At: <https://mailarchive.ietf.org/arch/msg/uta/uL2VIaN27rXzeWBfDoobBv0vJao>
Subject: Re: [Uta] Eric Rescorla's Discuss on draft-ietf-uta-mta-sts-17: (with DISCUSS and COMMENT)
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: Fri, 04 May 2018 05:19:50 -0000

On Thu, May 03, 2018 at 06:14:44PM -0700, Eric Rescorla wrote:

[ Though I am not one of the authors, I was actively involved in
  the evolution of the draft.  Some its features are in part are
  result of my influence, both based on prior work with DANE, and
  as a potential implementor of the specification in a future
  Postfix release.  The comments below may shed light on the
  rationale for some of the choices reflected in the draft. ]

> S 3.2.
> >      o  "max_age": Max lifetime of the policy (plain-text non-negative
> >         integer seconds, maximum value of 31557600).  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.
> 
> What if I receive a policy with a lifetime less than that remaining in
> the previously received policy

Good question, I don't recall any discussion of this.  Since the
policy might be "none", canceling the cached policy entirely, it
seems logical to allow the new "max_age" to end before the old
"max_age".  I hope the authors agree.

> >      indicates that mail for this domain might be handled by any MX with a
> >      certificate valid for a host at "mail.example.com" or "example.net".
> >      Valid patterns can be either fully specified names ("example.com") or
> >      suffixes (".example.net") matching the right-hand parts of a server's
> >      identity; the latter case are distinguished by a leading period.  If
> 
> How many labels can be prepended here. Is "a.b.c.example.net" valid?

Another good observation, I am having trouble finding normative
text in the body of the draft that makes this clear.  IIRC, as
evidenced by a comment in the Appendix B pseudo-code, the intention
is to support just a single label:

  // Leading '.' matches a wildcard against the first part, i.e.
  // .example.com matches x.example.com but not x.y.example.com.

The text should be more clear, unless we both missed where this is
specified.

> S 10.2.
> >      mode, to allow clean MTA-STS removal, as described in Section 8.3.)
> >   
> >      Resistance to downgrade attacks of this nature--due to the ability to
> >      authoritatively determine "lack of a record" even for non-
> >      participating recipients--is a feature of DANE, due to its use of
> >      DNSSEC for policy discovery.
> 
> I'm surprised that you don't note that if you use DNSSEC (and the
> client validates), you are in general resistant to this form of
> attack.

With MTA-STS, hardening the DNS is not enough, the policy does not
take effect until it is first verified to work.  First-contact
lookup failures for the TXT record do not cause email to be deferred.

Indeed with MTA-STS, some MTAs may do *background* policy retrieval,
and the first few messages to a destination may go out unprotected.

For a downgrade-resistant mechanism, a domain can use DANE SMTP
(RFC7672). If the destination domain is signed, the first step in
that direction is already taken.

> >      2.  That at least one of the policy's "mx" patterns matches at least
> >          one of the identities presented in the MX's X.509 certificate, as
> >          described in "MX Certificate Validation".
> 
> IMPORTANT: This doesn't seem like quite what you want. Consider
> the case where the STS policy has:
>
>    mx: mx1.example.com
>    mx: mx2.example.com
>
> And I then attempt to send to mx1.example.com, send SNI=mx1.example.com,
> and get a cert that is only valid for mx2.example.com.

[ This was discussed extensively in the WG.  This part of the design
  is substantially my doing... ]

An MiTM attacker can direct the traffic to any MX host of his choice
by blocking TCP SYNs, or generating RST packets for traffic to all
the other MXs, causing the desired MX host to be the only one the
client can reach.  Also, for a large fraction of domains a wildcard
certificate, or a certificate with all the names is used.  For
example, below are the SANs from the certificate for gmail.com:

    DNS:mx.google.com
    DNS:alt1.aspmx.l.google.com
    DNS:alt1.gmail-smtp-in.l.google.com
    DNS:alt1.gmr-smtp-in.l.google.com
    DNS:alt2.aspmx.l.google.com
    DNS:alt2.gmail-smtp-in.l.google.com
    DNS:alt2.gmr-smtp-in.l.google.com
    DNS:alt3.aspmx.l.google.com
    DNS:alt3.gmail-smtp-in.l.google.com
    DNS:alt3.gmr-smtp-in.l.google.com
    DNS:alt4.aspmx.l.google.com
    DNS:alt4.gmail-smtp-in.l.google.com
    DNS:alt4.gmr-smtp-in.l.google.com
    DNS:aspmx.l.google.com
    DNS:aspmx2.googlemail.com
    DNS:aspmx3.googlemail.com
    DNS:aspmx4.googlemail.com
    DNS:aspmx5.googlemail.com
    DNS:gmail-smtp-in.l.google.com
    DNS:gmr-mx.google.com
    DNS:gmr-smtp-in.l.google.com

So trying to make sure that you're reaching the MX host
you think you're reaching and not one of the others is
largely pointless and often a lost cause.

> This seems like it's extremely undesirable and might be the basis for some kind of attack.

See above.  If the MX host has a certificate that matches the
client's SNI, it'll may return it, even if that's one of the other
MX hosts.  If it does not return a matching certificate, the "attack"
fails.

> I think the rule you want is:
> 
>  You look up the MXes in the DNS.
>  You select one that must match one of the things in the mx list in the STS

Preemptive removal of non-matching MX hosts is liable (in sloppy
implementations, and I expect enough to be sloppy) to cause routing
loops, when a backup MX host, not after removing itself early from
the list, fails to eliminate worse priority MX hosts.  It also
requires all sites to duplicate MX host updates from DNS into the
STS policy, disallowing the "low-maintenance" ".example.com" form.

>  You then connect to the MX and provide its SNI.
>  The certificate must match the domain you provided in the SNI

The WG considered this issue, and in the end accepted the current
design.  I hope this helps.

> >      The certificate MAY be checked for revocation via the Online
> >      Certificate Status Protocol (OCSP) [RFC6960], certificate revocation
> >      lists (CRLs), or some other mechanism.
> 
> Why is revocation only MAY?

Looking at e.g. the X.509 certificate for Gmail, I don't see a
"must staple OCSP" extension.  So we get no meaningful security
from OCSP stapling, an attacker who misappropriates the private
key will not staple OCSP responses.

I have no intention of building an HTTP client into the Postfix
SMTP client to download CRLs from various CAs that remote peers
might use.  Full CRLs might at least be cached on a per-CA basis,
while per-certificate OCSP requires a connection to the CA for each
new certificate.

I'm afraid I see too little value in CRLs to consider CRL support
in Postfix.  The OS platforms that Postfix runs on don't deliver
a full intermediate CA store with regular updates of the associated
CRLs.  Doing CRL management in each application is IMHO impractical.

In short, I have not implemented and don't expect to implement CRL
support in Postfix.

[ I'll endeavour to leave further comments on the above topics to
  the authors.  I might still chime in if a new topic comes up
  where I'm one of the culprits responsible for the current text. ]
 
-- 
	Viktor.

P.S. (digression on what I'd like to see replace CRLs)

If we want effective revocation for WebPKI, let's fully automate
certificate roll-over (ACME is a good start) and drive down the
maximum certificate lifetimes to be short enough that most likely
you'd have a hard time noticing that your key is compromised any
faster, and getting the CA to revoke the cert, getting sites that
cache CRLs to get fresh CRLs, ...

I'd like to see one to two week certificate lifetimes, and X.509
stacks that can reload the certificates and keys without restarting
the server.