Coverage Report

Created: 2025-12-14 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gnupg/g10/misc.c
Line
Count
Source
1
/* misc.c - miscellaneous functions
2
 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
3
 *               2008, 2009, 2010 Free Software Foundation, Inc.
4
 * Copyright (C) 2014 Werner Koch
5
 *
6
 * This file is part of GnuPG.
7
 *
8
 * GnuPG is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * GnuPG is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <config.h>
23
#include <stdio.h>
24
#include <stdlib.h>
25
#include <string.h>
26
#include <unistd.h>
27
#include <errno.h>
28
#if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
29
#include <asm/sysinfo.h>
30
#include <asm/unistd.h>
31
#endif
32
#ifdef HAVE_SETRLIMIT
33
#include <time.h>
34
#include <sys/time.h>
35
#include <sys/resource.h>
36
#endif
37
#ifdef ENABLE_SELINUX_HACKS
38
#include <sys/stat.h>
39
#endif
40
41
#ifdef HAVE_W32_SYSTEM
42
#include <time.h>
43
#include <process.h>
44
#ifdef HAVE_WINSOCK2_H
45
# define WIN32_LEAN_AND_MEAN 1
46
# include <winsock2.h>
47
#endif
48
#include <windows.h>
49
#include <shlobj.h>
50
#ifndef CSIDL_APPDATA
51
#define CSIDL_APPDATA 0x001a
52
#endif
53
#ifndef CSIDL_LOCAL_APPDATA
54
#define CSIDL_LOCAL_APPDATA 0x001c
55
#endif
56
#ifndef CSIDL_FLAG_CREATE
57
#define CSIDL_FLAG_CREATE 0x8000
58
#endif
59
#endif /*HAVE_W32_SYSTEM*/
60
61
#include "gpg.h"
62
#ifdef HAVE_W32_SYSTEM
63
# include "../common/status.h"
64
#endif /*HAVE_W32_SYSTEM*/
65
#include "../common/util.h"
66
#include "main.h"
67
#include "photoid.h"
68
#include "options.h"
69
#include "call-agent.h"
70
#include "../common/i18n.h"
71
#include "../common/zb32.h"
72
73
74
/* FIXME: Libgcrypt 1.9 will support EAX.  Until we name this a
75
 * requirement we hardwire the enum used for EAX.  */
76
1
#define MY_GCRY_CIPHER_MODE_EAX 14
77
78
79
#ifdef ENABLE_SELINUX_HACKS
80
/* A object and a global variable to keep track of files marked as
81
   secured. */
82
struct secured_file_item
83
{
84
  struct secured_file_item *next;
85
  ino_t ino;
86
  dev_t dev;
87
};
88
static struct secured_file_item *secured_files;
89
#endif /*ENABLE_SELINUX_HACKS*/
90
91
92
93
94
/* For the sake of SELinux we want to restrict access through gpg to
95
   certain files we keep under our own control.  This function
96
   registers such a file and is_secured_file may then be used to
97
   check whether a file has ben registered as secured. */
98
void
99
register_secured_file (const char *fname)
100
0
{
101
#ifdef ENABLE_SELINUX_HACKS
102
  struct stat buf;
103
  struct secured_file_item *sf;
104
105
  /* Note that we stop immediately if something goes wrong here. */
106
  if (gnupg_stat (fname, &buf))
107
    log_fatal (_("fstat of '%s' failed in %s: %s\n"), fname,
108
               "register_secured_file", strerror (errno));
109
/*   log_debug ("registering '%s' i=%lu.%lu\n", fname, */
110
/*              (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
111
  for (sf=secured_files; sf; sf = sf->next)
112
    {
113
      if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
114
        return; /* Already registered.  */
115
    }
116
117
  sf = xmalloc (sizeof *sf);
118
  sf->ino = buf.st_ino;
119
  sf->dev = buf.st_dev;
120
  sf->next = secured_files;
121
  secured_files = sf;
122
#else /*!ENABLE_SELINUX_HACKS*/
123
0
  (void)fname;
124
0
#endif /*!ENABLE_SELINUX_HACKS*/
125
0
}
126
127
/* Remove a file registered as secure. */
128
void
129
unregister_secured_file (const char *fname)
130
0
{
131
#ifdef ENABLE_SELINUX_HACKS
132
  struct stat buf;
133
  struct secured_file_item *sf, *sfprev;
134
135
  if (gnupg_stat (fname, &buf))
136
    {
137
      log_error (_("fstat of '%s' failed in %s: %s\n"), fname,
138
                 "unregister_secured_file", strerror (errno));
139
      return;
140
    }
141
/*   log_debug ("unregistering '%s' i=%lu.%lu\n", fname,  */
142
/*              (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
143
  for (sfprev=NULL,sf=secured_files; sf; sfprev=sf, sf = sf->next)
144
    {
145
      if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
146
        {
147
          if (sfprev)
148
            sfprev->next = sf->next;
149
          else
150
            secured_files = sf->next;
151
          xfree (sf);
152
          return;
153
        }
154
    }
155
#else /*!ENABLE_SELINUX_HACKS*/
156
0
  (void)fname;
157
0
#endif /*!ENABLE_SELINUX_HACKS*/
158
0
}
159
160
/* Return true if FD is corresponds to a secured file.  Using -1 for
161
   FS is allowed and will return false. */
162
int
163
is_secured_file (gnupg_fd_t fd)
164
0
{
165
#ifdef ENABLE_SELINUX_HACKS
166
  struct stat buf;
167
  struct secured_file_item *sf;
168
169
  if (fd == -1)
170
    return 0; /* No file descriptor so it can't be secured either.  */
171
172
  /* Note that we print out a error here and claim that a file is
173
     secure if something went wrong. */
174
  if (fstat (fd, &buf))
175
    {
176
      log_error (_("fstat(%d) failed in %s: %s\n"), fd,
177
                 "is_secured_file", strerror (errno));
178
      return 1;
179
    }
180
/*   log_debug ("is_secured_file (%d) i=%lu.%lu\n", fd, */
181
/*              (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
182
  for (sf=secured_files; sf; sf = sf->next)
183
    {
184
      if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
185
        return 1; /* Yes.  */
186
    }
187
#else /*!ENABLE_SELINUX_HACKS*/
188
0
  (void)fd;
189
0
#endif /*!ENABLE_SELINUX_HACKS*/
190
0
  return 0; /* No. */
191
0
}
192
193
/* Return true if FNAME is corresponds to a secured file.  Using NULL,
194
   "" or "-" for FS is allowed and will return false. This function is
195
   used before creating a file, thus it won't fail if the file does
196
   not exist. */
197
int
198
is_secured_filename (const char *fname)
199
3
{
200
#ifdef ENABLE_SELINUX_HACKS
201
  struct stat buf;
202
  struct secured_file_item *sf;
203
204
  if (iobuf_is_pipe_filename (fname) || !*fname)
205
    return 0;
206
207
  /* Note that we print out a error here and claim that a file is
208
     secure if something went wrong. */
209
  if (gnupg_stat (fname, &buf))
210
    {
211
      if (errno == ENOENT || errno == EPERM || errno == EACCES)
212
        return 0;
213
      log_error (_("fstat of '%s' failed in %s: %s\n"), fname,
214
                 "is_secured_filename", strerror (errno));
215
      return 1;
216
    }
217
/*   log_debug ("is_secured_filename (%s) i=%lu.%lu\n", fname, */
218
/*              (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
219
  for (sf=secured_files; sf; sf = sf->next)
220
    {
221
      if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
222
        return 1; /* Yes.  */
223
    }
224
#else /*!ENABLE_SELINUX_HACKS*/
225
3
  (void)fname;
226
3
#endif /*!ENABLE_SELINUX_HACKS*/
227
3
  return 0; /* No. */
228
3
}
229
230
231
232
u16
233
checksum_u16( unsigned n )
234
0
{
235
0
    u16 a;
236
237
0
    a  = (n >> 8) & 0xff;
238
0
    a += n & 0xff;
239
0
    return a;
240
0
}
241
242
243
u16
244
checksum (const byte *p, unsigned n)
245
0
{
246
0
    u16 a;
247
248
0
    for(a=0; n; n-- )
249
0
  a += *p++;
250
0
    return a;
251
0
}
252
253
u16
254
checksum_mpi (gcry_mpi_t a)
255
0
{
256
0
  u16 csum;
257
0
  byte *buffer;
258
0
  size_t nbytes;
259
260
  /*
261
   * This code can be skipped when gcry_mpi_print
262
   * supports opaque MPI.
263
   */
264
0
  if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
265
0
    {
266
0
      const byte *p;
267
0
      unsigned int nbits;
268
269
0
      p = gcry_mpi_get_opaque (a, &nbits);
270
0
      if (!p)
271
0
        return 0;
272
273
0
      csum = nbits >> 8;
274
0
      csum += (nbits & 0xff);
275
0
      csum += checksum (p, (nbits+7)/8);
276
0
      return csum;
277
0
    }
278
279
0
  if ( gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0, &nbytes, a) )
280
0
    BUG ();
281
  /* Fixme: For numbers not in secure memory we should use a stack
282
   * based buffer and only allocate a larger one if mpi_print returns
283
   * an error. */
