Closed Bug 526689 (CVE-2009-3555) Opened 15 years ago Closed 15 years ago

SSL3 & TLS Renegotiation Vulnerability

Categories

(NSS :: Libraries, defect, P1)

3.12.4
defect

Tracking

(Not tracked)

RESOLVED FIXED
3.12.5

People

(Reporter: nelson, Assigned: nelson)

References

()

Details

(Whiteboard: [sg:high][3.6.x])

Attachments

(7 files, 4 obsolete files)

10.46 KB, patch
rrelyea
: review+
Details | Diff | Splinter Review
15.25 KB, text/plain
Details
5.00 KB, patch
nelson
: review+
wtc
: review+
Details | Diff | Splinter Review
10.54 KB, patch
wtc
: review+
rrelyea
: superreview+
Details | Diff | Splinter Review
10.74 KB, patch
Details | Diff | Splinter Review
11.88 KB, patch
Details | Diff | Splinter Review
20.67 KB, text/plain
Details
Existence of a vulnerability in SSL3/TLS renegotiation was publicly 
disclosed today.  Full details not yet publicly disclosed.
As it's public should we not have our bug public ?
This is embargoed until the author publicly releases it (soon).

The proposed short term solution (and the ONLY solution for SSL 3.0) is to 
disable renegotiation (that is, a second or subsequent handshake on a 
connection after a first handshake has been done).  The longer term solution
proposed for TLS (SSL 3.1+) is to implement the attached extension.  There's 
a lot more to be said/written, but this will suffice for now.
We need to decide on the default value when the extension is available.
Attachment #410524 - Flags: review?(rrelyea)
Attachment #410524 - Flags: review?(rrelyea) → review+
I believe this patch disables all SSL3/TLS renegotiation.  The next step is 
to add the code that allows the application to set the socket options, 
and/or allows the user/admin to set environment variables.  That next step 
will follow today's meeting.
Attachment #410544 - Flags: review?(rrelyea)
Summary: SSL3 & TLS Vulnerability → SSL3 & TLS Renegotiation Vulnerability
Target Milestone: --- → 3.12.5
Comment on attachment 410544 [details] [diff] [review]
Exceedingly preliminary untested patch - disable renegotiation

r+ I would also like to see to environment variables to control this:

1) Renable renegotiation.
2) renable *just* server initiated renegotiation

bob
Attachment #410544 - Flags: review?(rrelyea) → review+
I haven't yet separated enabling of server-requested renegotiations from 
client-initiated renegotations.
Bob, feel free to tell me if these small patch increments are not useful.
Attachment #410620 - Flags: review?(rrelyea)
Comment on attachment 410620 [details] [diff] [review]
untested patch v2, with API and environment variables

r+ rrelyea

Yes, I believe it's useful
Attachment #410620 - Flags: review?(rrelyea) → review+
Vulnerability description:

If an SSL3/TLS server:
1) requests or accepts mid-connection SSL/TLS session renegotiations
(full handshakes that negotiate a new SSL/TLS session after the initial
handshake on the connection has already been successfully completed), and
2) ASSUMES that the client party to whom it was talking before the
renegotiation is the same party to whom it is talking after the
renegotiation (rather than fully authenticating the parties in both
sessions), and
3) treats the encrypted data streams from the two sessions as one continuous
data stream for transaction purposes,

then it is possible for an attacker to create and use a session before
a legitimate client's session, thereby causing the attacker's data (request)
to appear to the server to be be joined (prefixed) to the legitimate
client's (victim's) data (request) lending the victim's authenticity to the
attacker's request.

This is being described by some as an SSL/TLS vulnerability, but it is
simply a mistake to take two different sessions (data streams) that have
been multiplexed together over a single connection and treat them as a
single data stream, assuming them to have a single common source.

Some applications (e.g. some https servers) allow a client to send in a
request while not authenticated, then force a renegotiation to get the
client to authenticate.  They are particularly vulnerable to this.  But
any server that is willing to accept a renegotiation in the middle of a
connection is vulnerable, unless it authenticates the clients of every
session, or otherwise does not treat the different sessions' data streams as
a single transaction data stream.  SMTP servers that accept renegotiations
are particularly useful for attackers' nefarious purposes.

Servers that do not allow mid-connection renegotiations are not vulnerable.

Clients cannot even detect that this is happening to them until the damage
is done.  This is because the SSL/TLS messages in an initial negotiation
are indistinguishable from the SSL/TLS messages in a renegotiation.

