Configuring Openfire for X.509 Certificates based authentication for clients

I have tried configuring openfire for client certificate authentication. Tried instructions from various blogs posts like the following but in vain

https://developer.pidgin.im/wiki/Openfire%20Client%20SSL%20Authentication%20How- to

http://forum.ag-software.net/thread/1274-Cannot-connect-using-Openfire-using-def ault-setti

Has anyone configured openfire for client certificated based authentication? if so could you please share the steps? I need it for a google summer of code project called ipop, which uses xmpp. If there are any developers out there, who implemented the feature, Could you please share the test scripts to test your code, yet least, which would help me figure out the exact setup requirements.

Here is a case study showing how I implemented XMPP Client Certificate Authentication with Openfire.

Scenario:

User “Andrew” installs a Windows XMPP Client along with a certificate signed by the local Certification Authority.

The certificate has a private key and owner designated as “CN=andrew@mychat.mydomain.local”.

The first time Andrew runs the XMPP Client, he gets presented with a dialog to enter JID.

He enters “andrew@mychat.mydomain.local”, hits “Login” button and after a short delay, is

presented with a roster containing mydomain.local contacts.

Technical Specs:

The XMPP Client uses Jivesoftware Smack library v4.1.4.

The Openfire XMPP Server v3.10.0 is hosted on Linux box “mychat”.

The Server listens for XMPP clients on port 5222 and requires TLS security for all connections.

The Openfire sole SASL Mechanism to be employed is “EXTERNAL”.

Openfire Configuration:

Set up keystore and truststore following instructions http://www.javacodegeeks.com/2015/02/secure-openfire-xmpp-server.html.

This describes how to install Certificate trust chain in both the the keystore and truststore.

The client.truststore file co-located with keystore and truststore must also contain the Certificate trust chain.

BEWARE: Use the default “changeit” keystore password initially to avoid issues with logging in to the admin console after making these changes.

Also, if on Linux, ensure the client.truststore, keystore and truststore files are owned by the Openfire user.

These are what I believe are the significant property settings for Client Certificate Authentication in this scenario:

xmpp.client.cert.policy = needed

xmpp.client.certificate.accept-selfsigned = false

xmpp.client.certificate.verify = true

xmpp.client.certificate.verify.chain = true

xmpp.client.certificate.verify.root = true

xmpp.client.certificate.verify.validity = true

xmpp.client.tls.policy = true

xmpp.domain = mychat.mydomain.local

xmpp.socket.ssl.active = true

sasl.mechs = EXTERNAL

In Security Settings - Client Connection Security: Select “Required”.

Note I also had an “xmpp.client.certificate.crl” property set but this appears to be optional judging from the code.

Certificate Revocation Lists are important for production systems.

Openfire Troubleshooting:

Turn on SSL debugging on the client using Java VM argument “-Djavax.net.debug=ssl”. If the Openfire configuration is correct,

you will see the “mydomain” CA Certificate listed during SSL Handshaking under the CertificateRequest Cert Authorities:

*** CertificateRequest

Cert Types: RSA, DSS, ECDSA

Cert Authorities:

<CN=mydomain-ROOT-CA>

*** ServerHelloDone

matching alias: andrew@mychat.mydomain.local

*** Certificate chain

