<?xml version="1.0" encoding="UTF-8"?>
  <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
  <!-- generated by https://github.com/cabo/kramdown-rfc version  (Ruby 3.1.2) -->


<!DOCTYPE rfc  [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">

]>


<rfc ipr="trust200902" docName="draft-dkg-openpgp-stateless-cli-08" category="info" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true">
  <front>
    <title>Stateless OpenPGP Command Line Interface</title>

    <author initials="D. K." surname="Gillmor" fullname="Daniel Kahn Gillmor">
      <organization abbrev="ACLU">American Civil Liberties Union</organization>
      <address>
        <postal>
          <street>125 Broad St.</street>
          <city>New York, NY</city>
          <code>10004</code>
          <country>USA</country>
        </postal>
        <email>dkg@fifthhorseman.net</email>
      </address>
    </author>

    <date year="2023" month="August" day="08"/>

    <area>int</area>
    <workgroup>openpgp</workgroup>
    <keyword>Internet-Draft</keyword>

    <abstract>


<t>This document defines a generic stateless command-line interface for dealing with OpenPGP messages, known as <spanx style="verb">sop</spanx>.
It aims for a minimal, well-structured API covering OpenPGP object security.</t>



    </abstract>

    <note title="About This Document" removeInRFC="true">
      <t>
        The latest revision of this draft can be found at <eref target="https://dkg.gitlab.io/openpgp-stateless-cli/"/>.
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-dkg-openpgp-stateless-cli/"/>.
      </t>
      <t>
        Discussion of this document takes place on the
        OpenPGP Working Group mailing list (<eref target="mailto:openpgp@ietf.org"/>),
        which is archived at <eref target="https://mailarchive.ietf.org/arch/browse/openpgp/"/>.
        Subscribe at <eref target="https://www.ietf.org/mailman/listinfo/openpgp/"/>.
      </t>
      <t>Source for this draft and an issue tracker can be found at
        <eref target="https://gitlab.com/dkg/openpgp-stateless-cli/"/>.</t>
    </note>


  </front>

  <middle>


<section anchor="introduction"><name>Introduction</name>

<t>Different OpenPGP implementations have many different requirements, which typically break down in two main categories: key/certificate management and object security.</t>

<t>The purpose of this document is to provide a "stateless" interface that primarily handles the object security side of things, and assumes that secret key management and certificate management will be handled some other way.</t>

<t>Isolating object security from key/certificate management should make it easier to provide interoperability testing for the object security side of OpenPGP implementations, as described in <xref target="test-suite"/>.</t>

<t>This document defines a generic stateless command-line interface for dealing with OpenPGP messages, known here by the placeholder <spanx style="verb">sop</spanx>.
It aims for a minimal, well-structured API.</t>

<t>An OpenPGP implementation should not name its executable <spanx style="verb">sop</spanx> to implement this specification.  It just needs to provide a program that conforms to this interface.</t>

<t>A <spanx style="verb">sop</spanx> implementation should leave no trace on the system, and its behavior should not be affected by anything other than command-line arguments and input.</t>

