Coverage Report

Created: 2022-12-08 06:09

/src/gnupg/g10/pubkey-enc.c
Line
Count
Source (jump to first uncovered line)
1
/* pubkey-enc.c - Process a public key encoded packet.
2
 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006, 2009,
3
 *               2010 Free Software Foundation, Inc.
4
 *
5
 * This file is part of GnuPG.
6
 *
7
 * GnuPG is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * GnuPG is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, see <https://www.gnu.org/licenses/>.
19
 */
20
21
#include <config.h>
22
#include <stdio.h>
23
#include <stdlib.h>
24
#include <string.h>
25
26
#include "gpg.h"
27
#include "../common/util.h"
28
#include "packet.h"
29
#include "keydb.h"
30
#include "trustdb.h"
31
#include "../common/status.h"
32
#include "options.h"
33
#include "main.h"
34
#include "../common/i18n.h"
35
#include "pkglue.h"
36
#include "call-agent.h"
37
#include "../common/host2net.h"
38
#include "../common/compliance.h"
39
40
41
static gpg_error_t get_it (ctrl_t ctrl, struct pubkey_enc_list *k,
42
                           DEK *dek, PKT_public_key *sk, u32 *keyid);
43
44
45
/* Check that the given algo is mentioned in one of the valid user-ids. */
46
static int
47
is_algo_in_prefs (kbnode_t keyblock, preftype_t type, int algo)
48
0
{
49
0
  kbnode_t k;
50
51
0
  for (k = keyblock; k; k = k->next)
52
0
    {
53
0
      if (k->pkt->pkttype == PKT_USER_ID)
54
0
        {
55
0
          PKT_user_id *uid = k->pkt->pkt.user_id;
56
0
          prefitem_t *prefs = uid->prefs;
57
58
0
          if (uid->created && prefs && !uid->flags.revoked && !uid->flags.expired)
59
0
            {
60
0
              for (; prefs->type; prefs++)
61
0
                if (prefs->type == type && prefs->value == algo)
62
0
                  return 1;
63
0
            }
64
0
        }
65
0
    }
66
0
  return 0;
67
0
}
68
69
70
/*
71
 * Get the session key from a pubkey enc packet and return it in DEK,
72
 * which should have been allocated in secure memory by the caller.
73
 */
74
gpg_error_t
75
get_session_key (ctrl_t ctrl, struct pubkey_enc_list *list, DEK *dek)
76
58.5k
{
77
58.5k
  PKT_public_key *sk = NULL;
78
58.5k
  gpg_error_t err;
79
58.5k
  void *enum_context = NULL;
80
58.5k
  u32 keyid[2];
81
58.5k
  int search_for_secret_keys = 1;
82
58.5k
  struct pubkey_enc_list *k;
83
84
58.5k
  if (DBG_CLOCK)
85
0
    log_clock ("get_session_key enter");
86
87
58.5k
  while (search_for_secret_keys)
88
58.5k
    {
89
58.5k
      sk = xmalloc_clear (sizeof *sk);
90
58.5k
      err = enum_secret_keys (ctrl, &enum_context, sk);
91
58.5k
      if (err)
92
58.5k
        break;
93
94
      /* Check compliance.  */
95
0
      if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_DECRYPTION,
96
0
                                 sk->pubkey_algo, 0,
97
0
                                 sk->pkey, nbits_from_pk (sk), NULL))
98
0
        {
99
0
          log_info (_("key %s is not suitable for decryption"
100
0
                      " in %s mode\n"),
101
0
                    keystr_from_pk (sk),
102
0
                    gnupg_compliance_option_string (opt.compliance));
103
0
          continue;
104
0
        }
105
106
      /* FIXME: The list needs to be sorted so that we try the keys in
107
       * an appropriate order.  For example:
108
       * - On-disk keys w/o protection
109
       * - On-disk keys with a cached passphrase
110
       * - On-card keys of an active card
111
       * - On-disk keys with protection
112
       * - On-card keys from cards which are not plugged it.  Here a
113
       *   cancel-all button should stop asking for other cards.
114
       * Without any anonymous keys the sorting can be skipped.
115
       */
