< draft-dkg-openpgp-stateless-cli-01.txt   draft-dkg-openpgp-stateless-cli-02.txt >
openpgp D. Gillmor openpgp D.K. Gillmor
Internet-Draft ACLU Internet-Draft ACLU
Intended status: Informational October 29, 2019 Intended status: Informational 6 March 2020
Expires: May 1, 2020 Expires: 7 September 2020
Stateless OpenPGP Command Line Interface Stateless OpenPGP Command Line Interface
draft-dkg-openpgp-stateless-cli-01 draft-dkg-openpgp-stateless-cli-02
Abstract Abstract
This document defines a generic stateless command-line interface for This document defines a generic stateless command-line interface for
dealing with OpenPGP messages, known as "sop". It aims for a dealing with OpenPGP messages, known as "sop". It aims for a
minimal, well-structured API covering OpenPGP object security. minimal, well-structured API covering OpenPGP object security.
Status of This Memo Status of This Memo
This Internet-Draft is submitted in full conformance with the This Internet-Draft is submitted in full conformance with the
skipping to change at page 1, line 32 skipping to change at page 1, line 32
Internet-Drafts are working documents of the Internet Engineering Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet- working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/. Drafts is at https://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress." material or to cite them other than as "work in progress."
This Internet-Draft will expire on May 1, 2020. This Internet-Draft will expire on 7 September 2020.
Copyright Notice Copyright Notice
Copyright (c) 2019 IETF Trust and the persons identified as the Copyright (c) 2020 IETF Trust and the persons identified as the
document authors. All rights reserved. document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents Provisions Relating to IETF Documents (https://trustee.ietf.org/
(https://trustee.ietf.org/license-info) in effect on the date of license-info) in effect on the date of publication of this document.
publication of this document. Please review these documents Please review these documents carefully, as they describe your rights
carefully, as they describe your rights and restrictions with respect and restrictions with respect to this document. Code Components
to this document. Code Components extracted from this document must extracted from this document must include Simplified BSD License text
include Simplified BSD License text as described in Section 4.e of as described in Section 4.e of the Trust Legal Provisions and are
the Trust Legal Provisions and are provided without warranty as provided without warranty as described in the Simplified BSD License.
described in the Simplified BSD License.
Table of Contents Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1. Requirements Language . . . . . . . . . . . . . . . . . . 3 1.1. Requirements Language . . . . . . . . . . . . . . . . . . 4
1.2. Terminology . . . . . . . . . . . . . . . . . . . . . . . 4 1.2. Terminology . . . . . . . . . . . . . . . . . . . . . . . 4
1.3. Using sop in a Test Suite . . . . . . . . . . . . . . . . 4
2. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . 4 2. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . 4
3. Subcommands . . . . . . . . . . . . . . . . . . . . . . . . . 4 3. Subcommands . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.1. version: Version Information . . . . . . . . . . . . . . 5 3.1. version: Version Information . . . . . . . . . . . . . . 5
3.2. generate-key: Generate a Secret Key . . . . . . . . . . . 5 3.2. generate-key: Generate a Secret Key . . . . . . . . . . . 6
3.3. extract-cert: Extract a Certificate from a Secret Key . . 5 3.3. extract-cert: Extract a Certificate from a Secret Key . . 6
3.4. sign: Create a Detached Signature . . . . . . . . . . . . 6 3.4. sign: Create Detached Signatures . . . . . . . . . . . . 7
3.5. verify: Verify a Detached Signature . . . . . . . . . . . 6 3.5. verify: Verify Detached Signatures . . . . . . . . . . . 7
3.6. encrypt: Encrypt a Message . . . . . . . . . . . . . . . 7 3.6. encrypt: Encrypt a Message . . . . . . . . . . . . . . . 8
3.7. decrypt: Decrypt a Message . . . . . . . . . . . . . . . 8 3.7. decrypt: Decrypt a Message . . . . . . . . . . . . . . . 10
3.8. armor: Add ASCII Armor . . . . . . . . . . . . . . . . . 10 3.8. armor: Convert binary to ASCII . . . . . . . . . . . . . 12
3.9. dearmor: Remove ASCII Armor . . . . . . . . . . . . . . . 11 3.9. dearmor: Convert ASCII to binary . . . . . . . . . . . . 13
4. Input String Types . . . . . . . . . . . . . . . . . . . . . 11 3.10. detach-inband-signature-and-message: split a clearsigned
4.1. DATE . . . . . . . . . . . . . . . . . . . . . . . . . . 11 message . . . . . . . . . . . . . . . . . . . . . . . . 13
4.2. USERID . . . . . . . . . . . . . . . . . . . . . . . . . 12 4. Input String Types . . . . . . . . . . . . . . . . . . . . . 14
5. Input/Output Indirect Types . . . . . . . . . . . . . . . . . 12 4.1. DATE . . . . . . . . . . . . . . . . . . . . . . . . . . 15
5.1. CERTS . . . . . . . . . . . . . . . . . . . . . . . . . . 12 4.2. USERID . . . . . . . . . . . . . . . . . . . . . . . . . 15
5.2. KEY . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 5. Input/Output Indirect Types . . . . . . . . . . . . . . . . . 15
5.3. CIPHERTEXT . . . . . . . . . . . . . . . . . . . . . . . 13 5.1. Special Designators for Indirect Types . . . . . . . . . 16
5.4. SIGNATURE . . . . . . . . . . . . . . . . . . . . . . . . 13 5.2. CERTS . . . . . . . . . . . . . . . . . . . . . . . . . . 16
5.5. SESSIONKEY . . . . . . . . . . . . . . . . . . . . . . . 13 5.3. KEY . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
5.6. PASSWORD . . . . . . . . . . . . . . . . . . . . . . . . 14 5.4. CIPHERTEXT . . . . . . . . . . . . . . . . . . . . . . . 16
5.7. VERIFICATIONS . . . . . . . . . . . . . . . . . . . . . . 14 5.5. SIGNATURES . . . . . . . . . . . . . . . . . . . . . . . 17
5.8. DATA . . . . . . . . . . . . . . . . . . . . . . . . . . 14 5.6. SESSIONKEY . . . . . . . . . . . . . . . . . . . . . . . 17
6. Failure modes . . . . . . . . . . . . . . . . . . . . . . . . 14 5.7. PASSWORD . . . . . . . . . . . . . . . . . . . . . . . . 18
7. Guidance for Implementors . . . . . . . . . . . . . . . . . . 15 5.8. VERIFICATIONS . . . . . . . . . . . . . . . . . . . . . . 18
7.1. One OpenPGP Message At a Time . . . . . . . . . . . . . . 15 5.9. DATA . . . . . . . . . . . . . . . . . . . . . . . . . . 18
7.2. Simplified Subset of OpenPGP Message . . . . . . . . . . 16 6. Failure Modes . . . . . . . . . . . . . . . . . . . . . . . . 19
7.3. Validate Signatures Only From Known Signers . . . . . . . 16 7. Guidance for Implementers . . . . . . . . . . . . . . . . . . 20
7.4. Detached Signatures . . . . . . . . . . . . . . . . . . . 16 7.1. One OpenPGP Message at a Time . . . . . . . . . . . . . . 21
7.5. Reliance on Supplied Certs and Keys . . . . . . . . . . . 16 7.2. Simplified Subset of OpenPGP Message . . . . . . . . . . 21
8. Guidance for Consumers . . . . . . . . . . . . . . . . . . . 16 7.3. Validate Signatures Only from Known Signers . . . . . . . 21
9. Security Considerations . . . . . . . . . . . . . . . . . . . 17 7.4. OpenPGP inputs can be either Binary or ASCII-armored . . 21
9.1. Signature Verification . . . . . . . . . . . . . . . . . 17 7.5. Detached Signatures . . . . . . . . . . . . . . . . . . . 22
9.2. Compression . . . . . . . . . . . . . . . . . . . . . . . 18 7.6. Reliance on Supplied Certs and Keys . . . . . . . . . . . 23
10. Privacy Considerations . . . . . . . . . . . . . . . . . . . 18 7.7. Text is always UTF-8 . . . . . . . . . . . . . . . . . . 23
10.1. Object Security vs. Transport Security . . . . . . . . . 18 7.8. Passwords are Human-Readable . . . . . . . . . . . . . . 24
11. Document Considerations . . . . . . . . . . . . . . . . . . . 18 7.9. Be careful with Special Designators . . . . . . . . . . . 25
11.1. Document History . . . . . . . . . . . . . . . . . . . . 19 8. Guidance for Consumers . . . . . . . . . . . . . . . . . . . 25
11.2. Future Work . . . . . . . . . . . . . . . . . . . . . . 19 8.1. Choosing between -as=text and -as=binary . . . . . . . . 26
12. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 20 8.2. Special Designators and Unusual Filenames . . . . . . . . 26
13. References . . . . . . . . . . . . . . . . . . . . . . . . . 20 9. Security Considerations . . . . . . . . . . . . . . . . . . . 27
13.1. Normative References . . . . . . . . . . . . . . . . . . 21 9.1. Signature Verification . . . . . . . . . . . . . . . . . 27
13.2. Informative References . . . . . . . . . . . . . . . . . 21 9.2. Compression . . . . . . . . . . . . . . . . . . . . . . . 28
10. Privacy Considerations . . . . . . . . . . . . . . . . . . . 28
Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 21 10.1. Object Security vs. Transport Security . . . . . . . . . 28
11. Document Considerations . . . . . . . . . . . . . . . . . . . 28
11.1. Document History . . . . . . . . . . . . . . . . . . . . 29
11.2. Future Work . . . . . . . . . . . . . . . . . . . . . . 30
12. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 31
13. References . . . . . . . . . . . . . . . . . . . . . . . . . 31
13.1. Normative References . . . . . . . . . . . . . . . . . . 31
13.2. Informative References . . . . . . . . . . . . . . . . . 32
Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 33
1. Introduction 1. Introduction
Different OpenPGP implementations have many different requirements, Different OpenPGP implementations have many different requirements,
which typically break down in two main categories: key/certificate which typically break down in two main categories: key/certificate
management and object security. management and object security.
The purpose of this document is to provide a "stateless" interface The purpose of this document is to provide a "stateless" interface
that primarily handles the object security side of things, and that primarily handles the object security side of things, and
assumes that secret key management and certificate management will be assumes that secret key management and certificate management will be
handled some other way. handled some other way.
This separation should make it easier to provide interoperability Isolating object security from key/certificate management should make
testing for the object security work, and to allow implementations to it easier to provide interoperability testing for the object security
consume and produce new cryptographic primitives as needed. side of OpenPGP implementations, as described in Section 1.3.
This document defines a generic stateless command-line interface for This document defines a generic stateless command-line interface for
dealing with OpenPGP messages, known here by the placeholder "sop". dealing with OpenPGP messages, known here by the placeholder "sop".
It aims for a minimal, well-structured API. It aims for a minimal, well-structured API.
An OpenPGP implementation should not name its executable "sop" to An OpenPGP implementation should not name its executable "sop" to
implement this specification, of course. It just needs to provide a implement this specification. It just needs to provide a program
binary that conforms to this interface. that conforms to this interface.
A "sop" implementation should leave no trace on the system, and its A "sop" implementation should leave no trace on the system, and its
behavior should not be affected by anything other than command-line behavior should not be affected by anything other than command-line
arguments and input. arguments and input.
Obviously, the user will need to manage their secret keys (and their Obviously, the user will need to manage their secret keys (and their
peers' certificates) somehow, but the goal of this interface is to peers' certificates) somehow, but the goal of this interface is to
separate out that task from the task of interacting with OpenPGP separate out that task from the task of interacting with OpenPGP
messages. messages.
skipping to change at page 4, line 25 skipping to change at page 4, line 33
certificates and secret keys themselves, and passing them to "sop" as certificates and secret keys themselves, and passing them to "sop" as
needed. The user should also not be concerned that any state could needed. The user should also not be concerned that any state could
affect the underlying operations. affect the underlying operations.
OpenPGP revocations can have "Reason for Revocation" (section OpenPGP revocations can have "Reason for Revocation" (section
5.2.3.23 of [RFC4880]), which can be either "soft" or "hard". The 5.2.3.23 of [RFC4880]), which can be either "soft" or "hard". The
set of "soft" reasons is: "Key is superseded" and "Key is retired and set of "soft" reasons is: "Key is superseded" and "Key is retired and
no longer used". All other reasons (and revocations that do not no longer used". All other reasons (and revocations that do not
state a reason) are "hard" revocations. state a reason) are "hard" revocations.
1.3. Using sop in a Test Suite
If an OpenPGP implementation provdids a "sop" interface, it can be
used to test interoperability (e.g.,
[OpenPGP-Interoperability-Test-Suite]).
Such an interop test suite can, for example, use custom code (_not_
"sop") to generate a new OpenPGP object that incorporates new
primitives, and feed that object to a stable of "sop"
implementations, to determine whether those implementations can
consume the new form.
Or, the test suite can drive each "sop" implementation with a simple
input, and observe which cryptographic primitives each implementation
chooses to use as it produces output.
2. Examples 2. Examples
These examples show no error checking, but give a flavor of how "sop" These examples show no error checking, but give a flavor of how "sop"
might be used in practice from a shell. might be used in practice from a shell.
The key and certificate files described in them (e.g. "alice.sec") The key and certificate files described in them (e.g. "alice.sec")
could be for example those found in could be for example those found in
[I-D.draft-bre-openpgp-samples-00]. [I-D.draft-bre-openpgp-samples-00].
sop generate-key "Alice Lovelace <alice@openpgp.example>" > alice.sec sop generate-key "Alice Lovelace <alice@openpgp.example>" > alice.sec
sop extract-cert < alice.sec > alice.pgp sop extract-cert < alice.sec > alice.pgp
sop sign --as=text alice.sec < announcement.txt > announcement.txt.asc sop sign --as=text alice.sec < statement.txt > statement.txt.asc
sop verify announcement.txt.asc alice.pgp < announcement.txt sop verify announcement.txt.asc alice.pgp < announcement.txt
sop encrypt --sign-with=alice.sec --as=mime bob.pgp < msg.eml > encrypted.asc sop encrypt --sign-with=alice.sec --as=mime bob.pgp < msg.eml > encrypted.asc
sop decrypt alice.sec < ciphertext.asc > cleartext.out sop decrypt alice.sec < ciphertext.asc > cleartext.out
See Section 6 for more information about errors and error handling.
3. Subcommands 3. Subcommands
"sop" uses a subcommand interface, similar to those popularized by "sop" uses a subcommand interface, similar to those popularized by
systems like "git" and "svn". systems like "git" and "svn".
If the user supplies a subcommand that "sop" does not implement, it If the user supplies a subcommand that "sop" does not implement, it
fails with a return code of 69. If a "sop" implementation does not fails with "UNSUPPORTED_SUBCOMMAND". If a "sop" implementation does
handle a supplied option for a given subcommand, it fails with a not handle a supplied option for a given subcommand, it fails with
return code of 37. "UNSUPPORTED_OPTION".
For all commands that have an "--armor|--no-armor" option, it All subcommands that produce OpenPGP material on standard output
defaults to "--armor", meaning that any output OpenPGP material produce ASCII-armored (section 6 of [I-D.ietf-openpgp-rfc4880bis])
should be ASCII-armored (section 6 of [I-D.ietf-openpgp-rfc4880bis]) objects by default (except for "sop dearmor"). These subcommands
by default. have a "--no-armor" option, which causes them to produce binary
OpenPGP material instead.
All subcommands that accept OpenPGP material on input should be able
to accept either ASCII-armored or binary inputs (see Section 7.4) and
behave accordingly.
See Section 5 for details about how various forms of OpenPGP material
are expected to be structured.
3.1. version: Version Information 3.1. version: Version Information
sop version sop version
o Standard Input: ignored * Standard Input: ignored
o Standard Output: version string * Standard Output: version string
The version string emitted should contain the name of the "sop" The version string emitted should contain the name of the "sop"
implementation, followed by a single space, followed by the version implementation, followed by a single space, followed by the version
number. number. A "sop" implementation should use a version number that
respects an established standard that is easily comparable and
parsable, like [SEMVER].
Example: Example:
$ sop version $ sop version
ExampleSop 0.2.1 ExampleSop 0.2.1
$ $
3.2. generate-key: Generate a Secret Key 3.2. generate-key: Generate a Secret Key
sop generate-key [--armor|--no-armor] [--] [USERID...] sop generate-key [--no-armor] [--] [USERID...]
o Standard Input: ignored * Standard Input: ignored
o Standard Output: "KEY" (Section 5.2) * Standard Output: "KEY" (Section 5.3)
Generate a single default OpenPGP certificate with zero or more User Generate a single default OpenPGP key with zero or more User IDs.
IDs.
The generated secret key SHOULD be usable for as much of the "sop"
functionality as possible. In particular:
* It should be possible to extract an OpenPGP certificate from the
"KEY" with "sop extract-cert".
* The "KEY" should be able to create signatures (with "sop sign")
that are verifiable by using "sop verify" with the extracted
certificate.
* The "KEY" should be able to decrypt messages (with "sop decrypt")
that are encrypted by using "sop encrypt" with the extracted
certificate.
The detailed internal structure of the certificate is left to the
discretion of the "sop" implementation.
Example: Example:
$ sop generate-key 'Alice Lovelace <alice@openpgp.example>' > alice.sec $ sop generate-key 'Alice Lovelace <alice@openpgp.example>' > alice.sec
$ head -n1 < alice.sec $ head -n1 < alice.sec
-----BEGIN PGP PRIVATE KEY BLOCK----- -----BEGIN PGP PRIVATE KEY BLOCK-----
$ $
3.3. extract-cert: Extract a Certificate from a Secret Key 3.3. extract-cert: Extract a Certificate from a Secret Key
sop extract-cert [--armor|--no-armor] sop extract-cert [--no-armor]
* Standard Input: "KEY" (Section 5.3)
o Standard Input: "KEY" (Section 5.2) * Standard Output: "CERTS" (Section 5.2)
o Standard Output: "CERTS" (Section 5.1)
Note that the resultant "CERTS" object will only ever contain one Note that the resultant "CERTS" object will only ever contain one
OpenPGP certificate. OpenPGP certificate, since "KEY" contains exactly one OpenPGP
Transferable Secret Key.
Example: Example:
$ sop extract-cert < alice.sec > alice.pgp $ sop extract-cert < alice.sec > alice.pgp
$ head -n1 < alice.pgp $ head -n1 < alice.pgp
-----BEGIN PGP PUBLIC KEY BLOCK----- -----BEGIN PGP PUBLIC KEY BLOCK-----
$ $
3.4. sign: Create a Detached Signature 3.4. sign: Create Detached Signatures
sop sign [--armor|--no-armor] sop sign [--no-armor]
[--as={binary|text}] [--] KEY [KEY...] [--as={binary|text}] [--] KEY [KEY...]
o Standard Input: "DATA" (Section 5.8) * Standard Input: "DATA" (Section 5.9)
o Standard Output: "SIGNATURE" (Section 5.4) * Standard Output: "SIGNATURES" (Section 5.5)
Exactly one signature will be made by each supplied "KEY".
"--as" defaults to "binary". If "--as=text" and the input "DATA" is "--as" defaults to "binary". If "--as=text" and the input "DATA" is
not valid "UTF-8", "sop sign" fails with a return code of 53. not valid "UTF-8" (Section 7.7), "sop sign" fails with
"EXPECTED_TEXT".
"--as=binary" SHOULD result in an OpenPGP signature of type 0x00
("Signature of a binary document"). "--as=text" SHOULD result in an
OpenPGP signature of type 0x01 ("Signature of a canonical text
document"). See section 5.2.1 of [RFC4880] for more details.
"sop sign" MUST NOT produce any extra signatures beyond those from
"KEY" objects supplied on the command line.
Example: Example:
$ sop sign --as=text alice.sec < message.txt > message.txt.asc $ sop sign --as=text alice.sec < message.txt > message.txt.asc
$ head -n1 < message.txt.asc $ head -n1 < message.txt.asc
-----BEGIN PGP SIGNATURE----- -----BEGIN PGP SIGNATURE-----
$ $
3.5. verify: Verify a Detached Signature 3.5. verify: Verify Detached Signatures
sop verify [--not-before=DATE] [--not-after=DATE] sop verify [--not-before=DATE] [--not-after=DATE]
[--] SIGNATURE CERTS [CERTS...] [--] SIGNATURES CERTS [CERTS...]
o Standard Input: "DATA" (Section 5.8) * Standard Input: "DATA" (Section 5.9)
o Standard Output: "VERIFICATIONS" (Section 5.7) * Standard Output: "VERIFICATIONS" (Section 5.8)
"--not-before" and "--not-after" indicate that signatures with dates "--not-before" and "--not-after" indicate that signatures with dates
outside certain range MUST NOT be considered valid. outside certain range MUST NOT be considered valid.
"--not-before" defaults to the beginning of time. Accepts the "--not-before" defaults to the beginning of time. Accepts the
special value "-" to indicate the beginning of time (i.e. no lower special value "-" to indicate the beginning of time (i.e. no lower
boundary). boundary).
"--not-after" defaults to the current system time ("now"). Accepts "--not-after" defaults to the current system time ("now"). Accepts
the special value "-" to indicate the end of time (i.e. no upper the special value "-" to indicate the end of time (i.e. no upper
boundary). boundary).
"sop verify" only returns 0 if at least one certificate included in "sop verify" only returns "OK" if at least one certificate included
any "CERTS" object made a valid signature in the range over the in any "CERTS" object made a valid signature in the range over the
"DATA" supplied. "DATA" supplied.
For details about the valid signatures, the user MUST inspect the For details about the valid signatures, the user MUST inspect the
"VERIFICATIONS" output. "VERIFICATIONS" output.
If no "CERTS" are supplied, "sop verify" fails with a return code of If no "CERTS" are supplied, "sop verify" fails with "MISSING_ARG".
19.
If no valid signatures are found, "sop verify" fails with a return If no valid signatures are found, "sop verify" fails with
code of 3. "NO_SIGNATURE".
See Section 9.1 for more details about signature verification. See Section 9.1 for more details about signature verification.
Example: Example:
(In this example, we see signature verification succeed first, and (In this example, we see signature verification succeed first, and
then fail on a modified version of the message.) then fail on a modified version of the message.)
$ sop verify message.txt.asc alice.pgp < message.txt $ sop verify message.txt.asc alice.pgp < message.txt
2019-10-29T18:36:45Z EB85BB5FA33A75E15E944E63F231550C4F47E38E EB85BB5FA33A75E15E944E63F231550C4F47E38E signed by alice.pgp 2019-10-29T18:36:45Z EB85BB5FA33A75E15E944E63F231550C4F47E38E EB85BB5FA33A75E15E944E63F231550C4F47E38E signed by alice.pgp
$ echo $? $ echo $?
0 0
$ tr a-z A-Z < message.txt | sop verify message.txt.asc alice.pgp $ tr a-z A-Z < message.txt | sop verify message.txt.asc alice.pgp
$ echo $? $ echo $?
3 3
$ $
3.6. encrypt: Encrypt a Message 3.6. encrypt: Encrypt a Message
sop encrypt [--as={binary|text|mime}] sop encrypt [--as={binary|text|mime}]
[--armor|--no-armor] [--no-armor]
[--with-password=PASSWORD...] [--with-password=PASSWORD...]
[--sign-with=KEY...] [--sign-with=KEY...]
[--] [CERTS...] [--] [CERTS...]
o Standard Input: "DATA" (Section 5.8) * Standard Input: "DATA" (Section 5.9)
o Standard Output: "CIPHERTEXT" (Section 5.3) * Standard Output: "CIPHERTEXT" (Section 5.4)
"--as" defaults to "binary". "--as" defaults to "binary". The setting of "--as" corresponds to
the one octet format field found in the Literal Data packet at the
core of the output "CIPHERTEXT". If "--as" is set to "binary", the
octet is "b" ("0x62"). If it is "text", the format octet is "u"
("0x75"). If it is "mime", the format octet is "m" ("0x6d").
"--with-password" enables symmetric encryption (and can be used "--with-password" enables symmetric encryption (and can be used
multiple times if multiple passwords are desired). If "sop encrypt" multiple times if multiple passwords are desired). If "sop encrypt"
encounters a "PASSWORD" which is not a valid "UTF-8" string, it fails encounters a "PASSWORD" which is not a valid "UTF-8" string
with a return code of 31. If "sop encrypt" sees trailing whitespace (Section 7.7), or is otherwise not robust in its representation to
at the end of a "PASSWORD", it will trim the trailing whitespace humans, it fails with "PASSWORD_NOT_HUMAN_READABLE". If "sop
before using the password. encrypt" sees trailing whitespace at the end of a "PASSWORD", it will
trim the trailing whitespace before using the password. See
Section 7.8 for more discussion about passwords.
"--sign-with" enables signing by a secret key (and can be used "--sign-with" creates exactly one signature by the identified secret
multiple times if multiple signatures are desired). key (and can be used multiple times if signatures from multiple keys
are desired).
If "--as" is set to either "text" or "mime", then "--sign-with" will If "--as" is set to "binary", then "--sign-with" will sign as a
sign as a canonical text document. In this case, if the input "DATA" binary document (OpenPGP signature type "0x00").
is not valid "UTF-8", "sop encrypt" fails with a return code of 53.
If "--as" is set to "text", then "--sign-with" will sign as a
canonical text document (OpenPGP signature type "0x01"). In this
case, if the input "DATA" is not valid "UTF-8" (Section 7.7), "sop
encrypt" fails with "EXPECTED_TEXT".
"sop" should only be invoked with "--as=mime" when the input "DATA"
is a MIME message ([RFC2045]. If "--sign-with" is supplied for such
a message, then if the input data is valid "UTF-8", "sop" SHOULD sign
as a canonical text document (OpenPGP signature type "0x01").
However, a MIME message itself might not be valid "UTF-8", for
example, if a MIME subpart contains a raw binary object. If "--sign-
with" is supplied for input "DATA" that is not valid "UTF-8", "sop
encrypt" MAY sign as a binary document (OpenPGP signature type
"0x00").
"sop encrypt" MUST NOT produce any extra signatures beyond those from
"KEY" objects identified by "--sign-with".
The resulting "CIPHERTEXT" should be decryptable by the secret keys The resulting "CIPHERTEXT" should be decryptable by the secret keys
corresponding to every certificate included in all "CERTS", as well corresponding to every certificate included in all "CERTS", as well
as each password given with "--with-password". as each password given with "--with-password".
If no "CERTS" or "--with-password" options are present, "sop encrypt" If no "CERTS" or "--with-password" options are present, "sop encrypt"
fails with a return code of 19. fails with "MISSING_ARG".
If at least one of the identified certificates requires encryption to If at least one of the identified certificates requires encryption to
an unsupported asymmetric algorithm, "sop encrypt" fails with a an unsupported asymmetric algorithm, "sop encrypt" fails with
return code of 13. "UNSUPPORTED_ASYMMETRIC_ALGO".
If at least one of the identified certificates is not encryption- If at least one of the identified certificates is not encryption-
capable (e.g., revoked, expired, no encryption-capable flags on capable (e.g., revoked, expired, no encryption-capable flags on
primary key and valid subkeys), "sop encrypt" fails with a return primary key and valid subkeys), "sop encrypt" fails with
code of 17. "CERT_CANNOT_ENCRYPT".
If "sop encrypt" fails for any reason, it emits no "CIPHERTEXT". If "sop encrypt" fails for any reason, it emits no "CIPHERTEXT".
Example: Example:
(In this example, "bob.bin" is a file containing Bob's binary- (In this example, "bob.bin" is a file containing Bob's binary-
formatted OpenPGP certificate. Alice is encrypting a message to both formatted OpenPGP certificate. Alice is encrypting a message to both
herself and Bob.) herself and Bob.)
$ sop encrypt --as=mime --sign-with=alice.key alice.asc bob.bin < message.eml > encrypted.asc $ sop encrypt --as=mime --sign-with=alice.key alice.asc bob.bin < message.eml > encrypted.asc
$ head -n1 encrypted.asc $ head -n1 encrypted.asc
$ -----BEGIN PGP MESSAGE-----
$
3.7. decrypt: Decrypt a Message 3.7. decrypt: Decrypt a Message
sop decrypt [--session-key-out=SESSIONKEY] sop decrypt [--session-key-out=SESSIONKEY]
[--with-session-key=SESSIONKEY...] [--with-session-key=SESSIONKEY...]
[--with-password=PASSWORD...] [--with-password=PASSWORD...]
[--verify-out=VERIFICATIONS [--verify-out=VERIFICATIONS
[--verify-with=CERTS...] [--verify-with=CERTS...]
[--verify-not-before=DATE] [--verify-not-before=DATE]
[--verify-not-after=DATE] ] [--verify-not-after=DATE] ]
[--] [KEY...] [--] [KEY...]
o Standard Input: "CIPHERTEXT" (Section 5.3) * Standard Input: "CIPHERTEXT" (Section 5.4)
o Standard Output: "DATA" (Section 5.8)
"--session-key-out" can be used to learn the session key on
successful decryption.
If "sop decrypt" fails for any reason and the identified "--session- * Standard Output: "DATA" (Section 5.9)
key-out" file already exists in the filesystem, the file will be The caller can ask "sop" for the session key discovered during
unlinked. decryption by supplying the "--session-key-out" option. If the
specified file already exists in the filesystem, "sop decrypt" will
fail with "OUTPUT_EXISTS". When decryption is successful, "sop
decrypt" writes the discovered session key to the specified file.
"--with-session-key" enables decryption of the "CIPHERTEXT" using the "--with-session-key" enables decryption of the "CIPHERTEXT" using the
session key directly against the "SEIPD" packet. This option can be session key directly against the "SEIPD" packet. This option can be
used multiple times if several possible session keys should be tried. used multiple times if several possible session keys should be tried.
"--with-password" enables decryption based on any "SKESK" packets in "--with-password" enables decryption based on any "SKESK" (section
the "CIPHERTEXT". This option can be used multiple times if the user 5.3 of [I-D.ietf-openpgp-rfc4880bis]) packets in the "CIPHERTEXT".
wants to try more than one password. This option can be used multiple times if the user wants to try more
than one password.
If "sop decrypt" tries and fails to use a supplied "PASSWORD", and it If "sop decrypt" tries and fails to use a supplied "PASSWORD", and it
observes that there is trailing "UTF-8" whitespace at the end of the observes that there is trailing "UTF-8" whitespace at the end of the
"PASSWORD", it will retry with the trailing whitespace stripped. "PASSWORD", it will retry with the trailing whitespace stripped. See
Section 7.8 for more discussion about passwords.
"--verify-out" produces signature verification status to the "--verify-out" produces signature verification status to the
designated file. designated file. If the designated file already exists in the
filesystem, "sop decrypt" will fail with "OUTPUT_EXISTS".
"sop decrypt" does not fail (that is, the return code is not The return code of "sop decrypt" is not affected by the results of
modified) based on the results of signature verification. The caller signature verification. The caller MUST check the returned
MUST check the returned "VERIFICATIONS" to confirm signature status. "VERIFICATIONS" to confirm signature status. An empty
An empty "VERIFICATIONS" output indicates that no valid signatures "VERIFICATIONS" output indicates that no valid signatures were found.
were found. If "sop decrypt" itself fails for any reason, and the
identified "VERIFICATIONS" file already exists in the filesystem, the
file will be unlinked.
"--verify-with" identifies a set of certificates whose signatures "--verify-with" identifies a set of certificates whose signatures
would be acceptable for signatures over this message. would be acceptable for signatures over this message.
If the caller is interested in signature verification, both "-- If the caller is interested in signature verification, both "--
verify-out" and at least one "--verify-with" must be supplied. If verify-out" and at least one "--verify-with" must be supplied. If
only one of these arguments is supplied, "sop decrypt" fails with a only one of these arguments is supplied, "sop decrypt" fails with
return code of 23. "INCOMPLETE_VERIFICATION".
"--verify-not-before" and "--verify-not-after" provide a date range "--verify-not-before" and "--verify-not-after" provide a date range
for acceptable signatures, by analogy with the options for "sop for acceptable signatures, by analogy with the options for "sop
verify" (see Section 3.5). They should only be supplied when doing verify" (see Section 3.5). They should only be supplied when doing
signature verification. signature verification.
See Section 9.1 for more details about signature verification. See Section 9.1 for more details about signature verification.
If no "KEY" or "--with-password" or "--with-session-key" options are If no "KEY" or "--with-password" or "--with-session-key" options are
present, "sop decrypt" fails with a return code of 19. present, "sop decrypt" fails with "MISSING_ARG".
If unable to decrypt, "sop decrypt" fails with a return code of 29. If unable to decrypt, "sop decrypt" fails with "CANNOT_DECRYPT".
"sop decrypt" only returns cleartext to Standard Output that was "sop decrypt" only emits cleartext to Standard Output that was
successfully decrypted. successfully decrypted.
Example: Example:
(In this example, Alice stashes and re-uses the session key of an (In this example, Alice stashes and re-uses the session key of an
encrypted message.) encrypted message.)
$ sop decrypt --session-key-out=session.key alice.sec < ciphertext.asc > cleartext.out $ sop decrypt --session-key-out=session.key alice.sec < ciphertext.asc > cleartext.out
$ ls -l 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 321 Oct 28 01:34 ciphertext.asc
-rw-r--r-- 1 user user 285 Oct 28 01:34 cleartext.out -rw-r--r-- 1 user user 285 Oct 28 01:34 cleartext.out
$ sop decrypt --with-session-key=session.key < ciphertext.asc > cleartext2.out $ sop decrypt --with-session-key=session.key < ciphertext.asc > cleartext2.out
$ diff cleartext.out cleartext2.out $ diff cleartext.out cleartext2.out
$ $
3.8. armor: Add ASCII Armor 3.8. armor: Convert binary to ASCII
sop armor [--label={auto|sig|key|cert|message}] sop armor [--label={auto|sig|key|cert|message}]
[--allow-nested]
o Standard Input: 8-bit, unarmored OpenPGP material ("SIGNATURE", * Standard Input: OpenPGP material ("SIGNATURES", "KEY", "CERTS", or
"CERTS", "KEY", or "CIPHERTEXT") "CIPHERTEXT")
o Standard Output: the same material with ASCII-armoring added * Standard Output: the same material with ASCII-armoring added, if
not already present
The user can choose to specify the label used in the header and tail The user can choose to specify the label used in the header and tail
of the armoring. The default is "auto", in which case, "sop" of the armoring.
inspects the input and chooses the label appropriately. In this
case, if "sop" cannot select a label on the basis of the input, it
treats it as literal data, and labels it as a "message".
If the incoming data is already armored, and the "--allow-nested" The default for "--label" is "auto", in which case, "sop" inspects
flag is not specified, the data MUST be output with no modifications. the input and chooses the label appropriately, based on the type of
Data is considered ASCII armored iff the first 14 bytes are exactly " the first OpenPGP packet. If the type of the first OpenPGP packet
-----BEGIN PGP". This operation is thus idempotent by default. is:
* "0x02" (Signature), the packet stream should be parsed as a
"SIGNATURES" input (with Armor Header "BEGIN PGP SIGNATURE").
* "0x05" (Secret-Key), the packet stream should be parsed as a "KEY"
input (with Armor Header "BEGIN PGP PRIVATE KEY BLOCK").
* "0x06" (Public-Key), the packet stream should be parsed as a
"CERTS" input (with Armor Header "BEGIN PGP PUBLIC KEY BLOCK").
* "0x01" (Public-key Encrypted Session Key) or "0x03" (Symmetric-key
Encrypted Session Key), the packet stream should be parsed as a
"CIPHERTEXT" input (with Armor Header "BEGIN PGP MESSAGE").
If the input packet stream does not match the expected sequence of
packet types, "sop armor" fails with "BAD_DATA".
Since "sop armor" accepts ASCII-armored input as well as binary
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 7-bit clean.
Example: Example:
$ sop armor < bob.bin > bob.pgp $ sop armor < bob.bin > bob.pgp
$ head -n1 bob.pgp $ head -n1 bob.pgp
-----BEGIN PGP PUBLIC KEY BLOCK----- -----BEGIN PGP PUBLIC KEY BLOCK-----
$ $
3.9. dearmor: Remove ASCII Armor 3.9. dearmor: Convert ASCII to binary
sop dearmor sop dearmor
o Standard Input: ASCII-armored OpenPGP material ("CIPHERTEXT", * Standard Input: OpenPGP material ("SIGNATURES", "KEY", "CERTS", or
"SIGNATURE", "CERTS", or "KEY") "CIPHERTEXT")
o Standard Output: the same material with ASCII-armoring removed * Standard Output: the same material with any ASCII-armoring removed
If the input packet stream does not match any of the the expected
sequence of packet types, "sop dearmor" fails with "BAD_DATA". See
also Section 7.4.
Since "sop dearmor" 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.
Example: Example:
$ sop dearmor < message.txt.asc > message.txt.sig $ sop dearmor < message.txt.asc > message.txt.sig
$ $
3.10. detach-inband-signature-and-message: split a clearsigned message
sop detach-inband-signature-and-message --signatures-out=SIGNATURES
* Standard Input: "DATA" (clearsigned message)
* Standard Output: "DATA" (the message without the cleartext
signature framework)
In some contexts, the user may encounter a clearsigned ("inline PGP")
message (section 7 of [RFC4880]) rather than a message and its
detached signature. This subcommand takes such a clearsigned message
on standard input, and splits it into:
* the potentially signed material on standard output, and
* a detached signature block to the destination identified by "--
signatures-to"
Note that no cryptographic verification of the signatures is done by
this subcommand. Once the clearsigned message is separated,
verification of the detached signature can be done with "sop verify".
If no "--signatures-to" is supplied, "sop detach-inband-signature-
and-message" fails with "MISSING_ARG".
Note that the signature block in a clearsigned message may contain
multiple signatures. All signatures found in the signature block
will be emitted to the "--signatures-to" destination.
The message body in the clearsigned message will be dash-escaped on
standard input (see section 7.1 of [RFC4880]). The output of "sop
detach-inband-signature-and-message" will have dash-escaping removed.
If the input "DATA" contains no clearsigned message, "sop detach-
inband-signature-and-message" fails with "BAD_DATA". If the input
"DATA" contains more than one clearsigned message, "sop detach-
inband-signature-and-message" also fails with "BAD_DATA". A "sop"
implementation MAY accept (and discard) leading and trailing data
around the inline PGP clearsigned message.
If the file designated by "--signatures-to" already exists in the
filesystem, "sop detach-inband-signature-and-message" will fail with
"OUTPUT_EXISTS".
Example:
$ sop detach-inband-signature-and-message --signature-out=Release.pgp < InRelease >Release
$ sop verify Release.pgp archive-keyring.pgp < Release
$
4. Input String Types 4. Input String Types
Some material is passed to "sop" directly as a string on the command Some material is passed to "sop" directly as a string on the command
line. line.
4.1. DATE 4.1. DATE
An ISO-8601 formatted timestamp with time zone, or the special value An ISO-8601 formatted timestamp with time zone, or the special value
"now" to indicate the current system time. "now" to indicate the current system time.
skipping to change at page 12, line 5 skipping to change at page 15, line 23
2019-10-29T12:11:04+00:00 2019-10-29T12:11:04+00:00
2019-10-24T23:48:29Z 2019-10-24T23:48:29Z
20191029T121104Z 20191029T121104Z
In some cases where used to specify lower and upper boundaries, a In some cases where used to specify lower and upper boundaries, a
"DATE" value can be set to "-" to indicate "no time limit". "DATE" value can be set to "-" to indicate "no time limit".
A flexible implementation of "sop" MAY accept date inputs in other A flexible implementation of "sop" MAY accept date inputs in other
unambiguous forms. unambiguous forms.
Note that whenever "sop" emits a timestamp (e.g. in Section 5.8) it
MUST produce only a UTC-based ISO-8601 compliant representation.
4.2. USERID 4.2. USERID
This is an arbitrary "UTF-8" string. By convention, most User IDs This is an arbitrary "UTF-8" string (Section 7.7). By convention,
are of the form "Display Name <email.address@example.com>", but they most User IDs are of the form "Display Name
do not need to be. <email.address@example.com>", but they do not need to be.
5. Input/Output Indirect Types 5. Input/Output Indirect Types
Some material is passed to "sop" indirectly, typically by referring Some material is passed to "sop" indirectly, typically by referring
to a filename containing the data in question. This type of data may to a filename containing the data in question. This type of data may
also be passed to "sop" on Standard Input, or delivered by "sop" to also be passed to "sop" on Standard Input, or delivered by "sop" to
Standard Output. Standard Output.
If any input data is specified explicitly to be read from a file that
does not exist, "sop" will fail with "MISSING_INPUT".
If any input data does not meet the requirements described below,
"sop" will fail with "BAD_DATA".
5.1. Special Designators for Indirect Types
An indirect argument or parameter that starts with "@" (COMMERCIAL
AT, U+0040) is not treated as a filename, but is reserved for special
handling, based on the prefix that follows the "@". We describe two
of those prefixes ("@ENV:" and "@FD:") here. A "sop" implementation
that recives such a special designator but does not know how to
handle a given prefix in that context MUST fail with
"UNSUPPORTED_SPECIAL_PREFIX".
If the filename for any indirect material used as input has the If the filename for any indirect material used as input has the
special form "@ENV:xxx", then contents of environment variable "$xxx" special form "@ENV:xxx", then contents of environment variable "$xxx"
is used instead of looking in the filesystem. is used instead of looking in the filesystem. "@ENV" is for input
only: if the prefix "@ENV:" is used for any output argument, "sop"
fails with "UNSUPPORTED_SPECIAL_PREFIX".
If the filename for any indirect material used as either input or If the filename for any indirect material used as either input or
output has the special form "@FD:nnn" where "nnn" is a decimal output has the special form "@FD:nnn" where "nnn" is a decimal
integer, then the associated data is read from file descriptor "nnn". integer, then the associated data is read from file descriptor "nnn".
If any input data does not meet the requirements described below, See Section 7.9 for more details about safe handling of these special
"sop" will fail with a return code of 41. designators.
5.1. CERTS 5.2. CERTS
One or more OpenPGP certificates (section 11.1 of One or more OpenPGP certificates (section 11.1 of
[I-D.ietf-openpgp-rfc4880bis]), aka "Transferable Public Key". May [I-D.ietf-openpgp-rfc4880bis]), aka "Transferable Public Key". May
be armored. be armored (see Section 7.4).
Although some existing workflows may prefer to use one "CERTS" object Although some existing workflows may prefer to use one "CERTS" object
with multiple certificates in it (a "keyring"), supplying exactly one with multiple certificates in it (a "keyring"), supplying exactly one
certificate per "CERTS" input will make error reporting clearer and certificate per "CERTS" input will make error reporting clearer and
easier. easier.
5.2. KEY 5.3. KEY
Exactly one OpenPGP Transferable Secret Key (section 11.2 of Exactly one OpenPGP Transferable Secret Key (section 11.2 of
[I-D.ietf-openpgp-rfc4880bis]). May be armored. [I-D.ietf-openpgp-rfc4880bis]). May be armored (see Section 7.4).
Secret key material should be in cleartext (that is, it should not be Secret key material should be in cleartext (that is, it should not be
locked with a password). If the secret key maerial is locked with a locked with a password). If the secret key material is locked with a
password, "sop" may fail to use the key. password, "sop" may fail with error "KEY_IS_PROTECTED".
5.3. CIPHERTEXT 5.4. CIPHERTEXT
"sop" accepts only a restricted subset of the arbitrarily-nested "sop" accepts only a restricted subset of the arbitrarily-nested
grammar allowed by the OpenPGP Messages definition (section 11.3 of grammar allowed by the OpenPGP Messages definition (section 11.3 of
[I-D.ietf-openpgp-rfc4880bis]). [I-D.ietf-openpgp-rfc4880bis]).
In particular, it accepts and generates only: In particular, it accepts and generates only:
An OpenPGP message, consisting of a sequence of PKESKs (section 5.1 An OpenPGP message, consisting of a sequence of PKESKs (section 5.1
of [I-D.ietf-openpgp-rfc4880bis]) and SKESKs (section 5.3 of of [I-D.ietf-openpgp-rfc4880bis]) and SKESKs (section 5.3 of
[I-D.ietf-openpgp-rfc4880bis]), followed by one SEIPD (section 5.14 [I-D.ietf-openpgp-rfc4880bis]), followed by one SEIPD (section 5.14
of [I-D.ietf-openpgp-rfc4880bis]). of [I-D.ietf-openpgp-rfc4880bis]).
The SEIPD can decrypt into one of two things: The SEIPD can decrypt into one of two things:
o "Maybe Signed Data" (see below), or * "Maybe Signed Data" (see below), or
o Compressed data packet that contains "Maybe Signed Data" * Compressed data packet that contains "Maybe Signed Data"
"Maybe Signed Data" is a sequence of: "Maybe Signed Data" is a sequence of:
o N (zero or more) one-pass signature packets, followed by * N (zero or more) one-pass signature packets, followed by
o zero or more signature packets, followed by * zero or more signature packets, followed by
o one Literal data packet, followed by * one Literal data packet, followed by
o N signature packets (corresponding to the outer one-pass * N signature packets (corresponding to the outer one-pass
signatures packets) signatures packets)
FIXME: does any tool do compression inside signing? Do we need to FIXME: does any tool do compression inside signing? Do we need to
handle that? handle that?
May be armored. May be armored (see Section 7.4).
5.4. SIGNATURE 5.5. SIGNATURES
One or more OpenPGP Signature packets. May be armored. One or more OpenPGP Signature packets. May be armored (see
Section 7.4).
5.5. SESSIONKEY 5.6. SESSIONKEY
This documentation uses the GnuPG defacto "ASCII" representation: This documentation uses the GnuPG defacto "ASCII" representation:
"ALGONUM:HEXKEY" "ALGONUM:HEXKEY"
where "ALGONUM" is the decimal value associated with the OpenPGP where "ALGONUM" is the decimal value associated with the OpenPGP
Symmetric Key Algorithms (section 9.3 of Symmetric Key Algorithms (section 9.3 of
[I-D.ietf-openpgp-rfc4880bis]). [I-D.ietf-openpgp-rfc4880bis]) and "HEXKEY" is the hexadecimal
representation of the binary key.
Example AES-256 session key: Example AES-256 session key:
9:FCA4BEAF687F48059CACC14FB019125CD57392BAB7037C707835925CBF9F7BCD 9:FCA4BEAF687F48059CACC14FB019125CD57392BAB7037C707835925CBF9F7BCD
5.6. PASSWORD 5.7. PASSWORD
This is expected to be a "UTF-8" string, but for "sop decrypt", any This is expected to be a "UTF-8" string (Section 7.7), but for "sop
bytestring that the user supplies will be accepted. Note the details decrypt", any bytestring that the user supplies will be accepted.
in "sop encrypt" and "sop decrypt" about trailing whitespace! Note the details in "sop encrypt" and "sop decrypt" about trailing
whitespace!
5.7. VERIFICATIONS See also Section 7.8 for more discussion.
5.8. VERIFICATIONS
One line per successful signature verification. Each line has three One line per successful signature verification. Each line has three
structured fields delimited by a single space, followed by arbitrary structured fields delimited by a single space, followed by arbitrary
text to the end of the line. text to the end of the line that forms a message describing the
verification.
o ISO-8601 UTC datestamp * ISO-8601 UTC datestamp
o Fingerprint of the signing key (may be a subkey) * Fingerprint of the signing key (may be a subkey)
o Fingerprint of primary key of signing certificate (if signed by * Fingerprint of primary key of signing certificate (if signed by
primary key, same as the previous field) primary key, same as the previous field)
o arbitrary text * message describing the verification (free form)
Note that while Section 4.1 permits a "sop" implementation to accept
other unambiguous date representations, its date output here MUST be
a strict ISO-8601 UTC date timestamp. In particular:
* the date and time fields MUST be separated by "T", not by
whitespace, since whitespace is used as a delimiter
* the time MUST be emitted in UTC, with the explicit suffix "Z"
Example: Example:
2019-10-24T23:48:29Z C90E6D36200A1B922A1509E77618196529AE5FF8 C4BC2DDB38CCE96485EBE9C2F20691179038E5C6 certificate from dkg.asc 2019-10-24T23:48:29Z C90E6D36200A1B922A1509E77618196529AE5FF8 C4BC2DDB38CCE96485EBE9C2F20691179038E5C6 certificate from dkg.asc
5.8. DATA 5.9. DATA
Cleartext, arbitrary data. This is either a bytestream or "UTF-8" Cleartext, arbitrary data. This is either a bytestream or "UTF-8"
text. text.
It MUST only be "UTF-8" text in the case of input supplied to "sop It MUST only be "UTF-8" text in the case of input supplied to "sop
sign --as=text" or "sop encrypt --as={mime|text}". If "sop" receives sign --as=text" or "sop encrypt --as={mime|text}". If "sop" receives
"DATA" containing non-"UTF-8" octets in this case, it will fail with "DATA" containing non-"UTF-8" octets in this case, it will fail (see
return code 53. Section 7.7) with "EXPECTED_TEXT".
6. Failure modes 6. Failure Modes
When "sop" succeeds, it will return 0 and emit nothing to Standard "sop" return codes have both mnemonics and numeric values.
Error. When "sop" fails, it fails with a non-zero return code, and
emits one or more warning messages on Standard Error. Known return
codes include:
+--------+----------------------------------------------------------+ When "sop" succeeds, it will return 0 ("OK") and emit nothing to
| Return | Meaning | Standard Error. When "sop" fails, it fails with a non-zero return
+--------+----------------------------------------------------------+ code, and emits one or more warning messages on Standard Error.
| 0 | Success | Known return codes include:
| | |
| 3 | No acceptable signatures found ("sop verify") |
| | |
| 13 | Asymmetric algorithm unsupported ("sop encrypt") |
| | |
| 17 | Certificate not encryption-capable (e.g., expired, |
| | revoked, unacceptable usage flags) ("sop encrypt") |
| | |
| 19 | Missing required argument |
| | |
| 23 | Incomplete verification instructions ("sop decrypt") |
| | |
| 29 | Unable to decrypt ("sop decrypt") |
| | |
| 31 | Non-"UTF-8" password ("sop encrypt") |
| | |
| 37 | Unsupported option |
| | |
| 41 | Invalid data type (no secret key where "KEY" expected, |
| | etc) |
| | |
| 53 | Non-text input where text expected |
| | |
| 69 | Unsupported subcommand |
+--------+----------------------------------------------------------+
A "sop" implementation MAY return other error codes than those listed +-------+-------------------------------+---------------------------+
above. | Value | Mnemonic | Meaning |
+=======+===============================+===========================+
| 0 | "OK" | Success |
+-------+-------------------------------+---------------------------+
| 3 | "NO_SIGNATURE" | No acceptable |
| | | signatures found ("sop |
| | | verify") |
+-------+-------------------------------+---------------------------+
| 13 | "UNSUPPORTED_ASYMMETRIC_ALGO" | Asymmetric algorithm |
| | | unsupported ("sop |
| | | encrypt") |
+-------+-------------------------------+---------------------------+
| 17 | "CERT_CANNOT_ENCRYPT" | Certificate not |
| | | encryption-capable |
| | | (e.g., expired, |
| | | revoked, unacceptable |
| | | usage flags) ("sop |
| | | encrypt") |
+-------+-------------------------------+---------------------------+
| 19 | "MISSING_ARG" | Missing required |
| | | argument |
+-------+-------------------------------+---------------------------+
| 23 | "INCOMPLETE_VERIFICATION" | Incomplete |
| | | verification |
| | | instructions ("sop |
| | | decrypt") |
+-------+-------------------------------+---------------------------+
| 29 | "CANNOT_DECRYPT" | Unable to decrypt |
| | | ("sop decrypt") |
+-------+-------------------------------+---------------------------+
| 31 | "PASSWORD_NOT_HUMAN_READABLE" | Non-"UTF-8" or |
| | | otherwise unreliable |
| | | password ("sop |
| | | encrypt") |
+-------+-------------------------------+---------------------------+
| 37 | "UNSUPPORTED_OPTION" | Unsupported option |
+-------+-------------------------------+---------------------------+
| 41 | "BAD_DATA" | Invalid data type (no |
| | | secret key where "KEY" |
| | | expected, etc) |
+-------+-------------------------------+---------------------------+
| 53 | "EXPECTED_TEXT" | Non-text input where |
| | | text expected |
+-------+-------------------------------+---------------------------+
| 59 | "OUTPUT_EXISTS" | Output file already |
| | | exists |
+-------+-------------------------------+---------------------------+
| 61 | "MISSING_INPUT" | Input file does not |
| | | exist |
+-------+-------------------------------+---------------------------+
| 67 | "KEY_IS_PROTECTED" | A "KEY" input is |
| | | protected (locked) |
| | | with a password, and |
| | | "sop" cannot unlock it |
+-------+-------------------------------+---------------------------+
| 69 | "UNSUPPORTED_SUBCOMMAND" | Unsupported subcommand |
+-------+-------------------------------+---------------------------+
| 71 | "UNSUPPORTED_SPECIAL_PREFIX" | An indirect parameter |
| | | is a special |
| | | designator (it starts |
| | | with "@") but "sop" |
| | | does not know how to |
| | | handle the prefix |
+-------+-------------------------------+---------------------------+
| 73 | "AMBIGUOUS_INPUT" | A indirect input |
| | | parameter is a special |
| | | designator (it starts |
| | | with "@"), and a |
| | | filename matching the |
| | | designator is actually |
| | | present |
+-------+-------------------------------+---------------------------+
7. Guidance for Implementors Table 1
If a "sop" implementation fails in some way not contemplated by this
document, it MAY return any non-zero error code, not only those
listed above.
7. Guidance for Implementers
"sop" uses a few assumptions that implementers might want to "sop" uses a few assumptions that implementers might want to
consider. consider.
7.1. One OpenPGP Message At a Time 7.1. One OpenPGP Message at a Time
"sop" is intended to be a simple tool that operates on one OpenPGP "sop" 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 object at a time. It should be composable, if you want to use it to
deal with multiple OpenPGP objects deal with multiple OpenPGP objects.
FIXME: discuss what this means for streaming. The stdio interface FIXME: discuss what this means for streaming. The stdio interface
doesn't necessarily imply streamed output. doesn't necessarily imply streamed output.
7.2. Simplified Subset of OpenPGP Message 7.2. Simplified Subset of OpenPGP Message
While the formal grammar for OpenPGP Message is arbitrarily While the formal grammar for OpenPGP Message is arbitrarily nestable,
nestable,"sop" constrains itself to what it sees as a single "layer" "sop" constrains itself to what it sees as a single "layer" (see
(see Section 5.3). Section 5.4).
This is a deliberate choice, because it is what most consumers This is a deliberate choice, because it is what most consumers
expect, and runaway recursion is bad news. expect. Also, if an arbitrarily-nested structure is parsed with a
recursive algorithm, this risks a denial of service vulnerability.
"sop" intends to be implementable with a parser that defensively
declines to do recursive descent into an OpenPGP Message.
Note that an implementation of "sop decrypt" MAY choose to handle Note that an implementation of "sop decrypt" MAY choose to handle
more complex structures, but if it does, it should document the other 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 structures it handles and why it chooses to do so. We can use such
documentation to improve future versions of this spec. documentation to improve future versions of this spec.
7.3. Validate Signatures Only From Known Signers 7.3. Validate Signatures Only from Known Signers
There are generally only a few signers who are relevant for a given There are generally only a few signers who are relevant for a given
OpenPGP message. When verifying signatures, "sop" expects that the OpenPGP message. When verifying signatures, "sop" expects that the
caller can identify those relevant signers ahead of time. caller can identify those relevant signers ahead of time.
7.4. Detached Signatures 7.4. OpenPGP inputs can be either Binary or ASCII-armored
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 "sop" to detect the form and adjust
accordingly seems both redundant and error-prone.
The simple way to detect possible ASCII-armoring is to see whether
the high bit of the first octet is set: section 4.2 of [RFC4880]
indicates that bit 7 is always one in the first octet of an OpenPGP
packet. In standard ASCII-armor, the first character is "-" (HYPHEN-
MINUS, U+002D), so the high bit should be cleared.
When considering an input as ASCII-armored OpenPGP material, "sop"
MAY reject an input based on any of the following variations (see
section 6.2 of [RFC4880] for precise definitions):
* An unknown Armor Header Line
* Any text before the Armor Header Line
* Malformed lines in the Armor Headers section
* Any non-whitespace data after the Armor Tail
* Any Radix-64 encoded line with more than 76 characters
* Invalid characters in the Radix-64-encoded data
* An invalid Armor Checksum
* A mismatch between the Armor Header Line and the Armor Tail
For robustness, "sop" SHOULD be willing to ignore whitespace after
the Armor Tail.
When considering OpenPGP material as input, regardless of whether it
is ASCII-armored or binary, "sop" SHOULD reject any material that
doesn't produce a valid stream of OpenPGP packets. For example,
"sop" SHOULD raise an error if an OpenPGP packet header is malformed,
or if there is trailing garbage after the end of a packet.
For a given type of OpenPGP input material (i.e., "SIGNATURES",
"CERTS", "KEY", or "CIPHERTEXT"), "sop" SHOULD also reject any input
that does not conform to the expected packet stream. See Section 5
for the expected packet stream for different types.
7.5. Detached Signatures
"sop" deals with detached signatures as the baseline form of OpenPGP "sop" deals with detached signatures as the baseline form of OpenPGP
signatures. signatures.
The main problem this avoids is the trickiness of handling a The primary alternative to detached signatures is inline signatures,
signature that is mixed inline into the data that it is signing. but handling an inline signature requires parsing to delimit the
multiple parts of the document, including at least:
7.5. Reliance on Supplied Certs and Keys * any preamble before the message
* the inline message header (delimiter line, OpenPGP headers)
* the message itself
* the divider between the message and the signature (including any
OpenPGP headers there)
* the signature
* the divider that terminates the signature
* any suffix after the signature
Note also that the preamble or the suffix might be arbitrary text,
and might themselves contain OpenPGP messages (whether signatures or
otherwise).
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.
Blurred boundary problems like this can produce ugly attacks similar
to those found in [EFAIL].
7.6. Reliance on Supplied Certs and Keys
A truly stateless implementation may find that it spends more time A truly stateless implementation may find that it spends more time
validating the internal consistency of certificates and keys than it validating the internal consistency of certificates and keys than it
does on the actual object security operations. does on the actual object security operations.
For performance reasons, an implementation may choose to ignore For performance reasons, an implementation may choose to ignore
validation on certificate and key material supplied to it. The validation on certificate and key material supplied to it. The
security implications are of doing so depend on how the certs and security implications of doing so depend on how the certs and keys
keys are managed outside of "sop". are managed outside of "sop".
7.7. Text is always UTF-8
Various places in this specification require UTF-8 [RFC3629] when
encoding text. "sop" implementations SHOULD NOT consider textual data
in any other character encoding.
OpenPGP Implementations MUST already handle UTF-8, because various
parts of [RFC4880] require it, including:
* User ID
* Notation name
* Reason for revocation
* ASCII-armor Comment: header
Dealing with messages in other charsets leads to weird security
failures like [Charset-Switching], especially when the charset
indication is not covered by any sort of cryptographic integrity
check. Restricting textual data to "UTF-8" universally across the
OpenPGP ecosystem eliminates any such risk without losing
functionality, since "UTF-8" can encode all known characters.
7.8. Passwords are Human-Readable
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 ensuring that there is a reliable bidirectional
mapping between strings and bytes. The maximally robust behavior
here is for "sop encrypt" to constrain the choice of passwords to
strings that have such a mapping, and for "sop decrypt" to try
multiple plausible versions of any supplied "PASSWORD".
When generating material based on a password, "sop encrypt" enforces
that the password is actually meaningfully human-transferable
(requiring "UTF-8", trimming trailing whitespace). Some "sop
encrypt" implementations may make even more strict requirements on
input to ensure that they are transferable between humans in a robust
way.
For example, a more strict "sop encrypt" MAY also:
* forbid leading whitespace
* forbid non-printing characters other than "SPACE (U+0020)", such
as "ZERO WIDTH NON-JOINER (U+200C)" or "TAB (U+0009)"
* require the password to be in Unicode Normal Form C
([UNICODE-NORMALIZATION])
Violations of these more-strict policies SHOULD result in an error of
"PASSWORD_NOT_HUMAN_READABLE".
A "sop encrypt" implementation typically SHOULD NOT attempt enforce a
minimum "password strength", but in the event that some
implementation does, it MUST NOT represent a weak password with
"PASSWORD_NOT_HUMAN_READABLE".
When "sop decrypt" receives a "PASSWORD" input, it sees it as a
bytestring. If the bytestring fails to work as a password, but ends
in "UTF-8" 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.
A more robust "sop decrypt" implementation that finds neither of the
above two attempts work for a given "PASSWORD" MAY try additional
variations if they produce a different bytestring, such as:
* trimming any leading whitespace, if discovered
* trimming any internal non-printable characters other than "SPACE
(U+0020)"
* converting the supplied "PASSWORD" into Unicode Normal Form C
([UNICODE-NORMALIZATION])
A "sop decrypt" implementation that stages multiple decryption
attempts like this SHOULD consider the computational resources
consumed by each attempt, to avoid presenting an attack surface for
resource exhaustion in the face of a non-standard "PASSWORD" input.
7.9. Be careful with Special Designators
As documented in Section 5.1, special designators for indirect inputs
like "@ENV:" and "@FD:" (and indirect outputs using "@FD:") warrant
some special/cautious handling.
For one thing, it's conceivable that the filesystem could contain a
file with these literal names. If "sop" receives an indirect output
parameter that starts with an "@" (COMMERCIAL AT, U+0040) it MUST NOT
write to the filesystem for that parameter. A "sop" implementation
that receives such a parameter as input MAY test for the presence of
such a file in the filesystem and fail with "AMBIGUOUS_INPUT" to warn
the user of the ambiguity and possible confusion.
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, "sop" should be
careful with such an input, and minimize its leakage to other
processes. In particular, "sop" SHOULD NOT leak any environment
variable identified by "@ENV:" or file descriptor identified by
"@FD:" to any subprocess unless the subprocess specifically needs
access to that data.
8. Guidance for Consumers 8. Guidance for Consumers
While "sop" is originally conceived of as an interface for While "sop" is originally conceived of as an interface for
interoperability testing, it's conceivable that an application that interoperability testing, it's conceivable that an application that
uses OpenPGP for object security would want to use it. uses OpenPGP for object security would want to use it.
FIXME: more guidance for how to use such a tool safely and FIXME: more guidance for how to use such a tool safely and
efficiently goes here. efficiently goes here.
FIXME: if an encrypted OpenPGP message arrives without metadata, it FIXME: if an encrypted OpenPGP message arrives without metadata, it
is difficult to know which signers to consider when decrypting. How is difficult to know which signers to consider when decrypting. How
do we do this efficiently without invoking "sop decrypt" twice, once do we do this efficiently without invoking "sop decrypt" twice, once
without "--verify-*" and again with the expected identity material? without "--verify-*" and again with the expected identity material?
8.1. Choosing between -as=text and -as=binary
A program that invokes "sop" to generate an OpenPGP signature
typically needs to decide whether it is making a text or binary
signature.
By default, "sop" will make a binary signature. The caller of "sop
sign" should choose "--as=text" only when it knows that: - the data
being signed is in fact textual, and encoded in "UTF-8", and - the
signed data might be transmitted to the recipient (the verifier of
the signature) over a channel that has the propensity to transform
line-endings.
Examples of such channels include FTP ([RFC0959]) and SMTP
([RFC5321]).
8.2. Special Designators and Unusual Filenames
In some cases, a user of "sop" 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).
If one of the files has a name that starts with "--", it might be
confused by "sop" for an option. If one of the files has a name that
starts with "@", it might be confused by "sop" as a special
designator (Section 5.1).
If the user wants to deliberately refer to such an ambiguously-named
file in the filesystem, they should prefix the filename with "./" or
use an absolute path.
Any specific "@FD:" special designator SHOULD NOT be supplied more
than once to an invocation of "sop". If a "sop" invocation sees
multiple copies of a specific "@FD:n" input (e.g., "sop sign @FD:3
@FD:3"), it MAY fail with "MISSING_INPUT" even if file descriptor 3
contains a valid "KEY", because the bytestream for the "KEY" was
consumed by the first argument. Doubling up on the same "@FD:" for
output (e.g., "sop decrypt --session-key-out=@FD:3 --verify-
out=@FD:3") also results in an ambiguous data stream.
9. Security Considerations 9. Security Considerations
The OpenPGP object security model is typically used for The OpenPGP object security model is typically used for
confidentiality and authenticity purposes. confidentiality and authenticity purposes.
9.1. Signature Verification 9.1. Signature Verification
In many contexts, an OpenPGP signature is verified, to prove the In many contexts, an OpenPGP signature is verified to prove the
origin and integrity of an underlying object. origin and integrity of an underlying object.
When "sop" checks a signature (e.g. via "sop verify" or "sop decrypt When "sop" checks a signature (e.g. via "sop verify" or "sop decrypt
--verify-with", it MUST NOT consider it to be verified unless all of --verify-with"), it MUST NOT consider it to be verified unless all of
these conditions are met: these conditions are met:
o The signature must be made by a signing-capable public key that is * The signature must be made by a signing-capable public key that is
present in one of the supplied certificates present in one of the supplied certificates
o The certificate and signing subkey must have been created before * The certificate and signing subkey must have been created before
or at the signature time or at the signature time
o The cetificate and signing subkey must not have been expired at * The certificate and signing subkey must not have been expired at
the signature time the signature time
o The certificate and signing subkey must not be revoked with a * The certificate and signing subkey must not be revoked with a
"hard" revocation "hard" revocation
o If the certificate or signing subkey is revoked with a "soft" * If the certificate or signing subkey is revoked with a "soft"
revocation, then the signature time must predate the revocation revocation, then the signature time must predate the revocation
o The signing subkey must be properly bound to the primary key, and * The signing subkey must be properly bound to the primary key, and
cross-signed cross-signed
o The signature (and any dependent signature, such as the cross-sig * The signature (and any dependent signature, such as the cross-sig
or subkey binding signatures) must be made with strong or subkey binding signatures) must be made with strong
cryptographic algorithms (e.g., not "MD5" or a 1024-bit "RSA" key) cryptographic algorithms (e.g., not "MD5" or a 1024-bit "RSA" key)
Implementers MAY also consider other factors in addition to the Implementers MAY also consider other factors in addition to the
origin and authenticity, including application-specific information. origin and authenticity, including application-specific information.
For example, consider the application domain of checking software For example, consider the application domain of checking software
updates. 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
If software package Foo version 13.3.2 was signed on 2019-10-04, and was signed on 2019-10-16, it may be authentic and have a more recent
the user receives a copy of Foo version 12.4.8 that was signed on signature date. But it is not an upgrade (12.4.8 < 13.3.2), and
2019-10-16, it may be authentic and have a more recent signature therefore it should not be applied automatically.
date. But it is not an upgrade (12.4.8 < 13.3.2), and therefore it
should not be applied automatically.
In such cases, it is critical that the application confirms that the In such cases, it is critical that the application confirms that the
other information verified is _also_ protected by the relevant other information verified is _also_ protected by the relevant
OpenPGP signature. OpenPGP signature.
Signature validity is a complex topic, and this documentation cannot Signature validity is a complex topic (see for example the discussion
list all possible details. at [DISPLAYING-SIGNATURES]), and this documentation cannot list all
possible details.
9.2. Compression 9.2. Compression
The interface as currently specified does not allow for control of The interface as currently specified does not allow for control of
compression. Compressing and encrypting data that may contain both compression. Compressing and encrypting data that may contain both
attacker-supplied material and sensitive material could leak attacker-supplied material and sensitive material could leak
information about the sensitive material (see the CRIME attack). information about the sensitive material (see the CRIME attack).
Unless an application knows for sure that no attacker-supplied Unless an application knows for sure that no attacker-supplied
material is present on the input, it should not compress during material is present in the input, it should not compress during
encryption. encryption.
10. Privacy Considerations 10. Privacy Considerations
Material produced by "sop encrypt" may be placed on an untrusted Material produced by "sop encrypt" may be placed on an untrusted
machine (e.g., sent through the public "SMTP" network). That machine (e.g., sent through the public "SMTP" network). That
material may contain metadata that leaks associational information material may contain metadata that leaks associational information
(e.g., recipient identifiers in PKESK packets). FIXME: document (e.g., recipient identifiers in PKESK packets (section 5.1 of
things like PURBs and "--hidden-recipient") [I-D.ietf-openpgp-rfc4880bis])). FIXME: document things like PURBs
and "--hidden-recipient")
10.1. Object Security vs. Transport Security 10.1. Object Security vs. Transport Security
OpenPGP offers an object security model, but says little to nothing OpenPGP offers an object security model, but says little to nothing
about how the secured objects get to the relevant parties. about how the secured objects get to the relevant parties.
When sending or receiving OpenPGP material, the implementer should When sending or receiving OpenPGP material, the implementer should
consider what privacy leakage is implicit with the transport. consider what privacy leakage is implicit with the transport.
11. Document Considerations 11. Document Considerations
skipping to change at page 19, line 9 skipping to change at page 29, line 7
[ RFC Editor: please remove this section before publication ] [ RFC Editor: please remove this section before publication ]
This document is currently edited as markdown. Minor editorial This document is currently edited as markdown. Minor editorial
changes can be suggested via merge requests at changes can be suggested via merge requests at
https://gitlab.com/dkg/openpgp-stateless-cli or by e-mail to the https://gitlab.com/dkg/openpgp-stateless-cli or by e-mail to the
authors. Please direct all significant commentary to the public IETF authors. Please direct all significant commentary to the public IETF
OpenPGP mailing list: openpgp@ietf.org OpenPGP mailing list: openpgp@ietf.org
11.1. Document History 11.1. Document History
substantive changes between -01 and -02:
* Added mnemonics for return codes
* "decrypt" should fail when asked to output to a pre-existing file
* Removed superfluous "--armor" option
* Much more specific about what "armor --label=auto" should do
* "armor" and "dearmor" are now fully idempotent, but work only
well-formed OpenPGP streams
* Dropped "armor --allow-nested"
* Specified what "encrypt --as=" means
* New error code: "KEY_IS_PROTECTED"
* Documented expectations around human-readable, human-transferable
passwords
* New subcommand: "detach-inband-signature-and-message"
* More specific guidance about special designators like "@FD:" and
"@ENV:", including new error codes "UNSUPPORTED_SPECIAL_PREFIX"
and "AMBIGUOUS_INPUT"
substantive changes between -00 and -01: substantive changes between -00 and -01:
o Changed "generate" subcommand to "generate-key" * Changed "generate" subcommand to "generate-key"
o Changed "convert" subcommand to "extract-cert" * Changed "convert" subcommand to "extract-cert"
o Added "Input String Types" section as distinct from indirect I/O * Added "Input String Types" section as distinct from indirect I/O
o Made implicit arguments potentially explicit (e.g. "sop armor * Made implicit arguments potentially explicit (e.g. "sop armor
--label=auto") --label=auto")
o Added "--allow-nested" to "sop armor" to make it idempotent by * Added "--allow-nested" to "sop armor" to make it idempotent by
default default
o Added fingerprint of signing (sub)key to "VERIFICATIONS" output * Added fingerprint of signing (sub)key to "VERIFICATIONS" output
o Dropped "--mode" and "--session-key" arguments for "sop encrypt" * Dropped "--mode" and "--session-key" arguments for "sop encrypt"
(no plausible use, not needed for interop) (no plausible use, not needed for interop)
o Added "--with-session-key" argument to "sop decrypt" to allow for * Added "--with-session-key" argument to "sop decrypt" to allow for
session-key-based decryption session-key-based decryption
o Added examples to each subcommand * Added examples to each subcommand
o More detailed error codes for "sop encrypt" * More detailed error codes for "sop encrypt"
o Move from "CERT" to "CERTS" (each "CERTS" argument might contain * Move from "CERT" to "CERTS" (each "CERTS" argument might contain
multiple certificates) multiple certificates)
11.2. Future Work 11.2. Future Work
o "detach-inband-signature-and-message" subcommand (split a * certificate transformation into popular publication forms:
clearsigned message into a message and a detached signature) (see
Section 7.4
o certificate transformation into popular publication forms:
* WKD - WKD
* DANE OPENPGPKEY - DANE OPENPGPKEY
* Autocrypt - Autocrypt
o "sop encrypt" - specify compression? (see Section 9.2) * "sop encrypt" - specify compression? (see Section 9.2)
o "sop encrypt" - specify padding policy/mechanism? * "sop encrypt" - specify padding policy/mechanism?
o "sop decrypt" - how can it more safely handle zip bombs? * "sop decrypt" - how can it more safely handle zip bombs?
o "sop decrypt" - what should it do when encountering weakly- * "sop decrypt" - what should it do when encountering weakly-
encrypted (or unencrypted) input? encrypted (or unencrypted) input?
o "sop encrypt" - minimize metadata (e.g. "--throw-keyids")? * "sop encrypt" - minimize metadata (e.g. "--throw-keyids")?
o handling secret keys that are locked with passwords?
o specify an error if a "DATE" arrives as input without a time zone? * handling secret keys that are locked with passwords?
o specify an error if a "sop" invocation sees multiple copies of a * specify an error if a "DATE" arrives as input without a time zone?
specific "@FD:n" input (e.g., "sop sign @FD:3 @FD:3")
o add considerations about what it means for armored "CERTS" to * add considerations about what it means for armored "CERTS" to
contain multiple certificates - multiple armorings? one big blob? contain multiple certificates - multiple armorings? one big blob?
o do we need an interface or option (for performance?) with the * do we need an interface or option (for performance?) with the
semantics that "sop" doesn't validate certificates internally, it semantics that "sop" doesn't validate certificates internally, it
just accepts whatever's given as legit data? (see Section 7.5) just accepts whatever's given as legit data? (see Section 7.6)
* do we need to be able to assemble a clearsigned message? I'd
rather not, given the additional complications.
12. Acknowledgements 12. Acknowledgements
This work was inspired by Justus Winter's This work was inspired by Justus Winter's
[OpenPGP-Interoperability-Test-Suite]. [OpenPGP-Interoperability-Test-Suite].
The following people contributed helpful feedback and considerations The following people contributed helpful feedback and considerations
to this draft, but are not responsible for its problems: to this draft, but are not responsible for its problems:
o Justus Winter * Allan Nordhoey
o Vincent Breitmoser * Antoine Beaupre
o Edwin Taylor * Edwin Taylor
o Jameson Rollins * Jameson Rollins
o Allan Nordhoey * Justus Winter
* Vincent Breitmoser
13. References 13. References
13.1. Normative References 13.1. Normative References
[I-D.ietf-openpgp-rfc4880bis] [I-D.ietf-openpgp-rfc4880bis]
Koch, W., carlson, b., Tse, R., Atkins, D., and D. Koch, W., carlson, b., Tse, R., Atkins, D., and D.
Gillmor, "OpenPGP Message Format", draft-ietf-openpgp- Gillmor, "OpenPGP Message Format", Work in Progress,
rfc4880bis-08 (work in progress), September 2019. Internet-Draft, draft-ietf-openpgp-rfc4880bis-08, 6
September 2019, <http://www.ietf.org/internet-drafts/
draft-ietf-openpgp-rfc4880bis-08.txt>.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997, DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/info/rfc2119>. <https://www.rfc-editor.org/info/rfc2119>.
[RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO
10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, November
2003, <https://www.rfc-editor.org/info/rfc3629>.
[RFC4880] Callas, J., Donnerhacke, L., Finney, H., Shaw, D., and R. [RFC4880] Callas, J., Donnerhacke, L., Finney, H., Shaw, D., and R.
Thayer, "OpenPGP Message Format", RFC 4880, Thayer, "OpenPGP Message Format", RFC 4880,
DOI 10.17487/RFC4880, November 2007, DOI 10.17487/RFC4880, November 2007,
<https://www.rfc-editor.org/info/rfc4880>. <https://www.rfc-editor.org/info/rfc4880>.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, <https://www.rfc-editor.org/info/rfc8174>. May 2017, <https://www.rfc-editor.org/info/rfc8174>.
13.2. Informative References 13.2. Informative References
[Charset-Switching]
Gillmor, D.K., "Inline PGP Considered Harmful", 24
February 2014,
<https://dkg.fifthhorseman.net/notes/inline-pgp-harmful/>.
[DISPLAYING-SIGNATURES]
Brunschwig, P., "On Displaying Signatures", n.d.,
<https://admin.hostpoint.ch/pipermail/enigmail-
users_enigmail.net/2017-November/004683.html>.
[EFAIL] Poddebniak, D. and C. Dresen, "Efail: Breaking S/MIME and
OpenPGP Email Encryption using Exfiltration Channels",
n.d., <https://efail.de>.
[I-D.draft-bre-openpgp-samples-00] [I-D.draft-bre-openpgp-samples-00]
Einarsson, B., juga, j., and D. Gillmor, "OpenPGP Example Einarsson, B., juga, j., and D. Gillmor, "OpenPGP Example
Keys and Certificates", draft-bre-openpgp-samples-00 (work Keys and Certificates", Work in Progress, Internet-Draft,
in progress), October 2019. draft-bre-openpgp-samples-00, 15 October 2019,
<http://www.ietf.org/internet-drafts/draft-bre-openpgp-
samples-00.txt>.
[OpenPGP-Interoperability-Test-Suite] [OpenPGP-Interoperability-Test-Suite]
"OpenPGP Interoperability Test Suite", October 2019, "OpenPGP Interoperability Test Suite", 28 October 2019,
<https://tests.sequoia-pgp.org/>. <https://tests.sequoia-pgp.org/>.
[RFC0959] Postel, J. and J. Reynolds, "File Transfer Protocol",
STD 9, RFC 959, DOI 10.17487/RFC0959, October 1985,
<https://www.rfc-editor.org/info/rfc959>.
[RFC2045] Freed, N. and N. Borenstein, "Multipurpose Internet Mail
Extensions (MIME) Part One: Format of Internet Message
Bodies", RFC 2045, DOI 10.17487/RFC2045, November 1996,
<https://www.rfc-editor.org/info/rfc2045>.
[RFC5321] Klensin, J., "Simple Mail Transfer Protocol", RFC 5321,
DOI 10.17487/RFC5321, October 2008,
<https://www.rfc-editor.org/info/rfc5321>.
[SEMVER] Preston-Werner, T., "Semantic Versioning 2.0.0", 18 June
2013, <https://semver.org/>.
[UNICODE-NORMALIZATION]
Whistler, K., "Unicode Normalization Forms", 4 February
2019, <https://unicode.org/reports/tr15/>.
Author's Address Author's Address
Daniel Kahn Gillmor Daniel Kahn Gillmor
American Civil Liberties Union American Civil Liberties Union
125 Broad St. 125 Broad St.
New York, NY 10004 New York, NY, 10004
USA United States of America
Email: dkg@fifthhorseman.net Email: dkg@fifthhorseman.net
 End of changes. 177 change blocks. 
341 lines changed or deleted 882 lines changed or added

This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/