Closed Bug 989674 Opened 10 years ago Closed 10 years ago

Handshake failed (-8179) libpurple/ssl-nss.c:332 ssl_nss_handshake_cb

Categories

(Chat Core :: XMPP, defect)

All
Linux
defect
Not set
normal

Tracking

(Not tracked)

RESOLVED INVALID

People

(Reporter: BenB, Unassigned)

Details

Possibly a duplicate of:
bug 953612
bug 954499
bug 954523
bug 954534
bug 954548
bug 955437
bug 974438

In bug 741550, Jules Blok wrote:

 Jules Blok (New to Bugzilla) 2014-02-12 12:25:19 CET

I am also affected by this bug. Even when using libpurple in Instantbird that supports DNS SRV records it will only accept a certificate that matches the server domain while XMPP specifies the certificate should match the account domain.

This also happens when connecting directly to the server. I would advise to check the account domain in all cases, both in DNS SRV redirects and connecting directly to a server. This is according to the standard and makes it easier to live with the lack of DNS SRV support in Thunderbird.

[wrap] [tag] [reply] [−]
Private
Comment 5 Jules Blok (New to Bugzilla) 2014-02-12 12:32:58 CET

The correct behavior is specified in RFC3920 in section 1.5.8:
 
>   8.  Certificates MUST be checked against the hostname as provided by
>       the initiating entity (e.g., a user), not the hostname as
>       resolved via the Domain Name System; e.g., if the user specifies
>       a hostname of "example.com" but a DNS SRV [SRV] lookup returned
>       "im.example.com", the certificate MUST be checked as
>       "example.com".

[wrap] [tag] [reply] [−]
Private
Comment 6 aleth 2014-02-12 12:39:52 CET

