Smack 4.1.0 - HOWTO Register SASL External Mechanism for TLS Client Authentication

Hello,

I am having trouble figuring out how to generate auth stanza for SASL EXTERNAL mechanism. Things have changed in this area from 3.1.0 so I am not finding anything like what I need to do so far. Below is my debug output. In summary,

  1. Stream init’ed between client and server
  2. Server is configured to require TLS and prefer EXTERNAL SASL mechanism via features advertising
  3. I found that SecurityMode.ifpossible generates the starttls negotiation
  4. The TLS handshake “apparently” happens just fine (I have a little more work to do with my keystore)
  5. Stream init’ed between client and server (again, as it should)
  6. Features offered again that include SASL EXTERNAL and compression

This is where I am stuck. I have registered the SASL External mechanism (I think).

02:20:45 PM SENT (0): <stream:stream xmlns=‘jabber:client’ to=‘MYSERVER.EXAMPLE.COM’ xmlns:stream=‘http://etherx.jabber.org/streams’ version=‘1.0’ xml:lang=‘en’>

02:20:45 PM RECV (0): <?xml version='1.0' encoding='UTF-8'?><stream:stream xmlns:stream=“http://etherx.jabber.org/streams” xmlns=“jabber:client” from=“MYSERVER.EXAMPLE.COM” id=“3959de67” xml:lang=“en” version=“1.0”>stream:featuresEXTERNAL</mecha nisms></stream:features>

02:20:45 PM SENT (0):

02:20:45 PM RECV (0):

02:20:46 PM SENT (0): <stream:stream xmlns=‘jabber:client’ to=‘MYSERVER.EXAMPLE.COM’ xmlns:stream=‘http://etherx.jabber.org/streams’ version=‘1.0’ xml:lang=‘en’>

02:20:46 PM RECV (0): <?xml version='1.0' encoding='UTF-8'?><stream:stream xmlns:stream=“http://etherx.jabber.org/streams” xmlns=“jabber:client” from=“MYSERVER.EXAMPLE.COM” id=“3959de67” xml:lang=“en” version=“1.0”>stream:featuresEXTERNAL</mecha nisms>zlib</stream:features>

*************** Here is the where I need to send <auth…/> stanza **************

02:20:46 PM SENT (0):

02:20:46 PM SENT (0): </stream:stream>

My code snippet:


XMPPTCPConnectionConfiguration.Builder connConfig = XMPPTCPConnectionConfiguration.builder()

.setCompressionEnabled(false)

.setHost(serverName)

.setServiceName(domainBareJid)

.setPort(serverPort)

.setSendPresence(true)

.setDebuggerEnabled(true)

.allowEmptyOrNullUsernames()

          .setSecurityMode(XMPPTCPConnectionConfiguration.SecurityMode.ifpossible);

      XMPPTCPConnectionConfiguration conf = connConfig.build();

try {

conn = new XMPPTCPConnection(conf);

SASLMechanism sm = new SASLExternalMechanism();

conn.connect();

SASLAuthentication.registerSASLMechanism(sm.instanceForAuthentication(conn)); (BTW, 4.1 API doc refers to v 3.1 supportSASLMechanism method)

} catch(SmackException | IOException | XMPPException six) {

System.out.println(six.toString());

           six.printStackTrace();

}

}


Thanks for any advice and guidance,

TT

Smack’s API re SASL EXTERNAL and ANONYMOUS is arguably not perfect yet. In your case it appears that the server does not accept the client cert, if there is one provided at all. Some hints when using SASL EXTERNAL:

  • Set security mode to ‘required’

  • You most likely want to use a custom SSLContext to inject your client certificate

  • Do not call registerSASLMechanism. SASL EXTERNAL will be automatically registered for you when Smack starts. (Especially the way you call registerSASLMechanism is wrong).

  • You may have to blacklist all other SASL mechanisms besides EXTERNAL

I removed the SASL External registration stuff and cleaned up my SSLContext keyStore issue and it all worked. Oh and I did set my security mode to required but did not need to blacklist anything as I am limiting the mechanisms for negotiation to EXTERNAL on the server. Thanks @Flow.