idnits 2.17.1 draft-dkg-openpgp-stateless-cli-03.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 55 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 (25 October 2021) is 913 days in the past. Is this intentional? Checking references for intended status: Informational ---------------------------------------------------------------------------- == Missing Reference: '--no-armor' is mentioned on line 649, but not defined == Missing Reference: '--' is mentioned on line 509, but not defined Summary: 2 errors (**), 0 flaws (~~), 5 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 25 October 2021 5 Expires: 28 April 2022 7 Stateless OpenPGP Command Line Interface 8 draft-dkg-openpgp-stateless-cli-03 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 minimal, 14 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 28 April 2022. 33 Copyright Notice 35 Copyright (c) 2021 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 . . . . . . . . . . . . . . . . . . . . . . . . . . 5 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 . . 7 58 3.4. sign: Create Detached Signatures . . . . . . . . . . . . 7 59 3.5. verify: Verify Detached Signatures . . . . . . . . . . . 8 60 3.6. encrypt: Encrypt a Message . . . . . . . . . . . . . . . 9 61 3.7. decrypt: Decrypt a Message . . . . . . . . . . . . . . . 11 62 3.8. armor: Convert binary to ASCII . . . . . . . . . . . . . 13 63 3.9. dearmor: Convert ASCII to binary . . . . . . . . . . . . 14 64 3.10. detach-inband-signature-and-message: split a clearsigned 65 message . . . . . . . . . . . . . . . . . . . . . . . . 14 66 4. Input String Types . . . . . . . . . . . . . . . . . . . . . 15 67 4.1. DATE . . . . . . . . . . . . . . . . . . . . . . . . . . 16 68 4.2. USERID . . . . . . . . . . . . . . . . . . . . . . . . . 16 69 5. Input/Output Indirect Types . . . . . . . . . . . . . . . . . 16 70 5.1. Special Designators for Indirect Types . . . . . . . . . 17 71 5.2. CERTS . . . . . . . . . . . . . . . . . . . . . . . . . . 17 72 5.3. KEYS . . . . . . . . . . . . . . . . . . . . . . . . . . 17 73 5.4. CIPHERTEXT . . . . . . . . . . . . . . . . . . . . . . . 18 74 5.5. SIGNATURES . . . . . . . . . . . . . . . . . . . . . . . 18 75 5.6. SESSIONKEY . . . . . . . . . . . . . . . . . . . . . . . 18 76 5.7. MICALG . . . . . . . . . . . . . . . . . . . . . . . . . 19 77 5.8. PASSWORD . . . . . . . . . . . . . . . . . . . . . . . . 19 78 5.9. VERIFICATIONS . . . . . . . . . . . . . . . . . . . . . . 19 79 5.10. DATA . . . . . . . . . . . . . . . . . . . . . . . . . . 20 80 6. Failure Modes . . . . . . . . . . . . . . . . . . . . . . . . 20 81 7. Alternate Interfaces . . . . . . . . . . . . . . . . . . . . 22 82 8. Guidance for Implementers . . . . . . . . . . . . . . . . . . 22 83 8.1. One OpenPGP Message at a Time . . . . . . . . . . . . . . 23 84 8.2. Simplified Subset of OpenPGP Message . . . . . . . . . . 23 85 8.3. Validate Signatures Only from Known Signers . . . . . . . 23 86 8.4. OpenPGP inputs can be either Binary or ASCII-armored . . 23 87 8.5. Detached Signatures . . . . . . . . . . . . . . . . . . . 24 88 8.6. Reliance on Supplied Certs and Keys . . . . . . . . . . . 25 89 8.7. Text is always UTF-8 . . . . . . . . . . . . . . . . . . 25 90 8.8. Passwords are Human-Readable . . . . . . . . . . . . . . 26 91 8.9. Be careful with Special Designators . . . . . . . . . . . 27 92 9. Guidance for Consumers . . . . . . . . . . . . . . . . . . . 27 93 9.1. Choosing between -as=text and -as=binary . . . . . . . . 28 94 9.2. Special Designators and Unusual Filenames . . . . . . . . 28 96 10. Security Considerations . . . . . . . . . . . . . . . . . . . 28 97 10.1. Signature Verification . . . . . . . . . . . . . . . . . 29 98 10.2. Compression . . . . . . . . . . . . . . . . . . . . . . 30 99 11. Privacy Considerations . . . . . . . . . . . . . . . . . . . 30 100 11.1. Object Security vs. Transport Security . . . . . . . . . 30 101 12. Document Considerations . . . . . . . . . . . . . . . . . . . 30 102 12.1. Document History . . . . . . . . . . . . . . . . . . . . 30 103 12.2. Future Work . . . . . . . . . . . . . . . . . . . . . . 32 104 13. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 33 105 14. References . . . . . . . . . . . . . . . . . . . . . . . . . 33 106 14.1. Normative References . . . . . . . . . . . . . . . . . . 33 107 14.2. Informative References . . . . . . . . . . . . . . . . . 34 108 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 35 110 1. Introduction 112 Different OpenPGP implementations have many different requirements, 113 which typically break down in two main categories: key/certificate 114 management and object security. 116 The purpose of this document is to provide a "stateless" interface 117 that primarily handles the object security side of things, and 118 assumes that secret key management and certificate management will be 119 handled some other way. 121 Isolating object security from key/certificate management should make 122 it easier to provide interoperability testing for the object security 123 side of OpenPGP implementations, as described in Section 1.3. 125 This document defines a generic stateless command-line interface for 126 dealing with OpenPGP messages, known here by the placeholder sop. It 127 aims for a minimal, well-structured API. 129 An OpenPGP implementation should not name its executable sop to 130 implement this specification. It just needs to provide a program 131 that conforms to this interface. 133 A sop implementation should leave no trace on the system, and its 134 behavior should not be affected by anything other than command-line 135 arguments and input. 137 Obviously, the user will need to manage their secret keys (and their 138 peers' certificates) somehow, but the goal of this interface is to 139 separate out that task from the task of interacting with OpenPGP 140 messages. 142 While this document identifies a command-line interface, the rough 143 outlines of this interface should also be amenable to relatively 144 straightforward library implementations in different languages. 146 1.1. Requirements Language 148 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 149 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 150 "OPTIONAL" in this document are to be interpreted as described in BCP 151 14 [RFC2119] [RFC8174] when, and only when, they appear in all 152 capitals, as shown here. 154 1.2. Terminology 156 This document uses the term "key" to refer exclusively to OpenPGP 157 Transferable Secret Keys (see section 11.2 of [RFC4880]). 159 It uses the term "certificate" to refer to OpenPGP Transferable 160 Public Key (see section 11.1 of [RFC4880]). 162 "Stateless" in "Stateless OpenPGP" means avoiding secret key and 163 certificate state. The user is responsible for managing all OpenPGP 164 certificates and secret keys themselves, and passing them to sop as 165 needed. The user should also not be concerned that any state could 166 affect the underlying operations. 168 OpenPGP revocations can have "Reason for Revocation" (section 169 5.2.3.23 of [RFC4880]), which can be either "soft" or "hard". The 170 set of "soft" reasons is: "Key is superseded" and "Key is retired and 171 no longer used". All other reasons (and revocations that do not 172 state a reason) are "hard" revocations. 174 1.3. Using sop in a Test Suite 176 If an OpenPGP implementation provides a sop interface, it can be used 177 to test interoperability (e.g., 178 [OpenPGP-Interoperability-Test-Suite]). 180 Such an interop test suite can, for example, use custom code (_not_ 181 sop) to generate a new OpenPGP object that incorporates new 182 primitives, and feed that object to a stable of sop implementations, 183 to determine whether those implementations can consume the new form. 185 Or, the test suite can drive each sop implementation with a simple 186 input, and observe which cryptographic primitives each implementation 187 chooses to use as it produces output. 189 2. Examples 191 These examples show no error checking, but give a flavor of how sop 192 might be used in practice from a shell. 194 The key and certificate files described in them (e.g. alice.sec) 195 could be for example those found in 196 [I-D.draft-bre-openpgp-samples-01]. 198 sop generate-key "Alice Lovelace " > alice.sec 199 sop extract-cert < alice.sec > alice.pgp 201 sop generate-key "Bob Babbage " > bob.sec 202 sop extract-cert < bob.sec > bob.pgp 204 sop sign --as=text alice.sec < statement.txt > statement.txt.asc 205 sop verify statement.txt.asc alice.pgp < statement.txt 207 sop encrypt --sign-with=alice.sec --as=mime bob.pgp < msg.eml > ciphertext.asc 208 sop decrypt bob.sec < ciphertext.asc > cleartext.eml 210 See Section 6 for more information about errors and error handling. 212 3. Subcommands 214 sop uses a subcommand interface, similar to those popularized by 215 systems like git and svn. 217 If the user supplies a subcommand that sop does not implement, it 218 fails with UNSUPPORTED_SUBCOMMAND. If a sop implementation does not 219 handle a supplied option for a given subcommand, it fails with 220 UNSUPPORTED_OPTION. 222 All subcommands that produce OpenPGP material on standard output 223 produce ASCII-armored (section 6 of [I-D.ietf-openpgp-rfc4880bis]) 224 objects by default (except for sop dearmor). These subcommands have 225 a --no-armor option, which causes them to produce binary OpenPGP 226 material instead. 228 All subcommands that accept OpenPGP material on input should be able 229 to accept either ASCII-armored or binary inputs (see Section 8.4) and 230 behave accordingly. 232 See Section 5 for details about how various forms of OpenPGP material 233 are expected to be structured. 235 3.1. version: Version Information 236 sop version [--backend|--extended] 238 * Standard Input: ignored 240 * Standard Output: version information 242 This subcommand emits version information as UTF-8-encoded text. 244 With no arguments, the version string emitted should contain the name 245 of the sop implementation, followed by a single space, followed by 246 the version number. A sop implementation should use a version number 247 that respects an established standard that is easily comparable and 248 parsable, like [SEMVER]. 250 If --backend is supplied, the implementation should produce a 251 comparable line of implementation and version information about the 252 primary underlying OpenPGP toolkit. 254 If --extended is supplied, the implementation may emit multiple lines 255 of version information. The first line MUST match the information 256 produced by a simple invocation, but the rest of the text has no 257 defined structure. 259 --backend and --extended are mutually-exclusive options. 261 Example: 263 $ sop version 264 ExampleSop 0.2.1 265 $ sop version --backend 266 LibExamplePGP 3.4.2 267 $ sop version --extended 268 ExampleSop 0.2.1 269 Running on MonkeyScript 4.5 270 LibExamplePGP 3.4.2 271 LibExampleCrypto 3.1.1 272 LibXCompression 4.0.2 273 See https://pgp.example/sop/ for more information 274 $ 276 3.2. generate-key: Generate a Secret Key 278 sop generate-key [--no-armor] [--] [USERID...] 280 * Standard Input: ignored 282 * Standard Output: KEYS (Section 5.3) 283 Generate a single default OpenPGP key with zero or more User IDs. 285 The generated secret key SHOULD be usable for as much of the sop 286 functionality as possible. In particular: 288 * It should be possible to extract an OpenPGP certificate from the 289 key in KEYS with sop extract-cert. 291 * The key in KEYS should be able to create signatures (with sop 292 sign) that are verifiable by using sop verify with the extracted 293 certificate. 295 * The key in KEYS should be able to decrypt messages (with sop 296 decrypt) that are encrypted by using sop encrypt with the 297 extracted certificate. 299 The detailed internal structure of the certificate is left to the 300 discretion of the sop implementation. 302 Example: 304 $ sop generate-key 'Alice Lovelace ' > alice.sec 305 $ head -n1 < alice.sec 306 -----BEGIN PGP PRIVATE KEY BLOCK----- 307 $ 309 3.3. extract-cert: Extract a Certificate from a Secret Key 311 sop extract-cert [--no-armor] 313 * Standard Input: KEYS (Section 5.3) 315 * Standard Output: CERTS (Section 5.2) 317 The output should contain one OpenPGP certificate in CERTS per 318 OpenPGP Transferable Secret Key found in KEYS. There is no guarantee 319 what order the CERTS will be in. 321 Example: 323 $ sop extract-cert < alice.sec > alice.pgp 324 $ head -n1 < alice.pgp 325 -----BEGIN PGP PUBLIC KEY BLOCK----- 326 $ 328 3.4. sign: Create Detached Signatures 329 sop sign [--no-armor] [--micalg-out=MICALG] 330 [--as={binary|text}] [--] KEYS [KEYS...] 332 * Standard Input: DATA (Section 5.10) 334 * Standard Output: SIGNATURES (Section 5.5) 336 Exactly one signature will be made by each key in the supplied KEYS 337 arguments. 339 --as defaults to binary. If --as=text and the input DATA is not 340 valid UTF-8 (Section 8.7), sop sign fails with EXPECTED_TEXT. 342 --as=binary SHOULD result in an OpenPGP signature of type 0x00 343 ("Signature of a binary document"). --as=text SHOULD result in an 344 OpenPGP signature of type 0x01 ("Signature of a canonical text 345 document"). See section 5.2.1 of [RFC4880] for more details. 347 When generating PGP/MIME messages ([RFC3156]), it is useful to know 348 what digest algorithm was used for the generated signature. When -- 349 micalg-out is supplied, sop sign emits the digest algorithm used to 350 the specified MICALG file in a way that can be used to populate the 351 micalg parameter for the Content-Type (see Section 5.7). If the 352 specified MICALG file already exists in the filesystem, sop sign will 353 fail with OUTPUT_EXISTS. 355 When signing with multiple keys, sop sign SHOULD use the same digest 356 algorithm for every signature generated in a single run, unless there 357 is some internal constraint on the KEYS objects. If --micalg-out is 358 requested, and multiple incompatibly-constrained KEYS objects are 359 supplied, sop sign MUST emit the empty string to the designated 360 MICALG. 362 If any key in the KEYS objects is not capable of producing a 363 signature, sop sign will fail with KEY_CANNOT_SIGN. 365 sop sign MUST NOT produce any extra signatures beyond those from KEYS 366 objects supplied on the command line. 368 Example: 370 $ sop sign --as=text alice.sec < message.txt > message.txt.asc 371 $ head -n1 < message.txt.asc 372 -----BEGIN PGP SIGNATURE----- 373 $ 375 3.5. verify: Verify Detached Signatures 376 sop verify [--not-before=DATE] [--not-after=DATE] 377 [--] SIGNATURES CERTS [CERTS...] 379 * Standard Input: DATA (Section 5.10) 381 * Standard Output: VERIFICATIONS (Section 5.9) 383 --not-before and --not-after indicate that signatures with dates 384 outside certain range MUST NOT be considered valid. 386 --not-before defaults to the beginning of time. Accepts the special 387 value - to indicate the beginning of time (i.e. no lower boundary). 389 --not-after defaults to the current system time (now). Accepts the 390 special value - to indicate the end of time (i.e. no upper boundary). 392 sop verify only returns OK if at least one certificate included in 393 any CERTS object made a valid signature in the range over the DATA 394 supplied. 396 For details about the valid signatures, the user MUST inspect the 397 VERIFICATIONS output. 399 If no CERTS are supplied, sop verify fails with MISSING_ARG. 401 If no valid signatures are found, sop verify fails with NO_SIGNATURE. 403 See Section 10.1 for more details about signature verification. 405 Example: 407 (In this example, we see signature verification succeed first, and 408 then fail on a modified version of the message.) 410 $ sop verify message.txt.asc alice.pgp < message.txt 411 2019-10-29T18:36:45Z EB85BB5FA33A75E15E944E63F231550C4F47E38E EB85BB5FA33A75E15E944E63F231550C4F47E38E signed by alice.pgp 412 $ echo $? 413 0 414 $ tr a-z A-Z < message.txt | sop verify message.txt.asc alice.pgp 415 $ echo $? 416 3 417 $ 419 3.6. encrypt: Encrypt a Message 420 sop encrypt [--as={binary|text|mime}] 421 [--no-armor] 422 [--with-password=PASSWORD...] 423 [--sign-with=KEYS...] 424 [--] [CERTS...] 426 * Standard Input: DATA (Section 5.10) 428 * Standard Output: CIPHERTEXT (Section 5.4) 430 --as defaults to binary. The setting of --as corresponds to the one 431 octet format field found in the Literal Data packet at the core of 432 the output CIPHERTEXT. If --as is set to binary, the octet is b 433 (0x62). If it is text, the format octet is u (0x75). If it is mime, 434 the format octet is m (0x6d). 436 --with-password enables symmetric encryption (and can be used 437 multiple times if multiple passwords are desired). If sop encrypt 438 encounters a PASSWORD which is not a valid UTF-8 string 439 (Section 8.7), or is otherwise not robust in its representation to 440 humans, it fails with PASSWORD_NOT_HUMAN_READABLE. If sop encrypt 441 sees trailing whitespace at the end of a PASSWORD, it will trim the 442 trailing whitespace before using the password. See Section 8.8 for 443 more discussion about passwords. 445 --sign-with creates exactly one signature by for each secret key 446 found in the supplied KEYS object (this can also be used multiple 447 times if signatures from keys found in separaate files are desired). 448 If any key in any supplied KEYS objects is not capable of producing a 449 signature, sop sign will fail with KEY_CANNOT_SIGN. 451 If --as is set to binary, then --sign-with will sign as a binary 452 document (OpenPGP signature type 0x00). 454 If --as is set to text, then --sign-with will sign as a canonical 455 text document (OpenPGP signature type 0x01). In this case, if the 456 input DATA is not valid UTF-8 (Section 8.7), sop encrypt fails with 457 EXPECTED_TEXT. 459 sop should only be invoked with --as=mime when the input DATA is a 460 MIME message ([RFC2045]. If --sign-with is supplied for such a 461 message, then if the input data is valid UTF-8, sop SHOULD sign as a 462 canonical text document (OpenPGP signature type 0x01). However, a 463 MIME message itself might not be valid UTF-8, for example, if a MIME 464 subpart contains a raw binary object. If --sign-with is supplied for 465 input DATA that is not valid UTF-8, sop encrypt MAY sign as a binary 466 document (OpenPGP signature type 0x00). 468 sop encrypt MUST NOT produce any extra signatures beyond those from 469 KEYS objects identified by --sign-with. 471 The resulting CIPHERTEXT should be decryptable by the secret keys 472 corresponding to every certificate included in all CERTS, as well as 473 each password given with --with-password. 475 If no CERTS or --with-password options are present, sop encrypt fails 476 with MISSING_ARG. 478 If at least one of the identified certificates requires encryption to 479 an unsupported asymmetric algorithm, sop encrypt fails with 480 UNSUPPORTED_ASYMMETRIC_ALGO. 482 If at least one of the identified certificates is not encryption- 483 capable (e.g., revoked, expired, no encryption-capable flags on 484 primary key and valid subkeys), sop encrypt fails with 485 CERT_CANNOT_ENCRYPT. 487 If sop encrypt fails for any reason, it emits no CIPHERTEXT. 489 Example: 491 (In this example, bob.bin is a file containing Bob's binary-formatted 492 OpenPGP certificate. Alice is encrypting a message to both herself 493 and Bob.) 495 $ sop encrypt --as=mime --sign-with=alice.key alice.asc bob.bin < message.eml > encrypted.asc 496 $ head -n1 encrypted.asc 497 -----BEGIN PGP MESSAGE----- 498 $ 500 3.7. decrypt: Decrypt a Message 502 sop decrypt [--session-key-out=SESSIONKEY] 503 [--with-session-key=SESSIONKEY...] 504 [--with-password=PASSWORD...] 505 [--verify-out=VERIFICATIONS 506 [--verify-with=CERTS...] 507 [--verify-not-before=DATE] 508 [--verify-not-after=DATE] ] 509 [--] [KEYS...] 511 * Standard Input: CIPHERTEXT (Section 5.4) 513 * Standard Output: DATA (Section 5.10) 514 The caller can ask sop for the session key discovered during 515 decryption by supplying the --session-key-out option. If the 516 specified file already exists in the filesystem, sop decrypt will 517 fail with OUTPUT_EXISTS. When decryption is successful, sop decrypt 518 writes the discovered session key to the specified file. 520 --with-session-key enables decryption of the CIPHERTEXT using the 521 session key directly against the SEIPD packet. This option can be 522 used multiple times if several possible session keys should be tried. 524 --with-password enables decryption based on any SKESK (section 5.3 of 525 [I-D.ietf-openpgp-rfc4880bis]) packets in the CIPHERTEXT. This 526 option can be used multiple times if the user wants to try more than 527 one password. 529 If sop decrypt tries and fails to use a supplied PASSWORD, and it 530 observes that there is trailing UTF-8 whitespace at the end of the 531 PASSWORD, it will retry with the trailing whitespace stripped. See 532 Section 8.8 for more discussion about passwords. 534 --verify-out produces signature verification status to the designated 535 file. If the designated file already exists in the filesystem, sop 536 decrypt will fail with OUTPUT_EXISTS. 538 The return code of sop decrypt is not affected by the results of 539 signature verification. The caller MUST check the returned 540 VERIFICATIONS to confirm signature status. An empty VERIFICATIONS 541 output indicates that no valid signatures were found. 543 --verify-with identifies a set of certificates whose signatures would 544 be acceptable for signatures over this message. 546 If the caller is interested in signature verification, both --verify- 547 out and at least one --verify-with must be supplied. If only one of 548 these arguments is supplied, sop decrypt fails with 549 INCOMPLETE_VERIFICATION. 551 --verify-not-before and --verify-not-after provide a date range for 552 acceptable signatures, by analogy with the options for sop verify 553 (see Section 3.5). They should only be supplied when doing signature 554 verification. 556 See Section 10.1 for more details about signature verification. 558 If no KEYS or --with-password or --with-session-key options are 559 present, sop decrypt fails with MISSING_ARG. 561 If unable to decrypt, sop decrypt fails with CANNOT_DECRYPT. 563 sop decrypt only emits cleartext to Standard Output that was 564 successfully decrypted. 566 Example: 568 (In this example, Alice stashes and re-uses the session key of an 569 encrypted message.) 571 $ sop decrypt --session-key-out=session.key alice.sec < ciphertext.asc > cleartext.out 572 $ ls -l ciphertext.asc cleartext.out 573 -rw-r--r-- 1 user user 321 Oct 28 01:34 ciphertext.asc 574 -rw-r--r-- 1 user user 285 Oct 28 01:34 cleartext.out 575 $ sop decrypt --with-session-key=session.key < ciphertext.asc > cleartext2.out 576 $ diff cleartext.out cleartext2.out 577 $ 579 3.8. armor: Convert binary to ASCII 581 sop armor [--label={auto|sig|key|cert|message}] 583 * Standard Input: OpenPGP material (SIGNATURES, KEYS, CERTS, or 584 CIPHERTEXT) 586 * Standard Output: the same material with ASCII-armoring added, if 587 not already present 589 The user can choose to specify the label used in the header and tail 590 of the armoring. 592 The default for --label is auto, in which case, sop inspects the 593 input and chooses the label appropriately, based on the type of the 594 first OpenPGP packet. If the type of the first OpenPGP packet is: 596 * 0x02 (Signature), the packet stream should be parsed as a 597 SIGNATURES input (with Armor Header BEGIN PGP SIGNATURE). 599 * 0x05 (Secret-Key), the packet stream should be parsed as a KEYS 600 input (with Armor Header BEGIN PGP PRIVATE KEY BLOCK). 602 * 0x06 (Public-Key), the packet stream should be parsed as a CERTS 603 input (with Armor Header BEGIN PGP PUBLIC KEY BLOCK). 605 * 0x01 (Public-key Encrypted Session Key) or 0x03 (Symmetric-key 606 Encrypted Session Key), the packet stream should be parsed as a 607 CIPHERTEXT input (with Armor Header BEGIN PGP MESSAGE). 609 If the input packet stream does not match the expected sequence of 610 packet types, sop armor fails with BAD_DATA. 612 Since sop armor accepts ASCII-armored input as well as binary input, 613 this operation is idempotent on well-structured data. A caller can 614 use this subcommand blindly ensure that any well-formed OpenPGP 615 packet stream is 7-bit clean. 617 Example: 619 $ sop armor < bob.bin > bob.pgp 620 $ head -n1 bob.pgp 621 -----BEGIN PGP PUBLIC KEY BLOCK----- 622 $ 624 3.9. dearmor: Convert ASCII to binary 626 sop dearmor 628 * Standard Input: OpenPGP material (SIGNATURES, KEYS, CERTS, or 629 CIPHERTEXT) 631 * Standard Output: the same material with any ASCII-armoring removed 633 If the input packet stream does not match any of the expected 634 sequence of packet types, sop dearmor fails with BAD_DATA. See also 635 Section 8.4. 637 Since sop dearmor accepts binary-formatted input as well as ASCII- 638 armored input, this operation is idempotent on well-structured data. 639 A caller can use this subcommand blindly ensure that any well-formed 640 OpenPGP packet stream is in its standard binary representation. 642 Example: 644 $ sop dearmor < message.txt.asc > message.txt.sig 645 $ 647 3.10. detach-inband-signature-and-message: split a clearsigned message 649 sop detach-inband-signature-and-message [--no-armor] --signatures-out=SIGNATURES 651 * Standard Input: DATA (clearsigned message) 653 * Standard Output: DATA (the message without the cleartext signature 654 framework) 656 In some contexts, the user may encounter a clearsigned ("inline PGP") 657 message (section 7 of [RFC4880]) rather than a message and its 658 detached signature. This subcommand takes such a clearsigned message 659 on standard input, and splits it into: 661 * the potentially signed material on standard output, and 663 * a detached signature block to the destination identified by -- 664 signatures-out 666 Note that no cryptographic verification of the signatures is done by 667 this subcommand. Once the clearsigned message is separated, 668 verification of the detached signature can be done with sop verify. 670 If no --signatures-out is supplied, sop detach-inband-signature-and- 671 message fails with MISSING_ARG. 673 Note that the signature block in a clearsigned message may contain 674 multiple signatures. All signatures found in the signature block 675 will be emitted to the --signatures-out destination. 677 The message body in the clearsigned message will be dash-escaped on 678 standard input (see section 7.1 of [RFC4880]). The output of sop 679 detach-inband-signature-and-message will have dash-escaping removed. 681 If the input DATA contains no clearsigned message, sop detach-inband- 682 signature-and-message fails with BAD_DATA. If the input DATA 683 contains more than one clearsigned message, sop detach-inband- 684 signature-and-message also fails with BAD_DATA. A sop implementation 685 MAY accept (and discard) leading and trailing data around the inline 686 PGP clearsigned message. 688 If the file designated by --signatures-out already exists in the 689 filesystem, sop detach-inband-signature-and-message will fail with 690 OUTPUT_EXISTS. 692 Note that --no-armor here governs the data written to the -- 693 signatures-out destination. Standard output is always the raw 694 message, not an OpenPGP packet. 696 Example: 698 $ sop detach-inband-signature-and-message --signatures-out=Release.pgp < InRelease >Release 699 $ sop verify Release.pgp archive-keyring.pgp < Release 700 $ 702 4. Input String Types 704 Some material is passed to sop directly as a string on the command 705 line. 707 4.1. DATE 709 An ISO-8601 formatted timestamp with time zone, or the special value 710 now to indicate the current system time. 712 Examples: 714 now 715 2019-10-29T12:11:04+00:00 716 2019-10-24T23:48:29Z 717 20191029T121104Z 719 In some cases where used to specify lower and upper boundaries, a 720 DATE value can be set to - to indicate "no time limit". 722 A flexible implementation of sop MAY accept date inputs in other 723 unambiguous forms. 725 Note that whenever sop emits a timestamp (e.g. in Section 5.9) it 726 MUST produce only a UTC-based ISO-8601 compliant representation. 728 4.2. USERID 730 This is an arbitrary UTF-8 string (Section 8.7). By convention, most 731 User IDs are of the form Display Name , 732 but they do not need to be. 734 5. Input/Output Indirect Types 736 Some material is passed to sop indirectly, typically by referring to 737 a filename containing the data in question. This type of data may 738 also be passed to sop on Standard Input, or delivered by sop to 739 Standard Output. 741 If any input data is specified explicitly to be read from a file that 742 does not exist, sop will fail with MISSING_INPUT. 744 If any input data does not meet the requirements described below, sop 745 will fail with BAD_DATA. 747 5.1. Special Designators for Indirect Types 749 An indirect argument or parameter that starts with "@" (COMMERCIAL 750 AT, U+0040) is not treated as a filename, but is reserved for special 751 handling, based on the prefix that follows the @. We describe two of 752 those prefixes (@ENV: and @FD:) here. A sop implementation that 753 receives such a special designator but does not know how to handle a 754 given prefix in that context MUST fail with 755 UNSUPPORTED_SPECIAL_PREFIX. 757 If the filename for any indirect material used as input has the 758 special form @ENV:xxx, then contents of environment variable $xxx is 759 used instead of looking in the filesystem. @ENV is for input only: if 760 the prefix @ENV: is used for any output argument, sop fails with 761 UNSUPPORTED_SPECIAL_PREFIX. 763 If the filename for any indirect material used as either input or 764 output has the special form @FD:nnn where nnn is a decimal integer, 765 then the associated data is read from file descriptor nnn. 767 See Section 8.9 for more details about safe handling of these special 768 designators. 770 5.2. CERTS 772 One or more OpenPGP certificates (section 11.1 of 773 [I-D.ietf-openpgp-rfc4880bis]), aka "Transferable Public Key". May 774 be armored (see Section 8.4). 776 Although some existing workflows may prefer to use one CERTS object 777 with multiple certificates in it (a "keyring"), supplying exactly one 778 certificate per CERTS input will make error reporting clearer and 779 easier. 781 5.3. KEYS 783 One or more OpenPGP Transferable Secret Keys (section 11.2 of 784 [I-D.ietf-openpgp-rfc4880bis]). May be armored (see Section 8.4). 786 Secret key material should be in cleartext (that is, it should not be 787 locked with a password). If any secret key material is locked with a 788 password, sop may fail with error KEY_IS_PROTECTED. 790 Although some existing workflows may prefer to use one KEYS object 791 with multiple keys in it (a "secret keyring"), supplying exactly one 792 key per KEYS input will make error reporting clearer and easier. 794 5.4. CIPHERTEXT 796 sop accepts only a restricted subset of the arbitrarily-nested 797 grammar allowed by the OpenPGP Messages definition (section 11.3 of 798 [I-D.ietf-openpgp-rfc4880bis]). 800 In particular, it accepts and generates only: 802 An OpenPGP message, consisting of a sequence of PKESKs (section 5.1 803 of [I-D.ietf-openpgp-rfc4880bis]) and SKESKs (section 5.3 of 804 [I-D.ietf-openpgp-rfc4880bis]), followed by one SEIPD (section 5.14 805 of [I-D.ietf-openpgp-rfc4880bis]). 807 The SEIPD can decrypt into one of two things: 809 * "Maybe Signed Data" (see below), or 811 * Compressed data packet that contains "Maybe Signed Data" 813 "Maybe Signed Data" is a sequence of: 815 * N (zero or more) one-pass signature packets, followed by 817 * zero or more signature packets, followed by 819 * one Literal data packet, followed by 821 * N signature packets (corresponding to the outer one-pass 822 signatures packets) 824 FIXME: does any tool do compression inside signing? Do we need to 825 handle that? 827 May be armored (see Section 8.4). 829 5.5. SIGNATURES 831 One or more OpenPGP Signature packets. May be armored (see 832 Section 8.4). 834 5.6. SESSIONKEY 836 This documentation uses the GnuPG defacto ASCII representation: 838 ALGONUM:HEXKEY 839 where ALGONUM is the decimal value associated with the OpenPGP 840 Symmetric Key Algorithms (section 9.3 of 841 [I-D.ietf-openpgp-rfc4880bis]) and HEXKEY is the hexadecimal 842 representation of the binary key. 844 Example AES-256 session key: 846 9:FCA4BEAF687F48059CACC14FB019125CD57392BAB7037C707835925CBF9F7BCD 848 5.7. MICALG 850 This output indicates the cryptographic digest used when making a 851 signature. It is useful specifically when generating signed PGP/MIME 852 objects, which want a micalg= parameter for the multipart/signed 853 content type as described in section 5 of [RFC3156]. 855 It will typically be a string like pgp-sha512, but in some situations 856 (multiple signatures using different digests) it will be the empty 857 string. If the user of sop is assembling a PGP/MIME signed object, 858 and the MICALG output is the empty string, the user should omit the 859 micalg= parameter entirely. 861 5.8. PASSWORD 863 This is expected to be a UTF-8 string (Section 8.7), but for sop 864 decrypt, any bytestring that the user supplies will be accepted. 865 Note the details in sop encrypt and sop decrypt about trailing 866 whitespace! 868 See also Section 8.8 for more discussion. 870 5.9. VERIFICATIONS 872 One line per successful signature verification. Each line has three 873 structured fields delimited by a single space, followed by arbitrary 874 text to the end of the line that forms a message describing the 875 verification. 877 * ISO-8601 UTC datestamp 879 * Fingerprint of the signing key (may be a subkey) 881 * Fingerprint of primary key of signing certificate (if signed by 882 primary key, same as the previous field) 884 * message describing the verification (free form) 885 Note that while Section 4.1 permits a sop implementation to accept 886 other unambiguous date representations, its date output here MUST be 887 a strict ISO-8601 UTC date timestamp. In particular: 889 * the date and time fields MUST be separated by T, not by 890 whitespace, since whitespace is used as a delimiter 892 * the time MUST be emitted in UTC, with the explicit suffix Z 894 Example: 896 2019-10-24T23:48:29Z C90E6D36200A1B922A1509E77618196529AE5FF8 C4BC2DDB38CCE96485EBE9C2F20691179038E5C6 certificate from dkg.asc 898 5.10. DATA 900 Cleartext, arbitrary data. This is either a bytestream or UTF-8 901 text. 903 It MUST only be UTF-8 text in the case of input supplied to sop sign 904 --as=text or sop encrypt --as={mime|text}. If sop receives DATA 905 containing non-UTF-8 octets in this case, it will fail (see 906 Section 8.7) with EXPECTED_TEXT. 908 6. Failure Modes 910 sop return codes have both mnemonics and numeric values. 912 When sop succeeds, it will return 0 (OK) and emit nothing to Standard 913 Error. When sop fails, it fails with a non-zero return code, and 914 emits one or more warning messages on Standard Error. Known return 915 codes include: 917 +=======+=============================+==========================+ 918 | Value | Mnemonic | Meaning | 919 +=======+=============================+==========================+ 920 | 0 | OK | Success | 921 +-------+-----------------------------+--------------------------+ 922 | 3 | NO_SIGNATURE | No acceptable signatures | 923 | | | found (sop verify) | 924 +-------+-----------------------------+--------------------------+ 925 | 13 | UNSUPPORTED_ASYMMETRIC_ALGO | Asymmetric algorithm | 926 | | | unsupported (sop | 927 | | | encrypt) | 928 +-------+-----------------------------+--------------------------+ 929 | 17 | CERT_CANNOT_ENCRYPT | Certificate not | 930 | | | encryption-capable | 931 | | | (e.g., expired, revoked, | 932 | | | unacceptable usage | 933 | | | flags) (sop encrypt) | 934 +-------+-----------------------------+--------------------------+ 935 | 19 | MISSING_ARG | Missing required | 936 | | | argument | 937 +-------+-----------------------------+--------------------------+ 938 | 23 | INCOMPLETE_VERIFICATION | Incomplete verification | 939 | | | instructions (sop | 940 | | | decrypt) | 941 +-------+-----------------------------+--------------------------+ 942 | 29 | CANNOT_DECRYPT | Unable to decrypt (sop | 943 | | | decrypt) | 944 +-------+-----------------------------+--------------------------+ 945 | 31 | PASSWORD_NOT_HUMAN_READABLE | Non-UTF-8 or otherwise | 946 | | | unreliable password (sop | 947 | | | encrypt) | 948 +-------+-----------------------------+--------------------------+ 949 | 37 | UNSUPPORTED_OPTION | Unsupported option | 950 +-------+-----------------------------+--------------------------+ 951 | 41 | BAD_DATA | Invalid data type (no | 952 | | | secret key where KEYS | 953 | | | expected, etc) | 954 +-------+-----------------------------+--------------------------+ 955 | 53 | EXPECTED_TEXT | Non-text input where | 956 | | | text expected | 957 +-------+-----------------------------+--------------------------+ 958 | 59 | OUTPUT_EXISTS | Output file already | 959 | | | exists | 960 +-------+-----------------------------+--------------------------+ 961 | 61 | MISSING_INPUT | Input file does not | 962 | | | exist | 963 +-------+-----------------------------+--------------------------+ 964 | 67 | KEY_IS_PROTECTED | A KEYS input is | 965 | | | protected (locked) with | 966 | | | a password, and sop | 967 | | | cannot unlock it | 968 +-------+-----------------------------+--------------------------+ 969 | 69 | UNSUPPORTED_SUBCOMMAND | Unsupported subcommand | 970 +-------+-----------------------------+--------------------------+ 971 | 71 | UNSUPPORTED_SPECIAL_PREFIX | An indirect parameter is | 972 | | | a special designator (it | 973 | | | starts with @) but sop | 974 | | | does not know how to | 975 | | | handle the prefix | 976 +-------+-----------------------------+--------------------------+ 977 | 73 | AMBIGUOUS_INPUT | A indirect input | 978 | | | parameter is a special | 979 | | | designator (it starts | 980 | | | with @), and a filename | 981 | | | matching the designator | 982 | | | is actually present | 983 +-------+-----------------------------+--------------------------+ 984 | 79 | KEY_CANNOT_SIGN | Key not signature- | 985 | | | capable (e.g., expired, | 986 | | | revoked, unacceptable | 987 | | | usage flags) (sop sign | 988 | | | and sop encrypt with -- | 989 | | | sign-with) | 990 +-------+-----------------------------+--------------------------+ 992 Table 1 994 If a sop implementation fails in some way not contemplated by this 995 document, it MAY return any non-zero error code, not only those 996 listed above. 998 7. Alternate Interfaces 1000 This draft primarily defines a command line interface, but future 1001 versions may try to outline a comparable idiomatic interface for C or 1002 some other widely-used programming language. 1004 Comparable idiomatic interfaces are already active in the wild for 1005 different programming languages, in particular: 1007 * Rust: [RUST-SOP] 1009 * Java: [SOP-JAVA] 1011 * Python: [PYTHON-SOP] 1013 These programmatic interfaces are typically coupled with a wrapper 1014 that can automatically generate a command-line tool compatible with 1015 this draft. 1017 An implemention that uses one of these languages should target the 1018 corresponding idiomatic interface for ease of development and 1019 interoperability. 1021 8. Guidance for Implementers 1023 sop uses a few assumptions that implementers might want to consider. 1025 8.1. One OpenPGP Message at a Time 1027 sop is intended to be a simple tool that operates on one OpenPGP 1028 object at a time. It should be composable, if you want to use it to 1029 deal with multiple OpenPGP objects. 1031 FIXME: discuss what this means for streaming. The stdio interface 1032 doesn't necessarily imply streamed output. 1034 8.2. Simplified Subset of OpenPGP Message 1036 While the formal grammar for OpenPGP Message is arbitrarily nestable, 1037 sop constrains itself to what it sees as a single "layer" (see 1038 Section 5.4). 1040 This is a deliberate choice, because it is what most consumers 1041 expect. Also, if an arbitrarily-nested structure is parsed with a 1042 recursive algorithm, this risks a denial of service vulnerability. 1043 sop intends to be implementable with a parser that defensively 1044 declines to do recursive descent into an OpenPGP Message. 1046 Note that an implementation of sop decrypt MAY choose to handle more 1047 complex structures, but if it does, it should document the other 1048 structures it handles and why it chooses to do so. We can use such 1049 documentation to improve future versions of this spec. 1051 8.3. Validate Signatures Only from Known Signers 1053 There are generally only a few signers who are relevant for a given 1054 OpenPGP message. When verifying signatures, sop expects that the 1055 caller can identify those relevant signers ahead of time. 1057 8.4. OpenPGP inputs can be either Binary or ASCII-armored 1059 OpenPGP material on input can be in either ASCII-armored or binary 1060 form. This is a deliberate choice because there are typical 1061 scenarios where the program can't predict which form will appear. 1062 Expecting the caller of sop to detect the form and adjust accordingly 1063 seems both redundant and error-prone. 1065 The simple way to detect possible ASCII-armoring is to see whether 1066 the high bit of the first octet is set: section 4.2 of [RFC4880] 1067 indicates that bit 7 is always one in the first octet of an OpenPGP 1068 packet. In standard ASCII-armor, the first character is "-" (HYPHEN- 1069 MINUS, U+002D), so the high bit should be cleared. 1071 When considering an input as ASCII-armored OpenPGP material, sop MAY 1072 reject an input based on any of the following variations (see section 1073 6.2 of [RFC4880] for precise definitions): 1075 * An unknown Armor Header Line 1077 * Any text before the Armor Header Line 1079 * Malformed lines in the Armor Headers section 1081 * Any non-whitespace data after the Armor Tail 1083 * Any Radix-64 encoded line with more than 76 characters 1085 * Invalid characters in the Radix-64-encoded data 1087 * An invalid Armor Checksum 1089 * A mismatch between the Armor Header Line and the Armor Tail 1091 For robustness, sop SHOULD be willing to ignore whitespace after the 1092 Armor Tail. 1094 When considering OpenPGP material as input, regardless of whether it 1095 is ASCII-armored or binary, sop SHOULD reject any material that 1096 doesn't produce a valid stream of OpenPGP packets. For example, sop 1097 SHOULD raise an error if an OpenPGP packet header is malformed, or if 1098 there is trailing garbage after the end of a packet. 1100 For a given type of OpenPGP input material (i.e., SIGNATURES, CERTS, 1101 KEYS, or CIPHERTEXT), sop SHOULD also reject any input that does not 1102 conform to the expected packet stream. See Section 5 for the 1103 expected packet stream for different types. 1105 8.5. Detached Signatures 1107 sop deals with detached signatures as the baseline form of OpenPGP 1108 signatures. 1110 The primary alternative to detached signatures is inline signatures, 1111 but handling an inline signature requires parsing to delimit the 1112 multiple parts of the document, including at least: 1114 * any preamble before the message 1116 * the inline message header (delimiter line, OpenPGP headers) 1118 * the message itself 1119 * the divider between the message and the signature (including any 1120 OpenPGP headers there) 1122 * the signature 1124 * the divider that terminates the signature 1126 * any suffix after the signature 1128 Note also that the preamble or the suffix might be arbitrary text, 1129 and might themselves contain OpenPGP messages (whether signatures or 1130 otherwise). 1132 If the parser that does this split differs in any way from the parser 1133 that does the verification, or parts of the message are confused, it 1134 would be possible to produce a verification status and an actual 1135 signed message that don't correspond to one another. 1137 Blurred boundary problems like this can produce ugly attacks similar 1138 to those found in [EFAIL]. 1140 8.6. Reliance on Supplied Certs and Keys 1142 A truly stateless implementation may find that it spends more time 1143 validating the internal consistency of certificates and keys than it 1144 does on the actual object security operations. 1146 For performance reasons, an implementation may choose to ignore 1147 validation on certificate and key material supplied to it. The 1148 security implications of doing so depend on how the certs and keys 1149 are managed outside of sop. 1151 8.7. Text is always UTF-8 1153 Various places in this specification require UTF-8 [RFC3629] when 1154 encoding text. sop implementations SHOULD NOT consider textual data 1155 in any other character encoding. 1157 OpenPGP Implementations MUST already handle UTF-8, because various 1158 parts of [RFC4880] require it, including: 1160 * User ID 1162 * Notation name 1164 * Reason for revocation 1166 * ASCII-armor Comment: header 1167 Dealing with messages in other charsets leads to weird security 1168 failures like [Charset-Switching], especially when the charset 1169 indication is not covered by any sort of cryptographic integrity 1170 check. Restricting textual data to UTF-8 universally across the 1171 OpenPGP ecosystem eliminates any such risk without losing 1172 functionality, since UTF-8 can encode all known characters. 1174 8.8. Passwords are Human-Readable 1176 Passwords are generally expected to be human-readable, as they are 1177 typically recorded and transmitted as human-visible, human- 1178 transferable strings. However, they are used in the OpenPGP protocol 1179 as bytestrings, so ensuring that there is a reliable bidirectional 1180 mapping between strings and bytes. The maximally robust behavior 1181 here is for sop encrypt to constrain the choice of passwords to 1182 strings that have such a mapping, and for sop decrypt to try multiple 1183 plausible versions of any supplied PASSWORD. 1185 When generating material based on a password, sop encrypt enforces 1186 that the password is actually meaningfully human-transferable 1187 (requiring UTF-8, trimming trailing whitespace). Some sop encrypt 1188 implementations may make even more strict requirements on input to 1189 ensure that they are transferable between humans in a robust way. 1191 For example, a more strict sop encrypt MAY also: 1193 * forbid leading whitespace 1195 * forbid non-printing characters other than SPACE (U+0020), such as 1196 ZERO WIDTH NON-JOINER (U+200C) or TAB (U+0009) 1198 * require the password to be in Unicode Normal Form C 1199 ([UNICODE-NORMALIZATION]) 1201 Violations of these more-strict policies SHOULD result in an error of 1202 PASSWORD_NOT_HUMAN_READABLE. 1204 A sop encrypt implementation typically SHOULD NOT attempt enforce a 1205 minimum "password strength", but in the event that some 1206 implementation does, it MUST NOT represent a weak password with 1207 PASSWORD_NOT_HUMAN_READABLE. 1209 When sop decrypt receives a PASSWORD input, it sees it as a 1210 bytestring. If the bytestring fails to work as a password, but ends 1211 in UTF-8 whitespace, it will try again with the trailing whitespace 1212 removed. This handles a common pattern of using a file with a final 1213 newline, for example. The pattern here is one of robustness in the 1214 face of typical errors in human-transferred textual data. 1216 A more robust sop decrypt implementation that finds neither of the 1217 above two attempts work for a given PASSWORD MAY try additional 1218 variations if they produce a different bytestring, such as: 1220 * trimming any leading whitespace, if discovered 1222 * trimming any internal non-printable characters other than SPACE 1223 (U+0020) 1225 * converting the supplied PASSWORD into Unicode Normal Form C 1226 ([UNICODE-NORMALIZATION]) 1228 A sop decrypt implementation that stages multiple decryption attempts 1229 like this SHOULD consider the computational resources consumed by 1230 each attempt, to avoid presenting an attack surface for resource 1231 exhaustion in the face of a non-standard PASSWORD input. 1233 8.9. Be careful with Special Designators 1235 As documented in Section 5.1, special designators for indirect inputs 1236 like @ENV: and @FD: (and indirect outputs using @FD:) warrant some 1237 special/cautious handling. 1239 For one thing, it's conceivable that the filesystem could contain a 1240 file with these literal names. If sop receives an indirect output 1241 parameter that starts with an "@" (COMMERCIAL AT, U+0040) it MUST NOT 1242 write to the filesystem for that parameter. A sop implementation 1243 that receives such a parameter as input MAY test for the presence of 1244 such a file in the filesystem and fail with AMBIGUOUS_INPUT to warn 1245 the user of the ambiguity and possible confusion. 1247 These special designators are likely to be used to pass sensitive 1248 data (like secret key material or passwords) so that it doesn't need 1249 to touch the filesystem. Given this sensitivity, sop should be 1250 careful with such an input, and minimize its leakage to other 1251 processes. In particular, sop SHOULD NOT leak any environment 1252 variable identified by @ENV: or file descriptor identified by @FD: to 1253 any subprocess unless the subprocess specifically needs access to 1254 that data. 1256 9. Guidance for Consumers 1258 While sop is originally conceived of as an interface for 1259 interoperability testing, it's conceivable that an application that 1260 uses OpenPGP for object security would want to use it. 1262 FIXME: more guidance for how to use such a tool safely and 1263 efficiently goes here. 1265 FIXME: if an encrypted OpenPGP message arrives without metadata, it 1266 is difficult to know which signers to consider when decrypting. How 1267 do we do this efficiently without invoking sop decrypt twice, once 1268 without --verify-* and again with the expected identity material? 1270 9.1. Choosing between -as=text and -as=binary 1272 A program that invokes sop to generate an OpenPGP signature typically 1273 needs to decide whether it is making a text or binary signature. 1275 By default, sop will make a binary signature. The caller of sop sign 1276 should choose --as=text only when it knows that: - the data being 1277 signed is in fact textual, and encoded in UTF-8, and - the signed 1278 data might be transmitted to the recipient (the verifier of the 1279 signature) over a channel that has the propensity to transform line- 1280 endings. 1282 Examples of such channels include FTP ([RFC0959]) and SMTP 1283 ([RFC5321]). 1285 9.2. Special Designators and Unusual Filenames 1287 In some cases, a user of sop might want to pass all the files in a 1288 given directory as positional parameters (e.g., a list of CERTS files 1289 to test a signature against). 1291 If one of the files has a name that starts with --, it might be 1292 confused by sop for an option. If one of the files has a name that 1293 starts with @, it might be confused by sop as a special designator 1294 (Section 5.1). 1296 If the user wants to deliberately refer to such an ambiguously-named 1297 file in the filesystem, they should prefix the filename with ./ or 1298 use an absolute path. 1300 Any specific @FD: special designator SHOULD NOT be supplied more than 1301 once to an invocation of sop. If a sop invocation sees multiple 1302 copies of a specific @FD:n input (e.g., sop sign @FD:3 @FD:3), it MAY 1303 fail with MISSING_INPUT even if file descriptor 3 contains a valid 1304 KEYS, because the bytestream for the KEYS was consumed by the first 1305 argument. Doubling up on the same @FD: for output (e.g., sop decrypt 1306 --session-key-out=@FD:3 --verify-out=@FD:3) also results in an 1307 ambiguous data stream. 1309 10. Security Considerations 1311 The OpenPGP object security model is typically used for 1312 confidentiality and authenticity purposes. 1314 10.1. Signature Verification 1316 In many contexts, an OpenPGP signature is verified to prove the 1317 origin and integrity of an underlying object. 1319 When sop checks a signature (e.g. via sop verify or sop decrypt -- 1320 verify-with), it MUST NOT consider it to be verified unless all of 1321 these conditions are met: 1323 * The signature must be made by a signing-capable public key that is 1324 present in one of the supplied certificates 1326 * The certificate and signing subkey must have been created before 1327 or at the signature time 1329 * The certificate and signing subkey must not have been expired at 1330 the signature time 1332 * The certificate and signing subkey must not be revoked with a 1333 "hard" revocation 1335 * If the certificate or signing subkey is revoked with a "soft" 1336 revocation, then the signature time must predate the revocation 1338 * The signing subkey must be properly bound to the primary key, and 1339 cross-signed 1341 * The signature (and any dependent signature, such as the cross-sig 1342 or subkey binding signatures) must be made with strong 1343 cryptographic algorithms (e.g., not MD5 or a 1024-bit RSA key) 1345 Implementers MAY also consider other factors in addition to the 1346 origin and authenticity, including application-specific information. 1348 For example, consider the application domain of checking software 1349 updates. If software package Foo version 13.3.2 was signed on 1350 2019-10-04, and the user receives a copy of Foo version 12.4.8 that 1351 was signed on 2019-10-16, it may be authentic and have a more recent 1352 signature date. But it is not an upgrade (12.4.8 < 13.3.2), and 1353 therefore it should not be applied automatically. 1355 In such cases, it is critical that the application confirms that the 1356 other information verified is _also_ protected by the relevant 1357 OpenPGP signature. 1359 Signature validity is a complex topic (see for example the discussion 1360 at [DISPLAYING-SIGNATURES]), and this documentation cannot list all 1361 possible details. 1363 10.2. Compression 1365 The interface as currently specified does not allow for control of 1366 compression. Compressing and encrypting data that may contain both 1367 attacker-supplied material and sensitive material could leak 1368 information about the sensitive material (see the CRIME attack). 1370 Unless an application knows for sure that no attacker-supplied 1371 material is present in the input, it should not compress during 1372 encryption. 1374 11. Privacy Considerations 1376 Material produced by sop encrypt may be placed on an untrusted 1377 machine (e.g., sent through the public SMTP network). That material 1378 may contain metadata that leaks associational information (e.g., 1379 recipient identifiers in PKESK packets (section 5.1 of 1380 [I-D.ietf-openpgp-rfc4880bis])). FIXME: document things like PURBs 1381 and --hidden-recipient) 1383 11.1. Object Security vs. Transport Security 1385 OpenPGP offers an object security model, but says little to nothing 1386 about how the secured objects get to the relevant parties. 1388 When sending or receiving OpenPGP material, the implementer should 1389 consider what privacy leakage is implicit with the transport. 1391 12. Document Considerations 1393 [ RFC Editor: please remove this section before publication ] 1395 This document is currently edited as markdown. Minor editorial 1396 changes can be suggested via merge requests at 1397 https://gitlab.com/dkg/openpgp-stateless-cli or by e-mail to the 1398 authors. Please direct all significant commentary to the public IETF 1399 OpenPGP mailing list: openpgp@ietf.org 1401 12.1. Document History 1403 substantive changes between -02 and -03: 1405 * Added --micalg-out parameter to sign 1407 * Change from KEY to KEYS (permit multiple secret keys in each blob) 1409 * New error code: KEY_CANNOT_SIGN 1410 * version now has --backend and --extended options 1412 substantive changes between -01 and -02: 1414 * Added mnemonics for return codes 1416 * decrypt should fail when asked to output to a pre-existing file 1418 * Removed superfluous --armor option 1420 * Much more specific about what armor --label=auto should do 1422 * armor and dearmor are now fully idempotent, but work only well- 1423 formed OpenPGP streams 1425 * Dropped armor --allow-nested 1427 * Specified what encrypt --as= means 1429 * New error code: KEY_IS_PROTECTED 1431 * Documented expectations around human-readable, human-transferable 1432 passwords 1434 * New subcommand: detach-inband-signature-and-message 1436 * More specific guidance about special designators like @FD: and 1437 @ENV:, including new error codes UNSUPPORTED_SPECIAL_PREFIX and 1438 AMBIGUOUS_INPUT 1440 substantive changes between -00 and -01: 1442 * Changed generate subcommand to generate-key 1444 * Changed convert subcommand to extract-cert 1446 * Added "Input String Types" section as distinct from indirect I/O 1448 * Made implicit arguments potentially explicit (e.g. sop armor 1449 --label=auto) 1451 * Added --allow-nested to sop armor to make it idempotent by default 1453 * Added fingerprint of signing (sub)key to VERIFICATIONS output 1455 * Dropped --mode and --session-key arguments for sop encrypt (no 1456 plausible use, not needed for interop) 1458 * Added --with-session-key argument to sop decrypt to allow for 1459 session-key-based decryption 1461 * Added examples to each subcommand 1463 * More detailed error codes for sop encrypt 1465 * Move from CERT to CERTS (each CERTS argument might contain 1466 multiple certificates) 1468 12.2. Future Work 1470 * certificate transformation into popular publication forms: 1472 - WKD 1474 - DANE OPENPGPKEY 1476 - Autocrypt 1478 * sop encrypt - specify compression? (see Section 10.2) 1480 * sop encrypt - specify padding policy/mechanism? 1482 * sop decrypt - how can it more safely handle zip bombs? 1484 * sop decrypt - what should it do when encountering weakly-encrypted 1485 (or unencrypted) input? 1487 * sop encrypt - minimize metadata (e.g. --throw-keyids)? 1489 * handling secret keys that are locked with passwords? 1491 * specify an error if a DATE arrives as input without a time zone? 1493 * add considerations about what it means for armored CERTS to 1494 contain multiple certificates - multiple armorings? one big blob? 1496 * do we need an interface or option (for performance?) with the 1497 semantics that sop doesn't validate certificates internally, it 1498 just accepts whatever's given as legit data? (see Section 8.6) 1500 * do we need to be able to assemble a clearsigned message? I'd 1501 rather not, given the additional complications. 1503 * does detach-inband-signature-and-message need to be able to split 1504 an OpenPGP signed message that _isn't_ using the clearsigned 1505 framework (e.g., the output of gpg --sign, in addition to handling 1506 gpg --clearsign)? 1508 13. Acknowledgements 1510 This work was inspired by Justus Winter's 1511 [OpenPGP-Interoperability-Test-Suite]. 1513 The following people contributed helpful feedback and considerations 1514 to this draft, but are not responsible for its problems: 1516 * Allan Nordhoey 1518 * Antoine Beaupre 1520 * Edwin Taylor 1522 * Jameson Rollins 1524 * Justus Winter 1526 * Paul Schaub 1528 * Vincent Breitmoser 1530 14. References 1532 14.1. Normative References 1534 [I-D.ietf-openpgp-rfc4880bis] 1535 Koch, W., carlson, B. M., Tse, R. H., Atkins, D., and D. 1536 K. Gillmor, "OpenPGP Message Format", Work in Progress, 1537 Internet-Draft, draft-ietf-openpgp-rfc4880bis-10, 31 1538 August 2020, . 1541 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 1542 Requirement Levels", BCP 14, RFC 2119, 1543 DOI 10.17487/RFC2119, March 1997, 1544 . 1546 [RFC3156] Elkins, M., Del Torto, D., Levien, R., and T. Roessler, 1547 "MIME Security with OpenPGP", RFC 3156, 1548 DOI 10.17487/RFC3156, August 2001, 1549 . 1551 [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 1552 10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, November 1553 2003, . 1555 [RFC4880] Callas, J., Donnerhacke, L., Finney, H., Shaw, D., and R. 1556 Thayer, "OpenPGP Message Format", RFC 4880, 1557 DOI 10.17487/RFC4880, November 2007, 1558 . 1560 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 1561 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 1562 May 2017, . 1564 14.2. Informative References 1566 [Charset-Switching] 1567 Gillmor, D.K., "Inline PGP Considered Harmful", 24 1568 February 2014, 1569 . 1571 [DISPLAYING-SIGNATURES] 1572 Brunschwig, P., "On Displaying Signatures", n.d., 1573 . 1576 [EFAIL] Poddebniak, D. and C. Dresen, "Efail: Breaking S/MIME and 1577 OpenPGP Email Encryption using Exfiltration Channels", 1578 n.d., . 1580 [I-D.draft-bre-openpgp-samples-01] 1581 Einarsson, B. R., "juga", and D. K. Gillmor, "OpenPGP 1582 Example Keys and Certificates", Work in Progress, 1583 Internet-Draft, draft-bre-openpgp-samples-01, 20 December 1584 2019, . 1587 [OpenPGP-Interoperability-Test-Suite] 1588 "OpenPGP Interoperability Test Suite", 25 October 2021, 1589 . 1591 [PYTHON-SOP] 1592 Gillmor, D., "SOP for python", n.d., 1593 . 1595 [RFC0959] Postel, J. and J. Reynolds, "File Transfer Protocol", 1596 STD 9, RFC 959, DOI 10.17487/RFC0959, October 1985, 1597 . 1599 [RFC2045] Freed, N. and N. Borenstein, "Multipurpose Internet Mail 1600 Extensions (MIME) Part One: Format of Internet Message 1601 Bodies", RFC 2045, DOI 10.17487/RFC2045, November 1996, 1602 . 1604 [RFC5321] Klensin, J., "Simple Mail Transfer Protocol", RFC 5321, 1605 DOI 10.17487/RFC5321, October 2008, 1606 . 1608 [RUST-SOP] Winter, J., "A Rust implementation of the Stateless 1609 OpenPGP Protocol", n.d., 1610 . 1612 [SEMVER] Preston-Werner, T., "Semantic Versioning 2.0.0", 18 June 1613 2013, . 1615 [SOP-JAVA] Schaub, P., "Stateless OpenPGP Protocol for Java.", n.d., 1616 . 1619 [UNICODE-NORMALIZATION] 1620 Whistler, K., "Unicode Normalization Forms", 4 February 1621 2019, . 1623 Author's Address 1625 Daniel Kahn Gillmor 1626 American Civil Liberties Union 1627 125 Broad St. 1628 New York, NY, 10004 1629 United States of America 1631 Email: dkg@fifthhorseman.net