284
0
  buffer = (gcry_is_secure(a)?
285
0
            gcry_xmalloc_secure (nbytes) : gcry_xmalloc (nbytes));
286
0
  if ( gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, NULL, a) )
287
0
    BUG ();
288
0
  csum = checksum (buffer, nbytes);
289
0
  xfree (buffer);
290
0
  return csum;
291
0
}
292
293
294
void
295
print_pubkey_algo_note (pubkey_algo_t algo)
296
0
{
297
0
  if(algo >= 100 && algo <= 110)
298
0
    {
299
0
      static int warn=0;
300
0
      if(!warn)
301
0
  {
302
0
    warn=1;
303
0
          es_fflush (es_stdout);
304
0
    log_info (_("WARNING: using experimental public key algorithm %s\n"),
305
0
        openpgp_pk_algo_name (algo));
306
0
  }
307
0
    }
308
0
  else if (algo == PUBKEY_ALGO_ELGAMAL)
309
0
    {
310
0
      es_fflush (es_stdout);
311
0
      log_info (_("WARNING: Elgamal sign+encrypt keys are deprecated\n"));
312
0
    }
313
0
}
314
315
void
316
print_cipher_algo_note (cipher_algo_t algo)
317
0
{
318
0
  if(algo >= 100 && algo <= 110)
319
0
    {
320
0
      static int warn=0;
321
0
      if(!warn)
322
0
  {
323
0
    warn=1;
324
0
          es_fflush (es_stdout);
325
0
    log_info (_("WARNING: using experimental cipher algorithm %s\n"),
326
0
                    openpgp_cipher_algo_name (algo));
327
0
  }
328
0
    }
329
0
}
330
331
void
332
print_digest_algo_note (digest_algo_t algo)
333
0
{
334
0
  if(algo >= 100 && algo <= 110)
335
0
    {
336
0
      static int warn=0;
337
0
      const enum gcry_md_algos galgo = map_md_openpgp_to_gcry (algo);
338
339
0
      if(!warn)
340
0
  {
341
0
    warn=1;
342
0
          es_fflush (es_stdout);
343
0
    log_info (_("WARNING: using experimental digest algorithm %s\n"),
344
0
                    gcry_md_algo_name (galgo));
345
0
  }
346
0
    }
347
0
  else if (is_weak_digest (algo))
348
0
    {
349
0
      const enum gcry_md_algos galgo = map_md_openpgp_to_gcry (algo);
350
0
      es_fflush (es_stdout);
351
0
      log_info (_("WARNING: digest algorithm %s is deprecated\n"),
352
0
                gcry_md_algo_name (galgo));
353
0
    }
354
0
}
355
356
357
void
358
print_digest_rejected_note (enum gcry_md_algos algo)
359
0
{
360
0
  struct weakhash* weak;
361
0
  int show = 1;
362
363
0
  if (opt.quiet)
364
0
    return;
365
366
0
  for (weak = opt.weak_digests; weak; weak = weak->next)
367
0
    if (weak->algo == algo)
368
0
      {
369
0
        if (weak->rejection_shown)
370
0
          show = 0;
371
0
        else
372
0
          weak->rejection_shown = 1;
373
0
        break;
374
0
      }
375
376
0
  if (show)
377
0
    {
378
0
      es_fflush (es_stdout);
379
0
      log_info
380
0
        (_("Note: signatures using the %s algorithm are rejected\n"),
381
0
         gcry_md_algo_name(algo));
382
0
    }
383
0
}
384
385
386
void
387
print_sha1_keysig_rejected_note (void)
388
0
{
389
0
  static int shown;
390
391
0
  if (shown || opt.quiet)
392
0
    return;
393
394
0
  shown = 1;
395
0
  es_fflush (es_stdout);
396
0
  log_info (_("Note: third-party key signatures using"
397
0
              " the %s algorithm are rejected\n"),
398
0
            gcry_md_algo_name (GCRY_MD_SHA1));
399
0
  if (!opt.quiet)
400
0
    log_info (_("(use option \"%s\" to override)\n"),
401
0
              "--allow-weak-key-signatures");
402
0
}
403
404
405
/* Print a message
406
 *  "(reported error: %s)\n
407
 * in verbose mode to further explain an error.  If the error code has
408
 * the value IGNORE_EC no message is printed.  A message is also not
409
 * printed if ERR is 0.  */
410
void
411
print_reported_error (gpg_error_t err, gpg_err_code_t ignore_ec)
412
0
{
413
0
  if (!opt.verbose)
414
0
    return;
415
416
0
  if (!gpg_err_code (err))
417
0
    ;
418
0
  else if (gpg_err_code (err) == ignore_ec)
419
0
    ;
420
0
  else if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT)
421
0
    log_info (_("(reported error: %s)\n"),
422
0
              gpg_strerror (err));
423
0
  else
424
0
    log_info (_("(reported error: %s <%s>)\n"),
425
0
              gpg_strerror (err), gpg_strsource (err));
426
427
0
}
428
429
430
/* Print a message
431
 *   "(further info: %s)\n
432
 * in verbose mode to further explain an error.  That message is
433
 * intended to help debug a problem and should not be translated.
434
 */
435
void
436
print_further_info (const char *format, ...)
437
0
{
438
0
  va_list arg_ptr;
439
440
0
  if (!opt.verbose)
441
0
    return;
442
443
0
  log_info (_("(further info: "));
444
0
  va_start (arg_ptr, format);
445
0
  log_logv (GPGRT_LOGLVL_CONT, format, arg_ptr);
446
0
  va_end (arg_ptr);
447
0
  log_printf (")\n");
448
0
}
449
450
451
/* Map OpenPGP algo numbers to those used by Libgcrypt.  We need to do
452
   this for algorithms we implemented in Libgcrypt after they become
453
   part of OpenPGP.  */
454
enum gcry_cipher_algos
455
map_cipher_openpgp_to_gcry (cipher_algo_t algo)
456
5.27k
{
457
5.27k
  switch (algo)
458
5.27k
    {
459
2
    case CIPHER_ALGO_NONE:        return GCRY_CIPHER_NONE;
460
461
0
#ifdef GPG_USE_IDEA
462
3.25k
    case CIPHER_ALGO_IDEA:        return GCRY_CIPHER_IDEA;
463
#else
464
    case CIPHER_ALGO_IDEA:        return 0;
465
#endif
466
467
42
    case CIPHER_ALGO_3DES:    return GCRY_CIPHER_3DES;
468
469
0
#ifdef GPG_USE_CAST5
470
207
    case CIPHER_ALGO_CAST5:   return GCRY_CIPHER_CAST5;
471
#else
472
    case CIPHER_ALGO_CAST5:   return 0;
473
#endif
474
475
0
#ifdef GPG_USE_BLOWFISH
476
79
    case CIPHER_ALGO_BLOWFISH:    return GCRY_CIPHER_BLOWFISH;
477
#else
478
    case CIPHER_ALGO_BLOWFISH:    return 0;
479
#endif
480
481
0
#ifdef GPG_USE_AES128
482
92
    case CIPHER_ALGO_AES:         return GCRY_CIPHER_AES;
483
#else
484
    case CIPHER_ALGO_AES:         return 0;
485
#endif
486
487
0
#ifdef GPG_USE_AES192
488
152
    case CIPHER_ALGO_AES192:      return GCRY_CIPHER_AES192;
489
#else
490
    case CIPHER_ALGO_AES192:      return 0;
491
#endif
492
493
0
#ifdef GPG_USE_AES256
494
140
    case CIPHER_ALGO_AES256:      return GCRY_CIPHER_AES256;
495
#else
496
    case CIPHER_ALGO_AES256:      return 0;
497
#endif
498
499
0
#ifdef GPG_USE_TWOFISH
500
362
    case CIPHER_ALGO_TWOFISH:     return GCRY_CIPHER_TWOFISH;
501
#else
502
    case CIPHER_ALGO_TWOFISH:     return 0;
503
#endif
504
505
0
#ifdef GPG_USE_CAMELLIA128
506
230
    case CIPHER_ALGO_CAMELLIA128: return GCRY_CIPHER_CAMELLIA128;
507
#else
508
    case CIPHER_ALGO_CAMELLIA128: return 0;
509
#endif
510
511
0
#ifdef GPG_USE_CAMELLIA192
512
241
    case CIPHER_ALGO_CAMELLIA192: return GCRY_CIPHER_CAMELLIA192;
513
#else
514
    case CIPHER_ALGO_CAMELLIA192: return 0;
515
#endif
516
517
0
#ifdef GPG_USE_CAMELLIA256
518
72
    case CIPHER_ALGO_CAMELLIA256: return GCRY_CIPHER_CAMELLIA256;
519
#else
520
    case CIPHER_ALGO_CAMELLIA256: return 0;
521
#endif
522
401
    default: return 0;
523
5.27k
    }
524
5.27k
}
525
526
/* The inverse function of above.  */
527
static cipher_algo_t
528
map_cipher_gcry_to_openpgp (enum gcry_cipher_algos algo)
529
0
{
530
0
  switch (algo)
531
0
    {
532
0
    case GCRY_CIPHER_NONE:        return CIPHER_ALGO_NONE;
533
0
    case GCRY_CIPHER_IDEA:        return CIPHER_ALGO_IDEA;
534
0
    case GCRY_CIPHER_3DES:        return CIPHER_ALGO_3DES;
535
0
    case GCRY_CIPHER_CAST5:       return CIPHER_ALGO_CAST5;
536
0
    case GCRY_CIPHER_BLOWFISH:    return CIPHER_ALGO_BLOWFISH;
537
0
    case GCRY_CIPHER_AES:         return CIPHER_ALGO_AES;
538
0
    case GCRY_CIPHER_AES192:      return CIPHER_ALGO_AES192;
539
0
    case GCRY_CIPHER_AES256:      return CIPHER_ALGO_AES256;
540
0
    case GCRY_CIPHER_TWOFISH:     return CIPHER_ALGO_TWOFISH;
541
0
    case GCRY_CIPHER_CAMELLIA128: return CIPHER_ALGO_CAMELLIA128;
542
0
    case GCRY_CIPHER_CAMELLIA192: return CIPHER_ALGO_CAMELLIA192;
543
0
    case GCRY_CIPHER_CAMELLIA256: return CIPHER_ALGO_CAMELLIA256;
544
0
    default: return 0;
545
0
    }
546
0
}
547
548
549
/* Return the block length of an OpenPGP cipher algorithm.  */
550
int
551
openpgp_cipher_blocklen (cipher_algo_t algo)
552
874
{
553
  /* We use the numbers from OpenPGP to be sure that we get the right
554
     block length.  This is so that the packet parsing code works even
555
     for unknown algorithms (for which we assume 8 due to tradition).
556
557
     NOTE: If you change the returned blocklen above 16, check
558
     the callers because they may use a fixed size buffer of that
559
     size. */
560
874
  switch (algo)
561
874
    {
562
0
    case CIPHER_ALGO_AES:
563
2
    case CIPHER_ALGO_AES192:
564
5
    case CIPHER_ALGO_AES256:
565
5
    case CIPHER_ALGO_TWOFISH:
566
7
    case CIPHER_ALGO_CAMELLIA128:
567
9
    case CIPHER_ALGO_CAMELLIA192:
568
10
    case CIPHER_ALGO_CAMELLIA256:
569
10
      return 16;
570
571
864
    default:
572
864
      return 8;
573
874
    }
574
874
}
575
576
/****************
577
 * Wrapper around the libgcrypt function with additional checks on
578
 * the OpenPGP constraints for the algo ID.
579
 */
