Experimental implementation of 1PA3PC protocol

This repository is built to supplement the article where we present this protocol, aimed at countering certificate poisoning attacks. The article is currently undergoing editorial review; this information will be updated once it is published.

Note on cleanliness

This code is just a working prototype. Its quality and cleanlines do not make us particularly proud (much the opposite...), but we publish it as a requisite we understand (and a conviction we share) to accompany the publication of scientific articles of all of the needed artifacts to reproduce them, and in the hope of contributing to free software.

Experimental setup

The systems in which the experiment is run is set up via the build_img.rb script. It could, and probably should, have been written as a set of Ansible playbooks — but it grew organically, and for a proof-of-concept, it is deemed sufficient.

This script sets up a lab with five empty Hockeypuck servers, peering with a random distribution (this means, sometimes the peering servers won't form a single network, but a partitioned one!), and generates 500 random OpenPGP keys, uploading 100 to each of the servers. Then, it runs an attack, poisoning five of said keys with 1000 signatures each, and uploads them randomly to the five servers.

Source changes

The protocol implementation required changes to two software packages, and the development of some glue between them. The software packages and versions in question are:

  1. Sequoia: This excellent Rust library for handling RFC4880 (OpenPGP) data is the first OpenPGP implementation we found to implement attestation support. we only had to add the sq list-attestations command, to display the list of attestations present on a given certification chain.

    Our modifications apply to version 0.27.0 of Sequoia; please refer to their Git repository if you want to apply them.

    Do note that Sequoia's authors reorganized their tools, and the repository for the sq tool can now be found here instead; the above link is provided to allow for building the exact modifications we propose. They require several changes to be applied to current versions!

    Here you can find the modifications needed to create the list_attestations function and the matching sq key list-attestations [KEY] command.

  2. Hockeypuck: The currently leading Gossip-enabled keyserver, written in Go. The experiment was built off a snapshot of Hockeypuck version 2.0~rc2 (commit 763e2025) not currently reachable from its Git repository, so full sources are included in this repository. Please disregard the version numbers, as they were chosen arbitrarily while packaging and do not intend to match upstream's; the package name for a Debian system was also changed to hockeypuck-pcic to avoid conflicts. The sources files are hockeypuck-pcic1.0.orig.tar.xz, hockeypuck-pcic1.0-2.debian.tar.xz and hockeypuck-pcic_1.0-2.dsc.

    The differences applied to the upstream project to make Hockeypuck implement 1PA3PC are available here.

  3. Glue code: The versions of Sequoia and Hockeypuck we modified are from different points in time, and they were not trivial to install on a single system. We also found it to be easier to express the semantics for the protocol we were deploying as a prototype in the Perl language. So, we authored two programs as glue code:

Licensing

The code here published as patches to a larger project should be covered by licensing compatible with the upstream project's. Sequoia is released under GPL-2.0-or-later licensing. Hockeypuck is released under AGPL-3.

The scripts developed for this project (tcp_to_sq.pl, filter_certs and build_img.rb) are released under the GPL v2 or later.

Authors

The authors responsible of this article and code are Gunnar Wolf (active developer and author) and Jorge Luis Ortega Arjona (PhD advisor). This work is published in partial fulfillment of the requirements for the «Posgrado en Ciencias e Ingeniería en Computación» (PCIC) program at Universidad Nacional Autónoma de México (UNAM).