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

Martin Rex <mrex@sap.com> Thu, 10 December 2009 16:13 UTC

Return-Path: <mrex@sap.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 970F53A69E4 for <tls@core3.amsl.com>; Thu, 10 Dec 2009 08:13:25 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -6.193
X-Spam-Level:
X-Spam-Status: No, score=-6.193 tagged_above=-999 required=5 tests=[AWL=0.056, BAYES_00=-2.599, HELO_EQ_DE=0.35, RCVD_IN_DNSWL_MED=-4]
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 PmdB7uXcQ8DR for <tls@core3.amsl.com>; Thu, 10 Dec 2009 08:13:20 -0800 (PST)
Received: from smtpde01.sap-ag.de (smtpde01.sap-ag.de [155.56.68.171]) by core3.amsl.com (Postfix) with ESMTP id 15BBC3A6A9E for <tls@ietf.org>; Thu, 10 Dec 2009 08:13:18 -0800 (PST)
Received: from mail.sap.corp by smtpde01.sap-ag.de (26) with ESMTP id nBAGD4JO001667 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 10 Dec 2009 17:13:04 +0100 (MET)
From: Martin Rex <mrex@sap.com>
Message-Id: <200912101613.nBAGD3X2016314@fs4113.wdf.sap.corp>
To: marsh@extendedsubset.com
Date: Thu, 10 Dec 2009 17:13:03 +0100
In-Reply-To: <4B20ABA4.3050805@extendedsubset.com> from "Marsh Ray" at Dec 10, 9 02:04:52 am
MIME-Version: 1.0
Content-Type: text/plain; charset="ISO-8859-1"
Content-Transfer-Encoding: 8bit
X-Scanner: Virus Scanner virwal05
X-SAP: out
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
Reply-To: mrex@sap.com
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 16:13:26 -0000

Marsh Ray wrote:
> 
> 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?

Netscape's official SSLv3 spec as of 2005:
http://web.archive.org/web/20050207004652/wp.netscape.com/eng/ssl3/3-SPEC.HTM


> 
> 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.

As obvious from it's name that spec is a product of the TLS WG and
the TLS WG decided to completely abandon (instead of publishing as
informational RFC) that document so that it expired and vanished
from the I-D repository 6 month later.


> 
> 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.

If that is the impression that the current draft-ietf-tls-renegotiation-01
leaves with you, then this draft needs MAJOR updates of the description,
because it is not correct.


One obvious problem with draft-ietf-tls-renegotiation-01.txt is that
is extremely underspecified.  The TLS extension RI is overloaded in
semantics, and the spec doesn't spell it out.

In the original definition (without MCSV) TLS extension RI conveys
three distinct pieces of information:

  1.) indication that the TLS peer is updated for secure renegotiation
      (1 bit of information)

  2.) indication of whether the TLS peer is performing an initial
      or a renegotiation handshake
      (1 bit of information)

  3.) identification of the previous TLS session the TLS peer
      assumes to be renegotiating


Since all of this information is carried in the same TLS extension,
a correct spec and a correct implementation is a little complex.

Since the current document does not make this clear, the decision
what to send, in particular for backwards interop scenarios,
is non-obvious -- and obviously some people on this list, which
I believe to be experienced engineers, seem to have gotten this wrong.


The reason why my proposal is actually much simpler to explain
in full detail and simpler to implement, is that it uses two
completely seperate mechanisms to convey (1) and to achieve (3)
and it doesn't do (2) at all.  (Not doing 2 means that MitM attacks
can not be distinguished from other finished MAC errors im my I-D).


For interop scenarios with old servers, and as currently used by
conservative clients and reconnect fallbacks (extension-less ClientHellos,
SSLv3 ClientHellos and SSLv2 ClientHellos), sending a TLS extension
in the initial ClientHello would be a change with a significant
disruptive potential.  Not sending any indiciation of the update
for TLS renego protection leaves vulnerabilities, therefore MCSV
is used.

>From the server reply (ServerHello), the client can determine whether
it is talking to an old or an updated server--the updated Server will
return a TLS extension RI in ServerHello.

When the client has established a TLS session with a presumably
old server, and that server asks for renegotiation for whatever
reason (or maybe the client wants renegotiation for client identity
protection), then TLS extension RI is of *NO* use at all.

