In 2015 I wrote a bit about Microsoft Catalog files and threatened to invent a new specification if nobody else stepped up to the plate. Microsoft have still not documented the format, and have seemingly broken the on-disk file format at least once, and there’s still no easy way we can write these files in Linux. Yesterday was a long day, and I think I have a prototype I want to share with the world now. Lets go back a bit first, what is a catalog file anyway?
A catalog file is a container format that can hold any number of signatures for external files. The data files themselves are not contained in the catalog, only the signatures. Detached signatures are something we’re familiar with in Linux, typically in the form of
.asc files for GPG and
.p7b files for PKCS-7 protocols. Detached files are something we also generate on the LVFS and consume in fwupd and this is the reason you can see more than just the
firmware.metainfo.xml in the cabinet archive:
The bug we’re trying to fix was we wanted to sign the metainfo file too so we can be sure that it came from the LVFS, rather than been modified by anyone capable of extracting and creating a new cabinet archive. This would have added
firmware.metainfo.xml.p7b to the archive, and at some point you have to wonder just how many extensions we can nest before the world descends into chaos. It also meant that we would have to add an extra
n_firmware_files + n_metainfo_files detached signatures to each archive for every extra signing mechanism we add.
The other problem with a single detached signature per engine per file is that only one entity can sign the firmware. At the moment it’s just the LVFS, but what if Dell wanted to sign the firmware with a detached signature too, saying “this firmware is 100% from Dell”? Would we have
com.dell.firmware.metainfo.xml.p7b too? This all got very complicated and basically forced me to create a new project to make it all much simpler.
Jcat is a gzipped JSON file of detached signatures. Because it’s gzipped it’s easy to compress and decompress in basically any language, and because it’s JSON it’s dead simple to parse and generate in any framework. There is a little overhead of some metadata (e.g. signing ID, creation time, etc) and but it’s all the kind of thing you can just edit in vim if you needed to. There’s also support for storing binary stuff like DER certificates (base64 to the rescue…), but if possible I’d like it to be all readable in a text editor. The
jcat command line tool can import existing detached signatures into the Jcat file, and can also verify the existing
.jcat file against all the files in a directory or archive. You can include multiple signatures for the same file (using the AppStream ID as the key) and of course sign multiple files using all the cryptographic engines you need. There’s also rudimentary support for actually creating signatures in the
jcat command line client too, although it’s WIP for the GNUTLS engine and completely missing for GPGME at the moment.
This new thing also lets us fix another glaring issue in fwupd. Some companies can’t use PKCS-7, and some can’t use GPG for equally bad and nonsensical reasons – at the moment you need to specify the remote keyring when enabling a remote as we need to know if we need to download the
metadata.xml.gz.asc or the
.p7b version. Using a
.jcat file allows to to not care, and just download one detached thing that can be used no matter how you’ve compiled your system. By adding SHA-256 as an additional not-to-be-used-for-trust engine, Jcat also lets you verify the download of your metadata and cabinet files even when you don’t have GPG or PKCS-7 available, which I know at least one company does on an IOT project. Jcat allows us to move the scary cryptographic verification code out of fwupd and makes the update-your-firmware codebase easier to maintain without worrying about potential landmines.
I’ve got a
wip/hughsie/jcat branch on fwupd, and the same for lvfs-website although none of it has had any kind of peer review. Feedback on the initial release of libjcat most welcome from anyone familiar with writing libraries with GIO and Glib.
I suck at naming, but Jcat is supposed to be “JSON Catalog”. My daughters also have lots of Jellycat toys scattered around the house too, and the name seemed not to be taken by any other projects so far. If anyone knows of a project already using the name, please let me know. Feedback very welcome.