idnits 2.17.1 draft-dkg-openpgp-stateless-cli-02.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The document seems to lack an IANA Considerations section. (See Section 2.2 of https://www.ietf.org/id-info/checklist for how to handle the case when there are no actions for IANA.) ** There are 8 instances of too long lines in the document, the longest one being 58 characters in excess of 72. == There are 7 instances of lines with non-RFC2606-compliant FQDNs in the document. == There are 1 instance of lines with non-RFC6890-compliant IPv4 addresses in the document. If these are example addresses, they should be changed. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (6 March 2020) is 1511 days in the past. Is this intentional? Checking references for intended status: Informational ---------------------------------------------------------------------------- == Missing Reference: '--no-armor' is mentioned on line 381, but not defined == Missing Reference: '--' is mentioned on line 468, but not defined == Outdated reference: A later version (-10) exists of draft-ietf-openpgp-rfc4880bis-08 == Outdated reference: A later version (-01) exists of draft-bre-openpgp-samples-00 Summary: 2 errors (**), 0 flaws (~~), 7 warnings (==), 1 comment (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 openpgp D.K. Gillmor 3 Internet-Draft ACLU 4 Intended status: Informational 6 March 2020 5 Expires: 7 September 2020 7 Stateless OpenPGP Command Line Interface 8 draft-dkg-openpgp-stateless-cli-02 10 Abstract 12 This document defines a generic stateless command-line interface for 13 dealing with OpenPGP messages, known as "sop". It aims for a 14 minimal, well-structured API covering OpenPGP object security. 16 Status of This Memo 18 This Internet-Draft is submitted in full conformance with the 19 provisions of BCP 78 and BCP 79. 21 Internet-Drafts are working documents of the Internet Engineering 22 Task Force (IETF). Note that other groups may also distribute 23 working documents as Internet-Drafts. The list of current Internet- 24 Drafts is at https://datatracker.ietf.org/drafts/current/. 26 Internet-Drafts are draft documents valid for a maximum of six months 27 and may be updated, replaced, or obsoleted by other documents at any 28 time. It is inappropriate to use Internet-Drafts as reference 29 material or to cite them other than as "work in progress." 31 This Internet-Draft will expire on 7 September 2020. 33 Copyright Notice 35 Copyright (c) 2020 IETF Trust and the persons identified as the 36 document authors. All rights reserved. 38 This document is subject to BCP 78 and the IETF Trust's Legal 39 Provisions Relating to IETF Documents (https://trustee.ietf.org/ 40 license-info) in effect on the date of publication of this document. 41 Please review these documents carefully, as they describe your rights 42 and restrictions with respect to this document. Code Components 43 extracted from this document must include Simplified BSD License text 44 as described in Section 4.e of the Trust Legal Provisions and are 45 provided without warranty as described in the Simplified BSD License. 47 Table of Contents 49 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 50 1.1. Requirements Language . . . . . . . . . . . . . . . . . . 4 51 1.2. Terminology . . . . . . . . . . . . . . . . . . . . . . . 4 52 1.3. Using sop in a Test Suite . . . . . . . . . . . . . . . . 4 53 2. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . 4 54 3. Subcommands . . . . . . . . . . . . . . . . . . . . . . . . . 5 55 3.1. version: Version Information . . . . . . . . . . . . . . 5 56 3.2. generate-key: Generate a Secret Key . . . . . . . . . . . 6 57 3.3. extract-cert: Extract a Certificate from a Secret Key . . 6 58 3.4. sign: Create Detached Signatures . . . . . . . . . . . . 7 59 3.5. verify: Verify Detached Signatures . . . . . . . . . . . 7 60 3.6. encrypt: Encrypt a Message . . . . . . . . . . . . . . . 8 61 3.7. decrypt: Decrypt a Message . . . . . . . . . . . . . . . 10 62 3.8. armor: Convert binary to ASCII . . . . . . . . . . . . . 12 63 3.9. dearmor: Convert ASCII to binary . . . . . . . . . . . . 13 64 3.10. detach-inband-signature-and-message: split a clearsigned 65 message . . . . . . . . . . . . . . . . . . . . . . . . 13 66 4. Input String Types . . . . . . . . . . . . . . . . . . . . . 14 67 4.1. DATE . . . . . . . . . . . . . . . . . . . . . . . . . . 15 68 4.2. USERID . . . . . . . . . . . . . . . . . . . . . . . . . 15 69 5. Input/Output Indirect Types . . . . . . . . . . . . . . . . . 15 70 5.1. Special Designators for Indirect Types . . . . . . . . . 16 71 5.2. CERTS . . . . . . . . . . . . . . . . . . . . . . . . . . 16 72 5.3. KEY . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 73 5.4. CIPHERTEXT . . . . . . . . . . . . . . . . . . . . . . . 16 74 5.5. SIGNATURES . . . . . . . . . . . . . . . . . . . . . . . 17 75 5.6. SESSIONKEY . . . . . . . . . . . . . . . . . . . . . . . 17 76 5.7. PASSWORD . . . . . . . . . . . . . . . . . . . . . . . . 18 77 5.8. VERIFICATIONS . . . . . . . . . . . . . . . . . . . . . . 18 78 5.9. DATA . . . . . . . . . . . . . . . . . . . . . . . . . . 18 79 6. Failure Modes . . . . . . . . . . . . . . . . . . . . . . . . 19 80 7. Guidance for Implementers . . . . . . . . . . . . . . . . . . 20 81 7.1. One OpenPGP Message at a Time . . . . . . . . . . . . . . 21 82 7.2. Simplified Subset of OpenPGP Message . . . . . . . . . . 21 83 7.3. Validate Signatures Only from Known Signers . . . . . . . 21 84 7.4. OpenPGP inputs can be either Binary or ASCII-armored . . 21 85 7.5. Detached Signatures . . . . . . . . . . . . . . . . . . . 22 86 7.6. Reliance on Supplied Certs and Keys . . . . . . . . . . . 23 87 7.7. Text is always UTF-8 . . . . . . . . . . . . . . . . . . 23 88 7.8. Passwords are Human-Readable . . . . . . . . . . . . . . 24 89 7.9. Be careful with Special Designators . . . . . . . . . . . 25 90 8. Guidance for Consumers . . . . . . . . . . . . . . . . . . . 25 91 8.1. Choosing between -as=text and -as=binary . . . . . . . . 26 92 8.2. Special Designators and Unusual Filenames . . . . . . . . 26 93 9. Security Considerations . . . . . . . . . . . . . . . . . . . 27 94 9.1. Signature Verification . . . . . . . . . . . . . . . . . 27 95 9.2. Compression . . . . . . . . . . . . . . . . . . . . . . . 28 96 10. Privacy Considerations . . . . . . . . . . . . . . . . . . . 28 97 10.1. Object Security vs. Transport Security . . . . . . . . . 28 98 11. Document Considerations . . . . . . . . . . . . . . . . . . . 28 99 11.1. Document History . . . . . . . . . . . . . . . . . . . . 29 100 11.2. Future Work . . . . . . . . . . . . . . . . . . . . . . 30 101 12. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 31 102 13. References . . . . . . . . . . . . . . . . . . . . . . . . . 31 103 13.1. Normative References . . . . . . . . . . . . . . . . . . 31 104 13.2. Informative References . . . . . . . . . . . . . . . . . 32 105 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 33 107 1. Introduction 109 Different OpenPGP implementations have many different requirements, 110 which typically break down in two main categories: key/certificate 111 management and object security. 113 The purpose of this document is to provide a "stateless" interface 114 that primarily handles the object security side of things, and 115 assumes that secret key management and certificate management will be 116 handled some other way. 118 Isolating object security from key/certificate management should make 119 it easier to provide interoperability testing for the object security 120 side of OpenPGP implementations, as described in Section 1.3. 122 This document defines a generic stateless command-line interface for 123 dealing with OpenPGP messages, known here by the placeholder "sop". 124 It aims for a minimal, well-structured API. 126 An OpenPGP implementation should not name its executable "sop" to 127 implement this specification. It just needs to provide a program 128 that conforms to this interface. 130 A "sop" implementation should leave no trace on the system, and its 131 behavior should not be affected by anything other than command-line 132 arguments and input. 134 Obviously, the user will need to manage their secret keys (and their 135 peers' certificates) somehow, but the goal of this interface is to 136 separate out that task from the task of interacting with OpenPGP 137 messages. 139 While this document identifies a command-line interface, the rough 140 outlines of this interface should also be amenable to relatively 141 straightforward library implementations in different languages. 143 1.1. Requirements Language 145 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 146 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 147 "OPTIONAL" in this document are to be interpreted as described in BCP 148 14 [RFC2119] [RFC8174] when, and only when, they appear in all 149 capitals, as shown here. 151 1.2. Terminology 153 This document uses the term "key" to refer exclusively to OpenPGP 154 Transferable Secret Keys (see section 11.2 of [RFC4880]). 156 It uses the term "certificate" to refer to OpenPGP Transferable 157 Public Key (see section 11.1 of [RFC4880]). 159 "Stateless" in "Stateless OpenPGP" means avoiding secret key and 160 certificate state. The user is responsible for managing all OpenPGP 161 certificates and secret keys themselves, and passing them to "sop" as 162 needed. The user should also not be concerned that any state could 163 affect the underlying operations. 165 OpenPGP revocations can have "Reason for Revocation" (section 166 5.2.3.23 of [RFC4880]), which can be either "soft" or "hard". The 167 set of "soft" reasons is: "Key is superseded" and "Key is retired and 168 no longer used". All other reasons (and revocations that do not 169 state a reason) are "hard" revocations. 171 1.3. Using sop in a Test Suite 173 If an OpenPGP implementation provdids a "sop" interface, it can be 174 used to test interoperability (e.g., 175 [OpenPGP-Interoperability-Test-Suite]). 177 Such an interop test suite can, for example, use custom code (_not_ 178 "sop") to generate a new OpenPGP object that incorporates new 179 primitives, and feed that object to a stable of "sop" 180 implementations, to determine whether those implementations can 181 consume the new form. 183 Or, the test suite can drive each "sop" implementation with a simple 184 input, and observe which cryptographic primitives each implementation 185 chooses to use as it produces output. 187 2. Examples 189 These examples show no error checking, but give a flavor of how "sop" 190 might be used in practice from a shell. 192 The key and certificate files described in them (e.g. "alice.sec") 193 could be for example those found in 194 [I-D.draft-bre-openpgp-samples-00]. 196 sop generate-key "Alice Lovelace " > alice.sec 197 sop extract-cert < alice.sec > alice.pgp 199 sop sign --as=text alice.sec < statement.txt > statement.txt.asc 200 sop verify announcement.txt.asc alice.pgp < announcement.txt 202 sop encrypt --sign-with=alice.sec --as=mime bob.pgp < msg.eml > encrypted.asc 203 sop decrypt alice.sec < ciphertext.asc > cleartext.out 205 See Section 6 for more information about errors and error handling. 207 3. Subcommands 209 "sop" uses a subcommand interface, similar to those popularized by 210 systems like "git" and "svn". 212 If the user supplies a subcommand that "sop" does not implement, it 213 fails with "UNSUPPORTED_SUBCOMMAND". If a "sop" implementation does 214 not handle a supplied option for a given subcommand, it fails with 215 "UNSUPPORTED_OPTION". 217 All subcommands that produce OpenPGP material on standard output 218 produce ASCII-armored (section 6 of [I-D.ietf-openpgp-rfc4880bis]) 219 objects by default (except for "sop dearmor"). These subcommands 220 have a "--no-armor" option, which causes them to produce binary 221 OpenPGP material instead. 223 All subcommands that accept OpenPGP material on input should be able 224 to accept either ASCII-armored or binary inputs (see Section 7.4) and 225 behave accordingly. 227 See Section 5 for details about how various forms of OpenPGP material 228 are expected to be structured. 230 3.1. version: Version Information 232 sop version 234 * Standard Input: ignored 236 * Standard Output: version string 238 The version string emitted should contain the name of the "sop" 239 implementation, followed by a single space, followed by the version 240 number. A "sop" implementation should use a version number that 241 respects an established standard that is easily comparable and 242 parsable, like [SEMVER]. 244 Example: 246 $ sop version 247 ExampleSop 0.2.1 248 $ 250 3.2. generate-key: Generate a Secret Key 252 sop generate-key [--no-armor] [--] [USERID...] 254 * Standard Input: ignored 256 * Standard Output: "KEY" (Section 5.3) 258 Generate a single default OpenPGP key with zero or more User IDs. 260 The generated secret key SHOULD be usable for as much of the "sop" 261 functionality as possible. In particular: 263 * It should be possible to extract an OpenPGP certificate from the 264 "KEY" with "sop extract-cert". 266 * The "KEY" should be able to create signatures (with "sop sign") 267 that are verifiable by using "sop verify" with the extracted 268 certificate. 270 * The "KEY" should be able to decrypt messages (with "sop decrypt") 271 that are encrypted by using "sop encrypt" with the extracted 272 certificate. 274 The detailed internal structure of the certificate is left to the 275 discretion of the "sop" implementation. 277 Example: 279 $ sop generate-key 'Alice Lovelace ' > alice.sec 280 $ head -n1 < alice.sec 281 -----BEGIN PGP PRIVATE KEY BLOCK----- 282 $ 284 3.3. extract-cert: Extract a Certificate from a Secret Key 286 sop extract-cert [--no-armor] 287 * Standard Input: "KEY" (Section 5.3) 289 * Standard Output: "CERTS" (Section 5.2) 291 Note that the resultant "CERTS" object will only ever contain one 292 OpenPGP certificate, since "KEY" contains exactly one OpenPGP 293 Transferable Secret Key. 295 Example: 297 $ sop extract-cert < alice.sec > alice.pgp 298 $ head -n1 < alice.pgp 299 -----BEGIN PGP PUBLIC KEY BLOCK----- 300 $ 302 3.4. sign: Create Detached Signatures 304 sop sign [--no-armor] 305 [--as={binary|text}] [--] KEY [KEY...] 307 * Standard Input: "DATA" (Section 5.9) 309 * Standard Output: "SIGNATURES" (Section 5.5) 311 Exactly one signature will be made by each supplied "KEY". 313 "--as" defaults to "binary". If "--as=text" and the input "DATA" is 314 not valid "UTF-8" (Section 7.7), "sop sign" fails with 315 "EXPECTED_TEXT". 317 "--as=binary" SHOULD result in an OpenPGP signature of type 0x00 318 ("Signature of a binary document"). "--as=text" SHOULD result in an 319 OpenPGP signature of type 0x01 ("Signature of a canonical text 320 document"). See section 5.2.1 of [RFC4880] for more details. 322 "sop sign" MUST NOT produce any extra signatures beyond those from 323 "KEY" objects supplied on the command line. 325 Example: 327 $ sop sign --as=text alice.sec < message.txt > message.txt.asc 328 $ head -n1 < message.txt.asc 329 -----BEGIN PGP SIGNATURE----- 330 $ 332 3.5. verify: Verify Detached Signatures 333 sop verify [--not-before=DATE] [--not-after=DATE] 334 [--] SIGNATURES CERTS [CERTS...] 336 * Standard Input: "DATA" (Section 5.9) 338 * Standard Output: "VERIFICATIONS" (Section 5.8) 340 "--not-before" and "--not-after" indicate that signatures with dates 341 outside certain range MUST NOT be considered valid. 343 "--not-before" defaults to the beginning of time. Accepts the 344 special value "-" to indicate the beginning of time (i.e. no lower 345 boundary). 347 "--not-after" defaults to the current system time ("now"). Accepts 348 the special value "-" to indicate the end of time (i.e. no upper 349 boundary). 351 "sop verify" only returns "OK" if at least one certificate included 352 in any "CERTS" object made a valid signature in the range over the 353 "DATA" supplied. 355 For details about the valid signatures, the user MUST inspect the 356 "VERIFICATIONS" output. 358 If no "CERTS" are supplied, "sop verify" fails with "MISSING_ARG". 360 If no valid signatures are found, "sop verify" fails with 361 "NO_SIGNATURE". 363 See Section 9.1 for more details about signature verification. 365 Example: 367 (In this example, we see signature verification succeed first, and 368 then fail on a modified version of the message.) 370 $ sop verify message.txt.asc alice.pgp < message.txt 371 2019-10-29T18:36:45Z EB85BB5FA33A75E15E944E63F231550C4F47E38E EB85BB5FA33A75E15E944E63F231550C4F47E38E signed by alice.pgp 372 $ echo $? 373 0 374 $ tr a-z A-Z < message.txt | sop verify message.txt.asc alice.pgp 375 $ echo $? 376 3 377 $ 379 3.6. encrypt: Encrypt a Message 380 sop encrypt [--as={binary|text|mime}] 381 [--no-armor] 382 [--with-password=PASSWORD...] 383 [--sign-with=KEY...] 384 [--] [CERTS...] 386 * Standard Input: "DATA" (Section 5.9) 388 * Standard Output: "CIPHERTEXT" (Section 5.4) 390 "--as" defaults to "binary". The setting of "--as" corresponds to 391 the one octet format field found in the Literal Data packet at the 392 core of the output "CIPHERTEXT". If "--as" is set to "binary", the 393 octet is "b" ("0x62"). If it is "text", the format octet is "u" 394 ("0x75"). If it is "mime", the format octet is "m" ("0x6d"). 396 "--with-password" enables symmetric encryption (and can be used 397 multiple times if multiple passwords are desired). If "sop encrypt" 398 encounters a "PASSWORD" which is not a valid "UTF-8" string 399 (Section 7.7), or is otherwise not robust in its representation to 400 humans, it fails with "PASSWORD_NOT_HUMAN_READABLE". If "sop 401 encrypt" sees trailing whitespace at the end of a "PASSWORD", it will 402 trim the trailing whitespace before using the password. See 403 Section 7.8 for more discussion about passwords. 405 "--sign-with" creates exactly one signature by the identified secret 406 key (and can be used multiple times if signatures from multiple keys 407 are desired). 409 If "--as" is set to "binary", then "--sign-with" will sign as a 410 binary document (OpenPGP signature type "0x00"). 412 If "--as" is set to "text", then "--sign-with" will sign as a 413 canonical text document (OpenPGP signature type "0x01"). In this 414 case, if the input "DATA" is not valid "UTF-8" (Section 7.7), "sop 415 encrypt" fails with "EXPECTED_TEXT". 417 "sop" should only be invoked with "--as=mime" when the input "DATA" 418 is a MIME message ([RFC2045]. If "--sign-with" is supplied for such 419 a message, then if the input data is valid "UTF-8", "sop" SHOULD sign 420 as a canonical text document (OpenPGP signature type "0x01"). 421 However, a MIME message itself might not be valid "UTF-8", for 422 example, if a MIME subpart contains a raw binary object. If "--sign- 423 with" is supplied for input "DATA" that is not valid "UTF-8", "sop 424 encrypt" MAY sign as a binary document (OpenPGP signature type 425 "0x00"). 427 "sop encrypt" MUST NOT produce any extra signatures beyond those from 428 "KEY" objects identified by "--sign-with". 430 The resulting "CIPHERTEXT" should be decryptable by the secret keys 431 corresponding to every certificate included in all "CERTS", as well 432 as each password given with "--with-password". 434 If no "CERTS" or "--with-password" options are present, "sop encrypt" 435 fails with "MISSING_ARG". 437 If at least one of the identified certificates requires encryption to 438 an unsupported asymmetric algorithm, "sop encrypt" fails with 439 "UNSUPPORTED_ASYMMETRIC_ALGO". 441 If at least one of the identified certificates is not encryption- 442 capable (e.g., revoked, expired, no encryption-capable flags on 443 primary key and valid subkeys), "sop encrypt" fails with 444 "CERT_CANNOT_ENCRYPT". 446 If "sop encrypt" fails for any reason, it emits no "CIPHERTEXT". 448 Example: 450 (In this example, "bob.bin" is a file containing Bob's binary- 451 formatted OpenPGP certificate. Alice is encrypting a message to both 452 herself and Bob.) 454 $ sop encrypt --as=mime --sign-with=alice.key alice.asc bob.bin < message.eml > encrypted.asc 455 $ head -n1 encrypted.asc 456 -----BEGIN PGP MESSAGE----- 457 $ 459 3.7. decrypt: Decrypt a Message 461 sop decrypt [--session-key-out=SESSIONKEY] 462 [--with-session-key=SESSIONKEY...] 463 [--with-password=PASSWORD...] 464 [--verify-out=VERIFICATIONS 465 [--verify-with=CERTS...] 466 [--verify-not-before=DATE] 467 [--verify-not-after=DATE] ] 468 [--] [KEY...] 470 * Standard Input: "CIPHERTEXT" (Section 5.4) 472 * Standard Output: "DATA" (Section 5.9) 473 The caller can ask "sop" for the session key discovered during 474 decryption by supplying the "--session-key-out" option. If the 475 specified file already exists in the filesystem, "sop decrypt" will 476 fail with "OUTPUT_EXISTS". When decryption is successful, "sop 477 decrypt" writes the discovered session key to the specified file. 479 "--with-session-key" enables decryption of the "CIPHERTEXT" using the 480 session key directly against the "SEIPD" packet. This option can be 481 used multiple times if several possible session keys should be tried. 483 "--with-password" enables decryption based on any "SKESK" (section 484 5.3 of [I-D.ietf-openpgp-rfc4880bis]) packets in the "CIPHERTEXT". 485 This option can be used multiple times if the user wants to try more 486 than one password. 488 If "sop decrypt" tries and fails to use a supplied "PASSWORD", and it 489 observes that there is trailing "UTF-8" whitespace at the end of the 490 "PASSWORD", it will retry with the trailing whitespace stripped. See 491 Section 7.8 for more discussion about passwords. 493 "--verify-out" produces signature verification status to the 494 designated file. If the designated file already exists in the 495 filesystem, "sop decrypt" will fail with "OUTPUT_EXISTS". 497 The return code of "sop decrypt" is not affected by the results of 498 signature verification. The caller MUST check the returned 499 "VERIFICATIONS" to confirm signature status. An empty 500 "VERIFICATIONS" output indicates that no valid signatures were found. 502 "--verify-with" identifies a set of certificates whose signatures 503 would be acceptable for signatures over this message. 505 If the caller is interested in signature verification, both "-- 506 verify-out" and at least one "--verify-with" must be supplied. If 507 only one of these arguments is supplied, "sop decrypt" fails with 508 "INCOMPLETE_VERIFICATION". 510 "--verify-not-before" and "--verify-not-after" provide a date range 511 for acceptable signatures, by analogy with the options for "sop 512 verify" (see Section 3.5). They should only be supplied when doing 513 signature verification. 515 See Section 9.1 for more details about signature verification. 517 If no "KEY" or "--with-password" or "--with-session-key" options are 518 present, "sop decrypt" fails with "MISSING_ARG". 520 If unable to decrypt, "sop decrypt" fails with "CANNOT_DECRYPT". 522 "sop decrypt" only emits cleartext to Standard Output that was 523 successfully decrypted. 525 Example: 527 (In this example, Alice stashes and re-uses the session key of an 528 encrypted message.) 530 $ sop decrypt --session-key-out=session.key alice.sec < ciphertext.asc > cleartext.out 531 $ ls -l ciphertext.asc cleartext.out 532 -rw-r--r-- 1 user user 321 Oct 28 01:34 ciphertext.asc 533 -rw-r--r-- 1 user user 285 Oct 28 01:34 cleartext.out 534 $ sop decrypt --with-session-key=session.key < ciphertext.asc > cleartext2.out 535 $ diff cleartext.out cleartext2.out 536 $ 538 3.8. armor: Convert binary to ASCII 540 sop armor [--label={auto|sig|key|cert|message}] 542 * Standard Input: OpenPGP material ("SIGNATURES", "KEY", "CERTS", or 543 "CIPHERTEXT") 545 * Standard Output: the same material with ASCII-armoring added, if 546 not already present 548 The user can choose to specify the label used in the header and tail 549 of the armoring. 551 The default for "--label" is "auto", in which case, "sop" inspects 552 the input and chooses the label appropriately, based on the type of 553 the first OpenPGP packet. If the type of the first OpenPGP packet 554 is: 556 * "0x02" (Signature), the packet stream should be parsed as a 557 "SIGNATURES" input (with Armor Header "BEGIN PGP SIGNATURE"). 559 * "0x05" (Secret-Key), the packet stream should be parsed as a "KEY" 560 input (with Armor Header "BEGIN PGP PRIVATE KEY BLOCK"). 562 * "0x06" (Public-Key), the packet stream should be parsed as a 563 "CERTS" input (with Armor Header "BEGIN PGP PUBLIC KEY BLOCK"). 565 * "0x01" (Public-key Encrypted Session Key) or "0x03" (Symmetric-key 566 Encrypted Session Key), the packet stream should be parsed as a 567 "CIPHERTEXT" input (with Armor Header "BEGIN PGP MESSAGE"). 569 If the input packet stream does not match the expected sequence of 570 packet types, "sop armor" fails with "BAD_DATA". 572 Since "sop armor" accepts ASCII-armored input as well as binary 573 input, this operation is idempotent on well-structured data. A 574 caller can use this subcommand blindly ensure that any well-formed 575 OpenPGP packet stream is 7-bit clean. 577 Example: 579 $ sop armor < bob.bin > bob.pgp 580 $ head -n1 bob.pgp 581 -----BEGIN PGP PUBLIC KEY BLOCK----- 582 $ 584 3.9. dearmor: Convert ASCII to binary 586 sop dearmor 588 * Standard Input: OpenPGP material ("SIGNATURES", "KEY", "CERTS", or 589 "CIPHERTEXT") 591 * Standard Output: the same material with any ASCII-armoring removed 593 If the input packet stream does not match any of the the expected 594 sequence of packet types, "sop dearmor" fails with "BAD_DATA". See 595 also Section 7.4. 597 Since "sop dearmor" accepts binary-formatted input as well as ASCII- 598 armored input, this operation is idempotent on well-structured data. 599 A caller can use this subcommand blindly ensure that any well-formed 600 OpenPGP packet stream is in its standard binary representation. 602 Example: 604 $ sop dearmor < message.txt.asc > message.txt.sig 605 $ 607 3.10. detach-inband-signature-and-message: split a clearsigned message 609 sop detach-inband-signature-and-message --signatures-out=SIGNATURES 611 * Standard Input: "DATA" (clearsigned message) 613 * Standard Output: "DATA" (the message without the cleartext 614 signature framework) 616 In some contexts, the user may encounter a clearsigned ("inline PGP") 617 message (section 7 of [RFC4880]) rather than a message and its 618 detached signature. This subcommand takes such a clearsigned message 619 on standard input, and splits it into: 621 * the potentially signed material on standard output, and 623 * a detached signature block to the destination identified by "-- 624 signatures-to" 626 Note that no cryptographic verification of the signatures is done by 627 this subcommand. Once the clearsigned message is separated, 628 verification of the detached signature can be done with "sop verify". 630 If no "--signatures-to" is supplied, "sop detach-inband-signature- 631 and-message" fails with "MISSING_ARG". 633 Note that the signature block in a clearsigned message may contain 634 multiple signatures. All signatures found in the signature block 635 will be emitted to the "--signatures-to" destination. 637 The message body in the clearsigned message will be dash-escaped on 638 standard input (see section 7.1 of [RFC4880]). The output of "sop 639 detach-inband-signature-and-message" will have dash-escaping removed. 641 If the input "DATA" contains no clearsigned message, "sop detach- 642 inband-signature-and-message" fails with "BAD_DATA". If the input 643 "DATA" contains more than one clearsigned message, "sop detach- 644 inband-signature-and-message" also fails with "BAD_DATA". A "sop" 645 implementation MAY accept (and discard) leading and trailing data 646 around the inline PGP clearsigned message. 648 If the file designated by "--signatures-to" already exists in the 649 filesystem, "sop detach-inband-signature-and-message" will fail with 650 "OUTPUT_EXISTS". 652 Example: 654 $ sop detach-inband-signature-and-message --signature-out=Release.pgp < InRelease >Release 655 $ sop verify Release.pgp archive-keyring.pgp < Release 656 $ 658 4. Input String Types 660 Some material is passed to "sop" directly as a string on the command 661 line. 663 4.1. DATE 665 An ISO-8601 formatted timestamp with time zone, or the special value 666 "now" to indicate the current system time. 668 Examples: 670 now 671 2019-10-29T12:11:04+00:00 672 2019-10-24T23:48:29Z 673 20191029T121104Z 675 In some cases where used to specify lower and upper boundaries, a 676 "DATE" value can be set to "-" to indicate "no time limit". 678 A flexible implementation of "sop" MAY accept date inputs in other 679 unambiguous forms. 681 Note that whenever "sop" emits a timestamp (e.g. in Section 5.8) it 682 MUST produce only a UTC-based ISO-8601 compliant representation. 684 4.2. USERID 686 This is an arbitrary "UTF-8" string (Section 7.7). By convention, 687 most User IDs are of the form "Display Name 688 ", but they do not need to be. 690 5. Input/Output Indirect Types 692 Some material is passed to "sop" indirectly, typically by referring 693 to a filename containing the data in question. This type of data may 694 also be passed to "sop" on Standard Input, or delivered by "sop" to 695 Standard Output. 697 If any input data is specified explicitly to be read from a file that 698 does not exist, "sop" will fail with "MISSING_INPUT". 700 If any input data does not meet the requirements described below, 701 "sop" will fail with "BAD_DATA". 703 5.1. Special Designators for Indirect Types 705 An indirect argument or parameter that starts with "@" (COMMERCIAL 706 AT, U+0040) is not treated as a filename, but is reserved for special 707 handling, based on the prefix that follows the "@". We describe two 708 of those prefixes ("@ENV:" and "@FD:") here. A "sop" implementation 709 that recives such a special designator but does not know how to 710 handle a given prefix in that context MUST fail with 711 "UNSUPPORTED_SPECIAL_PREFIX". 713 If the filename for any indirect material used as input has the 714 special form "@ENV:xxx", then contents of environment variable "$xxx" 715 is used instead of looking in the filesystem. "@ENV" is for input 716 only: if the prefix "@ENV:" is used for any output argument, "sop" 717 fails with "UNSUPPORTED_SPECIAL_PREFIX". 719 If the filename for any indirect material used as either input or 720 output has the special form "@FD:nnn" where "nnn" is a decimal 721 integer, then the associated data is read from file descriptor "nnn". 723 See Section 7.9 for more details about safe handling of these special 724 designators. 726 5.2. CERTS 728 One or more OpenPGP certificates (section 11.1 of 729 [I-D.ietf-openpgp-rfc4880bis]), aka "Transferable Public Key". May 730 be armored (see Section 7.4). 732 Although some existing workflows may prefer to use one "CERTS" object 733 with multiple certificates in it (a "keyring"), supplying exactly one 734 certificate per "CERTS" input will make error reporting clearer and 735 easier. 737 5.3. KEY 739 Exactly one OpenPGP Transferable Secret Key (section 11.2 of 740 [I-D.ietf-openpgp-rfc4880bis]). May be armored (see Section 7.4). 742 Secret key material should be in cleartext (that is, it should not be 743 locked with a password). If the secret key material is locked with a 744 password, "sop" may fail with error "KEY_IS_PROTECTED". 746 5.4. CIPHERTEXT 748 "sop" accepts only a restricted subset of the arbitrarily-nested 749 grammar allowed by the OpenPGP Messages definition (section 11.3 of 750 [I-D.ietf-openpgp-rfc4880bis]). 752 In particular, it accepts and generates only: 754 An OpenPGP message, consisting of a sequence of PKESKs (section 5.1 755 of [I-D.ietf-openpgp-rfc4880bis]) and SKESKs (section 5.3 of 756 [I-D.ietf-openpgp-rfc4880bis]), followed by one SEIPD (section 5.14 757 of [I-D.ietf-openpgp-rfc4880bis]). 759 The SEIPD can decrypt into one of two things: 761 * "Maybe Signed Data" (see below), or 763 * Compressed data packet that contains "Maybe Signed Data" 765 "Maybe Signed Data" is a sequence of: 767 * N (zero or more) one-pass signature packets, followed by 769 * zero or more signature packets, followed by 771 * one Literal data packet, followed by 773 * N signature packets (corresponding to the outer one-pass 774 signatures packets) 776 FIXME: does any tool do compression inside signing? Do we need to 777 handle that? 779 May be armored (see Section 7.4). 781 5.5. SIGNATURES 783 One or more OpenPGP Signature packets. May be armored (see 784 Section 7.4). 786 5.6. SESSIONKEY 788 This documentation uses the GnuPG defacto "ASCII" representation: 790 "ALGONUM:HEXKEY" 792 where "ALGONUM" is the decimal value associated with the OpenPGP 793 Symmetric Key Algorithms (section 9.3 of 794 [I-D.ietf-openpgp-rfc4880bis]) and "HEXKEY" is the hexadecimal 795 representation of the binary key. 797 Example AES-256 session key: 799 9:FCA4BEAF687F48059CACC14FB019125CD57392BAB7037C707835925CBF9F7BCD 801 5.7. PASSWORD 803 This is expected to be a "UTF-8" string (Section 7.7), but for "sop 804 decrypt", any bytestring that the user supplies will be accepted. 805 Note the details in "sop encrypt" and "sop decrypt" about trailing 806 whitespace! 808 See also Section 7.8 for more discussion. 810 5.8. VERIFICATIONS 812 One line per successful signature verification. Each line has three 813 structured fields delimited by a single space, followed by arbitrary 814 text to the end of the line that forms a message describing the 815 verification. 817 * ISO-8601 UTC datestamp 819 * Fingerprint of the signing key (may be a subkey) 821 * Fingerprint of primary key of signing certificate (if signed by 822 primary key, same as the previous field) 824 * message describing the verification (free form) 826 Note that while Section 4.1 permits a "sop" implementation to accept 827 other unambiguous date representations, its date output here MUST be 828 a strict ISO-8601 UTC date timestamp. In particular: 830 * the date and time fields MUST be separated by "T", not by 831 whitespace, since whitespace is used as a delimiter 833 * the time MUST be emitted in UTC, with the explicit suffix "Z" 835 Example: 837 2019-10-24T23:48:29Z C90E6D36200A1B922A1509E77618196529AE5FF8 C4BC2DDB38CCE96485EBE9C2F20691179038E5C6 certificate from dkg.asc 839 5.9. DATA 841 Cleartext, arbitrary data. This is either a bytestream or "UTF-8" 842 text. 844 It MUST only be "UTF-8" text in the case of input supplied to "sop 845 sign --as=text" or "sop encrypt --as={mime|text}". If "sop" receives 846 "DATA" containing non-"UTF-8" octets in this case, it will fail (see 847 Section 7.7) with "EXPECTED_TEXT". 849 6. Failure Modes 851 "sop" return codes have both mnemonics and numeric values. 853 When "sop" succeeds, it will return 0 ("OK") and emit nothing to 854 Standard Error. When "sop" fails, it fails with a non-zero return 855 code, and emits one or more warning messages on Standard Error. 856 Known return codes include: 858 +-------+-------------------------------+---------------------------+ 859 | Value | Mnemonic | Meaning | 860 +=======+===============================+===========================+ 861 | 0 | "OK" | Success | 862 +-------+-------------------------------+---------------------------+ 863 | 3 | "NO_SIGNATURE" | No acceptable | 864 | | | signatures found ("sop | 865 | | | verify") | 866 +-------+-------------------------------+---------------------------+ 867 | 13 | "UNSUPPORTED_ASYMMETRIC_ALGO" | Asymmetric algorithm | 868 | | | unsupported ("sop | 869 | | | encrypt") | 870 +-------+-------------------------------+---------------------------+ 871 | 17 | "CERT_CANNOT_ENCRYPT" | Certificate not | 872 | | | encryption-capable | 873 | | | (e.g., expired, | 874 | | | revoked, unacceptable | 875 | | | usage flags) ("sop | 876 | | | encrypt") | 877 +-------+-------------------------------+---------------------------+ 878 | 19 | "MISSING_ARG" | Missing required | 879 | | | argument | 880 +-------+-------------------------------+---------------------------+ 881 | 23 | "INCOMPLETE_VERIFICATION" | Incomplete | 882 | | | verification | 883 | | | instructions ("sop | 884 | | | decrypt") | 885 +-------+-------------------------------+---------------------------+ 886 | 29 | "CANNOT_DECRYPT" | Unable to decrypt | 887 | | | ("sop decrypt") | 888 +-------+-------------------------------+---------------------------+ 889 | 31 | "PASSWORD_NOT_HUMAN_READABLE" | Non-"UTF-8" or | 890 | | | otherwise unreliable | 891 | | | password ("sop | 892 | | | encrypt") | 893 +-------+-------------------------------+---------------------------+ 894 | 37 | "UNSUPPORTED_OPTION" | Unsupported option | 895 +-------+-------------------------------+---------------------------+ 896 | 41 | "BAD_DATA" | Invalid data type (no | 897 | | | secret key where "KEY" | 898 | | | expected, etc) | 899 +-------+-------------------------------+---------------------------+ 900 | 53 | "EXPECTED_TEXT" | Non-text input where | 901 | | | text expected | 902 +-------+-------------------------------+---------------------------+ 903 | 59 | "OUTPUT_EXISTS" | Output file already | 904 | | | exists | 905 +-------+-------------------------------+---------------------------+ 906 | 61 | "MISSING_INPUT" | Input file does not | 907 | | | exist | 908 +-------+-------------------------------+---------------------------+ 909 | 67 | "KEY_IS_PROTECTED" | A "KEY" input is | 910 | | | protected (locked) | 911 | | | with a password, and | 912 | | | "sop" cannot unlock it | 913 +-------+-------------------------------+---------------------------+ 914 | 69 | "UNSUPPORTED_SUBCOMMAND" | Unsupported subcommand | 915 +-------+-------------------------------+---------------------------+ 916 | 71 | "UNSUPPORTED_SPECIAL_PREFIX" | An indirect parameter | 917 | | | is a special | 918 | | | designator (it starts | 919 | | | with "@") but "sop" | 920 | | | does not know how to | 921 | | | handle the prefix | 922 +-------+-------------------------------+---------------------------+ 923 | 73 | "AMBIGUOUS_INPUT" | A indirect input | 924 | | | parameter is a special | 925 | | | designator (it starts | 926 | | | with "@"), and a | 927 | | | filename matching the | 928 | | | designator is actually | 929 | | | present | 930 +-------+-------------------------------+---------------------------+ 932 Table 1 934 If a "sop" implementation fails in some way not contemplated by this 935 document, it MAY return any non-zero error code, not only those 936 listed above. 938 7. Guidance for Implementers 940 "sop" uses a few assumptions that implementers might want to 941 consider. 943 7.1. One OpenPGP Message at a Time 945 "sop" is intended to be a simple tool that operates on one OpenPGP 946 object at a time. It should be composable, if you want to use it to 947 deal with multiple OpenPGP objects. 949 FIXME: discuss what this means for streaming. The stdio interface 950 doesn't necessarily imply streamed output. 952 7.2. Simplified Subset of OpenPGP Message 954 While the formal grammar for OpenPGP Message is arbitrarily nestable, 955 "sop" constrains itself to what it sees as a single "layer" (see 956 Section 5.4). 958 This is a deliberate choice, because it is what most consumers 959 expect. Also, if an arbitrarily-nested structure is parsed with a 960 recursive algorithm, this risks a denial of service vulnerability. 961 "sop" intends to be implementable with a parser that defensively 962 declines to do recursive descent into an OpenPGP Message. 964 Note that an implementation of "sop decrypt" MAY choose to handle 965 more complex structures, but if it does, it should document the other 966 structures it handles and why it chooses to do so. We can use such 967 documentation to improve future versions of this spec. 969 7.3. Validate Signatures Only from Known Signers 971 There are generally only a few signers who are relevant for a given 972 OpenPGP message. When verifying signatures, "sop" expects that the 973 caller can identify those relevant signers ahead of time. 975 7.4. OpenPGP inputs can be either Binary or ASCII-armored 977 OpenPGP material on input can be in either ASCII-armored or binary 978 form. This is a deliberate choice because there are typical 979 scenarios where the program can't predict which form will appear. 980 Expecting the caller of "sop" to detect the form and adjust 981 accordingly seems both redundant and error-prone. 983 The simple way to detect possible ASCII-armoring is to see whether 984 the high bit of the first octet is set: section 4.2 of [RFC4880] 985 indicates that bit 7 is always one in the first octet of an OpenPGP 986 packet. In standard ASCII-armor, the first character is "-" (HYPHEN- 987 MINUS, U+002D), so the high bit should be cleared. 989 When considering an input as ASCII-armored OpenPGP material, "sop" 990 MAY reject an input based on any of the following variations (see 991 section 6.2 of [RFC4880] for precise definitions): 993 * An unknown Armor Header Line 995 * Any text before the Armor Header Line 997 * Malformed lines in the Armor Headers section 999 * Any non-whitespace data after the Armor Tail 1001 * Any Radix-64 encoded line with more than 76 characters 1003 * Invalid characters in the Radix-64-encoded data 1005 * An invalid Armor Checksum 1007 * A mismatch between the Armor Header Line and the Armor Tail 1009 For robustness, "sop" SHOULD be willing to ignore whitespace after 1010 the Armor Tail. 1012 When considering OpenPGP material as input, regardless of whether it 1013 is ASCII-armored or binary, "sop" SHOULD reject any material that 1014 doesn't produce a valid stream of OpenPGP packets. For example, 1015 "sop" SHOULD raise an error if an OpenPGP packet header is malformed, 1016 or if there is trailing garbage after the end of a packet. 1018 For a given type of OpenPGP input material (i.e., "SIGNATURES", 1019 "CERTS", "KEY", or "CIPHERTEXT"), "sop" SHOULD also reject any input 1020 that does not conform to the expected packet stream. See Section 5 1021 for the expected packet stream for different types. 1023 7.5. Detached Signatures 1025 "sop" deals with detached signatures as the baseline form of OpenPGP 1026 signatures. 1028 The primary alternative to detached signatures is inline signatures, 1029 but handling an inline signature requires parsing to delimit the 1030 multiple parts of the document, including at least: 1032 * any preamble before the message 1034 * the inline message header (delimiter line, OpenPGP headers) 1036 * the message itself 1037 * the divider between the message and the signature (including any 1038 OpenPGP headers there) 1040 * the signature 1042 * the divider that terminates the signature 1044 * any suffix after the signature 1046 Note also that the preamble or the suffix might be arbitrary text, 1047 and might themselves contain OpenPGP messages (whether signatures or 1048 otherwise). 1050 If the parser that does this split differs in any way from the parser 1051 that does the verification, or parts of the message are confused, it 1052 would be possible to produce a verification status and an actual 1053 signed message that don't correspond to one another. 1055 Blurred boundary problems like this can produce ugly attacks similar 1056 to those found in [EFAIL]. 1058 7.6. Reliance on Supplied Certs and Keys 1060 A truly stateless implementation may find that it spends more time 1061 validating the internal consistency of certificates and keys than it 1062 does on the actual object security operations. 1064 For performance reasons, an implementation may choose to ignore 1065 validation on certificate and key material supplied to it. The 1066 security implications of doing so depend on how the certs and keys 1067 are managed outside of "sop". 1069 7.7. Text is always UTF-8 1071 Various places in this specification require UTF-8 [RFC3629] when 1072 encoding text. "sop" implementations SHOULD NOT consider textual data 1073 in any other character encoding. 1075 OpenPGP Implementations MUST already handle UTF-8, because various 1076 parts of [RFC4880] require it, including: 1078 * User ID 1080 * Notation name 1082 * Reason for revocation 1084 * ASCII-armor Comment: header 1085 Dealing with messages in other charsets leads to weird security 1086 failures like [Charset-Switching], especially when the charset 1087 indication is not covered by any sort of cryptographic integrity 1088 check. Restricting textual data to "UTF-8" universally across the 1089 OpenPGP ecosystem eliminates any such risk without losing 1090 functionality, since "UTF-8" can encode all known characters. 1092 7.8. Passwords are Human-Readable 1094 Passwords are generally expected to be human-readable, as they are 1095 typically recorded and transmitted as human-visible, human- 1096 transferable strings. However, they are used in the OpenPGP protocol 1097 as bytestrings, so ensuring that there is a reliable bidirectional 1098 mapping between strings and bytes. The maximally robust behavior 1099 here is for "sop encrypt" to constrain the choice of passwords to 1100 strings that have such a mapping, and for "sop decrypt" to try 1101 multiple plausible versions of any supplied "PASSWORD". 1103 When generating material based on a password, "sop encrypt" enforces 1104 that the password is actually meaningfully human-transferable 1105 (requiring "UTF-8", trimming trailing whitespace). Some "sop 1106 encrypt" implementations may make even more strict requirements on 1107 input to ensure that they are transferable between humans in a robust 1108 way. 1110 For example, a more strict "sop encrypt" MAY also: 1112 * forbid leading whitespace 1114 * forbid non-printing characters other than "SPACE (U+0020)", such 1115 as "ZERO WIDTH NON-JOINER (U+200C)" or "TAB (U+0009)" 1117 * require the password to be in Unicode Normal Form C 1118 ([UNICODE-NORMALIZATION]) 1120 Violations of these more-strict policies SHOULD result in an error of 1121 "PASSWORD_NOT_HUMAN_READABLE". 1123 A "sop encrypt" implementation typically SHOULD NOT attempt enforce a 1124 minimum "password strength", but in the event that some 1125 implementation does, it MUST NOT represent a weak password with 1126 "PASSWORD_NOT_HUMAN_READABLE". 1128 When "sop decrypt" receives a "PASSWORD" input, it sees it as a 1129 bytestring. If the bytestring fails to work as a password, but ends 1130 in "UTF-8" whitespace, it will try again with the trailing whitespace 1131 removed. This handles a common pattern of using a file with a final 1132 newline, for example. The pattern here is one of robustness in the 1133 face of typical errors in human-transferred textual data. 1135 A more robust "sop decrypt" implementation that finds neither of the 1136 above two attempts work for a given "PASSWORD" MAY try additional 1137 variations if they produce a different bytestring, such as: 1139 * trimming any leading whitespace, if discovered 1141 * trimming any internal non-printable characters other than "SPACE 1142 (U+0020)" 1144 * converting the supplied "PASSWORD" into Unicode Normal Form C 1145 ([UNICODE-NORMALIZATION]) 1147 A "sop decrypt" implementation that stages multiple decryption 1148 attempts like this SHOULD consider the computational resources 1149 consumed by each attempt, to avoid presenting an attack surface for 1150 resource exhaustion in the face of a non-standard "PASSWORD" input. 1152 7.9. Be careful with Special Designators 1154 As documented in Section 5.1, special designators for indirect inputs 1155 like "@ENV:" and "@FD:" (and indirect outputs using "@FD:") warrant 1156 some special/cautious handling. 1158 For one thing, it's conceivable that the filesystem could contain a 1159 file with these literal names. If "sop" receives an indirect output 1160 parameter that starts with an "@" (COMMERCIAL AT, U+0040) it MUST NOT 1161 write to the filesystem for that parameter. A "sop" implementation 1162 that receives such a parameter as input MAY test for the presence of 1163 such a file in the filesystem and fail with "AMBIGUOUS_INPUT" to warn 1164 the user of the ambiguity and possible confusion. 1166 These special designators are likely to be used to pass sensitive 1167 data (like secret key material or passwords) so that it doesn't need 1168 to touch the filesystem. Given this sensitivity, "sop" should be 1169 careful with such an input, and minimize its leakage to other 1170 processes. In particular, "sop" SHOULD NOT leak any environment 1171 variable identified by "@ENV:" or file descriptor identified by 1172 "@FD:" to any subprocess unless the subprocess specifically needs 1173 access to that data. 1175 8. Guidance for Consumers 1177 While "sop" is originally conceived of as an interface for 1178 interoperability testing, it's conceivable that an application that 1179 uses OpenPGP for object security would want to use it. 1181 FIXME: more guidance for how to use such a tool safely and 1182 efficiently goes here. 1184 FIXME: if an encrypted OpenPGP message arrives without metadata, it 1185 is difficult to know which signers to consider when decrypting. How 1186 do we do this efficiently without invoking "sop decrypt" twice, once 1187 without "--verify-*" and again with the expected identity material? 1189 8.1. Choosing between -as=text and -as=binary 1191 A program that invokes "sop" to generate an OpenPGP signature 1192 typically needs to decide whether it is making a text or binary 1193 signature. 1195 By default, "sop" will make a binary signature. The caller of "sop 1196 sign" should choose "--as=text" only when it knows that: - the data 1197 being signed is in fact textual, and encoded in "UTF-8", and - the 1198 signed data might be transmitted to the recipient (the verifier of 1199 the signature) over a channel that has the propensity to transform 1200 line-endings. 1202 Examples of such channels include FTP ([RFC0959]) and SMTP 1203 ([RFC5321]). 1205 8.2. Special Designators and Unusual Filenames 1207 In some cases, a user of "sop" might want to pass all the files in a 1208 given directory as positional parameters (e.g., a list of CERTS files 1209 to test a signature against). 1211 If one of the files has a name that starts with "--", it might be 1212 confused by "sop" for an option. If one of the files has a name that 1213 starts with "@", it might be confused by "sop" as a special 1214 designator (Section 5.1). 1216 If the user wants to deliberately refer to such an ambiguously-named 1217 file in the filesystem, they should prefix the filename with "./" or 1218 use an absolute path. 1220 Any specific "@FD:" special designator SHOULD NOT be supplied more 1221 than once to an invocation of "sop". If a "sop" invocation sees 1222 multiple copies of a specific "@FD:n" input (e.g., "sop sign @FD:3 1223 @FD:3"), it MAY fail with "MISSING_INPUT" even if file descriptor 3 1224 contains a valid "KEY", because the bytestream for the "KEY" was 1225 consumed by the first argument. Doubling up on the same "@FD:" for 1226 output (e.g., "sop decrypt --session-key-out=@FD:3 --verify- 1227 out=@FD:3") also results in an ambiguous data stream. 1229 9. Security Considerations 1231 The OpenPGP object security model is typically used for 1232 confidentiality and authenticity purposes. 1234 9.1. Signature Verification 1236 In many contexts, an OpenPGP signature is verified to prove the 1237 origin and integrity of an underlying object. 1239 When "sop" checks a signature (e.g. via "sop verify" or "sop decrypt 1240 --verify-with"), it MUST NOT consider it to be verified unless all of 1241 these conditions are met: 1243 * The signature must be made by a signing-capable public key that is 1244 present in one of the supplied certificates 1246 * The certificate and signing subkey must have been created before 1247 or at the signature time 1249 * The certificate and signing subkey must not have been expired at 1250 the signature time 1252 * The certificate and signing subkey must not be revoked with a 1253 "hard" revocation 1255 * If the certificate or signing subkey is revoked with a "soft" 1256 revocation, then the signature time must predate the revocation 1258 * The signing subkey must be properly bound to the primary key, and 1259 cross-signed 1261 * The signature (and any dependent signature, such as the cross-sig 1262 or subkey binding signatures) must be made with strong 1263 cryptographic algorithms (e.g., not "MD5" or a 1024-bit "RSA" key) 1265 Implementers MAY also consider other factors in addition to the 1266 origin and authenticity, including application-specific information. 1268 For example, consider the application domain of checking software 1269 updates. If software package Foo version 13.3.2 was signed on 1270 2019-10-04, and the user receives a copy of Foo version 12.4.8 that 1271 was signed on 2019-10-16, it may be authentic and have a more recent 1272 signature date. But it is not an upgrade (12.4.8 < 13.3.2), and 1273 therefore it should not be applied automatically. 1275 In such cases, it is critical that the application confirms that the 1276 other information verified is _also_ protected by the relevant 1277 OpenPGP signature. 1279 Signature validity is a complex topic (see for example the discussion 1280 at [DISPLAYING-SIGNATURES]), and this documentation cannot list all 1281 possible details. 1283 9.2. Compression 1285 The interface as currently specified does not allow for control of 1286 compression. Compressing and encrypting data that may contain both 1287 attacker-supplied material and sensitive material could leak 1288 information about the sensitive material (see the CRIME attack). 1290 Unless an application knows for sure that no attacker-supplied 1291 material is present in the input, it should not compress during 1292 encryption. 1294 10. Privacy Considerations 1296 Material produced by "sop encrypt" may be placed on an untrusted 1297 machine (e.g., sent through the public "SMTP" network). That 1298 material may contain metadata that leaks associational information 1299 (e.g., recipient identifiers in PKESK packets (section 5.1 of 1300 [I-D.ietf-openpgp-rfc4880bis])). FIXME: document things like PURBs 1301 and "--hidden-recipient") 1303 10.1. Object Security vs. Transport Security 1305 OpenPGP offers an object security model, but says little to nothing 1306 about how the secured objects get to the relevant parties. 1308 When sending or receiving OpenPGP material, the implementer should 1309 consider what privacy leakage is implicit with the transport. 1311 11. Document Considerations 1313 [ RFC Editor: please remove this section before publication ] 1315 This document is currently edited as markdown. Minor editorial 1316 changes can be suggested via merge requests at 1317 https://gitlab.com/dkg/openpgp-stateless-cli or by e-mail to the 1318 authors. Please direct all significant commentary to the public IETF 1319 OpenPGP mailing list: openpgp@ietf.org 1321 11.1. Document History 1323 substantive changes between -01 and -02: 1325 * Added mnemonics for return codes 1327 * "decrypt" should fail when asked to output to a pre-existing file 1329 * Removed superfluous "--armor" option 1331 * Much more specific about what "armor --label=auto" should do 1333 * "armor" and "dearmor" are now fully idempotent, but work only 1334 well-formed OpenPGP streams 1336 * Dropped "armor --allow-nested" 1338 * Specified what "encrypt --as=" means 1340 * New error code: "KEY_IS_PROTECTED" 1342 * Documented expectations around human-readable, human-transferable 1343 passwords 1345 * New subcommand: "detach-inband-signature-and-message" 1347 * More specific guidance about special designators like "@FD:" and 1348 "@ENV:", including new error codes "UNSUPPORTED_SPECIAL_PREFIX" 1349 and "AMBIGUOUS_INPUT" 1351 substantive changes between -00 and -01: 1353 * Changed "generate" subcommand to "generate-key" 1355 * Changed "convert" subcommand to "extract-cert" 1357 * Added "Input String Types" section as distinct from indirect I/O 1359 * Made implicit arguments potentially explicit (e.g. "sop armor 1360 --label=auto") 1362 * Added "--allow-nested" to "sop armor" to make it idempotent by 1363 default 1365 * Added fingerprint of signing (sub)key to "VERIFICATIONS" output 1367 * Dropped "--mode" and "--session-key" arguments for "sop encrypt" 1368 (no plausible use, not needed for interop) 1370 * Added "--with-session-key" argument to "sop decrypt" to allow for 1371 session-key-based decryption 1373 * Added examples to each subcommand 1375 * More detailed error codes for "sop encrypt" 1377 * Move from "CERT" to "CERTS" (each "CERTS" argument might contain 1378 multiple certificates) 1380 11.2. Future Work 1382 * certificate transformation into popular publication forms: 1384 - WKD 1386 - DANE OPENPGPKEY 1388 - Autocrypt 1390 * "sop encrypt" - specify compression? (see Section 9.2) 1392 * "sop encrypt" - specify padding policy/mechanism? 1394 * "sop decrypt" - how can it more safely handle zip bombs? 1396 * "sop decrypt" - what should it do when encountering weakly- 1397 encrypted (or unencrypted) input? 1399 * "sop encrypt" - minimize metadata (e.g. "--throw-keyids")? 1401 * handling secret keys that are locked with passwords? 1403 * specify an error if a "DATE" arrives as input without a time zone? 1405 * add considerations about what it means for armored "CERTS" to 1406 contain multiple certificates - multiple armorings? one big blob? 1408 * do we need an interface or option (for performance?) with the 1409 semantics that "sop" doesn't validate certificates internally, it 1410 just accepts whatever's given as legit data? (see Section 7.6) 1412 * do we need to be able to assemble a clearsigned message? I'd 1413 rather not, given the additional complications. 1415 12. Acknowledgements 1417 This work was inspired by Justus Winter's 1418 [OpenPGP-Interoperability-Test-Suite]. 1420 The following people contributed helpful feedback and considerations 1421 to this draft, but are not responsible for its problems: 1423 * Allan Nordhoey 1425 * Antoine Beaupre 1427 * Edwin Taylor 1429 * Jameson Rollins 1431 * Justus Winter 1433 * Vincent Breitmoser 1435 13. References 1437 13.1. Normative References 1439 [I-D.ietf-openpgp-rfc4880bis] 1440 Koch, W., carlson, b., Tse, R., Atkins, D., and D. 1441 Gillmor, "OpenPGP Message Format", Work in Progress, 1442 Internet-Draft, draft-ietf-openpgp-rfc4880bis-08, 6 1443 September 2019, . 1446 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 1447 Requirement Levels", BCP 14, RFC 2119, 1448 DOI 10.17487/RFC2119, March 1997, 1449 . 1451 [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 1452 10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, November 1453 2003, . 1455 [RFC4880] Callas, J., Donnerhacke, L., Finney, H., Shaw, D., and R. 1456 Thayer, "OpenPGP Message Format", RFC 4880, 1457 DOI 10.17487/RFC4880, November 2007, 1458 . 1460 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 1461 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 1462 May 2017, . 1464 13.2. Informative References 1466 [Charset-Switching] 1467 Gillmor, D.K., "Inline PGP Considered Harmful", 24 1468 February 2014, 1469 . 1471 [DISPLAYING-SIGNATURES] 1472 Brunschwig, P., "On Displaying Signatures", n.d., 1473 . 1476 [EFAIL] Poddebniak, D. and C. Dresen, "Efail: Breaking S/MIME and 1477 OpenPGP Email Encryption using Exfiltration Channels", 1478 n.d., . 1480 [I-D.draft-bre-openpgp-samples-00] 1481 Einarsson, B., juga, j., and D. Gillmor, "OpenPGP Example 1482 Keys and Certificates", Work in Progress, Internet-Draft, 1483 draft-bre-openpgp-samples-00, 15 October 2019, 1484 . 1487 [OpenPGP-Interoperability-Test-Suite] 1488 "OpenPGP Interoperability Test Suite", 28 October 2019, 1489 . 1491 [RFC0959] Postel, J. and J. Reynolds, "File Transfer Protocol", 1492 STD 9, RFC 959, DOI 10.17487/RFC0959, October 1985, 1493 . 1495 [RFC2045] Freed, N. and N. Borenstein, "Multipurpose Internet Mail 1496 Extensions (MIME) Part One: Format of Internet Message 1497 Bodies", RFC 2045, DOI 10.17487/RFC2045, November 1996, 1498 . 1500 [RFC5321] Klensin, J., "Simple Mail Transfer Protocol", RFC 5321, 1501 DOI 10.17487/RFC5321, October 2008, 1502 . 1504 [SEMVER] Preston-Werner, T., "Semantic Versioning 2.0.0", 18 June 1505 2013, . 1507 [UNICODE-NORMALIZATION] 1508 Whistler, K., "Unicode Normalization Forms", 4 February 1509 2019, . 1511 Author's Address 1513 Daniel Kahn Gillmor 1514 American Civil Liberties Union 1515 125 Broad St. 1516 New York, NY, 10004 1517 United States of America 1519 Email: dkg@fifthhorseman.net