Closed Bug 728715 Opened 12 years ago Closed 12 years ago

SSL+SNI+client-auth "lost" after some time

Categories

(NSS :: Libraries, defect)

x86_64
Linux
defect
Not set
major

Tracking

(Not tracked)

RESOLVED WONTFIX

People

(Reporter: calestyo, Assigned: wtc)

References

()

Details

Attachments

(4 files)

User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2 Iceweasel/10.0.2
Build ID: 20120217174734

Steps to reproduce:

Hi.

I've originally reported this problem against the Apache HTTPD Server, but there is some indication that this is not a problem of the server, but of the browsers.

The basic story is, that I have an Apache HTTPD server, that runs SSL vhosts with SNI (Server Name Indication).
The vhost uses SSL client authentication (required) and fakeBasicAuth (but the later is likely completely unrelated).


When I access the website in Firefox and/or Chromium authenticate myself by choosing one of my certificates, the access works and I see the website.

But after some time (between 2-10 minutes usually) when I reload the page or it automatically reloads, the access fails.

So far the reasons seems that the browser doesn't send the SNI host name again.
The only solution is to either restart the browser or in Firefox, clear the "Active Logins".
Then I can reload, reauthenticate and it works for another while.

As you can imagine this is extremely annoying ;-) .

I've put extensive information in the bug report:
https://issues.apache.org/bugzilla/show_bug.cgi?id=52703

and a thread on Apache's user mailing list:
https://mail-archives.apache.org/mod_mbox/httpd-users/201202.mbox/%3C9242b47ae7f6c0e17980992824c639c2%40scientia.net%3E
(click the thread link on the right top)

Maybe (but this is just pure speculation) bug #728713 (https://bugzilla.mozilla.org/show_bug.cgi?id=728713) is somehow related to this one.

