# An implementation of the `sopv` subset using `gpgv`

the [Stateless OpenPGP Command Line Interface](https://datatracker.ietf.org/doc/draft-dkg-openpgp-stateless-cli/) has a signature-verification-only subset called `sopv`.

This python script provides the `sopv` interface by wrapping [g10code](https://g10code.com/)'s [`gpgv`](https://www.gnupg.org/documentation/manuals/gnupg/gpgv.html) implementation.

## Impedance mismatches

There are some subtle differences and difficulties in mapping `sopv` to `gpgv`.
The goal of this project is to be a complete `sopv` implementation that exposes all of the OpenPGP functionality of `gpgv`, without inheriting any of `gpgv`'s interface quirks.

This means that if there is a particular cryptographic OpenPGP feature that `gpgv` can't support, `sopv-gpgv` won't be able to support them either; but if it's just an interface quirk, that should be smoothed over correctly.

### ASCII-armored keyrings

`gpgv` expects that certificates used for verification are in binary "keyring" form.

`sopv` permits ASCII-armored certificates.

### Whitespace at the end of Clearsigned Messages

GnuPG [does not follow the OpenPGP standard for clearsigned messages](https://dev.gnupg.org/T7106).
In particular, it changes the number of trailing newlines for most messages.

`gpgv-sopv` does not address this problem, as `gpgv`'s non-compliance with the spec is not an invertible transformation.
Other implementations of the `gpgv` interface, like [`gpgv-sq`](https://gitlab.com/sequoia-pgp/sequoia-chameleon-gnupg) do not have this problem.

### Filesystem Access

`gpgv` typically uses filesystem access, but `sopv` is expected to work entirely in read-only mode.

However, [`gpgv` cannot use keyrings from file descriptors](https://dev.gnupg.org/T4608).
Combined with the need to translate from ASCII-armored keyrings (see above), this means that we have to use a tmpfile for some keyrings.

The current implementation uses a tmpfile for CERTS objects that need this kind of rewriting.

Given that the project is already necessarily reliant on tmpfiles, it also uses tmpfiles for `gpgv`'s `--status` output.
If `gpgv` could use file descriptors for keyring input, then we might also want to rewrite `sopv-gpgv` to use asynchronous (or multithreaded concurrent) reads from the `--status` output.

## Author and License

This project is released by Daniel Kahn Gillmor under an [MIT-style license](LICENSE).
If you find any of it useful, either in implementing another `sopv` implementation, or in making sense of how to use `gpgv` safely, please reuse it where possible.

## Acknowledgements

The regular expression for unarmoring OpenPGP ASCII armor was adapted from [PGPy](https://github.com/SecurityInnovation/PGPy).

And this wrapper of course depends on the long-standing `gpgv` interface from [g10code](https://g10code.com/).

## Bug Reporting and Feedback

Please report bugs or provide other feedback at [https://gitlab.com/dkg/sopv-gpgv](https://gitlab.com/dkg/sopv-gpgv), or by e-mail to the author.
