LCOV - code coverage report
Current view: top level - g10 - gpgcompose.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 1284 0.0 %
Date: 2016-11-29 15:00:56 Functions: 0 64 0.0 %

          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 <https://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 : }

Generated by: LCOV version 1.11