TLS connection example for Android

Is there a working current example (with latest version of Smack) of connecting to xmpp server using TLS?

I’m trying to write a very simple android app to connect to XMPP.jp. What do I have to do?

Thank you!

What have you tried?

AbstractXMPPConnection connection = new XMPPTCPConnection("username", "password", "xmpp.jp");
connection.connect();.login()

Yes, I tried this when server used to support non-TLS connections. Worked well. Now they are saying “Disable Non-TLS connection. Please use secure StartTLS conection”. So as far as I understand I have to have in my code, something like:


config.setSecurityMode(ConnectionConfiguration.SecurityMode.required);
config.setSocketFactory( SOMETHING );

In some examples I see that for SOMETHING they use ‘new DummySSLSocketFactory()’ but I’m not sure what it is.

Others are talking about getting a client certificate, signing it with CA, exporting it to local key store e.t.c. Really? I need to do this just to connect to XMPP server? I’m successfully connecting with Miranda IM. I dont see anywhere in Miranda where it would have a client certificate.

I can say you that everything what is named DummySSLSocketFactory or DummyTrustManager is a big trap as this “things” aren’t checking any certificates!

Anyway it’s true that you have to implement X509TrustManager or SSLSocketFactory to use TLS with Smack. Here are some guides to JSEE and Java PKI where you can see how to implement TrustManager.

You might want to check TrustManager which I have done for Spark, it allow users to set some exceptions from general PKI rules but I hope you will get the idea from it.

EDIT
As @Flow pointed me out: Smack can use STARTTLS out of box but you might need to add trusted certificate to your JRE TrustStore. Otherwise you might use config.setSSLContext for STARTTLS or (if you need direct TLS to 5223) config.setSSLSocketFactory.

That is not true if you are talking (also) about STARTTLS style TLS, which Smack does securely out of the box if the code snipped I gave above is used.

An XMPP trace would be extremely helpful. See also How to ask for help, report an issue and possible solve the problem yourself · igniterealtime/Smack Wiki · GitHub

1 Like

I’ve changed my code to use the snippet above. This is logcat of what happens (trace enabled):

11-22 14:52:36.266 15198-15574/com.example.crypsis.mchat D/SMACK: SENT (0): <stream:stream xmlns='jabber:client' to='xmpp.jp' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' from='mysmacktest1@xmpp.jp' xml:lang='en'>
11-22 14:52:36.516 15198-15575/com.example.crypsis.mchat D/SMACK: RECV (0): <?xml version='1.0'?><stream:stream id='15297572048157353985' version='1.0' xml:lang='en' xmlns:stream='http://etherx.jabber.org/streams' to='mysmacktest1@xmpp.jp' from='xmpp.jp' xmlns='jabber:client'><stream:features><starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'><required/></starttls></stream:features>
11-22 14:52:36.516 15198-15574/com.example.crypsis.mchat D/SMACK: SENT (0): <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'></starttls>
11-22 14:52:37.386 15198-15575/com.example.crypsis.mchat D/SMACK: RECV (0): <proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
11-22 14:52:37.386 15198-15575/com.example.crypsis.mchat W/AbstractXMPPConnection: Connection XMPPTCPConnection[not-authenticated] (0) closed with error
                                                                                   java.security.KeyStoreException: java.security.NoSuchAlgorithmException: KeyStore jks implementation not found
                                                                                       at java.security.KeyStore.getInstance(KeyStore.java:119)
                                                                                       at org.jivesoftware.smack.tcp.XMPPTCPConnection.proceedTLSReceived(XMPPTCPConnection.java:730)
                                                                                       at org.jivesoftware.smack.tcp.XMPPTCPConnection.access$1200(XMPPTCPConnection.java:149)
                                                                                       at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1053)
                                                                                       at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$300(XMPPTCPConnection.java:980)
                                                                                       at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:996)
                                                                                       at java.lang.Thread.run(Thread.java:818)
                                                                                    Caused by: java.security.NoSuchAlgorithmException: KeyStore jks implementation not found
                                                                                       at org.apache.harmony.security.fortress.Engine.notFound(Engine.java:190)
                                                                                       at org.apache.harmony.security.fortress.Engine.getInstance(Engine.java:139)
                                                                                       at java.security.KeyStore.getInstance(KeyStore.java:116)
                                                                                       at org.jivesoftware.smack.tcp.XMPPTCPConnection.proceedTLSReceived(XMPPTCPConnection.java:730) 
                                                                                       at org.jivesoftware.smack.tcp.XMPPTCPConnection.access$1200(XMPPTCPConnection.java:149) 
                                                                                       at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1053) 
                                                                                       at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$300(XMPPTCPConnection.java:980) 
                                                                                       at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:996) 
                                                                                       at java.lang.Thread.run(Thread.java:818) 