116
0
      for (k = list; k; k = k->next)
117
0
        {
118
0
          if (!(k->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E
119
0
                || k->pubkey_algo == PUBKEY_ALGO_ECDH
120
0
                || k->pubkey_algo == PUBKEY_ALGO_RSA
121
0
                || k->pubkey_algo == PUBKEY_ALGO_RSA_E
122
0
                || k->pubkey_algo == PUBKEY_ALGO_ELGAMAL))
123
0
            continue;
124
125
0
          if (openpgp_pk_test_algo2 (k->pubkey_algo, PUBKEY_USAGE_ENC))
126
0
            continue;
127
128
0
          if (sk->pubkey_algo != k->pubkey_algo)
129
0
            continue;
130
131
0
          keyid_from_pk (sk, keyid);
132
133
0
          if (!k->keyid[0] && !k->keyid[1])
134
0
            {
135
0
              if (opt.skip_hidden_recipients)
136
0
                continue;
137
138
0
              if (!opt.quiet)
139
0
                log_info (_("anonymous recipient; trying secret key %s ...\n"),
140
0
                          keystr (keyid));
141
0
            }
142
0
          else if (opt.try_all_secrets
143
0
                   || (k->keyid[0] == keyid[0] && k->keyid[1] == keyid[1]))
144
0
            {
145
0
              if (!opt.quiet && !(sk->pubkey_usage & PUBKEY_USAGE_ENC))
146
0
                log_info (_("used key is not marked for encryption use.\n"));
147
0
            }
148
0
          else
149
0
            continue;
150
151
0
          err = get_it (ctrl, k, dek, sk, keyid);
152
0
          k->result = err;
153
0
          if (!err)
154
0
            {
155
0
              if (!opt.quiet && !k->keyid[0] && !k->keyid[1])
156
0
                {
157
0
                  log_info (_("okay, we are the anonymous recipient.\n"));
158
0
                  if (!(sk->pubkey_usage & PUBKEY_USAGE_ENC))
159
0
                    log_info (_("used key is not marked for encryption use.\n")
160
0
                              );
161
0
                }
162
0
              search_for_secret_keys = 0;
163
0
              break;
164
0
            }
165
0
          else if (gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
166
0
            {
167
0
              search_for_secret_keys = 0;
168
0
              break; /* Don't try any more secret keys.  */
169
0
            }
170
0
        }
171
0
    }
172
58.5k
  enum_secret_keys (ctrl, &enum_context, NULL);  /* free context */
173
174
58.5k
  if (gpg_err_code (err) == GPG_ERR_EOF)
175
58.5k
    {
176
58.5k
      err = gpg_error (GPG_ERR_NO_SECKEY);
177
178
      /* Return the last specific error, if any.  */
179
6.98M
      for (k = list; k; k = k->next)
180
6.92M
        if (k->result != -1)
181
0
          err = k->result;
182
58.5k
    }
183
184
58.5k
  if (DBG_CLOCK)
185
0
    log_clock ("get_session_key leave");
186
58.5k
  return err;
187
58.5k
}
188
189
190
static gpg_error_t
191
get_it (ctrl_t ctrl,
192
        struct pubkey_enc_list *enc, DEK *dek, PKT_public_key *sk, u32 *keyid)