The only thing that TLS extension RI on the renegotiation ClientHello
with an old server is interop problems.  But not sending anything
would make the renegotiation vulnerable to a "downgrade attack"
with an updated server.  Therefore we need to use MCSV for the
renegotiation with an old server.  MCSV will allow an updated
server in an MitM scenario to prevent a renegotiation handshake
from succeeding.

If the updated server receives the MCSV on an initial handshake,
it will reply with an empty TLS extension RI, which will allow
the client to determine whether his renegotiation with an
presumably old server is proxied into the initial handshake
of an updated server, so the client MUST abort.

If the updated server receives the MCSV in a renegotiation handshake,
but no accompanying TLS extension RI with the client_verify data,
then the server MUST abort the renegotiation handshake because
this is likely an updated's clients initial handshake that is
proxied into the renegotiation handshake of an updated server.


> 
> 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.

The client should not try to rationalize what and what not a server
might be doing.  The client should look at the handshake reply,
look at its policy/configuration and either abort the handshake
or continue.


> 
> 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.

Similarly, servers should not try to rationalize about clients, but
instead rely on policy/configuration and implement behaviour that
is mostly failsafe.

If an updated server receives a ClientHello on a renegotiation handshake
that carries an MCSV, but lacks the TLS extension RI containing the
Client.Finished.verify_data, then that server MUST abort the handshake.


> 
> 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.

Nope, it will be an MitM on backwards interopble clients, and many
of those clients will be updated and capable to send MCSV.


> 
> > 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.

You're _not_ sending the MCSV for use by that old server,
you're including it so that this ClientHello can not be diverted/proxied
into the handshake of an updated server and result in a successful
handshake if that server is backwards interoperable.


> 
> >> 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.


During my tests with openssl-0.9.8l I noticed that a client sending
a renegotiation ClientHello to openssl-0.9.8l will hang.  An openssl-0.9.8l
server seems to _not_ reply to this ClientHello (with a no_renegotiation
alert), but instead completely ignore the handshake message.  Not good.


>
> Look, SSLv3 is broken.

SSLv3 isn't broken.  It was just _not_ designed to be extensible.
If you look at TLS, it is not that much better.  It took them 7 years
to define extensibility.  They could have simply added a 4-octet bitfield
for future assignment as the first piece of TLS extensions right into
the TLSv1.0 spec.  If all you need to convey is a single bit of information,
then a single bit in a relatively fixed location of a handshake message
is _so_ much easier to use than the generic TLS extensions carriage.


> 
> 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.

As long as there are extensions-intolerant servers still in use,
only clients that have a re-connect fallback mechanism can benefit.

You may ship completely new products without fallbacks, but if
you are a software vendor, you definitely can not hotfix disruptive
changes into the installed base unless it is absolutely unavoidable
and your customers are willing to accept this.

For secure TLS renegotiation, the use of TLS extensions in a
disruptive fashion is easily and clearly avoidable.


>
> > 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.


... I actually wrote about an MitM attack scenario here, where the
description of the further communication should describe which of
the peers should at which point realize that it is an attack and
abort -- and not how they would securely renegotiate.  ;-)


> 
> > You're confused.
> 
> Wouldn't be the first time.

I assume I am simply writing too much and make it difficult for
others to follow my line of thought that way.

I'm sorry for that.  It is not my intention to confuse.


> 
> > 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?

Sending the MCSV on _every_ ClientHello (initial *AND* renegotiations).


> 
> > 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.

One signaling mechanism (MCSV) to for conveying Client->Server that the
client is updated is perfectly sufficient.

For signaling that a client is performing a secure renegotiation
with an updated server and for identifying the previous TLS session
that the client presumes to be renegotiating, that is what
TLS extension RI containing Client.Finished.verify_data is about.


>
> 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).

No, it isn't.  It enables RI-minimal implemementations of old TLS servers
to detect proxied handshakes with updated MitMs.

You might want to take the position, that it is the client who is
being fooled, so only the client needs to be aware of the attack,
but *I* think that would be an incomplete fix.  



> 
> >> 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.

No, it doesn't.  It needs to be fixed!


> > TLS extensions is purely optional, not 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.

Plain Wrong.  My proposal works without TLS extensions, that is
clearly explained.  It just happens to use a S->C signaling scheme
that looks like TLS extensions to TLS-extensions aware implementations
and can be parsed with TLS extensions parsers, for those who prefer
to do it that way.

