Summer of Code: The plan. Act 1: OpenPGP

OpenPGP

OpenPGP (know as RFC4880) defines a format for encrypted and signed data, as well as encryption keys and signatures.

My main problem with the specification is, that it is very noisy. The document is 90 pages long and describes every aspect an implementer needs to know about, from how big numbers are stored, over which magic bits and bytes are in use to mark special regions in a packet, to recommendations about used algorithms. Since I’m not going to write a crypto library from scratch, the first step I have to take is to identify which parts are important for me as a user of a – lets call it mid-level-API – and which parts I can ignore. You can see this posting as kind of an hopefully somewhat entertaining piece of jotting paper which I use to note down important parts of the spec while I go through the document.

Lets start to create a short TL;DR of the OpenPGP specification.
The basic process of creating an encrypted message is as follows:

  • The sender provides a plaintext message
  • That message gets encrypted with a randomly generated symmetric key (called session key)
  • The session key then gets encrypted for each recipients public key and the resulting block of data gets prepended to the previously encrypted message

As you can see, an OpenPGP message consists of multiple parts. Those are called sub-packets. There is a pretty respectable number of sub-packet types specified in the RFC. Many of them are not very interesting, so lets identify the few which are relevant for our project.

  • Public-Key Encrypted Session Key Packets
    Those packets represent a session key encrypted with the public key of a recipient.
  • Signature Packets
    Digital signatures are used to provide authenticity. If a piece of data is signed using the secret key of the sender, the recipient is able to verify its origin and authenticity. There is a whole load of different signature sub-packets, so for now we just acknowledge their existence without going into too much detail.
  • Compressed Data Packets
    OpenPGP provides the feature of compressing plaintext data prior to encrypting it. This might come in handy, since encrypting files or messages adds quite a bit of overhead. Compressing the original data can compensate that effect a little bit.
  • Symmetrically Encrypted Data Packets
    This packet type represents data which has been encrypted using a symmetric key (in our case the session key).
  • Literal Data Packets
    The original message we want to encrypt is referred to as literal data. The literal data packet consists of metadata like encoding of the original message, or filename in case we want to encrypt a file, as well as – of course – the data itself.
  • ASCII Armor (not really a Packet)
    Encrypted data is represented in binary form. Since one big use case of OpenPGP encryption is in Email messaging though, it is necessary to bring the data into a form which can be transported safely. The ASCII Armor is an additional layer which encodes the binary data using Base64. It also makes the data identifiable for humans by adding a readable header and footer. XEP-0373 forbids the use of ASCII Armor though, so lets focus on other things instead 😀

Those packet types can be nested, as well as concatenated in many different ways. For example, a common constellation would consist of a Literal Data Packet of our original message, which is, along with a Signature Packet, contained inside of a Compressed Data Packet to save some space. The Compressed Data Packet is nested inside of a Symmetrically Encrypted Data Packet, which lives inside of an OpenPGP message along with one or more Public-Key Encrypted Session Key Packets.

Each packet carries additional information, for example which compression algorithm is used in the Compressed Data Packet. We will not focus on those details, as we assume that the libraries we use will already handle those specifics for us.

OpenPGP also specifies a way to store and exchange keys. In order to be able to receive encrypted messages, a user must distribute their keys to other users. A key can carry a lot of additional information, like identities and signatures of other keys. Signatures are used to create trust networks like the web of trust, but we will most likely not dive deeper into that.

Signatures on keys can also be used to create key hierarchies like super keys and sub-keys. It still has to be determined, if and how those patterns will be reflected in my code. I can imagine it would be useful to only have sub-keys on mobile devices, while the main super key is hidden away from the orcs in a bunker somewhere, but I also think that it would be a rather complicated task to add support for sub-keys to my project. We will see 😉

That’s it for Part 1 of my sighting of the OpenPGP RFC.

Happy Hacking!

Summer of Code: Preparations

During preparations for my GSoC project, I’m finding first traces left by developers who dealt with OpenPGP before. It seems that Florian was right when he noted, that there is a lack of usable higher level Java libraries as I found out when I stumbled across this piece of code. On the other hand I also found a project which thrives to simplify OpenPGP encryption as much as possible. bouncy-gpg – while apparently laying its focus on file encryption and GnuPG compatibility – looks like a promising candidate for Smacks OX module. Unfortunately its code contained some very recent Java features like stream semantics, but I managed to modify its source code to make it compatible down to Androids API level 9, the version Smack is currently targeting. My changes will eventually be upstreamed.

