Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Developer
dkonigs
Posts: 241
Registered: ‎07-25-2008
My Device: Bold 9900
Accepted Solution

Switching to SSL after connection opened (i.e. STARTTLS)

While some protocols let you connect directly with SSL enabled (passing "ssl://" to Connector.open), others require that you first open a plain TCP socket connection, then send the "STARTTLS" command, then start talking SSL.

What I want to know, is how you switch from a plain StreamConnection to a SecureConnection in mid-flight.

 

I noticed that when I do open a secure connection, Connector.open actually instantiates TLS10Connection. This class does have a constructor which allows it to wrap an existing StreamConnection.  However, my own experimentation has shown that I cannot even do what I want with directly instantiating TLS10Connection (I tried on the simulator).  Any and all attempts end in some sort of exception, as that class only wants to be created to wrap a not-yet-opened StreamConnection.

 

Its not that uncommon to find protocols that want you to connect in-the-clear, do that initial capabilities check, then switch to SSL mode, so this is becoming a real hurdle.  While those protocols sometimes are implemented with a straight-SSL port, that is often a less common implementation.

Please use plain text.
Developer
peter_strange
Posts: 19,599
Registered: ‎07-14-2008
My Device: Not Specified

Re: Switching to SSL after connection opened (i.e. STARTTLS)

There is a recent post in the old forum, regarding an issue that seems similar to what you are asking.  See:

http://www.blackberry.com/developers/forum/thread.jsp?forum=1&thread=13238

 

 

Please use plain text.
Developer
dkonigs
Posts: 241
Registered: ‎07-25-2008
My Device: Bold 9900

Re: Switching to SSL after connection opened (i.e. STARTTLS)

Yeah, that post basically says "Sorry, you can't do that."  Was kinda hoping that with a newer, far more active forum, I might get a better response.

 

The only workable solution I've even heard of so far, is completely managing the SSL part inside my app.  To do that, I'd use some standalone J2ME-compatable SSL library like Bouncy Castle.

 

Please use plain text.
New Developer
ennova2005
Posts: 96
Registered: ‎07-26-2008
My Device: Not Specified

Re: Switching to SSL after connection opened (i.e. STARTTLS)

Style of the new forum wont change the substance ;-)


We had to switch to BouncyCastle as well - which works fine but increases the size of the code.  

One hopes that RIM will fix this ( as well as correct the documentation that seems to imply you can do the switch but in practice doesnt work)

 

Please use plain text.
New Developer
ennova2005
Posts: 96
Registered: ‎07-26-2008
My Device: Not Specified

Re: Switching to SSL after connection opened (i.e. STARTTLS)

Bumping this up.

 

At the recent Blackberry Developers Conference a number of speakers from RIM ( Mike K etc. ) indicated that they believed that this should work fine. 

 

I am hoping that they would comment with a code fragment that shows how starttls can be made to work 

 

Please use plain text.
Developer
dkonigs
Posts: 241
Registered: ‎07-25-2008
My Device: Bold 9900

Re: Switching to SSL after connection opened (i.e. STARTTLS)

Which reminds me...  I directly asked Mike K. this question in the "Ask the Experts" area, and while he didn't know the answer, it did ring a bell and he mentioned someone else did know.  Unfortunately he hasn't had a chance to follow up with the E-Mail I sent him after the conference, though I can imagine they've all been swamped following up on all the things we got the chance to tell them.
Please use plain text.
New Developer
ennova2005
Posts: 96
Registered: ‎07-26-2008
My Device: Not Specified

Re: Switching to SSL after connection opened (i.e. STARTTLS)

Is there an update on this issue from RIM ?

 

 

Please use plain text.
Developer
dkonigs
Posts: 241
Registered: ‎07-25-2008
My Device: Bold 9900

Re: Switching to SSL after connection opened (i.e. STARTTLS)

I can't believe I didn't figure this out earlier, but assuming you can build code that instantiates TLS10Connection (requires the crypto signing key, not sure of any remaining legal issues exist there), you actually can do this.  It just requires a little bit of trickery.

 