The problem is exacerbated by libraries that automate renegotiation, and 
allow the local application to ignore it, so that a renegotiation can occur
without the local application even being aware of it.  NSS does that. :(
Also, NSS has no way for the application to completely disable renegotiation.
These things will be fixed.

Longer term, a proposed extension to TLS will enable two TLS sessions to be 
bound together cryptographically, so that it will be possible to prove (as 
much as anything can be proven cryptographically) that two sessions have the 
same source.  That will take a few more days, I think.
The author(s) made this public today.
This has been in the mainstream news. No point in keeping the bug hidden.
Alias: CVE-2009-3555
Ben, There is a point, and that is, keeping this bug from becoming a discussion 
group.  It is essential that the people working on this bug have an uncluttered channel for communications.  If this gets flooded with opinions from John Q 
Public, I'll find something better to do.

Bob, Since only one of the 3 new socket options is implemented so far, and
it only partially, should I pull out the other two options, and commit the 
one option that I have now?  I hate to think how badly this is going to break
all.sh.  Maybe it will only break the tests where selfserv has the -rr option.
I think there may be value having the options in, but not hooked up. It would at least give applications a chance to change to set them (even if they don't do anything).

RE: breaking all.sh... I think only selfserv -rrr and selfserv -rrrr would break.
This patch turns off the renegotiation tests which will fail as a result of the attached paches.

bob
Comment on attachment 410688 [details] [diff] [review]
turn off SSL renegotiation tests.

r=nelson
Attachment #410688 - Flags: review+
blocking1.9.1: --- → ?
status1.9.1: --- → ?
Flags: wanted1.9.0.x?
Flags: blocking1.9.2?
Flags: blocking1.9.0.17?
Flags: blocking1.9.0.16?
Whiteboard: [sg:high]
Attachment #410544 - Attachment is obsolete: true
Attachment #410524 - Attachment is obsolete: true
Comment on attachment 410620 [details] [diff] [review]
untested patch v2, with API and environment variables

In lib/ssl/ssl.h:

>+#define SSL_ENABLE_RENEGOTIATION       20 /* See values below (default: off)*/

Use "never" instead of "off" to match the symbolic name
SSL_RENEGOTIATE_NEVER of the default value.

>+#define SSL_ENABLE_SSL30_HELLO_XTNS    22 /* Normally requires TLS          */

Do you use "SSL30" instead of just "SSL3" because TLS
is technically SSL 3.1?

The SSL 3.0 protocol specification does not contain the
word "extension".  Are you sure we need to add the
SSL_ENABLE_SSL30_HELLO_XTNS option?

>+/* Values for "on" with SSL_ENABLE_RENEGOTIATION */
>+#define SSL_RENEGOTIATE_NEVER       ((PRBool)0)
>+#define SSL_RENEGOTIATE_WITH_XTN    ((PRBool)1)
>+#define SSL_RENEGOTIATE_ALWAYS      ((PRBool)3)  /* backwards compatible */

Why do you skip the value "2"?

Please document SSL_RENEGOTIATE_WITH_XTN.

It seems more natural to list SSL_RENEGOTIATE_WITH_XTN
after SSL_RENEGOTIATE_ALWAYS, because
SSL_RENEGOTIATE_WITH_XTN is "always" plus "with extension".
(That ordering would match the values you used for the
environment variable below.)

In lib/ssl/sslsock.c:

>+    0,          /* enableRenegotiation (default: never) */

Why don't you use the symbolic name SSL_RENEGOTIATE_NEVER?

>+	ev = getenv("SSLENABLERENEGOTIATION");

Can we add underscores to the environment variable names?
"SSLENABLERENEGOTIATION" is difficult to read.

>+	    if (ev[0] == '0' || (ev[0] | 0x20) == 'n')
>+	    	ssl_defaults.enableRenegotiation = SSL_RENEGOTIATE_NEVER;
>+	    else if (ev[0] == '1' || (ev[0] | 0x20) == 'a')
>+	    	ssl_defaults.enableRenegotiation = SSL_RENEGOTIATE_ALWAYS;
>+	    else
>+	    	ssl_defaults.enableRenegotiation = SSL_RENEGOTIATE_WITH_XTN;

The | 0x20 can be an interview question.  It's not obvious
to me at all.

The value "1" is SSL_RENEGOTIATE_WITH_XTN in ssl.h, but here
it is SSL_RENEGOTIATE_ALWAYS.

Why isn't there an environment variable for SSL_ENABLE_SSL30_HELLO_XTNS?
(In reply to comment #15)
> >+	ev = getenv("SSLENABLERENEGOTIATION");
> 
> Can we add underscores to the environment variable names?
> "SSLENABLERENEGOTIATION" is difficult to read.

Also, is there a reason why the envvars aren't prefixed with NSS_ or something?
Comment on attachment 410620 [details] [diff] [review]
untested patch v2, with API and environment variables

>+/* Values for "on" with SSL_ENABLE_RENEGOTIATION */
>+#define SSL_RENEGOTIATE_NEVER       ((PRBool)0)
>+#define SSL_RENEGOTIATE_WITH_XTN    ((PRBool)1)
>+#define SSL_RENEGOTIATE_ALWAYS      ((PRBool)3)  /* backwards compatible */

I would name these three levels
  SSL_RENEGOTIATE_NOT_ALLOWED
  SSL_RENEGOTIATE_ALLOWED
  SSL_RENEGOTIATE_WITH_XTN

because I find "renegotiate always" a little confusing.
It can be interpreted to mean "always request a renegotiation".
(I know it means "always accept a renegotiation request".)
Comment on attachment 410688 [details] [diff] [review]
turn off SSL renegotiation tests.

r=wtc.  Please add a comment.
Attachment #410688 - Flags: review+
Thanks for all the review comments, solicited and unsolicited.
I'll try to answer questions here.

>Do you use "SSL30" instead of just "SSL3" because TLS is technically SSL 3.1?
Yes. All the TLS protocols are really SSL 3.x protocols, and some people 
interpret "SSL3" as "SSL 3.x".

> The SSL 3.0 protocol specification does not contain the word "extension".  

In section 5.6.1.2 Client Hello, draft-freier-ssl-version3-02.txt says:

   Forward compatibility note:
                  In the interests of forward compatibility, it is
                  permitted for a client hello message to include
                  extra data after the compression methods.  This data
                  must be included in the handshake hashes, but must
                  otherwise be ignored.

> Are you sure we need to add the SSL_ENABLE_SSL30_HELLO_XTNS option?

It's arguable.  If we don't, then when a server enables SSL_REQUIRE_SAFE_NEGOTIATION, an SSL 3.0 client that doesn't send the 
renegotiation info extension won't be able to connect to it, because today 
we never send extensions with an SSL 3.0 client hello.  When it becomes widespread for servers to required that, it will be the end of SSL 3.0 
clients, as we know them.  Maybe that's OK.

> Why do you skip the value "2"?

Because 0 and 3 represent extremes of a range of choices. Presently there's 
only one other choice between them, but there might be another. The three
choices are:
0: Never renegotiate at all
1: Only renegotiate if the peer's hello bears the renegotiation info extension
3: Renegotiate without restriction, whether or not the peer's client hello 
bears the renegotiation info extension (like we always did in the past).

Note that "WITH_XTN" is not yet implemented, and at the moment is treated as 
"always".

> Why don't you use the symbolic name SSL_RENEGOTIATE_NEVER?
Some compiler doesn't like initializing a bit field with a value cast to a 
PRBool.  

>The | 0x20 can be an interview question.  It's not obvious to me at all.
It's tolower() in a single instruction.

For environment variable values, I used '1' and '0' as synonyms for 
'on (always)' and 'off (never)' respectively.

Underscores in envariable names?  Sure.  I was just following the style of 
the existing envariables processed in that same function.  That also explains
the lack of NSS_ prefix.  If there's consensus, I'm happy to add underscores
and a prefix.  

> Why isn't there an environment variable for SSL_ENABLE_SSL30_HELLO_XTNS?
Someone called me and asked me to make a patch out of what I had right then.

At present, I'm torn between people who want a patch right now ASAP to the 
exclusion of ALL other work including server SNI and compression, and others
who don't see it that way.  

I Should also explain to Mozilla people that, until the 
SSL_REQUIRE_SAFE_NEGOTIATION feature is implemented, this patch is more-or-less irrelevant to browsers.  It's mostly a server-only patch until then, IMO.
So, I'm not at all sure that it should be blocking 1.9.0.anything.
Some test results.
When I did a test with selfserv with libSSL built with this patch, and -rrr
which attempts to renegotiate, selfserv got an error when it attempted to 
initiate the renegotiation.  The command was:

selfserv -d SERVER -n DAD -SErrrvvv -C 10 -c cinvyz -p 1443 -w test &

and the output included these lines:

selfserv: SSL version 3.1 using 128-bit RC4 with 128-bit MD5 MAC
selfserv: Server Auth: 1024-bit RSA, Key Exchange: 1024-bit RSA
selfserv: SSL_ReHandshake returned error -12176:
Renegotiation is not allowed on this SSL socket.

Then I used selfserv from an older build of libSSL, (same command) and 
tried testclnt with the new libSSL.  The tstclnt command was:

tstclnt -d CLIENT -f -vvv -h DAD.client -p 1443 < stdin.txt

This time, tstclnt reported:

tstclnt: Read from server -1 bytes
tstclnt: read from socket failed: Renegotiation is not allowed on this SSL socke
t.
tstclnt: exiting with return code 1

and selfserv reported:

selfserv: SSL_ForceHandshake returned error -5938:
Encountered end of file.

So, this seems to pass my tests.  

I will produce another patch equivalent to patch v2 above except for the 
requested cosmetic changes (comments, symbol names, etc.)
I removed the declaration & code for sending TLS hello extensions with SSL 3.0
from this version.  If we decided we need it, we can put in in later, but I 
don't want to commit to it now, especially in light of bug 526806.
I also changed the code for environment variables for options.  
I think this version will seem more intuitive to my reviewers.  Hope so.
Attachment #410735 - Flags: superreview?(rrelyea)
Attachment #410735 - Flags: review?(wtc)
> > Why isn't there an environment variable for SSL_ENABLE_SSL30_HELLO_XTNS?
> Someone called me and asked me to make a patch out of what I had right then.

I had asked nelson to add an option to enable SSL3 extensions explicitly, mostly for the case that some application really wanted to implement it. I don't think the environment variable is necessary. Certainly in the security firedrill sense, it doesn't hurt to not be able to turn SSL3 extensions on since we don't already have that option.

> I removed the declaration & code for sending TLS hello extensions with SSL 3.0
> from this version.

Sounds fine given the current feed back.

bob
Attachment #410735 - Flags: superreview?(rrelyea) → superreview+
Comment on attachment 410735 [details] [diff] [review]
patch v3 - with editorial changes

r+ rrelyea
> Some test results.

I've identified why we on those renegotiate tests we have enabled.
Selfserv goes to request renegotiation and the call fails. This means we don't actually implement a second handshake to get the certificate. Since we don't renegotiate, then tstclient succeeds (because selfserv is only testing the protocol, not the fact the cert was received.

If I turn on the renegotiate tests that are supposed to fail (the client can't access the client auth cert), Then I see the failure because the connection succeeds when we expected it to fail.

I believe both tests give us confidence the patch is working.

Setting the environment variable appropriately causes the tests to revert to the pre-patch behavior... I'll v3 shortly.

(Thanks nelson!).
v3 patch tested correctly as well. I think v3 is good to go.
Attachment #410735 - Flags: review?(wtc) → review+
Comment on attachment 410735 [details] [diff] [review]
patch v3 - with editorial changes

r=wtc.

In lib/ssl/ssl.h:

>+/* Values for "on" with SSL_ENABLE_RENEGOTIATION */
>+#define SSL_RENEGOTIATE_NEVER        ((PRBool)0)
>+#define SSL_RENEGOTIATE_REQUIRES_XTN ((PRBool)2)  /* only when hello bears */
>+                                           /* renegotiation_info extension */
>+#define SSL_RENEGOTIATE_UNRESTRICTED ((PRBool)3)  /* backwards compatible  */

Nit: I think the backwards compatible setting
(SSL_RENEGOTIATE_UNRESTRICTED) should have the value 1
(PR_TRUE/always).  It looks strange to have a hole in
the range of values.  We don't need to use extremal
values.

You can just use your description of these three settings
in comment 19 in ssl.h.  It's much clearer:

  0: Never renegotiate at all
  1: Only renegotiate if the peer's hello bears the renegotiation info extension
  3: Renegotiate without restriction, whether or not the peer's client hello 
  bears the renegotiation info extension (like we always did in the past).

SSL_ENABLE_RENEGOTIATION itself should also be documented.
It's not clear whether SSL_ENABLE_RENEGOTIATION controls
the client, the server, or both.  The comment "only when
hello bears renegotiation_info extension" suggests that
SSL_ENABLE_RENEGOTIATION controls the server.

In lib/ssl/ssl3con.c

>     SSL3AlertDescription desc    = illegal_parameter;
>     SSL3ProtocolVersion version;
>+    SSL3AlertLevel      level    = alert_fatal;

Nit: list |level| right below |desc| as they're closely related.

In lib/ssl/sslimpl.h:

>+    unsigned int enableSSL30HelloXtns   : 1;  /* 23 */

Remove this.

In lib/ssl/sslsock.c

>+#define LOWER(x) (x | 0x20)  /* cheap ToLower function ignores LOCALE */

This must be part of the folklore of system programmers :-)

The rest of this comment responds to previous replies.

Re: SSL30: the reason I asked about it is that "SSL3" is
widely used to mean SSL 3.0, including our own
SSL_ENABLE_SSL3 option.

Re: SSL_ENABLE_SSL30_HELLO_XTNS:

If an SSL 3.0 NSS client is taking the trouble to upgrade
to a new NSS release and enable the proposed
SSL_ENABLE_SSL30_HELLO_XTNS option, it might as well just
enable the SSL_ENABLE_TLS option.

Further, one kind of TLS-intolerant servers is those that
support TLS but not TLS extensions.  Right now NSS-based
browsers (Firefox and Chrome) fall back on SSL 3.0.  If
the browsers still send extensions in 3.0 client hello,
they won't be able to talk to such broken servers.
> Further, one kind of TLS-intolerant servers is those that
> support TLS but not TLS extensions.  Right now NSS-based
> browsers (Firefox and Chrome) fall back on SSL 3.0.  If
> the browsers still send extensions in 3.0 client hello,
> they won't be able to talk to such broken servers.

Right. the default would be as it is today. I doubt the mozilla clients would ever set that value.
blocking1.9.1: ? → needed
Flags: wanted1.9.0.x?
Flags: wanted1.9.0.x+
Flags: blocking1.9.0.17?
Flags: blocking1.9.0.16?
Whiteboard: [sg:high] → [sg:high][3.6.x]
I plan to commit this shortly, given the r+ and sr+ on patch v3.

I now see that I also need to enhance the ssl test programs with 
command line options to test the new socket options.  This will 
let us test clients with renegotiation disabled against servers 
with it enabled, etc.  

Wan-Teh, have a look at 
http://en.wikipedia.org/wiki/File:ASCII_Code_Chart-Quick_ref_card.jpg
This chart makes it evident at a glance why the LOWER function works.
Checking in cmd/lib/SSLerrs.h; new revision: 1.8;   previous revision: 1.7
Checking in lib/ssl/ssl.h;     new revision: 1.30;  previous revision: 1.29
Checking in lib/ssl/ssl3con.c; new revision: 1.119; previous revision: 1.118
Checking in lib/ssl/sslerr.h;  new revision: 1.8;   previous revision: 1.7
Checking in lib/ssl/sslimpl.h; new revision: 1.68;  previous revision: 1.67
Checking in lib/ssl/sslsock.c; new revision: 1.59;  previous revision: 1.58
Comment on attachment 410843 [details] [diff] [review]
patch v4 - addressing all Wan-Teh's review comments

I added the two new SSL error codes to the "NSS and SSL Error Codes"
page at http://www.mozilla.org/projects/security/pki/nss/ref/ssl/sslerr.html.

(SSL error codes from SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED to
SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET are not yet documented
on that page.)
Blocks: 527240
Thanks, Wan-Teh.  I maintained a CVS tree of the /projects/security/pki 
subtree for www.mozilla.org for many years, but now that www.mozilla.org 
no longer uses CVS, I am no longer maintaining those pages.
www.mozilla.org now uses SVN.  You can find the SVN instructions
if you click the "Edit this Page" link at the bottom of those pages.
It's very simple -- I have made several changes by using just the
"svn co" and "svn ci" commands in the instructions (and "svn diff").

In any case, I added the SSL error codes from
SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED to
SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET to that page on Saturday.
The reason I didn't do that on Friday night was that the SSL errors
are documented in categories, so it's more work to find the right
category for each new error code.
(In reply to comment #32)
> www.mozilla.org now uses SVN.  You can find the SVN instructions
> if you click the "Edit this Page" link at the bottom of those pages.
> It's very simple -- I have made several changes by using just the
> "svn co" and "svn ci" commands in the instructions (and "svn diff").

Indeed, the commands for basic checkout/check-in are almost the same as CVS. If you have any questions about SVN or how www.mozilla.org now works, feel free to contact me OOB.
Reed forgot to mention why he thinks this should block release; I'll confess that I've not had the time to read through all the comments, so if a summary could also include:

 - its state on NSS trunk
 - what taking this change means, release-mechanics-wise (new tag?)
 - what the state of tests are for this bug

Please renominate with that summary; many thanks.
Flags: blocking1.9.2?
So, what's keeping this bug from resolved fixed? The final modifications to some tests, or what exactly? As for getting this fixed in Firefox, we'll need updated tags. Who can handle that?
The renegotiation info extension must be issued an official extension number 
by the IANA before it can be put into released products.  That MAY happen 
this week in Hiroshima, or may happen later this month.  In the meantime, 
the best we can do is disable renegotiation, which primarily helps in servers,
but when deployed in servers, benefits both servers and clients.  That's what 
the presently committed patch does.  It's being tested now, and could be 
released and CVS tagged this week.  

I hope to soon have a patch that implements the renegotiation info extension 
using an unofficial (experimental) extension number, for testing purposes, 
while we wait for the official number to be issued.
(In reply to comment #36)
> In the meantime, 
> the best we can do is disable renegotiation, which primarily helps in servers,
> but when deployed in servers, benefits both servers and clients.  That's what 
> the presently committed patch does.  It's being tested now, and could be 
> released and CVS tagged this week.

Ok, good.
 
> I hope to soon have a patch that implements the renegotiation info extension 
> using an unofficial (experimental) extension number, for testing purposes, 
> while we wait for the official number to be issued.

Can we do this work in a separate bug, keeping this one just for disabling renegotiation? Thanks.
> Can we do this work in a separate bug, keeping this one just for disabling
> renegotiation?

Sure.  I don't know how/why any of this matters to or helps Mozilla, since 
the patch in 3.12.5 is essentially for servers (and AFAIK, Mozilla doesn't
make any of those) but if it does, go for it.  

Testing of 3.12.5 continues.  

To summarize:  In NSS 3.12.5, all SSL3/TLS renegotiation is disabled by 
default, and if someone is desperate to turn it back on, and is willing 
to accept the risk of the vulnerability, they can do so by setting the 
environment variable   NSS_SSL_ENABLE_RENEGOTIATION  to the string "1".

In NSS 3.12.6, we will re-enable renegotiation for TLS only, not for SSL 3.0
but only for use between clients and servers that both support the new 
renegotiation_info extension.  Clients will have the option to choose to 
connect ONLY to TLS servers that support that extension, if they wish.  
Doing so will (finally!) render them utterly invulnerable to this attack, 
at the cost of rendering them non-interoperable with all SSL 3.0 servers.
You can open this bug up now.  We'll mark it fixed when we release 3.12.5
Group: core-security
This patch is intended to give a taste of things to come. 
It uses the experimental extension number, which is one reason why it 
cannot be committed to a released product.  
I'm pretty sure there's a nasty bug in the sending of alerts from 
extension handlers, and fixing it will necessitate changing all the 
extension handlers a bit.

I'm not actively seeking review, but will accept review comments.
Comment on attachment 411702 [details] [diff] [review]
patch for NSS 3.12.6 - preliminary, untested, not for review

Not ready for prime time. :)
Attachment #411702 - Attachment is obsolete: true
Here's a status update.  The Internet Draft attached above is ambiguous.  
There are (at least) two different understandings of it that have led to 
two different sets of non-interoperable implementations.  I have a working implementation of one of those interpretations.  
I hope that this will be resolved within 24 hours, but ...  

Alert issues still need ironing out.
This patch works (client works with server) and does "safe" TLS renegotiation 
using one interpretation of the internet draft.  Still Uses the experimental 
extension number.  Will work on alerts issue next.
Re: default value for SSL_ENABLE_RENEGOTIATION

Nelson, turning off renegotiation for SSL clients by default
won't help servers prevent this vulnerability, so the current
default value of SSL_RENEGOTIATE_NEVER seems inappropriate
for SSL clients.  NSS-based browsers such as Firefox and
Chrome will need to set the SSL_ENABLE_RENEGOTIATION option
to SSL_RENEGOTIATE_UNRESTRICTED when they upgrade to
NSS 3.12.5.

Can the default value of an SSL option differ between clients
and servers?  I looked at the code in sslsock.c briefly, and
it seems hard.  An alternative is to add a new
SSL_RENEGOTIATE_SERVER_NEVER value that turns off renegotiation
only for SSL server sockets.  What do you think?
Wan-Teh, 
As I think you know, SSL3/TLS renegotiations, as presently defined, are unsafe.
When a client connects to and interoperates with a server that performs them,
the client is potentially vulnerable.  A client who does not perform them may
experience interoperability problems with a server that does.  This alerts 
the client to the fact that it/he/she is connected to a server that is 
potentially vulnerable, and that it/he/she becomes/remains vulnerable by 
continuing to attempt to interoperate with that vulnerable server.  

A client who does continue to perform unsafe renegotiations merely remains
blissfully ignorant of its vulnerability.  Is that the desired goal?
In the IETF TLS working group meeting last night, the ambiguity in the spec
was resolved.  Today I changed my implementation to match the resolved spec.

When tested in a client, this patch interoperates with two other server 
implementations of the new safe renegotiation TLS extension.  
I have more testing to do on the server side.  I expect there's more work 
to be done there.
Attachment #411862 - Attachment is obsolete: true
In NSS 3.12.5 where SSL_ENABLE_RENEGOTIATION is the only
defense available, I think SSL_RENEGOTIATE_SERVER_NEVER
is the right default value for SSL_ENABLE_RENEGOTIATION.

In NSS 3.12.6, which has the safe negotiation extension,
I think SL_RENEGOTIATE_WITH_XTN is the right default
value for SSL_ENABLE_RENEGOTIATION.

It should be clear that any general-purpose web browser
that upgrades to NSS 3.12.5 (as opposed to NSS 3.12.6)
must set SSL_ENABLE_RENEGOTIATION to
SSL_RENEGOTIATE_UNRESTRICTED if SSL_RENEGOTIATE_NEVER
is the default value.
I'm not yet convinced.  I've recently seen some statistics on renegotiation
that are startlingly low.  I'll bet the average FF user (or Chromium user)
could run with renegotiation disabled and never know the difference.
I meant to add that I intend to start running my own browser with 3.12.5, 
even though my own use of SSL/TLS is likely to be far above average, just 
to test my hypothesis.
There are three URLs in
http://code.google.com/p/chromium/issues/detail?id=6893#c18
that do SSL client auth during renegotiation.

If SSL client auth during renegotiation were very uncommon,
Marsh Ray would probably not have discovered this SSL protocol
flaw.
I predict that, within ~90 days, a very large percentage of the servers that
now rely on renegotiation to trigger client auth will have switched to the
alternate port method (server on alternate port requests client on initial
handshake) which is safe with SSL 3.0 clients and works with clients that
do no renegotiation.
Wan-Teh, Mozilla is talking about waiting until 3.12.6 for Firefox,
and skipping 3.12.5 for Firefox.  Is that an option for you?  or not?
Would you accept the name SSL_RENEGOTIATE_CLIENT instead of 
SSL_RENEGOTIATE_SERVER_NEVER?  I want the name to answer the question:
When (under what circumstances) will this socket renegotiate?
The name of the new SSL_RENEGOTIATE_xxx constant is less
important to me than choosing an approriate default for
SSL clients.  I suggested SSL_RENEGOTIATE_SERVER_NEVER
because it's similar to SSL_RENEGOTIATE_NEVER and one
can interpret it to mean "NEVER" restricted to "SERVER".
Along that line SSL_RENEGOTIATE_CLIENT_UNRESTRICTED would
be also a good name.
(In reply to comment #52)
> Wan-Teh, Mozilla is talking about waiting until 3.12.6 for Firefox,
> and skipping 3.12.5 for Firefox.  Is that an option for you?  or not?

I'm just trying to help QA NSS 3.12.5.  I am more interested than a
typical Mozilla developer in testing new NSS releases in Firefox trunk
nightly builds.
Wan-Teh, I thought about your suggestion some more, and decide that if you
really want to impose separate rules on clients and servers, then we should
have separate options for clients and servers, rather than a single option 
that attempts to set the rules for both.  You might want "client unrestricted" 
to be coupled with "server never" or with "server only with extension", for 
example.  

Johnathan & Wan-Teh, I want to ask you to speak for your respective browsers
as to how you plan to claim to have addressed the renegotiation vulnerability
for browser users.  I know what features we're planning to offer in NSS, 
and the default values we plan to set for those features. I do not know what
your respective browsers intend to do with those features, or when.

I believe the entire TLS developer community agrees that a client is safe 
when it KNOWS that it is only attempting to initiate SSL/TLS handshakes with 
servers that do not perform renegotiations, either (a) at all, ever, or 
(b) except in the presence of the renegotiation_info extensions.  

There are several ways that a client have have that knowledge.  

1) The client can send a renegotiation_info in the initial handshake, when 
negotiating TLS, and look for that extension in the reply from the server.
A successful initial handshake done this way assures the client that the 
server implements the renegotiation_info extension.  This only works for TLS,
not for SSL 3.0.  A client might choose to disconnect, rather than complete 
a handshake, if the server's response lacked this extension.  NSS will support
that mode of operation in NSS 3.12.6.

2) The client can have a whitelist of SSL 3.0 (and/or TLS) servers that are 
known NOT to support unsafe renegotiation, and can allow SSL 3.0 handshakes
with those servers.  This whitelist could be built up by any of several means
including;
a) automatic update from a service (just as google)
b) manual entry by the user himself
c) special testing transactions that could be implemented in the browser to 
make this determination, recording the results in the whitelist when appropriate.

My questions for you are:

- At what point do you think your browser will stop supporting renegotiation
with vulnerable servers (servers that do renegotiation, and do not require 
the renegotiation_info extension as a condition of renegotiation)?

- At what point, if ever, do you see your browser implementing the whitelist 
of servers that are safe to use, because they are known to NOT support 
renegotiation, even though they do not support the renegotiation_info 
extension?  (This would not be an NSS feature.)

- At what point, if ever, do you see your browser requiring that a server 
either (a) be on that whitelist, or (b) use TLS and correctly implement the 
renegotiation_info extension in the initial handshake, as a condition of 
completing an initial handshake with that server?  

- Do you understand how to safely probe a server with NSS to see if it 
supports unsafe renegotiation, for purposes of building a whitelist?
Additional question for browsers that support a "TLS-intolerant server
fallback to SSL v3" algorithm:  

- do you plan to change/reimplement that feature due to this vulnerability?
- If so, how?

One could well imagine that this feature would become integrated with the
whitelist discussed above, and that communication with pure SSL 3.0 
servers would henceforth require them to be on the whitelist.  

I presume the whitelist would be persistent.  When a server name appears in 
the whitelist, will you also record there that it is believed to be TLS 
intolerant (if it is), so that henceforth you will not attempt to connect
to that server with TLS?  Will you periodically re-test servers on the 
whitelist to see if they are still TLS intolerant, and or still fail to 
support the renegotiation_info extension?
Yet another question for browsers that use NSS.  I have been presuming that 
I know the answer to this question, but others have expressed serious doubt
that my presumption is correct, so I wish to ask outright.

When you are faced with the choice of 
a) disabling renegotiation with servers that are not known to be able to do
it in an invulnerable manner, but thereby breaking interoperability with some
unknown number of vulnerable servers that depend on renegotiation, and 
b) continuing to allow renegotiation with vulnerable servers, and hence having
your clients and their users remain vulnerable themselves,

