The Grumpy Troll

Ramblings of a grumpy troll.

Jitsi & Certificates

I’ve been on the lookout for an XMPP client I could trust, for macOS. Trust is a loaded term, but in this context, it means:

  • Either not written in C, or very proactive about security updates
  • OTR support
  • Source code available, should I choose
  • If installing binary packages, signed releases which can be verified.

Today I installed Jitsi.

It’s written in Java and is a little slow to start, but I’ll take that if it means my account isn’t compromised by anyone who can send me a friend request. Sure, it’s not immune to security problems, but it’s not baring its butt to the world (default stance of most C chat clients), and I’ll take it.

It supports OTR; looks like it may be a little easy to regenerate new identities, not seeing any import/export mechanism, but my public fingerprint statement has now been updated.

Running codesign with the right number of -v flags let me see not only that it was signed, but who signed it. The source code is available in git.

The program even runs, which initially surprised me, because I don’t keep a Java Runtime Environment (JRE) installed: too many security updates for that to keep tracking, and some interesting licensing choices.

Chat Server Security

Alas, Jitsi doesn’t appear to support DANE (although it does support DNSSEC) and there are some messages which are a couple of years old suggesting such support might be coming. It also doesn’t use the system certificate trust store.

I know this, because my chat server uses a certificate from my personal CA. I don’t use Let’s Encrypt because “done right” XMPP requires some name-type variants which LE doesn’t support (XMPPAddr). DANE works for server-server verification, could work for client-server, and frankly, all allowed clients for this private server should be using and trusting my personal CA anyway.

So, my server is secure, but I need Jitsi to believe that. It’s Java, so Google and find out how to get certs trusted in Java on macOS. Right, time to script it.

Jitsi and Java

I invoke /usr/libexec/java_home and … Java is not installed.

I invoke lsof -p 95078 to take a closer look at the Jitsi process and, sure enough, the application has bundled an entire JRE as an application resource.

At this point, I pause to take stock, before deciding that the developers appear to be fairly on-the-ball and will probably have fresh releases cut quickly if there’s another JRE security issue. And it’s better than

Okay, so … we have Java, we have bouncycastle, and I’ve even written docs in the past about installing certs for Android, with Bouncy Castle.

But we have no keytool command as part of Jitsi; running find /Applications/Jitsi.app -type f -perm +0111 -print yields nothing helpful. We do have a system keytool though, which immediately prompts for installing a runtime.

What about in /Applications/Jitsi.app/Contents/PlugIns/jre*.jre/Contents/Home ?
Nope. Not enough there.

$ file /Applications/Jitsi.app/Contents/PlugIns/jre*.jre/Contents/Home/lib/security/cacerts
/Applications/Jitsi.app/Contents/PlugIns/jre1.8.0_121.jre/Contents/Home/lib/security/cacerts: Java KeyStore

So I know what needs to be edited and where. So I just need Java and … no dice, none of my systems have it installed. I really don’t want to add a full build to my laptop either, if I’m just going to have to remember to check it for security updates too, since it doesn’t integrate into system security updates.

Getting Java somewhere, and use that

Beware that my knowledge of how to do things “right” with Java is about two decades out-of-date.

  1. Pick a Linux container running Ubuntu; this one is called workbench, it’s a container where I do random dev stuff and I’m happy to blow away the container whenever needful.
  2. apt-get install openjdk-7-jre
  3. update-alternatives --list keytool to confirm this is a Java tool
  4. On laptop:
    • cp /Applications/Jitsi.app/Contents/PlugIns/jre*.jre/Contents/Home/lib/security/cacerts ~/tmp/cacerts.bkp
    • scp /Applications/Jitsi.app/Contents/PlugIns/jre*.jre/Contents/Home/lib/security/cacerts workbench:
    • fgrep -ir keystorepassword ~/src/chat/jitsi/jitsi and review
    • conclude that there’s support for a keystore password, but it’s not defaulting to anything, and since I didn’t see it in the Jitsi properties file, I should stop over-thinking and just try hitting “Enter”.
  5. On workbench:
    • keytool -keystore ./cacerts -list and hit <Enter> at the password prompt
    • it’s proceeding unvalidated, this won’t succeed for making changes, I think
    • try various things, including my Jitsi Master Password in case that got re-used; no luck.
    • in desperation, try the ancient password I documented on my security page somewhere around 2008ish
    • changeit
    • it works … yay? What is this a “password” for, really?
    • keytool -storepass changeit -keystore ./cacerts -list
    • keytool -storepass changeit -keystore ./cacerts -import -file ${SSL_CERT_DIR:?}/globnixCA4.pem -trustcacerts
    • but see next section before copy/pasting that
  6. On laptop:
    • scp workbench:cacerts /Applications/Jitsi.app/Contents/PlugIns/jre*.jre/Contents/Home/lib/security/cacerts
  7. Quit and restart Jitsi
  8. Be happy
$ keytool -storepass changeit -keystore ./cacerts -import -file ${SSL_CERT_DIR:?}/globnixCA4.pem -trustcacerts
Certificate already exists in system-wide CA keystore under alias <debian:globnixca4.pem>
Do you still want to add it to your own keystore? [no]:  yes
Certificate was added to keystore

Some thoughts

The Java ecosystem still does its own cert management; that would be fine, if it did something more fine-grained than “trust-or-not” for a CA.

Using keytool ... -list I couldn’t find my cert, until I realized that it was the one called mykey. So:

keytool -storepass changeit -keystore ./cacerts -delete -alias mykey
import() {
  local file="${1:?need filename}" alias="${2:?need alias}" ;
  keytool -storepass changeit -keystore ./cacerts -import -file $file -alias $alias -trustcacerts ;
}
import ${SSL_CERT_DIR:?}/globnixCA4.pem globnixca4
import letsencrypt_rsa_authority_x3_IdenTrust.pem letsencrypt_rsa_x3
import letsencrypt_rsa_authority_x4_IdenTrust.pem letsencrypt_rsa_x4
import letsencrypt_rsa_root.pem letsencrypt_rsa_root

and copy that to the laptop once more.

Also: I need to fix the CSS on this blog to have scrolling boxes for long lines. It’s going on my long todo list.

-The Grumpy Troll

Categories: XMPP TLS PKIX Certificates Cryptography Jitsi macOS Java