Line data Source code
1 : /* gpgcompose.c - Maintainer tool to create OpenPGP messages by hand.
2 : * Copyright (C) 2016 g10 Code GmbH
3 : *
4 : * This file is part of GnuPG.
5 : *
6 : * GnuPG is free software; you can redistribute it and/or modify
7 : * it under the terms of the GNU General Public License as published by
8 : * the Free Software Foundation; either version 3 of the License, or
9 : * (at your option) any later version.
10 : *
11 : * GnuPG is distributed in the hope that it will be useful,
12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : * GNU General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU General Public License
17 : * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : #include <config.h>
21 : #include <errno.h>
22 :
23 : #include "gpg.h"
24 : #include "packet.h"
25 : #include "keydb.h"
26 : #include "main.h"
27 : #include "options.h"
28 :
29 : static int do_debug;
30 : #define debug(fmt, ...) \
31 : do { if (do_debug) log_debug (fmt, ##__VA_ARGS__); } while (0)
32 :
33 : /* --encryption, for instance, adds a filter in front of out. There
34 : is an operator (--encryption-pop) to end this. We use the
35 : following infrastructure to make it easy to pop the state. */
36 : struct filter
37 : {
38 : void *func;
39 : void *context;
40 : int pkttype;
41 : int partial_block_mode;
42 : struct filter *next;
43 : };
44 :
45 : static struct filter *filters;
46 :
47 : static void
48 0 : filter_push (iobuf_t out, void *func, void *context,
49 : int type, int partial_block_mode)
50 : {
51 : gpg_error_t err;
52 0 : struct filter *f = xmalloc_clear (sizeof (*f));
53 0 : f->next = filters;
54 0 : f->func = func;
55 0 : f->context = context;
56 0 : f->pkttype = type;
57 0 : f->partial_block_mode = partial_block_mode;
58 :
59 0 : filters = f;
60 :
61 0 : err = iobuf_push_filter (out, func, context);
62 0 : if (err)
63 0 : log_fatal ("Adding filter: %s\n", gpg_strerror (err));
64 0 : }
65 :
66 : static void
67 0 : filter_pop (iobuf_t out, int expected_type)
68 : {
69 : gpg_error_t err;
70 0 : struct filter *f = filters;
71 :
72 0 : log_assert (f);
73 :
74 0 : if (f->pkttype != expected_type)
75 0 : log_fatal ("Attempted to pop a %s container, "
76 : "but current container is a %s container.\n",
77 0 : pkttype_str (f->pkttype), pkttype_str (expected_type));
78 :
79 0 : if (f->pkttype == PKT_ENCRYPTED || f->pkttype == PKT_ENCRYPTED_MDC)
80 : {
81 0 : err = iobuf_pop_filter (out, f->func, f->context);
82 0 : if (err)
83 0 : log_fatal ("Popping encryption filter: %s\n", gpg_strerror (err));
84 : }
85 : else
86 0 : log_fatal ("FILTERS appears to be corrupted.\n");
87 :
88 0 : if (f->partial_block_mode)
89 0 : iobuf_set_partial_body_length_mode (out, 0);
90 :
91 0 : filters = f->next;
92 0 : xfree (f);
93 0 : }
94 :
95 : /* Return if CIPHER_ID is a valid cipher. */
96 : static int
97 0 : valid_cipher (int cipher_id)
98 : {
99 0 : return (cipher_id == CIPHER_ALGO_IDEA
100 0 : || cipher_id == CIPHER_ALGO_3DES
101 0 : || cipher_id == CIPHER_ALGO_CAST5
102 0 : || cipher_id == CIPHER_ALGO_BLOWFISH
103 0 : || cipher_id == CIPHER_ALGO_AES
104 0 : || cipher_id == CIPHER_ALGO_AES192
105 0 : || cipher_id == CIPHER_ALGO_AES256
106 0 : || cipher_id == CIPHER_ALGO_TWOFISH
107 0 : || cipher_id == CIPHER_ALGO_CAMELLIA128
108 0 : || cipher_id == CIPHER_ALGO_CAMELLIA192
109 0 : || cipher_id == CIPHER_ALGO_CAMELLIA256);
110 : }
111 :
112 : /* Parse a session key encoded as a string of the form x:HEXDIGITS
113 : where x is the algorithm id. (This is the format emitted by gpg
114 : --show-session-key.) */
115 : struct session_key
116 : {
117 : int algo;
118 : int keylen;
119 : char *key;
120 : };
121 :
122 : static struct session_key
123 0 : parse_session_key (const char *option, char *p, int require_algo)
124 : {
125 : char *tail;
126 : struct session_key sk;
127 :
128 0 : memset (&sk, 0, sizeof (sk));
129 :
130 : /* Check for the optional "cipher-id:" at the start of the
131 : string. */
132 0 : errno = 0;
133 0 : sk.algo = strtol (p, &tail, 10);
134 0 : if (! errno && tail && *tail == ':')
135 : {
136 0 : if (! valid_cipher (sk.algo))
137 0 : log_info ("%s: %d is not a known cipher (but using anyways)\n",
138 : option, sk.algo);
139 0 : p = tail + 1;
140 : }
141 0 : else if (require_algo)
142 0 : log_fatal ("%s: Session key must have the form algo:HEXCHARACTERS.\n",
143 : option);
144 : else
145 0 : sk.algo = 0;
146 :
147 : /* Ignore a leading 0x. */
148 0 : if (p[0] == '0' && p[1] == 'x')
149 0 : p += 2;
150 :
151 0 : if (strlen (p) % 2 != 0)
152 0 : log_fatal ("%s: session key must consist of an even number of hexadecimal characters.\n",
153 : option);
154 :
155 0 : sk.keylen = strlen (p) / 2;
156 0 : sk.key = xmalloc (sk.keylen);
157 :
158 0 : if (hex2bin (p, sk.key, sk.keylen) == -1)
159 0 : log_fatal ("%s: Session key must only contain hexadecimal characters\n",
160 : option);
161 :
162 0 : return sk;
163 : }
164 :
165 : /* A callback.
166 :
167 : OPTION_STR is the option that was matched. ARGC is the number of
168 : arguments following the option and ARGV are those arguments.
169 : (Thus, argv[0] is the first string following the option and
170 : argv[-1] is the option.)
171 :
172 : COOKIE is the opaque value passed to process_options. */
173 : typedef int (*option_prcessor_t) (const char *option_str,
174 : int argc, char *argv[],
175 : void *cookie);
176 :
177 : struct option
178 : {
179 : /* The option that this matches. This must start with "--" or be
180 : the empty string. The empty string matches bare arguments. */
181 : const char *option;
182 : /* The function to call to process this option. */
183 : option_prcessor_t func;
184 : /* Documentation. */
185 : const char *help;
186 : };
187 :
188 : /* Merge two lists of options. Note: this makes a shallow copy! The
189 : caller must xfree() the result. */
190 : static struct option *
191 0 : merge_options (struct option a[], struct option b[])
192 : {
193 : int i, j;
194 : struct option *c;
195 :
196 0 : for (i = 0; a[i].option; i ++)
197 : ;
198 0 : for (j = 0; b[j].option; j ++)
199 : ;
200 :
201 0 : c = xmalloc ((i + j + 1) * sizeof (struct option));
202 0 : memcpy (c, a, i * sizeof (struct option));
203 0 : memcpy (&c[i], b, j * sizeof (struct option));
204 0 : c[i + j].option = NULL;
205 :
206 0 : if (a[i].help && b[j].help)
207 0 : c[i + j].help = xasprintf ("%s\n\n%s", a[i].help, b[j].help);
208 0 : else if (a[i].help)
209 0 : c[i + j].help = a[i].help;
210 0 : else if (b[j].help)
211 0 : c[i + j].help = b[j].help;
212 :
213 0 : return c;
214 : }
215 :
216 : /* Returns whether ARG is an option. All options start with --. */
217 : static int
218 0 : is_option (const char *arg)
219 : {
220 0 : return arg[0] == '-' && arg[1] == '-';
221 : }
222 :
223 : /* OPTIONS is a NULL terminated array of struct option:s. Finds the
224 : entry that is the same as ARG. Returns -1 if no entry is found.
225 : The empty string option matches bare arguments. */
226 : static int
227 0 : match_option (const struct option options[], const char *arg)
228 : {
229 : int i;
230 0 : int bare_arg = ! is_option (arg);
231 :
232 0 : for (i = 0; options[i].option; i ++)
233 0 : if ((! bare_arg && strcmp (options[i].option, arg) == 0)
234 : /* Non-options match the empty string. */
235 0 : || (bare_arg && options[i].option[0] == '\0'))
236 0 : return i;
237 :
238 0 : return -1;
239 : }
240 :
241 : static void
242 0 : show_help (struct option options[])
243 : {
244 : int i;
245 0 : int max_length = 0;
246 : int space;
247 :
248 0 : for (i = 0; options[i].option; i ++)
249 : {
250 0 : const char *option = options[i].option[0] ? options[i].option : "ARG";
251 0 : int l = strlen (option);
252 0 : if (l > max_length)
253 0 : max_length = l;
254 : }
255 :
256 0 : space = 72 - (max_length + 2);
257 0 : if (space < 40)
258 0 : space = 40;
259 :
260 0 : for (i = 0; ; i ++)
261 : {
262 0 : const char *option = options[i].option;
263 0 : const char *help = options[i].help;
264 :
265 : int l;
266 : int j;
267 : char *tmp;
268 : char *formatted;
269 : char *p;
270 : char *newline;
271 :
272 0 : if (! option && ! help)
273 0 : break;
274 :
275 0 : if (option)
276 : {
277 0 : const char *o = option[0] ? option : "ARG";
278 0 : l = strlen (o);
279 0 : fprintf (stderr, "%s", o);
280 : }
281 :
282 0 : if (! help)
283 : {
284 0 : fputc ('\n', stderr);
285 0 : continue;
286 : }
287 :
288 0 : if (option)
289 0 : for (j = l; j < max_length + 2; j ++)
290 0 : fputc (' ', stderr);
291 :
292 : #define BOLD_START "\033[1m"
293 : #define NORMAL_RESTORE "\033[0m"
294 : #define BOLD(x) BOLD_START x NORMAL_RESTORE
295 :
296 0 : if (! option || options[i].func)
297 0 : tmp = (char *) help;
298 : else
299 0 : tmp = xasprintf ("%s " BOLD("(Unimplemented.)"), help);
300 :
301 0 : if (! option)
302 0 : space = 72;
303 0 : formatted = format_text (tmp, 0, space, space + 4);
304 :
305 0 : if (tmp != help)
306 0 : xfree (tmp);
307 :
308 0 : if (! option)
309 : {
310 0 : fprintf (stderr, "\n%s\n", formatted);
311 0 : break;
312 : }
313 :
314 0 : for (p = formatted;
315 0 : p && *p;
316 0 : p = (*newline == '\0') ? newline : newline + 1)
317 : {
318 0 : newline = strchr (p, '\n');
319 0 : if (! newline)
320 0 : newline = &p[strlen (p)];
321 :
322 0 : l = (size_t) newline - (size_t) p;
323 :
324 0 : if (p != formatted)
325 0 : for (j = 0; j < max_length + 2; j ++)
326 0 : fputc (' ', stderr);
327 :
328 0 : fwrite (p, l, 1, stderr);
329 0 : fputc ('\n', stderr);
330 : }
331 :
332 0 : xfree (formatted);
333 0 : }
334 0 : }
335 :
336 : /* Return value is number of consumed argv elements. */
337 : static int
338 0 : process_options (const char *parent_option,
339 : struct option break_options[],
340 : struct option local_options[], void *lcookie,
341 : struct option global_options[], void *gcookie,
342 : int argc, char *argv[])
343 : {
344 : int i;
345 0 : for (i = 0; i < argc; i ++)
346 : {
347 : int j;
348 : struct option *option;
349 : void *cookie;
350 : int bare_arg;
351 : option_prcessor_t func;
352 : int consumed;
353 :
354 0 : if (break_options)
355 : {
356 0 : j = match_option (break_options, argv[i]);
357 0 : if (j != -1)
358 : /* Match. Break out. */
359 0 : return i;
360 : }
361 :
362 0 : j = match_option (local_options, argv[i]);
363 0 : if (j == -1)
364 : {
365 0 : if (global_options)
366 0 : j = match_option (global_options, argv[i]);
367 0 : if (j == -1)
368 : {
369 0 : if (strcmp (argv[i], "--help") == 0)
370 : {
371 0 : if (! global_options)
372 0 : show_help (local_options);
373 : else
374 : {
375 0 : struct option *combined
376 : = merge_options (local_options, global_options);
377 0 : show_help (combined);
378 0 : xfree (combined);
379 : }
380 0 : g10_exit (0);
381 : }
382 :
383 0 : if (parent_option)
384 0 : log_fatal ("%s: Unknown option: %s\n", parent_option, argv[i]);
385 : else
386 0 : log_fatal ("Unknown option: %s\n", argv[i]);
387 : }
388 :
389 0 : option = &global_options[j];
390 0 : cookie = gcookie;
391 : }
392 : else
393 : {
394 0 : option = &local_options[j];
395 0 : cookie = lcookie;
396 : }
397 :
398 0 : bare_arg = strcmp (option->option, "") == 0;
399 :
400 0 : func = option->func;
401 0 : if (! func)
402 : {
403 0 : if (bare_arg)
404 0 : log_fatal ("Bare arguments unimplemented.\n");
405 : else
406 0 : log_fatal ("Unimplemented option: %s\n",
407 : option->option);
408 : }
409 :
410 0 : consumed = func (bare_arg ? parent_option : argv[i],
411 0 : argc - i - !bare_arg, &argv[i + !bare_arg],
412 : cookie);
413 0 : i += consumed;
414 0 : if (bare_arg)
415 0 : i --;
416 : }
417 :
418 0 : return i;
419 : }
420 :
421 : /* The keys, subkeys, user ids and user attributes in the order that
422 : they were added. */
423 : PACKET components[20];
424 : /* The number of components. */
425 : int ncomponents;
426 :
427 : static int
428 0 : add_component (int pkttype, void *component)
429 : {
430 0 : int i = ncomponents ++;
431 :
432 0 : log_assert (i < sizeof (components) / sizeof (components[0]));
433 0 : log_assert (pkttype == PKT_PUBLIC_KEY
434 : || pkttype == PKT_PUBLIC_SUBKEY
435 : || pkttype == PKT_SECRET_KEY
436 : || pkttype == PKT_SECRET_SUBKEY
437 : || pkttype == PKT_USER_ID
438 : || pkttype == PKT_ATTRIBUTE);
439 :
440 0 : components[i].pkttype = pkttype;
441 0 : components[i].pkt.generic = component;
442 :
443 0 : return i;
444 : }
445 :
446 : static void
447 0 : dump_component (PACKET *pkt)
448 : {
449 : struct kbnode_struct kbnode;
450 :
451 0 : if (! do_debug)
452 0 : return;
453 :
454 0 : memset (&kbnode, 0, sizeof (kbnode));
455 0 : kbnode.pkt = pkt;
456 0 : dump_kbnode (&kbnode);
457 : }
458 :
459 : /* Returns the first primary key in COMPONENTS or NULL if there is
460 : none. */
461 : static PKT_public_key *
462 0 : primary_key (void)
463 : {
464 : int i;
465 0 : for (i = 0; i < ncomponents; i ++)
466 0 : if (components[i].pkttype == PKT_PUBLIC_KEY)
467 0 : return components[i].pkt.public_key;
468 0 : return NULL;
469 : }
470 :
471 : /* The last session key (updated when adding a SK-ESK, PK-ESK or SED
472 : packet. */
473 : static DEK session_key;
474 :
475 : static int user_id (const char *option, int argc, char *argv[],
476 : void *cookie);
477 : static int public_key (const char *option, int argc, char *argv[],
478 : void *cookie);
479 : static int sk_esk (const char *option, int argc, char *argv[],
480 : void *cookie);
481 : static int pk_esk (const char *option, int argc, char *argv[],
482 : void *cookie);
483 : static int encrypted (const char *option, int argc, char *argv[],
484 : void *cookie);
485 : static int encrypted_pop (const char *option, int argc, char *argv[],
486 : void *cookie);
487 : static int literal (const char *option, int argc, char *argv[],
488 : void *cookie);
489 : static int signature (const char *option, int argc, char *argv[],
490 : void *cookie);
491 : static int copy (const char *option, int argc, char *argv[],
492 : void *cookie);
493 :
494 : static struct option major_options[] = {
495 : { "--user-id", user_id, "Create a user id packet." },
496 : { "--public-key", public_key, "Create a public key packet." },
497 : { "--private-key", NULL, "Create a private key packet." },
498 : { "--public-subkey", public_key, "Create a subkey packet." },
499 : { "--private-subkey", NULL, "Create a private subkey packet." },
500 : { "--sk-esk", sk_esk,
501 : "Create a symmetric-key encrypted session key packet." },
502 : { "--pk-esk", pk_esk,
503 : "Create a public-key encrypted session key packet." },
504 : { "--encrypted", encrypted, "Create a symmetrically encrypted data packet." },
505 : { "--encrypted-mdc", encrypted,
506 : "Create a symmetrically encrypted and integrity protected data packet." },
507 : { "--encrypted-pop", encrypted_pop,
508 : "Pop an encryption container." },
509 : { "--compressed", NULL, "Create a compressed data packet." },
510 : { "--literal", literal, "Create a literal (plaintext) data packet." },
511 : { "--signature", signature, "Create a signature packet." },
512 : { "--onepass-sig", NULL, "Create a one-pass signature packet." },
513 : { "--copy", copy, "Copy the specified file." },
514 : { NULL, NULL,
515 : "To get more information about a given command, use:\n\n"
516 : " $ gpgcompose --command --help to list a command's options."},
517 : };
518 :
519 : static struct option global_options[] = {
520 : { NULL, NULL, NULL },
521 : };
522 :
523 : /* Make our lives easier and use a static limit for the user name.
524 : 10k is way more than enough anyways... */
525 : const int user_id_max_len = 10 * 1024;
526 :
527 : static int
528 0 : user_id_name (const char *option, int argc, char *argv[], void *cookie)
529 : {
530 0 : PKT_user_id *uid = cookie;
531 : int l;
532 :
533 0 : if (argc == 0)
534 0 : log_fatal ("Usage: %s USER_ID\n", option);
535 :
536 0 : if (uid->len)
537 0 : log_fatal ("Attempt to set user id multiple times.\n");
538 :
539 0 : l = strlen (argv[0]);
540 0 : if (l > user_id_max_len)
541 0 : log_fatal ("user id too long (max: %d)\n", user_id_max_len);
542 :
543 0 : memcpy (uid->name, argv[0], l);
544 0 : uid->name[l] = 0;
545 0 : uid->len = l;
546 :
547 0 : return 1;
548 : }
549 :
550 : static struct option user_id_options[] = {
551 : { "", user_id_name,
552 : "Set the user id. This is usually in the format "
553 : "\"Name (comment) <email@example.org>\"" },
554 : { NULL, NULL,
555 : "Example:\n\n"
556 : " $ gpgcompose --user-id \"USERID\" | " GPG_NAME " --list-packets" }
557 : };
558 :
559 : static int
560 0 : user_id (const char *option, int argc, char *argv[], void *cookie)
561 : {
562 0 : iobuf_t out = cookie;
563 : gpg_error_t err;
564 0 : PKT_user_id *uid = xmalloc_clear (sizeof (*uid) + user_id_max_len);
565 0 : int c = add_component (PKT_USER_ID, uid);
566 : int processed;
567 :
568 0 : processed = process_options (option,
569 : major_options,
570 : user_id_options, uid,
571 : global_options, NULL,
572 : argc, argv);
573 :
574 0 : if (! uid->len)
575 0 : log_fatal ("%s: user id not given", option);
576 :
577 0 : err = build_packet (out, &components[c]);
578 0 : if (err)
579 0 : log_fatal ("Serializing user id packet: %s\n", gpg_strerror (err));
580 :
581 0 : debug ("Wrote user id packet:\n");
582 0 : dump_component (&components[c]);
583 :
584 0 : return processed;
585 : }
586 :
587 : static int
588 0 : pk_search_terms (const char *option, int argc, char *argv[], void *cookie)
589 : {
590 : gpg_error_t err;
591 : KEYDB_HANDLE hd;
592 : KEYDB_SEARCH_DESC desc;
593 : kbnode_t kb;
594 0 : PKT_public_key *pk = cookie;
595 : PKT_public_key *pk_ref;
596 : int i;
597 :
598 0 : if (argc == 0)
599 0 : log_fatal ("Usage: %s KEYID\n", option);
600 :
601 0 : if (pk->pubkey_algo)
602 0 : log_fatal ("%s: multiple keys provided\n", option);
603 :
604 0 : err = classify_user_id (argv[0], &desc, 0);
605 0 : if (err)
606 0 : log_fatal ("search terms '%s': %s\n", argv[0], gpg_strerror (err));
607 :
608 0 : hd = keydb_new ();
609 :
610 0 : err = keydb_search (hd, &desc, 1, NULL);
611 0 : if (err)
612 0 : log_fatal ("looking up '%s': %s\n", argv[0], gpg_strerror (err));
613 :
614 0 : err = keydb_get_keyblock (hd, &kb);
615 0 : if (err)
616 0 : log_fatal ("retrieving keyblock for '%s': %s\n",
617 : argv[0], gpg_strerror (err));
618 :
619 0 : keydb_release (hd);
620 :
621 0 : pk_ref = kb->pkt->pkt.public_key;
622 :
623 : /* Copy the timestamp (if not already set), algo and public key
624 : parameters. */
625 0 : if (! pk->timestamp)
626 0 : pk->timestamp = pk_ref->timestamp;
627 0 : pk->pubkey_algo = pk_ref->pubkey_algo;
628 0 : for (i = 0; i < pubkey_get_npkey (pk->pubkey_algo); i ++)
629 0 : pk->pkey[i] = gcry_mpi_copy (pk_ref->pkey[i]);
630 :
631 0 : release_kbnode (kb);
632 :
633 0 : return 1;
634 : }
635 :
636 : static int
637 0 : pk_timestamp (const char *option, int argc, char *argv[], void *cookie)
638 : {
639 0 : PKT_public_key *pk = cookie;
640 0 : char *tail = NULL;
641 :
642 0 : if (argc == 0)
643 0 : log_fatal ("Usage: %s TIMESTAMP\n", option);
644 :
645 0 : errno = 0;
646 0 : pk->timestamp = parse_timestamp (argv[0], &tail);
647 0 : if (errno || (tail && *tail))
648 0 : log_fatal ("Invalid value passed to %s (%s)\n", option, argv[0]);
649 :
650 0 : return 1;
651 : }
652 :
653 : #define TIMESTAMP_HELP \
654 : "Either as seconds since the epoch or as an ISO 8601 formatted " \
655 : "string (yyyymmddThhmmss, where the T is a literal)."
656 :
657 : static struct option pk_options[] = {
658 : { "--timestamp", pk_timestamp,
659 : "The creation time. " TIMESTAMP_HELP },
660 : { "", pk_search_terms,
661 : "The key to copy the creation time and public key parameters from." },
662 : { NULL, NULL,
663 : "Example:\n\n"
664 : " $ gpgcompose --public-key $KEYID --user-id \"USERID\" \\\n"
665 : " | " GPG_NAME " --list-packets" }
666 : };
667 :
668 : static int
669 0 : public_key (const char *option, int argc, char *argv[], void *cookie)
670 : {
671 : gpg_error_t err;
672 0 : iobuf_t out = cookie;
673 : PKT_public_key *pk;
674 : int c;
675 : int processed;
676 0 : int t = (strcmp (option, "--public-key") == 0
677 0 : ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY);
678 :
679 : (void) option;
680 :
681 0 : pk = xmalloc_clear (sizeof (*pk));
682 0 : pk->version = 4;
683 :
684 0 : c = add_component (t, pk);
685 :
686 0 : processed = process_options (option,
687 : major_options,
688 : pk_options, pk,
689 : global_options, NULL,
690 : argc, argv);
691 :
692 0 : if (! pk->pubkey_algo)
693 0 : log_fatal ("%s: key to extract public key parameters from not given",
694 : option);
695 :
696 : /* Clear the keyid in case we updated one of the relevant fields
697 : after accessing it. */
698 0 : pk->keyid[0] = pk->keyid[1] = 0;
699 :
700 0 : err = build_packet (out, &components[c]);
701 0 : if (err)
702 0 : log_fatal ("serializing %s packet: %s\n",
703 : t == PKT_PUBLIC_KEY ? "public key" : "subkey",
704 : gpg_strerror (err));
705 :
706 0 : debug ("Wrote %s packet:\n",
707 : t == PKT_PUBLIC_KEY ? "public key" : "subkey");
708 0 : dump_component (&components[c]);
709 :
710 0 : return processed;
711 : }
712 :
713 : struct signinfo
714 : {
715 : /* Key with which to sign. */
716 : kbnode_t issuer_kb;
717 : PKT_public_key *issuer_pk;
718 :
719 : /* Overrides the issuer's key id. */
720 : u32 issuer_keyid[2];
721 : /* Sets the issuer's keyid to the primary key's key id. */
722 : int issuer_keyid_self;
723 :
724 : /* Key to sign. */
725 : PKT_public_key *pk;
726 : /* Subkey to sign. */
727 : PKT_public_key *sk;
728 : /* User id to sign. */
729 : PKT_user_id *uid;
730 :
731 : int class;
732 : int digest_algo;
733 : u32 timestamp;
734 : u32 key_expiration;
735 :
736 : byte *cipher_algorithms;
737 : int cipher_algorithms_len;
738 : byte *digest_algorithms;
739 : int digest_algorithms_len;
740 : byte *compress_algorithms;
741 : int compress_algorithms_len;
742 :
743 : u32 expiration;
744 :
745 : int exportable_set;
746 : int exportable;
747 :
748 : int revocable_set;
749 : int revocable;
750 :
751 : int trust_level_set;
752 : byte trust_args[2];
753 :
754 : char *trust_scope;
755 :
756 : struct revocation_key *revocation_key;
757 : int nrevocation_keys;
758 :
759 : struct notation *notations;
760 :
761 : byte *key_server_preferences;
762 : int key_server_preferences_len;
763 :
764 : char *key_server;
765 :
766 : int primary_user_id_set;
767 : int primary_user_id;
768 :
769 : char *policy_uri;
770 :
771 : byte *key_flags;
772 : int key_flags_len;
773 :
774 : char *signers_user_id;
775 :
776 : byte reason_for_revocation_code;
777 : char *reason_for_revocation;
778 :
779 : byte *features;
780 : int features_len;
781 :
782 : /* Whether to corrupt the signature. */
783 : int corrupt;
784 : };
785 :
786 : static int
787 0 : sig_issuer (const char *option, int argc, char *argv[], void *cookie)
788 : {
789 : gpg_error_t err;
790 : KEYDB_HANDLE hd;
791 : KEYDB_SEARCH_DESC desc;
792 0 : struct signinfo *si = cookie;
793 :
794 0 : if (argc == 0)
795 0 : log_fatal ("Usage: %s KEYID\n", option);
796 :
797 0 : if (si->issuer_pk)
798 0 : log_fatal ("%s: multiple keys provided\n", option);
799 :
800 0 : err = classify_user_id (argv[0], &desc, 0);
801 0 : if (err)
802 0 : log_fatal ("search terms '%s': %s\n", argv[0], gpg_strerror (err));
803 :
804 0 : hd = keydb_new ();
805 :
806 0 : err = keydb_search (hd, &desc, 1, NULL);
807 0 : if (err)
808 0 : log_fatal ("looking up '%s': %s\n", argv[0], gpg_strerror (err));
809 :
810 0 : err = keydb_get_keyblock (hd, &si->issuer_kb);
811 0 : if (err)
812 0 : log_fatal ("retrieving keyblock for '%s': %s\n",
813 : argv[0], gpg_strerror (err));
814 :
815 0 : keydb_release (hd);
816 :
817 0 : si->issuer_pk = si->issuer_kb->pkt->pkt.public_key;
818 :
819 0 : return 1;
820 : }
821 :
822 : static int
823 0 : sig_issuer_keyid (const char *option, int argc, char *argv[], void *cookie)
824 : {
825 : gpg_error_t err;
826 : KEYDB_SEARCH_DESC desc;
827 0 : struct signinfo *si = cookie;
828 :
829 0 : if (argc == 0)
830 0 : log_fatal ("Usage: %s KEYID|self\n", option);
831 :
832 0 : if (si->issuer_keyid[0] || si->issuer_keyid[1] || si->issuer_keyid_self)
833 0 : log_fatal ("%s given multiple times.\n", option);
834 :
835 0 : if (strcasecmp (argv[0], "self") == 0)
836 : {
837 0 : si->issuer_keyid_self = 1;
838 0 : return 1;
839 : }
840 :
841 0 : err = classify_user_id (argv[0], &desc, 0);
842 0 : if (err)
843 0 : log_fatal ("search terms '%s': %s\n", argv[0], gpg_strerror (err));
844 :
845 0 : if (desc.mode != KEYDB_SEARCH_MODE_LONG_KID)
846 0 : log_fatal ("%s is not a valid long key id.\n", argv[0]);
847 :
848 0 : keyid_copy (si->issuer_keyid, desc.u.kid);
849 :
850 0 : return 1;
851 : }
852 :
853 : static int
854 0 : sig_pk (const char *option, int argc, char *argv[], void *cookie)
855 : {
856 0 : struct signinfo *si = cookie;
857 : int i;
858 0 : char *tail = NULL;
859 :
860 0 : if (argc == 0)
861 0 : log_fatal ("Usage: %s COMPONENT_INDEX\n", option);
862 :
863 0 : errno = 0;
864 0 : i = strtoul (argv[0], &tail, 10);
865 0 : if (errno || (tail && *tail))
866 0 : log_fatal ("Invalid value passed to %s (%s)\n", option, argv[0]);
867 :
868 0 : if (i >= ncomponents)
869 0 : log_fatal ("%d: No such component (have %d components so far)\n",
870 : i, ncomponents);
871 0 : if (! (components[i].pkttype == PKT_PUBLIC_KEY
872 0 : || components[i].pkttype == PKT_PUBLIC_SUBKEY))
873 0 : log_fatal ("Component %d is not a public key or a subkey.", i);
874 :
875 0 : if (strcmp (option, "--pk") == 0)
876 : {
877 0 : if (si->pk)
878 0 : log_fatal ("%s already given.\n", option);
879 0 : si->pk = components[i].pkt.public_key;
880 : }
881 0 : else if (strcmp (option, "--sk") == 0)
882 : {
883 0 : if (si->sk)
884 0 : log_fatal ("%s already given.\n", option);
885 0 : si->sk = components[i].pkt.public_key;
886 : }
887 : else
888 0 : log_fatal ("Cannot handle %s\n", option);
889 :
890 0 : return 1;
891 : }
892 :
893 : static int
894 0 : sig_user_id (const char *option, int argc, char *argv[], void *cookie)
895 : {
896 0 : struct signinfo *si = cookie;
897 : int i;
898 0 : char *tail = NULL;
899 :
900 0 : if (argc == 0)
901 0 : log_fatal ("Usage: %s COMPONENT_INDEX\n", option);
902 0 : if (si->uid)
903 0 : log_fatal ("%s already given.\n", option);
904 :
905 0 : errno = 0;
906 0 : i = strtoul (argv[0], &tail, 10);
907 0 : if (errno || (tail && *tail))
908 0 : log_fatal ("Invalid value passed to %s (%s)\n", option, argv[0]);
909 :
910 0 : if (i >= ncomponents)
911 0 : log_fatal ("%d: No such component (have %d components so far)\n",
912 : i, ncomponents);
913 0 : if (! (components[i].pkttype != PKT_USER_ID
914 0 : || components[i].pkttype == PKT_ATTRIBUTE))
915 0 : log_fatal ("Component %d is not a public key or a subkey.", i);
916 :
917 0 : si->uid = components[i].pkt.user_id;
918 :
919 0 : return 1;
920 : }
921 :
922 : static int
923 0 : sig_class (const char *option, int argc, char *argv[], void *cookie)
924 : {
925 0 : struct signinfo *si = cookie;
926 : int i;
927 0 : char *tail = NULL;
928 :
929 0 : if (argc == 0)
930 0 : log_fatal ("Usage: %s CLASS\n", option);
931 :
932 0 : errno = 0;
933 0 : i = strtoul (argv[0], &tail, 0);
934 0 : if (errno || (tail && *tail))
935 0 : log_fatal ("Invalid value passed to %s (%s)\n", option, argv[0]);
936 :
937 0 : si->class = i;
938 :
939 0 : return 1;
940 : }
941 :
942 : static int
943 0 : sig_digest (const char *option, int argc, char *argv[], void *cookie)
944 : {
945 0 : struct signinfo *si = cookie;
946 : int i;
947 0 : char *tail = NULL;
948 :
949 0 : if (argc == 0)
950 0 : log_fatal ("Usage: %s DIGEST_ALGO\n", option);
951 :
952 0 : errno = 0;
953 0 : i = strtoul (argv[0], &tail, 10);
954 0 : if (errno || (tail && *tail))
955 0 : log_fatal ("Invalid value passed to %s (%s)\n", option, argv[0]);
956 :
957 0 : si->digest_algo = i;
958 :
959 0 : return 1;
960 : }
961 :
962 : static int
963 0 : sig_timestamp (const char *option, int argc, char *argv[], void *cookie)
964 : {
965 0 : struct signinfo *si = cookie;
966 0 : char *tail = NULL;
967 :
968 0 : if (argc == 0)
969 0 : log_fatal ("Usage: %s TIMESTAMP\n", option);
970 :
971 0 : errno = 0;
972 0 : si->timestamp = parse_timestamp (argv[0], &tail);
973 0 : if (errno || (tail && *tail))
974 0 : log_fatal ("Invalid value passed to %s (%s)\n", option, argv[0]);
975 :
976 0 : return 1;
977 : }
978 :
979 : static int
980 0 : sig_expiration (const char *option, int argc, char *argv[], void *cookie)
981 : {
982 0 : struct signinfo *si = cookie;
983 0 : int is_expiration = strcmp (option, "--expiration") == 0;
984 0 : u32 *i = is_expiration ? &si->expiration : &si->key_expiration;
985 :
986 0 : if (! is_expiration)
987 0 : log_assert (strcmp (option, "--key-expiration") == 0);
988 :
989 0 : if (argc == 0)
990 0 : log_fatal ("Usage: %s DURATION\n", option);
991 :
992 0 : *i = parse_expire_string (argv[0]);
993 0 : if (*i == (u32)-1)
994 0 : log_fatal ("Invalid value passed to %s (%s)\n", option, argv[0]);
995 :
996 0 : return 1;
997 : }
998 :
999 : static int
1000 0 : sig_int_list (const char *option, int argc, char *argv[], void *cookie)
1001 : {
1002 0 : struct signinfo *si = cookie;
1003 0 : int nvalues = 1;
1004 0 : char *values = xmalloc (nvalues * sizeof (values[0]));
1005 0 : char *tail = argv[0];
1006 : int i;
1007 : byte **a;
1008 : int *n;
1009 :
1010 0 : if (argc == 0)
1011 0 : log_fatal ("Usage: %s VALUE[,VALUE...]\n", option);
1012 :
1013 0 : for (i = 0; tail && *tail; i ++)
1014 : {
1015 : int v;
1016 0 : char *old_tail = tail;
1017 :
1018 0 : errno = 0;
1019 0 : v = strtol (tail, &tail, 0);
1020 0 : if (errno || old_tail == tail || (tail && !(*tail == ',' || *tail == 0)))
1021 0 : log_fatal ("Invalid value passed to %s (%s). "
1022 : "Expected a list of comma separated numbers\n",
1023 : option, argv[0]);
1024 :
1025 0 : if (! (0 <= v && v <= 255))
1026 0 : log_fatal ("%s: %d is out of range (Expected: 0-255)\n", option, v);
1027 :
1028 0 : if (i == nvalues)
1029 : {
1030 0 : nvalues *= 2;
1031 0 : values = xrealloc (values, nvalues * sizeof (values[0]));
1032 : }
1033 :
1034 0 : values[i] = v;
1035 :
1036 0 : if (*tail == ',')
1037 0 : tail ++;
1038 : else
1039 0 : log_assert (*tail == 0);
1040 : }
1041 :
1042 0 : if (strcmp ("--cipher-algos", option) == 0)
1043 : {
1044 0 : a = &si->cipher_algorithms;
1045 0 : n = &si->cipher_algorithms_len;
1046 : }
1047 0 : else if (strcmp ("--digest-algos", option) == 0)
1048 : {
1049 0 : a = &si->digest_algorithms;
1050 0 : n = &si->digest_algorithms_len;
1051 : }
1052 0 : else if (strcmp ("--compress-algos", option) == 0)
1053 : {
1054 0 : a = &si->compress_algorithms;
1055 0 : n = &si->compress_algorithms_len;
1056 : }
1057 : else
1058 0 : log_fatal ("Cannot handle %s\n", option);
1059 :
1060 0 : if (*a)
1061 0 : log_fatal ("Option %s given multiple times.\n", option);
1062 :
1063 0 : *a = values;
1064 0 : *n = i;
1065 :
1066 0 : return 1;
1067 : }
1068 :
1069 : static int
1070 0 : sig_flag (const char *option, int argc, char *argv[], void *cookie)
1071 : {
1072 0 : struct signinfo *si = cookie;
1073 0 : int range[2] = {0, 255};
1074 : char *tail;
1075 : int v;
1076 :
1077 0 : if (strcmp (option, "--primary-user-id") == 0)
1078 0 : range[1] = 1;
1079 :
1080 0 : if (argc <= 1)
1081 : {
1082 0 : if (range[0] == 0 && range[1] == 1)
1083 0 : log_fatal ("Usage: %s 0|1\n", option);
1084 : else
1085 0 : log_fatal ("Usage: %s %d-%d\n", option, range[0], range[1]);
1086 : }
1087 :
1088 0 : errno = 0;
1089 0 : v = strtol (argv[0], &tail, 0);
1090 0 : if (errno || (tail && *tail) || !(range[0] <= v && v <= range[1]))
1091 0 : log_fatal ("Invalid value passed to %s (%s). Expected %d-%d\n",
1092 : option, argv[0], range[0], range[1]);
1093 :
1094 0 : if (strcmp (option, "--exportable") == 0)
1095 : {
1096 0 : si->exportable_set = 1;
1097 0 : si->exportable = v;
1098 : }
1099 0 : else if (strcmp (option, "--revocable") == 0)
1100 : {
1101 0 : si->revocable_set = 1;
1102 0 : si->revocable = v;
1103 : }
1104 0 : else if (strcmp (option, "--primary-user-id") == 0)
1105 : {
1106 0 : si->primary_user_id_set = 1;
1107 0 : si->primary_user_id = v;
1108 : }
1109 : else
1110 0 : log_fatal ("Cannot handle %s\n", option);
1111 :
1112 0 : return 1;
1113 : }
1114 :
1115 : static int
1116 0 : sig_trust_level (const char *option, int argc, char *argv[], void *cookie)
1117 : {
1118 0 : struct signinfo *si = cookie;
1119 : int i;
1120 : char *tail;
1121 :
1122 0 : if (argc <= 1)
1123 0 : log_fatal ("Usage: %s DEPTH TRUST_AMOUNT\n", option);
1124 :
1125 0 : for (i = 0; i < sizeof (si->trust_args) / sizeof (si->trust_args[0]); i ++)
1126 : {
1127 : int v;
1128 :
1129 0 : errno = 0;
1130 0 : v = strtol (argv[i], &tail, 0);
1131 0 : if (errno || (tail && *tail) || !(0 <= v && v <= 255))
1132 0 : log_fatal ("Invalid value passed to %s (%s). Expected 0-255\n",
1133 0 : option, argv[i]);
1134 :
1135 0 : si->trust_args[i] = v;
1136 : }
1137 :
1138 0 : si->trust_level_set = 1;
1139 :
1140 0 : return 2;
1141 : }
1142 :
1143 : static int
1144 0 : sig_string_arg (const char *option, int argc, char *argv[], void *cookie)
1145 : {
1146 0 : struct signinfo *si = cookie;
1147 0 : char *p = argv[0];
1148 : char **s;
1149 :
1150 0 : if (argc == 0)
1151 0 : log_fatal ("Usage: %s STRING\n", option);
1152 :
1153 0 : if (strcmp (option, "--trust-scope") == 0)
1154 0 : s = &si->trust_scope;
1155 0 : else if (strcmp (option, "--key-server") == 0)
1156 0 : s = &si->key_server;
1157 0 : else if (strcmp (option, "--signers-user-id") == 0)
1158 0 : s = &si->signers_user_id;
1159 0 : else if (strcmp (option, "--policy-uri") == 0)
1160 0 : s = &si->policy_uri;
1161 : else
1162 0 : log_fatal ("Cannot handle %s\n", option);
1163 :
1164 0 : if (*s)
1165 0 : log_fatal ("%s already given.\n", option);
1166 :
1167 0 : *s = xstrdup (p);
1168 :
1169 0 : return 1;
1170 : }
1171 :
1172 : static int
1173 0 : sig_revocation_key (const char *option, int argc, char *argv[], void *cookie)
1174 : {
1175 : gpg_error_t err;
1176 0 : struct signinfo *si = cookie;
1177 : int v;
1178 : char *tail;
1179 : PKT_public_key pk;
1180 : struct revocation_key *revkey;
1181 :
1182 0 : if (argc < 2)
1183 0 : log_fatal ("Usage: %s CLASS KEYID\n", option);
1184 :
1185 0 : memset (&pk, 0, sizeof (pk));
1186 :
1187 0 : errno = 0;
1188 0 : v = strtol (argv[0], &tail, 16);
1189 0 : if (errno || (tail && *tail) || !(0 <= v && v <= 255))
1190 0 : log_fatal ("%s: Invalid class value (%s). Expected 0-255\n",
1191 : option, argv[0]);
1192 :
1193 0 : pk.req_usage = PUBKEY_USAGE_SIG;
1194 0 : err = get_pubkey_byname (NULL, NULL, &pk, argv[1], NULL, NULL, 1, 1);
1195 0 : if (err)
1196 0 : log_fatal ("looking up key %s: %s\n", argv[1], gpg_strerror (err));
1197 :
1198 0 : si->nrevocation_keys ++;
1199 0 : si->revocation_key = xrealloc (si->revocation_key,
1200 : si->nrevocation_keys
1201 : * sizeof (*si->revocation_key));
1202 0 : revkey = &si->revocation_key[si->nrevocation_keys - 1];
1203 :
1204 0 : revkey->class = v;
1205 0 : revkey->algid = pk.pubkey_algo;
1206 0 : fingerprint_from_pk (&pk, revkey->fpr, NULL);
1207 :
1208 0 : release_public_key_parts (&pk);
1209 :
1210 0 : return 2;
1211 : }
1212 :
1213 : static int
1214 0 : sig_notation (const char *option, int argc, char *argv[], void *cookie)
1215 : {
1216 0 : struct signinfo *si = cookie;
1217 0 : int is_blob = strcmp (option, "--notation") != 0;
1218 : struct notation *notation;
1219 0 : char *p = argv[0];
1220 0 : int p_free = 0;
1221 : char *data;
1222 : int data_size;
1223 : int data_len;
1224 :
1225 0 : if (argc == 0)
1226 0 : log_fatal ("Usage: %s [!<]name=value\n", option);
1227 :
1228 0 : if ((p[0] == '!' && p[1] == '<') || p[0] == '<')
1229 : /* Read from a file. */
1230 0 : {
1231 0 : char *filename = NULL;
1232 : iobuf_t in;
1233 : int prefix;
1234 :
1235 0 : if (p[0] == '<')
1236 0 : p ++;
1237 : else
1238 : {
1239 : /* Remove the '<', which string_to_notation does not
1240 : understand, and preserve the '!'. */
1241 0 : p = xstrdup (&p[1]);
1242 0 : p_free = 1;
1243 0 : p[0] = '!';
1244 : }
1245 :
1246 0 : filename = strchr (p, '=');
1247 0 : if (! filename)
1248 0 : log_fatal ("No value specified. Usage: %s [!<]name=value\n",
1249 : option);
1250 0 : filename ++;
1251 :
1252 0 : prefix = (size_t) filename - (size_t) p;
1253 :
1254 0 : errno = 0;
1255 0 : in = iobuf_open (filename);
1256 0 : if (! in)
1257 0 : log_fatal ("Opening '%s': %s\n",
1258 0 : filename, errno ? strerror (errno): "unknown error");
1259 :
1260 : /* A notation can be at most about a few dozen bytes short of
1261 : 64k. Since this is relatively small, we just allocate that
1262 : much instead of trying to dynamically size a buffer. */
1263 0 : data_size = 64 * 1024;
1264 0 : data = xmalloc (data_size);
1265 0 : log_assert (prefix <= data_size);
1266 0 : memcpy (data, p, prefix);
1267 :
1268 0 : data_len = iobuf_read (in, &data[prefix], data_size - prefix - 1);
1269 0 : if (data_len == -1)
1270 : /* EOF => 0 bytes read. */
1271 0 : data_len = 0;
1272 :
1273 0 : if (data_len == data_size - prefix - 1)
1274 : /* Technically, we should do another read and check for EOF,
1275 : but what's one byte more or less? */
1276 0 : log_fatal ("Notation data doesn't fit in the packet.\n");
1277 :
1278 0 : iobuf_close (in);
1279 :
1280 : /* NUL terminate it. */
1281 0 : data[prefix + data_len] = 0;
1282 :
1283 0 : if (p_free)
1284 0 : xfree (p);
1285 0 : p = data;
1286 0 : p_free = 1;
1287 0 : data = &p[prefix];
1288 :
1289 0 : if (is_blob)
1290 0 : p[prefix - 1] = 0;
1291 : }
1292 0 : else if (is_blob)
1293 : {
1294 0 : data = strchr (p, '=');
1295 0 : if (! data)
1296 : {
1297 0 : data = p;
1298 0 : data_len = 0;
1299 : }
1300 : else
1301 : {
1302 0 : p = xstrdup (p);
1303 0 : p_free = 1;
1304 :
1305 0 : data = strchr (p, '=');
1306 0 : log_assert (data);
1307 :
1308 : /* NUL terminate the name. */
1309 0 : *data = 0;
1310 0 : data ++;
1311 0 : data_len = strlen (data);
1312 : }
1313 : }
1314 :
1315 0 : if (is_blob)
1316 0 : notation = blob_to_notation (p, data, data_len);
1317 : else
1318 0 : notation = string_to_notation (p, 1);
1319 0 : if (! notation)
1320 0 : log_fatal ("creating notation: an unknown error occurred.\n");
1321 0 : notation->next = si->notations;
1322 0 : si->notations = notation;
1323 :
1324 0 : if (p_free)
1325 0 : xfree (p);
1326 :
1327 0 : return 1;
1328 : }
1329 :
1330 : static int
1331 0 : sig_big_endian_arg (const char *option, int argc, char *argv[], void *cookie)
1332 : {
1333 0 : struct signinfo *si = cookie;
1334 0 : char *p = argv[0];
1335 : int i;
1336 : int l;
1337 : char *bytes;
1338 :
1339 0 : if (argc == 0)
1340 0 : log_fatal ("Usage: %s HEXDIGITS\n", option);
1341 :
1342 : /* Skip a leading "0x". */
1343 0 : if (p[0] == '0' && p[1] == 'x')
1344 0 : p += 2;
1345 :
1346 0 : for (i = 0; i < strlen (p); i ++)
1347 0 : if (!hexdigitp (&p[i]))
1348 0 : log_fatal ("%s: argument ('%s') must consist of hex digits.\n",
1349 : option, p);
1350 0 : if (strlen (p) % 2 != 0)
1351 0 : log_fatal ("%s: argument ('%s') must contain an even number of hex digits.\n",
1352 : option, p);
1353 :
1354 0 : l = strlen (p) / 2;
1355 0 : bytes = xmalloc (l);
1356 0 : hex2bin (p, bytes, l);
1357 :
1358 0 : if (strcmp (option, "--key-server-preferences") == 0)
1359 : {
1360 0 : if (si->key_server_preferences)
1361 0 : log_fatal ("%s given multiple times.\n", option);
1362 0 : si->key_server_preferences = bytes;
1363 0 : si->key_server_preferences_len = l;
1364 : }
1365 0 : else if (strcmp (option, "--key-flags") == 0)
1366 : {
1367 0 : if (si->key_flags)
1368 0 : log_fatal ("%s given multiple times.\n", option);
1369 0 : si->key_flags = bytes;
1370 0 : si->key_flags_len = l;
1371 : }
1372 0 : else if (strcmp (option, "--features") == 0)
1373 : {
1374 0 : if (si->features)
1375 0 : log_fatal ("%s given multiple times.\n", option);
1376 0 : si->features = bytes;
1377 0 : si->features_len = l;
1378 : }
1379 : else
1380 0 : log_fatal ("Cannot handle %s\n", option);
1381 :
1382 0 : return 1;
1383 : }
1384 :
1385 : static int
1386 0 : sig_reason_for_revocation (const char *option, int argc, char *argv[], void *cookie)
1387 : {
1388 0 : struct signinfo *si = cookie;
1389 : int v;
1390 : char *tail;
1391 :
1392 0 : if (argc < 2)
1393 0 : log_fatal ("Usage: %s REASON_CODE REASON_STRING\n", option);
1394 :
1395 0 : errno = 0;
1396 0 : v = strtol (argv[0], &tail, 16);
1397 0 : if (errno || (tail && *tail) || !(0 <= v && v <= 255))
1398 0 : log_fatal ("%s: Invalid reason code (%s). Expected 0-255\n",
1399 : option, argv[0]);
1400 :
1401 0 : if (si->reason_for_revocation)
1402 0 : log_fatal ("%s given multiple times.\n", option);
1403 :
1404 0 : si->reason_for_revocation_code = v;
1405 0 : si->reason_for_revocation = xstrdup (argv[1]);
1406 :
1407 0 : return 2;
1408 : }
1409 :
1410 : static int
1411 0 : sig_corrupt (const char *option, int argc, char *argv[], void *cookie)
1412 : {
1413 0 : struct signinfo *si = cookie;
1414 :
1415 : (void) option;
1416 : (void) argc;
1417 : (void) argv;
1418 : (void) cookie;
1419 :
1420 0 : si->corrupt = 1;
1421 :
1422 0 : return 0;
1423 : }
1424 :
1425 : static struct option sig_options[] = {
1426 : { "--issuer", sig_issuer,
1427 : "The key to use to generate the signature."},
1428 : { "--issuer-keyid", sig_issuer_keyid,
1429 : "Set the issuer's key id. This is useful for creating a "
1430 : "self-signature. As a special case, the value \"self\" refers "
1431 : "to the primary key's key id. "
1432 : "(RFC 4880, Section 5.2.3.5)" },
1433 : { "--pk", sig_pk,
1434 : "The primary keyas an index into the components (keys and uids) "
1435 : "created so far where the first component has the index 0." },
1436 : { "--sk", sig_pk,
1437 : "The subkey as an index into the components (keys and uids) created "
1438 : "so far where the first component has the index 0. Only needed for "
1439 : "0x18, 0x19, and 0x28 signatures." },
1440 : { "--user-id", sig_user_id,
1441 : "The user id as an index into the components (keys and uids) created "
1442 : "so far where the first component has the index 0. Only needed for "
1443 : "0x10-0x13 and 0x30 signatures." },
1444 : { "--class", sig_class,
1445 : "The signature's class. Valid values are "
1446 : "0x10-0x13 (user id and primary-key certification), "
1447 : "0x18 (subkey binding), "
1448 : "0x19 (primary key binding), "
1449 : "0x1f (direct primary key signature), "
1450 : "0x20 (key revocation), "
1451 : "0x28 (subkey revocation), and "
1452 : "0x30 (certification revocation)."
1453 : },
1454 : { "--digest", sig_digest, "The digest algorithm" },
1455 : { "--timestamp", sig_timestamp,
1456 : "The signature's creation time. " TIMESTAMP_HELP " 0 means now. "
1457 : "(RFC 4880, Section 5.2.3.4)" },
1458 : { "--key-expiration", sig_expiration,
1459 : "The number of days until the associated key expires. To specify "
1460 : "seconds, prefix the value with \"seconds=\". It is also possible "
1461 : "to use 'y', 'm' and 'w' as simple multipliers. For instance, 2y "
1462 : "means 2 years, etc. "
1463 : "(RFC 4880, Section 5.2.3.6)" },
1464 : { "--cipher-algos", sig_int_list,
1465 : "A comma separated list of the preferred cipher algorithms (identified by "
1466 : "their number, see RFC 4880, Section 9). "
1467 : "(RFC 4880, Section 5.2.3.7)" },
1468 : { "--digest-algos", sig_int_list,
1469 : "A comma separated list of the preferred algorithms (identified by "
1470 : "their number, see RFC 4880, Section 9). "
1471 : "(RFC 4880, Section 5.2.3.8)" },
1472 : { "--compress-algos", sig_int_list,
1473 : "A comma separated list of the preferred algorithms (identified by "
1474 : "their number, see RFC 4880, Section 9)."
1475 : "(RFC 4880, Section 5.2.3.9)" },
1476 : { "--expiration", sig_expiration,
1477 : "The number of days until the signature expires. To specify seconds, "
1478 : "prefix the value with \"seconds=\". It is also possible to use 'y', "
1479 : "'m' and 'w' as simple multipliers. For instance, 2y means 2 years, "
1480 : "etc. "
1481 : "(RFC 4880, Section 5.2.3.10)" },
1482 : { "--exportable", sig_flag,
1483 : "Mark this signature as exportable (1) or local (0). "
1484 : "(RFC 4880, Section 5.2.3.11)" },
1485 : { "--revocable", sig_flag,
1486 : "Mark this signature as revocable (1, revocations are ignored) "
1487 : "or non-revocable (0). "
1488 : "(RFC 4880, Section 5.2.3.12)" },
1489 : { "--trust-level", sig_trust_level,
1490 : "Set the trust level. This takes two integer arguments (0-255): "
1491 : "the trusted-introducer level and the degree of trust. "
1492 : "(RFC 4880, Section 5.2.3.13.)" },
1493 : { "--trust-scope", sig_string_arg,
1494 : "A regular expression that limits the scope of --trust-level. "
1495 : "(RFC 4880, Section 5.2.3.14.)" },
1496 : { "--revocation-key", sig_revocation_key,
1497 : "Specify a designated revoker. Takes two arguments: the class "
1498 : "(normally 0x80 or 0xC0 (sensitive)) and the key id of the "
1499 : "designatured revoker. May be given multiple times. "
1500 : "(RFC 4880, Section 5.2.3.15)" },
1501 : { "--notation", sig_notation,
1502 : "Add a human-readable notation of the form \"[!<]name=value\" where "
1503 : "\"!\" means that the critical flag should be set and \"<\" means "
1504 : "that VALUE is a file to read the data from. "
1505 : "(RFC 4880, Section 5.2.3.16)" },
1506 : { "--notation-binary", sig_notation,
1507 : "Add a binary notation of the form \"[!<]name=value\" where "
1508 : "\"!\" means that the critical flag should be set and \"<\" means "
1509 : "that VALUE is a file to read the data from. "
1510 : "(RFC 4880, Section 5.2.3.16)" },
1511 : { "--key-server-preferences", sig_big_endian_arg,
1512 : "Big-endian number encoding the keyserver preferences. "
1513 : "(RFC 4880, Section 5.2.3.17)" },
1514 : { "--key-server", sig_string_arg,
1515 : "The preferred keyserver. (RFC 4880, Section 5.2.3.18)" },
1516 : { "--primary-user-id", sig_flag,
1517 : "Sets the primary user id flag. (RFC 4880, Section 5.2.3.19)" },
1518 : { "--policy-uri", sig_string_arg,
1519 : "URI of a document that describes the issuer's signing policy. "
1520 : "(RFC 4880, Section 5.2.3.20)" },
1521 : { "--key-flags", sig_big_endian_arg,
1522 : "Big-endian number encoding the key flags. "
1523 : "(RFC 4880, Section 5.2.3.21)" },
1524 : { "--signers-user-id", sig_string_arg,
1525 : "The user id (as a string) responsible for the signing. "
1526 : "(RFC 4880, Section 5.2.3.22)" },
1527 : { "--reason-for-revocation", sig_reason_for_revocation,
1528 : "Takes two arguments: a reason for revocation code and a "
1529 : "user-provided string. "
1530 : "(RFC 4880, Section 5.2.3.23)" },
1531 : { "--features", sig_big_endian_arg,
1532 : "Big-endian number encoding the feature flags. "
1533 : "(RFC 4880, Section 5.2.3.24)" },
1534 : { "--signature-target", NULL,
1535 : "Takes three arguments: the target signature's public key algorithm "
1536 : " (as an integer), the hash algorithm (as an integer) and the hash "
1537 : " (as a hexadecimal string). "
1538 : "(RFC 4880, Section 5.2.3.25)" },
1539 : { "--embedded-signature", NULL,
1540 : "An embedded signature. This must be immediately followed by a "
1541 : "signature packet (created using --signature ...) or a filename "
1542 : "containing the packet."
1543 : "(RFC 4880, Section 5.2.3.26)" },
1544 : { "--hashed", NULL,
1545 : "The following attributes will be placed in the hashed area of "
1546 : "the signature. (This is the default and it reset at the end of"
1547 : "each signature.)" },
1548 : { "--unhashed", NULL,
1549 : "The following attributes will be placed in the unhashed area of "
1550 : "the signature (and thus not integrity protected)." },
1551 : { "--corrupt", sig_corrupt,
1552 : "Corrupt the signature." },
1553 : { NULL, NULL,
1554 : "Example:\n\n"
1555 : " $ gpgcompose --public-key $KEYID --user-id USERID \\\n"
1556 : " --signature --class 0x10 --issuer $KEYID --issuer-keyid self \\\n"
1557 : " | " GPG_NAME " --list-packets"}
1558 : };
1559 :
1560 : static int
1561 0 : mksubpkt_callback (PKT_signature *sig, void *cookie)
1562 : {
1563 0 : struct signinfo *si = cookie;
1564 : int i;
1565 :
1566 0 : if (si->key_expiration)
1567 : {
1568 : char buf[4];
1569 0 : buf[0] = (si->key_expiration >> 24) & 0xff;
1570 0 : buf[1] = (si->key_expiration >> 16) & 0xff;
1571 0 : buf[2] = (si->key_expiration >> 8) & 0xff;
1572 0 : buf[3] = si->key_expiration & 0xff;
1573 0 : build_sig_subpkt (sig, SIGSUBPKT_KEY_EXPIRE, buf, 4);
1574 : }
1575 :
1576 0 : if (si->cipher_algorithms)
1577 0 : build_sig_subpkt (sig, SIGSUBPKT_PREF_SYM,
1578 0 : si->cipher_algorithms,
1579 0 : si->cipher_algorithms_len);
1580 :
1581 0 : if (si->digest_algorithms)
1582 0 : build_sig_subpkt (sig, SIGSUBPKT_PREF_HASH,
1583 0 : si->digest_algorithms,
1584 0 : si->digest_algorithms_len);
1585 :
1586 0 : if (si->compress_algorithms)
1587 0 : build_sig_subpkt (sig, SIGSUBPKT_PREF_COMPR,
1588 0 : si->compress_algorithms,
1589 0 : si->compress_algorithms_len);
1590 :
1591 0 : if (si->exportable_set)
1592 : {
1593 0 : char buf = si->exportable;
1594 0 : build_sig_subpkt (sig, SIGSUBPKT_EXPORTABLE, &buf, 1);
1595 : }
1596 :
1597 0 : if (si->trust_level_set)
1598 0 : build_sig_subpkt (sig, SIGSUBPKT_TRUST,
1599 0 : si->trust_args, sizeof (si->trust_args));
1600 :
1601 0 : if (si->trust_scope)
1602 0 : build_sig_subpkt (sig, SIGSUBPKT_REGEXP,
1603 0 : si->trust_scope, strlen (si->trust_scope));
1604 :
1605 0 : for (i = 0; i < si->nrevocation_keys; i ++)
1606 : {
1607 0 : struct revocation_key *revkey = &si->revocation_key[i];
1608 0 : gpg_error_t err = keygen_add_revkey (sig, revkey);
1609 0 : if (err)
1610 : {
1611 : u32 keyid[2];
1612 0 : keyid_from_fingerprint (revkey->fpr, 20, keyid);
1613 0 : log_fatal ("adding revocation key %s: %s\n",
1614 : keystr (keyid), gpg_strerror (err));
1615 : }
1616 : }
1617 :
1618 : /* keygen_add_revkey sets revocable=0 so be sure to do this after
1619 : adding the rev keys. */
1620 0 : if (si->revocable_set)
1621 : {
1622 0 : char buf = si->revocable;
1623 0 : build_sig_subpkt (sig, SIGSUBPKT_REVOCABLE, &buf, 1);
1624 : }
1625 :
1626 0 : keygen_add_notations (sig, si->notations);
1627 :
1628 0 : if (si->key_server_preferences)
1629 0 : build_sig_subpkt (sig, SIGSUBPKT_KS_FLAGS,
1630 0 : si->key_server_preferences,
1631 0 : si->key_server_preferences_len);
1632 :
1633 0 : if (si->key_server)
1634 0 : build_sig_subpkt (sig, SIGSUBPKT_PREF_KS,
1635 0 : si->key_server, strlen (si->key_server));
1636 :
1637 0 : if (si->primary_user_id_set)
1638 : {
1639 0 : char buf = si->primary_user_id;
1640 0 : build_sig_subpkt (sig, SIGSUBPKT_PRIMARY_UID, &buf, 1);
1641 : }
1642 :
1643 0 : if (si->policy_uri)
1644 0 : build_sig_subpkt (sig, SIGSUBPKT_POLICY,
1645 0 : si->policy_uri, strlen (si->policy_uri));
1646 :
1647 0 : if (si->key_flags)
1648 0 : build_sig_subpkt (sig, SIGSUBPKT_KEY_FLAGS,
1649 0 : si->key_flags, si->key_flags_len);
1650 :
1651 0 : if (si->signers_user_id)
1652 0 : build_sig_subpkt (sig, SIGSUBPKT_SIGNERS_UID,
1653 0 : si->signers_user_id, strlen (si->signers_user_id));
1654 :
1655 0 : if (si->reason_for_revocation)
1656 : {
1657 0 : int l = 1 + strlen (si->reason_for_revocation);
1658 0 : char buf[l];
1659 :
1660 0 : buf[0] = si->reason_for_revocation_code;
1661 0 : memcpy (&buf[1], si->reason_for_revocation, l - 1);
1662 :
1663 0 : build_sig_subpkt (sig, SIGSUBPKT_REVOC_REASON, buf, l);
1664 : }
1665 :
1666 0 : if (si->features)
1667 0 : build_sig_subpkt (sig, SIGSUBPKT_FEATURES,
1668 0 : si->features, si->features_len);
1669 :
1670 0 : return 0;
1671 : }
1672 :
1673 : static int
1674 0 : signature (const char *option, int argc, char *argv[], void *cookie)
1675 : {
1676 : gpg_error_t err;
1677 0 : iobuf_t out = cookie;
1678 : struct signinfo si;
1679 : int processed;
1680 : PKT_public_key *pk;
1681 : PKT_signature *sig;
1682 : PACKET pkt;
1683 : u32 keyid_orig[2], keyid[2];
1684 :
1685 : (void) option;
1686 :
1687 0 : memset (&si, 0, sizeof (si));
1688 0 : memset (&pkt, 0, sizeof (pkt));
1689 :
1690 0 : processed = process_options (option,
1691 : major_options,
1692 : sig_options, &si,
1693 : global_options, NULL,
1694 : argc, argv);
1695 :
1696 0 : if (ncomponents)
1697 : {
1698 0 : int pkttype = components[ncomponents - 1].pkttype;
1699 :
1700 0 : if (pkttype == PKT_PUBLIC_KEY)
1701 : {
1702 0 : if (! si.class)
1703 : /* Direct key sig. */
1704 0 : si.class = 0x1F;
1705 : }
1706 0 : else if (pkttype == PKT_PUBLIC_SUBKEY)
1707 : {
1708 0 : if (! si.sk)
1709 0 : si.sk = components[ncomponents - 1].pkt.public_key;
1710 0 : if (! si.class)
1711 : /* Subkey binding sig. */
1712 0 : si.class = 0x18;
1713 : }
1714 0 : else if (pkttype == PKT_USER_ID)
1715 : {
1716 0 : if (! si.uid)
1717 0 : si.uid = components[ncomponents - 1].pkt.user_id;
1718 0 : if (! si.class)
1719 : /* Certification of a user id and public key packet. */
1720 0 : si.class = 0x10;
1721 : }
1722 : }
1723 :
1724 0 : pk = NULL;
1725 0 : if (! si.pk || ! si.issuer_pk)
1726 : /* No primary key specified. Default to the first one that we
1727 : find. */
1728 : {
1729 : int i;
1730 0 : for (i = 0; i < ncomponents; i ++)
1731 0 : if (components[i].pkttype == PKT_PUBLIC_KEY)
1732 : {
1733 0 : pk = components[i].pkt.public_key;
1734 0 : break;
1735 : }
1736 : }
1737 :
1738 0 : if (! si.pk)
1739 : {
1740 0 : if (! pk)
1741 0 : log_fatal ("%s: no primary key given and no primary key available",
1742 : "--pk");
1743 0 : si.pk = pk;
1744 : }
1745 0 : if (! si.issuer_pk)
1746 : {
1747 0 : if (! pk)
1748 0 : log_fatal ("%s: no issuer key given and no primary key available",
1749 : "--issuer");
1750 0 : si.issuer_pk = pk;
1751 : }
1752 :
1753 0 : if (si.class == 0x18 || si.class == 0x19 || si.class == 0x28)
1754 : /* Requires the primary key and a subkey. */
1755 : {
1756 0 : if (! si.sk)
1757 0 : log_fatal ("sig class 0x%x requires a subkey (--sk)\n", si.class);
1758 : }
1759 0 : else if (si.class == 0x10
1760 0 : || si.class == 0x11
1761 0 : || si.class == 0x12
1762 0 : || si.class == 0x13
1763 0 : || si.class == 0x30)
1764 : /* Requires the primary key and a user id. */
1765 : {
1766 0 : if (! si.uid)
1767 0 : log_fatal ("sig class 0x%x requires a uid (--uid)\n", si.class);
1768 : }
1769 0 : else if (si.class == 0x1F || si.class == 0x20)
1770 : /* Just requires the primary key. */
1771 : ;
1772 : else
1773 0 : log_fatal ("Unsupported signature class: 0x%x\n", si.class);
1774 :
1775 0 : sig = xmalloc_clear (sizeof (*sig));
1776 :
1777 : /* Save SI.ISSUER_PK->KEYID. */
1778 0 : keyid_copy (keyid_orig, pk_keyid (si.issuer_pk));
1779 0 : if (si.issuer_keyid[0] || si.issuer_keyid[1])
1780 0 : keyid_copy (si.issuer_pk->keyid, si.issuer_keyid);
1781 0 : else if (si.issuer_keyid_self)
1782 : {
1783 0 : PKT_public_key *pripk = primary_key();
1784 0 : if (! pripk)
1785 0 : log_fatal ("--issuer-keyid self given, but no primary key available.\n");
1786 0 : keyid_copy (si.issuer_pk->keyid, pk_keyid (pripk));
1787 : }
1788 :
1789 : /* Changing the issuer's key id is fragile. Check to make sure
1790 : make_keysig_packet didn't recompute the keyid. */
1791 0 : keyid_copy (keyid, si.issuer_pk->keyid);
1792 0 : err = make_keysig_packet (&sig, si.pk, si.uid, si.sk, si.issuer_pk,
1793 : si.class, si.digest_algo,
1794 : si.timestamp, si.expiration,
1795 : mksubpkt_callback, &si, NULL);
1796 0 : log_assert (keyid_cmp (keyid, si.issuer_pk->keyid) == 0);
1797 0 : if (err)
1798 0 : log_fatal ("Generating signature: %s\n", gpg_strerror (err));
1799 :
1800 : /* Restore SI.PK->KEYID. */
1801 0 : keyid_copy (si.issuer_pk->keyid, keyid_orig);
1802 :
1803 0 : if (si.corrupt)
1804 : {
1805 : /* Set the top 32-bits to 0xBAD0DEAD. */
1806 0 : int bits = gcry_mpi_get_nbits (sig->data[0]);
1807 0 : gcry_mpi_t x = gcry_mpi_new (0);
1808 0 : gcry_mpi_add_ui (x, x, 0xBAD0DEAD);
1809 0 : gcry_mpi_lshift (x, x, bits > 32 ? bits - 32 : bits);
1810 0 : gcry_mpi_clear_highbit (sig->data[0], bits > 32 ? bits - 32 : 0);
1811 0 : gcry_mpi_add (sig->data[0], sig->data[0], x);
1812 0 : gcry_mpi_release (x);
1813 : }
1814 :
1815 0 : pkt.pkttype = PKT_SIGNATURE;
1816 0 : pkt.pkt.signature = sig;
1817 :
1818 0 : err = build_packet (out, &pkt);
1819 0 : if (err)
1820 0 : log_fatal ("serializing public key packet: %s\n", gpg_strerror (err));
1821 :
1822 0 : debug ("Wrote signature packet:\n");
1823 0 : dump_component (&pkt);
1824 :
1825 0 : xfree (sig);
1826 0 : release_kbnode (si.issuer_kb);
1827 0 : xfree (si.revocation_key);
1828 :
1829 0 : return processed;
1830 : }
1831 :
1832 : struct sk_esk_info
1833 : {
1834 : /* The cipher used for encrypting the session key (when a session
1835 : key is used). */
1836 : int cipher;
1837 : /* The cipher used for encryping the SED packet. */
1838 : int sed_cipher;
1839 :
1840 : /* S2K related data. */
1841 : int hash;
1842 : int mode;
1843 : int mode_set;
1844 : byte salt[8];
1845 : int salt_set;
1846 : int iterations;
1847 :
1848 : /* If applying the S2K function to the passphrase is the session key
1849 : or if it is the decryption key for the session key. */
1850 : int s2k_is_session_key;
1851 : /* Generate a new, random session key. */
1852 : int new_session_key;
1853 :
1854 : /* The unencrypted session key. */
1855 : int session_key_len;
1856 : char *session_key;
1857 :
1858 : char *password;
1859 : };
1860 :
1861 : static int
1862 0 : sk_esk_cipher (const char *option, int argc, char *argv[], void *cookie)
1863 : {
1864 0 : struct sk_esk_info *si = cookie;
1865 0 : char *usage = "integer|IDEA|3DES|CAST5|BLOWFISH|AES|AES192|AES256|CAMELLIA128|CAMELLIA192|CAMELLIA256";
1866 : int cipher;
1867 :
1868 0 : if (argc == 0)
1869 0 : log_fatal ("Usage: %s %s\n", option, usage);
1870 :
1871 0 : if (strcasecmp (argv[0], "IDEA") == 0)
1872 0 : cipher = CIPHER_ALGO_IDEA;
1873 0 : else if (strcasecmp (argv[0], "3DES") == 0)
1874 0 : cipher = CIPHER_ALGO_3DES;
1875 0 : else if (strcasecmp (argv[0], "CAST5") == 0)
1876 0 : cipher = CIPHER_ALGO_CAST5;
1877 0 : else if (strcasecmp (argv[0], "BLOWFISH") == 0)
1878 0 : cipher = CIPHER_ALGO_BLOWFISH;
1879 0 : else if (strcasecmp (argv[0], "AES") == 0)
1880 0 : cipher = CIPHER_ALGO_AES;
1881 0 : else if (strcasecmp (argv[0], "AES192") == 0)
1882 0 : cipher = CIPHER_ALGO_AES192;
1883 0 : else if (strcasecmp (argv[0], "TWOFISH") == 0)
1884 0 : cipher = CIPHER_ALGO_TWOFISH;
1885 0 : else if (strcasecmp (argv[0], "CAMELLIA128") == 0)
1886 0 : cipher = CIPHER_ALGO_CAMELLIA128;
1887 0 : else if (strcasecmp (argv[0], "CAMELLIA192") == 0)
1888 0 : cipher = CIPHER_ALGO_CAMELLIA192;
1889 0 : else if (strcasecmp (argv[0], "CAMELLIA256") == 0)
1890 0 : cipher = CIPHER_ALGO_CAMELLIA256;
1891 : else
1892 : {
1893 : char *tail;
1894 : int v;
1895 :
1896 0 : errno = 0;
1897 0 : v = strtol (argv[0], &tail, 0);
1898 0 : if (errno || (tail && *tail) || ! valid_cipher (v))
1899 0 : log_fatal ("Invalid or unsupported value. Usage: %s %s\n",
1900 : option, usage);
1901 :
1902 0 : cipher = v;
1903 : }
1904 :
1905 0 : if (strcmp (option, "--cipher") == 0)
1906 : {
1907 0 : if (si->cipher)
1908 0 : log_fatal ("%s given multiple times.", option);
1909 0 : si->cipher = cipher;
1910 : }
1911 0 : else if (strcmp (option, "--sed-cipher") == 0)
1912 : {
1913 0 : if (si->sed_cipher)
1914 0 : log_fatal ("%s given multiple times.", option);
1915 0 : si->sed_cipher = cipher;
1916 : }
1917 :
1918 0 : return 1;
1919 : }
1920 :
1921 : static int
1922 0 : sk_esk_mode (const char *option, int argc, char *argv[], void *cookie)
1923 : {
1924 0 : struct sk_esk_info *si = cookie;
1925 0 : char *usage = "integer|simple|salted|iterated";
1926 :
1927 0 : if (argc == 0)
1928 0 : log_fatal ("Usage: %s %s\n", option, usage);
1929 :
1930 0 : if (si->mode)
1931 0 : log_fatal ("%s given multiple times.", option);
1932 :
1933 0 : if (strcasecmp (argv[0], "simple") == 0)
1934 0 : si->mode = 0;
1935 0 : else if (strcasecmp (argv[0], "salted") == 0)
1936 0 : si->mode = 1;
1937 0 : else if (strcasecmp (argv[0], "iterated") == 0)
1938 0 : si->mode = 3;
1939 : else
1940 : {
1941 : char *tail;
1942 : int v;
1943 :
1944 0 : errno = 0;
1945 0 : v = strtol (argv[0], &tail, 0);
1946 0 : if (errno || (tail && *tail) || ! (v == 0 || v == 1 || v == 3))
1947 0 : log_fatal ("Invalid or unsupported value. Usage: %s %s\n",
1948 : option, usage);
1949 :
1950 0 : si->mode = v;
1951 : }
1952 :
1953 0 : si->mode_set = 1;
1954 :
1955 0 : return 1;
1956 : }
1957 :
1958 : static int
1959 0 : sk_esk_hash_algorithm (const char *option, int argc, char *argv[], void *cookie)
1960 : {
1961 0 : struct sk_esk_info *si = cookie;
1962 0 : char *usage = "integer|MD5|SHA1|RMD160|SHA256|SHA384|SHA512|SHA224";
1963 :
1964 0 : if (argc == 0)
1965 0 : log_fatal ("Usage: %s %s\n", option, usage);
1966 :
1967 0 : if (si->hash)
1968 0 : log_fatal ("%s given multiple times.", option);
1969 :
1970 0 : if (strcasecmp (argv[0], "MD5") == 0)
1971 0 : si->hash = DIGEST_ALGO_MD5;
1972 0 : else if (strcasecmp (argv[0], "SHA1") == 0)
1973 0 : si->hash = DIGEST_ALGO_SHA1;
1974 0 : else if (strcasecmp (argv[0], "RMD160") == 0)
1975 0 : si->hash = DIGEST_ALGO_RMD160;
1976 0 : else if (strcasecmp (argv[0], "SHA256") == 0)
1977 0 : si->hash = DIGEST_ALGO_SHA256;
1978 0 : else if (strcasecmp (argv[0], "SHA384") == 0)
1979 0 : si->hash = DIGEST_ALGO_SHA384;
1980 0 : else if (strcasecmp (argv[0], "SHA512") == 0)
1981 0 : si->hash = DIGEST_ALGO_SHA512;
1982 0 : else if (strcasecmp (argv[0], "SHA224") == 0)
1983 0 : si->hash = DIGEST_ALGO_SHA224;
1984 : else
1985 : {
1986 : char *tail;
1987 : int v;
1988 :
1989 0 : errno = 0;
1990 0 : v = strtol (argv[0], &tail, 0);
1991 0 : if (errno || (tail && *tail)
1992 0 : || ! (v == DIGEST_ALGO_MD5
1993 0 : || v == DIGEST_ALGO_SHA1
1994 0 : || v == DIGEST_ALGO_RMD160
1995 0 : || v == DIGEST_ALGO_SHA256
1996 0 : || v == DIGEST_ALGO_SHA384
1997 0 : || v == DIGEST_ALGO_SHA512
1998 : || v == DIGEST_ALGO_SHA224))
1999 0 : log_fatal ("Invalid or unsupported value. Usage: %s %s\n",
2000 : option, usage);
2001 :
2002 0 : si->hash = v;
2003 : }
2004 :
2005 0 : return 1;
2006 : }
2007 :
2008 : static int
2009 0 : sk_esk_salt (const char *option, int argc, char *argv[], void *cookie)
2010 : {
2011 0 : struct sk_esk_info *si = cookie;
2012 0 : char *usage = "16-HEX-CHARACTERS";
2013 0 : char *p = argv[0];
2014 :
2015 0 : if (argc == 0)
2016 0 : log_fatal ("Usage: %s %s\n", option, usage);
2017 :
2018 0 : if (si->salt_set)
2019 0 : log_fatal ("%s given multiple times.", option);
2020 :
2021 0 : if (p[0] == '0' && p[1] == 'x')
2022 0 : p += 2;
2023 :
2024 0 : if (strlen (p) != 16)
2025 0 : log_fatal ("%s: Salt must be exactly 16 hexadecimal characters (have: %zd)\n",
2026 : option, strlen (p));
2027 :
2028 0 : if (hex2bin (p, si->salt, sizeof (si->salt)) == -1)
2029 0 : log_fatal ("%s: Salt must only contain hexadecimal characters\n",
2030 : option);
2031 :
2032 0 : si->salt_set = 1;
2033 :
2034 0 : return 1;
2035 : }
2036 :
2037 : static int
2038 0 : sk_esk_iterations (const char *option, int argc, char *argv[], void *cookie)
2039 : {
2040 0 : struct sk_esk_info *si = cookie;
2041 0 : char *usage = "ITERATION-COUNT";
2042 : char *tail;
2043 : int v;
2044 :
2045 0 : if (argc == 0)
2046 0 : log_fatal ("Usage: %s %s\n", option, usage);
2047 :
2048 0 : errno = 0;
2049 0 : v = strtol (argv[0], &tail, 0);
2050 0 : if (errno || (tail && *tail) || v < 0)
2051 0 : log_fatal ("%s: Non-negative integer expected.\n", option);
2052 :
2053 0 : si->iterations = v;
2054 :
2055 0 : return 1;
2056 : }
2057 :
2058 : static int
2059 0 : sk_esk_session_key (const char *option, int argc, char *argv[], void *cookie)
2060 : {
2061 0 : struct sk_esk_info *si = cookie;
2062 0 : char *usage = "HEX-CHARACTERS|auto|none";
2063 0 : char *p = argv[0];
2064 : struct session_key sk;
2065 :
2066 0 : if (argc == 0)
2067 0 : log_fatal ("Usage: %s %s\n", option, usage);
2068 :
2069 0 : if (si->session_key || si->s2k_is_session_key
2070 0 : || si->new_session_key)
2071 0 : log_fatal ("%s given multiple times.", option);
2072 :
2073 0 : if (strcasecmp (p, "none") == 0)
2074 : {
2075 0 : si->s2k_is_session_key = 1;
2076 0 : return 1;
2077 : }
2078 0 : if (strcasecmp (p, "new") == 0)
2079 : {
2080 0 : si->new_session_key = 1;
2081 0 : return 1;
2082 : }
2083 0 : if (strcasecmp (p, "auto") == 0)
2084 0 : return 1;
2085 :
2086 0 : sk = parse_session_key (option, p, 0);
2087 :
2088 0 : if (si->session_key)
2089 0 : log_fatal ("%s given multiple times.", option);
2090 :
2091 0 : if (sk.algo)
2092 0 : si->sed_cipher = sk.algo;
2093 :
2094 0 : si->session_key_len = sk.keylen;
2095 0 : si->session_key = sk.key;
2096 :
2097 0 : return 1;
2098 : }
2099 :
2100 : static int
2101 0 : sk_esk_password (const char *option, int argc, char *argv[], void *cookie)
2102 : {
2103 0 : struct sk_esk_info *si = cookie;
2104 0 : char *usage = "PASSWORD";
2105 :
2106 0 : if (argc == 0)
2107 0 : log_fatal ("Usage: --sk-esk %s\n", usage);
2108 :
2109 0 : if (si->password)
2110 0 : log_fatal ("%s given multiple times.", option);
2111 :
2112 0 : si->password = xstrdup (argv[0]);
2113 :
2114 0 : return 1;
2115 : }
2116 :
2117 : static struct option sk_esk_options[] = {
2118 : { "--cipher", sk_esk_cipher,
2119 : "The encryption algorithm for encrypting the session key. "
2120 : "One of IDEA, 3DES, CAST5, BLOWFISH, AES (default), AES192, "
2121 : "AES256, TWOFISH, CAMELLIA128, CAMELLIA192, or CAMELLIA256." },
2122 : { "--sed-cipher", sk_esk_cipher,
2123 : "The encryption algorithm for encrypting the SED packet. "
2124 : "One of IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, "
2125 : "AES256 (default), TWOFISH, CAMELLIA128, CAMELLIA192, or CAMELLIA256." },
2126 : { "--mode", sk_esk_mode,
2127 : "The S2K mode. Either one of the strings \"simple\", \"salted\" "
2128 : "or \"iterated\" or an integer." },
2129 : { "--hash", sk_esk_hash_algorithm,
2130 : "The hash algorithm to used to derive the key. One of "
2131 : "MD5, SHA1 (default), RMD160, SHA256, SHA384, SHA512, or SHA224." },
2132 : { "--salt", sk_esk_salt,
2133 : "The S2K salt encoded as 16 hexadecimal characters. One needed "
2134 : "if the S2K function is in salted or iterated mode." },
2135 : { "--iterations", sk_esk_iterations,
2136 : "The iteration count. If not provided, a reasonable value is chosen. "
2137 : "Note: due to the encoding scheme, not every value is valid. For "
2138 : "convenience, the provided value will be rounded appropriately. "
2139 : "Only needed if the S2K function is in iterated mode." },
2140 : { "--session-key", sk_esk_session_key,
2141 : "The session key to be encrypted by the S2K function as a hexadecimal "
2142 : "string. If this is \"new\", then a new session key is generated."
2143 : "If this is \"auto\", then either the last session key is "
2144 : "used, if the was none, one is generated. If this is \"none\", then "
2145 : "the session key is the result of applying the S2K algorithms to the "
2146 : "password. The session key may be prefaced with an integer and a colon "
2147 : "to indicate the cipher to use for the SED packet (making --sed-cipher "
2148 : "unnecessary and allowing the direct use of the result of "
2149 : "\"" GPG_NAME " --show-session-key\")." },
2150 : { "", sk_esk_password, "The password." },
2151 : { NULL, NULL,
2152 : "Example:\n\n"
2153 : " $ gpgcompose --sk-esk foobar --encrypted \\\n"
2154 : " --literal --value foo | " GPG_NAME " --list-packets" }
2155 : };
2156 :
2157 : static int
2158 0 : sk_esk (const char *option, int argc, char *argv[], void *cookie)
2159 : {
2160 0 : iobuf_t out = cookie;
2161 : gpg_error_t err;
2162 : int processed;
2163 : struct sk_esk_info si;
2164 : DEK sesdek;
2165 : DEK s2kdek;
2166 : PKT_symkey_enc *ske;
2167 : PACKET pkt;
2168 :
2169 0 : memset (&si, 0, sizeof (si));
2170 :
2171 0 : processed = process_options (option,
2172 : major_options,
2173 : sk_esk_options, &si,
2174 : global_options, NULL,
2175 : argc, argv);
2176 :
2177 0 : if (! si.password)
2178 0 : log_fatal ("%s: missing password. Usage: %s PASSWORD", option, option);
2179 :
2180 : /* Fill in defaults, if appropriate. */
2181 0 : if (! si.cipher)
2182 0 : si.cipher = CIPHER_ALGO_AES;
2183 :
2184 0 : if (! si.sed_cipher)
2185 0 : si.sed_cipher = CIPHER_ALGO_AES256;
2186 :
2187 0 : if (! si.hash)
2188 0 : si.hash = DIGEST_ALGO_SHA1;
2189 :
2190 0 : if (! si.mode_set)
2191 : /* Salted and iterated. */
2192 0 : si.mode = 3;
2193 :
2194 0 : if (si.mode != 0 && ! si.salt_set)
2195 : /* Generate a salt. */
2196 0 : gcry_randomize (si.salt, 8, GCRY_STRONG_RANDOM);
2197 :
2198 0 : if (si.mode == 0)
2199 : {
2200 0 : if (si.iterations)
2201 0 : log_info ("%s: --iterations provided, but not used for mode=0\n",
2202 : option);
2203 0 : si.iterations = 0;
2204 : }
2205 0 : else if (! si.iterations)
2206 0 : si.iterations = 10000;
2207 :
2208 0 : memset (&sesdek, 0, sizeof (sesdek));
2209 : /* The session key is used to encrypt the SED packet. */
2210 0 : sesdek.algo = si.sed_cipher;
2211 0 : if (si.session_key)
2212 : /* Copy the unencrypted session key into SESDEK. */
2213 : {
2214 0 : sesdek.keylen = openpgp_cipher_get_algo_keylen (sesdek.algo);
2215 0 : if (sesdek.keylen != si.session_key_len)
2216 0 : log_fatal ("%s: Cipher algorithm requires a %d byte session key, but provided session key is %d bytes.",
2217 : option, sesdek.keylen, si.session_key_len);
2218 :
2219 0 : log_assert (sesdek.keylen <= sizeof (sesdek.key));
2220 0 : memcpy (sesdek.key, si.session_key, sesdek.keylen);
2221 : }
2222 0 : else if (! si.s2k_is_session_key || si.new_session_key)
2223 : /* We need a session key, but one wasn't provided. Generate it. */
2224 0 : make_session_key (&sesdek);
2225 :
2226 : /* The encrypted session key needs 1 + SESDEK.KEYLEN bytes of
2227 : space. */
2228 0 : ske = xmalloc_clear (sizeof (*ske) + sesdek.keylen);
2229 :
2230 0 : ske->version = 4;
2231 0 : ske->cipher_algo = si.cipher;
2232 :
2233 0 : ske->s2k.mode = si.mode;
2234 0 : ske->s2k.hash_algo = si.hash;
2235 : log_assert (sizeof (si.salt) == sizeof (ske->s2k.salt));
2236 0 : memcpy (ske->s2k.salt, si.salt, sizeof (ske->s2k.salt));
2237 0 : if (! si.s2k_is_session_key)
2238 : /* 0 means get the default. */
2239 0 : ske->s2k.count = encode_s2k_iterations (si.iterations);
2240 :
2241 :
2242 : /* Derive the symmetric key that is either the session key or the
2243 : key used to encrypt the session key. */
2244 0 : memset (&s2kdek, 0, sizeof (s2kdek));
2245 :
2246 0 : s2kdek.algo = si.cipher;
2247 0 : s2kdek.keylen = openpgp_cipher_get_algo_keylen (s2kdek.algo);
2248 :
2249 0 : err = gcry_kdf_derive (si.password, strlen (si.password),
2250 0 : ske->s2k.mode == 3 ? GCRY_KDF_ITERSALTED_S2K
2251 0 : : ske->s2k.mode == 1 ? GCRY_KDF_SALTED_S2K
2252 0 : : GCRY_KDF_SIMPLE_S2K,
2253 0 : ske->s2k.hash_algo, ske->s2k.salt, 8,
2254 0 : S2K_DECODE_COUNT (ske->s2k.count),
2255 : /* The size of the desired key and its
2256 : buffer. */
2257 0 : s2kdek.keylen, s2kdek.key);
2258 0 : if (err)
2259 0 : log_fatal ("gcry_kdf_derive failed: %s", gpg_strerror (err));
2260 :
2261 :
2262 0 : if (si.s2k_is_session_key)
2263 : {
2264 0 : ske->seskeylen = 0;
2265 0 : session_key = s2kdek;
2266 : }
2267 : else
2268 : /* Encrypt the session key using the s2k specifier. */
2269 : {
2270 0 : DEK *sesdekp = &sesdek;
2271 :
2272 : /* Now encrypt the session key (or rather, the algorithm used to
2273 : encrypt the SED plus the session key) using ENCKEY. */
2274 0 : ske->seskeylen = 1 + sesdek.keylen;
2275 0 : encrypt_seskey (&s2kdek, &sesdekp, ske->seskey);
2276 :
2277 : /* Save the session key for later. */
2278 0 : session_key = sesdek;
2279 : }
2280 :
2281 0 : pkt.pkttype = PKT_SYMKEY_ENC;
2282 0 : pkt.pkt.symkey_enc = ske;
2283 :
2284 0 : err = build_packet (out, &pkt);
2285 0 : if (err)
2286 0 : log_fatal ("Serializing sym-key encrypted packet: %s\n",
2287 : gpg_strerror (err));
2288 :
2289 0 : debug ("Wrote sym-key encrypted packet:\n");
2290 0 : dump_component (&pkt);
2291 :
2292 0 : xfree (si.session_key);
2293 0 : xfree (si.password);
2294 0 : xfree (ske);
2295 :
2296 0 : return processed;
2297 : }
2298 :
2299 : struct pk_esk_info
2300 : {
2301 : int session_key_set;
2302 :
2303 : int new_session_key;
2304 :
2305 : int sed_cipher;
2306 : int session_key_len;
2307 : char *session_key;
2308 :
2309 : int throw_keyid;
2310 :
2311 : char *keyid;
2312 : };
2313 :
2314 : static int
2315 0 : pk_esk_session_key (const char *option, int argc, char *argv[], void *cookie)
2316 : {
2317 0 : struct pk_esk_info *pi = cookie;
2318 0 : char *usage = "HEX-CHARACTERS|auto|none";
2319 0 : char *p = argv[0];
2320 : struct session_key sk;
2321 :
2322 0 : if (argc == 0)
2323 0 : log_fatal ("Usage: %s %s\n", option, usage);
2324 :
2325 0 : if (pi->session_key_set)
2326 0 : log_fatal ("%s given multiple times.", option);
2327 0 : pi->session_key_set = 1;
2328 :
2329 0 : if (strcasecmp (p, "new") == 0)
2330 : {
2331 0 : pi->new_session_key = 1;
2332 0 : return 1;
2333 : }
2334 :
2335 0 : if (strcasecmp (p, "auto") == 0)
2336 0 : return 1;
2337 :
2338 0 : sk = parse_session_key (option, p, 0);
2339 :
2340 0 : if (pi->session_key)
2341 0 : log_fatal ("%s given multiple times.", option);
2342 :
2343 0 : if (sk.algo)
2344 0 : pi->sed_cipher = sk.algo;
2345 :
2346 0 : pi->session_key_len = sk.keylen;
2347 0 : pi->session_key = sk.key;
2348 :
2349 0 : return 1;
2350 : }
2351 :
2352 : static int
2353 0 : pk_esk_throw_keyid (const char *option, int argc, char *argv[], void *cookie)
2354 : {
2355 0 : struct pk_esk_info *pi = cookie;
2356 :
2357 : (void) option;
2358 : (void) argc;
2359 : (void) argv;
2360 :
2361 0 : pi->throw_keyid = 1;
2362 :
2363 0 : return 0;
2364 : }
2365 :
2366 : static int
2367 0 : pk_esk_keyid (const char *option, int argc, char *argv[], void *cookie)
2368 : {
2369 0 : struct pk_esk_info *pi = cookie;
2370 0 : char *usage = "KEYID";
2371 :
2372 0 : if (argc == 0)
2373 0 : log_fatal ("Usage: %s %s\n", option, usage);
2374 :
2375 0 : if (pi->keyid)
2376 0 : log_fatal ("Multiple key ids given, but only one is allowed.");
2377 :
2378 0 : pi->keyid = xstrdup (argv[0]);
2379 :
2380 0 : return 1;
2381 : }
2382 :
2383 : static struct option pk_esk_options[] = {
2384 : { "--session-key", pk_esk_session_key,
2385 : "The session key to be encrypted by the S2K function as a hexadecimal "
2386 : "string. If this is not given or is \"auto\", then the current "
2387 : "session key is used. If there is no session key or this is \"new\", "
2388 : "then a new session key is generated. The session key may be "
2389 : "prefaced with an integer and a colon to indicate the cipher to use "
2390 : "for the SED packet (making --sed-cipher unnecessary and allowing the "
2391 : "direct use of the result of \"" GPG_NAME " --show-session-key\")." },
2392 : { "--throw-keyid", pk_esk_throw_keyid,
2393 : "Throw the keyid." },
2394 : { "", pk_esk_keyid, "The key id." },
2395 : { NULL, NULL,
2396 : "Example:\n\n"
2397 : " $ gpgcompose --pk-esk $KEYID --encrypted --literal --value foo \\\n"
2398 : " | " GPG_NAME " --list-packets"}
2399 : };
2400 :
2401 : static int
2402 0 : pk_esk (const char *option, int argc, char *argv[], void *cookie)
2403 : {
2404 0 : iobuf_t out = cookie;
2405 : gpg_error_t err;
2406 : int processed;
2407 : struct pk_esk_info pi;
2408 : PKT_public_key pk;
2409 :
2410 0 : memset (&pi, 0, sizeof (pi));
2411 :
2412 0 : processed = process_options (option,
2413 : major_options,
2414 : pk_esk_options, &pi,
2415 : global_options, NULL,
2416 : argc, argv);
2417 :
2418 0 : if (! pi.keyid)
2419 0 : log_fatal ("%s: missing keyid. Usage: %s KEYID", option, option);
2420 :
2421 0 : memset (&pk, 0, sizeof (pk));
2422 0 : pk.req_usage = PUBKEY_USAGE_ENC;
2423 0 : err = get_pubkey_byname (NULL, NULL, &pk, pi.keyid, NULL, NULL, 1, 1);
2424 0 : if (err)
2425 0 : log_fatal ("%s: looking up key %s: %s\n",
2426 : option, pi.keyid, gpg_strerror (err));
2427 :
2428 0 : if (pi.sed_cipher)
2429 : /* Have a session key. */
2430 : {
2431 0 : session_key.algo = pi.sed_cipher;
2432 0 : session_key.keylen = pi.session_key_len;
2433 0 : log_assert (session_key.keylen <= sizeof (session_key.key));
2434 0 : memcpy (session_key.key, pi.session_key, session_key.keylen);
2435 : }
2436 :
2437 0 : if (pi.new_session_key || ! session_key.algo)
2438 : {
2439 0 : if (! pi.new_session_key)
2440 : /* Default to AES256. */
2441 0 : session_key.algo = CIPHER_ALGO_AES256;
2442 0 : make_session_key (&session_key);
2443 : }
2444 :
2445 0 : err = write_pubkey_enc (&pk, pi.throw_keyid, &session_key, out);
2446 0 : if (err)
2447 0 : log_fatal ("%s: writing pk_esk packet for %s: %s\n",
2448 : option, pi.keyid, gpg_strerror (err));
2449 :
2450 0 : debug ("Wrote pk_esk packet for %s\n", pi.keyid);
2451 :
2452 0 : xfree (pi.keyid);
2453 0 : xfree (pi.session_key);
2454 :
2455 0 : return processed;
2456 : }
2457 :
2458 : struct encinfo
2459 : {
2460 : int saw_session_key;
2461 : };
2462 :
2463 : static int
2464 0 : encrypted_session_key (const char *option, int argc, char *argv[], void *cookie)
2465 : {
2466 0 : struct encinfo *ei = cookie;
2467 0 : char *usage = "HEX-CHARACTERS|auto";
2468 0 : char *p = argv[0];
2469 : struct session_key sk;
2470 :
2471 0 : if (argc == 0)
2472 0 : log_fatal ("Usage: %s %s\n", option, usage);
2473 :
2474 0 : if (ei->saw_session_key)
2475 0 : log_fatal ("%s given multiple times.", option);
2476 0 : ei->saw_session_key = 1;
2477 :
2478 0 : if (strcasecmp (p, "auto") == 0)
2479 0 : return 1;
2480 :
2481 0 : sk = parse_session_key (option, p, 1);
2482 :
2483 0 : session_key.algo = sk.algo;
2484 0 : log_assert (sk.keylen <= sizeof (session_key.key));
2485 0 : memcpy (session_key.key, sk.key, sk.keylen);
2486 0 : xfree (sk.key);
2487 :
2488 0 : return 1;
2489 : }
2490 :
2491 : static struct option encrypted_options[] = {
2492 : { "--session-key", encrypted_session_key,
2493 : "The session key to be encrypted by the S2K function as a hexadecimal "
2494 : "string. If this is not given or is \"auto\", then the last session key "
2495 : "is used. If there was none, then an error is raised. The session key "
2496 : "must be prefaced with an integer and a colon to indicate the cipher "
2497 : "to use (this is format used by \"" GPG_NAME " --show-session-key\")." },
2498 : { NULL, NULL,
2499 : "After creating the packet, this command clears the current "
2500 : "session key.\n\n"
2501 : "Example: nested encryption packets:\n\n"
2502 : " $ gpgcompose --sk-esk foo --encrypted-mdc \\\n"
2503 : " --sk-esk bar --encrypted-mdc \\\n"
2504 : " --literal --value 123 --encrypted-pop --encrypted-pop | " GPG_NAME" -d" }
2505 : };
2506 :
2507 : static int
2508 0 : encrypted (const char *option, int argc, char *argv[], void *cookie)
2509 : {
2510 0 : iobuf_t out = cookie;
2511 : int processed;
2512 : struct encinfo ei;
2513 : PKT_encrypted e;
2514 : cipher_filter_context_t *cfx;
2515 :
2516 0 : memset (&ei, 0, sizeof (ei));
2517 :
2518 0 : processed = process_options (option,
2519 : major_options,
2520 : encrypted_options, &ei,
2521 : global_options, NULL,
2522 : argc, argv);
2523 :
2524 0 : if (! session_key.algo)
2525 0 : log_fatal ("%s: no session key configured.\n", option);
2526 :
2527 0 : memset (&e, 0, sizeof (e));
2528 : /* We only need to set E->LEN, E->EXTRALEN (if E->LEN is not
2529 : 0), and E->NEW_CTB. */
2530 0 : e.len = 0;
2531 0 : e.new_ctb = 1;
2532 :
2533 : /* Register the cipher filter. */
2534 :
2535 0 : cfx = xmalloc_clear (sizeof (*cfx));
2536 :
2537 : /* Copy the session key. */
2538 0 : cfx->dek = xmalloc (sizeof (*cfx->dek));
2539 0 : *cfx->dek = session_key;
2540 :
2541 0 : if (do_debug)
2542 : {
2543 0 : char buf[2 * session_key.keylen + 1];
2544 0 : debug ("session key: algo: %d; keylen: %d; key: %s\n",
2545 : session_key.algo, session_key.keylen,
2546 : bin2hex (session_key.key, session_key.keylen, buf));
2547 : }
2548 :
2549 0 : if (strcmp (option, "--encrypted-mdc") == 0)
2550 0 : cfx->dek->use_mdc = 1;
2551 0 : else if (strcmp (option, "--encrypted") == 0)
2552 0 : cfx->dek->use_mdc = 0;
2553 : else
2554 0 : log_fatal ("%s: option not handled by this function!\n", option);
2555 :
2556 0 : cfx->datalen = 0;
2557 :
2558 0 : filter_push (out, cipher_filter, cfx, PKT_ENCRYPTED, cfx->datalen == 0);
2559 :
2560 0 : debug ("Wrote encrypted packet:\n");
2561 :
2562 : /* Clear the current session key. */
2563 0 : memset (&session_key, 0, sizeof (session_key));
2564 :
2565 0 : return processed;
2566 : }
2567 :
2568 : static int
2569 0 : encrypted_pop (const char *option, int argc, char *argv[], void *cookie)
2570 : {
2571 0 : iobuf_t out = cookie;
2572 :
2573 : (void) argc;
2574 : (void) argv;
2575 :
2576 0 : if (strcmp (option, "--encrypted-pop") == 0)
2577 0 : filter_pop (out, PKT_ENCRYPTED);
2578 0 : else if (strcmp (option, "--encrypted-mdc-pop") == 0)
2579 0 : filter_pop (out, PKT_ENCRYPTED_MDC);
2580 : else
2581 0 : log_fatal ("%s: option not handled by this function!\n", option);
2582 :
2583 0 : debug ("Popped encryption container.\n");
2584 :
2585 0 : return 0;
2586 : }
2587 :
2588 : struct data
2589 : {
2590 : int file;
2591 : union
2592 : {
2593 : char *data;
2594 : char *filename;
2595 : };
2596 : struct data *next;
2597 : };
2598 :
2599 : /* This must be the first member of the struct to be able to use
2600 : add_value! */
2601 : struct datahead
2602 : {
2603 : struct data *head;
2604 : struct data **last_next;
2605 : };
2606 :
2607 : static int
2608 0 : add_value (const char *option, int argc, char *argv[], void *cookie)
2609 : {
2610 0 : struct datahead *dh = cookie;
2611 0 : struct data *d = xmalloc_clear (sizeof (struct data));
2612 :
2613 0 : d->file = strcmp ("--file", option) == 0;
2614 0 : if (! d->file)
2615 0 : log_assert (strcmp ("--value", option) == 0);
2616 :
2617 0 : if (argc == 0)
2618 : {
2619 0 : if (d->file)
2620 0 : log_fatal ("Usage: %s FILENAME\n", option);
2621 : else
2622 0 : log_fatal ("Usage: %s STRING\n", option);
2623 : }
2624 :
2625 0 : if (! dh->last_next)
2626 : /* First time through. Initialize DH->LAST_NEXT. */
2627 : {
2628 0 : log_assert (! dh->head);
2629 0 : dh->last_next = &dh->head;
2630 : }
2631 :
2632 0 : if (d->file)
2633 0 : d->filename = argv[0];
2634 : else
2635 0 : d->data = argv[0];
2636 :
2637 : /* Append it. */
2638 0 : *dh->last_next = d;
2639 0 : dh->last_next = &d->next;
2640 :
2641 0 : return 1;
2642 : }
2643 :
2644 : struct litinfo
2645 : {
2646 : /* This must be the first element for add_value to work! */
2647 : struct datahead data;
2648 :
2649 : int timestamp_set;
2650 : u32 timestamp;
2651 : char mode;
2652 : int partial_body_length_encoding;
2653 : char *name;
2654 : };
2655 :
2656 : static int
2657 0 : literal_timestamp (const char *option, int argc, char *argv[], void *cookie)
2658 : {
2659 0 : struct litinfo *li = cookie;
2660 :
2661 0 : char *tail = NULL;
2662 :
2663 0 : if (argc == 0)
2664 0 : log_fatal ("Usage: %s TIMESTAMP\n", option);
2665 :
2666 0 : errno = 0;
2667 0 : li->timestamp = parse_timestamp (argv[0], &tail);
2668 0 : if (errno || (tail && *tail))
2669 0 : log_fatal ("Invalid value passed to %s (%s)\n", option, argv[0]);
2670 0 : li->timestamp_set = 1;
2671 :
2672 0 : return 1;
2673 : }
2674 :
2675 : static int
2676 0 : literal_mode (const char *option, int argc, char *argv[], void *cookie)
2677 : {
2678 0 : struct litinfo *li = cookie;
2679 :
2680 0 : if (argc == 0
2681 0 : || ! (strcmp (argv[0], "b") == 0
2682 0 : || strcmp (argv[0], "t") == 0
2683 0 : || strcmp (argv[0], "u") == 0))
2684 0 : log_fatal ("Usage: %s [btu]\n", option);
2685 :
2686 0 : li->mode = argv[0][0];
2687 :
2688 0 : return 1;
2689 : }
2690 :
2691 : static int
2692 0 : literal_partial_body_length (const char *option, int argc, char *argv[],
2693 : void *cookie)
2694 : {
2695 0 : struct litinfo *li = cookie;
2696 : char *tail;
2697 : int v;
2698 0 : int range[2] = {0, 1};
2699 :
2700 0 : if (argc <= 1)
2701 0 : log_fatal ("Usage: %s [0|1]\n", option);
2702 :
2703 0 : errno = 0;
2704 0 : v = strtol (argv[0], &tail, 0);
2705 0 : if (errno || (tail && *tail) || !(range[0] <= v && v <= range[1]))
2706 0 : log_fatal ("Invalid value passed to %s (%s). Expected %d-%d\n",
2707 : option, argv[0], range[0], range[1]);
2708 :
2709 0 : li->partial_body_length_encoding = v;
2710 :
2711 0 : return 1;
2712 : }
2713 :
2714 : static int
2715 0 : literal_name (const char *option, int argc, char *argv[], void *cookie)
2716 : {
2717 0 : struct litinfo *li = cookie;
2718 :
2719 0 : if (argc <= 1)
2720 0 : log_fatal ("Usage: %s NAME\n", option);
2721 :
2722 0 : if (strlen (argv[0]) > 255)
2723 0 : log_fatal ("%s: name is too long (%zd > 255 characters).\n",
2724 : option, strlen (argv[0]));
2725 :
2726 0 : li->name = argv[0];
2727 :
2728 0 : return 1;
2729 : }
2730 :
2731 : static struct option literal_options[] = {
2732 : { "--value", add_value,
2733 : "A string to store in the literal packet." },
2734 : { "--file", add_value,
2735 : "A file to copy into the literal packet." },
2736 : { "--timestamp", literal_timestamp,
2737 : "The literal packet's time stamp. This defaults to the current time." },
2738 : { "--mode", literal_mode,
2739 : "The content's mode (normally 'b' (default), 't' or 'u')." },
2740 : { "--partial-body-length", literal_partial_body_length,
2741 : "Force partial body length encoding." },
2742 : { "--name", literal_name,
2743 : "The literal's name." },
2744 : { NULL, NULL,
2745 : "Example:\n\n"
2746 : " $ gpgcompose --literal --value foobar | " GPG_NAME " -d"}
2747 : };
2748 :
2749 : static int
2750 0 : literal (const char *option, int argc, char *argv[], void *cookie)
2751 : {
2752 0 : iobuf_t out = cookie;
2753 : gpg_error_t err;
2754 : int processed;
2755 : struct litinfo li;
2756 : PKT_plaintext *pt;
2757 : PACKET pkt;
2758 : struct data *data;
2759 :
2760 0 : memset (&li, 0, sizeof (li));
2761 :
2762 0 : processed = process_options (option,
2763 : major_options,
2764 : literal_options, &li,
2765 : global_options, NULL,
2766 : argc, argv);
2767 :
2768 0 : if (! li.data.head)
2769 0 : log_fatal ("%s: no data provided (use --value or --file)", option);
2770 :
2771 0 : pt = xmalloc_clear (sizeof (*pt) + (li.name ? strlen (li.name) : 0));
2772 0 : pt->new_ctb = 1;
2773 :
2774 0 : if (li.timestamp_set)
2775 0 : pt->timestamp = li.timestamp;
2776 : else
2777 : /* Default to the current time. */
2778 0 : pt->timestamp = make_timestamp ();
2779 :
2780 0 : pt->mode = li.mode;
2781 0 : if (! pt->mode)
2782 : /* Default to binary. */
2783 0 : pt->mode = 'b';
2784 :
2785 0 : if (li.name)
2786 : {
2787 0 : strcpy (pt->name, li.name);
2788 0 : pt->namelen = strlen (pt->name);
2789 : }
2790 :
2791 0 : pkt.pkttype = PKT_PLAINTEXT;
2792 0 : pkt.pkt.plaintext = pt;
2793 :
2794 0 : if (! li.partial_body_length_encoding)
2795 : /* Compute the amount of data. */
2796 : {
2797 0 : pt->len = 0;
2798 0 : for (data = li.data.head; data; data = data->next)
2799 : {
2800 0 : if (data->file)
2801 : {
2802 : iobuf_t in;
2803 : int overflow;
2804 : off_t off;
2805 :
2806 0 : in = iobuf_open (data->filename);
2807 0 : if (! in)
2808 : /* An error opening the file. We do error handling
2809 : below so just break here. */
2810 : {
2811 0 : pt->len = 0;
2812 0 : break;
2813 : }
2814 :
2815 0 : off = iobuf_get_filelength (in, &overflow);
2816 0 : iobuf_close (in);
2817 :
2818 0 : if (overflow || off == 0)
2819 : /* Length is unknown or there was an error
2820 : (unfortunately, iobuf_get_filelength doesn't
2821 : distinguish between 0 length files and an error!).
2822 : Fall back to partial body mode. */
2823 : {
2824 0 : pt->len = 0;
2825 0 : break;
2826 : }
2827 :
2828 0 : pt->len += off;
2829 : }
2830 : else
2831 0 : pt->len += strlen (data->data);
2832 : }
2833 : }
2834 :
2835 0 : err = build_packet (out, &pkt);
2836 0 : if (err)
2837 0 : log_fatal ("Serializing literal packet: %s\n", gpg_strerror (err));
2838 :
2839 : /* Write out the data. */
2840 0 : for (data = li.data.head; data; data = data->next)
2841 : {
2842 0 : if (data->file)
2843 : {
2844 : iobuf_t in;
2845 0 : errno = 0;
2846 0 : in = iobuf_open (data->filename);
2847 0 : if (! in)
2848 0 : log_fatal ("Opening '%s': %s\n",
2849 : data->filename,
2850 0 : errno ? strerror (errno): "unknown error");
2851 :
2852 0 : iobuf_copy (out, in);
2853 0 : if (iobuf_error (in))
2854 0 : log_fatal ("Reading from %s: %s\n",
2855 : data->filename,
2856 0 : gpg_strerror (iobuf_error (in)));
2857 0 : if (iobuf_error (out))
2858 0 : log_fatal ("Writing literal data from %s: %s\n",
2859 : data->filename,
2860 0 : gpg_strerror (iobuf_error (out)));
2861 :
2862 0 : iobuf_close (in);
2863 : }
2864 : else
2865 : {
2866 0 : err = iobuf_write (out, data->data, strlen (data->data));
2867 0 : if (err)
2868 0 : log_fatal ("Writing literal data: %s\n", gpg_strerror (err));
2869 : }
2870 : }
2871 :
2872 0 : if (! pt->len)
2873 : {
2874 : /* Disable partial body length mode. */
2875 0 : log_assert (pt->new_ctb == 1);
2876 0 : iobuf_set_partial_body_length_mode (out, 0);
2877 : }
2878 :
2879 0 : debug ("Wrote literal packet:\n");
2880 0 : dump_component (&pkt);
2881 :
2882 0 : while (li.data.head)
2883 : {
2884 0 : data = li.data.head->next;
2885 0 : xfree (li.data.head);
2886 0 : li.data.head = data;
2887 : }
2888 0 : xfree (pt);
2889 :
2890 0 : return processed;
2891 : }
2892 :
2893 : static int
2894 0 : copy_file (const char *option, int argc, char *argv[], void *cookie)
2895 : {
2896 0 : char **filep = cookie;
2897 :
2898 0 : if (argc == 0)
2899 0 : log_fatal ("Usage: %s FILENAME\n", option);
2900 :
2901 0 : *filep = argv[0];
2902 :
2903 0 : return 1;
2904 : }
2905 :
2906 : static struct option copy_options[] = {
2907 : { "", copy_file, "Copy the specified file to stdout." },
2908 : { NULL, NULL,
2909 : "Example:\n\n"
2910 : " $ gpgcompose --copy /etc/hostname\n\n"
2911 : "This is particularly useful when combined with gpgsplit." }
2912 : };
2913 :
2914 : static int
2915 0 : copy (const char *option, int argc, char *argv[], void *cookie)
2916 : {
2917 0 : iobuf_t out = cookie;
2918 0 : char *file = NULL;
2919 : iobuf_t in;
2920 :
2921 : int processed;
2922 :
2923 0 : processed = process_options (option,
2924 : major_options,
2925 : copy_options, &file,
2926 : global_options, NULL,
2927 : argc, argv);
2928 0 : if (! file)
2929 0 : log_fatal ("Usage: %s FILE\n", option);
2930 :
2931 0 : errno = 0;
2932 0 : in = iobuf_open (file);
2933 0 : if (! in)
2934 0 : log_fatal ("Error opening %s: %s.\n",
2935 0 : file, errno ? strerror (errno): "unknown error");
2936 :
2937 0 : iobuf_copy (out, in);
2938 0 : if (iobuf_error (out))
2939 0 : log_fatal ("Copying data to destination: %s\n",
2940 0 : gpg_strerror (iobuf_error (out)));
2941 0 : if (iobuf_error (in))
2942 0 : log_fatal ("Reading data from %s: %s\n",
2943 0 : argv[0], gpg_strerror (iobuf_error (in)));
2944 :
2945 0 : iobuf_close (in);
2946 :
2947 0 : return processed;
2948 : }
2949 :
2950 : int
2951 0 : main (int argc, char *argv[])
2952 : {
2953 0 : const char *filename = "-";
2954 : iobuf_t out;
2955 0 : int preprocessed = 1;
2956 : int processed;
2957 : ctrl_t ctrl;
2958 :
2959 0 : opt.ignore_time_conflict = 1;
2960 : /* Allow notations in the IETF space, for instance. */
2961 0 : opt.expert = 1;
2962 :
2963 0 : ctrl = xcalloc (1, sizeof *ctrl);
2964 :
2965 0 : keydb_add_resource ("pubring" EXTSEP_S GPGEXT_GPG,
2966 : KEYDB_RESOURCE_FLAG_DEFAULT);
2967 :
2968 0 : if (argc == 1)
2969 : /* Nothing to do. */
2970 0 : return 0;
2971 :
2972 0 : if (strcmp (argv[1], "--output") == 0
2973 0 : || strcmp (argv[1], "-o") == 0)
2974 : {
2975 0 : filename = argv[2];
2976 0 : log_info ("Writing to %s\n", filename);
2977 0 : preprocessed += 2;
2978 : }
2979 :
2980 0 : out = iobuf_create (filename, 0);
2981 0 : if (! out)
2982 0 : log_fatal ("Failed to open stdout for writing\n");
2983 :
2984 0 : processed = process_options (NULL, NULL,
2985 : major_options, out,
2986 : global_options, NULL,
2987 0 : argc - preprocessed, &argv[preprocessed]);
2988 0 : if (processed != argc - preprocessed)
2989 0 : log_fatal ("Didn't process %d options.\n", argc - preprocessed - processed);
2990 :
2991 0 : iobuf_close (out);
2992 :
2993 0 : return 0;
2994 : }
2995 :
2996 : /* Stubs duplicated from gpg.c. */
2997 :
2998 : int g10_errors_seen = 0;
2999 :
3000 : /* Note: This function is used by signal handlers!. */
3001 : static void
3002 0 : emergency_cleanup (void)
3003 : {
3004 0 : gcry_control (GCRYCTL_TERM_SECMEM );
3005 0 : }
3006 :
3007 : void
3008 0 : g10_exit( int rc )
3009 : {
3010 0 : gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE);
3011 :
3012 0 : emergency_cleanup ();
3013 :
3014 0 : rc = rc? rc : log_get_errorcount(0)? 2 : g10_errors_seen? 1 : 0;
3015 0 : exit (rc);
3016 : }
3017 :
3018 : void
3019 0 : keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
3020 : strlist_t commands, int quiet, int seckey_check)
3021 : {
3022 : (void) ctrl;
3023 : (void) username;
3024 : (void) locusr;
3025 : (void) commands;
3026 : (void) quiet;
3027 : (void) seckey_check;
3028 0 : }
3029 :
3030 : void
3031 0 : show_basic_key_info (KBNODE keyblock)
3032 : {
3033 : (void) keyblock;
3034 0 : }
|