chain [0] = [

[

Version: V3

Subject: CN=andrew@mychat.mydomain.local

…

If the CA Certificate is missing, then a “bad_certificate” error is reported.

The same error is reported if the client certificate is missing from the client application keystore or

the keystore is omitted when setting up the SSL Context. This problem can be determined from the debug log

by whether there is a line at the start of the log containing something like “found key for : andrew@mychat.mydomain.local”.

If the certificate chain is missing from client.truststore, then there is NullPointerException generated from within the SSL implementation code.

If the certificate chain is missing from trustore, then this error occurs after successful SSL Handshake completion:

org.jivesoftware.util.CertificateManager - Path builder: unable to find valid certification path to requested target

Smack Configuration:

Here is a routine to create an XMPPTCPConnectionConfiguration object which can be used as a guide:

private XMPPTCPConnectionConfiguration getConfiguration(

String host /* eg. “mychat.mydomain.local” */,

String keypass /* Keystore password */ )

throws NoSuchAlgorithmException,

KeyStoreException,

CertificateException,

FileNotFoundException,

IOException,

UnrecoverableKeyException,

KeyManagementException

{

XMPPTCPConnectionConfiguration.Builder configBuilder = XMPPTCPConnectionConfiguration.builder();

// Allow empty password

configBuilder.allowEmptyOrNullUsernames();

// Host and service name are the same. Port is 5222 by default.

configBuilder.setServiceName(host);

configBuilder.setHost(host);

// JKS with private key placed in home directory

File keystorePath = new File(System.getProperty(“user.home”), “andrew.mychat.jks”);

// Create SSLContext same as Openfire ie. the “TLSv1”

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

KeyStore ks = KeyStore.getInstance(“JKS”);

ks.load(new FileInputStream(keystorePath), keypass.toCharArray());

KeyManagerFactory kmf = KeyManagerFactory.getInstance(“SunX509”);

kmf.init(ks, keypass);

KeyManager[] kms = kmf.getKeyManagers();

sslContext.init(kms, null, new java.security.SecureRandom());

configBuilder.setCustomSSLContext(sslContext);

XMPPTCPConnectionConfiguration config = configBuilder.build();

return config;

}

Note that the client keystore contains the certificate chain and this is particularly important if there are intermediate CA certificates in the chain.

Final Comments:

The most important thing I want to say is that Client Certificate Authentication does work on Openfire V3.10 for TLS on port 5222.

I failed to get it working until I followed the keystore and truststore setup procedure on the javacodegeeks site.

Note that “xmpp.client.certificate.accept-selfsigned = false” means self-signed client certificates are not supported.

That is not to there may be a work-around, but the designers of SSL were keen to prevent “man-in-middle” attacks and

self-signed certificates break the spirit of their intentions.

1 Like

Hi Andrew

I have followed the exact steps as mentioned in your post. But when I am trying to authenticate a client that has certificate chain, Openfire throws an exception

SASLAuthentication: EXTERNAL authentication via SSL certs for c2s connection

2016.05.27 09:29:38 WARN [socket_c2s-thread-2]: org.jivesoftware.util.CertificateManager - Unkown exception while validating certificate chain: Index: 0, Size: 0

2016.05.27 09:29:38 DEBUG [socket_c2s-thread-2]: org.jivesoftware.openfire.net.SASLAuthentication - SASLAuthentication: EXTERNAL authentication requested, but EE cert untrusted.

How to solve this issue?

Hi, I have done full server setup (Openfire v4.2.1) and client (java custom Smack client), and I can see my certificate verified by Openfire server :

2018.01.26 16:25:57 DEBUG [NioProcessor-15]: org.jivesoftware.openfire.keystore.OpenfireX509TrustManager - Attempting to verify a chain of 1 certificates.
2018.01.26 16:25:57 DEBUG [NioProcessor-15]: org.jivesoftware.openfire.keystore.OpenfireX509TrustManager - Attempting to accept the self-signed certificate of this chain of length one, as instructed by configuration.
2018.01.26 16:25:57 DEBUG [NioProcessor-15]: org.jivesoftware.openfire.keystore.OpenfireX509TrustManager - Chain of one is not self-signed. Not adding it to the set of trusted issuers.
2018.01.26 16:25:57 DEBUG [NioProcessor-15]: org.jivesoftware.openfire.keystore.OpenfireX509TrustManager - Validating chain with 1 certificates, using 147 trust anchors.

But then it goes wrong, exactly like you :

2018.01.26 16:25:57 WARN [socket_c2s-thread-2]: org.jivesoftware.openfire.keystore.TrustStore - Unkown exception while validating certificate chain:Index: 0, Size: 0

So reading Openfire Source code, this looks like an Openfire bug, not like a missing cert in a truststore or something like this. I’ve tried with .jks, and with .p12, to get exactly same result.

The first patch for the Openfire source code would be to replace :

Log.warn( "Unkown exception while validating certificate chain:" + e.getMessage() );

by

Log.warn( "Unkown exception while validating certificate chain:", e );

so the full stack trace can be shown, like for the other exceptions.
P.S. : and of course, correct the typo (“Unkown” -> “Unknown”).

Are you able to submit these changes as github pull requests?

Well, sorry I don’t feel like setting up a full dev env, just to submit one line of log fix :slight_smile:

Moreover, I may not be able to resolve the real issue, but I can send u my test CA, test certificate with key and password if it’s useful.

No need for that, the github UI allows you to edit files via the website and submit pull requests in that manner.

Oh ok, you mean untested change, sure I can make untested change, here you are :