But my draft explains clearly how to do it without TLS extensions,
and the OpenSSL patch I posted contains an extension-less implementation
of the signaling -- and the Client side of the extension-less code
is actually used for server_version==SSL3_VERSION.

> 
> > 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.

Oh yes, there is.

Look at the last two paragraphs of Section 4.4 which describe
how extension-less clients and extension-less servers can implement
this with <10 LoC each.  And my openssl-patch contains exactly
that code.


> 
> >> 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"?

There are two possibilities with the same effect:
Do not implement it in the fashion of "have never contained it"
and do not implement it in the fashion that it is hardwired to disabled.

openssl-0.9.8l is one of the latter.

What you currently see is a lot of customers asking for patches
that reliably disable renegotiation for the servers, because most
servers do _not_ need it.

And once you've come to the conclusion that you don't really need
it, there is no use to implement full secure TLS renegitiation.
RI-minimal  would be just fine, and much easier to test and ship
as a hotfix for an old installed base.


> 
> 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.

Cipher suite values in SSLv3/TLS are two bytes,  and if you're really
concerned about that, you should go for draft-mrex-tls-secure-renegotiation,
because it will need even less bytes on every handshake, in particular
on the renegotiation handshakes.

If TLS extension RI specifies to NOT send an empty TLS extension RI
on the initial handshake EVER, only MCSV, and additionally include
MCSV on every renegotiation handshake, then you save 3-5 bytes
on every initial handshake and pay 2 bytes extra on every
renegotiation.  That means for >95% of the usage scenarios you
will save.


> 
> > 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.

I can imagine that it takes quite some time to implement an MitM attack
on TLS renegotiation.

I'm sorry for just thinking about it for an hour, checking the TLS spec
for flaws in my line of thought for 20 minutes and then posting it
publicly to tls@ietf.org that TLS renegotiation is susceptible
to MitM attacks.



> 
> > 
> > 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?.

I don't have problems with writing that code.  But you certainly
could help me with the weeks of paperwork and automated test-cases
necessary to get official permission to ship that change into an
installed base in maintenance mode.

Some 10 LoC changes require 300+ LoC test tools.  If you look at
my openssl patch, it does not create a lot of new code pathes
that can only be reached with test tools.  98% of that new
code is fully covered during regular use/interop, and works
in a failsafe fashion -- i.e. if it didn't work as designed, it
would result in interop problems.


> 
> 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.

It _only_ proves there is no MitM acting without consent of that
server.  If that server changes his certificate during renegotiation,
it is DEFINITELY not the same server as before.  Depending on what
the new cert looks like, the client may accept this change, but
the assumption that a client must not care is flawed, and can
by itself become a security problem for some situations.

If you're doing security-related stuff, it is extremely important
that you are staying clean at the abstract level.  Some of the
risks that one creates by sloppiness at the abstract level may
lead to mostly theoretical vulnerabilities (like adding arbitrary
data to the handshake message hash instead of handshake messages),
and sometimes it can create very practical risks (like ignoring
identity changes).


> 
> 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.

There are some apps on top of TLS that "tie" certs to hostnames, but
as previously discussed, that is entirely an apps issue, and the
TLS implementation can _NOT_ force re-authentication on the application
caller!


> 
> > 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?

In the IETF security area we try to avoid this kind of approach:
worrying about vulnerabilities only when exploits have been published.

We want to move away from MD5 in online authentication even though
nobody has demonstrated real-time second preimage attacks against MD5 yet.


> 
> > 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/

You mean the term "highlander"?

Look here: http://en.wikipedia.org/wiki/Highlander_%28film%29

"in the end, there can be only one."


> 
> > 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!

To have more than one client cert listed for an authenticated TLS session
would be a pretty dumb idea.

There are platforms that offer such mechanisms more like a feature
of the "Trusted Computing Base", which allows to pass of ACL checks
in a Posix-ACL style to the underlying OS (ImpersonateSecurityContext()).

These functions would likely have difficulties dealing with a set-of
instead of a single client identity, and they would be faced with the
problem that Access Control and auditing/audit logs can deal only
with a single Access Token (identity).


> 
> > 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.

That is what is supposed to happen.  I know that TLS extension RI
uses an unconventional way to perform this authentication -- it
exchanges the data in an integrity-protected fashion and needs to
memcmp() the contents.  Which is why TLS extension RI is not failSAFE.


-Martin