While my next target is now to create a very basic prototype of OX encryption, I’m also reading into OpenKeychains OpenPGP API. It would be very nice to create a universal interface that allows for OX encryption using multiple backends – BouncyCastle on pure Java systems and SpongyCastle / OpenKeychain on Android.

During my work on OX providers for Smack, I stumbled across an interesting issue. When putting a body element as a child into an signcrypt element, the body did not include its namespace, as it is normally only used as child of the message element. Putting it into a signcrypt element made up a special edge case. When a Provider tries to parse the body element, it would falsely interpret the missing namespace as the one of the parent element. Florian provided the solution to this problem by modifying the “toXML()” method of all elements to require an enclosing namespace. Now the body is able to include its namespace in the XML in case the enclosing namespace is different from “jabber:client”.

Happy Hacking!

Smack: Some busy nights

Hello everyone!

This weekend I stayed up late almost every evening. Thus I decided that I wanted to code something, but I wasn’t sure what, so I took a look at the list of published XEPs to maybe find something that is easy to implement, but missing from Smack.

I found that XEP-0394: Message Markup was missing from Smacks list of supported extensions, so I began to code. The next day I finished my work and created Smack#194. One or two nights later I again stayed up late and decided to take another look for an unimplemented XEP. I settled on XEP-0382: Spoiler Messages  this time, which was really easy to implement (apart from the one little attribute, which for whatever reason I struggled to parse until I found a solution). The result of that night is Smack#195.

So if you find yourself laying awake one night with no chance to sleep, just look out for an easy to do task on your favourite free software project. I’m sure this will help you sleep better once the task is done.

Happy Hacking!

OMEMO

The OMEMO logo – a clownfish

Recently there was a lot of news coverage of an alleged „backdoor“ in WhatsApp, the proprietary messaging application owned by Facebook. WhatsApp deployed OpenWhisperSystem’s Signal-protocol roughly a year ago. Now a researcher showed, that WhatsApp’s servers are able to register a new device key for a user, so that messages that the user did not read yet (the ones with only one checkmark) are re-encrypted for the new key, so they can be read by WhatsApp (or whoever registered the key). There were a lot of discussions going on about whether this is a security flaw, or careful design.

I also read a lot of articles suggesting alternatives to WhatsApp. Often mentioned was of course Signal, a free open source messenger by OpenWhisperSystems, the creators of the Signal-protocol, which does not suffer from WhatsApps “vulnerability”. Both WhatsApp and Signal share one major flaw: Both create a “walled garden” for their users. That means that you can only write WhatsApp messages to other WhatsApp users. Same goes for Signal. Since Signal depends on proprietary Google libraries, it cannot be used on mobile phones without Google Play services.

Every now and then the news mention another alternative, the XMPP network.

Conversations is a free libre XMPP client for Android, which introduced the OMEMO protocol for end-to-end encryption roughly two years ago. OMEMO is basically the Signal-protocol adapted to XMPP. Since there are many different XMPP servers that can be used with many different clients, the user has a choice, which software they want to use to communicate to their friends. The issue is, there are not too many clients supporting OMEMO at the moment. But what clients are able to do OMEMO at the moment?

For Android there is Conversations of course and very recently ChatSecure for iOS was released in version 4, which brought OMEMO support. So it looks good on the mobile front (Sorry WindowsPhone).

For the desktop there is Gajim, an XMPP client written in python, which offers OMEMO support as a plugin. This works well on Linux and Windows. I admit, this is not a lot compared to OTR or GPG – but wait, there is more 😉

Currently I am writing on my bachelors thesis about the OMEMO protocol. As part of this, I am working on a Smack module that hopefully will enable messenger apps based on the Smack library (eg. Xabber, Zom, Jitsi, Kontalk…) to encrypt messages with OMEMO.

Simultaneously another student is developing a Pidgin plugin and yet another one is implementing OMEMO for the console based XMPP client Profanity. You can find a quick overview of the state of OMEMO deployment on https://omemo.top.

Update (kind of, its two years later :D): It appears, that the original article by The Guardian has been amended due to its author massively overestimating the severity of the “flaw”.