First, you open your connection as usual:

 

StreamConnection socket = (StreamConnection)Connector.open(

                "socket://" + serverName + ":" + serverPort,

                Connector.READ_WRITE, true);
DataInputStream input = socket.openDataInputStream();
DataOutputStream output = socket.openDataOutputStream();

 

 

Then you do whatever protocol I/O is necessary to handshake with the server, query its capabilities, etc.  Finally, you send "STARTTLS\r\n", and now want to switch the mode of the socket.  Here's how:

 

TLS10Connection tlsSocket = new TLS10Connection(
        new StreamConnectionWrapper(socket, input, output),
        serverName + ":" + serverPort,
        true);

 

input = tlsSocket.openDataInputStream();

output = tlsSocket.openDataOutputStream();

 

The secret to this is StreamConnectionWrapper.  You see, if you try creating a TLS10Connection with the original StreamConnection, it will try opening the input/output streams again.  This causes I/O exceptions which break everything.  So, here's the extremely simple code to the wrapper:

 

    private class StreamConnectionWrapper implements StreamConnection {
        private StreamConnection stream;
        private DataInputStream dataInputStream;
        private DataOutputStream dataOutputStream;
       
        public StreamConnectionWrapper(

                StreamConnection stream,

                DataInputStream dataInputStream,

                DataOutputStream dataOutputStream) {
            this.stream = stream;
            this.dataInputStream = dataInputStream;
            this.dataOutputStream = dataOutputStream;
        }
       
        public DataInputStream openDataInputStream() throws IOException {
            return dataInputStream;
        }
        public InputStream openInputStream() throws IOException {
            return dataInputStream;
        }
        public void close() throws IOException {
            stream.close();
        }
        public DataOutputStream openDataOutputStream() throws IOException {
            return dataOutputStream;
        }
        public OutputStream openOutputStream() throws IOException {
            return dataOutputStream;
        }
    }

 

And that's all there is to it!  I seriously can't believe I didn't think of this workaround years ago.

 

 

Please use plain text.
New Developer
ennova2005
Posts: 96
Registered: ‎07-26-2008
My Device: Not Specified

Re: Switching to SSL after connection opened (i.e. STARTTLS)

 

We got it working couple of months ago using the same or similar work around technique - should have posted the results. Sorry.

 

The only annoyance  we found is the native TLS libs dont let you over ride the certificate validation, while the external library we were using did.  Most of the servers our users use dont have CA issued certificats and it introduces several extra steps during initial establishments as the process for storing the certs in the cert store etc is a bit confusing for an ordinary user. 

 

I would be interested to know if you see bettery baterry consumption with the native lib compared to 3rd party libs i.e. if these are optimized in any way. It certainly saves on the memory as we dont have to pack the external  lib.

Please use plain text.
Developer
dkonigs
Posts: 241
Registered: ‎07-25-2008
My Device: Bold 9900

Re: Switching to SSL after connection opened (i.e. STARTTLS)

Certificate-related popups have certainly been annoying my users quite a bit as well.  For my own personal use cases, I get them through CAcert.org, and use the BlackBerry Desktop software to load the CAcert root certificate on my BB.  For everyone else, that's probably a bit too much to ask.

 

While we can debate the whole source of this issue (and get into a whole rant over SSL itself and the CA system), that probably wouldn't be very productive here.  But we do have a couple of separate issues to overcome before people stop complaining.  Self-signed certs (easy to overcome if you load the CA cert with the desktop software), and invalid (expired or name mismatch) certs.  Even some desktop clients whine about invalid certs, but at least some of them let you store a permanent exception.

 

As far as battery life, I don't know of any easy and reproducible way to measure that (other than time-consuming device testing, with too many other variables).  I've got several use cases in my app where I'm curious to know (mainly about overhead of maintaining a connection versus periodically opening one, especially with TCP and/or SSL handshake overhead).

Please use plain text.