193
0
{
194
0
  gpg_error_t err;
195
0
  byte *frame = NULL;
196
0
  unsigned int n;
197
0
  size_t nframe;
198
0
  u16 csum, csum2;
199
0
  int padding;
200
0
  gcry_sexp_t s_data;
201
0
  char *desc;
202
0
  char *keygrip;
203
0
  byte fp[MAX_FINGERPRINT_LEN];
204
205
0
  if (DBG_CLOCK)
206
0
    log_clock ("decryption start");
207
208
  /* Get the keygrip.  */
209
0
  err = hexkeygrip_from_pk (sk, &keygrip);
210
0
  if (err)
211
0
    goto leave;
212
213
  /* Convert the data to an S-expression.  */
214
0
  if (sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL
215
0
      || sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E)
216
0
    {
217
0
      if (!enc->data[0] || !enc->data[1])
218
0
        err = gpg_error (GPG_ERR_BAD_MPI);
219
0
      else
220
0
        err = gcry_sexp_build (&s_data, NULL, "(enc-val(elg(a%m)(b%m)))",
221
0
                               enc->data[0], enc->data[1]);
222
0
    }
223
0
  else if (sk->pubkey_algo == PUBKEY_ALGO_RSA
224
0
           || sk->pubkey_algo == PUBKEY_ALGO_RSA_E)
225
0
    {
226
0
      if (!enc->data[0])
227
0
        err = gpg_error (GPG_ERR_BAD_MPI);
228
0
      else
229
0
        err = gcry_sexp_build (&s_data, NULL, "(enc-val(rsa(a%m)))",
230
0
                               enc->data[0]);
231
0
    }
232
0
  else if (sk->pubkey_algo == PUBKEY_ALGO_ECDH)
233
0
    {
234
0
      if (!enc->data[0] || !enc->data[1])
235
0
        err = gpg_error (GPG_ERR_BAD_MPI);
236
0
      else
237
0
        err = gcry_sexp_build (&s_data, NULL, "(enc-val(ecdh(s%m)(e%m)))",
238
0
                               enc->data[1], enc->data[0]);
239
0
    }
240
0
  else
241
0
    err = gpg_error (GPG_ERR_BUG);
242
243
0
  if (err)
244
0
    goto leave;
245
246
0
  if (sk->pubkey_algo == PUBKEY_ALGO_ECDH)
247
0
    fingerprint_from_pk (sk, fp, NULL);
248
249
  /* Decrypt. */
250
0
  desc = gpg_format_keydesc (ctrl, sk, FORMAT_KEYDESC_NORMAL, 1);
251
0
  err = agent_pkdecrypt (NULL, keygrip,
252
0
                         desc, sk->keyid, sk->main_keyid, sk->pubkey_algo,
253
0
                         s_data, &frame, &nframe, &padding);
254
0
  xfree (desc);
255
0
  gcry_sexp_release (s_data);
256
0
  if (err)
257
0
    goto leave;
258
259
  /* Now get the DEK (data encryption key) from the frame
260
   *
261
   * Old versions encode the DEK in this format (msb is left):
262
   *
263
   *     0  1  DEK(16 bytes)  CSUM(2 bytes)  0  RND(n bytes) 2
264
   *
265
   * Later versions encode the DEK like this:
266
   *
267
   *     0  2  RND(n bytes)  0  A  DEK(k bytes)  CSUM(2 bytes)
268
   *
269
   * (mpi_get_buffer already removed the leading zero).
270
   *
271
   * RND are non-zero randow bytes.
272
   * A   is the cipher algorithm
273
   * DEK is the encryption key (session key) with length k
274
   * CSUM
275
   */
276
0
  if (DBG_CRYPTO)
277
0
    log_printhex (frame, nframe, "DEK frame:");
278
0
  n = 0;
279
280
0
  if (sk->pubkey_algo == PUBKEY_ALGO_ECDH)
281
0
    {
282
0
      gcry_mpi_t decoded;
283
284
      /* At the beginning the frame are the bytes of shared point MPI.  */
285
0
      err = pk_ecdh_decrypt (&decoded, fp, enc->data[1]/*encr data as an MPI*/,
286
0
                             frame, nframe, sk->pkey);
287
0
      if(err)
288
0
        goto leave;
289
290
0
      xfree (frame);
291
0
      err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &frame, &nframe, decoded);
292
0
      mpi_release (decoded);
293
0
      if (err)
294
0
        goto leave;
295
296
      /* Now the frame are the bytes decrypted but padded session key.  */
297
0
      if (!nframe || nframe <= 8
298
0
          || frame[nframe-1] > nframe)
299
0
        {
300
0
          err = gpg_error (GPG_ERR_WRONG_SECKEY);
301
0
          goto leave;
302
0
        }
303
0
      nframe -= frame[nframe-1]; /* Remove padding.  */
304
0
      log_assert (!n); /* (used just below) */
305
0
    }
