idnits 2.17.1 draft-dkg-openpgp-stateless-cli-01.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 6 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 (October 29, 2019) is 1640 days in the past. Is this intentional? Checking references for intended status: Informational ---------------------------------------------------------------------------- == Missing Reference: '--' is mentioned on line 382, but not defined == Missing Reference: '--allow-nested' is mentioned on line 457, 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. Gillmor 3 Internet-Draft ACLU 4 Intended status: Informational October 29, 2019 5 Expires: May 1, 2020 7 Stateless OpenPGP Command Line Interface 8 draft-dkg-openpgp-stateless-cli-01 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 May 1, 2020. 33 Copyright Notice 35 Copyright (c) 2019 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 40 (https://trustee.ietf.org/license-info) in effect on the date of 41 publication of this document. Please review these documents 42 carefully, as they describe your rights and restrictions with respect 43 to this document. Code Components extracted from this document must 44 include Simplified BSD License text as described in Section 4.e of 45 the Trust Legal Provisions and are provided without warranty as 46 described in the Simplified BSD License. 48 Table of Contents 50 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 51 1.1. Requirements Language . . . . . . . . . . . . . . . . . . 3 52 1.2. Terminology . . . . . . . . . . . . . . . . . . . . . . . 4 53 2. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . 4 54 3. Subcommands . . . . . . . . . . . . . . . . . . . . . . . . . 4 55 3.1. version: Version Information . . . . . . . . . . . . . . 5 56 3.2. generate-key: Generate a Secret Key . . . . . . . . . . . 5 57 3.3. extract-cert: Extract a Certificate from a Secret Key . . 5 58 3.4. sign: Create a Detached Signature . . . . . . . . . . . . 6 59 3.5. verify: Verify a Detached Signature . . . . . . . . . . . 6 60 3.6. encrypt: Encrypt a Message . . . . . . . . . . . . . . . 7 61 3.7. decrypt: Decrypt a Message . . . . . . . . . . . . . . . 8 62 3.8. armor: Add ASCII Armor . . . . . . . . . . . . . . . . . 10 63 3.9. dearmor: Remove ASCII Armor . . . . . . . . . . . . . . . 11 64 4. Input String Types . . . . . . . . . . . . . . . . . . . . . 11 65 4.1. DATE . . . . . . . . . . . . . . . . . . . . . . . . . . 11 66 4.2. USERID . . . . . . . . . . . . . . . . . . . . . . . . . 12 67 5. Input/Output Indirect Types . . . . . . . . . . . . . . . . . 12 68 5.1. CERTS . . . . . . . . . . . . . . . . . . . . . . . . . . 12 69 5.2. KEY . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 70 5.3. CIPHERTEXT . . . . . . . . . . . . . . . . . . . . . . . 13 71 5.4. SIGNATURE . . . . . . . . . . . . . . . . . . . . . . . . 13 72 5.5. SESSIONKEY . . . . . . . . . . . . . . . . . . . . . . . 13 73 5.6. PASSWORD . . . . . . . . . . . . . . . . . . . . . . . . 14 74 5.7. VERIFICATIONS . . . . . . . . . . . . . . . . . . . . . . 14 75 5.8. DATA . . . . . . . . . . . . . . . . . . . . . . . . . . 14 76 6. Failure modes . . . . . . . . . . . . . . . . . . . . . . . . 14 77 7. Guidance for Implementors . . . . . . . . . . . . . . . . . . 15 78 7.1. One OpenPGP Message At a Time . . . . . . . . . . . . . . 15 79 7.2. Simplified Subset of OpenPGP Message . . . . . . . . . . 16 80 7.3. Validate Signatures Only From Known Signers . . . . . . . 16 81 7.4. Detached Signatures . . . . . . . . . . . . . . . . . . . 16 82 7.5. Reliance on Supplied Certs and Keys . . . . . . . . . . . 16 83 8. Guidance for Consumers . . . . . . . . . . . . . . . . . . . 16 84 9. Security Considerations . . . . . . . . . . . . . . . . . . . 17 85 9.1. Signature Verification . . . . . . . . . . . . . . . . . 17 86 9.2. Compression . . . . . . . . . . . . . . . . . . . . . . . 18 87 10. Privacy Considerations . . . . . . . . . . . . . . . . . . . 18 88 10.1. Object Security vs. Transport Security . . . . . . . . . 18 89 11. Document Considerations . . . . . . . . . . . . . . . . . . . 18 90 11.1. Document History . . . . . . . . . . . . . . . . . . . . 19 91 11.2. Future Work . . . . . . . . . . . . . . . . . . . . . . 19 92 12. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 20 93 13. References . . . . . . . . . . . . . . . . . . . . . . . . . 20 94 13.1. Normative References . . . . . . . . . . . . . . . . . . 21 95 13.2. Informative References . . . . . . . . . . . . . . . . . 21 97 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 21 99 1. Introduction 101 Different OpenPGP implementations have many different requirements, 102 which typically break down in two main categories: key/certificate 103 management and object security. 105 The purpose of this document is to provide a "stateless" interface 106 that primarily handles the object security side of things, and 107 assumes that secret key management and certificate management will be 108 handled some other way. 110 This separation should make it easier to provide interoperability 111 testing for the object security work, and to allow implementations to 112 consume and produce new cryptographic primitives as needed. 114 This document defines a generic stateless command-line interface for 115 dealing with OpenPGP messages, known here by the placeholder "sop". 116 It aims for a minimal, well-structured API. 118 An OpenPGP implementation should not name its executable "sop" to 119 implement this specification, of course. It just needs to provide a 120 binary that conforms to this interface. 122 A "sop" implementation should leave no trace on the system, and its 123 behavior should not be affected by anything other than command-line 124 arguments and input. 126 Obviously, the user will need to manage their secret keys (and their 127 peers' certificates) somehow, but the goal of this interface is to 128 separate out that task from the task of interacting with OpenPGP 129 messages. 131 While this document identifies a command-line interface, the rough 132 outlines of this interface should also be amenable to relatively 133 straightforward library implementations in different languages. 135 1.1. Requirements Language 137 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 138 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 139 "OPTIONAL" in this document are to be interpreted as described in BCP 140 14 [RFC2119] [RFC8174] when, and only when, they appear in all 141 capitals, as shown here. 143 1.2. Terminology 145 This document uses the term "key" to refer exclusively to OpenPGP 146 Transferable Secret Keys (see section 11.2 of [RFC4880]). 148 It uses the term "certificate" to refer to OpenPGP Transferable 149 Public Key (see section 11.1 of [RFC4880]). 151 "Stateless" in "Stateless OpenPGP" means avoiding secret key and 152 certificate state. The user is responsible for managing all OpenPGP 153 certificates and secret keys themselves, and passing them to "sop" as 154 needed. The user should also not be concerned that any state could 155 affect the underlying operations. 157 OpenPGP revocations can have "Reason for Revocation" (section 158 5.2.3.23 of [RFC4880]), which can be either "soft" or "hard". The 159 set of "soft" reasons is: "Key is superseded" and "Key is retired and 160 no longer used". All other reasons (and revocations that do not 161 state a reason) are "hard" revocations. 163 2. Examples 165 These examples show no error checking, but give a flavor of how "sop" 166 might be used in practice from a shell. 168 The key and certificate files described in them (e.g. "alice.sec") 169 could be for example those found in 170 [I-D.draft-bre-openpgp-samples-00]. 172 sop generate-key "Alice Lovelace " > alice.sec 173 sop extract-cert < alice.sec > alice.pgp 175 sop sign --as=text alice.sec < announcement.txt > announcement.txt.asc 176 sop verify announcement.txt.asc alice.pgp < announcement.txt 178 sop encrypt --sign-with=alice.sec --as=mime bob.pgp < msg.eml > encrypted.asc 179 sop decrypt alice.sec < ciphertext.asc > cleartext.out 181 3. Subcommands 183 "sop" uses a subcommand interface, similar to those popularized by 184 systems like "git" and "svn". 186 If the user supplies a subcommand that "sop" does not implement, it 187 fails with a return code of 69. If a "sop" implementation does not 188 handle a supplied option for a given subcommand, it fails with a 189 return code of 37. 191 For all commands that have an "--armor|--no-armor" option, it 192 defaults to "--armor", meaning that any output OpenPGP material 193 should be ASCII-armored (section 6 of [I-D.ietf-openpgp-rfc4880bis]) 194 by default. 196 3.1. version: Version Information 198 sop version 200 o Standard Input: ignored 202 o Standard Output: version string 204 The version string emitted should contain the name of the "sop" 205 implementation, followed by a single space, followed by the version 206 number. 208 Example: 210 $ sop version 211 ExampleSop 0.2.1 212 $ 214 3.2. generate-key: Generate a Secret Key 216 sop generate-key [--armor|--no-armor] [--] [USERID...] 218 o Standard Input: ignored 220 o Standard Output: "KEY" (Section 5.2) 222 Generate a single default OpenPGP certificate with zero or more User 223 IDs. 225 Example: 227 $ sop generate-key 'Alice Lovelace ' > alice.sec 228 $ head -n1 < alice.sec 229 -----BEGIN PGP PRIVATE KEY BLOCK----- 230 $ 232 3.3. extract-cert: Extract a Certificate from a Secret Key 234 sop extract-cert [--armor|--no-armor] 236 o Standard Input: "KEY" (Section 5.2) 238 o Standard Output: "CERTS" (Section 5.1) 239 Note that the resultant "CERTS" object will only ever contain one 240 OpenPGP certificate. 242 Example: 244 $ sop extract-cert < alice.sec > alice.pgp 245 $ head -n1 < alice.pgp 246 -----BEGIN PGP PUBLIC KEY BLOCK----- 247 $ 249 3.4. sign: Create a Detached Signature 251 sop sign [--armor|--no-armor] 252 [--as={binary|text}] [--] KEY [KEY...] 254 o Standard Input: "DATA" (Section 5.8) 256 o Standard Output: "SIGNATURE" (Section 5.4) 258 "--as" defaults to "binary". If "--as=text" and the input "DATA" is 259 not valid "UTF-8", "sop sign" fails with a return code of 53. 261 Example: 263 $ sop sign --as=text alice.sec < message.txt > message.txt.asc 264 $ head -n1 < message.txt.asc 265 -----BEGIN PGP SIGNATURE----- 266 $ 268 3.5. verify: Verify a Detached Signature 270 sop verify [--not-before=DATE] [--not-after=DATE] 271 [--] SIGNATURE CERTS [CERTS...] 273 o Standard Input: "DATA" (Section 5.8) 275 o Standard Output: "VERIFICATIONS" (Section 5.7) 277 "--not-before" and "--not-after" indicate that signatures with dates 278 outside certain range MUST NOT be considered valid. 280 "--not-before" defaults to the beginning of time. Accepts the 281 special value "-" to indicate the beginning of time (i.e. no lower 282 boundary). 284 "--not-after" defaults to the current system time ("now"). Accepts 285 the special value "-" to indicate the end of time (i.e. no upper 286 boundary). 288 "sop verify" only returns 0 if at least one certificate included in 289 any "CERTS" object made a valid signature in the range over the 290 "DATA" supplied. 292 For details about the valid signatures, the user MUST inspect the 293 "VERIFICATIONS" output. 295 If no "CERTS" are supplied, "sop verify" fails with a return code of 296 19. 298 If no valid signatures are found, "sop verify" fails with a return 299 code of 3. 301 See Section 9.1 for more details about signature verification. 303 Example: 305 (In this example, we see signature verification succeed first, and 306 then fail on a modified version of the message.) 308 $ sop verify message.txt.asc alice.pgp < message.txt 309 2019-10-29T18:36:45Z EB85BB5FA33A75E15E944E63F231550C4F47E38E EB85BB5FA33A75E15E944E63F231550C4F47E38E signed by alice.pgp 310 $ echo $? 311 0 312 $ tr a-z A-Z < message.txt | sop verify message.txt.asc alice.pgp 313 $ echo $? 314 3 315 $ 317 3.6. encrypt: Encrypt a Message 319 sop encrypt [--as={binary|text|mime}] 320 [--armor|--no-armor] 321 [--with-password=PASSWORD...] 322 [--sign-with=KEY...] 323 [--] [CERTS...] 325 o Standard Input: "DATA" (Section 5.8) 327 o Standard Output: "CIPHERTEXT" (Section 5.3) 329 "--as" defaults to "binary". 331 "--with-password" enables symmetric encryption (and can be used 332 multiple times if multiple passwords are desired). If "sop encrypt" 333 encounters a "PASSWORD" which is not a valid "UTF-8" string, it fails 334 with a return code of 31. If "sop encrypt" sees trailing whitespace 335 at the end of a "PASSWORD", it will trim the trailing whitespace 336 before using the password. 338 "--sign-with" enables signing by a secret key (and can be used 339 multiple times if multiple signatures are desired). 341 If "--as" is set to either "text" or "mime", then "--sign-with" will 342 sign as a canonical text document. In this case, if the input "DATA" 343 is not valid "UTF-8", "sop encrypt" fails with a return code of 53. 345 The resulting "CIPHERTEXT" should be decryptable by the secret keys 346 corresponding to every certificate included in all "CERTS", as well 347 as each password given with "--with-password". 349 If no "CERTS" or "--with-password" options are present, "sop encrypt" 350 fails with a return code of 19. 352 If at least one of the identified certificates requires encryption to 353 an unsupported asymmetric algorithm, "sop encrypt" fails with a 354 return code of 13. 356 If at least one of the identified certificates is not encryption- 357 capable (e.g., revoked, expired, no encryption-capable flags on 358 primary key and valid subkeys), "sop encrypt" fails with a return 359 code of 17. 361 If "sop encrypt" fails for any reason, it emits no "CIPHERTEXT". 363 Example: 365 (In this example, "bob.bin" is a file containing Bob's binary- 366 formatted OpenPGP certificate. Alice is encrypting a message to both 367 herself and Bob.) 369 $ sop encrypt --as=mime --sign-with=alice.key alice.asc bob.bin < message.eml > encrypted.asc 370 $ head -n1 encrypted.asc 371 -----BEGIN PGP MESSAGE----- 372 $ 374 3.7. decrypt: Decrypt a Message 375 sop decrypt [--session-key-out=SESSIONKEY] 376 [--with-session-key=SESSIONKEY...] 377 [--with-password=PASSWORD...] 378 [--verify-out=VERIFICATIONS 379 [--verify-with=CERTS...] 380 [--verify-not-before=DATE] 381 [--verify-not-after=DATE] ] 382 [--] [KEY...] 384 o Standard Input: "CIPHERTEXT" (Section 5.3) 386 o Standard Output: "DATA" (Section 5.8) 388 "--session-key-out" can be used to learn the session key on 389 successful decryption. 391 If "sop decrypt" fails for any reason and the identified "--session- 392 key-out" file already exists in the filesystem, the file will be 393 unlinked. 395 "--with-session-key" enables decryption of the "CIPHERTEXT" using the 396 session key directly against the "SEIPD" packet. This option can be 397 used multiple times if several possible session keys should be tried. 399 "--with-password" enables decryption based on any "SKESK" packets in 400 the "CIPHERTEXT". This option can be used multiple times if the user 401 wants to try more than one password. 403 If "sop decrypt" tries and fails to use a supplied "PASSWORD", and it 404 observes that there is trailing "UTF-8" whitespace at the end of the 405 "PASSWORD", it will retry with the trailing whitespace stripped. 407 "--verify-out" produces signature verification status to the 408 designated file. 410 "sop decrypt" does not fail (that is, the return code is not 411 modified) based on the results of signature verification. The caller 412 MUST check the returned "VERIFICATIONS" to confirm signature status. 413 An empty "VERIFICATIONS" output indicates that no valid signatures 414 were found. If "sop decrypt" itself fails for any reason, and the 415 identified "VERIFICATIONS" file already exists in the filesystem, the 416 file will be unlinked. 418 "--verify-with" identifies a set of certificates whose signatures 419 would be acceptable for signatures over this message. 421 If the caller is interested in signature verification, both "-- 422 verify-out" and at least one "--verify-with" must be supplied. If 423 only one of these arguments is supplied, "sop decrypt" fails with a 424 return code of 23. 426 "--verify-not-before" and "--verify-not-after" provide a date range 427 for acceptable signatures, by analogy with the options for "sop 428 verify" (see Section 3.5). They should only be supplied when doing 429 signature verification. 431 See Section 9.1 for more details about signature verification. 433 If no "KEY" or "--with-password" or "--with-session-key" options are 434 present, "sop decrypt" fails with a return code of 19. 436 If unable to decrypt, "sop decrypt" fails with a return code of 29. 438 "sop decrypt" only returns cleartext to Standard Output that was 439 successfully decrypted. 441 Example: 443 (In this example, Alice stashes and re-uses the session key of an 444 encrypted message.) 446 $ sop decrypt --session-key-out=session.key alice.sec < ciphertext.asc > cleartext.out 447 $ ls -l ciphertext.asc cleartext.out 448 -rw-r--r-- 1 user user 321 Oct 28 01:34 ciphertext.asc 449 -rw-r--r-- 1 user user 285 Oct 28 01:34 cleartext.out 450 $ sop decrypt --with-session-key=session.key < ciphertext.asc > cleartext2.out 451 $ diff cleartext.out cleartext2.out 452 $ 454 3.8. armor: Add ASCII Armor 456 sop armor [--label={auto|sig|key|cert|message}] 457 [--allow-nested] 459 o Standard Input: 8-bit, unarmored OpenPGP material ("SIGNATURE", 460 "CERTS", "KEY", or "CIPHERTEXT") 462 o Standard Output: the same material with ASCII-armoring added 464 The user can choose to specify the label used in the header and tail 465 of the armoring. The default is "auto", in which case, "sop" 466 inspects the input and chooses the label appropriately. In this 467 case, if "sop" cannot select a label on the basis of the input, it 468 treats it as literal data, and labels it as a "message". 470 If the incoming data is already armored, and the "--allow-nested" 471 flag is not specified, the data MUST be output with no modifications. 472 Data is considered ASCII armored iff the first 14 bytes are exactly " 473 -----BEGIN PGP". This operation is thus idempotent by default. 475 Example: 477 $ sop armor < bob.bin > bob.pgp 478 $ head -n1 bob.pgp 479 -----BEGIN PGP PUBLIC KEY BLOCK----- 480 $ 482 3.9. dearmor: Remove ASCII Armor 484 sop dearmor 486 o Standard Input: ASCII-armored OpenPGP material ("CIPHERTEXT", 487 "SIGNATURE", "CERTS", or "KEY") 489 o Standard Output: the same material with ASCII-armoring removed 491 Example: 493 $ sop dearmor < message.txt.asc > message.txt.sig 494 $ 496 4. Input String Types 498 Some material is passed to "sop" directly as a string on the command 499 line. 501 4.1. DATE 503 An ISO-8601 formatted timestamp with time zone, or the special value 504 "now" to indicate the current system time. 506 Examples: 508 now 509 2019-10-29T12:11:04+00:00 510 2019-10-24T23:48:29Z 511 20191029T121104Z 513 In some cases where used to specify lower and upper boundaries, a 514 "DATE" value can be set to "-" to indicate "no time limit". 516 A flexible implementation of "sop" MAY accept date inputs in other 517 unambiguous forms. 519 4.2. USERID 521 This is an arbitrary "UTF-8" string. By convention, most User IDs 522 are of the form "Display Name ", but they 523 do not need to be. 525 5. Input/Output Indirect Types 527 Some material is passed to "sop" indirectly, typically by referring 528 to a filename containing the data in question. This type of data may 529 also be passed to "sop" on Standard Input, or delivered by "sop" to 530 Standard Output. 532 If the filename for any indirect material used as input has the 533 special form "@ENV:xxx", then contents of environment variable "$xxx" 534 is used instead of looking in the filesystem. 536 If the filename for any indirect material used as either input or 537 output has the special form "@FD:nnn" where "nnn" is a decimal 538 integer, then the associated data is read from file descriptor "nnn". 540 If any input data does not meet the requirements described below, 541 "sop" will fail with a return code of 41. 543 5.1. CERTS 545 One or more OpenPGP certificates (section 11.1 of 546 [I-D.ietf-openpgp-rfc4880bis]), aka "Transferable Public Key". May 547 be armored. 549 Although some existing workflows may prefer to use one "CERTS" object 550 with multiple certificates in it (a "keyring"), supplying exactly one 551 certificate per "CERTS" input will make error reporting clearer and 552 easier. 554 5.2. KEY 556 Exactly one OpenPGP Transferable Secret Key (section 11.2 of 557 [I-D.ietf-openpgp-rfc4880bis]). May be armored. 559 Secret key material should be in cleartext (that is, it should not be 560 locked with a password). If the secret key maerial is locked with a 561 password, "sop" may fail to use the key. 563 5.3. CIPHERTEXT 565 "sop" accepts only a restricted subset of the arbitrarily-nested 566 grammar allowed by the OpenPGP Messages definition (section 11.3 of 567 [I-D.ietf-openpgp-rfc4880bis]). 569 In particular, it accepts and generates only: 571 An OpenPGP message, consisting of a sequence of PKESKs (section 5.1 572 of [I-D.ietf-openpgp-rfc4880bis]) and SKESKs (section 5.3 of 573 [I-D.ietf-openpgp-rfc4880bis]), followed by one SEIPD (section 5.14 574 of [I-D.ietf-openpgp-rfc4880bis]). 576 The SEIPD can decrypt into one of two things: 578 o "Maybe Signed Data" (see below), or 580 o Compressed data packet that contains "Maybe Signed Data" 582 "Maybe Signed Data" is a sequence of: 584 o N (zero or more) one-pass signature packets, followed by 586 o zero or more signature packets, followed by 588 o one Literal data packet, followed by 590 o N signature packets (corresponding to the outer one-pass 591 signatures packets) 593 FIXME: does any tool do compression inside signing? Do we need to 594 handle that? 596 May be armored. 598 5.4. SIGNATURE 600 One or more OpenPGP Signature packets. May be armored. 602 5.5. SESSIONKEY 604 This documentation uses the GnuPG defacto "ASCII" representation: 606 "ALGONUM:HEXKEY" 608 where "ALGONUM" is the decimal value associated with the OpenPGP 609 Symmetric Key Algorithms (section 9.3 of 610 [I-D.ietf-openpgp-rfc4880bis]). 612 Example AES-256 session key: 614 9:FCA4BEAF687F48059CACC14FB019125CD57392BAB7037C707835925CBF9F7BCD 616 5.6. PASSWORD 618 This is expected to be a "UTF-8" string, but for "sop decrypt", any 619 bytestring that the user supplies will be accepted. Note the details 620 in "sop encrypt" and "sop decrypt" about trailing whitespace! 622 5.7. VERIFICATIONS 624 One line per successful signature verification. Each line has three 625 structured fields delimited by a single space, followed by arbitrary 626 text to the end of the line. 628 o ISO-8601 UTC datestamp 630 o Fingerprint of the signing key (may be a subkey) 632 o Fingerprint of primary key of signing certificate (if signed by 633 primary key, same as the previous field) 635 o arbitrary text 637 Example: 639 2019-10-24T23:48:29Z C90E6D36200A1B922A1509E77618196529AE5FF8 C4BC2DDB38CCE96485EBE9C2F20691179038E5C6 certificate from dkg.asc 641 5.8. DATA 643 Cleartext, arbitrary data. This is either a bytestream or "UTF-8" 644 text. 646 It MUST only be "UTF-8" text in the case of input supplied to "sop 647 sign --as=text" or "sop encrypt --as={mime|text}". If "sop" receives 648 "DATA" containing non-"UTF-8" octets in this case, it will fail with 649 return code 53. 651 6. Failure modes 653 When "sop" succeeds, it will return 0 and emit nothing to Standard 654 Error. When "sop" fails, it fails with a non-zero return code, and 655 emits one or more warning messages on Standard Error. Known return 656 codes include: 658 +--------+----------------------------------------------------------+ 659 | Return | Meaning | 660 +--------+----------------------------------------------------------+ 661 | 0 | Success | 662 | | | 663 | 3 | No acceptable signatures found ("sop verify") | 664 | | | 665 | 13 | Asymmetric algorithm unsupported ("sop encrypt") | 666 | | | 667 | 17 | Certificate not encryption-capable (e.g., expired, | 668 | | revoked, unacceptable usage flags) ("sop encrypt") | 669 | | | 670 | 19 | Missing required argument | 671 | | | 672 | 23 | Incomplete verification instructions ("sop decrypt") | 673 | | | 674 | 29 | Unable to decrypt ("sop decrypt") | 675 | | | 676 | 31 | Non-"UTF-8" password ("sop encrypt") | 677 | | | 678 | 37 | Unsupported option | 679 | | | 680 | 41 | Invalid data type (no secret key where "KEY" expected, | 681 | | etc) | 682 | | | 683 | 53 | Non-text input where text expected | 684 | | | 685 | 69 | Unsupported subcommand | 686 +--------+----------------------------------------------------------+ 688 A "sop" implementation MAY return other error codes than those listed 689 above. 691 7. Guidance for Implementors 693 "sop" uses a few assumptions that implementers might want to 694 consider. 696 7.1. One OpenPGP Message At a Time 698 "sop" is intended to be a simple tool that operates on one OpenPGP 699 object at a time. It should be composable, if you want to use it to 700 deal with multiple OpenPGP objects 702 FIXME: discuss what this means for streaming. The stdio interface 703 doesn't necessarily imply streamed output. 705 7.2. Simplified Subset of OpenPGP Message 707 While the formal grammar for OpenPGP Message is arbitrarily 708 nestable,"sop" constrains itself to what it sees as a single "layer" 709 (see Section 5.3). 711 This is a deliberate choice, because it is what most consumers 712 expect, and runaway recursion is bad news. 714 Note that an implementation of "sop decrypt" MAY choose to handle 715 more complex structures, but if it does, it should document the other 716 structures it handles and why it chooses to do so. We can use such 717 documentation to improve future versions of this spec. 719 7.3. Validate Signatures Only From Known Signers 721 There are generally only a few signers who are relevant for a given 722 OpenPGP message. When verifying signatures, "sop" expects that the 723 caller can identify those relevant signers ahead of time. 725 7.4. Detached Signatures 727 "sop" deals with detached signatures as the baseline form of OpenPGP 728 signatures. 730 The main problem this avoids is the trickiness of handling a 731 signature that is mixed inline into the data that it is signing. 733 7.5. Reliance on Supplied Certs and Keys 735 A truly stateless implementation may find that it spends more time 736 validating the internal consistency of certificates and keys than it 737 does on the actual object security operations. 739 For performance reasons, an implementation may choose to ignore 740 validation on certificate and key material supplied to it. The 741 security implications are of doing so depend on how the certs and 742 keys are managed outside of "sop". 744 8. Guidance for Consumers 746 While "sop" is originally conceived of as an interface for 747 interoperability testing, it's conceivable that an application that 748 uses OpenPGP for object security would want to use it. 750 FIXME: more guidance for how to use such a tool safely and 751 efficiently goes here. 753 FIXME: if an encrypted OpenPGP message arrives without metadata, it 754 is difficult to know which signers to consider when decrypting. How 755 do we do this efficiently without invoking "sop decrypt" twice, once 756 without "--verify-*" and again with the expected identity material? 758 9. Security Considerations 760 The OpenPGP object security model is typically used for 761 confidentiality and authenticity purposes. 763 9.1. Signature Verification 765 In many contexts, an OpenPGP signature is verified, to prove the 766 origin and integrity of an underlying object. 768 When "sop" checks a signature (e.g. via "sop verify" or "sop decrypt 769 --verify-with", it MUST NOT consider it to be verified unless all of 770 these conditions are met: 772 o The signature must be made by a signing-capable public key that is 773 present in one of the supplied certificates 775 o The certificate and signing subkey must have been created before 776 or at the signature time 778 o The cetificate and signing subkey must not have been expired at 779 the signature time 781 o The certificate and signing subkey must not be revoked with a 782 "hard" revocation 784 o If the certificate or signing subkey is revoked with a "soft" 785 revocation, then the signature time must predate the revocation 787 o The signing subkey must be properly bound to the primary key, and 788 cross-signed 790 o The signature (and any dependent signature, such as the cross-sig 791 or subkey binding signatures) must be made with strong 792 cryptographic algorithms (e.g., not "MD5" or a 1024-bit "RSA" key) 794 Implementers MAY also consider other factors in addition to the 795 origin and authenticity, including application-specific information. 797 For example, consider the application domain of checking software 798 updates. 800 If software package Foo version 13.3.2 was signed on 2019-10-04, and 801 the user receives a copy of Foo version 12.4.8 that was signed on 802 2019-10-16, it may be authentic and have a more recent signature 803 date. But it is not an upgrade (12.4.8 < 13.3.2), and therefore it 804 should not be applied automatically. 806 In such cases, it is critical that the application confirms that the 807 other information verified is _also_ protected by the relevant 808 OpenPGP signature. 810 Signature validity is a complex topic, and this documentation cannot 811 list all possible details. 813 9.2. Compression 815 The interface as currently specified does not allow for control of 816 compression. Compressing and encrypting data that may contain both 817 attacker-supplied material and sensitive material could leak 818 information about the sensitive material (see the CRIME attack). 820 Unless an application knows for sure that no attacker-supplied 821 material is present on the input, it should not compress during 822 encryption. 824 10. Privacy Considerations 826 Material produced by "sop encrypt" may be placed on an untrusted 827 machine (e.g., sent through the public "SMTP" network). That 828 material may contain metadata that leaks associational information 829 (e.g., recipient identifiers in PKESK packets). FIXME: document 830 things like PURBs and "--hidden-recipient") 832 10.1. Object Security vs. Transport Security 834 OpenPGP offers an object security model, but says little to nothing 835 about how the secured objects get to the relevant parties. 837 When sending or receiving OpenPGP material, the implementer should 838 consider what privacy leakage is implicit with the transport. 840 11. Document Considerations 842 [ RFC Editor: please remove this section before publication ] 844 This document is currently edited as markdown. Minor editorial 845 changes can be suggested via merge requests at 846 https://gitlab.com/dkg/openpgp-stateless-cli or by e-mail to the 847 authors. Please direct all significant commentary to the public IETF 848 OpenPGP mailing list: openpgp@ietf.org 850 11.1. Document History 852 substantive changes between -00 and -01: 854 o Changed "generate" subcommand to "generate-key" 856 o Changed "convert" subcommand to "extract-cert" 858 o Added "Input String Types" section as distinct from indirect I/O 860 o Made implicit arguments potentially explicit (e.g. "sop armor 861 --label=auto") 863 o Added "--allow-nested" to "sop armor" to make it idempotent by 864 default 866 o Added fingerprint of signing (sub)key to "VERIFICATIONS" output 868 o Dropped "--mode" and "--session-key" arguments for "sop encrypt" 869 (no plausible use, not needed for interop) 871 o Added "--with-session-key" argument to "sop decrypt" to allow for 872 session-key-based decryption 874 o Added examples to each subcommand 876 o More detailed error codes for "sop encrypt" 878 o Move from "CERT" to "CERTS" (each "CERTS" argument might contain 879 multiple certificates) 881 11.2. Future Work 883 o "detach-inband-signature-and-message" subcommand (split a 884 clearsigned message into a message and a detached signature) (see 885 Section 7.4 887 o certificate transformation into popular publication forms: 889 * WKD 891 * DANE OPENPGPKEY 893 * Autocrypt 895 o "sop encrypt" - specify compression? (see Section 9.2) 897 o "sop encrypt" - specify padding policy/mechanism? 899 o "sop decrypt" - how can it more safely handle zip bombs? 901 o "sop decrypt" - what should it do when encountering weakly- 902 encrypted (or unencrypted) input? 904 o "sop encrypt" - minimize metadata (e.g. "--throw-keyids")? 906 o handling secret keys that are locked with passwords? 908 o specify an error if a "DATE" arrives as input without a time zone? 910 o specify an error if a "sop" invocation sees multiple copies of a 911 specific "@FD:n" input (e.g., "sop sign @FD:3 @FD:3") 913 o add considerations about what it means for armored "CERTS" to 914 contain multiple certificates - multiple armorings? one big blob? 916 o do we need an interface or option (for performance?) with the 917 semantics that "sop" doesn't validate certificates internally, it 918 just accepts whatever's given as legit data? (see Section 7.5) 920 12. Acknowledgements 922 This work was inspired by Justus Winter's 923 [OpenPGP-Interoperability-Test-Suite]. 925 The following people contributed helpful feedback and considerations 926 to this draft, but are not responsible for its problems: 928 o Justus Winter 930 o Vincent Breitmoser 932 o Edwin Taylor 934 o Jameson Rollins 936 o Allan Nordhoey 938 13. References 939 13.1. Normative References 941 [I-D.ietf-openpgp-rfc4880bis] 942 Koch, W., carlson, b., Tse, R., Atkins, D., and D. 943 Gillmor, "OpenPGP Message Format", draft-ietf-openpgp- 944 rfc4880bis-08 (work in progress), September 2019. 946 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 947 Requirement Levels", BCP 14, RFC 2119, 948 DOI 10.17487/RFC2119, March 1997, 949 . 951 [RFC4880] Callas, J., Donnerhacke, L., Finney, H., Shaw, D., and R. 952 Thayer, "OpenPGP Message Format", RFC 4880, 953 DOI 10.17487/RFC4880, November 2007, 954 . 956 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 957 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 958 May 2017, . 960 13.2. Informative References 962 [I-D.draft-bre-openpgp-samples-00] 963 Einarsson, B., juga, j., and D. Gillmor, "OpenPGP Example 964 Keys and Certificates", draft-bre-openpgp-samples-00 (work 965 in progress), October 2019. 967 [OpenPGP-Interoperability-Test-Suite] 968 "OpenPGP Interoperability Test Suite", October 2019, 969 . 971 Author's Address 973 Daniel Kahn Gillmor 974 American Civil Liberties Union 975 125 Broad St. 976 New York, NY 10004 977 USA 979 Email: dkg@fifthhorseman.net