Single socket TLS Encryption solution

Hi everybody!

I built an extention to the XMPPConnection.as class to enable connecting to a server, negotiating TLS and encrypting further communication all on a single socket connection. The class wraps the socket into the TLSSocket when encryption is negotiated.

This is built on Base rev. 11209, because the project I’m working on is stable with this version. Updating it should not cost alot of time, i assume. I am planning on writing an extention for the negotiating. It’s not very elegant now. Please let me know if there are other “proceed” node types, other than the one used for TLS negotiating.

I have left in/built in some checks for future compression negotiating.

I have only tested it with the Flex Builder.

Credit has to go out to this thread:

I pretty much got it working trough studying all the solutions there. I also used it as a template

for the description down here.

(New) Things you need:

  • AS3 version of XIFF

    • Base rev 11209

    • attached XMPPTLSConnection.as in the same directory as XMPPConnection.as

  • Latest as3Crypto from the repository (It’s now rev 28)

(New) Things to note beforehand.

  • This only works with a socket connection. Not with BOSH.

  • I’m not sure but I think crypto will only work with RSA certs.

  • Crypto does not work with self signed certificates (detault certs generated by openfire). This can be bypassed by changing line 802 in TLSEngine.as from “if(_config.trustAllCertificates)” to “if(true)”. Don’t forget to put back the check when you get a certificate for your server! =] You can of course also supply your own configuration.

To use TLS simply use the following boolean flag on your interface scripting that handles the initial connect. Here is my example code block.

xconn.username = usernameti.text;

xconn.password = passwordti.text;

xconn.server = DEFAULT_SERVER;

xconn.tls = true;

xconn.connect();

Behaviour:

xconn.tls defaults to false. If it is false it will connect unencrypted like usual.

If TLS is enabled with xmpp.tls = true and the server does not have TLS it will not connect.

If TLS is not enabled but the server requires TLS it will be automatically enabled and connect.

I haven’t had time to write a demo app or test it extensively.

Let me know if this works for you!

Cheers
Single Socket TLS Connection.zip (13835 Bytes)

Has anybody gotten this to work against ejabberd? When I try it, I get:

Send XML on stream = “<?xml version='1.0'?><stream:stream xmlns=‘jabber:client’ xmlns:stream=‘http://etherx.jabber.org/streams’ id=‘2147303942’ from=‘xmpp.irok2.com’ xml:lang=‘en’>stream:error</stream:error></stream:stream>”

in my ejabberd logs. It’s not clear what’s causing this, though, as the previous received data is:

Received XML on stream = “<auth mechanism=“PLAIN” xmlns=“urn:ietf:params:xml:ns:xmpp-sasl”>…”

Thanks,

Andrew.

I should mention that replacing the XMPPTLSConnection with a regular XMPPConnection works.

I had a look at what was going on here, and the fix is simple enough. According to RFC 3920, after successful TLS negotiation, you need to start a new stream. The XMPPTLSConnection was sending the authentication stanzas instead. To fix it, just send the opening stream tag again. See attached patch.
0001-ROK-567-Start-new-stream-after-TLS.patch.zip (910 Bytes)

Interesting patch.

Have you signed the contributor agreement and sent it to Igniterealtime?

If you have done this, I can commit this patch.

No, but I can start that process if you need it.

Andrew.

Pardon me for not assisting you with your prior issues Andrew. It seems you got it working anyway. Congrats.

The openfire we are using seems to work okay without the adjustment.

I have not done a code contribution actually for the original code, as I first wanted to get some responses from the community.

Could still do this together with your patch.

Cheers,

Folkert

Step 7 in section 5.2 of RFC 3920 (from http://www.ietf.org/rfc/rfc3920.txt) is:

  1. If the TLS negotiation is unsuccessful, the receiving entity MUST
    terminate the TCP connection. If the TLS negotiation is
    successful, the initiating entity MUST initiate a new stream by
    sending an opening XML stream header to the receiving entity (it
    is not necessary to send a closing tag first, since the
    receiving entity and initiating entity MUST consider the original
    stream to be closed upon successful TLS negotiation).

So a server that accepts data on the original stream would seem to be in violation of the RFC.

Andrew.

It works with and also without your patch on OpenFire 3.6.4. No wonder I didnt notice

and you didnt get it to work on ejabberd.

Seems we found an OpenFire issue. I was just scanning their open issues but I can’t find anything related. Don’t have much time at the moment to check, though.

please see http://www.igniterealtime.org/community/message/202485