306
0
  else
307
0
    {
308
0
      if (padding)
309
0
        {
310
0
          if (n + 7 > nframe)
311
0
            {
312
0
              err = gpg_error (GPG_ERR_WRONG_SECKEY);
313
0
              goto leave;
314
0
            }
315
316
          /* FIXME: Actually the leading zero is required but due to
317
           * the way we encode the output in libgcrypt as an MPI we
318
           * are not able to encode that leading zero.  However, when
319
           * using a Smartcard we are doing it the right way and
320
           * therefore we have to skip the zero.  This should be fixed
321
           * in gpg-agent of course. */
322
0
          if (!frame[n])
323
0
            n++;
324
325
0
          if (frame[n] == 1 && frame[nframe - 1] == 2)
326
0
            {
327
0
              log_info (_("old encoding of the DEK is not supported\n"));
328
0
              err = gpg_error (GPG_ERR_CIPHER_ALGO);
329
0
              goto leave;
330
0
            }
331
0
          if (frame[n] != 2) /* Something went wrong.  */
332
0
            {
333
0
              err = gpg_error (GPG_ERR_WRONG_SECKEY);
334
0
              goto leave;
335
0
            }
336
0
          for (n++; n < nframe && frame[n]; n++) /* Skip the random bytes.  */
337
0
            ;
338
0
          n++; /* Skip the zero byte.  */
339
0
        }
340
0
    }
341
342
0
  if (n + 4 > nframe)
343
0
    {
344
0
      err = gpg_error (GPG_ERR_WRONG_SECKEY);
345
0
      goto leave;
346
0
    }
347
348
0
  dek->keylen = nframe - (n + 1) - 2;
349
0
  dek->algo = frame[n++];
350
0
  err = openpgp_cipher_test_algo (dek->algo);
351
0
  if (err)
352
0
    {
353
0
      if (!opt.quiet && gpg_err_code (err) == GPG_ERR_CIPHER_ALGO)
354
0
        {
355
0
          log_info (_("cipher algorithm %d%s is unknown or disabled\n"),
356
0
                    dek->algo,
357
0
                    dek->algo == CIPHER_ALGO_IDEA ? " (IDEA)" : "");
358
0
        }
359
0
      dek->algo = 0;
360
0
      goto leave;
361
0
    }
362
0
  if (dek->keylen != openpgp_cipher_get_algo_keylen (dek->algo))
363
0
    {
364
0
      err = gpg_error (GPG_ERR_WRONG_SECKEY);
365
0
      goto leave;
366
0
    }
367
368
  /* Copy the key to DEK and compare the checksum.  */
369
0
  csum = buf16_to_u16 (frame+nframe-2);
370
0
  memcpy (dek->key, frame + n, dek->keylen);
371
0
  for (csum2 = 0, n = 0; n < dek->keylen; n++)
372
0
    csum2 += dek->key[n];
373
0
  if (csum != csum2)
374
0
    {
375
0
      err = gpg_error (GPG_ERR_WRONG_SECKEY);
376
0
      goto leave;
377
0
    }
378
0
  if (DBG_CLOCK)
379
0
    log_clock ("decryption ready");
380
0
  if (DBG_CRYPTO)
381
0
    log_printhex (dek->key, dek->keylen, "DEK is:");
382
383
  /* Check that the algo is in the preferences and whether it has
384
   * expired.  Also print a status line with the key's fingerprint.  */