580
int
581
openpgp_cipher_test_algo (cipher_algo_t algo)
582
5.27k
{
583
5.27k
  enum gcry_cipher_algos ga;
584
585
5.27k
  ga = map_cipher_openpgp_to_gcry (algo);
586
5.27k
  if (!ga)
587
403
    return gpg_error (GPG_ERR_CIPHER_ALGO);
588
589
4.87k
  return gcry_cipher_test_algo (ga);
590
5.27k
}
591
592
/* Map the OpenPGP cipher algorithm whose ID is contained in ALGORITHM to a
593
   string representation of the algorithm name.  For unknown algorithm
594
   IDs this function returns "?".  */
595
const char *
596
openpgp_cipher_algo_name (cipher_algo_t algo)
597
2.08k
{
598
2.08k
  switch (algo)
599
2.08k
    {
600
66
    case CIPHER_ALGO_IDEA:        return "IDEA";
601
42
    case CIPHER_ALGO_3DES:    return "3DES";
602
207
    case CIPHER_ALGO_CAST5:   return "CAST5";
603
79
    case CIPHER_ALGO_BLOWFISH:    return "BLOWFISH";
604
92
    case CIPHER_ALGO_AES:         return "AES";
605
152
    case CIPHER_ALGO_AES192:      return "AES192";
606
140
    case CIPHER_ALGO_AES256:      return "AES256";
607
362
    case CIPHER_ALGO_TWOFISH:     return "TWOFISH";
608
230
    case CIPHER_ALGO_CAMELLIA128: return "CAMELLIA128";
609
241
    case CIPHER_ALGO_CAMELLIA192: return "CAMELLIA192";
610
72
    case CIPHER_ALGO_CAMELLIA256: return "CAMELLIA256";
611
2
    case CIPHER_ALGO_NONE:
612
403
    default: return "?";
613
2.08k
    }
614
2.08k
}
615
616
617
/* Same as openpgp_cipher_algo_name but returns a string in the form
618
 * "ALGO.MODE".  If AEAD is 0 "CFB" is used for the mode.  */
619
const char *
620
openpgp_cipher_algo_mode_name (cipher_algo_t algo, aead_algo_t aead)
621
0
{
622
0
  return map_static_strings ("openpgp_cipher_algo_mode_name", algo, aead,
623
0
                             openpgp_cipher_algo_name (algo),
624
0
                             ".",
625
0
                             aead? openpgp_aead_algo_name (aead) : "CFB",
626
0
                             NULL);
627
0
}
628
629
630
/* Return 0 if ALGO is supported.  Return an error if not. */
631
gpg_error_t
632
openpgp_aead_test_algo (aead_algo_t algo)
633
0
{
634
  /* FIXME: We currently have no easy way to test whether libgcrypt
635
   * implements a mode.  The only way we can do this is to open a
636
   * cipher context with that mode and close it immediately.  That is
637
   * a bit costly.  Thus in case we add another algo we need to look
638
   * at the libgcrypt version and assume nothing has been patched out.  */
639
0
  switch (algo)
640
0
    {
641
0
    case AEAD_ALGO_NONE:
642
0
      break;
643
644
0
    case AEAD_ALGO_EAX:
645
0
    case AEAD_ALGO_OCB:
646
0
      return 0;
647
0
    }
648
649
0
  return gpg_error (GPG_ERR_INV_CIPHER_MODE);
650
0
}
651
652
653
/* Map the OpenPGP AEAD algorithm with ID ALGO to a string
654
 * representation of the algorithm name.  For unknown algorithm IDs
655
 * this function returns "?".  */
656
const char *
657
openpgp_aead_algo_name (aead_algo_t algo)
658
51
{
659
51
  switch (algo)
660
51
    {
661
0
    case AEAD_ALGO_NONE:  break;
662
2
    case AEAD_ALGO_EAX:   return "EAX";
663
32
    case AEAD_ALGO_OCB:   return "OCB";
664
51
    }
665
666
17
  return "?";
667
51
}
668
669
670
/* Return information for the AEAD algorithm ALGO.  The corresponding
671
 * Libgcrypt ciphermode is stored at R_MODE and the required number of
672
 * octets for the nonce at R_NONCELEN.  On error and error code is
673
 * returned.  Note that the taglen is always 128 bits.  */
674
gpg_error_t
675
openpgp_aead_algo_info (aead_algo_t algo, enum gcry_cipher_modes *r_mode,
676
                        unsigned int *r_noncelen)
677
42
{
678
42
  switch (algo)
679
42
    {
680
3
    case AEAD_ALGO_OCB:
681
3
      *r_mode = GCRY_CIPHER_MODE_OCB;
682
3
      *r_noncelen = 15;
683
3
      break;
684
685
1
    case AEAD_ALGO_EAX:
686
1
      *r_mode = MY_GCRY_CIPHER_MODE_EAX;
687
1
      *r_noncelen = 16;
688
1
      break;
689
690
38
    default:
691
38
      log_error ("unsupported AEAD algo %d\n", algo);
692
38
      return gpg_error (GPG_ERR_INV_CIPHER_MODE);
693
42
    }
694
4
  return 0;
695
42
}
696
697
698
/* Return 0 if ALGO is a supported OpenPGP public key algorithm.  */
699
int
700
openpgp_pk_test_algo (pubkey_algo_t algo)
701
524
{
702
524
  return openpgp_pk_test_algo2 (algo, 0);
703
524
}
704
705
706
/* Return 0 if ALGO is a supported OpenPGP public key algorithm and
707
   allows the usage USE.  */
