Openfire Client SSL Authentication How-to
Openfire is the only open source XMPP server (that I know of) that supports client-side certificate authentication. This will explain how to setup Openfire and Pidgin to using client-side certificate authentication.
Create Certificates
- You will need to create a test certificate authority. A number of web sites have how-tos on creating a certificate authority for testing.
 
- Using the OpenSSL CA tools:
 
Create a certificate/key pair for each user.
The certificate's COMMON NAME must match the XMPP login name
- Create a PKCS12 file containing the certificate/key pair. The files need to be in PEM (text) format for openssl and not DER (binary).
 
- To convert a certificate to PEM format:
 
openssl x509 -inform der -in DER_CERT_FILE -outform pem PEM_CERT_FILE
- To convert a key to PEM format:
 
openssl pkey -inform der -in DER_KEY_FILE -outform pem PEM_KEY_FILE
- To create the PKCS12 file:
 
openssl pkcs12 -export -inkey KEYFILE -in CERTFILE -out USER.p12 -name USER
Setting Up Openfire
- Download, install, and setup Openfire:
 
http://www.igniterealtime.org/projects/openfire/index.jsp http://www.igniterealtime.org/builds/openfire/docs/latest/documentation/install-guide.html
- Openfire maintains several key stores in /etc/openfire/security. We are interested in client.truststore which contains the certificates trusted to authenticate users. We can place a certificate authority certificate in the key store and any certificates signed by the authority will be accepted for login to the server.
 
To add a certificate:
keytool -importcert -keystore /etc/openfire/security/client.truststore -alias NAME -file CERTFILE
The default password is "changeit"
Be sure to say yes to "Trust this certificate?".
- Login to you Openfire server on http://server:9090 and go to Server->Server Manager->System Properties. Ensure the following properties exist and are set:
 
| Property | Value | 
|---|---|
| xmpp.client.cert.policy | "needed" or "wanted" | 
| xmpp.client.certificate.accept-selfsigned | true | 
| xmpp.client.certificate.verify | true | 
| xmpp.client.certificate.verify.chain | true | 
| xmpp.client.certificate.verify.root | true | 
| sasl.mechs | EXTERNAL (plus whatever else) | 
More properties can be found here:
http://community.igniterealtime.org/thread/45670 http://community.igniterealtime.org/thread/37967
- Add a user with the same username as the common name of the certificate you created above in Users/Groups?->Users->Create New User.
 
Build Pidgin with Client Certificate Authentication
- Pull the cpw.ljfisher.ssl_client_auth branch from the http://hg.pidgin.im/cpw/ljfisher/ssl_client_auth/ repository.
 
- Ensure the following prerequisites are installed:
- gnutls 2.10 + Older versions will work but exporting certificates and keys will fail
 - Cyrus SASL
 
 
- Configure Pidgin with these options:
 
./configure --enable-cyrus-sasl --enable-gnutls=yes
- Build and install Pidgin:
 
make install
Configure Pidgin
- Open Tools -> Certificates -> Your Certificates. Select Add. Select the PKCS12 file, USER.p12, created above. Enter a passwords and name.
 
- Create a XMPP (Jabber) account.
 
On the Basic tab:
- Enter a username same as the common name in the certificate
 
On the Advanced tab:
- Select Connection Security: Use old-style SSL
 - Select Login certificate: the cert you added above
 - Change connection port to 5223.
 
Openfire doesn't seem to play well with client authentication using starttls so we use regular SSL which uses port 5223.
- Enable the account and it should login.
 
Troubleshooting
You get SSL Handshake failed messages
- Check that /etc/openfire/security/client.truststore is readable by openfire user.
 - Check that the certificate authority's certificate has been added to /etc/openfire/security/client.truststore and has been trusted:
 
keytool -list -keystore /etc/openfire/security/client.truststore
- Check that the user name matches the common name of the login certificate.
 
You get a password dialog when trying to login even though you selected a login certificate
- Check that EXTERNAL has been added to the sasl.mechs Openfire server property.
 - Check that the user name matches the common name of the login certificate.
 - Check that there is an account for the user on the Openfire server
 
Bug Reports
If you cannot resolve the issue send a capture of the Pidgin debug output by running Pidgin with debug and GNUTLS debug enabled:
PURPLE_GNUTLS_DEBUG=9 pidgin -d > pidgin.dbg
And capture the login using Wireshark and send a pcap.