which will you choose?
The Renegotiation Info extension draft is getting a huge amount of discussion
in the IETF TLS working group mailing list.  Lots of alternatives are being
proposed, none of which seem to be gaining large consensus (IMO).  

One change to the RI proposal that does seem to be gaining consensus is that 
the client should ONLY send that extension in its initial handshake on a 
connection IF that client would abort the connection in the event that the 
server's hello response did not include the RI.  IOW, don't send RI unless 
you intend to require RI.  

This is a change from what is presently implemented in attachment 412101 [details] [diff] [review]
which always sends the RI extension in a TLS client hello, whether RI is
required in the response or not.  It also means that servers *CANNOT* 
require RI in the initial client hello on a connection, which the patch in 
attachment 412101 [details] [diff] [review] does optionally, and one vendor's present implementation
does unconditionally.  

So, this solution continues to evolve.  Meanwhile, live exploits are now 
being reported in the popular media.  
http://www.h-online.com/security/news/item/Password-theft-via-vulnerability-in-SSL-TLS-protocol-860435.html
Errrr, this is a weakness of the applications and implementations of Twitter mostly, second servers can disable renegotiation for now. No need for panic. :-)
(In reply to comment #58)
>
> When you are faced with the choice of 
> a) disabling renegotiation with servers that are not known to be able to do
> it in an invulnerable manner, but thereby breaking interoperability with some
> unknown number of vulnerable servers that depend on renegotiation, and 
> b) continuing to allow renegotiation with vulnerable servers, and hence having
> your clients and their users remain vulnerable themselves,
> 
> which will you choose?