708
int
709
openpgp_pk_test_algo2 (pubkey_algo_t algo, unsigned int use)
710
524
{
711
524
  enum gcry_pk_algos ga = 0;
712
524
  size_t use_buf = use;
713
714
524
  switch (algo)
715
524
    {
716
0
#ifdef GPG_USE_RSA
717
38
    case PUBKEY_ALGO_RSA:       ga = GCRY_PK_RSA;   break;
718
0
    case PUBKEY_ALGO_RSA_E:     ga = GCRY_PK_RSA_E; break;
719
0
    case PUBKEY_ALGO_RSA_S:     ga = GCRY_PK_RSA_S; break;
720
#else
721
    case PUBKEY_ALGO_RSA:       break;
722
    case PUBKEY_ALGO_RSA_E:     break;
723
    case PUBKEY_ALGO_RSA_S:     break;
724
#endif
725
726
64
    case PUBKEY_ALGO_ELGAMAL_E: ga = GCRY_PK_ELG;   break;
727
397
    case PUBKEY_ALGO_DSA:       ga = GCRY_PK_DSA;   break;
728
729
0
#ifdef GPG_USE_ECDH
730
3
    case PUBKEY_ALGO_ECDH:      ga = GCRY_PK_ECC;   break;
731
#else
732
    case PUBKEY_ALGO_ECDH:      break;
733
#endif
734
735
0
#ifdef GPG_USE_ECDSA
736
22
    case PUBKEY_ALGO_ECDSA:     ga = GCRY_PK_ECC;   break;
737
#else
738
    case PUBKEY_ALGO_ECDSA:     break;
739
#endif
740
741
0
#ifdef GPG_USE_EDDSA
742
0
    case PUBKEY_ALGO_EDDSA:     ga = GCRY_PK_ECC;   break;
743
#else
744
    case PUBKEY_ALGO_EDDSA:     break;
745
#endif
746
747
0
    case PUBKEY_ALGO_ELGAMAL:
748
      /* Don't allow type 20 keys unless in rfc2440 mode.  */
749
0
      if (RFC2440)
750
0
        ga = GCRY_PK_ELG;
751
0
      break;
752
753
0
    case PUBKEY_ALGO_KYBER:     ga = GCRY_PK_KEM; break;
754
755
0
    default:
756
0
      break;
757
524
    }
758
524
  if (!ga)
759
0
    return gpg_error (GPG_ERR_PUBKEY_ALGO);
760
761
  /* Elgamal in OpenPGP used to support signing and Libgcrypt still
762
   * does.  However, we removed the signing capability from gpg ages
763
   * ago.  This function should reflect this so that errors are thrown
764
   * early and not only when we try to sign using Elgamal.  */
765
524
  if (ga == GCRY_PK_ELG && (use & (PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG)))
766
0
    return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
767
768
  /* Now check whether Libgcrypt has support for the algorithm.  */
769
524
  return gcry_pk_algo_info (ga, GCRYCTL_TEST_ALGO, NULL, &use_buf);
770
524
}
771
772
773
int
774
openpgp_pk_algo_usage ( int algo )
775
561
{
776
561
    int use = 0;
777
778
    /* They are hardwired in gpg 1.0. */
779
561
    switch ( algo ) {
780
46
      case PUBKEY_ALGO_RSA:
781
46
          use = (PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG
782
46
                 | PUBKEY_USAGE_ENC | PUBKEY_USAGE_RENC | PUBKEY_USAGE_AUTH);
783
46
          break;
784
0
      case PUBKEY_ALGO_RSA_E:
785
3
      case PUBKEY_ALGO_ECDH:
786
3
          use = PUBKEY_USAGE_ENC | PUBKEY_USAGE_RENC;
787
3
          break;
788
2
      case PUBKEY_ALGO_RSA_S:
789
2
          use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG;
790
2
          break;
791
0
      case PUBKEY_ALGO_ELGAMAL:
792
0
          if (RFC2440)
793
0
             use = PUBKEY_USAGE_ENC | PUBKEY_USAGE_RENC;
794
0
          break;
795
64
      case PUBKEY_ALGO_ELGAMAL_E:
796
64
          use = PUBKEY_USAGE_ENC | PUBKEY_USAGE_RENC;
797
64
          break;
798
128
      case PUBKEY_ALGO_DSA:
799
128
          use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH;
800
128
          break;
801
56
      case PUBKEY_ALGO_ECDSA:
802
84
      case PUBKEY_ALGO_EDDSA:
803
84
          use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH;
804
84
          break;
805
806
0
      case PUBKEY_ALGO_KYBER:
807
0
          use = PUBKEY_USAGE_ENC | PUBKEY_USAGE_RENC;
808
0
          break;
809
810
0
      case PUBKEY_ALGO_DIL3_25519:
811
0
      case PUBKEY_ALGO_DIL5_448:
812
2
      case PUBKEY_ALGO_SPHINX_SHA2:
813
2
          use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG;
814
2
          break;
815
816
232
      default:
817
232
          break;
818
561
    }
819
561
    return use;
820
561
}
821
822
/* Map the OpenPGP pubkey algorithm whose ID is contained in ALGO to a
823
   string representation of the algorithm name.  For unknown algorithm
824
   IDs this function returns "?".  */
825
const char *
826
openpgp_pk_algo_name (pubkey_algo_t algo)
827
5.81k
{
828
5.81k
  switch (algo)
829
5.81k
    {
830
2
    case PUBKEY_ALGO_RSA:
831
4
    case PUBKEY_ALGO_RSA_E:
832
10
    case PUBKEY_ALGO_RSA_S:     return "RSA";
833
0
    case PUBKEY_ALGO_ELGAMAL:
834
13
    case PUBKEY_ALGO_ELGAMAL_E: return "ELG";
835
1.01k
    case PUBKEY_ALGO_DSA:       return "DSA";
836
14
    case PUBKEY_ALGO_ECDH:      return "ECDH";
837
2
    case PUBKEY_ALGO_ECDSA:     return "ECDSA";
838
0
    case PUBKEY_ALGO_EDDSA:     return "EDDSA";
839
1
    case PUBKEY_ALGO_KYBER:     return "Kyber";
840
4.76k
    default: return "?";
841
5.81k
    }
842
5.81k
}
843
844
845
/* Explicit mapping of OpenPGP digest algos to Libgcrypt.  */
846
/* FIXME: We do not yes use it everywhere.  */
847
enum gcry_md_algos
848
map_md_openpgp_to_gcry (digest_algo_t algo)
849
5.39k
{
850
5.39k
  switch (algo)
851
5.39k
    {
852
0
#ifdef GPG_USE_MD5
853
417
    case DIGEST_ALGO_MD5:    return GCRY_MD_MD5;
854
#else
855
    case DIGEST_ALGO_MD5:    return 0;
856
#endif
857
858
824
    case DIGEST_ALGO_SHA1:   return GCRY_MD_SHA1;
859
860
0
#ifdef GPG_USE_RMD160
861
77
    case DIGEST_ALGO_RMD160: return GCRY_MD_RMD160;
862
#else
863
    case DIGEST_ALGO_RMD160: return 0;
864
#endif
865
866
0
#ifdef GPG_USE_SHA224
867
74
    case DIGEST_ALGO_SHA224: return GCRY_MD_SHA224;
868
#else
869
    case DIGEST_ALGO_SHA224: return 0;
870
#endif
871
872
125
    case DIGEST_ALGO_SHA256: return GCRY_MD_SHA256;
873
874
0
#ifdef GPG_USE_SHA384
875
142
    case DIGEST_ALGO_SHA384: return GCRY_MD_SHA384;
876
#else
877
    case DIGEST_ALGO_SHA384: return 0;
878
#endif
879
880
0
#ifdef GPG_USE_SHA512
881
148
    case DIGEST_ALGO_SHA512: return GCRY_MD_SHA512;
882
#else
883
    case DIGEST_ALGO_SHA512: return 0;
884
#endif
885
3.59k
    default: return 0;
886
5.39k
    }
887
5.39k
}
888
889
890
/* Return 0 if ALGO is suitable and implemented OpenPGP hash
891
   algorithm.  */
892
int
893
openpgp_md_test_algo (digest_algo_t algo)
894
5.20k
{
895
5.20k
  enum gcry_md_algos ga;
896
897
5.20k
  ga = map_md_openpgp_to_gcry (algo);
898
5.20k
  if (!ga)
899
3.59k
    return gpg_error (GPG_ERR_DIGEST_ALGO);
900
901
1.61k
  return gcry_md_test_algo (ga);
902
5.20k
}
903
904
905
/* Map the OpenPGP digest algorithm whose ID is contained in ALGO to a
906
   string representation of the algorithm name.  For unknown algorithm
907
   IDs this function returns "?".  */
908
const char *
909
openpgp_md_algo_name (int algo)
910
0
{
911
0
  switch (algo)
912
0
    {
913
0
    case DIGEST_ALGO_MD5:    return "MD5";
914
0
    case DIGEST_ALGO_SHA1:   return "SHA1";
915
0
    case DIGEST_ALGO_RMD160: return "RIPEMD160";
916
0
    case DIGEST_ALGO_SHA256: return "SHA256";
917
0
    case DIGEST_ALGO_SHA384: return "SHA384";
918
0
    case DIGEST_ALGO_SHA512: return "SHA512";
919
0
    case DIGEST_ALGO_SHA224: return "SHA224";
920
0
    }
921
0
  return "?";
922
0
}
923
924
925
static unsigned long
926
get_signature_count (PKT_public_key *pk)
927
0
{
928
#ifdef ENABLE_CARD_SUPPORT
929
  struct agent_card_info_s info;
930
931
  (void)pk;
932
  if (!agent_scd_getattr ("SIG-COUNTER",&info))
933
    return info.sig_counter;
934
  else
935
    return 0;
936
#else
937
0
  (void)pk;
938
0
  return 0;
939
0
#endif
940
0
}
941
942
/* Expand %-strings.  Returns a string which must be xfreed.  Returns
943
   NULL if the string cannot be expanded (too large). */