Any help or information how to further trace this down would be great.
(I'm however on holidays till 1st of March, so expect a delay in further answers)


Cheers,
Chris.
Severity: normal → major
Please try bug 728713#c3
Sorry, the URL in comment 2 meant to be described as:

I've just reported the same issue in Chromium.
Matthias, I've just tried "NSS_SSL_CBC_RANDOM_IV=0" with this issue.
It doesn't change anything.
I've added two logs made with ssltap.
Again, a 1st connection where it worked and a 2nd where it then failed.

I'm not an SSL expert, but it seems that on the 1st access it correctly sends the server_name.
But on the later access nothing at all.
In the second connection log you can see that the client is using a session_id and that looks like a connection resumption.

From rfc6066:
>Note also that all the extensions defined in this document are
>relevant only when a session is initiated.  A client that requests
>session resumption does not in general know whether the server will
>accept this request, and therefore it SHOULD send the same extensions
>as it would send if it were not attempting resumption.
Assignee: nobody → nobody
Component: Untriaged → Libraries
Product: Firefox → NSS
QA Contact: untriaged → libraries
Version: 10 Branch → unspecified
What does this mean now?
Is there anything I can do to help (I'm on vacation starting with today, till 29th... not sure whether I can go online till then.)?

If this was a bug in NSS, it would also explain why Chromium is affected, right?
It uses NSS, too, AFAIR?
Is there anything left I can do to help tracking this down?
I've just reported this https://issues.apache.org/bugzilla/show_bug.cgi?id=52703#c3 ... which seems to imply that SSL session resumption is responsible for this issue, as well as for #728713.

Again, it happens with Firefox/Chromium (both using NSS) so this might be
either a NSS bug or an Apache bug or some bad playing between both.
Christoph: thank you for the bug report.  The ssltap logs
are helpful.

The ssltap log for the full handshake shows the ClientHello
advertised SSL version 3.1 (TLS 1.0) but the ServerHello
chose SSL version 3.0.

The ssltap log for the session resumption handshake shows the
ClientHello advertised SSL version 3.0, which is why it had
no TLS extensions.

Here is how NSS determines the SSL version to advertise in
ClientHello:

http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/security/nss/lib/ssl/ssl3con.c&rev=1.165&mark=3891,3899,3907,3910,3918#3891

'sid' points to a sslSessionID structure.  Note the second
argument passed to ssl3_NegotiateVersion().  It caps the
version advertised in ClientHello.  So, if sid exists and
sid->version is SSL 3.0, ClientHello will advertise SSL 3.0.

So, you can solve the problem by turning on TLS 1.0 in your
Apache HTTPD server.

I have two questions for the people cc'ed in this bug.

1. If a server chooses SSL version 3.0, should it process
the TLS extensions in the ClientHello?

Since SSL 3.0 does not define any extensions (except the
renegotiation_info extension that was added in RFC 5746),
it seems that a server that chooses SSL 3.0 should ignore
all extensions in the ClientHello except the
renegotiation_info extension.

An NSS server seems to process extensions when it uses
SSL 3.0:
http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/security/nss/lib/ssl/ssl3con.c&rev=1.165&mark=6145-6150#6145

2. When a client tries to resume an SSL 3.0 session,
should it cap the version advertised in ClientHello to
SSL 3.0, or more generally the version of the previous
session?
Assignee: nobody → wtc
Status: UNCONFIRMED → ASSIGNED
Ever confirmed: true
Uhm... SSLProtocol is set to "TLSv1 SSLv3", so TLS is on... do you mean _only_ TLS?

Anything else I can do?
Christoph:

In "ssltap log - connection #1 (success)" (attachment 598729 [details]),
search for "client_version" and "server_version".  You will
see that the browser advertised version 3.1 (TLS 1.0) in
ClientHello, but the server chose version 3.0 (SSL 3.0) in
ServerHello.

So you need to figure out why your server chose SSL 3.0 under
that condition.  I thought it was because TLS 1.0 was disabled.
But the SSLProtocol setting you showed seems to mean both
TLS 1.0 and SSL 3.0 are enabled.  So I don't know why your
server didn't choose TLS 1.0.

The Apache mod_ssl doc at
http://httpd.apache.org/docs/2.0/mod/mod_ssl.html#sslprotocol
seems to suggest that you need to use the plus sign '+'.  So
you can give "+TLSv1 +SSLv3" a try.
Ok I just changed the setting to "+TLSv1 +SSLv3" and indeed it seems to change the behaviour of Apache, at least it seems to work now WITH SSLSessionCache shmcb:${APACHE_RUN_DIR}/ssl_scache(512000).

This is a bit strange, as normally the +/- is only used to merge options from different and not the same directive.


So:
a) With TLS 1.0, evertyhing seems to work

b) This seems to be a bug (or documentation unclarity) with respect to which protocols get enabled.

c) It does no work with SSL 3.0... is this expected? Or a bug somewhere (NSS or Apache?)?
Eric from the Apache folks made some interesting comments at
https://issues.apache.org/bugzilla/show_bug.cgi?id=52703#c6
https://issues.apache.org/bugzilla/show_bug.cgi?id=52703#c8

If you haven't read this, it might be worth to do so.
I don't fully understand their implications...
comment #15
>c) It does no work with SSL 3.0... is this expected?

from comment #12
>Since SSL 3.0 does not define any extensions
There is no SNI in SSL3.0 since SNI appeared only in TLSv1 (=SSL3.1).

