Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-6211] iOS: Add Support for TLS to TCP Sockets

GitHub Issuen/a
TypeNew Feature
PriorityMedium
StatusOpen
ResolutionUnresolved
Affected Version/sRelease 1.8.0.1
Fix Version/sn/a
ComponentsiOS
Labelsexalture
ReporterShak Hossain
AssigneeEric Merriman
Created2011-11-17T07:21:22.000+0000
Updated2018-08-02T17:31:41.000+0000

Description

Problem

Facebook chat now requires a secure connection, so any apps that are using it are now broken until TLS is exposed through our TCP sockets.

Pull Request

https://github.com/appcelerator/titanium_mobile/pull/725

How to Test

Drop the following in an app.js. Look at the log. After some network traffic (~5 seconds) you should see the log message, "Socket secured!". (Note that around 10 seconds later, the connection will timeout and you'll be disconnected -- this is expected behavior.)
var win = Ti.UI.createWindow({
    backgroundColor: '#fff'
});

var states = {
    WAITING_FOR_FIRST_RESPONSE: 0,
    WAITING_FOR_START_TLS: 1,
    WAITING_FOR_PROCEED: 2,
    WAITING_FOR_SECURED: 3,
    DONE: 4,
    ERRORED: 5
};
var currentState = Ti.Android ? states.WAITING_FOR_FIRST_RESPONSE : states.WAITING_FOR_START_TLS;

var socket = Ti.Network.Socket.createTCP({
    host: 'chat.facebook.com', port: 5222,
    connected: function (e) {
        Ti.API.info('Socket opened!');
        Ti.Stream.pump(e.socket, read, 1024, true);
        socket.write(Ti.createBuffer({
            value: '<stream:stream xmlns:stream="http://etherx.jabber.org/streams" version="1.0" \
                xmlns="jabber:client" to="chat.facebook.com" xml:lang="en" \
                xmlns:xml="http://www.w3.org/XML/1998/namespace">'
        }));
    },
    secured: function (e) {
        Ti.API.info('Socket secured!');
    },
    error: function (e) {
        Ti.API.info('Error (' + e.errorCode + '): ' + e.error);
    },
    closed: function (e) {
        Ti.API.info('Socket closed!');
    }
});
socket.connect();

function write(msg) {
    Ti.API.info('State: ' + currentState + ', Wrote: ' + msg);
    socket.write(Ti.createBuffer({
        value: msg
    }));
}

function read(e) {
    try {
        if (e.buffer) {
            var received = e.buffer.toString();
            Ti.API.info('State: ' + currentState + ', Received: ' + received);
            switch (currentState) {

                case states.WAITING_FOR_FIRST_RESPONSE:
                    if (received.split('<?xml version="1.0"?><stream:stream ').length <= 1) {
                        Ti.API.error('Unexpected response from server while WAITING_FOR_FIRST_RESPONSE!');
                        return currentState = states.ERRORED;
                    }
                    return currentState = states.WAITING_FOR_START_TLS;

                case states.WAITING_FOR_START_TLS:
                    if (received.split('<stream:features><starttls ').length <= 1) {
                        Ti.API.error('Unexpected response from server while WAITING_FOR_START_TLS!');
                        return currentState = states.ERRORED;
                    }
                    write('<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>');
                    if (!Ti.Android) {
                        // Note: iOS requires that startTLS be called right after sending the above XML.
                        // This is required because of how reads and writes are queued up before a secure handshake.
                        socket.startTLS();
                        return currentState = states.WAITING_FOR_SECURED;
                    }
                    return currentState = states.WAITING_FOR_PROCEED;

                case states.WAITING_FOR_PROCEED:
                    if (received.split('<proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>').length <= 1) {
                        Ti.API.error('Unexpected response from server while WAITING_FOR_PROCEED!');
                        return currentState = states.ERRORED;
                    }
                    socket.startTLS();
                    return currentState = states.WAITING_FOR_SECURED;

                case states.WAITING_FOR_SECURED:
                    write('<stream:stream xmlns:stream="http://etherx.jabber.org/streams" version="1.0" \
                        xmlns="jabber:client" to="chat.facebook.com" xml:lang="en" \
                        xmlns:xml="http://www.w3.org/XML/1998/namespace">');
                    return currentState = states.DONE;

            }
        }
        else {
            Ti.API.error('Error: no e.buffer!');
        }
    } catch (ex) {
        Ti.API.error(ex);
    }
}

win.open();

Related Tickets

iOS: [TIMOB-6211] Android: [TIMOB-6212] APIDoc: [TIMOB-6213]

Comments

  1. Dawson Toth 2011-11-17

    Cloned off of [MOD-286]. Android and Doc tickets en route as well as pull requests for all of them.
  2. Dawson Toth 2011-11-17

    Opened pull request https://github.com/appcelerator/titanium_mobile/pull/725
  3. Dawson Toth 2011-11-17

    Revamped the description so that it is clear what this is addressing and how it can be tested.
  4. Matej 2014-04-19

    Still nothing changed? Can somebody explain me how can I develop secure software using Titanium if features like this one are not provided?
  5. Ingo Muschenetz 2014-04-22

    [~sko] Are you actually creating a direct TCP socket, or just using a HTTPS connection? TLS is already supported in that context, see http://www.appcelerator.com/blog/2012/11/the-titanium-sdk-and-certificate-validation/.
  6. Matej 2014-04-23

    Hi Ingo, yes I create a direct TCP connection to be more specific I have got my own module that provides connection using WebSocket protocol and this protocol works over TCP that unfortunately can't be encrypted... That's a big problem. This feature is not required only by me ,but several other people that mentioned this in Titanium Community Questions & Answers. // To be honest at this time every serious application uses encrypted connection (https, wss or directly TCP). I think this feature is quite important.
  7. Ingo Muschenetz 2014-04-23

    [~sko] is this a native module? How is it creating the TCP connection?
  8. Matej 2014-04-23

    No it is not a native module. The TCP connection is created exactly in the same way as in the example above so using Ti.Network.Socket.createTCP
  9. Matej 2014-06-13

    Ingo, please could you set higher priority for this issue? We are quite far with our application and we can't release it without encrypted connection. That's standard. Thank you a lot
  10. Ingo Muschenetz 2014-06-13

    [~sko] I currently cannot bump the priority. If you are interested, I believe you could take [~dtoth]'s PR and expand it.
  11. Harald Schlager 2014-12-18

    i would need a secure socket for a chat app for ios and android - is there timeline or a workaround ? thanks
  12. Sandro Lain 2017-09-05

    Hello to all Also in my work I find myself needing to create secure connections on TLS. Specifically for the creation of IoT app with proprietary protocol that require a minimum level of data transmission security.

JSON Source