944
char *
945
pct_expando (ctrl_t ctrl, const char *string,struct expando_args *args)
946
0
{
947
0
  const char *ch=string;
948
0
  int idx=0,maxlen=0,done=0;
949
0
  u32 pk_keyid[2]={0,0},sk_keyid[2]={0,0};
950
0
  char *ret=NULL;
951
952
  /* The parser below would return NULL for an empty string, thus we
953
   * catch it here.  Also catch NULL here. */
954
0
  if (!string || !*string)
955
0
    return xstrdup ("");
956
957
0
  if(args->pk)
958
0
    keyid_from_pk(args->pk,pk_keyid);
959
960
0
  if(args->pksk)
961
0
    keyid_from_pk (args->pksk, sk_keyid);
962
963
  /* This is used so that %k works in photoid command strings in
964
     --list-secret-keys (which of course has a sk, but no pk). */
965
0
  if(!args->pk && args->pksk)
966
0
    keyid_from_pk (args->pksk, pk_keyid);
967
968
0
  while(*ch!='\0')
969
0
    {
970
0
      if(!done)
971
0
  {
972
    /* 8192 is way bigger than we'll need here */
973
0
    if(maxlen>=8192)
974
0
      goto fail;
975
976
0
    maxlen+=1024;
977
0
    ret=xrealloc(ret,maxlen);
978
0
  }
979
980
0
      done=0;
981
982
0
      if(*ch=='%')
983
0
  {
984
0
    switch(*(ch+1))
985
0
      {
986
0
      case 's': /* short key id */
987
0
        if(idx+8<maxlen)
988
0
    {
989
0
      sprintf(&ret[idx],"%08lX",(ulong)sk_keyid[1]);
990
0
      idx+=8;
991
0
      done=1;
992
0
    }
993
0
        break;
994
995
0
      case 'S': /* long key id */
996
0
        if(idx+16<maxlen)
997
0
    {
998
0
      sprintf(&ret[idx],"%08lX%08lX",
999
0
        (ulong)sk_keyid[0],(ulong)sk_keyid[1]);
1000
0
      idx+=16;
1001
0
      done=1;
1002
0
    }
1003
0
        break;
1004
1005
0
      case 'k': /* short key id */
1006
0
        if(idx+8<maxlen)
1007
0
    {
1008
0
      sprintf(&ret[idx],"%08lX",(ulong)pk_keyid[1]);
1009
0
      idx+=8;
1010
0
      done=1;
1011
0
    }
1012
0
        break;
1013
1014
0
      case 'K': /* long key id */
1015
0
        if(idx+16<maxlen)
1016
0
    {
1017
0
      sprintf(&ret[idx],"%08lX%08lX",
1018
0
        (ulong)pk_keyid[0],(ulong)pk_keyid[1]);
1019
0
      idx+=16;
1020
0
      done=1;
1021
0
    }
1022
0
        break;
1023
1024
0
      case 'U': /* z-base-32 encoded user id hash. */
1025
0
              if (args->namehash)
1026
0
                {
1027
0
                  char *tmp = zb32_encode (args->namehash, 8*20);
1028
0
                  if (tmp)
1029
0
                    {
1030
0
                      if (idx + strlen (tmp) < maxlen)
1031
0
                        {
1032
0
                          strcpy (ret+idx, tmp);
1033
0
                          idx += strlen (tmp);
1034
0
                        }
1035
0
                      xfree (tmp);
1036
0
                      done = 1;
1037
0
                    }
1038
0
                }
1039
0
        break;
1040
1041
0
      case 'c': /* signature count from card, if any. */
1042
0
        if(idx+10<maxlen)
1043
0
    {
1044
0
      sprintf (&ret[idx],"%lu", get_signature_count (args->pksk));
1045
0
      idx+=strlen(&ret[idx]);
1046
0
      done=1;
1047
0
    }
1048
0
        break;
1049
1050
0
      case 'f': /* Fingerprint of key being signed */
1051
0
      case 'p': /* Fingerprint of the primary key making the signature. */
1052
0
      case 'g': /* Fingerprint of the key making the signature.  */
1053
0
        {
1054
0
    byte array[MAX_FINGERPRINT_LEN];
1055
0
    size_t len;
1056
0
    int i;
1057
1058
0
    if ((*(ch+1))=='f' && args->pk)
1059
0
      fingerprint_from_pk (args->pk, array, &len);
1060
0
    else if ((*(ch+1))=='p' && args->pksk)
1061
0
      {
1062
0
        if(args->pksk->flags.primary)
1063
0
          fingerprint_from_pk (args->pksk, array, &len);
1064
0
        else if (args->pksk->main_keyid[0]
1065
0
                             || args->pksk->main_keyid[1])
1066
0
          {
1067
                        /* Not the primary key: Find the fingerprint
1068
                           of the primary key.  */
1069
0
      PKT_public_key *pk=
1070
0
        xmalloc_clear(sizeof(PKT_public_key));
1071
1072
0
      if (!get_pubkey_fast (ctrl, pk,args->pksk->main_keyid))
1073
0
        fingerprint_from_pk (pk, array, &len);
1074
0
      else
1075
0
        memset (array, 0, (len=MAX_FINGERPRINT_LEN));
1076
0
      free_public_key (pk);
1077
0
          }
1078
0
        else /* Oops: info about the primary key missing.  */
1079
0
          memset(array,0,(len=MAX_FINGERPRINT_LEN));
1080
0
      }
1081
0
    else if((*(ch+1))=='g' && args->pksk)
1082
0
      fingerprint_from_pk (args->pksk, array, &len);
1083
0
    else
1084
0
      memset(array,0,(len=MAX_FINGERPRINT_LEN));
1085
1086
0
    if(idx+(len*2)<maxlen)
1087
0
      {
1088
0
        for(i=0;i<len;i++)
1089
0
          {
1090
0
      sprintf(&ret[idx],"%02X",array[i]);
1091
0
      idx+=2;
1092
0
          }
1093
0
        done=1;
1094
0
      }
1095
0
        }
1096
0
        break;
1097
1098
0
      case 'v': /* validity letters */
1099
0
        if(args->validity_info && idx+1<maxlen)
1100
0
    {
1101
0
      ret[idx++]=args->validity_info;
1102
0
      ret[idx]='\0';
1103
0
      done=1;
1104
0
    }
1105
0
        break;
1106
1107
        /* The text string types */
1108
0
      case 't':
1109
0
      case 'T':
1110
0
      case 'V':
1111
0
        {
1112
0
    const char *str=NULL;
1113
1114
0
    switch(*(ch+1))
1115
0
      {
1116
0
      case 't': /* e.g. "jpg" */
1117
0
        str=image_type_to_string(args->imagetype,0);
1118
0
        break;
1119
1120
0
      case 'T': /* e.g. "image/jpeg" */
1121
0
        str=image_type_to_string(args->imagetype,2);
1122
0
        break;
1123
1124
0
      case 'V': /* e.g. "full", "expired", etc. */
1125
0
        str=args->validity_string;
1126
0
        break;
1127
0
      }
1128
1129
0
    if(str && idx+strlen(str)<maxlen)
1130
0
      {
1131
0
        strcpy(&ret[idx],str);
1132
0
        idx+=strlen(str);
1133
0
        done=1;
1134
0
      }
1135
0
        }
1136
0
        break;
1137
1138
0
      case '%':
1139
0
        if(idx+1<maxlen)
1140
0
    {
1141
0
      ret[idx++]='%';
1142
0
      ret[idx]='\0';
1143
0
      done=1;
1144
0
    }
1145
0
        break;
1146
1147
        /* Any unknown %-keys (like %i, %o, %I, and %O) are
1148
     passed through for later expansion.  Note this also
1149
     handles the case where the last character in the
1150
     string is a '%' - the terminating \0 will end up here
1151
     and properly terminate the string. */
1152
0
      default:
1153
0
        if(idx+2<maxlen)
1154
0
    {
1155
0
      ret[idx++]='%';
1156
0
      ret[idx++]=*(ch+1);
1157
0
      ret[idx]='\0';
1158
0
      done=1;
1159
0
    }
1160
0
        break;
1161
0
        }
1162
1163
0
    if(done)
1164
0
      ch++;
1165
0
  }
1166
0
      else
1167
0
  {
1168
0
    if(idx+1<maxlen)
1169
0
      {
1170
0
        ret[idx++]=*ch;
1171
0
        ret[idx]='\0';
1172
0
        done=1;
1173
0
      }
1174
0
  }
1175
1176
0
      if(done)
1177
0
  ch++;
1178
0
    }
1179
1180
0
  return ret;
1181
1182
0
 fail:
1183
0
  xfree(ret);
1184
0
  return NULL;
1185
0
}
1186
1187
void
1188
deprecated_warning(const char *configname,unsigned int configlineno,
1189
       const char *option,const char *repl1,const char *repl2)
1190
0
{
1191
0
  if(configname)
1192
0
    {
1193
0
      if(strncmp("--",option,2)==0)
1194
0
  option+=2;
1195
1196
0
      if(strncmp("--",repl1,2)==0)
1197
0
  repl1+=2;
1198
1199
0
      log_info(_("%s:%d: deprecated option \"%s\"\n"),
1200
0
         configname,configlineno,option);
1201
0
    }
1202
0
  else
1203
0
    log_info(_("WARNING: \"%s\" is a deprecated option\n"),option);
1204
1205
0
  log_info(_("please use \"%s%s\" instead\n"),repl1,repl2);
1206
0
}
1207
1208
1209
void
1210
deprecated_command (const char *name)
1211
0
{
1212
0
  log_info(_("WARNING: \"%s\" is a deprecated command - do not use it\n"),
1213
0
           name);
1214
0
}
1215
1216
1217
void
1218
obsolete_scdaemon_option (const char *configname, unsigned int configlineno,
1219
                          const char *name)