11-22 14:52:37.386 15198-15575/com.example.crypsis.mchat D/xmpp: ConnectionClosedOn Error!
11-22 14:52:37.396 15198-15447/com.example.crypsis.mchat E/(onCreate): SMACKException: java.security.KeyStoreException: java.security.NoSuchAlgorithmException: KeyStore jks implementation not found

Do you run on Android? Or which Java runtime environment is this?

Android :frowning:

Is this something to do with JKS vs BKS keystores?

Indeed, I usually use the Memorizing Trust Manager (MTM) on Android (and in fact most applications do that). and the process of plugging MTM into the Android app also selects the right keystore. Anyway, you could try calling ConnectionConfiguration.setKeystoreType(String) with “BKS” as argument. That possibly does the trick on Android.

As result of this, I’ve just commited https://github.com/igniterealtime/Smack/commit/32f681c6e5bf14ecf6138edee3f24748f69cd152 which will eventually hit Smack 4.2.2, making Smack easier to use out of the box on Android. Thanks everyone :slight_smile:

Thanks Flow for looking into this. Something is still not working though. Added

config.setKeystoreType(“BKS”);

to my code and getting this in log:


11-22 16:45:57.546 12346-12497/com.example.crypsis.mchat D/SMACK: SENT (0): <stream:stream xmlns='jabber:client' to='xmpp.jp' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' xml:lang='en'>
11-22 16:45:57.776 12346-12498/com.example.crypsis.mchat D/SMACK: RECV (0): <?xml version='1.0'?><stream:stream id='1650370811942426113' version='1.0' xml:lang='en' xmlns:stream='http://etherx.jabber.org/streams' from='xmpp.jp' xmlns='jabber:client'>
11-22 16:45:57.786 12346-12498/com.example.crypsis.mchat D/SMACK: RECV (0): <stream:features><starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'><required/></starttls></stream:features>
11-22 16:45:57.786 12346-12497/com.example.crypsis.mchat D/SMACK: SENT (0): <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'></starttls>
11-22 16:45:58.026 12346-12498/com.example.crypsis.mchat D/SMACK: RECV (0): <proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
11-22 16:45:58.026 12346-12498/com.example.crypsis.mchat W/AbstractXMPPConnection: Connection XMPPTCPConnection[not-authenticated] (0) closed with error
                                                                                   java.security.NoSuchAlgorithmException: KeyManagerFactory SunX509 implementation not found
                                                                                       at org.apache.harmony.security.fortress.Engine.notFound(Engine.java:190)
                                                                                       at org.apache.harmony.security.fortress.Engine.getInstance(Engine.java:139)
                                                                                       at javax.net.ssl.KeyManagerFactory.getInstance(KeyManagerFactory.java:77)
                                                                                       at org.jivesoftware.smack.tcp.XMPPTCPConnection.proceedTLSReceived(XMPPTCPConnection.java:747)
                                                                                       at org.jivesoftware.smack.tcp.XMPPTCPConnection.access$1200(XMPPTCPConnection.java:149)
                                                                                       at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1053)
                                                                                       at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$300(XMPPTCPConnection.java:980)
                                                                                       at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:996)
                                                                                       at java.lang.Thread.run(Thread.java:818)
11-22 16:45:58.036 12346-12498/com.example.crypsis.mchat D/xmpp: ConnectionClosedOn Error!
11-22 16:45:58.036 12346-12469/com.example.crypsis.mchat E/(onCreate): SMACKException: java.security.NoSuchAlgorithmException: KeyManagerFactory SunX509 implementation not found
11-22 16:45:59.266 12346-12346/com.example.crypsis.mchat D/ViewRootImpl: #1 mView = android.widget.LinearLayout{f676e4 V.E...... ......I. 0,0-0,0 #10203a7 android:id/toast_layout_root}

I see. I’ve uploaded 4.2.2-SNAPSHOT with a potential fix. Could you try that snapshot version with my initial code snipped, i.e. no more setting a custom keystore type. It hopefully should work then out of the box (if the servers certifcate is trusted by the system truststore).

More information on how to use Smack snapshots can be found at https://github.com/igniterealtime/Smack/wiki/How-to-use-Smack-snapshots

Heeeeeey! Works! Thanks so much! :slight_smile:

So, I wonder, will I ever need to do this:

?

No, see my reply above.