Asmack SSL connection issue on Android 5.0

Hi all,

I have a problem about SSL secure connection blocked with asmack 4.0.5 on Android 5.0. I also tried smack 4.1 alpha 1, but got same blocked result.

Following code snippet is working fine on Android 4.4.4:

ConnectionConfiguration connConfig = new ConnectionConfiguration(XMPP_CONNECT_HOST, XMPP_CONNECT_PORT, XMPP_SERVICE_NAME);

connConfig.setSecurityMode(ConnectionConfiguration.SecurityMode.enabled);

connConfig.setSocketFactory(new DummySSLSocketFactory());

XMPPConnection connection = new XMPPTCPConnection(connConfig);

connection.connect();

After upgrade to Android 5.0, connection.connect() doesn’t return and seems blocked.

I am still try to dig into the source code to find a solution, but I am happy to know if anyone has similar problems or has possible fixes already.

Thanks,

Johnny

1 Like

Hard to diagnose the issue with the information at hand. I suggest you attach an debugger to determine the place where it blocks (and maybe even the reason why it blocks).

Hi Flow,

I use SmackConfiguration.DEBUG_ENABLED = true; to enable debugger. But didn’t get any further information, it didn’t output first stream packet:

<stream:stream to=“XXX.XXX.XXX.XXX” xmlns=“jabber:client” xmlns:stream=“http://etherx.jabber.org/streams” version=“1.0”>

I currently found it blocks at socket.getInputStream() in function initReaderAndWriter().

Thanks.

Johnny

Hi Flow,

I use Openfire 3.9.3 at server side.

Thanks,

Johnny

hi, for this question,l have saw it .and this is my solve method:see code:

config = new ConnectionConfiguration(host, port);

config.setSASLAuthenticationEnabled(false);

config.setSecurityMode(SecurityMode.disabled);

conn = new XMPPConnection(config);

then it doesn’t occur the problem about SSL secure;

Hi hai,

Thanks for your help, I do need enable SSL secure connection not just disable it.

I found an issue of Android 5.0 but not sure this is related:

Issue 1058 - android-developer-preview - Android L SSL TLS v1.0 Socket Bug - A public project for reporting issues wi…

Currently, all I knew is the code stalled at “socket.getInputStream()” function call in the function “initReaderAndWriter()”.

Thanks,

Johnny

The issue report mentions a SSLHandshakeException, are you sure that Smack just stalls and there is no other (related) Exception in the logs?

Hi Flow,

Yes, the connect() call is stall there without no responding. I just upgraded the last build of Android 5.0 of Nexus 5, but the problem is not solved.

Thanks,

Johnny

Hi,

I found a possible solution for this, in the your DummySSLSocketFactory:

public Socket createSocket(String s, int i) throws IOException {

SSLSocket socket = (SSLSocket)factory.createSocket(s, i);

***socket.setEnabledCipherSuites(socket.getSupportedCipherSuites());***

return socket;

}

Not sure is this relative to: Android 5.0 Changes | Android Developers

Thanks.

Johnny

Hi,

I have the same problem here. I have no problem if using Android 4.4.4 via SSL, however when I use Android 5 with asmack (4.0.8) to connect to Openfire (3.9.3) via SSL, it throws the following exception:

org.jivesoftware.smack.SmackException$NoResponseException

at org.jivesoftware.smack.XMPPConnection.throwConnectionExceptionOrNoResponse(XMPP Connection.java:548)

at org.jivesoftware.smack.tcp.XMPPTCPConnection.throwConnectionExceptionOrNoRespon se(XMPPTCPConnection.java:867)

at org.jivesoftware.smack.tcp.PacketReader.startup(PacketReader.java:113)

at org.jivesoftware.smack.tcp.XMPPTCPConnection.initConnection(XMPPTCPConnection.j ava:482)

at org.jivesoftware.smack.tcp.XMPPTCPConnection.connectUsingConfiguration(XMPPTCPC onnection.java:440)

at org.jivesoftware.smack.tcp.XMPPTCPConnection.connectInternal(XMPPTCPConnection. java:811)

at org.jivesoftware.smack.XMPPConnection.connect(XMPPConnection.java:396)

Here are my code snippets:

ConnectionConfiguration config = new ConnectionConfiguration(DOMAIN, 5222);

SASLAuthentication.supportSASLMechanism(“DIGEST-MD5”);

config.setSecurityMode(ConnectionConfiguration.SecurityMode.required);

config.setReconnectionAllowed(false);

config.setSendPresence(true);

config.setRosterLoadedAtLogin(false);

config.setSocketFactory(new MySocketFactory());

config.setLegacySessionDisabled(false);

config.setDebuggerEnabled(true);

trustStore = KeyStore.getInstance(“BKS”);

trustStore.load(context.getResources().openRawResource(R.raw.keystore), password);

TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());

trustManagerFactory.init(trustStore);

SSLContext sslContext = SSLContext.getInstance(“TLS”);

sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());

config.setCustomSSLContext(sslContext);

Here is the debug information for your reference:

SENT (0): <stream:stream to=“server” xmlns=“jabber:client” xmlns:stream=“http://etherx.jabber.org/streams” version=“1.0”>

RCV (0): <?xml version='1.0' encoding='UTF-8'?>

      <stream:stream xmlns:stream="[http://etherx.jabber.org/streams](http://etherx.jabber.org/streams)" xmlns="jabber:client" from="server" id="b938aff2" xml:lang="en" version="1.0">

RCV (0): stream:features

DIGEST-MD5

PLAIN

CRAM-MD5

</stream:features>

SENT (0):

RCV (0):

SENT (0): </stream:stream>

Regards,

Jeffrey

config.setSocketFactory(new MySocketFactory());

What does MySocketFactory?

Hi Flow,

It is a class inherited from SocketFactory, I want to make sure the socket connection can be kept longer than the ping interval before connection timeout.

Jeffrey

private static final SocketFactory defaultFactory = SocketFactory.getDefault();

private Socket socket;

@Override

public Socket createSocket(String arg0, int arg1) throws IOException {

socket = defaultFactory.createSocket(arg0, arg1);

setSockOpt(socket);

return socket;

}

@Override

public Socket createSocket(InetAddress host, int port) throws IOException {

socket = defaultFactory.createSocket(host, port);

setSockOpt(socket);

return socket;

}

@Override

public Socket createSocket(String host, int port, InetAddress localHost,

int localPort) throws IOException {

socket = defaultFactory.createSocket(host, port, localHost, localPort);

setSockOpt(socket);

return socket;

}

@Override

public Socket createSocket(InetAddress address, int port,

InetAddress localAddress, int localPort) throws IOException {

socket = defaultFactory.createSocket(address, port, localAddress, localPort);

setSockOpt(socket);

return socket;

}

private static void setSockOpt(Socket socket) throws IOException {

socket.setKeepAlive(false);

socket.setSoTimeout(1000 * 60 * 17);

socket.setTcpNoDelay(false);

}