1220
0
{
1221
0
  if (configname)
1222
0
    log_info (_("%s:%u: \"%s\" is obsolete in this file"
1223
0
                " - it only has effect in %s\n"),
1224
0
              configname, configlineno, name, SCDAEMON_NAME EXTSEP_S "conf");
1225
0
  else
1226
0
    log_info (_("WARNING: \"%s%s\" is an obsolete option"
1227
0
                " - it has no effect except on %s\n"),
1228
0
              "--", name, SCDAEMON_NAME);
1229
0
}
1230
1231
1232
/*
1233
 * Wrapper around gcry_cipher_map_name to provide a fallback using the
1234
 * "Sn" syntax as used by the preference strings.  Note that only the
1235
 * second syntax does a check on the actual availibily of the
1236
 * algorithm.  That might make a difference in case Libgcrypt is
1237
 * running in FIPS mode.
1238
 */
1239
int
1240
string_to_cipher_algo (const char *string)
1241
0
{
1242
0
  int val;
1243
1244
0
  val = map_cipher_gcry_to_openpgp (gcry_cipher_map_name (string));
1245
0
  if (!val && string && (string[0]=='S' || string[0]=='s'))
1246
0
    {
1247
0
      char *endptr;
1248
0
      long longval;
1249
1250
0
      string++;
1251
0
      longval = strtol (string, &endptr, 10);
1252
0
      if (*string && !*endptr && longval >= 0 && longval < 256
1253
0
          && openpgp_cipher_test_algo ((int)longval))
1254
0
        val = longval;
1255
0
    }
1256
1257
0
  return val;
1258
0
}
1259
1260
1261
/*
1262
 * Map an AEAD mode string to a an AEAD algorithm number as defined by
1263
 * rfc4880bis.  Also support the "An" syntax as used by the preference
1264
 * strings.
1265
 */
1266
aead_algo_t
1267
string_to_aead_algo (const char *string)
1268
0
{
1269
0
  int result;
1270
1271
0
  if (!string)
1272
0
    result = 0;
1273
0
  else if (!ascii_strcasecmp (string, "EAX"))
1274
0
    result = 1;
1275
0
  else if (!ascii_strcasecmp (string, "OCB"))
1276
0
    result = 2;
1277
0
  else
1278
0
    {
1279
0
      result = 0;
1280
0
      if ((string[0]=='A' || string[0]=='a'))
1281
0
        {
1282
0
          char *endptr;
1283
0
          long longval;
1284
1285
0
          string++;
1286
0
          longval = strtol (string, &endptr, 10);
1287
0
          if (*string && !*endptr && longval >= 1 && longval <= 2)
1288
0
            result = longval;
1289
0
        }
1290
0
    }
1291
1292
0
  return result;
1293
0
}
1294
1295
1296
/*
1297
 * Wrapper around gcry_md_map_name to provide a fallback using the
1298
 * "Hn" syntax as used by the preference strings.
1299
 */
1300
int
1301
string_to_digest_algo (const char *string)
1302
0
{
1303
0
  int val;
1304
1305
  /* FIXME: We should make use of our wrapper function and not assume
1306
     that there is a 1 to 1 mapping between OpenPGP and Libgcrypt.  */
1307
0
  val = gcry_md_map_name (string);
1308
0
  if (!val && string && (string[0]=='H' || string[0]=='h'))
1309
0
    {
1310
0
      char *endptr;
1311
0
      long longval;
1312
1313
0
      string++;
1314
0
      longval = strtol (string, &endptr, 10);
1315
0
      if (*string && !*endptr && longval >= 0 && longval < 256
1316
0
          && openpgp_md_test_algo ((int)longval))
1317
0
        val = longval;
1318
0
    }
1319
1320
0
  return val;
1321
0
}
1322
1323
1324
1325
const char *
1326
compress_algo_to_string(int algo)
1327
0
{
1328
0
  const char *s=NULL;
1329
1330
0
  switch(algo)
1331
0
    {
1332
0
    case COMPRESS_ALGO_NONE:
1333
0
      s=_("Uncompressed");
1334
0
      break;
1335
1336
0
    case COMPRESS_ALGO_ZIP:
1337
0
      s="ZIP";
1338
0
      break;
1339
1340
0
    case COMPRESS_ALGO_ZLIB:
1341
0
      s="ZLIB";
1342
0
      break;
1343
1344
#ifdef HAVE_BZIP2
1345
    case COMPRESS_ALGO_BZIP2:
1346
      s="BZIP2";
1347
      break;
1348
#endif
1349
0
    }
1350
1351
0
  return s;
1352
0
}
1353
1354
int
1355
string_to_compress_algo(const char *string)
1356
0
{
1357
  /* TRANSLATORS: See doc/TRANSLATE about this string. */
1358
0
  if(match_multistr(_("uncompressed|none"),string))
1359
0
    return 0;
1360
0
  else if(ascii_strcasecmp(string,"uncompressed")==0)
1361
0
    return 0;
1362
0
  else if(ascii_strcasecmp(string,"none")==0)
1363
0
    return 0;
1364
0
  else if(ascii_strcasecmp(string,"zip")==0)
1365
0
    return 1;
1366
0
  else if(ascii_strcasecmp(string,"zlib")==0)
1367
0
    return 2;
1368
#ifdef HAVE_BZIP2
1369
  else if(ascii_strcasecmp(string,"bzip2")==0)
1370
    return 3;
1371
#endif
1372
0
  else if(ascii_strcasecmp(string,"z0")==0)
1373
0
    return 0;
1374
0
  else if(ascii_strcasecmp(string,"z1")==0)
1375
0
    return 1;
1376
0
  else if(ascii_strcasecmp(string,"z2")==0)
1377
0
    return 2;
1378
#ifdef HAVE_BZIP2
1379
  else if(ascii_strcasecmp(string,"z3")==0)
1380
    return 3;
1381
#endif
1382
0
  else
1383
0
    return -1;
1384
0
}
1385
1386
int
1387
check_compress_algo(int algo)
1388
784
{
1389
784
  switch (algo)
1390
784
    {
1391
758
    case 0: return 0;
1392
#ifdef HAVE_ZIP
1393
    case 1:
1394
    case 2: return 0;
1395
#endif
1396
#ifdef HAVE_BZIP2
1397
    case 3: return 0;
1398
#endif
1399
26
    default: return GPG_ERR_COMPR_ALGO;
1400
784
    }
1401
784
}
1402
1403
int
1404
default_cipher_algo(void)
1405
0
{
1406
0
  if(opt.def_cipher_algo)
1407
0
    return opt.def_cipher_algo;
1408
0
  else if(opt.personal_cipher_prefs)
1409
0
    return opt.personal_cipher_prefs[0].value;
1410
0
  else
1411
0
    return opt.s2k_cipher_algo;
1412
0
}
1413
1414
1415
/* There is no default_digest_algo function, but see
1416
   sign.c:hash_for() */
1417
1418
int
1419
default_compress_algo(void)
1420
0
{
1421
0
  if(opt.compress_algo!=-1)
1422
0
    return opt.compress_algo;
1423
0
  else if(opt.personal_compress_prefs)
1424
0
    return opt.personal_compress_prefs[0].value;
1425
0
  else
1426
0
    return DEFAULT_COMPRESS_ALGO;
1427
0
}
1428
1429
1430
void
1431
compliance_failure(void)
1432
0
{
1433
0
  char *ver="???";
1434
1435
0
  switch(opt.compliance)
1436
0
    {
1437
0
    case CO_GNUPG:
1438
0
      ver="GnuPG";
1439
0
      break;
1440
1441
0
    case CO_RFC4880:
1442
0
      ver="OpenPGP";
1443
0
      break;
1444
1445
0
    case CO_RFC2440:
1446
0
      ver="OpenPGP (older)";
1447
0
      break;
1448
1449
0
    case CO_PGP7:
1450
0
      ver="PGP 7.x";
1451
0
      break;
1452
1453
0
    case CO_PGP8:
1454
0
      ver="PGP 8.x";
1455
0
      break;
1456
1457
0
    case CO_DE_VS:
1458
0
      ver="DE-VS applications";
1459
0
      break;
1460
0
    }
1461
1462
0
  log_info(_("this message may not be usable by %s\n"),ver);
1463
0
  opt.compliance=CO_GNUPG;
1464
0
}
1465
1466
/* Break a string into successive option pieces.  Accepts single word
1467
   options and key=value argument options. */
