<?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.0.3) -->


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

]>


<rfc ipr="trust200902" docName="draft-dkg-openpgp-stateless-cli-04" 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="2022" month="May" day="15"/>

    <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/"/>.
      </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>
<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-05"/>) 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="version"><name>version: Version Information</name>

<figure><artwork><![CDATA[
sop version [--backend|--extended]
]]></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><spanx style="verb">--backend</spanx> and <spanx style="verb">--extended</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
$ 
]]></artwork></figure>

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

<figure><artwork><![CDATA[
sop generate-key [--no-armor]
    [--with-key-password=PASSWORD]
    [--] [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>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>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="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 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>.</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 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...]
    [--] [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).
<spanx style="verb">PASSWORD</spanx> is 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><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> 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>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 <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...]
    [--verify-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-05"/>) 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">--verify-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">--verify-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>
<section anchor="armor-convert-binary-to-ascii"><name>armor: Convert Binary to ASCII</name>

<figure><artwork><![CDATA[
sop armor [--label={auto|sig|key|cert|message}]
]]></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>The user can choose to specify the label used in the header and tail of the armoring.</t>

<t>The default for <spanx style="verb">--label</spanx> is <spanx style="verb">auto</spanx>, in which case, <spanx style="verb">sop</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 the expected sequence of packet types, <spanx style="verb">sop armor</spanx> fails with <spanx style="verb">BAD_DATA</spanx>.</t>

<t>Note that <spanx style="verb">--label=message</spanx> may be used for either <spanx style="verb">INLINESIGNED</spanx> or <spanx style="verb">CIPHERTEXT</spanx> inputs.</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 the 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 armor < bob.bin > bob.pgp
$ head -n1 bob.pgp
-----BEGIN PGP PUBLIC KEY BLOCK-----
$
]]></artwork></figure>

</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 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="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>

</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="11.1" sectionFormat="of" target="I-D.ietf-openpgp-crypto-refresh-05"/>), 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="11.2" sectionFormat="of" target="I-D.ietf-openpgp-crypto-refresh-05"/>).
May be armored (see <xref target="optional-input-armoring"/>).</t>

<t>By default, secret key material is expected to be in cleartext (that is, not locked with a password).
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>.</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="11.3" sectionFormat="of" target="I-D.ietf-openpgp-crypto-refresh-05"/>).</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-05"/>) and SKESKs (<xref section="5.3" sectionFormat="of" target="I-D.ietf-openpgp-crypto-refresh-05"/>),
followed by one SEIPD (<xref section="5.14" sectionFormat="of" target="I-D.ietf-openpgp-crypto-refresh-05"/>).</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="11.3" sectionFormat="of" target="I-D.ietf-openpgp-crypto-refresh-05"/></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-05"/></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-05"/>) 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>

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

<t>This output 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 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>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, 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>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 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>
<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>
      <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> 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>
</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="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>
</list></t>

<t>For robustness, <spanx style="verb">sop</spanx> <bcp14>SHOULD</bcp14> be willing to ignore whitespace after the Armor Tail.</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>, 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> 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> 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 (requiring <spanx style="verb">UTF-8</spanx>, trimming trailing whitespace).
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:
 - the data being signed is in fact textual, and encoded in <spanx style="verb">UTF-8</spanx>, and
 - 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>

<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 --verify-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 (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>
</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-05"/>)).
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' target='https://www.rfc-editor.org/info/rfc2119'>
<front>
<title>Key words for use in RFCs to Indicate Requirement Levels</title>
<author fullname='S. Bradner' initials='S.' surname='Bradner'><organization/></author>
<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' target='https://www.rfc-editor.org/info/rfc8174'>
<front>
<title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
<author fullname='B. Leiba' initials='B.' surname='Leiba'><organization/></author>
<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' target='https://www.rfc-editor.org/info/rfc4880'>
<front>
<title>OpenPGP Message Format</title>
<author fullname='J. Callas' initials='J.' surname='Callas'><organization/></author>
<author fullname='L. Donnerhacke' initials='L.' surname='Donnerhacke'><organization/></author>
<author fullname='H. Finney' initials='H.' surname='Finney'><organization/></author>
<author fullname='D. Shaw' initials='D.' surname='Shaw'><organization/></author>
<author fullname='R. Thayer' initials='R.' surname='Thayer'><organization/></author>
<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-05'>
   <front>
      <title>OpenPGP Message Format</title>
      <author fullname='Werner Koch' initials='W.' surname='Koch'>
         <organization>GnuPG e.V.</organization>
      </author>
      <author fullname='Paul Wouters' initials='P.' surname='Wouters'>
         <organization>Aiven</organization>
      </author>
      <date day='7' month='March' year='2022'/>
      <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-05'/>
   <format target='https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-05.txt' type='TXT'/>
</reference>



<reference anchor='RFC3156' target='https://www.rfc-editor.org/info/rfc3156'>
<front>
<title>MIME Security with OpenPGP</title>
<author fullname='M. Elkins' initials='M.' surname='Elkins'><organization/></author>
<author fullname='D. Del Torto' initials='D.' surname='Del Torto'><organization/></author>
<author fullname='R. Levien' initials='R.' surname='Levien'><organization/></author>
<author fullname='T. Roessler' initials='T.' surname='Roessler'><organization/></author>
<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' target='https://www.rfc-editor.org/info/rfc3629'>
<front>
<title>UTF-8, a transformation format of ISO 10646</title>
<author fullname='F. Yergeau' initials='F.' surname='Yergeau'><organization/></author>
<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='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'/>
   <format target='https://www.ietf.org/archive/id/draft-bre-openpgp-samples-01.txt' type='TXT'/>
</reference>


<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='RFC0959' target='https://www.rfc-editor.org/info/rfc959'>
<front>
<title>File Transfer Protocol</title>
<author fullname='J. Postel' initials='J.' surname='Postel'><organization/></author>
<author fullname='J. Reynolds' initials='J.' surname='Reynolds'><organization/></author>
<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' target='https://www.rfc-editor.org/info/rfc5321'>
<front>
<title>Simple Mail Transfer Protocol</title>
<author fullname='J. Klensin' initials='J.' surname='Klensin'><organization/></author>
<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 &quot;mail submission&quot; protocol for &quot;split-UA&quot; (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="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>
</list></t>

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

<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">sign</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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

-->

</rfc>