I can't answer this question because I disagree with
the validity of choice b).  Disallowing renegotiation
in a browser won't help because it is the attacker
that performs renegotiation.  I know you think that
by turning off renegotiation, a browser can discover
the vulnerable servers.  But you can only discover
servers that request renegotiation this way.  You
can't discover servers that respond to client-initiated
renegotiation, unless the browser probes each server
it talks to with an unsolicited renegotiation client
hello.  For example, I don't think twitter servers
request renegotiation.
Wan-Teh, 
I see I made a consistent error when typing my question in comment 58.
I meant to ask about disabling of "initial negotiation" with servers that 
are not known to be invulnerable the renegotiation attacks, but instead 
I asked about disabling renegotiation.  Please re-read that question in 
that light, and answer it in that light.

Also, please address my questions in comments 56 and 57, especially about
whether you want separate settable options for clients and servers.
Wan-Teh, In reply to comment 61, there is a renegotiation attach that is the
mirror image of the most well known one.  In it, the attacker negotiates 
first with the victim client, then does a renegotiation with the victim 
client, causing that client to handshake with the victim server.  This is 
thought to be only possible if the attacker has a wildcard cert for the 
victim server's domain, or controls one of N servers named on a cert with 
multiple subject alternative names, and so you may regard it to be outside 
your threat model, but it is nonetheless an attack which safe renegotiation 
will overcome, provided that clients do not do renegotiations in a vulnerable 
way.
Nelson, reading your last comments, I think this bug is starting to look more and more like a discussion/a debate, that should take place on mozilla.dev.tech.crypto instead. I have my own point to add to it, I'd like to try to show the position of people running web servers that use client authentication.
Don't you agree with that ?
+1 ditto
There's really no debate here.  NSS is going to do what it's going to do.
It will make changes to the default behavior so that the default behavior 
is no longer vulnerable, and provide ways (through API and also environment variables) for the application or its user to alter that behavior.  