The NSS developer don't need additional information at the moment since the technical issue seems to be clear (comment #12)
So what does this mean now? Is everything "clear" and the bugs can all be closed?
(In reply to Wan-Teh Chang from comment #12)
> 1. If a server chooses SSL version 3.0, should it process
> the TLS extensions in the ClientHello?

 "A server that receives a client hello containing the "server_name"
  extension MAY use the information contained in the extension to guide
  selection of an appropriate certificate to return to the client,
  and/or other aspects of security policy.  In this event, the server
  SHALL include an extension of type "server_name" in the (extended)
  server hello."

 "The client SHOULD include the same server_name extension in the
  session resumption request as it did in the full handshake that
  established the session."

My recommendation is that if the server includes the server name indication extension in the server hello, regardless of whether the server selects SSL 3.0 or TLS 1.0, then we must include the server name indication extension in any resumption handshakes for that server.

More generally, I suggest that if the server includes ANY server hello extensions, then we should assume that the server can tolerate extensions, regardless of whether the negotiated protocol version is SSL 3.0 or TLS 1.0+; in the case of SSL 3.0 with at least one server extension, we should then send the same extensions we would send for a TLS 1.0 session resumption.

> Since SSL 3.0 does not define any extensions (except the
> renegotiation_info extension that was added in RFC 5746),
> it seems that a server that chooses SSL 3.0 should ignore
> all extensions in the ClientHello except the
> renegotiation_info extension.

AFAICT, nothing prohibits SSL 3.0 servers from implementing extensions.

> 2. When a client tries to resume an SSL 3.0 session,
> should it cap the version advertised in ClientHello to
> SSL 3.0, or more generally the version of the previous
> session?

This has been discussed repeatedly on the TLS WG mailing list. But, IIRC, there are bugs with IIS (or generically with SChannel?) that sort of forces this issue, one way or another. I cannot remember the details though.
Christoph:

From your point of view, everything is clear and the bugs can all be closed.

Both the NSS and Apache/mod_ssl teams can look into how their respective code
works under certain conditions.  But it's possible that neither team will spend
much time on them because SSL 3.0 is becoming less and less important.

NSS side:
1. Consider sending extensions in a SSL 3.0 ClientHello when trying to resume a
   session if the server previously included an extension other than renegotiation_info
   in ServerHello.
2. Consider not capping the protocol version in ClientHello to the version of the
   previous session when trying to resume a session.

(I think only #2 is worth doing because it is independent of SSL 3.0.)

Apache/mod_ssl side:
- Find out why Apache/mod_ssl cannot resume an SSL 3.0 session if the server name
  indicator is not provided in the ClientHello that tries to resume the session.
  See "ssltap log - connection #2 (failed)"
  (https://bugzilla.mozilla.org/attachment.cgi?id=598730) for the SSL packet
  trace that shows the session resumption failed and a full handshake was
  performed.
Status: ASSIGNED → RESOLVED
Closed: 12 years ago
Resolution: --- → WONTFIX
My experiments showed that IE also caps the protocol version advertised
in a ClientHello that tries to resume a session to the version of the
session.

I don't know of an SSL 3.0 website, so I enabled TLS 1.1 in IE and
tested against a TLS 1.0 website (https://www.verisign.com/).  IE
advertised version 3.2 (TLS 1.1) in ClientHellos that didn't have a
session ID, but advertised version 3.1 (TLS 1.0) in ClientHellos
that had a session ID.

So it may not be a good idea to change the behavior of NSS but I
still don't know why we should cap the protocol version like this :-)
Wan-Teh, there are implementations that are buggy with respect to RSA key exchange. Remember that the negotiated version number is included as part of the encrypted data in RSA key exchange, to avoid version rollbacks. IIRC, some implementations expect that the version offered in the client hello will appear there; other implementations expect that the version negotiated will appear there. IIRC, such problems may occur only with renegotiations and/or only with resumptions. I think that such capping has a positive effect when dealing with such things.
I found that capping the version advertised in ClientHello by the
version in the SSL session ID is recommended by the TLS RFCs.  So
I added a comment about that.
Attachment #606069 - Flags: review?(bsmith)
Wasn't 2246 obsoleted by 4346? Is it still recommended there?
This recommendation is still in TLS 1.2 (RFC 5246).  The only change
is that "should" is capitalized "SHOULD".

Since that piece of code was written before year 2000, I thought I
should cite the current TLS specification at that time.
Attachment #606069 - Flags: review?(bsmith) → review+
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: