Coverage Report

Created: 2022-12-08 06:09

/src/gnupg/g10/passphrase.c
Line
Count
Source (jump to first uncovered line)
1
/* passphrase.c -  Get a passphrase
2
 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3
 *               2005, 2006, 2007, 2009, 2011 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 <stddef.h>
23
#include <stdio.h>
24
#include <stdlib.h>
25
#include <string.h>
26
#include <unistd.h>
27
#include <errno.h>
28
#ifdef HAVE_LOCALE_H
29
#include <locale.h>
30
#endif
31
#ifdef HAVE_LANGINFO_CODESET
32
#include <langinfo.h>
33
#endif
34
35
#include "gpg.h"
36
#include "../common/util.h"
37
#include "options.h"
38
#include "../common/ttyio.h"
39
#include "keydb.h"
40
#include "main.h"
41
#include "../common/i18n.h"
42
#include "../common/status.h"
43
#include "call-agent.h"
44
#include "../common/shareddefs.h"
45
46
static char *fd_passwd = NULL;
47
static char *next_pw = NULL;
48
static char *last_pw = NULL;
49
50
51
int
52
have_static_passphrase (void)
53
118k
{
54
118k
  return (!!fd_passwd
55
118k
          && (opt.batch || opt.pinentry_mode == PINENTRY_MODE_LOOPBACK));
56
118k
}
57
58
59
/* Return a static passphrase.  The returned value is only valid as
60
   long as no other passphrase related function is called.  NULL may
61
   be returned if no passphrase has been set; better use
62
   have_static_passphrase first.  */
63
const char *
64
get_static_passphrase (void)
65
0
{
66
0
  return fd_passwd;
67
0
}
68
69
70
/****************
71
 * Set the passphrase to be used for the next query and only for the next
72
 * one.
73
 */
74
void
75
set_next_passphrase( const char *s )
76
0
{
77
0
  xfree(next_pw);
78
0
  next_pw = NULL;
79
0
  if ( s )
80
0
    {
81
0
      next_pw = xmalloc_secure( strlen(s)+1 );
82
0
      strcpy (next_pw, s );
83
0
    }
84
0
}
85
86
/****************
87
 * Get the last passphrase used in passphrase_to_dek.
88
 * Note: This removes the passphrase from this modules and
89
 * the caller must free the result.  May return NULL:
90
 */
91
char *
92
get_last_passphrase (void)
93
0
{
94
0
  char *p = last_pw;
95
0
  last_pw = NULL;
96
0
  return p;
97
0
}
98
99
/* Here's an interesting question: since this passphrase was passed in
100
   on the command line, is there really any point in using secure
101
   memory for it?  I'm going with 'yes', since it doesn't hurt, and
102
   might help in some small way (swapping). */
103
104
void
105
set_passphrase_from_string(const char *pass)
106
0
{
107
0
  xfree (fd_passwd);
108
0
  fd_passwd = xmalloc_secure(strlen(pass)+1);
109
0
  strcpy (fd_passwd, pass);
110
0
}
111
112
113
void
114
read_passphrase_from_fd( int fd )
115
0
{
116
0
  int i, len;
117
0
  char *pw;
118
119
0
  if (! gnupg_fd_valid (fd))
120
0
    log_fatal ("passphrase-fd is invalid: %s\n", strerror (errno));
121
122
0
  if ( !opt.batch && opt.pinentry_mode != PINENTRY_MODE_LOOPBACK)
123
0
    { /* Not used but we have to do a dummy read, so that it won't end
124
         up at the begin of the message if the quite usual trick to
125
         prepend the passphtrase to the message is used. */
126
0
      char buf[1];
127
128
0
      while (!(read (fd, buf, 1) != 1 || *buf == '\n' ))
129
0
        ;
130
0
      *buf = 0;
131
0
      return;
132
0
    }
133
134
0
  for (pw = NULL, i = len = 100; ; i++ )
135
0
    {
136
0
      if (i >= len-1 )
137
0
        {
138
0
          char *pw2 = pw;
139
0
          len += 100;
140
0
          pw = xmalloc_secure( len );
141
0
          if( pw2 )
142
0
            {
143
0
              memcpy(pw, pw2, i );
144
0
              xfree (pw2);
145
0
            }
146
0
          else
147
0
            i=0;
148
0
  }
149
0
      if (read( fd, pw+i, 1) != 1 || pw[i] == '\n' )
150
0
        break;
151
0
    }
152
0
  pw[i] = 0;
153
0
  if (!opt.batch && opt.pinentry_mode != PINENTRY_MODE_LOOPBACK)
154
0
    tty_printf("\b\b\b   \n" );
155
156
0
  xfree ( fd_passwd );
157
0
  fd_passwd = pw;
158
0
}
159
160
161
/*
162
 * Ask the GPG Agent for the passphrase.
163
 * If NOCACHE is set the symmetric passpharse caching will not be used.
164
 *
165
 * If REPEAT is positive, a new passphrase is requested and the agent
166
 * shall require REPEAT times repetitions of the entered passphrase.
167
 * This is used for symmetric encryption.
168
 *
169
 * Note that TRYAGAIN_TEXT must not be translated.  If CANCELED is not
170
 * NULL, the function does set it to 1 if the user canceled the
171
 * operation.  If CACHEID is not NULL, it will be used as the cacheID
172
 * for the gpg-agent; if is NULL and a key fingerprint can be
173
 * computed, this will be used as the cacheid.
174
 *
175
 * For FLAGS see passphrase_to_dek;
176
 */
177
static char *
178
passphrase_get (int newsymkey, int nocache, const char *cacheid, int repeat,
179
                const char *tryagain_text, unsigned int flags, int *canceled)
180
118k
{
181
118k
  int rc;
182
118k
  char *pw = NULL;
183
118k
  char *orig_codeset;
184
118k
  const char *my_cacheid;
185
118k
  const char *desc;
186
187
118k
  if (canceled)
188
118k
    *canceled = 0;
189
190
118k
  orig_codeset = i18n_switchto_utf8 ();
191
192
118k
  if (!nocache && cacheid)
193
5.87k
    my_cacheid = cacheid;
194
112k
  else
195
112k
    my_cacheid = NULL;
196
197
118k
  if (tryagain_text)
198
0
    tryagain_text = _(tryagain_text);
199
200
118k
  if ((flags & GETPASSWORD_FLAG_SYMDECRYPT))
201
118k
    desc = _("Please enter the passphrase for decryption.");
202
0
  else
203
0
    desc = _("Enter passphrase\n");
204
205
  /* Here we have:
206
   * REPEAT is set in create mode and if opt.passphrase_repeat is set.
207
   * (Thus it is not a clean indication that we want a new passphrase).
208
   * NOCACHE is set in create mode or if --no-symkey-cache is used.
209
   * CACHEID is only set if caching shall be used.
210
   * NEWSYMKEY has been added latter to make it clear that a new key
211
   * is requested.  The whole chain of API is a bit too complex since
212
   * we we stripped things out over time; however, there is no time
213
   * for a full state analysis and thus this new parameter.
214
   */
215
118k
  rc = agent_get_passphrase (my_cacheid, tryagain_text, NULL,
216
118k
                             desc,
217
118k
                             newsymkey, repeat, nocache, &pw);
218
219
118k
  i18n_switchback (orig_codeset);
220
221
222
118k
  if (!rc)
223
0
    ;
224
118k
  else if (gpg_err_code (rc) == GPG_ERR_CANCELED
225
118k
            || gpg_err_code (rc) == GPG_ERR_FULLY_CANCELED)
226
0
    {
227
0
      log_info (_("cancelled by user\n") );
228
0
      if (canceled)
229
0
        *canceled = 1;
230
0
    }
231
118k
  else
232
118k
    {
233
118k
      log_error (_("problem with the agent: %s\n"), gpg_strerror (rc));
234
      /* Due to limitations in the API of the upper layers they
235
         consider an error as no passphrase entered.  This works in
236
         most cases but not during key creation where this should
237
         definitely not happen and let it continue without requiring a
238
         passphrase.  Given that now all the upper layers handle a
239
         cancel correctly, we simply set the cancel flag now for all
240
         errors from the agent.  */
241
118k
      if (canceled)
242
118k
        *canceled = 1;
243
244
118k
      write_status_errcode ("get_passphrase", rc);
245
118k
    }
246
247
118k
  if (rc)
248
118k
    {
249
118k
      xfree (pw);
250
118k
      pw = NULL;
251
118k
    }
252
118k
  return pw;
253
118k
}
254
255
256
/*
257
 * Clear the cached passphrase with CACHEID.
258
 */
259
void
260
passphrase_clear_cache (const char *cacheid)
261
0
{
262
0
  int rc;
263
264
0
  rc = agent_clear_passphrase (cacheid);
265
0
  if (rc)
266
0
    log_error (_("problem with the agent: %s\n"), gpg_strerror (rc));
267
0
}
268
269
270
/* Return a new DEK object using the string-to-key specifier S2K.
271
 * Returns NULL if the user canceled the passphrase entry and if
272
 * CANCELED is not NULL, sets it to true.
273
 *
274
 * If CREATE is true a new passphrase will be created.  If NOCACHE is
275
 * true the symmetric key caching will not be used.
276
 * FLAG bits are:
277
 *   GETPASSWORD_FLAG_SYMDECRYPT := for symmetric decryption
278
 */
279
DEK *
280
passphrase_to_dek (int cipher_algo, STRING2KEY *s2k,
281
                   int create, int nocache,
282
                   const char *tryagain_text, unsigned int flags,
283
                   int *canceled)
284
118k
{
285
118k
  char *pw = NULL;
286
118k
  DEK *dek;
287
118k
  STRING2KEY help_s2k;
288
118k
  int dummy_canceled;
289
118k
  char s2k_cacheidbuf[1+16+1];
290
118k
  char *s2k_cacheid = NULL;
291
292
118k
  if (!canceled)
293
7.85k
    canceled = &dummy_canceled;
294
118k
  *canceled = 0;
295
296
118k
  if (opt.no_symkey_cache)
297
0
    nocache = 1;  /* Force no symmetric key caching.  */
298
299
118k
  if ( !s2k )
300
0
    {
301
0
      log_assert (create && !nocache);
302
      /* This is used for the old rfc1991 mode
303
       * Note: This must match the code in encode.c with opt.rfc1991 set */
304
0
      memset (&help_s2k, 0, sizeof (help_s2k));
305
0
      s2k = &help_s2k;
306
0
      s2k->hash_algo = S2K_DIGEST_ALGO;
307
0
    }
308
309
  /* Create a new salt or what else to be filled into the s2k for a
310
     new key.  */
311
118k
  if (create && (s2k->mode == 1 || s2k->mode == 3))
312
0
    {
313
0
      gcry_randomize (s2k->salt, 8, GCRY_STRONG_RANDOM);
314
0
      if ( s2k->mode == 3 )
315
0
        {
316
          /* We delay the encoding until it is really needed.  This is
317
             if we are going to dynamically calibrate it, we need to
318
             call out to gpg-agent and that should not be done during
319
             option processing in main().  */
320
0
          if (!opt.s2k_count)
321
0
            opt.s2k_count = encode_s2k_iterations (agent_get_s2k_count ());
322
0
          s2k->count = opt.s2k_count;
323
0
        }
324
0
    }
325
326
  /* If we do not have a passphrase available in NEXT_PW and status
327
     information are request, we print them now. */
328
118k
  if ( !next_pw && is_status_enabled() )
329
0
    {
330
0
      char buf[50];
331
332
0
      snprintf (buf, sizeof buf, "%d %d %d",
333
0
                cipher_algo, s2k->mode, s2k->hash_algo );
334
0
      write_status_text ( STATUS_NEED_PASSPHRASE_SYM, buf );
335
0
    }
336
337
118k
  if ( next_pw )
338
0
    {
339
      /* Simply return the passphrase we already have in NEXT_PW. */
340
0
      pw = next_pw;
341
0
      next_pw = NULL;
342
0
    }
343
118k
  else if ( have_static_passphrase () )
344
0
    {
345
      /* Return the passphrase we have stored in FD_PASSWD. */
346
0
      pw = xmalloc_secure ( strlen(fd_passwd)+1 );
347
0
      strcpy ( pw, fd_passwd );
348
0
    }
349
118k
  else
350
118k
    {
351
118k
      if (!nocache && (s2k->mode == 1 || s2k->mode == 3))
352
5.87k
  {
353
5.87k
    memset (s2k_cacheidbuf, 0, sizeof s2k_cacheidbuf);
354
5.87k
    *s2k_cacheidbuf = 'S';
355
5.87k
    bin2hex (s2k->salt, 8, s2k_cacheidbuf + 1);
356
5.87k
    s2k_cacheid = s2k_cacheidbuf;
357
5.87k
  }
358
359
118k
      if (opt.pinentry_mode == PINENTRY_MODE_LOOPBACK)
360
0
        {
361
0
          char buf[32];
362
363
0
          snprintf (buf, sizeof (buf), "%u", 100);
364
0
          write_status_text (STATUS_INQUIRE_MAXLEN, buf);
365
0
        }
366
367
      /* Divert to the gpg-agent. */
368
118k
      pw = passphrase_get (create, create && nocache, s2k_cacheid,
369
118k
                           create? opt.passphrase_repeat : 0,
370
118k
                           tryagain_text, flags, canceled);
371
118k
      if (*canceled)
372
118k
        {
373
118k
          xfree (pw);
374
118k
    write_status( STATUS_CANCELED_BY_USER );
375
118k
          return NULL;
376
118k
        }
377
118k
    }
378
379
0
  if ( !pw || !*pw )
380
0
    write_status( STATUS_MISSING_PASSPHRASE );
381
382
  /* Hash the passphrase and store it in a newly allocated DEK object.
383
     Keep a copy of the passphrase in LAST_PW for use by
384
     get_last_passphrase(). */
385
0
  dek = xmalloc_secure_clear ( sizeof *dek );
386
0
  dek->algo = cipher_algo;
387
0
  if ( (!pw || !*pw) && create)
388
0
    dek->keylen = 0;
389
0
  else
390
0
    {
391
0
      gpg_error_t err;
392
393
0
      dek->keylen = openpgp_cipher_get_algo_keylen (dek->algo);
394
0
      if (!(dek->keylen > 0 && dek->keylen <= DIM(dek->key)))
395
0
        BUG ();
396
0
      err = gcry_kdf_derive (pw, strlen (pw),
397
0
                             s2k->mode == 3? GCRY_KDF_ITERSALTED_S2K :
398
0
                             s2k->mode == 1? GCRY_KDF_SALTED_S2K :
399
0
                             /* */           GCRY_KDF_SIMPLE_S2K,
400
0
                             s2k->hash_algo, s2k->salt, 8,
401
0
                             S2K_DECODE_COUNT(s2k->count),
402
0
                             dek->keylen, dek->key);
403
0
      if (err)
404
0
        {
405
0
          log_error ("gcry_kdf_derive failed: %s", gpg_strerror (err));
406
0
          xfree (pw);
407
0
          xfree (dek);
408
0
    write_status( STATUS_MISSING_PASSPHRASE );
409
0
          return NULL;
410
0
        }
411
0
    }
412
0
  if (s2k_cacheid)
413
0
    memcpy (dek->s2k_cacheid, s2k_cacheid, sizeof dek->s2k_cacheid);
414
0
  xfree(last_pw);
415
0
  last_pw = pw;
416
0
  return dek;
417
0
}
418
419
420
/* Emit the USERID_HINT and the NEED_PASSPHRASE status messages.
421
   MAINKEYID may be NULL. */
422
void
423
emit_status_need_passphrase (ctrl_t ctrl,
424
                             u32 *keyid, u32 *mainkeyid, int pubkey_algo)
425
0
{
426
0
  char buf[50];
427
0
  char *us;
428
429
0
  us = get_long_user_id_string (ctrl, keyid);
430
0
  write_status_text (STATUS_USERID_HINT, us);
431
0
  xfree (us);
432
433
0
  snprintf (buf, sizeof buf, "%08lX%08lX %08lX%08lX %d 0",
434
0
            (ulong)keyid[0],
435
0
            (ulong)keyid[1],
436
0
            (ulong)(mainkeyid? mainkeyid[0]:keyid[0]),
437
0
            (ulong)(mainkeyid? mainkeyid[1]:keyid[1]),
438
0
            pubkey_algo);
439
440
0
  write_status_text (STATUS_NEED_PASSPHRASE, buf);
441
0
}
442
443
444
/* Return an allocated utf-8 string describing the key PK.  If ESCAPED
445
   is true spaces and control characters are percent or plus escaped.
446
   MODE describes the use of the key description; use one of the
447
   FORMAT_KEYDESC_ macros. */
448
char *
449
gpg_format_keydesc (ctrl_t ctrl, PKT_public_key *pk, int mode, int escaped)
450
0
{
451
0
  char *uid;
452
0
  size_t uidlen;
453
0
  const char *algo_name;
454
0
  const char *timestr;
455
0
  char *orig_codeset;
456
0
  char *maink;
457
0
  char *desc;
458
0
  const char *prompt;
459
0
  const char *trailer = "";
460
0
  int is_subkey;
461
462
0
  if (mode == FORMAT_KEYDESC_KEYGRIP)
463
0
    {
464
0
      is_subkey = 0;
465
0
      algo_name = NULL;
466
0
      timestr = NULL;
467
0
      uid = NULL;
468
0
    }
469
0
  else
470
0
    {
471
0
      is_subkey = (pk->main_keyid[0] && pk->main_keyid[1]
472
0
                   && pk->keyid[0] != pk->main_keyid[0]
473
0
                   && pk->keyid[1] != pk->main_keyid[1]);
474
0
      algo_name = openpgp_pk_algo_name (pk->pubkey_algo);
475
0
      timestr = strtimestamp (pk->timestamp);
476
0
      uid = get_user_id (ctrl, is_subkey? pk->main_keyid:pk->keyid,
477
0
                         &uidlen, NULL);
478
0
    }
479
480
0
  orig_codeset = i18n_switchto_utf8 ();
481
482
0
  if (is_subkey)
483
0
    maink = xtryasprintf (_(" (main key ID %s)"), keystr (pk->main_keyid));
484
0
  else
485
0
    maink = NULL;
486
487
0
  switch (mode)
488
0
    {
489
0
    case FORMAT_KEYDESC_NORMAL:
490
0
      prompt = _("Please enter the passphrase to unlock the"
491
0
                 " OpenPGP secret key:");
492
0
      break;
493
0
    case FORMAT_KEYDESC_IMPORT:
494
0
      prompt = _("Please enter the passphrase to import the"
495
0
                 " OpenPGP secret key:");
496
0
      break;
497
0
    case FORMAT_KEYDESC_EXPORT:
498
0
      if (is_subkey)
499
0
        prompt = _("Please enter the passphrase to export the"
500
0
                   " OpenPGP secret subkey:");
501
0
      else
502
0
        prompt = _("Please enter the passphrase to export the"
503
0
                   " OpenPGP secret key:");
504
0
      break;
505
0
    case FORMAT_KEYDESC_DELKEY:
506
0
      if (is_subkey)
507
0
        prompt = _("Do you really want to permanently delete the"
508
0
                   " OpenPGP secret subkey key:");
509
0
      else
510
0
        prompt = _("Do you really want to permanently delete the"
511
0
                   " OpenPGP secret key:");
512
0
      trailer = "?";
513
0
      break;
514
0
    case FORMAT_KEYDESC_KEYGRIP:
515
0
      prompt = _("Please enter the passphrase to export the"
516
0
                 " secret key with keygrip:");
517
0
      break;
518
0
    default:
519
0
      prompt = "?";
520
0
      break;
521
0
    }
522
523
0
  if (mode == FORMAT_KEYDESC_KEYGRIP)
524
0
    desc = xtryasprintf ("%s\n\n"
525
0
                         "   %s\n",
526
0
                         prompt,
527
0
                         "<keygrip>");
528
0
  else
529
0
    desc = xtryasprintf (_("%s\n"
530
0
                           "\"%.*s\"\n"
531
0
                           "%u-bit %s key, ID %s,\n"
532
0
                           "created %s%s.\n%s"),
533
0
                         prompt,
534
0
                         (int)uidlen, uid,
535
0
                         nbits_from_pk (pk), algo_name,
536
0
                         keystr (pk->keyid), timestr,
537
0
                         maink?maink:"", trailer);
538
0
  xfree (maink);
539
0
  xfree (uid);
540
541
0
  i18n_switchback (orig_codeset);
542
543
0
  if (escaped)
544
0
    {
545
0
      char *tmp = percent_plus_escape (desc);
546
0
      xfree (desc);
547
0
      desc = tmp;
548
0
    }
549
550
0
  return desc;
551
0
}