Re: [Acme] On multiple CAs and contact-based recovery

Richard Barnes <rlb@ipv.sx> Thu, 24 March 2016 15:46 UTC

Return-Path: <rlb@ipv.sx>
X-Original-To: acme@ietfa.amsl.com
Delivered-To: acme@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 68AB812DC18 for <acme@ietfa.amsl.com>; Thu, 24 Mar 2016 08:46:57 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.589
X-Spam-Level:
X-Spam-Status: No, score=-2.589 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, T_FILL_THIS_FORM_SHORT=0.01] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=ipv-sx.20150623.gappssmtp.com
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 N4SeL3gntLta for <acme@ietfa.amsl.com>; Thu, 24 Mar 2016 08:46:53 -0700 (PDT)
Received: from mail-vk0-x22b.google.com (mail-vk0-x22b.google.com [IPv6:2607:f8b0:400c:c05::22b]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 45E1B12DC0E for <acme@ietf.org>; Thu, 24 Mar 2016 08:33:19 -0700 (PDT)
Received: by mail-vk0-x22b.google.com with SMTP id k1so63860885vkb.0 for <acme@ietf.org>; Thu, 24 Mar 2016 08:33:19 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ipv-sx.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc; bh=EKNLuEmPMxcMQdD5PT+LuYNn+0tHYLaOnsPCjsRi28o=; b=m8olOU4IY05JEvvkPWXtMev5JDL8Q4giQrdd41gwDbQAB4dEqLQbYoIKTcQBgwZ6sx IDzAmbUGUz9tecDEHAXtI92ROvdQHNmQy8cLYGotWiov1nMKoIuKDFTjYBNcLsmuZt/5 Vr7h68ZXvbpkFl4H1XPxa3983xhIVFWhR6goKadEgTGocQfKvVPF5OvqBn2jzDYneMay 4o1i84B89RLg+bLtA2miTmCn4tqSSi/zZXb1NP6rQlh5vKAdF8e3+B4AEvmA0zuhOAcj ZaqAieTICSSN3m8171rq6GzmJ+acQ/WlVzUDvOZqb2psctlnYHYadxskjSb6I+NGHTp8 R65g==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc; bh=EKNLuEmPMxcMQdD5PT+LuYNn+0tHYLaOnsPCjsRi28o=; b=H5FYQ/OcFcm6t5WFpRGd6pGHymJ15R8ebaE+Kw5pCku5XaYac66ORATa9w7yM2Bauw XZHqCxjYOWJUQ/+LHjMifQ5D93YzSiHZDl1oleYPpN9S4Y543w512kn0XVR405lcWF3U 9VGQJxuVHZdStE+WlyOX7BxvvW/XJUwTUoLcD6MzHZBaIwsRIQ4vzBDloh4TQGIYzdla CB+aMluLLd5hJMwtGSdtzAjH86URGMAO1kVZgfnTegDYCsdQtLUA9TUn+bIhj4YKCU0g xj/RqhJivCYyvTTyiB+sBttoIvhYM/9H7uY1OUToV0+CDUS8Crg6Fk+PjDP48eRl4xbp SQtQ==
X-Gm-Message-State: AD7BkJJ4We7I+1WHLpKVuFoF3+FBdb/UmVc6pGlDYGebdFk8WEVsti/Q6o8eC4iLbUT43YJ1V/Uv2kaeVLEV9w==
MIME-Version: 1.0
X-Received: by 10.159.36.39 with SMTP id 36mr4314679uaq.16.1458833598177; Thu, 24 Mar 2016 08:33:18 -0700 (PDT)
Received: by 10.31.151.85 with HTTP; Thu, 24 Mar 2016 08:33:18 -0700 (PDT)
In-Reply-To: <B594A7FA-1F8B-489C-8A7D-328BCD60C79A@inria.fr>
References: <B594A7FA-1F8B-489C-8A7D-328BCD60C79A@inria.fr>
Date: Thu, 24 Mar 2016 11:33:18 -0400
Message-ID: <CAL02cgQPDogLc=JAjC8BD6tQkWDU4XNCmofm1H6BaCAJ3j9n-A@mail.gmail.com>
From: Richard Barnes <rlb@ipv.sx>
To: Karthik Bhargavan <karthikeyan.bhargavan@inria.fr>
Content-Type: multipart/alternative; boundary="001a11352768681ba9052ecd2a47"
Archived-At: <http://mailarchive.ietf.org/arch/msg/acme/97w4A8WExNy8JpSMzttUnZPgdh0>
Cc: "acme@ietf.org" <acme@ietf.org>
Subject: Re: [Acme] On multiple CAs and contact-based recovery
X-BeenThere: acme@ietf.org
X-Mailman-Version: 2.1.17
Precedence: list
List-Id: Automated Certificate Management Environment <acme.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/acme>, <mailto:acme-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/acme/>
List-Post: <mailto:acme@ietf.org>
List-Help: <mailto:acme-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/acme>, <mailto:acme-request@ietf.org?subject=subscribe>
X-List-Received-Date: Thu, 24 Mar 2016 15:46:57 -0000

Hey Karthik,

Thanks so much for this analysis.  Couple of comments inline.

On Wed, Mar 23, 2016 at 6:33 PM, Karthik Bhargavan <
karthikeyan.bhargavan@inria.fr> wrote:

> Dear All,
>
> Recently, after being asked by Josh Aas, I wrote a formal model of the
> ACME protocol
> in ProVerif and analyzed it for various properties. I am still in the
> process of cleaning
> up the model and writing up a proper report, but with the next IETF being
> so close,
> here’re some early comments that may be useful for the group to discuss.
> These notes are inspired by my model of the -01 draft and some of it may
> be out of date.
>
> Summary:
> -------------
>
> Against a classic symbolic protocol adversary, ACME achieves most of its
> security goals.
> Notably, it prevents many more attacks than traditional CAs through its
> use of client signatures,
> and specifically through the strong binding between the client’s account
> key and the validated domain.
>
> However, there are two scenarios of concern that should be studied more
> carefully:
> (1) if an ACME client supports multiple CAs or ACME servers and one of
> them may be malicious or compromised;
> (2) if the contact channel is used for account recovery or, in the future,
> if an email channel is used for domain validation.
>
> In both these cases, the protocol as it is currently specified (in -01) is
> not strong enough to provide the desired guarantees,
> but the good news is that it can be easily strengthened to prevent abuse.
>
> We describe 3 issues, in increasing order of seriousness. The first two
> are closely related and may have been discussed
> in the list before. Issue 3 seems to be new and should probably be
> considered an attack on the stated goals of the ACME -01 spec.
>
> Model:
> ---------
>
> Our model consists of four kinds of principals:
> - Domain Owners (who can answer domain validation challenges)
> - ACME clients (who own account keys)
> - ACME servers (who own HTTPS certificates acceptable to ACME clients)
> - CAs (who own CA signing certificates)
>
> An ACME client can talk to any number of ACME servers over three kinds of
> channels:
>
> - HTTPS channels, which are treated as server-authenticated
> request-response channels
>   That is: anybody can send a request but only the server can read it,
>      only the server can send a response,
> and furthermore only the client who sent the request can read the response.
>

You might want to consider one additional nuance here.  The threat model
we're considering includes the ability for the CA to use a CDN that
terminates TLS.  So this particular entity is able to forge responses from
the server and block messages to the server.  (And of course, it can act as
a client if it wants to.)  That is the reason, for example, that the
keyAuthorization includes the account key being authorized, so that the
intermediary can't swap tokens to cause a domain holder to authorize its
own key pair.  I have pretty good confidence that we're OK in this model,
but the attacks can be subtle, so some modeling would be really helpful.


> - DNS/HTTPS/SNI validation channels, which are treated as
> sender-authenticated asynchronous channels
>   That is:  only the domain owner(s) can write on the channel, but
> anybody can read it
>
> - Contact/Email channels, which are treated as receiver-authenticated
> asynchronous channels
>   That is: anybody can write messages on the channel, but only the domain
> owner(s) can read it.
>
> In our model, we can experiment with the compromise of various
> combinations of principals.
> When a principal is compromised, all the channels they control become
> available to the adversary.
> For example, if an ACME HTTPS server is malicious or compromised, then its
>  HTTPS certificate
> signing key is known to the adversary, and consequently the ACME channel
> is compromised.
>
> The ACME spec informally assumes that at most one channel is compromised.
> In the rest of this email, we primarily consider compromise of the HTTPS
> channel
> between ACME clients and servers. We assume that the CA signing key and the
> honest client’s account key remains secure.
>
>
> Issue 1: No Mutual Authentication
> ---------------------------------------------
>
> The first issue already appears when we model the ACME HTTPS channel.
> We would have expected to model this as a mutually-authenticated channel
> since the client always signs its messages with the account key.
> However, although the client’s signature is tunnelled inside HTTPS, the
> signature itself is not “bound” to the HTTPS channel.
>
> This means that a message from an ACME client C to a server S
> can be forwarded by S to a different ACME server S’ (as long as S’ is also
> willing
> to accept C’s account key). This is a classic “credential forwarding”
> attack
> that is typically mitigated by channel binding.
>

I think we had considered this in some pre-WG analyses of ACME.  At that
point, it seemed that these risks were not so severe, since the attacker
cannot cause the CA to assert a name/key binding that the domain owner
didn't intent; he can only cause that binding to be asserted by a CA other
than the one that the client expects.

However, if there's an easy way to to fix this, is seems worth nailing down.



> For example, ACME could rely on the Token Binding specifications
> to securely bind the client signature to the underlying channel:
> https://datatracker.ietf.org/wg/tokbind/documents/
>
> Alternatively, all ACME messages could include the identity of the ACME
> server
> (this could, for example, be the SNI or server domain name that the ACME
> client
>  checks in the certificate when it connects to the server.)
>
> Either of these choices would make the HTTPS channel truly
> mutually-authenticated,
> simplifying a lot of the subsequent analysis.
>

Between these two options, I would be more attracted to the latter.  It's
always been a bit of a sore point that the request URI was not covered by
the client's signature, but to avoid the complexity of URL comparison, we
did the "resource" thing instead.  But maybe it makes sense to include the
whole URL after all.

OLD: { "resource": "new-reg", ... }
NEW: { "url": "https://example.com/acme/new-reg", ... }

Now that I look at that, there's one more additional property, in addition
to mitigating issues (1) and (2) here.  In cases where the server might
have multiple ACME services running (e.g., for different CAs), it prevents
a TLS MitM like a CDN from switching requests between them.

Do folks have opinions on whether we should do this?


>
> Issue 2: Certificate Request not bound to CA
> ------------------------------------------------------------
>
> Suppose an ACME client C connects to an ACME server S,
> and suppose that S’s HTTPS private key is compromised (or that S is
> malicious,
> or a man-in-the-middle has compromised the ACME channel or that the
> attacker has obtained a mis-issued certificate for S, or that the attacker
> has fooled the client into accepting its certificate).
>
> Now, the attacker can intercept authorization and certificate requests
> from C to S,
> and instead forward them to another ACME server S’. If S’ requests domain
> validation with a token T, the attacker forwards the token to the client,
> who
> will dutifully place its account key K and token T on its validation
> channel.
> S’ will check this token and accept the authorization and issue a
> certificate
> that the attacker can forward to C.
>
> This means that C asked for a certificate from S, but instead received a
> certificate from S’.
> Moreover, it may have paid S for the service, but S’ might have done it
> for free.
> This request forwarding “attack” can be prevented if C checks the
> certificate
> it gets to make sure it was issued by the expected CA. It can also be
> prevented
> by channel binding.
>
> An alternative mitigation would be for ACME to extend the Key
> Authorization string to include the CA’s identifier. E.g.:
>
> key-authz = token || '.' || base64url(JWK_Thumbprint(accountKey)) || ‘.’
> || base64url(server_id)
>

I think channel binding, in the form discussed above, is a more elegant
solution to this.  IIUC, with channel binding, the token would implicitly
tie in the server's identity, since it was issued in response to a request
for that server.


> Where server_id could be the ACME server’s SNI or certificate-hash.
> In other words, the domain validation challenge currently includes the
> client’s identity and the server’s challenge,
> but it does not include the server’s identity, allowing the challenge
> response to be used with multiple servers.
> This may well be a privacy feature (?) but if not then adding further
> context to the challenge response will add protection
> in the multiple CA use case
>
>
> Issue 3: Contact-based Recovery can be Hijacked
> -------------------------------------------------------------------
>
> The use of sender-authenticated channels in ACME (HTTPS/SNI/DNS) seems
> to  be relatively secure.
> However, more attention needs to be paid to the receiver-authenticated
> channels like email, because they are
> easy to get wrong. For example, if the ACME server (in some future draft)
> uses the website administrator’s email
> address to send the domain validation token, a naive implementation of
> this kind of challenge would be vulnerable to attack.
>
> In the -01 specification, the contact channel (typically email) is used
> for account recovery
> when the ACME client has forgotten its account key. We show how the
> careless
> use of this channel can be vulnerable to attack, and propose a
> countermeasure.
>
> Suppose an ACME client C issues an account recovery request for account A
> with a new key K to the ACME server S.
> A network attacker blocks this request and instead sends his own account
> recovery request for account A (pretending to be C)
> with his own key K’. The server S will then send C an email asking to
> click on a link.
> C will think this is a request in response to its own account recovery
> request and will click on it.
> S will think that C has confirmed account recovery and will transfer the
> account A to the attacker’s key K’.
>
> In the above attack, the attacker did not need to compromise the contact
> channel (or for that matter, the ACME channel).
> This seems to directly contradict the security considerations in 9.3,
> unless I am reading something wrong.
> The key observation here is that on receiver-authenticated channels (e.g.
> email) the receiver does not get to
> bind the token provided by the server with its own account key.
> Consequently, we need to add further checks.
>
> The email sent from S to C should contain a fresh token + C’s new account
> key (e.g. within a key-authz field)
> Instead of clicking on the link (out-of-band), C should cut and paste the
> token into the ACME client which
> can first check that the account key provided by the server matches the
> one in the ACME client and only
> then does it send the token back to the server.
>
> Alternatively, if we don’t want to change ACME too much, we must require
> that the email recipient at C
> visually confirms that the account key (thumbprint) provided by the server
> matches the one displayed
> in the ACME client.
>
> The attack described here is on account recovery, but a similar attack
> appears if we allow email-based
> domain validation. A malicious ACME server or man-in-the-middle can then
> get certificate issued for C’s
> domains with its own public key, without compromising the
> contact/validation channel. The mitigation
> for that attack would be very similar to the one proposed above.
>
> Emails with clickable links are *BAD*; we should enhance their security by
> linking them better with
> the ACME account key.
>
>
> Proposal
> ---------------
>
> I notice that -02 has removed account recovery completely. I would
> recommend that we can
> include account recovery, by piggybacking on the account roll-over
> mechanism and using MACs
> instead of bearer tokens sent in emails.
>
> The proposal that came up in discussions with Richard Barnes is as follows.
>
> Currently, account roll-over does something like the following: It signs
> the roll-over request with the old key, where the request itself contains a
> signature of the old key with the new key.
> Note that it would be fine to flip the order of these signatures: It could
> sign the roll-over request with the new key, where the request itself
> contains a signature of the new key with the old key.
>
> We further observe that account recovery is a form of roll-over where you
> are expected to know a secret that has been delivered out-of-band.
> So, let’s assume that when the ACME client initiates account recovery, the
> server will somehow out-of-band authenticate the user’s request
> and issue the user with a MAC key (e.g. it may email a MAC key to the
> contact email address, but it would be better advised to ask the user some
> questions first.)
>
> Now, the ACME client can complete the account recovery by sending a
> message as follows: It signs the recovery request with a new account key,
> and the request itself
> contains a MAC of the new key with the recovery MAC key.
>
> To make this fully uniform with account roll-over, it would also be
> attractive to flip the order of signatures in the roll-over request, as
> described above, so that the outer
> signature is always with the new key, and the inner JWS is either a
> signature with the old account key or a MAC with the recovery key.
> account key, and the request itself contains a signature of the old key
> with the new key.
>

I agree that this is worth doing.  It's worth having some recovery
mechanism in here to avoid CAs having to invent their own (and possibly
introduce vulns).  I would propose we do this in 2-3 pull requests:

1. Swap the order of the signatures in account key roll-over

OLD: Sign(K_old_priv, Sign(K_new_priv, Fingerprint(K_old_pub)))
NEW: Sign(K_new_priv, Sign(K_old_priv, Fingerprint(K_new_pub)))

2. Add a section on how to do account recovery if you have a recovery key
provisioned, namely:

NEW: Sign(K_new_priv, MAC(K_recovery, Fingerprint(K_new_pub)))

(We can benefit from JWS's conflation of signature and MAC here.)

3. (Optional) Define a way to provision a client with a recovery key.

I mark (3) as optional because neither of the options for how to do it are
especially nice.  On the one hand, if you do it in-band, then you have to
add a lot of complexity to encrypt the recovery key so that only the client
can read it (in order to keep it out of the hands of a TLS MitM).   On the
other hand, if you do it out-of-band, then you're vulnerable to hijacking
via compromise of the contact channel.  Between those two, my preference
would be for the latter, just for simplicity, but I'm open to suggestions.

--Richard


>
> Best,
> Karthik
>
> _______________________________________________
> Acme mailing list
> Acme@ietf.org
> https://www.ietf.org/mailman/listinfo/acme
>
>