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


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

]>


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

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

    <date year="2023" month="July" day="10"/>

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

    <abstract>


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



    </abstract>

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


  </front>

  <middle>


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

<t>Example:</t>

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

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

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

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

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

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

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

<t>Example:</t>

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

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

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

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

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

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

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

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

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

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

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

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

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

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

<t>Example:</t>

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

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

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

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

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

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

<t>Example:</t>

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

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

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

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

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

<t>Example:</t>

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

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

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

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

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

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

<t>Example:</t>

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

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

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

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

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

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

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

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

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

<t>When generating PGP/MIME messages (<xref target="RFC3156"/>), it is useful to know what digest algorithm was used for the generated signature.
When <spanx style="verb">--micalg-out</spanx> is supplied, <spanx style="verb">sop sign</spanx> emits the digest algorithm used to the specified <spanx style="verb">MICALG</spanx> file in a way that can be used to populate the <spanx style="verb">micalg</spanx> parameter for the Content-Type (see <xref target="micalg"/>).
If the specified <spanx style="verb">MICALG</spanx> file already exists in the filesystem, <spanx style="verb">sop sign</spanx> will fail with <spanx style="verb">OUTPUT_EXISTS</spanx>.</t>

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

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

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

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

<t>Example:</t>

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

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

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

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

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

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

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

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

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

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

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

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

<t>Example:</t>

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

<t>Example:</t>

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

<t>Example:</t>

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

<t>Example:</t>

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

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

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

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

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

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

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

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

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

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

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

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

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

<t>Example:</t>

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

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

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

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

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

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

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

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

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

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

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

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

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

<t>Example:</t>

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

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

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

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

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

<figure><artwork><![CDATA[
sop armor [--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 signatures block) and Literal Data packet (from the message body).</t>
  <t>Raise a specific error.</t>
</list></t>

<t>Example:</t>

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

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

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

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

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

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

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

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

<t>Example:</t>

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

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

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

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

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

<t>Examples:</t>

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

<t>Example:</t>

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

<t><list style="symbols">
  <t>An unknown Armor Header Line</t>
  <t>Any text before the Armor Header Line</t>
  <t>Malformed lines in the Armor Headers section</t>
  <t>Any non-whitespace data after the Armor Tail</t>
  <t>Any Radix-64 encoded line with more than 76 characters</t>
  <t>Invalid characters in the Radix-64-encoded data</t>
  <t>An invalid Armor Checksum</t>
  <t>A mismatch between the Armor Header Line and the Armor Tail</t>
</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>, <spanx style="verb">INLINESIGNED</spanx>, or <spanx style="verb">CIPHERTEXT</spanx>), <spanx style="verb">sop</spanx> <bcp14>SHOULD</bcp14> also reject any input that does not conform to the expected packet stream.
See <xref target="indirect-types"/> for the expected packet stream for different types.</t>

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

<t>When <spanx style="verb">sop</spanx> checks a signature (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-10"/>)).
FIXME: document things like PURBs and <spanx style="verb">--hidden-recipient</spanx>)</t>

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

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

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

</section>
</section>


  </middle>

  <back>


    <references title='Normative References'>



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

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

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


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

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

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

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

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

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




    </references>

    <references title='Informative References'>

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



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

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

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

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




    </references>


<section anchor="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-06-and-07"><name>Substantive Changes between -06 and -07:</name>

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

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

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

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

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

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

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

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

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

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

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

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

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

</section>
</section>


  </back>

<!-- ##markdown-source:
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
AvHm/wENq1onbS8BAA==

-->

</rfc>