1468
char *
1469
optsep(char **stringp)
1470
0
{
1471
0
  char *tok,*end;
1472
1473
0
  tok=*stringp;
1474
0
  if(tok)
1475
0
    {
1476
0
      end=strpbrk(tok," ,=");
1477
0
      if(end)
1478
0
  {
1479
0
    int sawequals=0;
1480
0
    char *ptr=end;
1481
1482
    /* what we need to do now is scan along starting with *end,
1483
       If the next character we see (ignoring spaces) is an =
1484
       sign, then there is an argument. */
1485
1486
0
    while(*ptr)
1487
0
      {
1488
0
        if(*ptr=='=')
1489
0
    sawequals=1;
1490
0
        else if(*ptr!=' ')
1491
0
    break;
1492
0
        ptr++;
1493
0
      }
1494
1495
    /* There is an argument, so grab that too.  At this point,
1496
       ptr points to the first character of the argument. */
1497
0
    if(sawequals)
1498
0
      {
1499
        /* Is it a quoted argument? */
1500
0
        if(*ptr=='"')
1501
0
    {
1502
0
      ptr++;
1503
0
      end=strchr(ptr,'"');
1504
0
      if(end)
1505
0
        end++;
1506
0
    }
1507
0
        else
1508
0
    end=strpbrk(ptr," ,");
1509
0
      }
1510
1511
0
    if(end && *end)
1512
0
      {
1513
0
        *end='\0';
1514
0
        *stringp=end+1;
1515
0
      }
1516
0
    else
1517
0
      *stringp=NULL;
1518
0
  }
1519
0
      else
1520
0
  *stringp=NULL;
1521
0
    }
1522
1523
0
  return tok;
1524
0
}
1525
1526
/* Breaks an option value into key and value.  Returns NULL if there
1527
   is no value.  Note that "string" is modified to remove the =value
1528
   part. */
1529
char *
1530
argsplit(char *string)
1531
0
{
1532
0
  char *equals,*arg=NULL;
1533
1534
0
  equals=strchr(string,'=');
1535
0
  if(equals)
1536
0
    {
1537
0
      char *quote,*space;
1538
1539
0
      *equals='\0';
1540
0
      arg=equals+1;
1541
1542
      /* Quoted arg? */
1543
0
      quote=strchr(arg,'"');
1544
0
      if(quote)
1545
0
  {
1546
0
    arg=quote+1;
1547
1548
0
    quote=strchr(arg,'"');
1549
0
    if(quote)
1550
0
      *quote='\0';
1551
0
  }
1552
0
      else
1553
0
  {
1554
0
    size_t spaces;
1555
1556
    /* Trim leading spaces off of the arg */
1557
0
    spaces=strspn(arg," ");
1558
0
    arg+=spaces;
1559
0
  }
1560
1561
      /* Trim tailing spaces off of the tag */
1562
0
      space=strchr(string,' ');
1563
0
      if(space)
1564
0
  *space='\0';
1565
0
    }
1566
1567
0
  return arg;
1568
0
}
1569
1570
/* Return the length of the initial token, leaving off any
1571
   argument. */
1572
static size_t
1573
optlen(const char *s)
1574
0
{
1575
0
  char *end=strpbrk(s," =");
1576
1577
0
  if(end)
1578
0
    return end-s;
1579
0
  else
1580
0
    return strlen(s);
1581
0
}
1582
1583
1584
/* Note: This function returns true on success.  */
1585
int
1586
parse_options(char *str,unsigned int *options,
1587
        struct parse_options *opts,int noisy)
1588
0
{
1589
0
  char *tok;
1590
1591
0
  if (str && (!strcmp (str, "help")
1592
0
              || !strcmp (str, "full-help") || !strcmp (str, "fullhelp")))
1593
0
    {
1594
0
      int i,maxlen=0;
1595
0
      int full = *str == 'f';
1596
0
      int set;
1597
1598
      /* Figure out the longest option name so we can line these up
1599
   neatly. */
1600
0
      for(i=0;opts[i].name;i++)
1601
0
  if((full || opts[i].help) && maxlen<strlen(opts[i].name))
1602
0
    maxlen=strlen(opts[i].name);
1603
1604
0
      for(i=0;opts[i].name;i++)
1605
0
        if(opts[i].help)
1606
0
          {
1607
0
            set = (*options & opts[i].bit);
1608
0
            es_printf("%s%*s%s%s%s%s\n",opts[i].name,
1609
0
                      maxlen+2-(int)strlen(opts[i].name),"",_(opts[i].help),
1610
0
                      set?"  [":"", set? _("enabled"):"", set?"]":"");
1611
0
          }
1612
1613
0
      if (full)
1614
0
        for (i=0; opts[i].name; i++)
1615
0
          if(!opts[i].help)
1616
0
            {
1617
0
              set = (*options & opts[i].bit);
1618
0
              es_printf("%s%*s%s%s%s\n",opts[i].name,
1619
0
                        set? (maxlen+2-(int)strlen(opts[i].name)):0,"",
1620
0
                        set?"[":"", set? _("enabled"):"", set?"]":"");
1621
0
            }
1622
1623
0
      g10_exit(0);
1624
0
    }
1625
1626
0
  while((tok=optsep(&str)))
1627
0
    {
1628
0
      int i,rev=0;
1629
0
      char *otok=tok;
1630
1631
0
      if(tok[0]=='\0')
1632
0
  continue;
1633
1634
0
      if(ascii_strncasecmp("no-",tok,3)==0)
1635
0
  {
1636
0
    rev=1;
1637
0
    tok+=3;
1638
0
  }
1639
1640
0
      for(i=0;opts[i].name;i++)
1641
0
  {
1642
0
    size_t toklen=optlen(tok);
1643
1644
0
    if(ascii_strncasecmp(opts[i].name,tok,toklen)==0)
1645
0
      {
1646
        /* We have a match, but it might be incomplete */
1647
0
        if(toklen!=strlen(opts[i].name))
1648
0
    {
1649
0
      int j;
1650
1651
0
      for(j=i+1;opts[j].name;j++)
1652
0
        {
1653
0
          if(ascii_strncasecmp(opts[j].name,tok,toklen)==0)
1654
0
      {
1655
0
        if(noisy)
1656
0
          log_info(_("ambiguous option '%s'\n"),otok);
1657
0
        return 0;
1658
0
      }
1659
0
        }
1660
0
    }
1661
1662
0
        if(rev)
1663
0
    {
1664
0
      *options&=~opts[i].bit;
1665
0
      if(opts[i].value)
1666
0
        *opts[i].value=NULL;
1667
0
    }
1668
0
        else
1669
0
    {
1670
0
      *options|=opts[i].bit;
1671
0
      if(opts[i].value)
1672
0
        *opts[i].value=argsplit(tok);
1673
0
    }
1674
0
        break;
1675
0
      }
1676
0
  }
1677
1678
0
      if(!opts[i].name)
1679
0
  {
1680
0
    if(noisy)
1681
0
      log_info(_("unknown option '%s'\n"),otok);
1682
0
    return 0;
1683
0
  }
1684
0
    }
1685
1686
0
  return 1;
1687
0
}
1688
1689
1690
/* Similar to access(2), but uses PATH to find the file. */
1691
int
1692
path_access(const char *file,int mode)
1693
0
{
1694
0
  char *envpath;
1695
0
  int ret=-1;
1696
1697
0
  envpath=getenv("PATH");
1698
1699
0
  if(!envpath
1700
#ifdef HAVE_DRIVE_LETTERS
1701
     || (((file[0]>='A' && file[0]<='Z')
1702
    || (file[0]>='a' && file[0]<='z'))
1703
   && file[1]==':')
1704
#else
1705
0
     || file[0]=='/'
1706
0
#endif
1707
0
     )
1708
0
    return access(file,mode);
1709
0
  else
1710
0
    {
1711
      /* At least as large as, but most often larger than we need. */
1712
0
      char *buffer=xmalloc(strlen(envpath)+1+strlen(file)+1);
1713
0
      char *split,*item,*path=xstrdup(envpath);
1714
1715
0
      split=path;
1716
1717
0
      while((item=strsep(&split,PATHSEP_S)))
1718
0
  {
1719
0
    strcpy(buffer,item);
1720
0
    strcat(buffer,"/");
1721
0
    strcat(buffer,file);
1722
0
    ret=access(buffer,mode);
1723
0
    if(ret==0)
1724
0
      break;
1725
0
  }
1726
1727
0
      xfree(path);
1728
0
      xfree(buffer);
1729
0
    }
1730
1731
0
  return ret;
1732
0
}
1733
1734
1735