Above,  I'm merely trying to make sure that two of the products that use NSS
are aware of this and are making appropriate plans to deal with it.  It 
appears that one of them is, but it does not appear that the other one is.  
There's been no response from mozilla.{org,com}.

Feel free to discuss this in dev-tech-crypto all you want, of course!
I'll be happy to join you there.  But that is not a place where people from
mozilla.com historically participate, so I don't think that moving the 
discussion there is likely to increase the probability of their participation.
I'm a bit worried about changes to the client side. StartCom for example is using client certificate authentication extensively with a big number of users. Since this affects mostly the server side, I'm not sure how clients should/could be protected and from what exactly? Perhaps Jean-Marc has different concerns, not sure...I'm glad to provide more information if this would be of any help.
See Also: → 529450
Is there still some plan to change the client-side "renegotiation disabled" default for 3.12.5 as was requested / pointed out by wtc?
When I filed this bug, there was a single definite plan (as embodied in the 
Internet Draft, attachment 410650 [details] above).  The plan for NSS 
was simple: Implement the provisions of that ID.  

Now, there are at least two competing plans in the TLS working group.  
One is a successor Internet Draft to the one I previously attached. 
(I will attach it shortly).  The other has not yet become a draft, but will
I think, and has a very vocal group of proponents (although others regard it
as a set of "ugly gross hacks").  

