Subject: [openpgp] Stateless OpenPGP command line interface proposal

From: Daniel Kahn Gillmor <[email-masked]>
Date: Mon, 28 Oct 2019 16:20:39 -0400

Hi OpenPGP folks--

The recently-announced OpenPGP test suite [0] inspired me to try
drafting a spec for a purely-functional, stateless OpenPGP command line
interface.  The idea is that different implementers could provide the
same interface, focusing specifically on the object security aspect of
OpenPGP (leaving aside identity management).

An example (using "sop" as the command, short for "Stateless OpenPGP"):

    sop generate 'Alice Lovelace <[email-masked]>' > alice.sec
    sop convert < alice.sec > alice.pgp

    sop sign --as=text alice.sec < announcement.txt > announcement.txt.asc
    sop verify announcement.txt.asc alice.pgp < announcement.txt

    sop encrypt --sign-with=alice.sec --as=mime bob.pgp < msg.eml > encrypted.asc
    sop decrypt alice.sec < ciphertext.asc > cleartext.out

My hope is that any implementer that provides a command "foo" that meets
the given spec can be interoperably tested against all other
implementers.

I've just published an initial draft of this specification here:

    https://datatracker.ietf.org/doc/draft-dkg-openpgp-stateless-cli/

It's tracked as markdown source in git at:

    https://gitlab.com/dkg/openpgp-stateless-cli

But i'd very much like other contributions or authors.  If you're an
implementer of an OpenPGP toolkit, and you think you might take a crack
at implementing part of it, i'd love your feedback.  If there's
sufficient interest in the community, i'd be happy to move the `sop`
spec over to https://gitlab.com/openpgp-wg/ so that it's clearly not
something that i'd be a blocker on.

Why do this?  I want to encourage interoperability and testing, and
applications that use OpenPGP tend to have a rather simple model of what
they *want* out of OpenPGP, even though the spec itself is very complex.

A shared spec could help us build some tools that capture that model, as
closely (and as simply) as possible.

In particular, traditional OpenPGP implementations are capable of many
different kinds of work:

  * Object Security
   - Authenticity/Integrity
     - message/object signing
     - signature verification
   - Confidentiality
     - message/object encryption
     - ciphertext decryption
  * Identity Management
   - personal
     - creation and storage of your own secret keys
     - management of your own public keys/certificates
     - publication of certificates (e.g. keyservers, WKD)
     - management of hardware security tokens
   - peers
     - discovery of peer certificates (e.g. keyservers, WKD)
     - curation and maintenance of peer certificates
     - association of peer certs with application contexts
     - certification of peers ("key signing")
     - graph analysis of certifications ("web of trust")

There are probably more things too that i've forgotten about…

My thought was that if we could separate these things out, we can focus
on interoperability of the first part ("Object Security") and treat the
second part ("Identity Management") as a distinct project.

Obviously, both parts are critical to a functional use of OpenPGP, but i
think if we tackle them separately we can provide more plausible and
efficient interoperability, which should in turn lead to the ability to
drive new cryptographic primitives out into the community.

Please take a look and let me know what you think!

       --dkg

[0] id:[email-masked]

---

From: Santiago Torres-Arias <[email-masked]>
Date: Mon, 28 Oct 2019 16:40:33 -0400

>     sop decrypt alice.sec < ciphertext.asc > cleartext.out

I think this is a *phenomenal* idea. I wonder if this could mature in a
well-defined API that e.g., gpgme could adopt?
 
> something that i'd be a blocker on.

I'll definitely take a look, as we implement bits and pieces of
rfc4880/rfc4880bis on NYU's securesystemslib.

Thanks!
-Santiago.

---

From: Daniel Kahn Gillmor <[email-masked]>
Date: Tue, 29 Oct 2019 22:04:02 -0400

On Mon 2019-10-28 16:20:39 -0400, Daniel Kahn Gillmor wrote:
> interface.
 […]
>     https://datatracker.ietf.org/doc/draft-dkg-openpgp-stateless-cli/

I got a lot of very useful feedback on this draft (mostly off-list) from
several people over the past day, and i've published a revised version
that incorporates what I learned.

substantive changes between -00 and -01:

 * Changed `generate` subcommand to `generate-key`
 * Changed `convert` subcommand to `extract-cert`
 * Added "Input String Types" section as distinct from indirect I/O
 * Made implicit arguments potentially explicit (e.g. `sop armor --label=auto`)
 * Added `--allow-nested` to `sop armor` to make it idempotent by default
 * Added fingerprint of signing (sub)key to `VERIFICATIONS` output
 * Dropped `--mode` and `--session-key` arguments for `sop encrypt` (no plausible use, not needed for interop)
 * Added `--with-session-key` argument to `sop decrypt` to allow for session-key-based decryption
 * Added examples to each subcommand
 * More detailed error codes for `sop encrypt`
 * Move from `CERT` to `CERTS` (each `CERTS` argument might contain multiple certificates)

Some things that I observed from this process:

  - `sop` should be simple to operate.  It shouldn't ask the user any
    question (or offer any options) that the user doesn't already know
    the answer to, or that will have no effect on how the data produced
    will ultimately be used.

  - Implementers of `sop` are expected to make reasonable decisions in
    those corners of the spec are unclear.  Hopefully interoperability
    test suites will help identify those corners.

  - While we want `sop` implementations to be robust when trying to
    consume weird input, sometimes being robust really should just mean
    a clean failure, rather than trying to make sense of non-sensible
    inputs.

I also note that xml2rfc v3 output is substantially nicer to read than
the htmlized form produced by tools.ietf.org by default right now.

You can compare the forms:

    https://tools.ietf.org/html/draft-dkg-openpgp-stateless-cli-01
    https://dkg.fifthhorseman.net/draft-openpgp-stateless-cli.html

I prefer the latter, which i aim to keep updating if (as i hope) more
revisions are forthcoming.

I welcome further feedback on this spec, both here on-list and also via
https://gitlab.com/dkg/openpgp-stateless-cli

Regards,

       --dkg