1736
/* Return the number of public key parameters as used by OpenPGP.  */
1737
int
1738
pubkey_get_npkey (pubkey_algo_t algo)
1739
13.8k
{
1740
13.8k
  switch (algo)
1741
13.8k
    {
1742
669
    case PUBKEY_ALGO_RSA:
1743
741
    case PUBKEY_ALGO_RSA_E:
1744
1.18k
    case PUBKEY_ALGO_RSA_S:     return 2;
1745
312
    case PUBKEY_ALGO_ELGAMAL_E: return 3;
1746
1.47k
    case PUBKEY_ALGO_DSA:       return 4;
1747
130
    case PUBKEY_ALGO_ECDH:      return 3;
1748
217
    case PUBKEY_ALGO_ECDSA:     return 2;
1749
74
    case PUBKEY_ALGO_ELGAMAL:   return 3;
1750
119
    case PUBKEY_ALGO_EDDSA:     return 2;
1751
4
    case PUBKEY_ALGO_KYBER:     return 3;
1752
10.3k
    default: return 0;
1753
13.8k
    }
1754
13.8k
}
1755
1756
1757
/* Return the number of secret key parameters as used by OpenPGP.  */
1758
int
1759
pubkey_get_nskey (pubkey_algo_t algo)
1760
2.84k
{
1761
2.84k
  switch (algo)
1762
2.84k
    {
1763
1.07k
    case PUBKEY_ALGO_RSA:
1764
1.17k
    case PUBKEY_ALGO_RSA_E:
1765
2.02k
    case PUBKEY_ALGO_RSA_S:     return 6;
1766
89
    case PUBKEY_ALGO_ELGAMAL_E: return 4;
1767
84
    case PUBKEY_ALGO_DSA:       return 5;
1768
99
    case PUBKEY_ALGO_ECDH:      return 4;
1769
108
    case PUBKEY_ALGO_ECDSA:     return 3;
1770
139
    case PUBKEY_ALGO_ELGAMAL:   return 4;
1771
93
    case PUBKEY_ALGO_EDDSA:     return 3;
1772
1
    case PUBKEY_ALGO_KYBER:     return 5;
1773
213
    default: return 0;
1774
2.84k
    }
1775
2.84k
}
1776
1777
/* Temporary helper. */
1778
int
1779
pubkey_get_nsig (pubkey_algo_t algo)
1780
12.1k
{
1781
12.1k
  switch (algo)
1782
12.1k
    {
1783
287
    case PUBKEY_ALGO_RSA:
1784
305
    case PUBKEY_ALGO_RSA_E:
1785
355
    case PUBKEY_ALGO_RSA_S:     return 1;
1786
31
    case PUBKEY_ALGO_ELGAMAL_E: return 0;
1787
1.08k
    case PUBKEY_ALGO_DSA:       return 2;
1788
30
    case PUBKEY_ALGO_ECDH:      return 0;
1789
142
    case PUBKEY_ALGO_ECDSA:     return 2;
1790
30
    case PUBKEY_ALGO_ELGAMAL:   return 2;
1791
85
    case PUBKEY_ALGO_EDDSA:     return 2;
1792
10.3k
    default: return 0;
1793
12.1k
    }
1794
12.1k
}
1795
1796
1797
/* Temporary helper. */
1798
int
1799
pubkey_get_nenc (pubkey_algo_t algo)
1800
3.90k
{
1801
3.90k
  switch (algo)
1802
3.90k
    {
1803
984
    case PUBKEY_ALGO_RSA:
1804
1.16k
    case PUBKEY_ALGO_RSA_E:
1805
1.66k
    case PUBKEY_ALGO_RSA_S:     return 1;
1806
86
    case PUBKEY_ALGO_ELGAMAL_E: return 2;
1807
684
    case PUBKEY_ALGO_DSA:       return 0;
1808
212
    case PUBKEY_ALGO_ECDH:      return 2;
1809
12
    case PUBKEY_ALGO_ECDSA:     return 0;
1810
8
    case PUBKEY_ALGO_ELGAMAL:   return 2;
1811
0
    case PUBKEY_ALGO_EDDSA:     return 0;
1812
22
    case PUBKEY_ALGO_KYBER:     return 3;
1813
1.21k
    default: return 0;
1814
3.90k
    }
1815
3.90k
}
1816
1817
1818
/* Temporary helper. */
1819
unsigned int
1820
pubkey_nbits( int algo, gcry_mpi_t *key )
1821
158
{
1822
158
  int rc, nbits;
1823
158
  gcry_sexp_t sexp;
1824
1825
158
  if (algo == PUBKEY_ALGO_DSA
1826
64
      && key[0] && key[1] && key[2] && key[3])
1827
64
    {
1828
64
      rc = gcry_sexp_build (&sexp, NULL,
1829
64
                            "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
1830
64
                            key[0], key[1], key[2], key[3] );
1831
64
    }
1832
94
  else if ((algo == PUBKEY_ALGO_ELGAMAL || algo == PUBKEY_ALGO_ELGAMAL_E)
1833
66
           && key[0] && key[1] && key[2])
1834
66
    {
1835
66
      rc = gcry_sexp_build (&sexp, NULL,
1836
66
                            "(public-key(elg(p%m)(g%m)(y%m)))",
1837
66
                            key[0], key[1], key[2] );
1838
66
    }
1839
28
  else if (is_RSA (algo)
1840
27
           && key[0] && key[1])
1841
27
    {
1842
27
      rc = gcry_sexp_build (&sexp, NULL,
1843
27
                            "(public-key(rsa(n%m)(e%m)))",
1844
27
                            key[0], key[1] );
1845
27
    }
1846
1
  else if ((algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH
1847
1
            || algo == PUBKEY_ALGO_EDDSA)
1848
0
           && key[0] && key[1])
1849
0
    {
1850
0
      char *curve = openpgp_oid_to_str (key[0]);
1851
0
      if (!curve)
1852
0
        rc = gpg_error_from_syserror ();
1853
0
      else
1854
0
        {
1855
0
          rc = gcry_sexp_build (&sexp, NULL,
1856
0
                                "(public-key(ecc(curve%s)(q%m)))",
1857
0
                                curve, key[1]);
1858
0
          xfree (curve);
1859
0
        }
1860
0
    }
1861
1
  else
1862
1
    return 0;
1863
1864
157
  if (rc)
1865
0
    BUG ();
1866
1867
157
  nbits = gcry_pk_get_nbits (sexp);
1868
157
  gcry_sexp_release (sexp);
1869
157
  return nbits;
1870
157
}
1871
1872
1873
1874
int
1875
mpi_print (estream_t fp, gcry_mpi_t a, int mode)
1876
0
{
1877
0
  int n = 0;
1878
0
  size_t nwritten;
1879
1880
0
  if (!a)
1881
0
    return es_fprintf (fp, "[MPI_NULL]");
1882
0
  if (!mode)
1883
0
    {
1884
0
      unsigned int n1;
1885
0
      n1 = gcry_mpi_get_nbits(a);
1886
0
      n += es_fprintf (fp, "[%u bits]", n1);
1887
0
    }
1888
0
  else if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
1889
0
    {
1890
0
      unsigned int nbits;
1891
0
      unsigned char *p = gcry_mpi_get_opaque (a, &nbits);
1892
0
      if (!p)
1893
0
        n += es_fprintf (fp, "[invalid opaque value]");
1894
0
      else
1895
0
        {
1896
0
          if (!es_write_hexstring (fp, p, (nbits + 7)/8, 0, &nwritten))
1897
0
            n += nwritten;
1898
0
        }
1899
0
    }
1900
0
  else
1901
0
    {
1902
0
      unsigned char *buffer;
1903
0
      size_t buflen;
1904
1905
0
      if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &buffer, &buflen, a))
1906
0
        BUG ();
1907
0
      if (!es_write_hexstring (fp, buffer, buflen, 0, &nwritten))
1908
0
        n += nwritten;
1909
0
      gcry_free (buffer);
1910
0
    }
1911
0
  return n;
1912
0
}
1913
1914
1915
/* pkey[1] or skey[1] is Q for ECDSA, which is an uncompressed point,
1916
   i.e.  04 <x> <y> */
1917
unsigned int
1918
ecdsa_qbits_from_Q (unsigned int qbits)
1919
11
{
1920
11
  if ((qbits%8) > 3)
1921
0
    {
1922
0
      log_error (_("ECDSA public key is expected to be in SEC encoding "
1923
0
                   "multiple of 8 bits\n"));
1924
0
      return 0;
1925
0
    }
1926
11
  qbits -= qbits%8;
1927
11
  qbits /= 2;
1928
11
  return qbits;
1929
11
}
1930
1931
1932
/* Ignore signatures and certifications made over certain digest
1933
 * algorithms by default, MD5 is considered weak.  This allows users
1934
 * to deprecate support for other algorithms as well.
1935
 */
1936
void
1937
additional_weak_digest (const char* digestname)
1938
0
{
1939
0
  struct weakhash *weak = NULL;
1940
0
  const enum gcry_md_algos algo = string_to_digest_algo(digestname);
1941
1942
0
  if (algo == GCRY_MD_NONE)
1943
0
    {
1944
0
      log_error (_("unknown weak digest '%s'\n"), digestname);
1945
0
      return;
1946
0
    }
1947
1948
  /* Check to ensure it's not already present.  */
1949
0
  for (weak = opt.weak_digests; weak; weak = weak->next)
1950
0
    if (algo == weak->algo)
1951
0
      return;
1952
1953
  /* Add it to the head of the list.  */
1954
0
  weak = xmalloc(sizeof(*weak));
1955
0
  weak->algo = algo;
1956
0
  weak->rejection_shown = 0;
1957
0
  weak->next = opt.weak_digests;
1958
0
  opt.weak_digests = weak;
1959
0
}
1960
1961
1962
/* Return true if ALGO is in the list of weak digests.  */
1963
int
1964
is_weak_digest (digest_algo_t algo)
1965
193
{
1966
193
  const enum gcry_md_algos galgo = map_md_openpgp_to_gcry (algo);
1967
193
  const struct weakhash *weak;
1968
1969
193
  for (weak = opt.weak_digests; weak; weak = weak->next)
1970
0
    if (weak->algo == galgo)
1971
0
      return 1;
1972
193
  return 0;
1973
193
}