One way or another, the TLS WG will eventually settle on a new standard and
then NSS will implement it.  As a result of all the debate, I now think it is likely tht the standard will define two modes of operation for clients and 
two for servers, to be known as "strict" and "lenient".  NSS will probably 
provide API that matches those modes very closely.  That probably means 
separate socket option settings for clients and servers.

Incidentally, a BIG issue in all this is how important it will be, going 
forward, for browsers to continue to support old servers that are not, 
and never were compliant with either the SSL 3.0 or TLS specifications.
Those are the servers for which Firefox implements the "TLS intolerant 
server fallback" feature.  Some people are using the ongoing existence of 
that feature as evidence that browsers will always insist on supporting
old broken servers forever, even if it means remaining vulnerable.

Microsoft and Opera are well represented in this discussion.  Mozilla is 
noticeably absent.
Attachment #413655 - Attachment description: Renegotiation_Info draft of November 19 → Renegotiation_Info Internet Draft of November 19
(In reply to comment #69)
> Microsoft and Opera are well represented in this discussion.  Mozilla is 
> noticeably absent.

Hm - NSS is Mozilla, unless I'm misunderstanding things? There are mozilla tinderboxes building off mozilla source repositories that hold fixes from mozilla bugs tracked in mozilla modules and discussions in mozilla newsgroups about how NSS integrates with other mozilla projects like Firefox and Thunderbird.

Do you mean that Firefox as a browser is absent? Do you feel like the Firefox team is likely to take starkly different stances on the eventual resolution of these questions than the NSS team? I haven't personally chimed in here very much because it's not clear to me what that would add in the current state. You guys think much more deeply about TLS renegotiation than I do; I feel like it would be patronizing for the NSS team and their work for me (for instance) to come in and presume to have trenchant insights or give direction on the problem. 

I care that users of client software - Firefox in particular but any client-side NSS consumer, really - have a balance between security and usability. I don't want them to have to make technical choices they are unlikely to be equipped to make, and I do want them to be able to use the sites they are accustomed to using, unless we simply cannot stomach the risk that that would represent.

But these are guiding principles, not specific answers to questions about TLS renegotiation. As the Mozilla project most closely tied to the future of TLS, I trust and expect the NSS team to be advocates for Mozilla principles. I know that you have been concerned for some time that the Mozilla corporation doesn't employ people to work directly on NSS, but I think you'd agree that having random MoCo employees on these calls would not help things particularly beyond the expertise the NSS team already brings. I'm certain, for instance, that my presence wouldn't.

Have I misunderstood your concern, here? I know that your intent with your comment wasn't to tuck that in as a passive aggressive slight against MoCo, but I'm not sure what resources you think the Mozilla project should be bringing to bear, beyond your own expertise as an NSS module owner?
The NSS team is unable to accurately represent the Firefox team's preference for security vs. incompatibility. Of course we will do the secure thing with patched servers, but what will we do when we encounter an unpatched (but not necessarily vulnerable) server? We could reject connections entirely (unlikely, at least for a long while), we could connect but without showing a secure state (kind of like "mixed" mode), or we could go ahead and connect and hope the server has either turned off renegotiation or doesn't have any user data worth attacking (wishful thinking).

If we're going to stop connecting to certain old servers is that likely to be over a long phase out, or a more immediate knee-capping? Does NSS need to support prefs that let the browser and/or the browser's user choose the behavior?

I think that's the kind of Feedback Nelson is wanting from "Mozilla" (which, like you I thought included NSS).
In reply to Johnathan's comment 71:
> Do you mean that Firefox as a browser is absent? 

Yes, I did.  Sorry for not being clear about that.  People's perceptions of browsers future responses to this vulnerability are very much driving the actions of the TLS WG at this time.  Several people (not me) are claiming 
they know what browsers will do when faced with the dilemmas I've described
above.  I think the browsers (especially Firefox) should speak for themselves.

> Do you feel like the Firefox team is likely to take starkly different 
> stances on the eventual resolution of these questions than the NSS team? 

Quite possibly, and more than a little likely, yes.  Or perhaps just at vastly different times.  Perhaps the browser team will decide that it's time to cut 
off vulnerable standards non-compliant servers about 10 years later than the 
NSS team would have (as with bad cert overrides). 

The motivations and goals for the browser team are quite different than the motivations and goals for the NSS team.  More generally, the motivations and goals of browser developers are different than those of SSL/TLS developers.  
On numerous occasions, we've seen those two sets of motivations be almost diametrically opposed.

SSL/TLS developers understand that, over time, there will always be a steady 
evolution of ciphers, cipher suites, and protocol versions, as older ciphers 
and hashes are found to be too weak, and flaws in older protocol versions
are found, and so the SSL/TLS designers want SSL/TLS to be able to easily
evolve and move forward as necessary.  They don't inherently value keeping 
the old ciphers, suites, and versions alive forever and ever, especially 
after they've become perceived as vulnerable, even if it means having to cut 
off interoperability with peers (clients, servers) that continue to support
only the old flawed ciphers, suites and versions.  TLS developers are ready
to move forward and cut off interoperability with old vulnerable products 
as soon as possible, with all due haste.  The motivation for SSL/TLS
developers is SECURITY, SECURITY, SECURITY.  

Browsers, on the other hand, are all about maximal interoperability.  If the
competition works with some site, however flawed, and your browser doesn't,
then your browser is disadvantaged.  That's a powerful incentive to browser
developers to keep their products interoperating with old servers, even ones
that are vulnerable.  I anticipate that, for a long time to come, we'll be 
hearing rationalizations for delaying the day when browsers stop 
interoperating with old vulnerable servers (and hence remain vulnerable 
themselves).  

Today, the companies that STILL sell (in 2009) old SSL 3.0-only servers 
that still don't ignore hello extensions, and still don't negotiate SSL 3.0
when offered TLS (in other words, that still absolutely require Firefox's 
TLS intolerant server fallback to remain viable on the internet) are using 
the fact that Firefox has kept that fallback feature alive for 11 years as 
an argument against forward evolution of TLS.  Essentially, they're arguing
that, by virtue of keeping fallback alive for 11 years, the browsers are 
demonstrating that keeping interoperability alive with those broken old 
servers is AND WILL ALWAYS BE valuable, and hence it must be preserved in 
perpetuity.  So they now argue that TLS can only evolve if it does so in 
ways that do not require any changes on the part of those old servers.  

The browsers could collectively kill that nonsense with one statement.  
If the browsers got together and agreed to collectively kill SSL fallback 
on some date, say March 31, 2010, that would right a lot of wrongs, and put 
things back on course.  It would silence all those who would freeze SSL/TLS 
forever as it was 11 years ago.  This vulnerability provides a perfect time 
to do that, to tell the world that it cannot sit on broken old servers 
forever.  But if the browsers don't do it, then the purveyors of those 
servers will win.

I wish I could say, with confidence, that Firefox would be willing to drop 
that fallback stuff on some date (TBD) soon, but today, I cannot.  For all 
I know. FF really does want to keep it for another 10 years.
Blocks: 530575
We released NSS 3.12.5 with renegotiation disabled by default.  
This makes servers invulnerable, but not clients.  

This is as much as we can do until the IETF TLS working group standardizes
modifications to TLS, which they are slowly doing.  I will file a separate
bug to track that work, and declare this vulnerability fixed.
Status: NEW → RESOLVED
Closed: 15 years ago
Resolution: --- → FIXED
Nelson, I think your last comment needs some rewording to be more clear.

If I'm correct, you mean renegotiation is disabled by default for both server *and* clients using NSS 3.12.5 (you can enable it back with the right option flags when setting up the connection).

But that due to the nature of the vulnerability, even when using NSS 3.12.5 with renegotiation disabled, clients can still find themselves interacting with a vulnerable server without any way of knowing it, and this will have the result that the requests they send can be abused.

I think the consequence is that clients using NSS 3.12.5 will probably prefer to programmatically reenable renegotiation when opening a SSL connection, as not doing that will not protect them more (it's when they *don't* see a renegotiation happening that they are being abused), and will make them incompatible with non updated servers.

There might be viable strategy of having a warning when a server request of renegotiation and trying to collect the URL of such servers in order to evangelize them into fixing their vulnerability, but this bug is not the right place for discussing such ideas.
Jean-Marc,
I agree with the first two paragraphs of your comment 75.  
There is also a renegotiation attack on clients that is the mirror image
of the one most common described.  Instead of one server seeing streams from
two clients being "spliced" through renegotiation, in the mirror image, 
one client sees streams from two servers being spliced through renegotiation.
Disabling renegotiation in clients does render clients invulnerable to those
attacks, but not servers.  It's the exact mirror image, and the efficacy of
the single-sided solution is also the mirror image.  It protects the side 
that would otherwise be fooled by the sliced stream, but not the peers.  

So, I think it clients should not assume it is safe to reenable renegotiation
with 3.12.5.
Blocks: 537356
My name is Mikhail Davidov and I am a security consultant for Leviathan Security Group.  I have been doing extensive research on this vulnerability since early August and from reading of this thread and the attached patches I fear you have missed the point.

In the case of client-initiated renegotiation, the browser never sees the renegotiation at all.  The man-in-the-middle is the 'client' and performs the renegotiation with the SERVER and not the browser.  As far as the browser is concerned (at the TCP  level) the connection is simply taking a long time to open for an SSL handshake to come through.  There is nothing that a browser can do to prevent this so disabling client-initiated renegotiation provides no additional level of security.

Here is the simplified flow of the client-initiated renegotiation bug:



Client              Evil                 Server
================================================
                      <<<<<LETS_START_SSL<<<<<
                      >>>>>SSLHANDSHAKE>>>>>>>
		      <<<<<FINISHHANDSHAKE<<<<
		      >>>>>>EVIL_HTTP_REQ>>>>>
                      >>>>RENEGOTIATE_REQ>>>>>


<<<<<<<<<<<<<<<<<<<<<<<<<<<LETS_START_SSL<<<<<
>>>>SSLHANDSHAKE>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<FINISHHANDSHAKE<<<<
>>>>LEGITIMATE_HTTP_REQ>>>>>>>>>>>>>>>>>>>>>>>  
<<<<<<<<<<<<<<<<<<<<<<<<<RESPONSE_TO_EVIL<<<<<

In conclusion the browser never sees nor does it ever initiate a renegotiation.

I will be pushing out a whitepaper on this subject very shortly which will cover this more in depth but in the mean time feel free to contact me for further clarification.
Interesting! This was my impression too - thanks Mikhail for bringing this up!
Mikhail,
Your comment 77 wasn't addressed to anyone in particular, but no-one on the
NSS team has missed the point here.  We're quite aware that the client 
doesn't see the attack, when the attack is done against the server, and 
conversely, the server doesn't see the attack when it is done against the 
client.  

As you know, until such time as clients and servers have been upgraded to 
know how to avoid this vulnerability, and to signal that they have been 
upgraded, the best we can do is to avoid consciously participating in 
vulnerable renegotiations.  That's what the patch for this bug did. 

The upgraded behavior is the subject of bug 537356.
blocking1.9.1: needed → ---
You need to log in before you can comment on or make changes to this bug.