Re: [TLS] Analysis of Interop scenarios TLS extension RI w/MCSV

Marsh Ray <marsh@extendedsubset.com> Thu, 10 December 2009 08:05 UTC

Return-Path: <marsh@extendedsubset.com>
X-Original-To: tls@core3.amsl.com
Delivered-To: tls@core3.amsl.com
Received: from localhost (localhost [127.0.0.1]) by core3.amsl.com (Postfix) with ESMTP id 1A5AE3A693D for <tls@core3.amsl.com>; Thu, 10 Dec 2009 00:05:12 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.595
X-Spam-Level:
X-Spam-Status: No, score=-2.595 tagged_above=-999 required=5 tests=[AWL=0.004, BAYES_00=-2.599]
Received: from mail.ietf.org ([64.170.98.32]) by localhost (core3.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id b6Chsr5l8+DG for <tls@core3.amsl.com>; Thu, 10 Dec 2009 00:05:09 -0800 (PST)
Received: from mho-02-ewr.mailhop.org (mho-02-ewr.mailhop.org [204.13.248.72]) by core3.amsl.com (Postfix) with ESMTP id E2D783A62C1 for <tls@ietf.org>; Thu, 10 Dec 2009 00:05:08 -0800 (PST)
Received: from xs01.extendedsubset.com ([69.164.193.58]) by mho-02-ewr.mailhop.org with esmtpa (Exim 4.68) (envelope-from <marsh@extendedsubset.com>) id 1NIe1B-000BMi-4K; Thu, 10 Dec 2009 08:04:57 +0000
Received: from [127.0.0.1] (localhost [127.0.0.1]) by xs01.extendedsubset.com (Postfix) with ESMTP id D6234603A; Thu, 10 Dec 2009 08:04:54 +0000 (UTC)
X-Mail-Handler: MailHop Outbound by DynDNS
X-Originating-IP: 69.164.193.58
X-Report-Abuse-To: abuse@dyndns.com (see http://www.dyndns.com/services/mailhop/outbound_abuse.html for abuse reporting information)
X-MHO-User: U2FsdGVkX186xS261ocV5XLSK0XVdi1lbBzGMO8YjuY=
Message-ID: <4B20ABA4.3050805@extendedsubset.com>
Date: Thu, 10 Dec 2009 02:04:52 -0600
From: Marsh Ray <marsh@extendedsubset.com>
User-Agent: Thunderbird 2.0.0.23 (Windows/20090812)
MIME-Version: 1.0
To: mrex@sap.com
References: <200912092309.nB9N9G0r014068@fs4113.wdf.sap.corp>
In-Reply-To: <200912092309.nB9N9G0r014068@fs4113.wdf.sap.corp>
X-Enigmail-Version: 0.96.0
OpenPGP: id=1E36DBF2
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 7bit
Cc: tls@ietf.org
Subject: Re: [TLS] Analysis of Interop scenarios TLS extension RI w/MCSV
X-BeenThere: tls@ietf.org
X-Mailman-Version: 2.1.9
Precedence: list
List-Id: "This is the mailing list for the Transport Layer Security working group of the IETF." <tls.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/listinfo/tls>, <mailto:tls-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/tls>
List-Post: <mailto:tls@ietf.org>
List-Help: <mailto:tls-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/tls>, <mailto:tls-request@ietf.org?subject=subscribe>
X-List-Received-Date: Thu, 10 Dec 2009 08:05:12 -0000

Replies to three emails in one.

Apologies in advance if this doesn't all get quoted perfectly.

Martin Rex wrote:
> Marsh Ray wrote:
>> The draft-freier-ssl-version3-02.txt says to ignore data after the 
>> Client Hello, which implies extension-intolerant SSLv3 servers are 
>> defective, too. Not that it really matters at this point. Had you 
>> mentioned something about an earlier version not saying that?
> 
> The official SSLv3 spec doesn't say that!
> 
> The IETF archives do not know freier-ssl-version3-02  (only -00 and
> -01) freier-ssl-version3-02 is probably what is known as 
> draft-ietf-tls-ssl-version3-00.txt -- a document which the TLS WG 
> chose _NOT_ to publish as informational, and which Netscape did _NOT_
> see as an official spec, otherwise they would have updated their much
> more prominently offered versions of the SSLv3 spec based on the
> freier -01 draft _without_ the extensibility option.

That is interesting information. Would you happen to have a copy of the
last "official" spec you can send me?

I probably got draft-freier-ssl-version3-02.txt from:
http://www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt
I don't know if that implies anything "official" past or present.

The IETF's DNS seems to be inoperative, but Google has a cached version of:
http://tools.ietf.org/html/draft-ietf-tls-ssl-version3-00

It has the same "it is permitted for a client hello message to include
extra data after the compression methods" language.

>> It will never be safe to conduct renegotiation with a remote party
>> in the absence of negotiated RI.
> 
> That is wrong.  An old server (potentially an extensions-intolerant
> one) does only mean that renegotiation with _that_ old server will
> remain unprotected.

And clients that care about the security of the connection had better
refuse to connect to it at all!

Servers receiving an initial connection request without a request for RI
will soon know some things:
1. The client software is not patched for security.
2. There's a good chance the client is vulnerable to one or more
variants of this basic attack.

Clients receiving a request for renegotiation without having previously
negotiated RI can expect that the server is vulnerable to MitM and they
may have already been pwned on this connection state.

Servers receiving a client-initiated renegotiation without having
previously negotiated RI can not know that it is the same party they
have on the current connection state.

Sure you can point to some combinations of (client renegotiates)x(server
renegotiates)x(specific protocol)x(specific implementation) that is not
vulnerable, but a fundamental guarantee of TLS is missing and most
setups are vulnerable to one or more attacks. Mix in the possibility of
application data between the handshake messages and it's just plain not
there.

Starting soon, the absence of RI on a hello is going to be an
increasingly strong indicator of "broken and insecure". Eventually, it
will just be discarded along with SSLv1 and v2.

> What secure TLS renegotiation should protect from is a downgrade
> attack, that an MitM acts as an old extensions-intolerant server and
> then proxies an updated clients renegotiation with an presumably old
> server into the handshake of a backwards-compatible updated server.

This is only a problem while you run in compatible mode.

> Only MCSV can provide this protection.

I'm missing something. How can MCSV fix "updated clients renegotiation
with an presumably old server"?

> TLS extension RI on renegotiation will break interop with all old
> servers that request renegotiation.

That's the least of your problems as a client. Your connection may have
already been pwned.

Before the renegotiation, you could have held out some hope that the
server would never renegotiate at all. But now that you know the server
does renegotiation it's like realizing that you've just sent your online
banking credentials to an unmaintained Debian Etch system.

How could one conduct a secure renegotiation without first establishing
that the initial negotiation was secure?  The server has an unknown
amount of evil buffered state and may be just waiting for you to supply
the credentials to act on it.

>> The expectation is that clients and servers will be transitioned
>> into "strict mode" at the earliest opportunity.
> 
> You seem to entirely ignore the transition period. We can not shut
> down the entire internet, wait for 6 or 12 months until everybody has
> updated every client and server, and then re-launch the internet.

Oh no, we mustn't shut down the entire internet!

> If we do not provide provisions for smooth interop for at least the 
> transition period, it will hurt _everyone_!

If you really want to renegotiate with old, broken, unpatched, and
extension-intolerant servers so badly that you're willing to do it
insecurely <em>then don't send them the freaking extension</em>!

Sending them an MCSV is at best going to be ignored by such a server, no
matter what semantics some document attaches to it.

Just don't expect an IETF I-D in 2010 to magically make something secure
that's been nominally obsolete since January 1999 (RFC 2246 TLS 1.0)
without having to add more than 20 lines of code!

> Users and admins will _not_ install client-side patches if these are
> disruptive to some usage scenarios (it's mostly a server problem). 
> And when clients are not updated, then Server operators that need 
> that functionality and do not want to loose significant sales can not
> disable old renegotiations on their servers.

+10

>> Lots of clients (browsers, etc) currently do send extensions on 
>> Client Hello, so they may never choose to send MCSV on those
>> connections.
> 
> Several hundred millions clients do _not_ send extensions on
> ClientHello.

Not relevant. What matters is the number of servers that hang in a slow
fail condition when sent an extension.

>> It is hoped that at some point in the future, extension-intolerant
>> (and -ignorant) servers will be insignificant and the MCSV can stop
>> being sent by clients.
> 
> 5-10 years.

I intend to still be capturing packets at that time.

>> Yes, the MCSV is a work-around for old broken servers. This
>> work-around does not constitute the endorsement of brokenness by
>> anyone. It's simply that in this one bugfix we are choosing to be
>> extra accommodating.
> 
> No, MCSV is _not_ only a necessesity for a few broken TLSv1.0
> servers, it is also a necessity for a number of fully compliant SSLv3
> servers

I believe you, but I can't find a copy of this SSLv3 spec anywhere on
the web. However, I don't think there are many on this list who place
much weight on the compliance to a spec that appears to have been
abandoned 11 years ago. What matters is what's in the field at this point.

> _and_ it is an enabler to _relief_ old servers (including
> extensions-tolerant) from having to add 5x the amount of code to
> their code base which has nothing to do with the underlying security
> problem.

Look, SSLv3 is broken. Everyone here did their best, but no one could
come up with a palatable solution that did not require the use of a
protocol extension, even if just for the S->C signaling. Therefore,
SSLv3 needs to either be completely deprecated or it needs to have added
minimal support for this one extension.

Vendors can choose to fix their old SSLv3 implementations if they want
to. There are real concessions to interoperability in the proposals. But
the fact that the fix to this long-abandoned protocol spec might take
100 lines of code instead of 20 is not going to drive the design.

> The client can easily abort when it doesn't like the server's answer,
> 
And it must if it needs proper SSL/TLS security.

> so there is absolutely _no_ justification for the client to send data
> that will cause interop problems.

Sure there is: some clients get a positive benefit from the use of
extensions. How to manage the tradeoff between that benefit vs.
potential interactions with intolerant servers is something app
developers and admins/users currently manage.

> For an updated server in an MitM attack scenario, the presence of the
> MCSV is sufficient to realize that it is talking to an updated client
> that is probing.

Right. After that initial Client Hello with the MCSV, the server knows
that the client is patched and responds with an extension. From that
point on, the client knows he can send extensions. And both endpoints
now must send the extension on every single hello on that connection,
because they will have nonempty verify_data.

> You're confused.

Wouldn't be the first time.

> This requirement is about protection from MitM-attacks, it is _NOT_
> about successful secure renegotiations (which are not possible when
> talking to an old server in backwards interop mode).

Sorry, which requirement was that?

Again, full protection from these attacks (i.e. effective TLS) involves
refusing to handshake with an unpatched remote.

>> Why would you want to ignore that a client is attempting to
>> negotiate the use of RI?
> 
> Simple answer: to facilitate testing and QA.  Make sure that every 
> client is correctly sending MCSV.

Or the RI extension.

> We do not need two signaling mechanisms where one is perfectly
> sufficient.

I don't think one is perfectly sufficient. Keep in mind the attacker
generally gets to choose which handshake is presented where. If you
allow conformant servers to not look for and validate the RI extension
on every single Client Hello they receive, it makes it possible for a
patched client's renegotiation handshake to be presented to a patched
server which doesn't validate it.

So MCSV only needs to be sent on the initial Client Hello, and then only
if you aren't sending extensions for any other reason and don't want to
upset an unpatched extensions-intolerant server.

The client must then validate the emptiness of the RI returned on the
Server Hello.

Patched clients and servers must validate the content of the (now
required to be present and nonempty) RI extension received on subsequent
Hellos. The MCSV field on subsequent Client Hellos is now redundant in
all cases (both valid and attack).

You can save three octets by not sending the MCSV when you're also
sending the RI extension.

> Besides, MCSV is 3-5 octets less on the wire and you need the code
> for MCSV anyway-- so the most reasonable solution is to make it
> mandatory to use.

That's a pretty weak argument, I know because I'm usually the one making it.

I'll take the cost of five extra octets over a phony cipher suite hack
any day.

>> So you're saying that an implementor who has let their code rot for
>> the last 6.5 years could save 140 LoC?
>> 
>> Personally, I don't find that to be a primary consideration.
> 
> Rot for 6.5 years?  What are you talking about?

RFC 3546 TLS Extensions June 2003

> There is even brand new code under active maintenance without support
> for TLS extensions.

Well, guess what! The protocol now needs to be extended.

> TLS extensions is purely optional, not

s/is/were/

> part of the vulnerability and does not need to be part of the
> solution.

No one came up with any other less-impactful way to do the required S->C
signaling, and not for lack of trying.

> Besides, in those cases where it is about code that has been mostly 
> unchanged for 6+ years, it is not "implementers" who will have to add
> the secure renegotiation patch, it will often be "maintainers" with
> little knowledge about the code -- and then, it makes perfect sense
> to ask them for only 20 lines of code instead of 150+

There's no 20 line fix for this. Neither is there a (palatable) solution
which does not use extensions. Last I checked,
draft-mrex-tls-secure-renegotiation used an extension.

>>> 11.) updated TLS client, RI-minimal,    no renegotiation
>> Could you explain what you mean by RI-minimal, RI-only, and
>> "extensions".
> 
> RI-minimal client (one which does not implement renegotiation):
> 
> sends MCSV on ClientHello, tolerates ServerHellos with extra data 
> following compression-method, i.e. will complete handshake if that
> extra data is 7 octets long and resembles an empty extension RI
> 
> 0x00 0x05 0xFF 0x01 0x00 0x01 0x00
> 
> and abort the handshake otherwise.

OK, but it better do more than tolerate that data, it better require it.

By the way, do you of any TLS implementations that do not "implement
renegotiation"?

I'm sure they exist, but in general renegotiation seems to fall
naturally (hmmm, a bit too naturally) out of a straightforward
implementation.

> RI-minimal server (one which does not implement renegotiation):
> 
> searches MCSV in ClientHello, ignores TLS extensions completely sends
> back the above 7 octets extra data after compression_method in
> ServerHello when MCSV was found.

If you write the spec that way, the world is married to the MCSV
forever. And we waste three bytes on every handshake. All for the sake
of some unknown-but-small number of servers which fail badly when sent a
modern Hello and will probably be put away for their own protection any
time now.

> RI-only client (one which does not implement TLS extensions in
> general but adds secure renegotiation with TLS extension RI):
> 
> minimalistic TLS extensions support, only for TLS extension RI, sends
> MCSV in initial ClientHellos, sends TLS extension RI with
> Client.Finished.verify_data on renegotiation can parse TLS extension
> RI in ServerHello, and in order to reliably recognize updated Servers
> on renegotiation, it must be able to find TLS extension RI among
> other ServerHello extensions (or abort if there are others)

Nothing wrong with that.

> RI-only server (one which does not implemet TLS extensions in general
>  but adds secure renegotiation with TLS extension RI):
> 
> minimalistic TLS extensions support, only for TLS extension RI, can
> find and parse TLS extension RI in ClientHello between other 
> extensions, will send back fixed 7-octet string above on initial
> handshakes and TLS extension RI with content on renegotiation
> handshakes when the ClientHello contains MCSV or TLS extension RI.

Nothing wrong there.

Nobody said you had to add general support for extensions.

All you have to do is iterate a list of TLVs looking for one type by number.

>> Those tiny LoC differences are not significant, especially
>> considering the margin of error for those types of things. Usually
>> you're lucky to get within a factor of two.
> 
> 20 LoC vs. 80 LoC can be a HUGE difference for old code that one 
> doesn't know.
> 
> ~20 LoC is  1 day implementing, 1 day testing. ~80 LoC is  3 day
> implementing, 5 day testing.

I have heard of these teams which produce less than a screenful of code
a day.

Oh heaven forbid, somebody writes 80 lines of code.

Work three days? Do you know how many all-nights and all-weekends I did
to get a working test case going for this bug so I could fully
characterize it and give the most complete info to people who needed it
so they could come up with a workable solution in the shortest period of
time to minimize the risk of public disclosure? Every TLS implementation
that we could think of and get a non-disclosure agreement with has known
about this tentative proposal and the need to implement extensions since
the end of September! Most have experimental implementations already.

>> They certainly don't give a realistic indication of "level of
>> effort".
> 
> I've been doing development, support, maintenance and QA for mission 
> critical software for the past 14 year, and I can assure you, they do
> give a pretty good picture about the effort.
> 
> If you're providing free and open source software, you might not 
> worry about trial-and-error.
> 
> If you are a software vendor that charges for maintenance, then it is
> a completely different issue.  You do not change any code that has
> been in extended maintenance mode for a few years, and the original
> authors of that code are likely not the ones who will have to patch
> the code.  There are software logistic procedures in place that make
> it extremely expensive and extremely unlikely that you make code
> changes that break interoperability "unintentionally".
> 
> Have you worked for a software company with 5000+ software developers
>  during the last three years?

No, would you like me to write the 80 LoC for you?.

Martin Rex wrote:
> Marsh Ray wrote:
>> 
>> In order for this example to be a problem, the legitimate client
>> would have to renegotiate specifically for the purpose of dropping
>> certain cert credentials. This would seem to imply that the
>> application code was expecting cert changes.
> 
> The above code sample provide by Pasi is about client-side code, as
> indicated by "openTlsConnection" and the comparison 
> "conn.getPeerCert().getName() != expected_name"

Right.

> So this is more about server certificates changing then clients using
> different credentials.  And it is about apps coding above TLS, and
> not about details of TLS implementations.

So why would a legitimate server renegotiate a connection and switch
certificates in a way that could surprise a client and be manipulated
for evil? The renegotiation fix proves it's the same server with no
MitM. The last certificate is properly validated and accepted by the
client. By extension, this proves the previous connection states were
with the trusted server, too, with no interference from a MitM. Whatever
such a trusted server wanted to do to the client, he could also do
without involving the complexities of a renegotiation.

The reverse case applies equally for client certs but seems potentially
more plausible because of the way server certs are currently tied to
listening IP addresses.

> Since a non-negligible amount of clients will need allow old
> renegotiation for a little while, one might want to think about
> mitigating unexpected changes the server certificate.

Again, something bad could possibly happen but nobody's produced an
actual scenario. Perhaps something involving multiple sites behind a
confused reverse proxy?

> There are a lot of applications scenarios where this either doesn't 
> make any sense or will cause endless problems, support calls and confusion.
> Would you want your browser to send *ALL* your WWW-authenticate 
> credentials to every server and let the server pick (AFAIK the 
> protocol doesn't even allow that).
> In most Audit log facilities, you can only log *ONE* identity for 
> which an operation was attempted (and failed or succeeded), and not 
> an arbitrary set of identites.
> As soon as you have larger distributed systems, your TLS endpoint 
> might be a reverse proxy at the perimeter of the backend server farm.
> The reverse proxy [...] For HTTPS, a client that shows a different
> cert after renegotiation just doesn't make any sense most of the
> time.

My point wasn't that it was useful most of the time, or even any of the
time. My point was that these were the trust relationships implied by
the crypto as I understood it. I wouldn't mind being shown to be wrong,
but don't really care if you think it's useful or not.

> If the client wants to use a different cert, he should open a
> new network connection.

I do not believe that's not how all https servers work. Usually it's the
server asking for a different client cert. For example, Apache will
renegotiate for different crypto requirements as the connection
traverses different parts of the site. This has been demonstrated with
using an .htaccess file to trigger server-initiated renegotiation.

> If the reverse proxy or the backend wants to mitigate
> session-id-stealing it might employ a memcmp() on the certificates
> forwarded by the reverse proxy, and will rightfully abort if that
> changes.

Sure it might do that. Whether it's rightful or not depends on the
application protocol.

> A client architecture which allows the use of different client 
> certificates on different connects and does not reliably distinguish 
> TLS sessions established with different client properties (anonymous,
> client cert A, client cert B, ...) is probably broken.

Probably, but only because it seems few were aware of the hidden
potential (and pitfalls) provided by TLS renegotiation.

>> With renegotiation fixed, credentials supplied on different
>> handshakes may legitimately be treated as additive. This is how
>> https client certificates often work: an initial anon-client
>> connection adds a client cert to the connection by renegotiating.
> 
> Nope, that is not how it works.

You'll have to do better than that.

> A client that has not been previously
> authenticated performs a client cert authentication.  That is a
> highlander operation.

I'm not familiar with that term. Searching for it results in some NSA
wiretapping gone wrong.
http://www.wired.com/threatlevel/2008/10/kinne/

> Which of the TLS implementation actually keeps
> a set of certs/cert-chains for a TLS peer crowd created through
> renegotiation and has API calls to iterate through them? The
> implementations that I know have only APIs to request "THE" peer
> certificate.

I believe that list could be maintained by app code using the existing
APIs. Better that you don't do it as
"getJustTheMostRecentOneRemotePartyCert()" of course.

> So if there actually are apps today that can handle a multitude of
> client identites on a SSL/SecurityContext handle, they will likely 
> have to implement that at the app layer, because very few, if any TLS
> implementations provide "a set of TLS peers".

Well, tell me why it's flawed or I shall have to find an interesting use
for it!

>> It will never be safe to conduct renegotiation with a remote party
>> in the absence of negotiated RI.
> 
> As I wrote a while ago, the name "TLS_RENEGO_PROTECTION_REQUEST" was
> chosen _not_ as a requst for secure renegotiation (which it is NOT), 
> but as a request for _protection_ from the vulnerability through old
> TLS renegotiation.

Sure.

> There are two different issues that the fix needs to provide:
> 
> - secure renegotiation between updated clients and servers directly
> talking to each other

Yes.

> - protection from MitM attacks in all 3 attack scenarios

Between which of
  ((patched|unpatched)x(compatible|strict))**2
x (client-side-renego | server-side-renego | dual-renego)


> - protection from MitM attacks for communication between updated
> clients and updated servers even when both allow old renegotiation
> for backwards interop.

Yes

> The secure renegotiation is provided by "authenticating" the verify
> data from the previous finished messages.

I wouldn't describe it that way. It's just checking that two values are
in agreement. These values were authenticated by the previous handshake
process.

Sides have the same, but independent, interests in thwarting MitM. It's
natural that they would cooperate to do the checking, but it's not
mutual authentication. Each side says "this is who I thought you were,
please look after me". Either side could lie when they send the RI data,
or fail to check when they receive it, but would gain nothing by doing so.

> TLS extension RI performs
> the authentication with memcmp() on data exchanged through a TLS
> extension in the renegotiation handshake.
> 
> The protection is provided through negotiating/signaling with the 
> peer that one is updated.

The negotiation is only necessary to enable the option of a compatible
but insecure mode, it's not part of the security. "Opportunistic
security" you might call it, but I hope it is only very temporary.

> TLS extension RI does both with the same piece of data in the 
> handshake message (TLS extension RI), and it seems that some people 
> fail to understand the difference between the two things.
>
> Previously, I wrote that draft-mrex-tls-secure-renegotiation-03.txt 
> is a "nanny spec", because it does _not_only_ describes how to
> perform secure renegotiation, but it _also_ describes how to
> implement backwards interop securely.  This discussion here sugggests
> that this difference is unclear to at least some people, and
> therefore should be better explained in the
> draft-ietf-tls-renegotiation-02 as well!

There are definitely some subtle points here.

- Marsh