<t>Obviously, the user will need to manage their secret keys (and their peers' certificates) somehow,
but the goal of this interface is to separate out that task from the task of interacting with OpenPGP messages.</t>

<t>While this document identifies a command-line interface,
the rough outlines of this interface should also be amenable to relatively straightforward library implementations in different languages.</t>

<section anchor="requirements-language"><name>Requirements Language</name>

<t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>

</section>
<section anchor="terminology"><name>Terminology</name>

<t>This document uses the term "key" to refer exclusively to OpenPGP Transferable Secret Keys (see <xref section="11.2" sectionFormat="of" target="RFC4880"/>).</t>

<t>It uses the term "certificate" to refer to OpenPGP Transferable Public Key (see <xref section="11.1" sectionFormat="of" target="RFC4880"/>).</t>

<t>"Stateless" in "Stateless OpenPGP" means avoiding secret key and certificate state.
The user is responsible for managing all OpenPGP certificates and secret keys themselves,
and passing them to <spanx style="verb">sop</spanx> as needed.
The user should also not be concerned that any state could affect the underlying operations.</t>

<t>OpenPGP revocations can have "Reason for Revocation" (<xref section="5.2.3.23" sectionFormat="of" target="RFC4880"/>), which can be either "soft" or "hard".
The set of "soft" reasons is: "Key is superseded" and "Key is retired and no longer used".
All other reasons (and revocations that do not state a reason) are "hard" revocations.</t>

</section>
<section anchor="test-suite"><name>Using sop in a Test Suite</name>

<t>If an OpenPGP implementation provides a <spanx style="verb">sop</spanx> interface, it can be used to test interoperability (e.g., <xref target="OpenPGP-Interoperability-Test-Suite"></xref>).</t>

<t>Such an interop test suite can, for example, use custom code (<em>not</em> <spanx style="verb">sop</spanx>) to generate a new OpenPGP object that incorporates new primitives, and feed that object to a stable of <spanx style="verb">sop</spanx> implementations, to determine whether those implementations can consume the new form.</t>

<t>Or, the test suite can drive each <spanx style="verb">sop</spanx> implementation with a simple input, and observe which cryptographic primitives each implementation chooses to use as it produces output.</t>

</section>
<section anchor="semantics-vs-wire-format"><name>Semantics vs. Wire Format</name>

<t>The semantics of <spanx style="verb">sop</spanx> are deliberately simple and very high-level compared to the vast complexity and nuance available within the OpenPGP specification.
This reflects the perspective of nearly every piece of tooling that relies on OpenPGP to accomplish its task: most toolchains don't care about the specifics, they just want the high-level object security properties.</t>

<t>Given this framing, this document generally tries to avoid overconstraining the details of the wire format objects emitted, or what kinds of wire format structures should be acceptable or unacceptable.
This allows a test suite to evaluate and contrast the wire format choices made by different implementations in as close to their native configuration as possible.
It also makes it easier to promote interoperability by ensuring that the native wire formats emitted by one implementation can be consumed by another, without relying on their choices of wire format being constrained by this draft.</t>

<t>Where this draft does identify specific wire format requirements, that might be due to an ambiguity in the existing specifications (which maybe needs fixing elsewhere), or to a bug in this specification that could be improved.</t>

</section>
</section>
<section anchor="examples"><name>Examples</name>

<t>These examples show no error checking, but give a flavor of how <spanx style="verb">sop</spanx> might be used in practice from a shell.</t>

<t>The key and certificate files described in them (e.g., <spanx style="verb">alice.sec</spanx>) could be for example those found in <xref target="I-D.draft-bre-openpgp-samples-01"/>.</t>

<figure><artwork><![CDATA[
sop generate-key "Alice Lovelace <alice@openpgp.example>" > alice.sec
sop extract-cert < alice.sec > alice.pgp

sop generate-key "Bob Babbage <bob@openpgp.example>" > bob.sec
sop extract-cert < bob.sec > bob.pgp

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

sop encrypt --sign-with=alice.sec bob.pgp < msg.eml > ciphertext.asc
sop decrypt bob.sec < ciphertext.asc > cleartext.eml
]]></artwork></figure>

<t>See <xref target="failure-modes"/> for more information about errors and error handling.</t>

</section>
<section anchor="subcommands"><name>Subcommands</name>

<t><spanx style="verb">sop</spanx> uses a subcommand interface, similar to those popularized by systems like <spanx style="verb">git</spanx> and <spanx style="verb">svn</spanx>.</t>

<t>If the user supplies a subcommand that <spanx style="verb">sop</spanx> does not implement, it fails with <spanx style="verb">UNSUPPORTED_SUBCOMMAND</spanx>.
If a <spanx style="verb">sop</spanx> implementation does not handle a supplied option for a given subcommand, it fails with <spanx style="verb">UNSUPPORTED_OPTION</spanx>.</t>

<t>All subcommands that produce OpenPGP material on standard output produce ASCII-armored (<xref section="6" sectionFormat="of" target="I-D.ietf-openpgp-crypto-refresh-10"/>) objects by default (except for <spanx style="verb">sop dearmor</spanx>).
These subcommands have a <spanx style="verb">--no-armor</spanx> option, which causes them to produce binary OpenPGP material instead.</t>

<t>All subcommands that accept OpenPGP material on input should be able to accept either ASCII-armored or binary inputs (see <xref target="optional-input-armoring"/>) and behave accordingly.</t>

<t>See <xref target="indirect-types"/> for details about how various forms of OpenPGP material are expected to be structured.</t>

<section anchor="meta-subcommands"><name>Meta Subcommands</name>

<t>The subcommands grouped in this section are related to the <spanx style="verb">sop</spanx> implementation itself.</t>

<section anchor="version"><name>version: Version Information</name>

<figure><artwork><![CDATA[
sop version [--backend|--extended|--sop-spec]
]]></artwork></figure>

<t><list style="symbols">
  <t>Standard Input: ignored</t>
  <t>Standard Output: version information</t>
</list></t>

<t>This subcommand emits version information as UTF-8-encoded text.</t>

<t>With no arguments, the version string emitted should contain the name of the <spanx style="verb">sop</spanx> implementation, followed by a single space, followed by the version number.
A <spanx style="verb">sop</spanx> implementation should use a version number that respects an established standard that is easily comparable and parsable, like <xref target="SEMVER"></xref>.</t>

<t>If <spanx style="verb">--backend</spanx> is supplied, the implementation should produce a comparable line of implementation and version information about the primary underlying OpenPGP toolkit.</t>

<t>If <spanx style="verb">--extended</spanx> is supplied, the implementation may emit multiple lines of version information.
The first line <bcp14>MUST</bcp14> match the information produced by a simple invocation, but the rest of the text has no defined structure.</t>

<t>If <spanx style="verb">--sop-spec</spanx> is supplied, the implementation should emit a single line of text indicating the latest version of this draft that it targets, for example, <spanx style="verb">draft-dkg-openpgp-stateless-cli-06</spanx>.
If the implementation targets a specific draft but the implementer knows the implementation is incomplete, it should prefix the draft title with a <u>~</u>, for example: <spanx style="verb">~draft-dkg-openpgp-stateless-cli-06</spanx>.
The implementation <bcp14>MAY</bcp14> emit additional text about its relationship to the targeted draft on the lines following the versioned title.</t>

<t><spanx style="verb">--backend</spanx>, <spanx style="verb">--extended</spanx>, and <spanx style="verb">--sop-spec</spanx> are mutually-exclusive options.</t>

<t>Example:</t>

<figure><artwork><![CDATA[
$ sop version
ExampleSop 0.2.1
$ sop version --backend
LibExamplePGP 3.4.2
$ sop version --extended
ExampleSop 0.2.1
Running on MonkeyScript 4.5
LibExamplePGP 3.4.2
LibExampleCrypto 3.1.1
LibXCompression 4.0.2
See https://pgp.example/sop/ for more information
$ sop version --sop-spec
~draft-dkg-openpgp-stateless-cli-06

This implementation does not handle @FD: special designators for output.
$
]]></artwork></figure>

</section>
<section anchor="list-profiles"><name>list-profiles: Describe Available Profiles</name>

<figure><artwork><![CDATA[
sop list-profiles SUBCOMMAND
]]></artwork></figure>

<t><list style="symbols">
  <t>Standard Input: ignored</t>
  <t>Standard Output: PROFILELIST (<xref target="profilelist"/>)</t>
</list></t>

<t>This subcommand emits a list of profiles supported by the identified subcommand.</t>

<t>If the indicated <spanx style="verb">SUBCOMMAND</spanx> does not accept a <spanx style="verb">--profile</spanx> option, it returns <spanx style="verb">UNSUPPORTED_PROFILE</spanx>.</t>

<t>Example:</t>

<figure><artwork><![CDATA[
$ sop list-profiles generate-key
default: use the implementer's recommendations
rfc4880: use algorithms from RFC 4880
$
]]></artwork></figure>

</section>
</section>
<section anchor="key-and-certificate-management-subcommands"><name>Key and Certificate Management Subcommands</name>

<t>The subcommands grouped in this section are primarily intended to manipulate keys and certificates.</t>

<section anchor="generate-key"><name>generate-key: Generate a Secret Key</name>

<figure><artwork><![CDATA[
sop generate-key [--no-armor]
    [--with-key-password=PASSWORD]
    [--profile=PROFILE]
    [--signing-only]
    [--] [USERID...]
]]></artwork></figure>

<t><list style="symbols">
  <t>Standard Input: ignored</t>
  <t>Standard Output: <spanx style="verb">KEYS</spanx> (<xref target="keys"/>)</t>
</list></t>

<t>Generate a single default OpenPGP key with zero or more User IDs.</t>

<t>The generated secret key <bcp14>SHOULD</bcp14> be usable for as much of the <spanx style="verb">sop</spanx> functionality as possible.
In particular:</t>

<t><list style="symbols">
  <t>It should be possible to extract an OpenPGP certificate from the key in <spanx style="verb">KEYS</spanx> with <spanx style="verb">sop extract-cert</spanx>.</t>
  <t>The key in <spanx style="verb">KEYS</spanx> should be able to create signatures (with <spanx style="verb">sop sign</spanx>) that are verifiable by using <spanx style="verb">sop verify</spanx> with the extracted certificate.</t>
  <t>Unless the <spanx style="verb">--signing-only</spanx> parameter is supplied, the key in <spanx style="verb">KEYS</spanx> should be able to decrypt messages (with <spanx style="verb">sop decrypt</spanx>) that are encrypted by using <spanx style="verb">sop encrypt</spanx> with the extracted certificate.</t>
</list></t>

<t>The detailed internal structure of the certificate is left to the discretion of the <spanx style="verb">sop</spanx> implementation.</t>

<t>If the <spanx style="verb">--with-key-password</spanx> option is supplied, the generated key will be password-protected (locked) with the supplied password.
Note that <spanx style="verb">PASSWORD</spanx> is an indirect data type from which the actual password is acquired (<xref target="indirect-types"/>).
See also the guidance on ensuring that the password is human-readable in <xref target="generating-human-readable"/>.</t>

<t>If no <spanx style="verb">--with-key-password</spanx> option is supplied, the generated key will be unencrypted.</t>

<t>If the <spanx style="verb">--profile</spanx> argument is supplied and the indicated <spanx style="verb">PROFILE</spanx> is not supported by the implementation, <spanx style="verb">sop</spanx> will fail with <spanx style="verb">UNSUPPORTED_PROFILE</spanx>.</t>

<t>The presence of the <spanx style="verb">--signing-only</spanx> option is intended to create a key that is only capable of signing, not decrypting.
This is useful for deployments where only signing and verification are necessary.</t>

<t>If any of the <spanx style="verb">USERID</spanx> options are not valid <spanx style="verb">UTF-8</spanx>, <spanx style="verb">sop generate-key</spanx> fails with <spanx style="verb">EXPECTED_TEXT</spanx>.</t>

<t>If the implementation rejects any <spanx style="verb">USERID</spanx> option that is valid <spanx style="verb">UTF-8</spanx> (e.g., due to internal policy, see <xref target="userid"/>), <spanx style="verb">sop generate-key</spanx> fails with <spanx style="verb">BAD_DATA</spanx>.</t>

<t>Example:</t>

<figure><artwork><![CDATA[
$ sop generate-key 'Alice Lovelace <alice@openpgp.example>' > alice.sec
$ head -n1 < alice.sec
-----BEGIN PGP PRIVATE KEY BLOCK-----
$
]]></artwork></figure>

</section>
<section anchor="change-key-password"><name>change-key-password: Update a Key's Password</name>

<figure><artwork><![CDATA[
sop change-key-password [--no-armor]
    [--new-key-password=PASSWORD]
    [--old-key-password=PASSWORD...]
]]></artwork></figure>

<t><list style="symbols">
  <t>Standard Input: <spanx style="verb">KEYS</spanx> (<xref target="keys"/>)</t>
  <t>Standard Output: <spanx style="verb">KEYS</spanx> (<xref target="keys"/>)</t>
</list></t>

<t>The output will be the same set of OpenPGP Transferable Secret Keys as the input, but with all secret key material locked according to the password indicated by the <spanx style="verb">--new-key-password</spanx> option (or, with no password at all, if <spanx style="verb">--new-key-password</spanx> is absent).
Note that <spanx style="verb">--old-key-password</spanx> can be supplied multiple times, and each supplied password will be tried as a means to unlock any locked key material encountered.
It will normalize a Transferable Secret Key to use a single password even if it originally had distinct passwords locking each of the subkeys.</t>

<t>If any secret key packet is locked but cannot be unlocked with any of the supplied <spanx style="verb">--old-key-password</spanx> arguments, this subcommand should fail with <spanx style="verb">KEY_IS_PROTECTED</spanx>.</t>

<t>Example:</t>

<figure><artwork><![CDATA[
# adding a password to an unlocked key:
$ sop change-key-password --new-key-password=@ENV:keypass < unlocked.key > locked.key
# removing a password:
$ sop change-key-password --old-key-password=@ENV:keypass < locked.key > unlocked.key
# changing a password:
$ sop change-key-password --old-key-password=@ENV:keypass --new-key-password=@ENV:newpass < locked.key > refreshed.key
$
]]></artwork></figure>

</section>
<section anchor="revoke-key"><name>revoke-key: Create a Revocation Certificate</name>

<figure><artwork><![CDATA[
sop revoke-key [--no-armor]
    [--with-key-password=PASSWORD...]
]]></artwork></figure>

<t><list style="symbols">
  <t>Standard Input: <spanx style="verb">KEYS</spanx> (<xref target="keys"/>)</t>
  <t>Standard Output: <spanx style="verb">CERTS</spanx> (<xref target="certs"/>)</t>
</list></t>

<t>Generate a revocation certificate for each Transferable Secret Key found.
See <xref section="10" sectionFormat="of" target="I-D.ietf-openpgp-crypto-refresh-10"/> for a discussion of common forms of revocation certificate.</t>

<t>Example:</t>

<figure><artwork><![CDATA[
$ sop revoke-key < alice.key > alice-revoked.pgp
$
]]></artwork></figure>

</section>
<section anchor="extract-cert"><name>extract-cert: Extract a Certificate from a Secret Key</name>

<figure><artwork><![CDATA[
sop extract-cert [--no-armor]
]]></artwork></figure>

<t><list style="symbols">
  <t>Standard Input: <spanx style="verb">KEYS</spanx> (<xref target="keys"/>)</t>
  <t>Standard Output: <spanx style="verb">CERTS</spanx> (<xref target="certs"/>)</t>
</list></t>

<t>The output should contain one OpenPGP certificate in <spanx style="verb">CERTS</spanx> per OpenPGP Transferable Secret Key found in <spanx style="verb">KEYS</spanx>.
There is no guarantee what order the <spanx style="verb">CERTS</spanx> will be in.</t>

<t><spanx style="verb">sop extract-cert</spanx> <bcp14>SHOULD</bcp14> work even if any of the keys in <spanx style="verb">KEYS</spanx> is password-protected.</t>

<t>Example:</t>

<figure><artwork><![CDATA[
$ sop extract-cert < alice.sec > alice.pgp
$ head -n1 < alice.pgp
-----BEGIN PGP PUBLIC KEY BLOCK-----
$
]]></artwork></figure>

</section>
</section>
<section anchor="messaging-subcommands"><name>Messaging Subcommands</name>

<t>The subcommands in this section handle OpenPGP messages: encrypting, decrypting, signing, and verifying.</t>

<section anchor="sign"><name>sign: Create Detached Signatures</name>

<figure><artwork><![CDATA[
sop sign [--no-armor] [--micalg-out=MICALG]
     [--with-key-password=PASSWORD...]
     [--as={binary|text}] [--] KEYS [KEYS...]
]]></artwork></figure>

<t><list style="symbols">
  <t>Standard Input: <spanx style="verb">DATA</spanx> (<xref target="data"/>)</t>
  <t>Standard Output: <spanx style="verb">SIGNATURES</spanx> (<xref target="signature"/>)</t>
</list></t>

<t>Exactly one signature will be made by each key in the supplied <spanx style="verb">KEYS</spanx> arguments.</t>

<t><spanx style="verb">--as</spanx> defaults to <spanx style="verb">binary</spanx>.
If <spanx style="verb">--as=text</spanx> and the input <spanx style="verb">DATA</spanx> is not valid <spanx style="verb">UTF-8</spanx> (<xref target="utf8"/>), <spanx style="verb">sop sign</spanx> fails with <spanx style="verb">EXPECTED_TEXT</spanx>.</t>

<t><spanx style="verb">--as=binary</spanx> <bcp14>SHOULD</bcp14> result in OpenPGP signatures of type 0x00 ("Signature of a binary document").
<spanx style="verb">--as=text</spanx> <bcp14>SHOULD</bcp14> result in OpenPGP signatures of type 0x01 ("Signature of a canonical text document").
See <xref section="5.2.1" sectionFormat="of" target="RFC4880"/> for more details.</t>

<t>When generating PGP/MIME messages (<xref target="RFC3156"/>), it is useful to know what digest algorithm was used for the generated signature.
When <spanx style="verb">--micalg-out</spanx> is supplied, <spanx style="verb">sop sign</spanx> emits the digest algorithm used to the specified <spanx style="verb">MICALG</spanx> file in a way that can be used to populate the <spanx style="verb">micalg</spanx> parameter for the Content-Type (see <xref target="micalg"/>).
If the specified <spanx style="verb">MICALG</spanx> file already exists in the filesystem, <spanx style="verb">sop sign</spanx> will fail with <spanx style="verb">OUTPUT_EXISTS</spanx>.
When <spanx style="verb">--micalg-out</spanx> is supplied, the <spanx style="verb">DATA</spanx> on standard input should already be in canonical text form (7-bit clean, CRLF line endings, no trailing whitespace), as specified in <xref section="3" sectionFormat="of" target="RFC3156"/>.
If the incoming <spanx style="verb">DATA</spanx> does not already meet these requirements, <spanx style="verb">sop sign</spanx> will fail with <spanx style="verb">EXPECTED_TEXT</spanx>, regardless of any argument supplied for <spanx style="verb">--as</spanx>.</t>

<t>When signing with multiple keys, <spanx style="verb">sop sign</spanx> <bcp14>SHOULD</bcp14> use the same digest algorithm for every signature generated in a single run, unless there is some internal constraint on the <spanx style="verb">KEYS</spanx> objects.
If <spanx style="verb">--micalg-out</spanx> is requested, and multiple incompatibly-constrained <spanx style="verb">KEYS</spanx> objects are supplied, <spanx style="verb">sop sign</spanx> <bcp14>MUST</bcp14> emit the empty string to the designated <spanx style="verb">MICALG</spanx>.</t>

<t>If the signing key material in any key in the <spanx style="verb">KEYS</spanx> objects is password-protected, <spanx style="verb">sop sign</spanx> <bcp14>SHOULD</bcp14> try all supplied <spanx style="verb">--with-key-password</spanx> options to unlock the key material until it finds one that enables the use of the key for signing.
If none of the <spanx style="verb">PASSWORD</spanx> options unlock the key (or if no such option is supplied), <spanx style="verb">sop sign</spanx> will fail with <spanx style="verb">KEY_IS_PROTECTED</spanx>.
Note that <spanx style="verb">PASSWORD</spanx> is an indirect data type from which the actual password is acquired (<xref target="indirect-types"/>).
Note also the guidance for retrying variants of a non-human-readable password in <xref target="consuming-passwords"/>.</t>

<t>If any key in the <spanx style="verb">KEYS</spanx> objects is not capable of producing a signature, <spanx style="verb">sop sign</spanx> will fail with <spanx style="verb">KEY_CANNOT_SIGN</spanx>.</t>

<t><spanx style="verb">sop sign</spanx> <bcp14>MUST NOT</bcp14> produce any extra signatures beyond those from <spanx style="verb">KEYS</spanx> objects supplied on the command line.</t>

<t>Example:</t>

<figure><artwork><![CDATA[
$ sop sign --as=text alice.sec < message.txt > message.txt.asc
$ head -n1 < message.txt.asc
-----BEGIN PGP SIGNATURE-----
$
]]></artwork></figure>

</section>
<section anchor="verify"><name>verify: Verify Detached Signatures</name>

<figure><artwork><![CDATA[
sop verify [--not-before=DATE] [--not-after=DATE]
    [--] SIGNATURES CERTS [CERTS...]
]]></artwork></figure>

<t><list style="symbols">
  <t>Standard Input: <spanx style="verb">DATA</spanx> (<xref target="data"/>)</t>
  <t>Standard Output: <spanx style="verb">VERIFICATIONS</spanx> (<xref target="verifications"/>)</t>
</list></t>

<t><spanx style="verb">--not-before</spanx> and <spanx style="verb">--not-after</spanx> indicate that signatures with dates outside certain range <bcp14>MUST NOT</bcp14> be considered valid.</t>

<t><spanx style="verb">--not-before</spanx> defaults to the beginning of time.
Accepts the special value <spanx style="verb">-</spanx> to indicate the beginning of time (i.e., no lower boundary).</t>

<t><spanx style="verb">--not-after</spanx> defaults to the current system time (<spanx style="verb">now</spanx>).
Accepts the special value <spanx style="verb">-</spanx> to indicate the end of time (i.e., no upper boundary).</t>

<t><spanx style="verb">sop verify</spanx> only returns <spanx style="verb">OK</spanx> if at least one certificate included in any <spanx style="verb">CERTS</spanx> object made a valid signature in the time window specified over the <spanx style="verb">DATA</spanx> supplied.</t>

<t>For details about the valid signatures, the user <bcp14>MUST</bcp14> inspect the <spanx style="verb">VERIFICATIONS</spanx> output.</t>

<t>If no <spanx style="verb">CERTS</spanx> are supplied, <spanx style="verb">sop verify</spanx> fails with <spanx style="verb">MISSING_ARG</spanx>.</t>

<t>If no valid signatures are found, <spanx style="verb">sop verify</spanx> fails with <spanx style="verb">NO_SIGNATURE</spanx>.</t>

<t>See <xref target="signature-verification"/> for more details about signature verification.</t>

<t>Example:</t>

<t>(In this example, we see signature verification succeed first, and then fail on a modified version of the message.)</t>

<figure><artwork><![CDATA[
$ sop verify message.txt.asc alice.pgp < message.txt
2019-10-29T18:36:45Z EB85BB5FA33A75E15E944E63F231550C4F47E38E EB85BB5FA33A75E15E944E63F231550C4F47E38E mode:text signed by alice.pgp
$ echo $?
0
$ tr a-z A-Z < message.txt | sop verify message.txt.asc alice.pgp
$ echo $?
3
$
]]></artwork></figure>

</section>
<section anchor="encrypt"><name>encrypt: Encrypt a Message</name>

<figure><artwork><![CDATA[
sop encrypt [--as={binary|text}]
    [--no-armor]
    [--with-password=PASSWORD...]
    [--sign-with=KEYS...]
    [--with-key-password=PASSWORD...]
    [--profile=PROFILE]
    [--session-key-out=SESSIONKEY]
    [--] [CERTS...]
]]></artwork></figure>

<t><list style="symbols">
  <t>Standard Input: <spanx style="verb">DATA</spanx> (<xref target="data"/>)</t>
  <t>Standard Output: <spanx style="verb">CIPHERTEXT</spanx> (<xref target="ciphertext"/>)</t>
</list></t>

<t><spanx style="verb">--as</spanx> defaults to <spanx style="verb">binary</spanx>.
The setting of <spanx style="verb">--as</spanx> corresponds to the one octet format field found in the Literal Data packet at the core of the output <spanx style="verb">CIPHERTEXT</spanx>.
If <spanx style="verb">--as</spanx> is set to <spanx style="verb">binary</spanx>, the octet is <spanx style="verb">b</spanx> (<spanx style="verb">0x62</spanx>).
If it is <spanx style="verb">text</spanx>, the format octet is <spanx style="verb">u</spanx> (<spanx style="verb">0x75</spanx>).</t>

<t><spanx style="verb">--with-password</spanx> enables symmetric encryption (and can be used multiple times if multiple passwords are desired).</t>

<t><spanx style="verb">--sign-with</spanx> creates exactly one signature by for each secret key found in the supplied <spanx style="verb">KEYS</spanx> object (this can also be used multiple times if signatures from keys found in separaate files are desired).
If any key in any supplied <spanx style="verb">KEYS</spanx> object is not capable of producing a signature, <spanx style="verb">sop sign</spanx> will fail with <spanx style="verb">KEY_CANNOT_SIGN</spanx>.
If any signing key material in any supplied <spanx style="verb">KEYS</spanx> object is password-protected, <spanx style="verb">sop encrypt</spanx> <bcp14>SHOULD</bcp14> try all supplied <spanx style="verb">--with-key-password</spanx> options to unlock the key material until it finds one that enables the use of the key for signing.
If none of the <spanx style="verb">--with-key-password=PASSWORD</spanx> options can unlock any locked signing key material (or if no such option is supplied), <spanx style="verb">sop encrypt</spanx> will fail with <spanx style="verb">KEY_IS_PROTECTED</spanx>.
All signatures made must be placed inside the encryption produced by <spanx style="verb">sop encrypt</spanx>.</t>

<t>Note that both <spanx style="verb">--with-password</spanx> and <spanx style="verb">--with-key-password</spanx> supply <spanx style="verb">PASSWORD</spanx> arguments, but they do so in different contexts which are not interchangeable.
A <spanx style="verb">PASSWORD</spanx> supplied for symmetric encryption (<spanx style="verb">--with-password</spanx>) <bcp14>MUST NOT</bcp14> be used to try to unlock a signing key (<spanx style="verb">--with-key-password</spanx>) and a <spanx style="verb">PASSWORD</spanx> supplied to unlock a signing key <bcp14>MUST NOT</bcp14> be used to symmetrically encrypt the message.
Regardless of context, each <spanx style="verb">PASSWORD</spanx> argument is presented as an indirect data type from which the actual password is acquired (<xref target="indirect-types"/>).
If <spanx style="verb">sop encrypt</spanx> encounters a password which is not a valid <spanx style="verb">UTF-8</spanx> string (<xref target="utf8"/>), or is otherwise not robust in its representation to humans,
it fails with <spanx style="verb">PASSWORD_NOT_HUMAN_READABLE</spanx>.
If <spanx style="verb">sop encrypt</spanx> sees trailing whitespace at the end of a password,
it will trim the trailing whitespace before using the password.
See <xref target="human-readable-passwords"/> for more discussion about passwords.</t>

<t>If <spanx style="verb">--as</spanx> is set to <spanx style="verb">binary</spanx>, then <spanx style="verb">--sign-with</spanx> will sign as a binary document (OpenPGP signature type <spanx style="verb">0x00</spanx>).</t>

<t>If <spanx style="verb">--as</spanx> is set to <spanx style="verb">text</spanx>, then <spanx style="verb">--sign-with</spanx> will sign as a canonical text document (OpenPGP signature type <spanx style="verb">0x01</spanx>).
In this case, if the input <spanx style="verb">DATA</spanx> is not valid <spanx style="verb">UTF-8</spanx>  (<xref target="utf8"/>), <spanx style="verb">sop encrypt</spanx> fails with <spanx style="verb">EXPECTED_TEXT</spanx>.</t>

<t>If <spanx style="verb">--sign-with</spanx> is supplied for input <spanx style="verb">DATA</spanx> that is not valid <spanx style="verb">UTF-8</spanx>, <spanx style="verb">sop encrypt</spanx> <bcp14>MAY</bcp14> sign as a binary document (OpenPGP signature type <spanx style="verb">0x00</spanx>).</t>

<t><spanx style="verb">sop encrypt</spanx> <bcp14>MUST NOT</bcp14> produce any extra signatures beyond those from <spanx style="verb">KEYS</spanx> objects identified by <spanx style="verb">--sign-with</spanx>.</t>

<t>The resulting <spanx style="verb">CIPHERTEXT</spanx> should be decryptable by the secret keys corresponding to every certificate included in all <spanx style="verb">CERTS</spanx>, as well as each password given with <spanx style="verb">--with-password</spanx>.</t>

<t>If no <spanx style="verb">CERTS</spanx> or <spanx style="verb">--with-password</spanx> options are present, <spanx style="verb">sop encrypt</spanx> fails with <spanx style="verb">MISSING_ARG</spanx>.</t>

<t>If at least one of the identified certificates requires encryption to an unsupported asymmetric algorithm, <spanx style="verb">sop encrypt</spanx> fails with <spanx style="verb">UNSUPPORTED_ASYMMETRIC_ALGO</spanx>.</t>

<t>If at least one of the identified certificates is not encryption-capable (e.g., revoked, expired, no encryption-capable flags on primary key and valid subkeys), <spanx style="verb">sop encrypt</spanx> fails with <spanx style="verb">CERT_CANNOT_ENCRYPT</spanx>.</t>

<t>If the <spanx style="verb">--profile</spanx> argument is supplied and the indicated <spanx style="verb">PROFILE</spanx> is not supported by the implementation, <spanx style="verb">sop</spanx> will fail with <spanx style="verb">UNSUPPORTED_PROFILE</spanx>.
The use of a profile for this subcommand allows an implementation faced with parametric or algorithmic choices to make a decision coarsely guided by the operator.
For example, when encrypting with a password, there is no knowledge about the capabilities of the recipient, and an implementation may prefer cryptographically modern algorithms, or it may prefer more broad compatibility.
In the event that a known recipient (i.e., one of the <spanx style="verb">CERTS</spanx>) explicitly indicates a lack of support for one of the features preferred by the indicated profile, the implementation <bcp14>SHOULD</bcp14> conform to the recipient's advertised capabilities where possible.</t>

<t>If <spanx style="verb">--session-key-out</spanx> argument is supplied, the session key generated for this encrypted will be written to the indicated location.
This can be useful, for example, when Alice encrypts a message to Bob, but also wants to retain the ability to read it without having any of her own secret key material available (see <xref section="9.1" sectionFormat="of" target="I-D.ietf-lamps-e2e-mail-guidance-11"/>).</t>

<t>If <spanx style="verb">sop encrypt</spanx> fails for any reason, it emits no <spanx style="verb">CIPHERTEXT</spanx>.</t>

<t>Example:</t>

<t>(In this example, <spanx style="verb">bob.bin</spanx> is a file containing Bob's binary-formatted OpenPGP certificate.
Alice is encrypting a message to both herself and Bob.)</t>

<figure><artwork><![CDATA[
$ sop encrypt --as=text --sign-with=alice.key alice.asc bob.bin < message.eml > encrypted.asc
$ head -n1 encrypted.asc
-----BEGIN PGP MESSAGE-----
$
]]></artwork></figure>

</section>
<section anchor="decrypt"><name>decrypt: Decrypt a Message</name>

<figure><artwork><![CDATA[
sop decrypt [--session-key-out=SESSIONKEY]
    [--with-session-key=SESSIONKEY...]
    [--with-password=PASSWORD...]
    [--with-key-password=PASSWORD...]
    [--verifications-out=VERIFICATIONS
     [--verify-with=CERTS...]
     [--verify-not-before=DATE]
     [--verify-not-after=DATE] ]
    [--] [KEYS...]
]]></artwork></figure>

<t><list style="symbols">
  <t>Standard Input: <spanx style="verb">CIPHERTEXT</spanx> (<xref target="ciphertext"/>)</t>
  <t>Standard Output: <spanx style="verb">DATA</spanx> (<xref target="data"/>)</t>
</list></t>

<t>The caller can ask <spanx style="verb">sop</spanx> for the session key discovered during decryption by supplying the <spanx style="verb">--session-key-out</spanx> option.
If the specified file already exists in the filesystem, <spanx style="verb">sop decrypt</spanx> will fail with <spanx style="verb">OUTPUT_EXISTS</spanx>.
When decryption is successful, <spanx style="verb">sop decrypt</spanx> writes the discovered session key to the specified file.</t>

<t><spanx style="verb">--with-session-key</spanx> enables decryption of the <spanx style="verb">CIPHERTEXT</spanx> using the session key directly against the <spanx style="verb">SEIPD</spanx> packet.
This option can be used multiple times if several possible session keys should be tried.
<spanx style="verb">SESSIONKEY</spanx> is an indirect data type from which the actual <spanx style="verb">sessionkey</spanx> value is acquired (<xref target="indirect-types"/>).</t>

<t><spanx style="verb">--with-password</spanx> enables decryption based on any <spanx style="verb">SKESK</spanx> (<xref section="5.3" sectionFormat="of" target="I-D.ietf-openpgp-crypto-refresh-10"/>) packets in the <spanx style="verb">CIPHERTEXT</spanx>.
This option can be used multiple times if the user wants to try more than one password.</t>

<t><spanx style="verb">--with-key-password</spanx> lets the user use password-protected (locked) secret key material.
If the decryption-capable secret key material in any key in the <spanx style="verb">KEYS</spanx> objects is password-protected, <spanx style="verb">sop decrypt</spanx> <bcp14>SHOULD</bcp14> try all supplied <spanx style="verb">--with-key-password</spanx> options to unlock the key material until it finds one that enables the use of the key for decryption.
If none of the <spanx style="verb">--with-key-password</spanx> options unlock the key (or if no such option is supplied), and the message cannot be decrypted with any other <spanx style="verb">KEYS</spanx>, <spanx style="verb">--with-session-key</spanx>, or <spanx style="verb">--with-password</spanx> options, <spanx style="verb">sop decrypt</spanx> will fail with <spanx style="verb">KEY_IS_PROTECTED</spanx>.</t>

<t>Note that the two kinds of <spanx style="verb">PASSWORD</spanx> options are for different domains: <spanx style="verb">--with-password</spanx> is for unlocking an <spanx style="verb">SKESK</spanx>, and <spanx style="verb">--with-key-password</spanx> is for unlocking secret key material in <spanx style="verb">KEYS</spanx>.
<spanx style="verb">sop decrypt</spanx> <bcp14>SHOULD NOT</bcp14> apply the <spanx style="verb">--with-key-password</spanx> argument to any <spanx style="verb">SKESK</spanx>, or the <spanx style="verb">--with-password</spanx> argument to any <spanx style="verb">KEYS</spanx>.</t>

<t>Each <spanx style="verb">PASSWORD</spanx> argument is an indirect data type from which the actual password is acquired (<xref target="indirect-types"/>).
If <spanx style="verb">sop decrypt</spanx> tries and fails to use a password supplied by a <spanx style="verb">PASSWORD</spanx>,
and it observes that there is trailing <spanx style="verb">UTF-8</spanx> whitespace at the end of the password,
it will retry with the trailing whitespace stripped.
See <xref target="consuming-passwords"/> for more discussion about consuming password-protected key material.</t>

<t><spanx style="verb">--verifications-out</spanx> produces signature verification status to the designated file.
If the designated file already exists in the filesystem, <spanx style="verb">sop decrypt</spanx> will fail with <spanx style="verb">OUTPUT_EXISTS</spanx>.</t>

<t>The return code of <spanx style="verb">sop decrypt</spanx> is not affected by the results of signature verification.
The caller <bcp14>MUST</bcp14> check the returned <spanx style="verb">VERIFICATIONS</spanx> to confirm signature status.
An empty <spanx style="verb">VERIFICATIONS</spanx> output indicates that no valid signatures were found.</t>

<t><spanx style="verb">--verify-with</spanx> identifies a set of certificates whose signatures would be acceptable for signatures over this message.</t>

<t>If the caller is interested in signature verification, both <spanx style="verb">--verifications-out</spanx> and at least one <spanx style="verb">--verify-with</spanx> must be supplied.
If only one of these options is supplied, <spanx style="verb">sop decrypt</spanx> fails with <spanx style="verb">INCOMPLETE_VERIFICATION</spanx>.</t>

<t><spanx style="verb">--verify-not-before</spanx> and <spanx style="verb">--verify-not-after</spanx> provide a date range for acceptable signatures,
by analogy with the options for <spanx style="verb">sop verify</spanx> (see <xref target="verify"/>).
They should only be supplied when doing signature verification.</t>

<t>See <xref target="signature-verification"/> for more details about signature verification.</t>

<t>If no <spanx style="verb">KEYS</spanx> or <spanx style="verb">--with-password</spanx> or <spanx style="verb">--with-session-key</spanx> options are present, <spanx style="verb">sop decrypt</spanx> fails with <spanx style="verb">MISSING_ARG</spanx>.</t>

<t>If unable to decrypt, <spanx style="verb">sop decrypt</spanx> fails with <spanx style="verb">CANNOT_DECRYPT</spanx>.</t>

<t><spanx style="verb">sop decrypt</spanx> only emits cleartext to Standard Output that was successfully decrypted.</t>

<t>Example:</t>

<t>(In this example, Alice stashes and re-uses the session key of an encrypted message.)</t>

<figure><artwork><![CDATA[
$ sop decrypt --session-key-out=session.key alice.sec < ciphertext.asc > cleartext.out
$ ls -l ciphertext.asc cleartext.out
-rw-r--r-- 1 user user   321 Oct 28 01:34 ciphertext.asc
-rw-r--r-- 1 user user   285 Oct 28 01:34 cleartext.out
$ sop decrypt --with-session-key=session.key < ciphertext.asc > cleartext2.out
$ diff cleartext.out cleartext2.out
$
]]></artwork></figure>

<section anchor="historic-options-for-sop-decrypt"><name>Historic Options for sop decrypt</name>

<t>The <spanx style="verb">sop decrypt</spanx> option <spanx style="verb">--verifications-out</spanx> used to be named <spanx style="verb">--verify-out</spanx>.
An implementation <bcp14>SHOULD</bcp14> accept either form of this option, and <bcp14>SHOULD</bcp14> produce a deprecation warning to standard error if the old form is used.</t>

</section>
</section>
<section anchor="inline-detach"><name>inline-detach: Split Signatures from an Inline-Signed Message</name>

<figure><artwork><![CDATA[
sop inline-detach [--no-armor] --signatures-out=SIGNATURES
]]></artwork></figure>

<t><list style="symbols">
  <t>Standard Input: <spanx style="verb">INLINESIGNED</spanx></t>
  <t>Standard Output: <spanx style="verb">DATA</spanx> (the message without any signatures)</t>
</list></t>

<t>In some contexts, the user may expect an inline-signed message of some form or another (<spanx style="verb">INLINESIGNED</spanx>, see <xref target="inlinesigned"/>) rather than a message and its detached signature.
<spanx style="verb">sop inline-detach</spanx> takes such an inline-signed message on standard input, and splits it into:</t>

<t><list style="symbols">
  <t>the potentially signed material on standard output, and</t>
  <t>a detached signature block to the destination identified by <spanx style="verb">--signatures-out</spanx></t>
</list></t>

<t>Note that no cryptographic verification of the signatures is done by this subcommand.
Once the inline-signed message is separated, verification of the detached signature can be done with <spanx style="verb">sop verify</spanx>.</t>

<t>If no <spanx style="verb">--signatures-out</spanx> is supplied, <spanx style="verb">sop inline-detach</spanx> fails with <spanx style="verb">MISSING_ARG</spanx>.</t>

<t>Note that there may be more than one Signature packet in an inline-signed message.
All signatures found in the inline-signed message will be emitted to the <spanx style="verb">--signatures-out</spanx> destination.</t>

<t>If the inline-signed message uses the Cleartext Signature Framework, it may be dash-escaped (see <xref section="7.1" sectionFormat="of" target="RFC4880"/>).
The output of <spanx style="verb">sop detach-inband-signature-and-message</spanx> will have any dash-escaping removed.</t>

<t>If the input is not an <spanx style="verb">INLINESIGNED</spanx> message, <spanx style="verb">sop inline-detach</spanx> fails with <spanx style="verb">BAD_DATA</spanx>.
If the input contains more than one object that could be interpreted as an <spanx style="verb">INLINESIGNED</spanx> message, <spanx style="verb">sop inline-detach</spanx> also fails with <spanx style="verb">BAD_DATA</spanx>.
A <spanx style="verb">sop</spanx> implementation <bcp14>MAY</bcp14> accept (and discard) leading and trailing data when the incoming <spanx style="verb">INLINESIGNED</spanx> message uses the Cleartext Signature Framework.</t>

<t>If the file designated by <spanx style="verb">--signatures-out</spanx> already exists in the filesystem, <spanx style="verb">sop detach-inband-signature-and-message</spanx> will fail with <spanx style="verb">OUTPUT_EXISTS</spanx>.</t>

<t>Note that <spanx style="verb">--no-armor</spanx> here governs the data written to the <spanx style="verb">--signatures-out</spanx> destination.
Standard output is always the raw message, not an OpenPGP packet.</t>

<t>Example:</t>

<figure><artwork><![CDATA[
$ sop inline-detach --signatures-out=Release.pgp < InRelease >Release
$ sop verify Release.pgp archive-keyring.pgp < Release
$
]]></artwork></figure>

</section>
<section anchor="inline-verify"><name>inline-verify: Verify an Inline-Signed Message</name>

<figure><artwork><![CDATA[
sop inline-verify [--not-before=DATE] [--not-after=DATE]
    [--verifications-out=VERIFICATIONS]
    [--] CERTS [CERTS...]
]]></artwork></figure>

<t><list style="symbols">
  <t>Standard Input: <spanx style="verb">INLINESIGNED</spanx> (<xref target="inlinesigned"/>)</t>
  <t>Standard Output: <spanx style="verb">DATA</spanx> (<xref target="data"/>)</t>
</list></t>

<t>This command is similar to <spanx style="verb">sop verify</spanx> (<xref target="verify"/>) except that it takes an <spanx style="verb">INLINESIGNED</spanx> message (see <xref target="inlinesigned"/>) and produces the message body (without signatures) on standard output.
It is also similar to <spanx style="verb">sop inline-detach</spanx> (<xref target="inline-detach"/>) except that it actually performs signature verification.</t>

<t><spanx style="verb">--not-before</spanx> and <spanx style="verb">--not-after</spanx> indicate that signatures with dates outside certain range <bcp14>MUST NOT</bcp14> be considered valid.</t>

<t><spanx style="verb">--not-before</spanx> defaults to the beginning of time.
Accepts the special value <spanx style="verb">-</spanx> to indicate the beginning of time (i.e., no lower boundary).</t>

<t><spanx style="verb">--not-after</spanx> defaults to the current system time (<spanx style="verb">now</spanx>).
Accepts the special value <spanx style="verb">-</spanx> to indicate the end of time (i.e., no upper boundary).</t>

<t><spanx style="verb">sop inline-verify</spanx> only returns <spanx style="verb">OK</spanx> if <spanx style="verb">INLINESIGNED</spanx> contains at least one valid signature made during the time window specified by a certificate included in any <spanx style="verb">CERTS</spanx> object.</t>

<t>For details about the valid signatures, the user <bcp14>MUST</bcp14> inspect the <spanx style="verb">VERIFICATIONS</spanx> output.</t>

<t>If no <spanx style="verb">CERTS</spanx> are supplied, <spanx style="verb">sop inline-verify</spanx> fails with <spanx style="verb">MISSING_ARG</spanx>.</t>

<t>If no valid signatures are found, <spanx style="verb">sop inline-verify</spanx> fails with <spanx style="verb">NO_SIGNATURE</spanx> and emits nothing on standard output.</t>

<t>See <xref target="signature-verification"/> for more details about signature verification.</t>

<t>Example:</t>

<t>(In this example, we see signature verification succeed first, and then fail on a modified version of the message.)</t>

<figure><artwork><![CDATA[
$ sop inline-verify -- alice.pgp < message.txt
Hello, world!
$ echo $?
0
$ sed s/Hello/Goodbye/ < message.txt | sop inline-verify -- alice.pgp
$ echo $?
3
$
]]></artwork></figure>

</section>
<section anchor="inline-sign"><name>inline-sign: Create an Inline-Signed Message</name>

<figure><artwork><![CDATA[
sop inline-sign [--no-armor]
     [--with-key-password=PASSWORD...]
     [--as={binary|text|clearsigned}]
     [--] KEYS [KEYS...]
]]></artwork></figure>

<t><list style="symbols">
  <t>Standard Input: <spanx style="verb">DATA</spanx> (<xref target="data"/>)</t>
  <t>Standard Output: <spanx style="verb">INLINESIGNED</spanx> (<xref target="inlinesigned"/>)</t>
</list></t>

<t>Exactly one signature will be made by each key in the supplied <spanx style="verb">KEYS</spanx> arguments.</t>

<t>The generated output stream will be an inline-signed message, by default producing an OpenPGP "Signed Message" packet stream.</t>

<t><spanx style="verb">--as</spanx> defaults to <spanx style="verb">binary</spanx>.
If <spanx style="verb">--as=</spanx> is set to either <spanx style="verb">text</spanx> or <spanx style="verb">clearsigned</spanx>, and the input <spanx style="verb">DATA</spanx> is not valid <spanx style="verb">UTF-8</spanx> (<xref target="utf8"/>), <spanx style="verb">sop inline-sign</spanx> fails with <spanx style="verb">EXPECTED_TEXT</spanx>.</t>

<t><spanx style="verb">--as=binary</spanx> <bcp14>SHOULD</bcp14> result in OpenPGP signatures of type 0x00 ("Signature of a binary document").
<spanx style="verb">--as=text</spanx> <bcp14>SHOULD</bcp14> result in an OpenPGP signature of type 0x01 ("Signature of a canonical text document").
See <xref section="5.2.1" sectionFormat="of" target="RFC4880"/> for more details.
<spanx style="verb">--as=clearsigned</spanx> <bcp14>SHOULD</bcp14> behave the same way as <spanx style="verb">--as=text</spanx> except that it produces an output stream using the Cleartext Signature Framework (see <xref section="7" sectionFormat="of" target="RFC4880"/> and <xref target="csf-risks"/>).</t>

<t>If both <spanx style="verb">--no-armor</spanx> and <spanx style="verb">--as=clearsigned</spanx>  are supplied, <spanx style="verb">sop inline-sign</spanx> fails with <spanx style="verb">INCOMPATIBLE_OPTIONS</spanx>.</t>

<t>If the signing key material in any key in the <spanx style="verb">KEYS</spanx> objects is password-protected, <spanx style="verb">sop inline-sign</spanx> <bcp14>SHOULD</bcp14> try all supplied <spanx style="verb">--with-key-password</spanx> options to unlock the key material until it finds one that enables the use of the key for signing.
If none of the <spanx style="verb">PASSWORD</spanx> options unlock the key (or if no such option is supplied), <spanx style="verb">sop inline-sign</spanx> will fail with <spanx style="verb">KEY_IS_PROTECTED</spanx>.
Note that <spanx style="verb">PASSWORD</spanx> is an indirect data type from which the actual password is acquired (<xref target="indirect-types"/>).
Note also the guidance for retrying variants of a non-human-readable password in <xref target="consuming-passwords"/>.</t>

<t>If any key in the <spanx style="verb">KEYS</spanx> objects is not capable of producing a signature, <spanx style="verb">sop inline-sign</spanx> will fail with <spanx style="verb">KEY_CANNOT_SIGN</spanx>.</t>

<t><spanx style="verb">sop inline-sign</spanx> <bcp14>MUST NOT</bcp14> produce any extra signatures beyond those from <spanx style="verb">KEYS</spanx> objects supplied on the command line.</t>

<t>Example:</t>

<figure><artwork><![CDATA[
$ sop inline-sign --as=clearsigned alice.sec < message.txt > message-signed.txt
$ head -n5 < message-signed.txt
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

This is the message.
-----BEGIN PGP SIGNATURE-----
$
]]></artwork></figure>

</section>
</section>
<section anchor="transport-subcommands"><name>Transport Subcommands</name>

<t>The commands in this section handle manipulating OpenPGP objects for transport: armoring and dearmoring for 7-bit cleanness and compactness, respectively.</t>

<section anchor="armor-convert-binary-to-ascii"><name>armor: Convert Binary to ASCII</name>

<figure><artwork><![CDATA[
sop armor
]]></artwork></figure>

<t><list style="symbols">
  <t>Standard Input: OpenPGP material (<spanx style="verb">SIGNATURES</spanx>, <spanx style="verb">KEYS</spanx>, <spanx style="verb">CERTS</spanx>, <spanx style="verb">CIPHERTEXT</spanx>, or <spanx style="verb">INLINESIGNED</spanx>)</t>
  <t>Standard Output: the same material with ASCII-armoring added, if not already present</t>
</list></t>

<t><spanx style="verb">sop armor</spanx> inspects the input and chooses the label appropriately, based on the OpenPGP packets encountered.
If the type of the first OpenPGP packet is:</t>

<t><list style="symbols">
  <t><spanx style="verb">0x05</spanx> (Secret-Key), the packet stream should be parsed as a <spanx style="verb">KEYS</spanx> input (with Armor Header <spanx style="verb">BEGIN PGP PRIVATE KEY BLOCK</spanx>).</t>
  <t><spanx style="verb">0x06</spanx> (Public-Key), the packet stream should be parsed as a <spanx style="verb">CERTS</spanx> input (with Armor Header <spanx style="verb">BEGIN PGP PUBLIC KEY BLOCK</spanx>).</t>
  <t><spanx style="verb">0x01</spanx> (Public-key Encrypted Session Key) or <spanx style="verb">0x03</spanx> (Symmetric-key Encrypted Session Key), the packet stream should be parsed as a <spanx style="verb">CIPHERTEXT</spanx> input (with Armor Header <spanx style="verb">BEGIN PGP MESSAGE</spanx>).</t>
  <t><spanx style="verb">0x04</spanx> (One-Pass Signature), the packet stream should be parsed as an <spanx style="verb">INLINESIGNED</spanx> input (with Armor Header <spanx style="verb">BEGIN PGP MESSAGE</spanx>).</t>
  <t><spanx style="verb">0x02</spanx> (Signature), the packet stream may be either a <spanx style="verb">SIGNATURES</spanx> input or an <spanx style="verb">INLINESIGNED</spanx> input.
If the packet stream contains only Signature packets, it should be parsed as a<spanx style="verb">SIGNATURES</spanx> input (with Armor Header <spanx style="verb">BEGIN PGP SIGNATURE</spanx>).
If it contains any packet other than a Signature packet, it should be parsed as an <spanx style="verb">INLINESIGNED</spanx> input (with Armor Header <spanx style="verb">BEGIN PGP MESSAGE</spanx>).</t>
</list></t>

<t>If the input packet stream does not match any expected sequence of packet types, <spanx style="verb">sop armor</spanx> fails with <spanx style="verb">BAD_DATA</spanx>.</t>

<t>Since <spanx style="verb">sop armor</spanx> accepts ASCII-armored input as well as binary input, this operation is idempotent on well-structured data.
A caller can use this subcommand blindly to ensure that any well-formed OpenPGP packet stream is 7-bit clean.</t>

<t>FIXME: what to do if the input is a CSF <spanx style="verb">INLINESIGNED</spanx> message?
Three choices:</t>

<t><list style="symbols">
  <t>Leave it untouched -- this violates the claim about blindly ensuring 7-bit clean, since UTF-8-encoded message text is not necessarily 7-bit clean.</t>
  <t>Convert to ASCII-armored <spanx style="verb">INLINESIGNED</spanx> -- this requires synthesis of OPS packet (from signatures block) and Literal Data packet (from the message body).</t>
  <t>Raise a specific error.</t>
</list></t>

<t>Example:</t>

<figure><artwork><![CDATA[
$ sop armor < bob.bin > bob.pgp
$ head -n1 bob.pgp
-----BEGIN PGP PUBLIC KEY BLOCK-----
$
]]></artwork></figure>

<section anchor="historic-options-for-sop-armor"><name>Historic Options for sop armor</name>

<t><spanx style="verb">sop armor</spanx> used to be specified as having a <spanx style="verb">--label</spanx> option, with an argument that took one of the following values: <spanx style="verb">auto</spanx>, <spanx style="verb">sig</spanx>, <spanx style="verb">key</spanx>, <spanx style="verb">cert</spanx>, or <spanx style="verb">message</spanx>, which allowed the user to specify the label used in the header and tail of the armoring.</t>

<t>The default value for <spanx style="verb">--label</spanx> was <spanx style="verb">auto</spanx>, which matches the currently specified behavior.
This option is now deprecated, as it offers no useful functionality.</t>

</section>
</section>
<section anchor="dearmor-convert-ascii-to-binary"><name>dearmor: Convert ASCII to Binary</name>

<figure><artwork><![CDATA[
sop dearmor
]]></artwork></figure>

<t><list style="symbols">
  <t>Standard Input: OpenPGP material (<spanx style="verb">SIGNATURES</spanx>, <spanx style="verb">KEYS</spanx>, <spanx style="verb">CERTS</spanx>, <spanx style="verb">CIPHERTEXT</spanx>, or <spanx style="verb">INLINESIGNED</spanx>)</t>
  <t>Standard Output: the same material with any ASCII-armoring removed</t>
</list></t>

<t>If the input packet stream does not match any of the expected sequence of packet types, <spanx style="verb">sop dearmor</spanx> fails with <spanx style="verb">BAD_DATA</spanx>.  See also <xref target="optional-input-armoring"/>.</t>

<t>Since <spanx style="verb">sop dearmor</spanx> accepts binary-formatted input as well as ASCII-armored input, this operation is idempotent on well-structured data.
A caller can use this subcommand blindly ensure that any well-formed OpenPGP packet stream is in its standard binary representation.</t>

<t>FIXME: what to do if the input is a CSF <spanx style="verb">INLINESIGNED</spanx>?
Three choices:</t>

<t><list style="symbols">
  <t>Leave it untouched -- output data is not really in binary format.</t>
  <t>Convert to binary-format <spanx style="verb">INLINESIGNED</spanx> -- this requires synthesis of OPS packet (from CSF <spanx style="verb">Hash</spanx> header) and Literal Data packet (from the message body).</t>
  <t>Raise a specific error.</t>
</list></t>

<t>Example:</t>

<figure><artwork><![CDATA[
$ sop dearmor < message.txt.asc > message.txt.sig
$
]]></artwork></figure>

</section>
</section>
</section>
<section anchor="input-string-types"><name>Input String Types</name>

<t>Some material is passed to <spanx style="verb">sop</spanx> directly as a string on the command line.</t>

<section anchor="date"><name>DATE</name>

<t>An ISO-8601 formatted timestamp with time zone, or the special value <spanx style="verb">now</spanx> to indicate the current system time.</t>

<t>Examples:</t>

<t><list style="symbols">
  <t><spanx style="verb">now</spanx></t>
  <t><spanx style="verb">2019-10-29T12:11:04+00:00</spanx></t>
  <t><spanx style="verb">2019-10-24T23:48:29Z</spanx></t>
  <t><spanx style="verb">20191029T121104Z</spanx></t>
</list></t>

<t>In some cases where used to specify lower and upper boundaries, a <spanx style="verb">DATE</spanx> value can be set to <spanx style="verb">-</spanx> to indicate "no time limit".</t>

<t>A flexible implementation of <spanx style="verb">sop</spanx> <bcp14>MAY</bcp14> accept date inputs in other unambiguous forms.</t>

<t>Note that whenever <spanx style="verb">sop</spanx> emits a timestamp (e.g., in <xref target="verifications"/>) it <bcp14>MUST</bcp14> produce only a UTC-based ISO-8601 compliant representation with a resolution of one second, using the literal <spanx style="verb">Z</spanx> suffix to indicate timezone.</t>

</section>
<section anchor="userid"><name>USERID</name>

<t>This is an arbitrary <spanx style="verb">UTF-8</spanx> string (<xref target="utf8"/>).
By convention, most User IDs are of the form <spanx style="verb">Display Name &lt;email.address@example.com&gt;</spanx>, but they do not need to be.</t>

<t>By internal policy, an implementation <bcp14>MAY</bcp14> reject a <spanx style="verb">USERID</spanx> if there are certain <spanx style="verb">UTF-8</spanx> strings it declines to work with as a User ID.
For example, an implementation may reject the empty string, or a string with characters in it that it considers problematic.
Of course, refusing to create a particular User ID does not prevent an implementation from encountering such a User ID in its input.</t>

</section>
<section anchor="subcommand"><name>SUBCOMMAND</name>

<t>This is an <spanx style="verb">ASCII</spanx> string that matches the name of one of the subcommands listed in <xref target="subcommands"/>.</t>

</section>
<section anchor="profile"><name>PROFILE</name>

<t>Some <spanx style="verb">sop</spanx> subcommands can accept a <spanx style="verb">--profile</spanx> option, which takes as an argument the name of a profile.</t>

<t>A profile name is a UTF-8 string that has no whitespace in it.</t>

<t>Which profiles are available depends on the <spanx style="verb">sop</spanx> implementation.</t>

<t>Similar to OpenPGP Notation names, profile names are divided into two namespaces: the IETF namespace and the user namespace.
A profile name in the user namespace ends with the <spanx style="verb">@</spanx> character (0x40) followed by a DNS domain name.
A profile name in the IETF namespace does not have an <spanx style="verb">@</spanx> character.</t>

<t>A profile name in the user space is owned and controlled by the owner of the domain in the suffix.
A <spanx style="verb">sop</spanx> implementation that implements a user profile but does not own the domain in question <bcp14>SHOULD</bcp14> hew as closely as possible to the semantics described by the owner of the domain.</t>

<t>A profile name in the IETF namespace that begins with the string <spanx style="verb">rfc</spanx> should have semantics that hew as closely as possible to the referenced RFC.
Similarly, a profile name in the IETF namespace that begins with the string <spanx style="verb">draft-</spanx> should have semantics that hew as closely as possible to the referenced Internet Draft.</t>

<t>The reserved profile name <spanx style="verb">default</spanx> in the IETF namespace simply refers to the implementation's default choices.</t>

<t>Note that this profile mechanism is intended to provide a limited way for an implementation to select among a small set of options that the implementer has vetted and is satisfied with.
It is not intended to provide an arbitrary channel for complex configuration, and a <spanx style="verb">sop</spanx> implementation <bcp14>MUST NOT</bcp14> use it in that way.</t>

</section>
</section>
<section anchor="indirect-types"><name>Input/Output Indirect Types</name>

<t>Some material is passed to <spanx style="verb">sop</spanx> indirectly, typically by referring to a filename containing the data in question.
This type of data may also be passed to <spanx style="verb">sop</spanx> on Standard Input, or delivered by <spanx style="verb">sop</spanx> to Standard Output.</t>

<t>If any input data is specified explicitly to be read from a file that does not exist, <spanx style="verb">sop</spanx> will fail with <spanx style="verb">MISSING_INPUT</spanx>.</t>

<t>If any input data does not meet the requirements described below, <spanx style="verb">sop</spanx> will fail with <spanx style="verb">BAD_DATA</spanx>.</t>

<section anchor="special-designators"><name>Special Designators for Indirect Types</name>

<t>An indirect argument or parameter that starts with <u>@</u> is not treated as a filename, but is reserved for special handling, based on the prefix that follows the <spanx style="verb">@</spanx>.
We describe two of those prefixes (<spanx style="verb">@ENV:</spanx> and <spanx style="verb">@FD:</spanx>) here.
A <spanx style="verb">sop</spanx> implementation that receives such a special designator but does not know how to handle a given prefix in that context <bcp14>MUST</bcp14> fail with <spanx style="verb">UNSUPPORTED_SPECIAL_PREFIX</spanx>.</t>

<t>If the filename for any indirect material used as input has the special form <spanx style="verb">@ENV:xxx</spanx>,
then contents of environment variable <spanx style="verb">$xxx</spanx> is used instead of looking in the filesystem.
<spanx style="verb">@ENV</spanx> is for input only: if the prefix <spanx style="verb">@ENV:</spanx> is used for any output argument, <spanx style="verb">sop</spanx> fails with <spanx style="verb">UNSUPPORTED_SPECIAL_PREFIX</spanx>.</t>

<t>If the filename for any indirect material used as either input or output has the special form <spanx style="verb">@FD:nnn</spanx> where <spanx style="verb">nnn</spanx> is a decimal integer,
then the associated data is read from file descriptor <spanx style="verb">nnn</spanx>.</t>

<t>See <xref target="special-designators-guidance"/> for more details about safe handling of these special designators.</t>

</section>
<section anchor="certs"><name>CERTS</name>

<t>One or more OpenPGP certificates (<xref section="10.1" sectionFormat="of" target="I-D.ietf-openpgp-crypto-refresh-10"/>), aka "Transferable Public Key".
May be armored (see <xref target="optional-input-armoring"/>).</t>

<t>Although some existing workflows may prefer to use one <spanx style="verb">CERTS</spanx> object with multiple certificates in it (a "keyring"), supplying exactly one certificate per <spanx style="verb">CERTS</spanx> input will make error reporting clearer and easier.</t>

</section>
<section anchor="keys"><name>KEYS</name>

<t>One or more OpenPGP Transferable Secret Keys (<xref section="10.2" sectionFormat="of" target="I-D.ietf-openpgp-crypto-refresh-10"/>).
May be armored (see <xref target="optional-input-armoring"/>).</t>

<t>Secret key material is often locked with a password to ensure that it cannot be simply copied and reused.
If any secret key material is locked with a password and no <spanx style="verb">--with-key-password</spanx> option is supplied, <spanx style="verb">sop</spanx> may fail with error <spanx style="verb">KEY_IS_PROTECTED</spanx>.
However, when a cleartext secret key (that is, one not locked with a password) is available, <spanx style="verb">sop</spanx> should always be able to use it, whether a <spanx style="verb">--with-key-password</spanx> option is supplied or not.</t>

<t>Although some existing workflows may prefer to use one <spanx style="verb">KEYS</spanx> object with multiple keys in it (a "secret keyring"), supplying exactly one key per <spanx style="verb">KEYS</spanx> input will make error reporting clearer and easier.</t>

</section>
<section anchor="ciphertext"><name>CIPHERTEXT</name>

<t><spanx style="verb">sop</spanx> accepts only a restricted subset of the arbitrarily-nested grammar allowed by the OpenPGP Messages definition (<xref section="10.3" sectionFormat="of" target="I-D.ietf-openpgp-crypto-refresh-10"/>).</t>

<t>In particular, it accepts and generates only:</t>

<t>An OpenPGP message, consisting of a sequence of PKESKs (<xref section="5.1" sectionFormat="of" target="I-D.ietf-openpgp-crypto-refresh-10"/>) and SKESKs (<xref section="5.3" sectionFormat="of" target="I-D.ietf-openpgp-crypto-refresh-10"/>),
followed by one SEIPD (<xref section="5.13" sectionFormat="of" target="I-D.ietf-openpgp-crypto-refresh-10"/>).</t>

<t>The SEIPD can decrypt into one of two things:</t>

<t><list style="symbols">
  <t>"Maybe Signed Data" (see below), or</t>
  <t>Compressed data packet that contains "Maybe Signed Data"</t>
</list></t>

<t>"Maybe Signed Data" is a sequence of:</t>

<t><list style="symbols">
  <t>N (zero or more) one-pass signature packets, followed by</t>
  <t>zero or more signature packets, followed by</t>
  <t>one Literal data packet, followed by</t>
  <t>N signature packets (corresponding to the outer one-pass signatures packets)</t>
</list></t>

<t>FIXME: does any tool do compression inside signing?  Do we need to handle that?</t>

<t>May be armored (see <xref target="optional-input-armoring"/>).</t>

</section>
<section anchor="inlinesigned"><name>INLINESIGNED</name>

<t>An inline-signed message may take any one of three different forms:</t>

<t><list style="symbols">
  <t>A binary sequence of OpenPGP packets that matches a subset of the "Signed Message" element in the grammar in <xref section="10.3" sectionFormat="of" target="I-D.ietf-openpgp-crypto-refresh-10"/></t>
  <t>The same sequence of packets, but ASCII-armored (see <xref target="optional-input-armoring"/>)</t>
  <t>A message using the Cleartext Signature Framework described in <xref section="7" sectionFormat="of" target="I-D.ietf-openpgp-crypto-refresh-10"/></t>
</list></t>

<t>The subset of the packet grammar expected in the first two forms consists of either:</t>

<t><list style="symbols">
  <t>a series of Signature packets followed by a Literal Data packet</t>
  <t>a series of One-Pass Signature (OPS) packets, followed by one Literal Data packet, followed by an equal number of Signature packets corresponding to the OPS packets</t>
</list></t>

<t>When the message is in the third form (Cleartext Signature Framework), it has the following properties:</t>

<t><list style="symbols">
  <t>The stream <bcp14>SHOULD</bcp14> consist solely of <spanx style="verb">UTF-8</spanx> text</t>
  <t>Every Signature packet found in the stream <bcp14>SHOULD</bcp14> have Signature Type 0x01 (canonical text document).</t>
  <t>It <bcp14>SHOULD NOT</bcp14> contain leading text (before the <spanx style="verb">-----BEGIN PGP SIGNED MESSAGE-----</spanx> cleartext header) or trailing text (after the <spanx style="verb">-----END PGP SIGNATURE-----</spanx> armor tail).</t>
</list></t>

<t>While some OpenPGP implementations <bcp14>MAY</bcp14> produce more complicated inline signed messages, a <spanx style="verb">sop</spanx> implementation <bcp14>SHOULD</bcp14> limit itself to producing these straightforward forms.</t>

</section>
<section anchor="signature"><name>SIGNATURES</name>

<t>One or more OpenPGP Signature packets.  May be armored (see <xref target="optional-input-armoring"/>).</t>

</section>
<section anchor="sessionkey"><name>SESSIONKEY</name>

<t>This documentation uses the GnuPG defacto <spanx style="verb">ASCII</spanx> representation:</t>

<t><spanx style="verb">ALGONUM:HEXKEY</spanx></t>

<t>where <spanx style="verb">ALGONUM</spanx> is the decimal value associated with the OpenPGP Symmetric Key Algorithms (<xref section="9.3" sectionFormat="of" target="I-D.ietf-openpgp-crypto-refresh-10"/>) and <spanx style="verb">HEXKEY</spanx> is the hexadecimal
representation of the binary key.</t>

<t>Example AES-256 session key:</t>

<figure><artwork><![CDATA[
9:FCA4BEAF687F48059CACC14FB019125CD57392BAB7037C707835925CBF9F7BCD
]]></artwork></figure>

<t>A <spanx style="verb">sop</spanx> implementation <bcp14>SHOULD</bcp14> produce session key data in this format.
When consuming such a session key, <spanx style="verb">sop</spanx> <bcp14>SHOULD</bcp14> be willing to accept either upper or lower case hexadecimal digits, and to gracefully ignore any trailing whitespace.</t>

</section>
<section anchor="micalg"><name>MICALG</name>

<t>This output-only type indicates the cryptographic digest used when making a signature.
It is useful specifically when generating signed PGP/MIME objects, which want a <spanx style="verb">micalg=</spanx> parameter for the <spanx style="verb">multipart/signed</spanx> content type as described in <xref section="5" sectionFormat="of" target="RFC3156"/>.</t>

<t>It will typically be a string like <spanx style="verb">pgp-sha512</spanx>, but in some situations (multiple signatures using different digests) it will be the empty string.
If the user of <spanx style="verb">sop</spanx> is assembling a PGP/MIME signed object, and the <spanx style="verb">MICALG</spanx> output is the empty string,
the user should omit the <spanx style="verb">micalg=</spanx> parameter entirely.</t>

</section>
<section anchor="password"><name>PASSWORD</name>

<t>This input-only is expected to be a <spanx style="verb">UTF-8</spanx> string (<xref target="utf8"/>), but for <spanx style="verb">sop decrypt</spanx>, any bytestring that the user supplies will be accepted.
Note the details in <spanx style="verb">sop encrypt</spanx> and <spanx style="verb">sop decrypt</spanx> about trailing whitespace!</t>

<t>See also <xref target="human-readable-passwords"/> for more discussion.</t>

</section>
<section anchor="verifications"><name>VERIFICATIONS</name>

<t>This output-only type consists of one line per successful signature verification.
Each line has three structured fields delimited by a single space,
followed by arbitrary text to the end of the line that forms a message describing the verification.</t>

<t><list style="symbols">
  <t>ISO-8601 UTC datestamp of the signature, to one second precision, using the <spanx style="verb">Z</spanx> suffix</t>
  <t>Fingerprint of the signing key (may be a subkey)</t>
  <t>Fingerprint of primary key of signing certificate (if signed by primary key, same as the previous field)</t>
  <t>(optional) a string describing the mode of the signature, either <spanx style="verb">mode:text</spanx> or <spanx style="verb">mode:binary</spanx></t>
  <t>message describing the verification (free form)</t>
</list></t>

<t>Note that while <xref target="date"/> permits a <spanx style="verb">sop</spanx> implementation to accept other unambiguous date representations,
its date output here <bcp14>MUST</bcp14> be a strict ISO-8601 UTC date timestamp.
In particular:</t>

<t><list style="symbols">
  <t>the date and time fields <bcp14>MUST</bcp14> be separated by <spanx style="verb">T</spanx>, not by whitespace, since whitespace is used as a delimiter</t>
  <t>the time <bcp14>MUST</bcp14> be emitted in UTC, with the explicit suffix <spanx style="verb">Z</spanx></t>
  <t>the time <bcp14>MUST</bcp14> be emitted with one-second precision</t>
</list></t>

<t>Example:</t>

<figure><artwork><![CDATA[
2019-10-24T23:48:29Z C90E6D36200A1B922A1509E77618196529AE5FF8 C4BC2DDB38CCE96485EBE9C2F20691179038E5C6 mode:binary certificate from dkg.asc
]]></artwork></figure>

</section>
<section anchor="data"><name>DATA</name>

<t>Cleartext, arbitrary data.  This is either a bytestream or <spanx style="verb">UTF-8</spanx> text.</t>

<t>It <bcp14>MUST</bcp14> only be <spanx style="verb">UTF-8</spanx> text in the case of input supplied to <spanx style="verb">sop sign --as=text</spanx> or <spanx style="verb">sop encrypt --as=text</spanx>.
If <spanx style="verb">sop</spanx> receives <spanx style="verb">DATA</spanx> containing non-<spanx style="verb">UTF-8</spanx> octets in this case, it will fail (see <xref target="utf8"/>) with <spanx style="verb">EXPECTED_TEXT</spanx>.</t>

</section>
<section anchor="profilelist"><name>PROFILELIST</name>

<t>This output-only type consists of simple UTF-8 textual output, with one line per profile.
Each line consists of the profile name optionally followed by a colon (0x31), a space (0x20), and a brief human-readable description of the intended semantics of the profile.
Each line may be at most 1000 bytes, and no more than 4 profiles may be listed.</t>

<t>These limits are intended to force <spanx style="verb">sop</spanx> implementers to make hard decisions and to keep things simple.</t>

<t>The first profile <bcp14>MAY</bcp14> be explicitly named <spanx style="verb">default</spanx>.
If it is not named <spanx style="verb">default</spanx>, then <spanx style="verb">default</spanx> is an alias for the first profile listed.
No profile after the first listed may be named <spanx style="verb">default</spanx>.</t>

<t>See <xref target="profile"/> for more discussion about the namespace and intended semantics of each profile.</t>

</section>
</section>
<section anchor="failure-modes"><name>Failure Modes</name>

<t><spanx style="verb">sop</spanx> return codes have both mnemonics and numeric values.</t>

<t>When <spanx style="verb">sop</spanx> succeeds, it will return 0 (<spanx style="verb">OK</spanx>) and emit nothing to Standard Error.
When <spanx style="verb">sop</spanx> fails, it fails with a non-zero return code, and emits one or more warning messages on Standard Error.
Known return codes include:</t>

<texttable title="Error return codes">
      <ttcol align='right'>Value</ttcol>
      <ttcol align='left'>Mnemonic</ttcol>
      <ttcol align='left'>Meaning</ttcol>
      <c>0</c>
      <c><spanx style="verb">OK</spanx></c>
      <c>Success</c>
      <c>3</c>
      <c><spanx style="verb">NO_SIGNATURE</spanx></c>
      <c>No acceptable signatures found (<spanx style="verb">sop verify</spanx>)</c>
      <c>13</c>
      <c><spanx style="verb">UNSUPPORTED_ASYMMETRIC_ALGO</spanx></c>
      <c>Asymmetric algorithm unsupported (<spanx style="verb">sop encrypt</spanx>)</c>
      <c>17</c>
      <c><spanx style="verb">CERT_CANNOT_ENCRYPT</spanx></c>
      <c>Certificate not encryption-capable (e.g., expired, revoked, unacceptable usage flags) (<spanx style="verb">sop encrypt</spanx>)</c>
      <c>19</c>
      <c><spanx style="verb">MISSING_ARG</spanx></c>
      <c>Missing required argument</c>
      <c>23</c>
      <c><spanx style="verb">INCOMPLETE_VERIFICATION</spanx></c>
      <c>Incomplete verification instructions (<spanx style="verb">sop decrypt</spanx>)</c>
      <c>29</c>
      <c><spanx style="verb">CANNOT_DECRYPT</spanx></c>
      <c>Unable to decrypt (<spanx style="verb">sop decrypt</spanx>)</c>
      <c>31</c>
      <c><spanx style="verb">PASSWORD_NOT_HUMAN_READABLE</spanx></c>
      <c>Non-<spanx style="verb">UTF-8</spanx> or otherwise unreliable password (<spanx style="verb">sop encrypt</spanx>, <spanx style="verb">sop generate-key</spanx>)</c>
      <c>37</c>
      <c><spanx style="verb">UNSUPPORTED_OPTION</spanx></c>
      <c>Unsupported option</c>
      <c>41</c>
      <c><spanx style="verb">BAD_DATA</spanx></c>
      <c>Invalid data type (no secret key where <spanx style="verb">KEYS</spanx> expected, etc)</c>
      <c>53</c>
      <c><spanx style="verb">EXPECTED_TEXT</spanx></c>
      <c>Non-text input where text expected</c>
      <c>59</c>
      <c><spanx style="verb">OUTPUT_EXISTS</spanx></c>
      <c>Output file already exists</c>
      <c>61</c>
      <c><spanx style="verb">MISSING_INPUT</spanx></c>
      <c>Input file does not exist</c>
      <c>67</c>
      <c><spanx style="verb">KEY_IS_PROTECTED</spanx></c>
      <c>A <spanx style="verb">KEYS</spanx> input is password-protected (locked), and <spanx style="verb">sop</spanx> cannot unlock it with any of the <spanx style="verb">--with-key-password</spanx> (or <spanx style="verb">--old-key-password</spanx>) options</c>
      <c>69</c>
      <c><spanx style="verb">UNSUPPORTED_SUBCOMMAND</spanx></c>
      <c>Unsupported subcommand</c>
      <c>71</c>
      <c><spanx style="verb">UNSUPPORTED_SPECIAL_PREFIX</spanx></c>
      <c>An indirect parameter is a special designator (it starts with <spanx style="verb">@</spanx>) but <spanx style="verb">sop</spanx> does not know how to handle the prefix</c>
      <c>73</c>
      <c><spanx style="verb">AMBIGUOUS_INPUT</spanx></c>
      <c>A indirect input parameter is a special designator (it starts with <spanx style="verb">@</spanx>), and a filename matching the designator is actually present</c>
      <c>79</c>
      <c><spanx style="verb">KEY_CANNOT_SIGN</spanx></c>
      <c>Key not signature-capable (e.g., expired, revoked, unacceptable usage flags) (<spanx style="verb">sop sign</spanx> and <spanx style="verb">sop encrypt</spanx> with <spanx style="verb">--sign-with</spanx>)</c>
      <c>83</c>
      <c><spanx style="verb">INCOMPATIBLE_OPTIONS</spanx></c>
      <c>Options were supplied that are incompatible with each other</c>
      <c>89</c>
      <c><spanx style="verb">UNSUPPORTED_PROFILE</spanx></c>
      <c>The requested profile is unsupported (<spanx style="verb">sop generate-key</spanx>, <spanx style="verb">sop encrypt</spanx>), or the indicated subcommand does not accept profiles (<spanx style="verb">sop list-profiles</spanx>)</c>
</texttable>

<t>If a <spanx style="verb">sop</spanx> implementation fails in some way not contemplated by this document, it <bcp14>MAY</bcp14> return any non-zero error code, not only those listed above.</t>

</section>
<section anchor="known-implementations"><name>Known Implementations</name>

<t>The following implementations are known at the time of this draft:</t>

<texttable title="Known implementations">
      <ttcol align='left'>Project name</ttcol>
      <ttcol align='left'>URL</ttcol>
      <ttcol align='left'>cli name</ttcol>
      <ttcol align='left'>notes</ttcol>
      <c>Sequoia SOP</c>
      <c>https://gitlab.com/sequoia-pgp/sequoia-sop</c>
      <c><spanx style="verb">sqop</spanx></c>
      <c>Implemented in Rust using the <spanx style="verb">sequoia-openpgp</spanx> crate</c>
      <c>gosop</c>
      <c>https://github.com/ProtonMail/gosop</c>
      <c><spanx style="verb">gosop</spanx></c>
      <c>Implemented in golang (Go) using GOpenPGP</c>
      <c>PGPainless SOP</c>
      <c>https://codeberg.org/PGPainless/pgpainless/src/branch/master/pgpainless-sop</c>
      <c><spanx style="verb">pgpainless-cli</spanx></c>
      <c>Implemented in Java using PGPainless</c>
      <c>sopgpy</c>
      <c>https://gitlab.com/sequoia-pgp/openpgp-interoperability-test-suite/-/blob/main/glue/sopgpy</c>
      <c><spanx style="verb">sopgpy</spanx></c>
      <c>Implemented in Python using PGPy</c>
      <c>sop-openpgp.js</c>
      <c>https://github.com/openpgpjs/sop-openpgpjs</c>
      <c><spanx style="verb">sop-openpgp</spanx></c>
      <c>Implemented in JavaScript using OpenPGP.js</c>
      <c>gpgme-sop</c>
      <c>https://gitlab.com/sequoia-pgp/gpgme-sop</c>
      <c><spanx style="verb">gpgme-sop</spanx></c>
      <c>A Rust wrapper around the gpgme C library</c>
      <c>RNP-sop</c>
      <c>https://gitlab.com/sequoia-pgp/rnp-sop</c>
      <c><spanx style="verb">rnp-sop</spanx></c>
      <c>A Rust wrapper around the librnp C library</c>
      <c>dkg-sop</c>
      <c>https://git.savannah.nongnu.org/cgit/dkgpg.git/tree/tools/dkg-sop.cc</c>
      <c><spanx style="verb">dkg-sop</spanx></c>
      <c>Implemented in C++ using the LibTMCG library</c>
</texttable>

</section>
<section anchor="alternate-interfaces"><name>Alternate Interfaces</name>

<t>This draft primarily defines a command line interface, but future versions may try to outline a comparable idiomatic interface for C or some other widely-used programming language.</t>

<t>Comparable idiomatic interfaces are already active in the wild for different programming languages, in particular:</t>

<t><list style="symbols">
  <t>Rust: <xref target="RUST-SOP"/></t>
  <t>Java: <xref target="SOP-JAVA"/></t>
  <t>Python: <xref target="PYTHON-SOP"/></t>
</list></t>

<t>These programmatic interfaces are typically coupled with a wrapper that can automatically generate a command-line tool compatible with this draft.</t>

<t>An implementation that uses one of these languages should target the corresponding idiomatic interface for ease of development and interoperability.</t>

</section>
<section anchor="guidance-for-implementers"><name>Guidance for Implementers</name>

<t><spanx style="verb">sop</spanx> uses a few assumptions that implementers might want to consider.</t>

<section anchor="one-openpgp-message-at-a-time"><name>One OpenPGP Message at a Time</name>

<t><spanx style="verb">sop</spanx> is intended to be a simple tool that operates on one OpenPGP object at a time.  It should be composable, if you want to use it to deal with multiple OpenPGP objects.</t>

<t>FIXME: discuss what this means for streaming.
The stdio interface doesn't necessarily imply streamed output.</t>

</section>
<section anchor="simplified-subset-of-openpgp-message"><name>Simplified Subset of OpenPGP Message</name>

<t>While the formal grammar for OpenPGP Message is arbitrarily nestable, <spanx style="verb">sop</spanx> constrains itself to what it sees as a single "layer" (see <xref target="ciphertext"/>).</t>

<t>This is a deliberate choice, because it is what most consumers expect.
Also, if an arbitrarily-nested structure is parsed with a recursive algorithm, this risks a denial of service vulnerability.
<spanx style="verb">sop</spanx> intends to be implementable with a parser that defensively declines to do recursive descent into an OpenPGP Message.</t>

<t>Note that an implementation of <spanx style="verb">sop decrypt</spanx> <bcp14>MAY</bcp14> choose to handle more complex structures, but if it does, it should document the other structures it handles and why it chooses to do so.
We can use such documentation to improve future versions of this spec.</t>

</section>
<section anchor="validate-signatures-only-from-known-signers"><name>Validate Signatures Only from Known Signers</name>

<t>There are generally only a few signers who are relevant for a given OpenPGP message.
When verifying signatures, <spanx style="verb">sop</spanx> expects that the caller can identify those relevant signers ahead of time.</t>

</section>
<section anchor="optional-input-armoring"><name>OpenPGP Inputs can be either Binary or ASCII-armored</name>

<t>OpenPGP material on input can be in either ASCII-armored or binary form.
This is a deliberate choice because there are typical scenarios where the program can't predict which form will appear.
Expecting the caller of <spanx style="verb">sop</spanx> to detect the form and adjust accordingly seems both redundant and error-prone.</t>

<t>The simple way to detect possible ASCII-armoring is to see whether the high bit of the first octet is set:
<xref section="4.2" sectionFormat="of" target="RFC4880"/> indicates that bit 7 is always one in the first octet of an OpenPGP packet.
In standard ASCII-armor, the first character is <u>-</u>, so the high bit should be cleared.</t>

<t>When considering an input as ASCII-armored OpenPGP material, <spanx style="verb">sop</spanx> <bcp14>MAY</bcp14> reject an input based on any of the following variations (see <xref section="6.2" sectionFormat="of" target="RFC4880"/> for precise definitions):</t>

<t><list style="symbols">
  <t>An unknown Armor Header Line</t>
  <t>Any text before the Armor Header Line</t>
  <t>Malformed lines in the Armor Headers section</t>
  <t>Any non-whitespace data after the Armor Tail</t>
  <t>Any Radix-64 encoded line with more than 76 characters</t>
  <t>Invalid characters in the Radix-64-encoded data</t>
  <t>An invalid Armor Checksum</t>
  <t>A mismatch between the Armor Header Line and the Armor Tail</t>
  <t>More than one ASCII-armored object in the input</t>
</list></t>

<t>For robustness, <spanx style="verb">sop</spanx> <bcp14>SHOULD</bcp14> be willing to ignore whitespace after the Armor Tail.</t>

<t>For any plural data type (i.e.,<spanx style="verb">SIGNATURES</spanx>, <spanx style="verb">CERTS</spanx>, or <spanx style="verb">KEYS</spanx>), the unarmored form is trivially concatenatable with another object of the same type (e.g., with Unix's <spanx style="verb">cat</spanx> utility).
But the armored forms are not concatenatable without first dearmoring.
To avoid inconsistent behavior, a <spanx style="verb">sop</spanx> implementation <bcp14>SHOULD</bcp14> reject anything that appears to be a concatenated series of ASCII-armored objects.</t>

<t>When considering OpenPGP material as input, regardless of whether it is ASCII-armored or binary, <spanx style="verb">sop</spanx> <bcp14>SHOULD</bcp14> reject any material that doesn't produce a valid stream of OpenPGP packets.
For example, <spanx style="verb">sop</spanx> <bcp14>SHOULD</bcp14> raise an error if an OpenPGP packet header is malformed, or if there is trailing garbage after the end of a packet.</t>

<t>For a given type of OpenPGP input material (i.e.,  <spanx style="verb">SIGNATURES</spanx>, <spanx style="verb">CERTS</spanx>, <spanx style="verb">KEYS</spanx>, <spanx style="verb">INLINESIGNED</spanx>, or <spanx style="verb">CIPHERTEXT</spanx>), <spanx style="verb">sop</spanx> <bcp14>SHOULD</bcp14> also reject any input that does not conform to the expected packet stream.
See <xref target="indirect-types"/> for the expected packet stream for different types.</t>

</section>
<section anchor="csf-risks"><name>Complexities of the Cleartext Signature Framework</name>

<t><spanx style="verb">sop</spanx> prefers a detached signature as the baseline form of OpenPGP signature, but provides affordances for dealing with inline-signed messages (see <spanx style="verb">INLINESIGNED</spanx>, <xref target="inlinesigned"/>) as well.</t>

<t>The most complex form of inline-signed messages is the Cleartext Signature Framework (CSF).
Handling the CSF structure requires parsing to delimit the multiple parts of the document, including at least:</t>

<t><list style="symbols">
  <t>any preamble before the message</t>
  <t>the inline message header (delimiter line, OpenPGP headers)</t>
  <t>the message itself</t>
  <t>the divider between the message and the signature (including any OpenPGP headers there)</t>
  <t>the signature</t>
  <t>the divider that terminates the signature</t>
  <t>any suffix after the signature</t>
</list></t>

<t>Note also that the preamble or the suffix might be arbitrary text, and might themselves contain OpenPGP messages (whether signatures or otherwise).</t>

<t>If the parser that does this split differs in any way from the parser that does the verification, or parts of the message are confused,
it would be possible to produce a verification status and an actual signed message that don't correspond to one another.</t>

<t>Blurred boundary problems like this can produce ugly attacks similar to those found in <xref target="EFAIL"></xref>.</t>

<t>A user of <spanx style="verb">sop</spanx> that receives an inline-signed message (whether the message uses the CSF or not) can detach the signature from the message with <spanx style="verb">sop inline-detach</spanx> (see <xref target="inline-detach"/>).</t>

<t>Alternately, the user can send the message through <spanx style="verb">sop inline-verify</spanx> to confirm required signatures, and then (if signatures are valid) supply its output to the consumer of the signed message.</t>

</section>
<section anchor="cert-validity-performance"><name>Reliance on Supplied Certs and Keys</name>

<t>A truly stateless implementation may find that it spends more time validating the internal consistency of certificates and keys than it does on the actual object security operations.</t>

<t>For performance reasons, an implementation may choose to ignore validation on certificate and key material supplied to it.  The security implications of doing so depend on how the certs and keys are managed outside of <spanx style="verb">sop</spanx>.</t>

</section>
<section anchor="utf8"><name>Text is always UTF-8</name>

<t>Various places in this specification require UTF-8 <xref target="RFC3629"/> when encoding text. <spanx style="verb">sop</spanx> implementations <bcp14>SHOULD NOT</bcp14> consider textual data in any other character encoding.</t>

<t>OpenPGP Implementations <bcp14>MUST</bcp14> already handle UTF-8, because various parts of <xref target="RFC4880"/> require it, including:</t>

<t><list style="symbols">
  <t>User ID</t>
  <t>Notation name</t>
  <t>Reason for revocation</t>
  <t>ASCII-armor Comment: header</t>
</list></t>

<t>Dealing with messages in other charsets leads to weird security failures like <xref target="Charset-Switching"/>, especially when the charset indication is not covered by any sort of cryptographic integrity check.
Restricting textual data to <spanx style="verb">UTF-8</spanx> universally across the OpenPGP ecosystem eliminates any such risk without losing functionality, since <spanx style="verb">UTF-8</spanx> can encode all known characters.</t>

</section>
<section anchor="human-readable-passwords"><name>Passwords are Human-Readable</name>

<t>Passwords are generally expected to be human-readable, as they are typically recorded and transmitted as human-visible, human-transferable strings.
However, they are used in the OpenPGP protocol as bytestrings, so it is important to ensure that there is a reliable bidirectional mapping between strings and bytes.
The maximally robust behavior here is for <spanx style="verb">sop encrypt</spanx> and <spanx style="verb">sop generate-key</spanx> (that is, commands that use a password to encrypt) to constrain the choice of passwords to strings that have such a mapping,
and for <spanx style="verb">sop decrypt</spanx> and <spanx style="verb">sop sign</spanx> (and <spanx style="verb">sop inline-sign</spanx>, as well as<spanx style="verb">sop encrypt</spanx> when decrypting a signing key; that is, commands that use a password to decrypt) to try multiple plausible versions of any password supplied by <spanx style="verb">PASSWORD</spanx>.</t>

<section anchor="generating-human-readable"><name>Generating Material with Human-Readable Passwords</name>

<t>When generating material based on a password, <spanx style="verb">sop encrypt</spanx> and <spanx style="verb">sop generate-key</spanx> enforce that the password is actually meaningfully human-transferable.
In particular, an implementation generating material based on a new paasword <bcp14>SHOULD</bcp14> apply the following considerations to the supplied password:</t>

<t><list style="symbols">
  <t>require <spanx style="verb">UTF-8</spanx></t>
  <t>trim trailing whitespace</t>
</list></t>

<t>Some <spanx style="verb">sop encrypt</spanx> and <spanx style="verb">sop generate-key</spanx> implementations may make even more strict requirements on input to ensure that they are transferable between humans in a robust way.</t>

<t>For example, a more strict <spanx style="verb">sop encrypt</spanx> or <spanx style="verb">sop generate-key</spanx> <bcp14>MAY</bcp14> also:</t>

<t><list style="symbols">
  <t>forbid leading whitespace</t>
  <t>forbid non-printing characters other than <spanx style="verb">SPACE (U+0020)</spanx>, such as <spanx style="verb">ZERO WIDTH NON-JOINER (U+200C)</spanx> or <spanx style="verb">TAB (U+0009)</spanx></t>
  <t>require the password to be in Unicode Normal Form C (<xref target="UNICODE-NORMALIZATION"/>)</t>
</list></t>

<t>Violations of these more-strict policies <bcp14>SHOULD</bcp14> result in an error of <spanx style="verb">PASSWORD_NOT_HUMAN_READABLE</spanx>.</t>

<t>A <spanx style="verb">sop encrypt</spanx> or <spanx style="verb">sop generate-key</spanx> implementation typically <bcp14>SHOULD NOT</bcp14> attempt enforce a minimum "password strength",
but in the event that some implementation does, it <bcp14>MUST NOT</bcp14> represent a weak password with <spanx style="verb">PASSWORD_NOT_HUMAN_READABLE</spanx>.</t>

</section>
<section anchor="consuming-passwords"><name>Consuming Password-protected Material</name>

<t>When <spanx style="verb">sop decrypt</spanx> receives a <spanx style="verb">PASSWORD</spanx> input, either from a <spanx style="verb">--with-key-password</spanx> or <spanx style="verb">--with-password</spanx> option, it sees its content as a bytestring.
<spanx style="verb">sop sign</spanx> also sees the content of any <spanx style="verb">PASSWORD</spanx> input supplied to its <spanx style="verb">--with-key-password</spanx>  option as a bytestring.
If the bytestring fails to work as a password, but ends in <spanx style="verb">UTF-8</spanx> whitespace, it will try again with the trailing whitespace removed.
This handles a common pattern of using a file with a final newline, for example.
The pattern here is one of robustness in the face of typical errors in human-transferred textual data.</t>

<t>A more robust <spanx style="verb">sop decrypt</spanx> or <spanx style="verb">sop sign</spanx> implementation that finds neither of the above two attempts work for a given <spanx style="verb">PASSWORD</spanx> <bcp14>MAY</bcp14> try additional variations if they produce a different bytestring, such as:</t>

<t><list style="symbols">
  <t>trimming any leading whitespace, if discovered</t>
  <t>trimming any internal non-printable characters other than <spanx style="verb">SPACE (U+0020)</spanx></t>
  <t>converting the supplied <spanx style="verb">PASSWORD</spanx> into Unicode Normal Form C (<xref target="UNICODE-NORMALIZATION"/>)</t>
</list></t>

<t>A <spanx style="verb">sop decrypt</spanx> or <spanx style="verb">sop sign</spanx> implementation that stages multiple decryption attempts like this <bcp14>SHOULD</bcp14> consider the computational resources consumed by each attempt, to avoid presenting an attack surface for resource exhaustion in the face of a non-standard <spanx style="verb">PASSWORD</spanx> input.</t>

</section>
</section>
<section anchor="special-designators-guidance"><name>Be Careful with Special Designators</name>

<t>As documented in <xref target="special-designators"/>, special designators for indirect inputs like <spanx style="verb">@ENV:</spanx> and <spanx style="verb">@FD:</spanx> (and indirect outputs using <spanx style="verb">@FD:</spanx>) warrant some special/cautious handling.</t>

<t>For one thing, it's conceivable that the filesystem could contain a file with these literal names.
If <spanx style="verb">sop</spanx> receives an indirect output parameter that starts with an <u>@</u> it <bcp14>MUST NOT</bcp14> write to the filesystem for that parameter.
A <spanx style="verb">sop</spanx> implementation that receives such a parameter as input <bcp14>MAY</bcp14> test for the presence of such a file in the filesystem and fail with <spanx style="verb">AMBIGUOUS_INPUT</spanx> to warn the user of the ambiguity and possible confusion.</t>

<t>These special designators are likely to be used to pass sensitive data (like secret key material or passwords) so that it doesn't need to touch the filesystem.
Given this sensitivity, <spanx style="verb">sop</spanx> should be careful with such an input, and minimize its leakage to other processes.
In particular, <spanx style="verb">sop</spanx> <bcp14>SHOULD NOT</bcp14> leak any environment variable identified by <spanx style="verb">@ENV:</spanx> or file descriptor identified by <spanx style="verb">@FD:</spanx> to any subprocess unless the subprocess specifically needs access to that data.</t>

</section>
</section>
<section anchor="guidance-for-consumers"><name>Guidance for Consumers</name>

<t>While <spanx style="verb">sop</spanx> is originally conceived of as an interface for interoperability testing, it's conceivable that an application that uses OpenPGP for object security would want to use it.</t>

<t>FIXME: more guidance for how to use such a tool safely and efficiently goes here.</t>

<t>FIXME: if an encrypted OpenPGP message arrives without metadata, it is difficult to know which signers to consider when decrypting.
How do we do this efficiently without invoking <spanx style="verb">sop decrypt</spanx> twice, once without <spanx style="verb">--verify-*</spanx> and again with the expected identity material?</t>

<section anchor="choosing-between-astext-and-asbinary"><name>Choosing Between --as=text and --as=binary</name>

<t>A program that invokes <spanx style="verb">sop</spanx> to generate an OpenPGP signature typically needs to decide whether it is making a text or binary signature.</t>

<t>By default, <spanx style="verb">sop</spanx> will make a binary signature.
The caller of <spanx style="verb">sop sign</spanx> should choose <spanx style="verb">--as=text</spanx> only when it knows that:</t>

<t><list style="symbols">
  <t>the data being signed is in fact textual, and encoded in <spanx style="verb">UTF-8</spanx>, and</t>
  <t>the signed data might be transmitted to the recipient (the verifier of the signature) over a channel that has the propensity to transform line-endings.</t>
</list></t>

<t>Examples of such channels include FTP (<xref target="RFC0959"/>) and SMTP (<xref target="RFC5321"/>).</t>

</section>
<section anchor="special-designators-and-unusual-filenames"><name>Special Designators and Unusual Filenames</name>

<t>In some cases, a user of <spanx style="verb">sop</spanx> might want to pass all the files in a given directory as positional parameters (e.g., a list of CERTS files to test a signature against).</t>

<t>If one of the files has a name that starts with <spanx style="verb">--</spanx>, it might be confused by <spanx style="verb">sop</spanx> for an option.
If one of the files has a name that starts with <spanx style="verb">@</spanx>, it might be confused by <spanx style="verb">sop</spanx> as a special designator (<xref target="special-designators"/>).</t>

<t>If the user wants to deliberately refer to such an ambiguously-named file in the filesystem, they should prefix the filename with  <spanx style="verb">./</spanx> or use an absolute path.</t>

<t>Any specific <spanx style="verb">@FD:</spanx> special designator <bcp14>SHOULD NOT</bcp14> be supplied more than once to an invocation of <spanx style="verb">sop</spanx>.
If a <spanx style="verb">sop</spanx> invocation sees multiple copies of a specific <spanx style="verb">@FD:n</spanx> input (e.g., <spanx style="verb">sop sign @FD:3 @FD:3</spanx>),
it <bcp14>MAY</bcp14> fail with <spanx style="verb">MISSING_INPUT</spanx> even if file descriptor 3 contains a valid <spanx style="verb">KEYS</spanx>, because the bytestream for the <spanx style="verb">KEYS</spanx> was consumed by the first argument.
Doubling up on the same <spanx style="verb">@FD:</spanx> for output (e.g., <spanx style="verb">sop decrypt --session-key-out=@FD:3 --verifications-out=@FD:3</spanx>) also results in an ambiguous data stream.</t>

</section>
</section>
<section anchor="security-considerations"><name>Security Considerations</name>

<t>The OpenPGP object security model is typically used for confidentiality and authenticity purposes.</t>

<section anchor="signature-verification"><name>Signature Verification</name>

<t>In many contexts, an OpenPGP signature is verified to prove the origin and integrity of an underlying object.</t>

<t>When <spanx style="verb">sop</spanx> checks a signature over data (e.g., via <spanx style="verb">sop verify</spanx> or <spanx style="verb">sop decrypt --verify-with</spanx>), it <bcp14>MUST NOT</bcp14> consider it to be verified unless all of these conditions are met:</t>

<t><list style="symbols">
  <t>The signature must be made by a signing-capable public key that is present in one of the supplied certificates</t>
  <t>The certificate and signing subkey must have been created before or at the signature time</t>
  <t>The certificate and signing subkey must not have been expired at the signature time</t>
  <t>The certificate and signing subkey must not be revoked with a "hard" revocation</t>
  <t>If the certificate or signing subkey is revoked with a "soft" revocation, then the signature time must predate the revocation</t>
  <t>The signing subkey must be properly bound to the primary key, and cross-signed</t>
  <t>The signature (and any dependent signature, such as the cross-sig or subkey binding signatures) must be made with strong cryptographic algorithms (e.g., not <spanx style="verb">MD5</spanx> or a 1024-bit <spanx style="verb">RSA</spanx> key)</t>
  <t>The signature must be of type 0x00 ("Signature of a binary document") or 0x01 ("Signature of a canonical text document"); other signature types are inappropriate for data signatures</t>
</list></t>

<t>Implementers <bcp14>MAY</bcp14> also consider other factors in addition to the origin and authenticity, including application-specific information.</t>

<t>For example, consider the application domain of checking software updates.
If software package Foo version 13.3.2 was signed on 2019-10-04, and the user receives a copy of Foo version 12.4.8 that was signed on 2019-10-16, it may be authentic and have a more recent signature date.
But it is not an upgrade (12.4.8 &lt; 13.3.2), and therefore it should not be applied automatically.</t>

<t>In such cases, it is critical that the application confirms that the other information verified is <em>also</em> protected by the relevant OpenPGP signature.</t>

<t>Signature validity is a complex topic (see for example the discussion at <xref target="DISPLAYING-SIGNATURES"/>), and this documentation cannot list all possible details.</t>

</section>
<section anchor="compression"><name>Compression</name>

<t>The interface as currently specified does not allow for control of compression.
Compressing and encrypting data that may contain both attacker-supplied material and sensitive material could leak information about the sensitive material (see the CRIME attack).</t>

<t>Unless an application knows for sure that no attacker-supplied material is present in the input, it should not compress during encryption.</t>

</section>
</section>
<section anchor="privacy-considerations"><name>Privacy Considerations</name>

<t>Material produced by <spanx style="verb">sop encrypt</spanx> may be placed on an untrusted machine (e.g., sent through the public <spanx style="verb">SMTP</spanx> network).
That material may contain metadata that leaks associational information (e.g., recipient identifiers in PKESK packets (<xref section="5.1" sectionFormat="of" target="I-D.ietf-openpgp-crypto-refresh-10"/>)).
FIXME: document things like PURBs and <spanx style="verb">--hidden-recipient</spanx>)</t>

<section anchor="object-security-vs-transport-security"><name>Object Security vs. Transport Security</name>

<t>OpenPGP offers an object security model, but says little to nothing about how the secured objects get to the relevant parties.</t>

<t>When sending or receiving OpenPGP material, the implementer should consider what privacy leakage is implicit with the transport.</t>

</section>
</section>


  </middle>

  <back>


    <references title='Normative References'>



<reference anchor='RFC2119'>
  <front>
    <title>Key words for use in RFCs to Indicate Requirement Levels</title>
    <author fullname='S. Bradner' initials='S.' surname='Bradner'/>
    <date month='March' year='1997'/>
    <abstract>
      <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
    </abstract>
  </front>
  <seriesInfo name='BCP' value='14'/>
  <seriesInfo name='RFC' value='2119'/>
  <seriesInfo name='DOI' value='10.17487/RFC2119'/>
</reference>

<reference anchor='RFC8174'>
  <front>
    <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
    <author fullname='B. Leiba' initials='B.' surname='Leiba'/>
    <date month='May' year='2017'/>
    <abstract>
      <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
    </abstract>
  </front>
  <seriesInfo name='BCP' value='14'/>
  <seriesInfo name='RFC' value='8174'/>
  <seriesInfo name='DOI' value='10.17487/RFC8174'/>
</reference>

<reference anchor='RFC4880'>
  <front>
    <title>OpenPGP Message Format</title>
    <author fullname='J. Callas' initials='J.' surname='Callas'/>
    <author fullname='L. Donnerhacke' initials='L.' surname='Donnerhacke'/>
    <author fullname='H. Finney' initials='H.' surname='Finney'/>
    <author fullname='D. Shaw' initials='D.' surname='Shaw'/>
    <author fullname='R. Thayer' initials='R.' surname='Thayer'/>
    <date month='November' year='2007'/>
    <abstract>
      <t>This document is maintained in order to publish all necessary information needed to develop interoperable applications based on the OpenPGP format. It is not a step-by-step cookbook for writing an application. It describes only the format and methods needed to read, check, generate, and write conforming packets crossing any network. It does not deal with storage and implementation questions. It does, however, discuss implementation issues necessary to avoid security flaws.</t>
      <t>OpenPGP software uses a combination of strong public-key and symmetric cryptography to provide security services for electronic communications and data storage. These services include confidentiality, key management, authentication, and digital signatures. This document specifies the message formats used in OpenPGP. [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name='RFC' value='4880'/>
  <seriesInfo name='DOI' value='10.17487/RFC4880'/>
</reference>


<reference anchor='I-D.ietf-openpgp-crypto-refresh-10'>
   <front>
      <title>OpenPGP</title>
      <author fullname='Paul Wouters' initials='P.' surname='Wouters'>
         <organization>Aiven</organization>
      </author>
      <author fullname='Daniel Huigens' initials='D.' surname='Huigens'>
         <organization>Proton AG</organization>
      </author>
      <author fullname='Justus Winter' initials='J.' surname='Winter'>
         <organization>Sequoia-PGP</organization>
      </author>
      <author fullname='Niibe Yutaka' initials='N.' surname='Yutaka'>
         <organization>FSIJ</organization>
      </author>
      <date day='21' month='June' year='2023'/>
      <abstract>
	 <t>   This document specifies the message formats used in OpenPGP.  OpenPGP
   provides encryption with public-key or symmetric cryptographic
   algorithms, digital signatures, compression and key management.

   This document is maintained in order to publish all necessary
   information needed to develop interoperable applications based on the
   OpenPGP format.  It is not a step-by-step cookbook for writing an
   application.  It describes only the format and methods needed to
   read, check, generate, and write conforming packets crossing any
   network.  It does not deal with storage and implementation questions.
   It does, however, discuss implementation issues necessary to avoid
   security flaws.

   This document obsoletes: RFC 4880 (OpenPGP), RFC 5581 (Camellia in
   OpenPGP) and RFC 6637 (Elliptic Curves in OpenPGP).

	 </t>
      </abstract>
   </front>
   <seriesInfo name='Internet-Draft' value='draft-ietf-openpgp-crypto-refresh-10'/>
   
</reference>

<reference anchor='RFC3156'>
  <front>
    <title>MIME Security with OpenPGP</title>
    <author fullname='M. Elkins' initials='M.' surname='Elkins'/>
    <author fullname='D. Del Torto' initials='D.' surname='Del Torto'/>
    <author fullname='R. Levien' initials='R.' surname='Levien'/>
    <author fullname='T. Roessler' initials='T.' surname='Roessler'/>
    <date month='August' year='2001'/>
    <abstract>
      <t>This document describes how the OpenPGP Message Format can be used to provide privacy and authentication using the Multipurpose Internet Mail Extensions (MIME) security content types described in RFC 1847. [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name='RFC' value='3156'/>
  <seriesInfo name='DOI' value='10.17487/RFC3156'/>
</reference>

<reference anchor='RFC3629'>
  <front>
    <title>UTF-8, a transformation format of ISO 10646</title>
    <author fullname='F. Yergeau' initials='F.' surname='Yergeau'/>
    <date month='November' year='2003'/>
    <abstract>
      <t>ISO/IEC 10646-1 defines a large character set called the Universal Character Set (UCS) which encompasses most of the world's writing systems. The originally proposed encodings of the UCS, however, were not compatible with many current applications and protocols, and this has led to the development of UTF-8, the object of this memo. UTF-8 has the characteristic of preserving the full US-ASCII range, providing compatibility with file systems, parsers and other software that rely on US-ASCII values but are transparent to other values. This memo obsoletes and replaces RFC 2279.</t>
    </abstract>
  </front>
  <seriesInfo name='STD' value='63'/>
  <seriesInfo name='RFC' value='3629'/>
  <seriesInfo name='DOI' value='10.17487/RFC3629'/>
</reference>




    </references>

    <references title='Informative References'>

<reference anchor="OpenPGP-Interoperability-Test-Suite" target="https://tests.sequoia-pgp.org/">
  <front>
    <title>OpenPGP Interoperability Test Suite</title>
    <author >
      <organization></organization>
    </author>
    <date year="2021" month="October" day="25"/>
  </front>
</reference>
<reference anchor="Charset-Switching" target="https://dkg.fifthhorseman.net/notes/inline-pgp-harmful/">
  <front>
    <title>Inline PGP Considered Harmful</title>
    <author initials="D. K." surname="Gillmor" fullname="Daniel Kahn Gillmor">
      <organization></organization>
    </author>
    <date year="2014" month="February" day="24"/>
  </front>
</reference>
<reference anchor="DISPLAYING-SIGNATURES" target="https://admin.hostpoint.ch/pipermail/enigmail-users_enigmail.net/2017-November/004683.html">
  <front>
    <title>On Displaying Signatures</title>
    <author initials="P." surname="Brunschwig" fullname="Patrick Brunschwig">
      <organization></organization>
    </author>
    <date year="n.d."/>
  </front>
</reference>
<reference anchor="EFAIL" target="https://efail.de">
  <front>
    <title>Efail: Breaking S/MIME and OpenPGP Email Encryption using Exfiltration Channels</title>
    <author initials="D." surname="Poddebniak" fullname="Damian Poddebniak">
      <organization></organization>
    </author>
    <author initials="C." surname="Dresen" fullname="Christian Dresen">
      <organization></organization>
    </author>
    <date year="n.d."/>
  </front>
</reference>
<reference anchor="PYTHON-SOP" target="https://pypi.org/project/sop/">
  <front>
    <title>SOP for python</title>
    <author initials="D." surname="Gillmor" fullname="Daniel Kahn Gillmor">
      <organization></organization>
    </author>
    <date year="n.d."/>
  </front>
</reference>
<reference anchor="RUST-SOP" target="https://sequoia-pgp.gitlab.io/sop-rs/">
  <front>
    <title>A Rust implementation of the Stateless OpenPGP Protocol</title>
    <author initials="J." surname="Winter" fullname="Justus Winter">
      <organization>Sequoia</organization>
    </author>
    <date year="n.d."/>
  </front>
</reference>
<reference anchor="SEMVER" target="https://semver.org/">
  <front>
    <title>Semantic Versioning 2.0.0</title>
    <author initials="T." surname="Preston-Werner" fullname="Tom Preston-Werner">
      <organization></organization>
    </author>
    <date year="2013" month="June" day="18"/>
  </front>
</reference>
<reference anchor="SOP-JAVA" target="https://github.com/pgpainless/sop-java">
  <front>
    <title>Stateless OpenPGP Protocol for Java.</title>
    <author initials="P." surname="Schaub" fullname="Paul Schaub">
      <organization></organization>
    </author>
    <date year="n.d."/>
  </front>
</reference>
<reference anchor="UNICODE-NORMALIZATION" target="https://unicode.org/reports/tr15/">
  <front>
    <title>Unicode Normalization Forms</title>
    <author initials="K." surname="Whistler" fullname="Ken Whistler">
      <organization>Unicode Consortium</organization>
    </author>
    <date year="2019" month="February" day="04"/>
  </front>
</reference>



<reference anchor='I-D.draft-bre-openpgp-samples-01'>
   <front>
      <title>OpenPGP Example Keys and Certificates</title>
      <author fullname='Bjarni Rúnar Einarsson' initials='B. R.' surname='Einarsson'>
         <organization>Mailpile ehf</organization>
      </author>
      <author fullname='&quot;juga&quot;' initials='' surname='&quot;juga&quot;'>
         <organization>Independent</organization>
      </author>
      <author fullname='Daniel Kahn Gillmor' initials='D. K.' surname='Gillmor'>
         <organization>American Civil Liberties Union</organization>
      </author>
      <date day='20' month='December' year='2019'/>
      <abstract>
	 <t>   The OpenPGP development community benefits from sharing samples of
   signed or encrypted data.  This document facilitates such
   collaboration by defining a small set of OpenPGP certificates and
   keys for use when generating such samples.

	 </t>
      </abstract>
   </front>
   <seriesInfo name='Internet-Draft' value='draft-bre-openpgp-samples-01'/>
   
</reference>


<reference anchor='I-D.ietf-lamps-e2e-mail-guidance-11'>
   <front>
      <title>Guidance on End-to-End E-mail Security</title>
      <author fullname='Daniel Kahn Gillmor' initials='D. K.' surname='Gillmor'>
         <organization>American Civil Liberties Union</organization>
      </author>
      <author fullname='Bernie Hoeneisen' initials='B.' surname='Hoeneisen'>
         <organization>pEp Foundation</organization>
      </author>
      <author fullname='Alexey Melnikov' initials='A.' surname='Melnikov'>
         <organization>Isode Ltd</organization>
      </author>
      <date day='8' month='August' year='2023'/>
      <abstract>
	 <t>   End-to-end cryptographic protections for e-mail messages can provide
   useful security.  However, the standards for providing cryptographic
   protection are extremely flexible.  That flexibility can trap users
   and cause surprising failures.  This document offers guidance for
   mail user agent implementers to help mitigate those risks, and to
   make end-to-end e-mail simple and secure for the end user.  It
   provides a useful set of vocabulary as well as suggestions to avoid
   common failures.  It also identifies a number of currently unsolved
   usability and interoperability problems.

	 </t>
      </abstract>
   </front>
   <seriesInfo name='Internet-Draft' value='draft-ietf-lamps-e2e-mail-guidance-11'/>
   
</reference>

<reference anchor='RFC0959'>
  <front>
    <title>File Transfer Protocol</title>
    <author fullname='J. Postel' initials='J.' surname='Postel'/>
    <author fullname='J. Reynolds' initials='J.' surname='Reynolds'/>
    <date month='October' year='1985'/>
    <abstract>
      <t>This memo is the official specification of the File Transfer Protocol (FTP) for the DARPA Internet community. The primary intent is to clarify and correct the documentation of the FTP specification, not to change the protocol. The following new optional commands are included in this edition of the specification: Change to Parent Directory (CDUP), Structure Mount (SMNT), Store Unique (STOU), Remove Directory (RMD), Make Directory (MKD), Print Directory (PWD), and System (SYST). Note that this specification is compatible with the previous edition.</t>
    </abstract>
  </front>
  <seriesInfo name='STD' value='9'/>
  <seriesInfo name='RFC' value='959'/>
  <seriesInfo name='DOI' value='10.17487/RFC0959'/>
</reference>

<reference anchor='RFC5321'>
  <front>
    <title>Simple Mail Transfer Protocol</title>
    <author fullname='J. Klensin' initials='J.' surname='Klensin'/>
    <date month='October' year='2008'/>
    <abstract>
      <t>This document is a specification of the basic protocol for Internet electronic mail transport. It consolidates, updates, and clarifies several previous documents, making all or parts of most of them obsolete. It covers the SMTP extension mechanisms and best practices for the contemporary Internet, but does not provide details about particular extensions. Although SMTP was designed as a mail transport and delivery protocol, this specification also contains information that is important to its use as a "mail submission" protocol for "split-UA" (User Agent) mail reading systems and mobile environments. [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name='RFC' value='5321'/>
  <seriesInfo name='DOI' value='10.17487/RFC5321'/>
</reference>




    </references>


<section anchor="c-library-api-tentative"><name>C Library API (Tentative)</name>

<t>As specified in this draft, SOP is a command-line tool.</t>

<t>However, it can also be useful to have a comparable API exposed as a C library.
This library can be implemented as a shared object (e.g., <spanx style="verb">.so</spanx>, <spanx style="verb">.dll</spanx>, or <spanx style="verb">.dylib</spanx> depending on the platform) or as a statically linked object.
This interface can be reused in many different places, as most modern programming languages offer "bindings" to C libraries.</t>

<t>A proposed interface to a C library follows here as a C header file.</t>

<figure><sourcecode type="text/x-chdr" name="sop.h"><![CDATA[
#ifndef __SOP_H__
#define __SOP_H__

#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>

/* C API for Stateless OpenPGP */

/* Depends on C99 */


/* statically-defined, non-opaque definitions */

typedef enum {
  SOP_OK = 0,
  SOP_INTERNAL_ERROR = 1, /* Not part of sop CLI */
  SOP_INVALID_ARG = 2, /* Not part of sop CLI */
  SOP_NO_SIGNATURE = 3,
  SOP_UNSUPPORTED_ASYMMETRIC_ALGO = 13,
  SOP_CERT_CANNOT_ENCRYPT = 17,
  SOP_MISSING_ARG = 19,
  SOP_INCOMPLETE_VERIFICATION = 23,
  SOP_CANNOT_DECRYPT = 29,
  SOP_PASSWORD_NOT_HUMAN_READABLE = 31,
  SOP_UNSUPPORTED_OPTION = 37,
  SOP_BAD_DATA = 41,
  SOP_EXPECTED_TEXT = 53,
  SOP_OUTPUT_EXISTS = 59,
  SOP_MISSING_INPUT = 61,
  SOP_KEY_IS_PROTECTED = 67,
  SOP_UNSUPPORTED_SUBCOMMAND = 69,
  SOP_UNSUPPORTED_SPECIAL_PREFIX = 71,
  SOP_AMBIGUOUS_INPUT = 73,
  SOP_KEY_CANNOT_SIGN = 79,
  SOP_INCOMPATIBLE_OPTIONS = 83,
  SOP_UNSUPPORTED_PROFILE = 89,
} sop_err;
  

typedef enum {
  SOP_SIGN_AS_BINARY = 0,
  SOP_SIGN_AS_TEXT = 1,
} sop_sign_as;

typedef enum {
  SOP_INLINE_SIGN_AS_BINARY = 0,
  SOP_INLINE_SIGN_AS_TEXT = 1,
  SOP_INLINE_SIGN_AS_CLEARSIGNED = 2,
} sop_inline_sign_as;

typedef enum {
  SOP_ENCRYPT_AS_BINARY = 0,
  SOP_ENCRYPT_AS_TEXT = 1,
} sop_encrypt_as;


/* FIXME: timestamps */
/* time_t is 32-bit on some architectures; we also want this to be
   able to represent a "none" value as well as a "now" value without
   removing some value from the range of time_t */
typedef time_t sop_time;
#define sop_time_none ((sop_time)0)
#define sop_time_now ((sop_time)-1)


/* Context object
 *
 * Each SOP object is bound back to a context object, and, when used
 * in combination with other SOP objects, all SOP objects should come
 * from the same context.
 */

struct sop_ctx_st;
typedef struct sop_ctx_st sop_ctx;

sop_ctx*
sop_ctx_new ();
void
sop_ctx_free (sop_ctx *sop);

/* Logging: */

typedef enum {
  SOP_LOG_ERROR = 1,
  SOP_LOG_WARNING = 2,
  SOP_LOG_INFO = 3,
  SOP_LOG_DEBUG = 4,
} sop_log_level;

static inline const char *
sop_log_level_name (sop_log_level log_level) {
#define rep(x) if (log_level == SOP_LOG_ ## x) return #x
  rep(ERROR);
  rep(WARNING);
  rep(INFO);
  rep(DEBUG);
#undef rep
  return "Unknown";
}

/* Handle warnings and other feedback.
 * 
 * A SOP implementation that is capable of producing log messages will
 * invoke the requested function with the log level of the message,
 * and a NULL-terminated UTF-8 human-readable string with no trailing
 * whitespace.
 */
typedef void (*sop_log_func) (sop_log_level log_level, const char *);
void
sop_set_log_function (sop_ctx *sop, sop_log_func func);
/* Set the logging verbosity.
 *
 * Only log warnings up to max_level. (by default, max_level is
 * SOP_LOG_WARNING, meaning SOP_LOG_INFO and SOP_LOG_DEBUG will be
 * suppressed).
 */
void
sop_set_log_level (sop_ctx *sop, sop_log_level max_level);



/* Information about the library: */

/* The name and version of the implementation of the C API (simple
   NUL-terminated string, no newlines) MUST NOT return NULL. */
const char *
sop_version (sop_ctx *sop);
/* The name and version of the primary underlying OpenPGP toolkit */
const char *
sop_version_backend (sop_ctx *sop);
/* Any arbitrary extended version information other than sop_ctx_version.
   Version info should be UTF-8 text, separated by newlines (a
   NUL-terminated string, no trailing newline).  Can return NULL if
   there is nothing more to report beyond sop_version. */
const char *
sop_version_extended (sop_ctx *sop);

/* note: there is nothing comparable to sop version --sop-spec because
 * that should be visible based on the exported symbols in the shared
 * object */



/* PROFILE objects: */

/* These describe a profile (e.g. for generate-key or encrypt).  This
 * use used when the implementation might legitimately want to offer
 * the user some minimal amount of control over what is done.  The
 * profile-listing functions return blocks of four profiles.  A
 * sop_profile value of NULL represents no profile at all.  In a list
 * of sop_profile objects, once a NULL profile appears, no non-NULL
 * profiles may follow.
 
 */
struct sop_profile_st;
typedef struct sop_profile_st sop_profile;
/* the NUL-terminated string returned by sop_profile_name MUST be a
   UTF-8 encoded string, and MUST NOT include any whitespace or colon
   (`:`) characters.  It MUST NOT vary depending on locale. */
const char *
sop_profile_name (const sop_profile *profile);
/* The NUL-terminated string returned by sop_profile_description
   cannot contain any newlines, and it MAY vary depending on
   locale(7) if the implementation is internationalized. */
const char *
sop_profile_description (const sop_profile *profile);


#define SOP_MAX_PROFILE_COUNT 4

typedef struct {
  sop_profile *profile[SOP_MAX_PROFILE_COUNT];
} sop_profiles;

static inline int
sop_profiles_count(const sop_profiles profiles) {
  for (int i = 0; i < SOP_MAX_PROFILE_COUNT; i++)
    if (profiles.profile[i] == NULL)
      return i;
  return SOP_MAX_PROFILE_COUNT;
}

/* Return a list of profiles supported by the library for generating
 * keys.
 */
sop_profiles
sop_list_profiles_generate_key (sop_ctx *sop);


/* CLEARTEXT (and other raw data): */

/* This is a standard buffer for bytestrings produced by sop.  Users
   never create this kind of object, but it is sometimes returned from
   the library. */
struct sop_buf_st;
typedef struct sop_buf_st sop_buf;

void
sop_buf_free (sop_buf *buf);
size_t
sop_buf_size (const sop_buf *buf);
const uint8_t *
sop_buf_data (const sop_buf *buf);


/* KEYS objects: */
struct sop_keys_st;
typedef struct sop_keys_st sop_keys;

sop_err
sop_keys_import (sop_ctx *sop,
                 const uint8_t* data, size_t len,
                 sop_keys **out);
sop_err
sop_keys_export (const sop_keys *keys,
                 bool armor, sop_buf **out);
void
sop_keys_free (sop_keys *keys);



/* Generate a new, minimal OpenPGP Transferable secret key.  `profile`
   can be NULL to mean the default profile. */
sop_err
sop_generate_key_with_profile (sop_ctx *sop,
                               sop_profile *profile,
                               bool sign_only,
                               sop_keys **out);

static inline sop_err
sop_generate_key (sop_ctx *sop, sop_keys **out) {
  return sop_generate_key_with_profile (sop, NULL, false, out);
}

/* add the given user ID to each key in the sop_keys object. */
sop_err
sop_keys_add_uid (sop_keys *keys, const char *uid);

/* returns true if any of the secret key material is currently locked
   with a password */
bool
sop_keys_locked (sop_keys *keys);

/* unlocks any secret key material encrypted with `password`.
   returns SOP_OK if all keys have now been unlocked.

   If any locked key material could not be unlocked, return
   SOP_KEY_IS_PROTECTED, while also unlocking what key material can be
   unlocked.

   This allows the user to try an arbitrary bytestream as a password.
   Most users will just invoke the inlined sop_keys_unlock, below.*/
sop_err
sop_keys_unlock_raw (sop_keys *keys,
                     const uint8_t *raw_password, size_t len);


static inline sop_err
sop_keys_unlock (sop_keys *keys, const char *password) {
  return sop_keys_unlock_raw (keys,
                              (const uint8_t *)password,
                              strlen (password));
}


/* locks all secret key material with `password` where possible.

   If any key material is already locked, it does nothing and returns
   SOP_KEY_IS_PROTECTED.
*/
sop_err
sop_keys_lock_raw (sop_keys *keys,
                   const uint8_t *password, size_t len);

static inline sop_err
sop_keys_lock (sop_keys *keys, const char *password) {
  return sop_keys_lock_raw (keys,
                            (const uint8_t *)password,
                            strlen (password));
}





/* CERTS objects: */
struct sop_certs_st;
typedef struct sop_certs_st sop_certs;

sop_err
sop_certs_import (sop_ctx *sop,
                  const uint8_t* data, size_t len,
                  sop_certs **out);
sop_err
sop_certs_export (const sop_certs *certs,
                  bool armor, sop_buf **out);
void
sop_certs_free (sop_certs *certs);

/* Return the OpenPGP certificates ("Transferable Public Keys") that
   correspond to the OpenPGP Transferable Secret Keys. */
sop_err
sop_keys_extract_certs (const sop_keys *keys, sop_certs **out);


/* Return an OpenPGP revocation certificate for each Transferable
   Secret Key found in the input. */
sop_err
sop_keys_revoke_keys (const sop_keys *keys, sop_certs **out);






/* SIGNATURES objects: */
struct sop_sigs_st;
typedef struct sop_sigs_st sop_sigs;

sop_err
sop_sigs_import (sop_ctx *sop,
                 const uint8_t* data, size_t len,
                 sop_sigs **out);
sop_err
sop_sigs_export (const sop_sigs *sigs,
                 bool armor, sop_buf **out);
void
sop_sigs_free (sop_sigs *sigs);



/* VERIFICATIONS (output only, describes valid, verified signatures): */
struct sop_verifications_st;
typedef struct sop_verifications_st sop_verifications;

void
sop_verifications_free (sop_verifications *verifs);
int
sop_verifications_count (const sop_verifications *verifs);
/* textual representations of verifications, in the form described by
   VERIFICATIONS in the CLI */
sop_err
sop_verifications_export (const sop_verifications *verifs,
                          sop_buf **out);
/* returns sop_time_none if count is out of bounds */
sop_time
sop_verifications_get_time (const sop_verifications *verifs, int count);
/* returns SOP_INTERNAL_ERROR if count is out of bounds.  If the
   signature is neither type 0x00 nor 0x01, this should probably not
   be considered a valid, verified signature. */
sop_err
sop_verifications_get_mode (const sop_verifications *verifs,
                            int count, sop_sign_as **out);

/* FIXME: (do we want to get more detailed info programmatically?
   each verification should also have an issuing key fingerprint, a
   primary key fingerprint, and a trailing text string) */






/* create detached signatures: */
struct sop_op_sign_st;
typedef struct sop_op_sign_st sop_op_sign;

sop_op_sign*
sop_op_sign_new (sop_ctx *sop);
void
sop_op_sign_free (sop_op_sign *sign);

sop_err
sop_op_sign_use_keys (sop_op_sign *sign, const sop_keys *keys);

sop_err
sop_op_sign_detached_execute (sop_op_sign *sign,
                              sop_sign_as sign_as,
                              const uint8_t *msg,
                              size_t sz,
                              sop_buf **micalg_out,
                              sop_sigs **out);


/* verify detached signatures: */
struct sop_op_verify_st;
typedef struct sop_op_verify_st sop_op_verify;

sop_op_verify*
sop_op_verify_new (sop_ctx *sop);
void
sop_op_verify_free (sop_op_verify *verify);

sop_err
sop_op_verify_not_before (sop_op_verify *verify, sop_time when);
sop_err
sop_op_verify_not_after (sop_op_verify *verify, sop_time when);
sop_err
sop_op_verify_add_signers (sop_op_verify *verify,
                           const sop_certs *signers);

/* if no verifications are possible with the set of signers, this
   returns SOP_NO_SIGNATURE, and *out is set to NULL */
sop_err
sop_op_verify_detached_execute (sop_op_verify *verify,
                                const sop_sigs *sigs,
                                const uint8_t *msg,
                                size_t sz,
                                sop_verifications **out);



/* INLINESIGNED object: */
struct sop_inlinesigned_st;
typedef struct sop_inlinesigned_st sop_inlinesigned;

sop_err
sop_inlinesigned_import (sop_ctx *sop,
                         const uint8_t* data, size_t len,
                         sop_inlinesigned **out);
/* if the inlinesigned object uses the Cleartext Signing framework,
 * the armor parameter is ignored.
 */
sop_err
sop_inlinesigned_export (const sop_inlinesigned *inlinesigned,
                         bool armor, sop_buf **out);
void
sop_inlinesigned_free (sop_inlinesigned *inlinesigned);


/* sop inline-sign */
sop_err
sop_op_sign_inline_execute (sop_op_sign *sign,
                            sop_inline_sign_as sign_as,
                            const uint8_t *msg,
                            size_t sz,
                            sop_inlinesigned **out);

/* sop inline-verify */
sop_err
sop_op_verify_inline_execute (sop_op_verify *verify,
                              const sop_inlinesigned *msg,
                              sop_verifications **verifications_out,
                              sop_buf **msg_out);

/* sop inline-detach */
sop_err
sop_inlinesigned_detach (const sop_inlinesigned *msg,
                         sop_sigs **sigs_out,
                         sop_buf **msg_out);

#endif // __SOP_H__
]]></sourcecode></figure>

<t>This proposed interface currently deals only with signing.
Encryption and decryption will be added in a future revision.</t>

<section anchor="design-choices-for-library-api"><name>Design Choices for Library API</name>

<t>The library is deliberately minimal, with data types and functionality corresponding to the SOP CLI.
The interface itself should expose no dependencies beyond libc.</t>

<t>All datatypes are opaque structs.
Library implementations <bcp14>MUST NOT</bcp14> expose library users to the memory layout of the underlying objects.</t>

<t>The library deals with data that is all in RAM, and produces data in RAM.
For simplicity, it does not currently expose a streaming interface.</t>

<t>It should be fairly straightforward to implement the SOP CLI on top of such a library.</t>

</section>
</section>
<section anchor="acknowledgements"><name>Acknowledgements</name>

<t>This work was inspired by Justus Winter's <xref target="OpenPGP-Interoperability-Test-Suite"/>.</t>

<t>The following people contributed helpful feedback and considerations to this draft, but are not responsible for its problems:</t>

<t><list style="symbols">
  <t>Allan Nordhøy</t>
  <t>Antoine Beaupré</t>
  <t>Edwin Taylor</t>
  <t>Heiko Schaefer</t>
  <t>Jameson Rollins</t>
  <t>Justus Winter</t>
  <t>Paul Schaub</t>
  <t>Vincent Breitmoser</t>
</list></t>

</section>
<section anchor="future-work"><name>Future Work</name>

<t><list style="symbols">
  <t>certificate transformation into popular publication forms:
  <list style="symbols">
      <t>WKD</t>
      <t>DANE OPENPGPKEY</t>
      <t>Autocrypt</t>
    </list></t>
  <t><spanx style="verb">sop encrypt</spanx> -- specify compression? (see <xref target="compression"/>)</t>
  <t><spanx style="verb">sop encrypt</spanx> -- specify padding policy/mechanism?</t>
  <t><spanx style="verb">sop decrypt</spanx> -- how can it more safely handle zip bombs?</t>
  <t><spanx style="verb">sop decrypt</spanx> -- what should it do when encountering weakly-encrypted (or unencrypted) input?</t>
  <t><spanx style="verb">sop encrypt</spanx> -- minimize metadata (e.g., <spanx style="verb">--throw-keyids</spanx>)?</t>
  <t>specify an error if a <spanx style="verb">DATE</spanx> arrives as input without a time zone?</t>
  <t>add considerations about what it means for armored <spanx style="verb">CERTS</spanx> to contain multiple certificates -- multiple armorings?  one big blob?</t>
  <t>do we need an interface or option (for performance?) with the semantics that <spanx style="verb">sop</spanx> doesn't validate certificates internally, it just accepts whatever's given as legit data? (see <xref target="cert-validity-performance"/>)</t>
  <t>do we need to be able to convert a message with a text-based signature to a CSF <spanx style="verb">INLINESIGNED</spanx> message? I'd rather not, given the additional complications.</t>
  <t>add encryption and decryption to C Library API</t>
</list></t>

</section>
<section anchor="document-history"><name>Document History</name>

<section anchor="substantive-changes-between-07-and-08"><name>Substantive Changes between -07 and -08:</name>

<t><list style="symbols">
  <t><spanx style="verb">revoke-key</spanx>, <spanx style="verb">change-key-password</spanx>: add <spanx style="verb">--no-armor</spanx> option</t>
  <t><spanx style="verb">generate-key</spanx>: should fail on non-UTF-8 <spanx style="verb">USERID</spanx></t>
  <t><spanx style="verb">generate-key</spanx>: acknowledge that implementations <bcp14>MAY</bcp14> reject <spanx style="verb">USERID</spanx>s that seem bad</t>
  <t><spanx style="verb">armor</spanx>: drop <spanx style="verb">--label</spanx> option</t>
  <t><spanx style="verb">encrypt</spanx>: add <spanx style="verb">--session-key-out</spanx> option</t>
  <t>ASCII-armored objects should not be concatenated</t>
  <t>signature verification should only work for sigtypes 0x00 (binary) and 0x01 (canonical text)</t>
  <t><spanx style="verb">sign</spanx>: Constrain input when <spanx style="verb">--micalg-out</spanx> is present for alignment with <xref target="RFC3156"/></t>
  <t>propose simple C API for signing and verification</t>
</list></t>

</section>
<section anchor="substantive-changes-between-06-and-07"><name>Substantive Changes between -06 and -07:</name>

<t><list style="symbols">
  <t><spanx style="verb">generate-key</spanx>: add <spanx style="verb">--signing-only</spanx> option</t>
  <t>new key management subcommand: <spanx style="verb">change-key-password</spanx></t>
  <t>new key management subcommand: <spanx style="verb">revoke-key</spanx></t>
</list></t>

</section>
<section anchor="substantive-changes-between-05-and-06"><name>Substantive Changes between -05 and -06:</name>

<t><list style="symbols">
  <t><spanx style="verb">version</spanx>: add <spanx style="verb">--sop-spec</spanx> argument</t>
  <t><spanx style="verb">encrypt</spanx>: add <spanx style="verb">--profile</spanx> argument</t>
</list></t>

</section>
<section anchor="substantive-changes-between-04-and-05"><name>Substantive Changes between -04 and -05:</name>

<t><list style="symbols">
  <t><spanx style="verb">decrypt</spanx>: change <spanx style="verb">--verify-out</spanx> to <spanx style="verb">--verifications-out</spanx></t>
  <t><spanx style="verb">encrypt</spanx>: add missing <spanx style="verb">--with-key-password</spanx></t>
  <t>add the concept of "profiles", use with <spanx style="verb">generate-key</spanx></t>
  <t>include table of known implementations</t>
  <t><spanx style="verb">VERIFICATIONS</spanx> can now indicate the type of the signature (<spanx style="verb">mode:text</spanx> or <spanx style="verb">mode:binary</spanx>)</t>
</list></t>

</section>
<section anchor="substantive-changes-between-03-and-04"><name>Substantive Changes between -03 and -04:</name>

<t><list style="symbols">
  <t>Reinforce that PASSWORD and SESSIONKEY are indirect data types</t>
  <t><spanx style="verb">encrypt</spanx>: remove <spanx style="verb">--as=mime</spanx> option</t>
  <t>Handle password-locked secret key material: add <spanx style="verb">--with-key-password</spanx> options to <spanx style="verb">generate-key</spanx>, <spanx style="verb">sign</spanx>, and <spanx style="verb">decrypt</spanx>.</t>
  <t>Introduce <spanx style="verb">INLINESIGNED</spanx> message type (<xref target="inlinesigned"/>)</t>
  <t>Rename <spanx style="verb">detach-inband-signature-and-message</spanx> to <spanx style="verb">inline-detach</spanx>, clarify its possible inputs</t>
  <t>Add <spanx style="verb">inline-verify</spanx></t>
  <t>Add <spanx style="verb">inline-sign</spanx></t>
</list></t>

</section>
<section anchor="substantive-changes-between-02-and-03"><name>Substantive Changes between -02 and -03:</name>

<t><list style="symbols">
  <t>Added <spanx style="verb">--micalg-out</spanx> parameter to <spanx style="verb">sign</spanx></t>
  <t>Change from <spanx style="verb">KEY</spanx> to <spanx style="verb">KEYS</spanx> (permit multiple secret keys in each blob)</t>
  <t>New error code: <spanx style="verb">KEY_CANNOT_SIGN</spanx></t>
  <t><spanx style="verb">version</spanx> now has <spanx style="verb">--backend</spanx> and <spanx style="verb">--extended</spanx> options</t>
</list></t>

</section>
<section anchor="substantive-changes-between-01-and-02"><name>Substantive Changes between -01 and -02:</name>

<t><list style="symbols">
  <t>Added mnemonics for return codes</t>
  <t><spanx style="verb">decrypt</spanx> should fail when asked to output to a pre-existing file</t>
  <t>Removed superfluous <spanx style="verb">--armor</spanx> option</t>
  <t>Much more specific about what <spanx style="verb">armor --label=auto</spanx> should do</t>
  <t><spanx style="verb">armor</spanx> and <spanx style="verb">dearmor</spanx> are now fully idempotent, but work only well-formed OpenPGP streams</t>
  <t>Dropped <spanx style="verb">armor --allow-nested</spanx></t>
  <t>Specified what <spanx style="verb">encrypt --as=</spanx> means</t>
  <t>New error code: <spanx style="verb">KEY_IS_PROTECTED</spanx></t>
  <t>Documented expectations around human-readable, human-transferable passwords</t>
  <t>New subcommand: <spanx style="verb">detach-inband-signature-and-message</spanx></t>
  <t>More specific guidance about special designators like <spanx style="verb">@FD:</spanx> and <spanx style="verb">@ENV:</spanx>, including new error codes <spanx style="verb">UNSUPPORTED_SPECIAL_PREFIX</spanx> and <spanx style="verb">AMBIGUOUS_INPUT</spanx></t>
</list></t>

</section>
<section anchor="substantive-changes-between-00-and-01"><name>Substantive Changes between -00 and -01:</name>

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

</section>
</section>


  </back>

<!-- ##markdown-source:
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
01mbVvhtlCRZG+tBJdP/WJPfh+aEYpue3n6VZdPxMtpuzPRbPftdOX6OJG7L
vd3JViu1lZxvmxP8/lgxpV/JhiPsxn/yz6uwdCcX/heUWUJ9xEbHaYGzEk5h
ZsZdpbW13Q5UTmqWFes2/NPbUFWQJ7h3lSc3Fl/sUxyST0Zh52hG1j/8O2pB
OYv8Ny8JFTbM8V9aFIqhc3feFqUnLZXwDuvaYCkl0Pvc5VTEJCO2oRrpIaAN
zVmrb9XUbh96xIgPHybFZSePi3eFCWtUb5JVgkTsqq5sDZer4wp7hIBtvnzd
lw5yw39p5RoPkn+XiJD/ggI23rr/fx2bP6+OzZ0b21TOxnvp/15VG1cMqF7k
u2vcCH8zQpKJ2X1i36g+01Dppn9Yj+D9NizQsfFtb+9JrS2Qp7B2P6V+DhcT
pcj9WiXMu8pgmrYubvs13XqKPdWx9wNtpUgUUlpL4kd8zCn8lmImJ7d8ngGn
L/FzW1vZxTcRdVxEkY8G2McyeRj9H7xk9gdkiBo9WqmOnmsSqGqNFzfd+pRt
G/KlaVZueCHHfHnSVqNAZniYmYXugNOMkrZkOkVaTDTL1qATT7TcDuEvomA5
1dF5t7SX+zV2bRtHCQZa5dkcpsT2620bd4lP+CazolIYXJrPIQnTHA7qcee/
BTi3j9uKmXdPQBLiMrSd76LlVltCjhw5zW0Kgzk4Urlca8XSOrilSQ/XCbpF
iOVpR2sK8KPCztM/helPF2O4mp86vaig95q/UlDWTr9rp0f62TeO8qE40REo
whd4+BFulSawrXn+UxbhRCLfZyVCWOwCHgNMJ0DysDuBFY7uD0LN0Pa7oNjD
nVk7ubhLRHwP/XqyPCf5MRvBQaI4uGwY1ZhZyCZTdTkVbudAf9kN069fsrUz
bAk0seMIQQYnkGWua7UK0WqA/ug5+B4af5dMhUzub8ncWJrUFljiURquyFsk
xIgwIJRrVXePYYyvuk+GYobzW/YKsbO5rm4D37ZGGVCFWWnuMo1m7AxGuodv
dWwjXZLT0AHk5E1wMU0/FxGuNbA6YizUnEfkP1w/jYhGWSedyN80GMphbWhU
G/ztTX+f69hisFDmp2lTAtPB8GiF4fprYMo5qCmS4Ujk93WEqhJMAfQ7W5Bn
t9PhVdzEWRJqNsQkCeOZ2KF0TabbkFd4taDz8BvlmhQoahLKiKCtarDXm7fK
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
AA==

-->

</rfc>