385
0
  {
386
0
    PKT_public_key *pk = NULL;
387
0
    PKT_public_key *mainpk = NULL;
388
0
    KBNODE pkb = get_pubkeyblock (ctrl, keyid);
389
390
0
    if (!pkb)
391
0
      {
392
0
        err = -1;
393
0
        log_error ("oops: public key not found for preference check\n");
394
0
      }
395
0
    else if (pkb->pkt->pkt.public_key->selfsigversion > 3
396
0
             && dek->algo != CIPHER_ALGO_3DES
397
0
             && !opt.quiet
398
0
             && !is_algo_in_prefs (pkb, PREFTYPE_SYM, dek->algo))
399
0
      log_info (_("WARNING: cipher algorithm %s not found in recipient"
400
0
                  " preferences\n"), openpgp_cipher_algo_name (dek->algo));
401
402
0
    if (!err)
403
0
      {
404
0
        kbnode_t k;
405
0
        int first = 1;
406
407
0
        for (k = pkb; k; k = k->next)
408
0
          {
409
0
            if (k->pkt->pkttype == PKT_PUBLIC_KEY
410
0
                || k->pkt->pkttype == PKT_PUBLIC_SUBKEY)
411
0
              {
412
0
                u32 aki[2];
413
414
0
                if (first)
415
0
                  {
416
0
                    first = 0;
417
0
                    mainpk = k->pkt->pkt.public_key;
418
0
                  }
419
420
0
                keyid_from_pk (k->pkt->pkt.public_key, aki);
421
0
                if (aki[0] == keyid[0] && aki[1] == keyid[1])
422
0
                  {
423
0
                    pk = k->pkt->pkt.public_key;
424
0
                    break;
425
0
                  }
426
0
              }
427
0
          }
428
0
        if (!pk)
429
0
          BUG ();
430
0
        if (pk->expiredate && pk->expiredate <= make_timestamp ())
431
0
          {
432
0
            log_info (_("Note: secret key %s expired at %s\n"),
433
0
                      keystr (keyid), asctimestamp (pk->expiredate));
434
0
          }
435
0
      }
436
437
0
    if (pk && pk->flags.revoked)
438
0
      {
439
0
        log_info (_("Note: key has been revoked"));
440
0
        log_printf ("\n");
441
0
        show_revocation_reason (ctrl, pk, 1);
442
0
      }
443
444
0
    if (is_status_enabled () && pk && mainpk)
445
0
      {
446
0
        char pkhex[MAX_FINGERPRINT_LEN*2+1];
447
0
        char mainpkhex[MAX_FINGERPRINT_LEN*2+1];
448
449
0
        hexfingerprint (pk, pkhex, sizeof pkhex);
450
0
        hexfingerprint (mainpk, mainpkhex, sizeof mainpkhex);
451
452
        /* Note that we do not want to create a trustdb just for
453
         * getting the ownertrust: If there is no trustdb there can't
454
         * be ulitmately trusted key anyway and thus the ownertrust
455
         * value is irrelevant.  */
456
0
        write_status_printf (STATUS_DECRYPTION_KEY, "%s %s %c",
457
0
                             pkhex, mainpkhex,
458
0
                             get_ownertrust_info (ctrl, mainpk, 1));
459
460
0
      }
461
462
0
    release_kbnode (pkb);
463
0
    err = 0;
464
0
  }
465
466
0
 leave:
467
0
  xfree (frame);
468
0
  xfree (keygrip);
469
0
  return err;
470
0
}
471
472
473
/*
474
 * Get the session key from the given string.
475
 * String is supposed to be formatted as this:
476
 *  <algo-id>:<even-number-of-hex-digits>
477
 */
478
gpg_error_t
479
get_override_session_key (DEK *dek, const char *string)
480
0
{
481
0
  const char *s;
482
0
  int i;
483
484
0
  if (!string)
485
0
    return GPG_ERR_BAD_KEY;
486
0
  dek->algo = atoi (string);
487
0
  if (dek->algo < 1)
488
0
    return GPG_ERR_BAD_KEY;
489
0
  if (!(s = strchr (string, ':')))
490
0
    return GPG_ERR_BAD_KEY;
491
0
  s++;
492
0
  for (i = 0; i < DIM (dek->key) && *s; i++, s += 2)
493
0
    {
494
0
      int c = hextobyte (s);
495
0
      if (c == -1)
496
0
        return GPG_ERR_BAD_KEY;
497
0
      dek->key[i] = c;
498
0
    }
499
0
  if (*s)
500
0
    return GPG_ERR_BAD_KEY;
501
0
  dek->keylen = i;
502
0
  return 0;
503
0
}