(In reply to Jules Blok from comment #4)
> I am also affected by this bug. Even when using libpurple in Instantbird

For the record, the error message is
Error: Handshake failed  (-8179)
Source File: http://hg.instantbird.org/instantbird/raw-file/94b13a23dac6/purple/libpurple/ssl-nss.c
Line: 332
nss: ssl_nss_handshake_cb

Hardware: x86_64 → All
OS: Linux → All
[wrap] [tag] [reply] [−]
Private
Comment 7 Florian Quèze [:florian] [:flo] 2014-02-12 21:44:15 CET

(In reply to Jules Blok from comment #4)
> I am also affected by this bug. Even when using libpurple in Instantbird
> that supports DNS SRV records it will only accept a certificate that matches
> the server domain

Are you sure you haven't specified a value in the "Connect server" advanced option?

[tag] [reply] [−]
Private
Comment 8 Jules Blok (New to Bugzilla) 2014-02-13 10:52:44 CET

At first I didn't specify it but later for testing purposes I did. When I removed that option again today InstantBird kept crashing, I removed the account and added it again and suddenly the handshake worked correctly for once.

But now I get the constant crashes again, from the reports it looks like a null pointer is being freed. There are no InstantBird crash reports or any dumps to send. I'll look into the problem further.

[wrap] [tag] [reply] [−]
Private
Comment 9 Florian Quèze [:florian] [:flo] 2014-02-13 13:21:16 CET

(In reply to Jules Blok from comment #8)

> from the reports it looks like a
> null pointer is being freed. There are no InstantBird crash reports or any
> dumps to send.

I'm confused by you saying these 2 sentences at once. Are there crash reports to look at or not?

[tag] [reply] [−]
Private
Comment 10 Jules Blok (New to Bugzilla) 2014-02-13 13:43:56 CET

Created attachment 8375440 [details]
crash_report.txt

Sorry I forgot to mention that the report that said that a null pointer was being freed is the Mac OS X crash dialog. But it doesn't provide a stack trace or anything like that.

[tag] [reply] [−]
Private
Comment 11 Jules Blok (New to Bugzilla) 2014-02-13 13:45:05 CET

Oh wait, it does, I just looked over it.

[tag] [reply] [−]
Private
Comment 12 Ben Bucksch (:BenB) 2014-02-13 15:46:10 CET

Jules, could you please file a new bug about the crash and discuss there?
This one here is an important API design problem, and I don't want it clobbered with other discussion.

Ben Bucksch (:BenB) 2014-02-13 15:46:35 CET
Attachment #8375440 [details] - Attachment is obsolete: true
[wrap] [tag] [reply] [−]
Private
Comment 13 Jules Blok (New to Bugzilla) 2014-03-29 18:48:18 CET

I'm still affected by this problem:

> Error: Handshake failed  (-8179)
> Source File: http://hg.instantbird.org/instantbird/raw-file/94b13a23dac6/purple/libpurple/ssl-nss.c
> Line: 332
> nss: ssl_nss_handshake_cb

[tag] [reply] [−]
Private
Comment 14 Jules Blok (New to Bugzilla) 2014-03-29 18:55:22 CET

This is on InstantBird 1.5 and happens both with and without a server address specified.

I've already confirmed in the past that changing the certificate to one that matches the server address fixes the problem. It should be checking the account domain instead as explained above.

Thunderbird is also affected by this problem. When using Thunderbird I am able to add an exception as outlined here: http://askubuntu.com/questions/196107/unable-to-connect-to-xmpp-account-with-thunderbird
The error is due to an incorrect hostname check, when bug 741550 has been fixed then this bug should also be fixed.
(In reply to Jules Blok from comment #1)
> The error is due to an incorrect hostname check, when bug 741550 has been
> fixed then this bug should also be fixed.

I don't think these 2 problems are related. I'm not even sure what the problem here is.

The behavior with the libpurple XMPP plugin is:
- the certificate is checked against the servername that's part of the username, even if a DNS SRV request says that we need to connect to another server.
- If the user manually specifies a 'connect server' to use instead of doing a DNS SRV query, then the certificate is checked against that user-specified connect server.

I don't see any issue with this behavior, and AFAIK it's the only way to connect to Google Talk for Google Apps accounts.


The problem in bug 741550 is that "the certificate is checked against the servername that's part of the username, even if a DNS SRV request says that we need to connect to another server" is currently impossible to implement in the JavaScript implementation of XMPP that we have, because of some missing platform APIs.
You're right, there is no direct relation, but I am able to work around the problem somehow.

Here are the exact steps I've done to fix the problem:

> 1. Confirm the handshake is still failing
> 2. Specify a connect server
> 3. Confirm the handshake is still failing (this time due to the hostname mismatch)
> 4. Log in to the XMPP server and change the certificate to match the connect server
> 5. Confirm a successful connection
> 6. Revert changes: remove connect server and offer previous certificate
> 7. Confirm successful connected

If I remove the account and re-add it the problem is still fixed. Only if I remove all application data I am able to reproduce the problem again. I've used the steps above to fix the problem three times.
So what is the initial server name, what's the server name you are specifying as "connect server", and what's the name in the certificate?

I still don't understand why you are setting a "connect server".
I'll use examples, as the specific hostname is irrelevant. The initial server name is 'example.com' and the connect server is 'xmpp.example.com'. The DNS SRV records for 'example.com' are set to point to 'xmpp.example.com' and all other clients are able to successfully connect.

The certificate offered by the server is for 'example.com', but I also have a valid certificate for 'xmpp.example.com'. Unfortunately, I can only offer one at the same time.

I'm unable to initially connect to 'example.com' due to the failed handshake, it will only successfully connect if it has somehow been able to successfully connect before.

The only other way to successfully connect is to specify 'xmpp.example.com' as the connect server. However this requires me to change the certificates on the server, because it checks for the 'xmpp.example.com' hostname.

After this is done and I have successfully connected at least once I can revert all the changes and still be able to connect. However, if I were to delete all InstantBird configuration data the handshake will fail again.

It's a very strange problem.
I just tested the nightly version 1.6a1pre (20140330041712). Everything I've said also applies for that version. It fails the initial handshake with the same error code (-8179).

What's strange is after reverting all changes and successfully connecting without a "connect server" specified I get this error:

> Error: Couldn't look up SRV record. DNS name does not exist. (9003).
> Source File: http://hg.mozilla.org/comm-central/raw-file/9afe71c06fa3/purple/libpurple/dnssrv.c
> Line: 589
> Source Code:
> dnssrv: res_main_thread_cb

But it is still able to successfully connect. I've double checked the records, there is a SRV record and all other clients can successfully connect.
This really looks like a problem related to DNS SRV queries failing (if a DNS SRV query fails, the libpurple plugin will fallback to the hostname that's part of the user name (example.com in your case)).
(In reply to Florian Quèze [:florian] [:flo] from comment #2)
> The behavior with the libpurple XMPP plugin is:
> - the certificate is checked against the servername that's part of the
> username, even if a DNS SRV request says that we need to connect to another
> server.
> - If the user manually specifies a 'connect server' to use instead of doing
> a DNS SRV query, then the certificate is checked against that user-specified
> connect server.

That behaviour is correct per XMPP spec.
>> - If the user manually specifies a 'connect server' to use instead of doing
>> a DNS SRV query, then the certificate is checked against that user-specified
>> connect server.
> That behaviour is correct per XMPP spec.

I'd say the spec is ambiguous here, since it does not specify whether the "connect server" or the account domain is considered the "hostname".

If we look at consistency: the account domain is usually considered the "hostname", so the certificate should be checked against the account domain. This is the most convenient since it allows you to bypass the DNS SRV entry, which has a lot of support problems currently, without having to add a security exception (which makes SSL useless against MITM attacks). 

The only reason I see for the current behaviour is as a work around to serve multiple XMPP domains with only one certificate.
The spec is unambiguous: Whatever the end user sets is what we must check the cert against. We are to ignore DNS SRV.
RFC 3920, Section 5.1, point 8 <http://xmpp.org/rfcs/rfc3920.html>:
"Certificates MUST be checked against the hostname as provided by the initiating entity (e.g., a user), not the hostname as resolved via the Domain Name System; e.g., if the user specifies a hostname of "example.com" but a DNS SRV [SRV] lookup returned "im.example.com", the certificate MUST be checked as "example.com"."
I was talking specifically about the case where the 'connect server' is specified. I think it makes a lot more sense to check against the account domain instead of the 'connect server'.

Since you could consider the 'connect server' a user-specified domain resolution, which should be ignored for the purpose of checking the certificate as specified in RFC 3920 5.1.8.
The "connect server" field we have is not something that's part of the spec.

The current behavior with the 'connect server' field is required to connect some Google Talk accounts, so we won't change it.

If we want to do something useful with this bug, we should focus on figuring out why DNS SRV requests failed for you (if your server is well configured and your DNS server works, there's no reason for you to touch the "connect server" field at all).
The error was caused by missing intermediate CAs in the SSL certificate. The solution to the problem is to combine the key and all necessary certificates into one PEM file and serve that.

This can be easily done with a simple concatenation:

> cat example.key example.crt intermediate.crt > example.pem

This issue can be closed.
(In reply to Jules Blok from comment #5)

> The only other way to successfully connect is to specify 'xmpp.example.com'
> as the connect server. However this requires me to change the certificates
> on the server, because it checks for the 'xmpp.example.com' hostname.
> 
> After this is done and I have successfully connected at least once I can
> revert all the changes and still be able to connect. However, if I were to
> delete all InstantBird configuration data the handshake will fail again.
> 
> It's a very strange problem.

The reason for this is that the cert for xmpp.example.com contained the intermediate CA, which got cached by NSS after using it once, so after connecting once to xmpp.example.com, connections to example.com worked.
Status: NEW → RESOLVED
Closed: 10 years ago
Resolution: --- → INVALID
You need to log in before you can comment on or make changes to this bug.