A library is only as good as its integration in downstream projects. As such, we made ease of use one of our main goals.
Our first decision in this regard is our library-first approach. In contrast with other implementations, we decided to provide a library that contains all the functionality first, and a command-line frontend on top of that. The rationale is that a library offers better integration into downstream applications, and no user should be tempted to ‘shell out’ to our command-line frontend because of a feature not available in the library.
Now, while Sequoia is implemented in Rust, most software currently out there is not. But Rust offers a way to create an API with C calling conventions, allowing the use from C and other languages. A Rust library equipped with such an interface can be used in a large variety of environments, from kernel space or embedded devices to garbage collected environments due to the fact that Rust requires little to no runtime support.
While the C API is necessarily more verbose than the Rust one, experience with our library has shown that C code using Sequoia is more compact than code using GPGME, even though Sequoia currently offers only a low-level interface, whereas GPGME offers a high-level one.
Often, all you want is to verify an OpenPGP signature. For example, OpenPGP signatures secure the software distribution mechanisms of all major Linux distributions. We provide sqv, an specialized tool to verify detached signatures that is robust and easy to use. It allows you to specify signature thresholds (e.g. at least two valid signatures required), and to restrict the time interval in which signatures should be considered valid (e.g. newer than X). Simply looking at the tool’s exit status tells you the result of the verification.
One of the main design aspects of Sequoia’s core OpenPGP crate is that we tried hard to avoid dictating how OpenPGP should be used. This doesn’t mean that we don’t have opinions about how OpenPGP should be used in a number of common scenarios (for instance, message validation). But, in this crate, we refrain from expressing those opinions. By keeping the core policy-free, you don’t have to work around an implementations policy or design decisions.
Of course, there are policy decisions that have to be expressed, for example if an algorithm is considered insecure, or simply not in compliance with local regulation. For this, we abstracted over concrete policies using our policy framework. A standard policy is provided that can be further tweaked to fit your needs.
Finally, we want to provide easy-to-use applications for developers and power-users. Our command-line frontend sq provides encryption, decryption, signature creation and verification, key and certificate management, and powerful data inspection capabilities with an easy-to-use git-style interface.