Coverage Report

Created: 2026-01-10 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gnupg/g10/keyid.c
Line
Count
Source
1
/* keyid.c - key ID and fingerprint handling
2
 * Copyright (C) 1998, 1999, 2000, 2001, 2003,
3
 *               2004, 2006, 2010 Free Software Foundation, Inc.
4
 * Copyright (C) 2014 Werner Koch
5
 * Copyright (C) 2016, 2023 g10 Code GmbH
6
 *
7
 * This file is part of GnuPG.
8
 *
9
 * GnuPG is free software; you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License as published by
11
 * the Free Software Foundation; either version 3 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * GnuPG is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, see <https://www.gnu.org/licenses/>.
21
 * SPDX-License-Identifier: GPL-3.0-or-later
22
 */
23
24
#include <config.h>
25
#include <stdio.h>
26
#include <stdlib.h>
27
#include <string.h>
28
#include <errno.h>
29
#include <time.h>
30
31
#include "gpg.h"
32
#include "../common/util.h"
33
#include "main.h"
34
#include "packet.h"
35
#include "options.h"
36
#include "keydb.h"
37
#include "../common/i18n.h"
38
#include "rmd160.h"
39
#include "../common/host2net.h"
40
41
42
0
#define KEYID_STR_SIZE 19
43
44
#ifdef HAVE_UNSIGNED_TIME_T
45
# define IS_INVALID_TIME_T(a) ((a) == (time_t)(-1))
46
#else
47
  /* Error or 32 bit time_t and value after 2038-01-19.  */
48
0
# define IS_INVALID_TIME_T(a) ((a) < 0)
49
#endif
50
51
52
/* Return a letter describing the public key algorithms.  */
53
int
54
pubkey_letter( int algo )
55
0
{
56
0
  switch (algo)
57
0
    {
58
0
    case PUBKEY_ALGO_RSA: return 'R' ;
59
0
    case PUBKEY_ALGO_RSA_E: return 'r' ;
60
0
    case PUBKEY_ALGO_RSA_S: return 's' ;
61
0
    case PUBKEY_ALGO_ELGAMAL_E: return 'g' ;
62
0
    case PUBKEY_ALGO_ELGAMAL:   return 'G' ;
63
0
    case PUBKEY_ALGO_DSA: return 'D' ;
64
0
    case PUBKEY_ALGO_ECDH:  return 'e' ;  /* ECC DH (encrypt only) */
65
0
    case PUBKEY_ALGO_ECDSA: return 'E' ;  /* ECC DSA (sign only)   */
66
0
    case PUBKEY_ALGO_EDDSA: return 'E' ;  /* ECC EdDSA (sign only) */
67
0
    default: return '?';
68
0
    }
69
0
}
70
71
/* Return a string describing the public key algorithm and the
72
   keysize.  For elliptic curves the function prints the name of the
73
   curve because the keysize is a property of the curve.  The string
74
   is copied to the supplied buffer up a length of BUFSIZE-1.
75
   Examples for the output are:
76
77
   "rsa3072"     - RSA with 3072 bit
78
   "elg1024"     - Elgamal with 1024 bit
79
   "ed25519"     - EdDSA using the curve Ed25519.
80
   "cv25519"     - ECDH using the curve X25519.
81
   "ky768_cv448  - Kyber-768 with X448 as second algo.
82
   "ky1024_bp512 - Kyber-1024 with BrainpoolP256r1 as second algo.
83
   "E_1.2.3.4"   - ECC using the unsupported curve with OID "1.2.3.4".
84
   "unknown_N"   - Unknown OpenPGP algorithm N.
85
   "E_1.3.6.1.4.1.11591.2.12242973" ECC with a bogus OID.
86
87
   Note that with Kyber we use "bp" as abbreviation for BrainpoolP and
88
   ignore the final r1 part.
89
90
   If the option --legacy-list-mode is active, the output use the
91
   legacy format:
92
93
   "3072R" - RSA with 3072 bit
94
   "1024g" - Elgamal with 1024 bit
95
   "256E"  - ECDSA using a curve with 256 bit
96
97
   The macro PUBKEY_STRING_SIZE may be used to allocate a buffer with
98
   a suitable size.  Note that a more general version of this function
99
   exists as get_keyalgo_string.  However, that has no special
100
   treatment for the old and unsupported Elgamal which we here print as
101
   xxxNNNN.  */
102
char *
103
pubkey_string (PKT_public_key *pk, char *buffer, size_t bufsize)
104
0
{
105
0
  const char *prefix = NULL;
106
0
  int dual = 0;
107
0
  char *curve;
108
0
  const char *name;
109
110
0
  if (opt.legacy_list_mode)
111
0
    {
112
0
      snprintf (buffer, bufsize, "%4u%c",
113
0
                nbits_from_pk (pk), pubkey_letter (pk->pubkey_algo));
114
0
      return buffer;
115
0
    }
116
117
0
  switch (pk->pubkey_algo)
118
0
    {
119
0
    case PUBKEY_ALGO_RSA:
120
0
    case PUBKEY_ALGO_RSA_E:
121
0
    case PUBKEY_ALGO_RSA_S: prefix = "rsa"; break;
122
0
    case PUBKEY_ALGO_ELGAMAL_E: prefix = "elg"; break;
123
0
    case PUBKEY_ALGO_DSA: prefix = "dsa"; break;
124
0
    case PUBKEY_ALGO_ELGAMAL:   prefix = "xxx"; break;
125
0
    case PUBKEY_ALGO_ECDH:
126
0
    case PUBKEY_ALGO_ECDSA:
127
0
    case PUBKEY_ALGO_EDDSA:     prefix = "";    break;
128
0
    case PUBKEY_ALGO_KYBER:     prefix = "ky"; dual = 1;  break;
129
0
    case PUBKEY_ALGO_DIL3_25519:  prefix = "dil3";        break;
130
0
    case PUBKEY_ALGO_DIL5_448:    prefix = "dil5";        break;
131
0
    case PUBKEY_ALGO_SPHINX_SHA2: prefix = "sphinx_sha2"; break;
132
0
    }
133
134
135
0
  if (prefix && *prefix)
136
0
    {
137
0
      if (dual)
138
0
        {
139
0
          curve = openpgp_oid_to_str (pk->pkey[0]);
140
          /* Note that we prefer the abbreviated name of the curve. */
141
0
          name = openpgp_oid_to_curve (curve, 2);
142
0
          if (!name)
143
0
            name = "unknown";
144
145
0
          snprintf (buffer, bufsize, "%s%u_%s",
146
0
                    prefix, nbits_from_pk (pk), name);
147
0
          xfree (curve);
148
0
        }
149
0
      else
150
0
        snprintf (buffer, bufsize, "%s%u", prefix, nbits_from_pk (pk));
151
0
    }
152
0
  else if (prefix)
153
0
    {
154
0
      curve = openpgp_oid_to_str (pk->pkey[0]);
155
0
      name = openpgp_oid_to_curve (curve, 0);
156
157
0
      if (name)
158
0
        snprintf (buffer, bufsize, "%s", name);
159
0
      else if (curve)
160
0
        snprintf (buffer, bufsize, "E_%s", curve);
161
0
      else
162
0
        snprintf (buffer, bufsize, "E_error");
163
0
      xfree (curve);
164
0
    }
165
0
  else
166
0
    snprintf (buffer, bufsize, "unknown_%u", (unsigned int)pk->pubkey_algo);
167
168
0
  return buffer;
169
0
}
170
171
172
/* Helper for compare_pubkey_string.  This skips leading spaces,
173
 * commas and optional condition operators and returns a pointer to
174
 * the first non-space character or NULL in case of an error.  The
175
 * length of a prefix consisting of letters is then returned ar PFXLEN
176
 * and the value of the number (e.g. 384 for "brainpoolP384r1") at
177
 * NUMBER.  R_LENGTH receives the entire length of the algorithm name
178
 * which is terminated by a space, nul, or a comma.  If R_CONDITION is
179
 * not NULL, 0 is stored for a leading "=", 1 for a ">", 2 for a ">=",
180
 * -1 for a "<", and -2 for a "<=".  If R_CONDITION is NULL no
181
 * condition prefix is allowed.  */
182
static const char *
183
parse_one_algo_string (const char *str, size_t *pfxlen, unsigned int *number,
184
                       size_t *r_length, int *r_condition)
185
0
{
186
0
  int condition = 0;
187
0
  const char *result;
188
189
0
  while (spacep (str) || *str ==',')
190
0
    str++;
191
0
  if (!r_condition)
192
0
    ;
193
0
  else if (*str == '>' && str[1] == '=')
194
0
    condition = 2, str += 2;
195
0
  else if (*str == '>' )
196
0
    condition = 1, str += 1;
197
0
  else if (*str == '<' && str[1] == '=')
198
0
    condition = -2, str += 2;
199
0
  else if (*str == '<')
200
0
    condition = -1, str += 1;
201
0
  else if (*str == '=')  /* Default.  */
202
0
    str += 1;
203
204
0
  if (!alphap (str))
205
0
    return NULL;  /* Error.  */
206
207
0
  *pfxlen = 1;
208
0
  for (result = str++; alphap (str); str++)
209
0
    ++*pfxlen;
210
0
  while (*str == '-' || *str == '+')
211
0
    str++;
212
0
  *number = atoi (str);
213
0
  while (*str && !spacep (str) && *str != ',')
214
0
    str++;
215
216
0
  *r_length = str - result;
217
0
  if (r_condition)
218
0
    *r_condition = condition;
219
0
  return result;
220
0
}
221
222
223
/* Return an extra algo strength offset to handle peculiarities like
224
 * ed448 > ed25519.  */
225
static size_t
226
extra_algo_strength_offset (const char *string)
227
0
{
228
0
  if (!string || !*string)
229
0
    return 0;
230
0
  if (!ascii_strcasecmp (string, "ed448"))
231
0
    return 50000; /* (ed)50448 is larger (ed)25519.  */
232
0
  if (!ascii_strcasecmp (string, "cv448"))
233
0
    return 50000; /* (cv)50448 is larger (cv)25519.  */
234
0
  return 0;
235
0
}
236
237
238
239
/* Helper for compare_pubkey_string.  If BPARSED is set to 0 on
240
 * return, an error in ASTR or BSTR was found and further checks are
241
 * not possible.  */
242
static int
243
compare_pubkey_string_part (const char *astr, const char *bstr_arg,
244
                            size_t *bparsed)
245
0
{
246
0
  const char *bstr = bstr_arg;
247
0
  size_t alen, apfxlen, blen, bpfxlen;
248
0
  unsigned int anumber, bnumber;
249
0
  int condition;
250
251
0
  *bparsed = 0;
252
0
  astr = parse_one_algo_string (astr, &apfxlen, &anumber, &alen, &condition);
253
0
  if (!astr)
254
0
    return 0;  /* Invalid algorithm name.  */
255
0
  anumber += extra_algo_strength_offset (astr);
256
0
  bstr = parse_one_algo_string (bstr, &bpfxlen, &bnumber, &blen, &condition);
257
0
  if (!bstr)
258
0
    return 0;  /* Invalid algorithm name.  */
259
0
  bnumber += extra_algo_strength_offset (bstr);
260
0
  *bparsed = blen + (bstr - bstr_arg);
261
0
  if (apfxlen != bpfxlen || ascii_strncasecmp (astr, bstr, apfxlen))
262
0
    return 0;  /* false.  */
263
0
  switch (condition)
264
0
    {
265
0
    case 2: return anumber >= bnumber;
266
0
    case 1: return anumber > bnumber;
267
0
    case -1: return anumber < bnumber;
268
0
    case -2: return anumber <= bnumber;
269
0
    }
270
271
0
  return alen == blen && !ascii_strncasecmp (astr, bstr, alen);
272
0
}
273
274
275
/* Check whether ASTR matches the constraints given by BSTR.  ASTR may
276
 * be any algo string like "rsa2048", "ed25519" and BSTR may be a
277
 * constraint which is in the simplest case just another algo string.
278
 * BSTR may have more that one string in which case they are comma
279
 * separated and any match will return true.  It is possible to prefix
280
 * BSTR with ">", ">=", "<=", or "<".  That prefix operator is applied
281
 * to the number part of the algorithm, i.e. the first sequence of
282
 * digits found before end-of-string or a comma.  Examples:
283
 *
284
 * | ASTR     | BSTR                 | result |
285
 * |----------+----------------------+--------|
286
 * | rsa2048  | rsa2048              | true   |
287
 * | rsa2048  | >=rsa2048            | true   |
288
 * | rsa2048  | >rsa2048             | false  |
289
 * | ed25519  | >rsa1024             | false  |
290
 * | ed25519  | ed25519              | true   |
291
 * | nistp384 | >nistp256            | true   |
292
 * | nistp521 | >=rsa3072, >nistp384 | true   |
293
 */
294
int
295
compare_pubkey_string (const char *astr, const char *bstr)
296
0
{
297
0
  size_t bparsed;
298
0
  int result;
299
300
0
  while (*bstr)
301
0
    {
302
0
      result = compare_pubkey_string_part (astr, bstr, &bparsed);
303
0
      if (result)
304
0
        return 1;
305
0
      if (!bparsed)
306
0
        return 0; /* Syntax error in ASTR or BSTR.  */
307
0
      bstr += bparsed;
308
0
    }
309
310
0
  return 0;
311
0
}
312
313
314
315
/* Hash a public key and allow to specify the to be used format.
316
 * Note that if the v5 format is requested for a v4 key, a 0x04 as
317
 * version is hashed instead of the 0x05. */
318
static void
319
do_hash_public_key (gcry_md_hd_t md, PKT_public_key *pk, int use_v5)
320
0
{
321
0
  unsigned int n;
322
0
  unsigned int nn[PUBKEY_MAX_NPKEY];
323
0
  byte *pp[PUBKEY_MAX_NPKEY];
324
0
  int i;
325
0
  unsigned int nbits;
326
0
  size_t nbytes;
327
0
  int npkey = pubkey_get_npkey (pk->pubkey_algo);
328
329
0
  n = use_v5? 10 : 6;
330
  /* FIXME: We can avoid the extra malloc by calling only the first
331
     mpi_print here which computes the required length and calling the
332
     real mpi_print only at the end.  The speed advantage would only be
333
     for ECC (opaque MPIs) or if we could implement an mpi_print
334
     variant with a callback handler to do the hashing.  */
335
0
  if (npkey==0 && pk->pkey[0]
336
0
      && gcry_mpi_get_flag (pk->pkey[0], GCRYMPI_FLAG_OPAQUE))
337
0
    {
338
0
      pp[0] = gcry_mpi_get_opaque (pk->pkey[0], &nbits);
339
0
      nn[0] = (nbits+7)/8;
340
0
      n+=nn[0];
341
0
    }
342
0
  else
343
0
    {
344
0
      for (i=0; i < npkey; i++ )
345
0
        {
346
0
          if (!pk->pkey[i])
347
0
            {
348
              /* This case may only happen if the parsing of the MPI
349
                 failed but the key was anyway created.  May happen
350
                 during "gpg KEYFILE".  */
351
0
              pp[i] = NULL;
352
0
              nn[i] = 0;
353
0
            }
354
0
          else if (pk->pubkey_algo == PUBKEY_ALGO_KYBER && i == 2)
355
0
            {
356
              /* Ugly: We need to re-construct the wire format of the
357
               * key parameter.  It would be easier to use a second
358
               * index for pp and nn which we could bump independent of
359
               * i.  */
360
0
              const char *p;
361
362
0
              p = gcry_mpi_get_opaque (pk->pkey[i], &nbits);
363
0
              nn[i] = (nbits+7)/8;
364
0
              pp[i] = xmalloc (4 + nn[i] + 1);
365
0
              if (p)
366
0
                {
367
0
                  pp[i][0] = nn[i] >> 24;
368
0
                  pp[i][1] = nn[i] >> 16;
369
0
                  pp[i][2] = nn[i] >> 8;
370
0
                  pp[i][3] = nn[i];
371
0
                  memcpy (pp[i] + 4 , p, nn[i]);
372
0
                  nn[i] += 4;
373
0
                }
374
0
              else
375
0
                pp[i] = NULL;
376
0
              n += nn[i];
377
0
            }
378
0
          else if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE))
379
0
            {
380
0
              const char *p;
381
0
              int is_sos = 0;
382
383
0
              if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_USER2))
384
0
                is_sos = 2;
385
386
0
              p = gcry_mpi_get_opaque (pk->pkey[i], &nbits);
387
0
              pp[i] = xmalloc ((nbits+7)/8 + is_sos);
388
0
              if (p)
389
0
                memcpy (pp[i] + is_sos, p, (nbits+7)/8);
390
0
              else
391
0
                pp[i] = NULL;
392
0
              if (is_sos)
393
0
                {
394
0
                  if (*p)
395
0
                    {
396
0
                      nbits = ((nbits + 7) / 8) * 8;
397
398
0
                      if (nbits >= 8 && !(*p & 0x80))
399
0
                        if (--nbits >= 7 && !(*p & 0x40))
400
0
                          if (--nbits >= 6 && !(*p & 0x20))
401
0
                            if (--nbits >= 5 && !(*p & 0x10))
402
0
                              if (--nbits >= 4 && !(*p & 0x08))
403
0
                                if (--nbits >= 3 && !(*p & 0x04))
404
0
                                  if (--nbits >= 2 && !(*p & 0x02))
405
0
                                    if (--nbits >= 1 && !(*p & 0x01))
406
0
                                      --nbits;
407
0
                    }
408
409
0
                  pp[i][0] = (nbits >> 8);
410
0
                  pp[i][1] = nbits;
411
0
                }
412
0
              nn[i] = (nbits+7)/8 + is_sos;
413
0
              n += nn[i];
414
0
            }
415
0
          else
416
0
            {
417
0
              if (gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0,
418
0
                                  &nbytes, pk->pkey[i]))
419
0
                BUG ();
420
0
              pp[i] = xmalloc (nbytes);
421
0
              if (gcry_mpi_print (GCRYMPI_FMT_PGP, pp[i], nbytes,
422
0
                                  &nbytes, pk->pkey[i]))
423
0
                BUG ();
424
0
              nn[i] = nbytes;
425
0
              n += nn[i];
426
0
            }
427
0
        }
428
0
    }
429
430
0
  if (use_v5)
431
0
    {
432
0
      gcry_md_putc ( md, 0x9a );     /* ctb */
433
0
      gcry_md_putc ( md, n >> 24 );  /* 4 byte length header (upper bits) */
434
0
      gcry_md_putc ( md, n >> 16 );
435
0
    }
436
0
  else
437
0
    {
438
0
      gcry_md_putc ( md, 0x99 );     /* ctb */
439
0
    }
440
0
  gcry_md_putc ( md, n >> 8 );       /* lower bits of the length header.  */
441
0
  gcry_md_putc ( md, n );
442
0
  gcry_md_putc ( md, pk->version );
443
0
  gcry_md_putc ( md, pk->timestamp >> 24 );
444
0
  gcry_md_putc ( md, pk->timestamp >> 16 );
445
0
  gcry_md_putc ( md, pk->timestamp >>  8 );
446
0
  gcry_md_putc ( md, pk->timestamp       );
447
448
0
  gcry_md_putc ( md, pk->pubkey_algo );
449
450
0
  if (use_v5) /* Hash the 32 bit length */
451
0
    {
452
0
      n -= 10;
453
0
      gcry_md_putc ( md, n >> 24 );
454
0
      gcry_md_putc ( md, n >> 16 );
455
0
      gcry_md_putc ( md, n >>  8 );
456
0
      gcry_md_putc ( md, n       );
457
0
    }
458
459
0
  if(npkey==0 && pk->pkey[0]
460
0
     && gcry_mpi_get_flag (pk->pkey[0], GCRYMPI_FLAG_OPAQUE))
461
0
    {
462
0
      if (pp[0])
463
0
        gcry_md_write (md, pp[0], nn[0]);
464
0
    }
465
0
  else
466
0
    {
467
0
      for(i=0; i < npkey; i++ )
468
0
        {
469
0
          if (pp[i])
470
0
            gcry_md_write ( md, pp[i], nn[i] );
471
0
          xfree(pp[i]);
472
0
        }
473
0
    }
474
0
}
475
476
477
/* Hash a public key.  This function is useful for v4 and v5
478
 * fingerprints and for v3 or v4 key signing. */
479
void
480
hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
481
0
{
482
0
  do_hash_public_key (md, pk, (pk->version == 5));
483
0
}
484
485
486
/* fixme: Check whether we can replace this function or if not
487
   describe why we need it.  */
488
u32
489
v3_keyid (gcry_mpi_t a, u32 *ki)
490
0
{
491
0
  byte *buffer, *p;
492
0
  size_t nbytes;
493
494
0
  if (gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &nbytes, a ))
495
0
    BUG ();
496
  /* fixme: allocate it on the stack */
497
0
  buffer = xmalloc (nbytes);
498
0
  if (gcry_mpi_print( GCRYMPI_FMT_USG, buffer, nbytes, NULL, a ))
499
0
    BUG ();
500
0
  if (nbytes < 8) /* oops */
501
0
    ki[0] = ki[1] = 0;
502
0
  else
503
0
    {
504
0
      p = buffer + nbytes - 8;
505
0
      ki[0] = buf32_to_u32 (p);
506
0
      p += 4;
507
0
      ki[1] = buf32_to_u32 (p);
508
0
    }
509
0
  xfree (buffer);
510
0
  return ki[1];
511
0
}
512
513
514
/* Return PK's keyid.  The memory is owned by PK.  */
515
u32 *
516
pk_keyid (PKT_public_key *pk)
517
0
{
518
0
  keyid_from_pk (pk, NULL);
519
520
  /* Uncomment this for help tracking down bugs related to keyid or
521
     main_keyid not being set correctly.  */
522
#if 0
523
  if (! (pk->main_keyid[0] || pk->main_keyid[1]))
524
    log_bug ("pk->main_keyid not set!\n");
525
  if (keyid_cmp (pk->keyid, pk->main_keyid) == 0
526
      && ! pk->flags.primary)
527
    log_bug ("keyid and main_keyid are the same, but primary flag not set!\n");
528
  if (keyid_cmp (pk->keyid, pk->main_keyid) != 0
529
      && pk->flags.primary)
530
    log_bug ("keyid and main_keyid are different, but primary flag set!\n");
531
#endif
532
533
0
  return pk->keyid;
534
0
}
535
536
/* Return the keyid of the primary key associated with PK.  The memory
537
   is owned by PK.  */
538
u32 *
539
pk_main_keyid (PKT_public_key *pk)
540
0
{
541
  /* Uncomment this for help tracking down bugs related to keyid or
542
     main_keyid not being set correctly.  */
543
#if 0
544
  if (! (pk->main_keyid[0] || pk->main_keyid[1]))
545
    log_bug ("pk->main_keyid not set!\n");
546
#endif
547
548
0
  return pk->main_keyid;
549
0
}
550
551
/* Copy the keyid in SRC to DEST and return DEST.  */
552
u32 *
553
keyid_copy (u32 *dest, const u32 *src)
554
0
{
555
0
  dest[0] = src[0];
556
0
  dest[1] = src[1];
557
0
  return dest;
558
0
}
559
560
char *
561
format_keyid (u32 *keyid, int format, char *buffer, int len)
562
67.8k
{
563
67.8k
  if (! buffer)
564
0
    {
565
0
      len = KEYID_STR_SIZE;
566
0
      buffer = xtrymalloc (len);
567
0
      if (!buffer)
568
0
        return NULL;
569
0
    }
570
571
67.8k
  if (format == KF_DEFAULT)
572
0
    format = opt.keyid_format;
573
67.8k
  if (format == KF_DEFAULT)
574
0
    format = KF_NONE;
575
576
67.8k
  switch (format)
577
67.8k
    {
578
0
    case KF_NONE:
579
0
      if (len)
580
0
        *buffer = 0;
581
0
      break;
582
583
0
    case KF_SHORT:
584
0
      snprintf (buffer, len, "%08lX", (ulong)keyid[1]);
585
0
      break;
586
587
67.8k
    case KF_LONG:
588
67.8k
      snprintf (buffer, len, "%08lX%08lX", (ulong)keyid[0], (ulong)keyid[1]);
589
67.8k
      break;
590
591
0
    case KF_0xSHORT:
592
0
      snprintf (buffer, len, "0x%08lX", (ulong)keyid[1]);
593
0
      break;
594
595
0
    case KF_0xLONG:
596
0
      snprintf (buffer, len, "0x%08lX%08lX", (ulong)keyid[0],(ulong)keyid[1]);
597
0
      break;
598
599
0
    default:
600
0
      BUG();
601
67.8k
    }
602
603
67.8k
  return buffer;
604
67.8k
}
605
606
size_t
607
keystrlen(void)
608
67.8k
{
609
67.8k
  int format = opt.keyid_format;
610
67.8k
  if (format == KF_DEFAULT)
611
67.8k
    format = KF_NONE;
612
613
67.8k
  switch(format)
614
67.8k
    {
615
67.8k
    case KF_NONE:
616
67.8k
      return 0;
617
618
0
    case KF_SHORT:
619
0
      return 8;
620
621
0
    case KF_LONG:
622
0
      return 16;
623
624
0
    case KF_0xSHORT:
625
0
      return 10;
626
627
0
    case KF_0xLONG:
628
0
      return 18;
629
630
0
    default:
631
0
      BUG();
632
67.8k
    }
633
67.8k
}
634
635
636
const char *
637
keystr (u32 *keyid)
638
67.8k
{
639
67.8k
  static char keyid_str[KEYID_STR_SIZE];
640
67.8k
  int format = opt.keyid_format;
641
642
67.8k
  if (format == KF_DEFAULT)
643
67.8k
    format = KF_NONE;
644
67.8k
  if (format == KF_NONE)
645
67.8k
    format = KF_LONG;
646
647
67.8k
  return format_keyid (keyid, format, keyid_str, sizeof (keyid_str));
648
67.8k
}
649
650
/* This function returns the key id of the main and possible the
651
 * subkey as one string.  It is used by error messages.  */
652
const char *
653
keystr_with_sub (u32 *main_kid, u32 *sub_kid)
654
0
{
655
0
  static char buffer[KEYID_STR_SIZE+1+KEYID_STR_SIZE];
656
0
  char *p;
657
0
  int format = opt.keyid_format;
658
659
0
  if (format == KF_NONE)
660
0
    format = KF_LONG;
661
662
0
  format_keyid (main_kid, format, buffer, KEYID_STR_SIZE);
663
0
  if (sub_kid)
664
0
    {
665
0
      p = buffer + strlen (buffer);
666
0
      *p++ = '/';
667
0
      format_keyid (sub_kid, format, p, KEYID_STR_SIZE);
668
0
    }
669
0
  return buffer;
670
0
}
671
672
673
const char *
674
keystr_from_pk(PKT_public_key *pk)
675
0
{
676
0
  keyid_from_pk(pk,NULL);
677
678
0
  return keystr(pk->keyid);
679
0
}
680
681
682
const char *
683
keystr_from_pk_with_sub (PKT_public_key *main_pk, PKT_public_key *sub_pk)
684
0
{
685
0
  keyid_from_pk (main_pk, NULL);
686
0
  if (sub_pk)
687
0
    keyid_from_pk (sub_pk, NULL);
688
689
0
  return keystr_with_sub (main_pk->keyid, sub_pk? sub_pk->keyid:NULL);
690
0
}
691
692
693
/* Return PK's key id as a string using the default format.  PK owns
694
   the storage.  */
695
const char *
696
pk_keyid_str (PKT_public_key *pk)
697
0
{
698
0
  return keystr (pk_keyid (pk));
699
0
}
700
701
702
const char *
703
keystr_from_desc(KEYDB_SEARCH_DESC *desc)
704
0
{
705
0
  switch(desc->mode)
706
0
    {
707
0
    case KEYDB_SEARCH_MODE_LONG_KID:
708
0
    case KEYDB_SEARCH_MODE_SHORT_KID:
709
0
      return keystr(desc->u.kid);
710
711
0
    case KEYDB_SEARCH_MODE_FPR:
712
0
      {
713
0
  u32 keyid[2];
714
715
0
        if (desc->fprlen == 32)
716
0
          {
717
0
            keyid[0] = buf32_to_u32 (desc->u.fpr);
718
0
            keyid[1] = buf32_to_u32 (desc->u.fpr+4);
719
0
          }
720
0
        else if (desc->fprlen == 20)
721
0
          {
722
0
            keyid[0] = buf32_to_u32 (desc->u.fpr+12);
723
0
            keyid[1] = buf32_to_u32 (desc->u.fpr+16);
724
0
          }
725
0
        else if (desc->fprlen == 16)
726
0
          return "?v3 fpr?";
727
0
        else /* oops */
728
0
          return "?vx fpr?";
729
0
  return keystr(keyid);
730
0
      }
731
732
0
    default:
733
0
      BUG();
734
0
    }
735
0
}
736
737
738
/* Compute the fingerprint and keyid and store it in PK.  */
739
static void
740
compute_fingerprint (PKT_public_key *pk)
741
0
{
742
0
  const byte *dp;
743
0
  gcry_md_hd_t md;
744
0
  size_t len;
745
746
0
  if (gcry_md_open (&md, pk->version == 5 ? GCRY_MD_SHA256 : GCRY_MD_SHA1, 0))
747
0
    BUG ();
748
0
  hash_public_key (md, pk);
749
0
  gcry_md_final (md);
750
0
  dp = gcry_md_read (md, 0);
751
0
  len = gcry_md_get_algo_dlen (gcry_md_get_algo (md));
752
0
  log_assert (len <= MAX_FINGERPRINT_LEN);
753
0
  memcpy (pk->fpr, dp, len);
754
0
  pk->fprlen = len;
755
0
  if (pk->version == 5)
756
0
    {
757
0
      pk->keyid[0] = buf32_to_u32 (dp);
758
0
      pk->keyid[1] = buf32_to_u32 (dp+4);
759
0
    }
760
0
  else
761
0
    {
762
0
      pk->keyid[0] = buf32_to_u32 (dp+12);
763
0
      pk->keyid[1] = buf32_to_u32 (dp+16);
764
0
    }
765
0
  gcry_md_close( md);
766
0
}
767
768
769
/*
770
 * Get the keyid from the public key PK and store it at KEYID unless
771
 * this is NULL.  Returns the 32 bit short keyid.
772
 */
773
u32
774
keyid_from_pk (PKT_public_key *pk, u32 *keyid)
775
0
{
776
0
  u32 dummy_keyid[2];
777
778
0
  if (!keyid)
779
0
    keyid = dummy_keyid;
780
781
0
  if (!pk->fprlen)
782
0
    compute_fingerprint (pk);
783
784
0
  keyid[0] = pk->keyid[0];
785
0
  keyid[1] = pk->keyid[1];
786
787
0
  if (pk->fprlen == 32)
788
0
    return keyid[0];
789
0
  else
790
0
    return keyid[1];
791
0
}
792
793
794
/*
795
 * Get the keyid from the fingerprint.  This function is simple for
796
 * most keys, but has to do a key lookup for old v3 keys where the
797
 * keyid is not part of the fingerprint.
798
 */
799
u32
800
keyid_from_fingerprint (ctrl_t ctrl, const byte *fpr, size_t fprlen, u32 *keyid)
801
0
{
802
0
  u32 dummy_keyid[2];
803
804
0
  if( !keyid )
805
0
    keyid = dummy_keyid;
806
807
0
  if (fprlen != 20 && fprlen != 32)
808
0
    {
809
      /* This is special as we have to lookup the key first.  */
810
0
      PKT_public_key pk;
811
0
      int rc;
812
813
0
      memset (&pk, 0, sizeof pk);
814
0
      rc = get_pubkey_byfpr (ctrl, &pk, NULL, fpr, fprlen);
815
0
      if( rc )
816
0
        {
817
0
          log_printhex (fpr, fprlen,
818
0
                        "Oops: keyid_from_fingerprint: no pubkey; fpr:");
819
0
          keyid[0] = 0;
820
0
          keyid[1] = 0;
821
0
        }
822
0
      else
823
0
        keyid_from_pk (&pk, keyid);
824
0
    }
825
0
  else
826
0
    {
827
0
      const byte *dp = fpr;
828
0
      if (fprlen == 20)  /* v4 key */
829
0
        {
830
0
          keyid[0] = buf32_to_u32 (dp+12);
831
0
          keyid[1] = buf32_to_u32 (dp+16);
832
0
        }
833
0
      else  /* v5 key */
834
0
        {
835
0
          keyid[0] = buf32_to_u32 (dp);
836
0
          keyid[1] = buf32_to_u32 (dp+4);
837
0
        }
838
0
    }
839
840
0
  return keyid[1];
841
0
}
842
843
844
u32
845
keyid_from_sig (PKT_signature *sig, u32 *keyid)
846
0
{
847
0
  if( keyid )
848
0
    {
849
0
      keyid[0] = sig->keyid[0];
850
0
      keyid[1] = sig->keyid[1];
851
0
    }
852
0
  return sig->keyid[1];  /*FIXME:shortkeyid*/
853
0
}
854
855
856
byte *
857
namehash_from_uid (PKT_user_id *uid)
858
0
{
859
0
  if (!uid->namehash)
860
0
    {
861
0
      uid->namehash = xmalloc (20);
862
863
0
      if (uid->attrib_data)
864
0
  rmd160_hash_buffer (uid->namehash, uid->attrib_data, uid->attrib_len);
865
0
      else
866
0
  rmd160_hash_buffer (uid->namehash, uid->name, uid->len);
867
0
    }
868
869
0
  return uid->namehash;
870
0
}
871
872
873
/*
874
 * Return the number of bits used in PK.  For Kyber we return the
875
 * octet count of the Kyber part and not of the ECC (thus likely
876
 * values are 768 or 1024).  Note that this function may be called
877
 * with only pubkey_algo and pkey[] correctly set.
878
 */
879
unsigned int
880
nbits_from_pk (PKT_public_key *pk)
881
0
{
882
0
  if (pk->pubkey_algo == PUBKEY_ALGO_KYBER)
883
0
    {
884
0
      unsigned int nbits;
885
0
      if (!gcry_mpi_get_opaque (pk->pkey[2], &nbits))
886
0
        return 0;
887
0
      switch (nbits/8)
888
0
        {
889
0
        case 800:  nbits =  512; break;
890
0
        case 1184: nbits =  768; break;
891
0
        case 1568: nbits = 1024; break;
892
0
        default:   nbits = 0;    break;  /* Unknown version.  */
893
0
        }
894
0
      return nbits;
895
0
    }
896
0
  else
897
0
    return pubkey_nbits (pk->pubkey_algo, pk->pkey);
898
0
}
899
900
901
/* Convert an UTC TIMESTAMP into an UTC yyyy-mm-dd string.  Return
902
 * that string.  The caller should pass a buffer with at least a size
903
 * of MK_DATESTR_SIZE.  */
904
char *
905
mk_datestr (char *buffer, size_t bufsize, u32 timestamp)
906
0
{
907
0
  time_t atime = timestamp;
908
0
  struct tm *tp;
909
910
0
  if (IS_INVALID_TIME_T (atime))
911
0
    strcpy (buffer, "????" "-??" "-??"); /* Mark this as invalid. */
912
0
  else
913
0
    {
914
0
      tp = gmtime (&atime);
915
0
      snprintf (buffer, bufsize, "%04d-%02d-%02d",
916
0
                1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
917
0
    }
918
0
  return buffer;
919
0
}
920
921
922
/*
923
 * return a string with the creation date of the pk
924
 * Note: this is alloced in a static buffer.
925
 *    Format is: yyyy-mm-dd
926
 */
927
const char *
928
dateonlystr_from_pk (PKT_public_key *pk)
929
0
{
930
0
  static char buffer[MK_DATESTR_SIZE];
931
932
0
  return mk_datestr (buffer, sizeof buffer, pk->timestamp);
933
0
}
934
935
936
/* Same as dateonlystr_from_pk but with a global option a full iso
937
 * timestamp is returned.  In this case it shares a static buffer with
938
 * isotimestamp(). */
939
const char *
940
datestr_from_pk (PKT_public_key *pk)
941
0
{
942
0
  if (opt.flags.full_timestrings)
943
0
    return isotimestamp (pk->timestamp);
944
0
  else
945
0
    return dateonlystr_from_pk (pk);
946
0
}
947
948
949
const char *
950
dateonlystr_from_sig (PKT_signature *sig )
951
0
{
952
0
  static char buffer[MK_DATESTR_SIZE];
953
954
0
  return mk_datestr (buffer, sizeof buffer, sig->timestamp);
955
0
}
956
957
const char *
958
datestr_from_sig (PKT_signature *sig )
959
0
{
960
0
  if (opt.flags.full_timestrings)
961
0
    return isotimestamp (sig->timestamp);
962
0
  else
963
0
    return dateonlystr_from_sig (sig);
964
0
}
965
966
967
const char *
968
expirestr_from_pk (PKT_public_key *pk)
969
0
{
970
0
  static char buffer[MK_DATESTR_SIZE];
971
972
0
  if (!pk->expiredate)
973
0
    return _("never     ");
974
975
0
  if (opt.flags.full_timestrings)
976
0
    return isotimestamp (pk->expiredate);
977
978
0
  return mk_datestr (buffer, sizeof buffer, pk->expiredate);
979
0
}
980
981
982
const char *
983
expirestr_from_sig (PKT_signature *sig)
984
0
{
985
0
  static char buffer[MK_DATESTR_SIZE];
986
987
0
  if (!sig->expiredate)
988
0
    return _("never     ");
989
990
0
  if (opt.flags.full_timestrings)
991
0
    return isotimestamp (sig->expiredate);
992
993
0
  return mk_datestr (buffer, sizeof buffer, sig->expiredate);
994
0
}
995
996
997
const char *
998
revokestr_from_pk( PKT_public_key *pk )
999
0
{
1000
0
  static char buffer[MK_DATESTR_SIZE];
1001
1002
0
  if(!pk->revoked.date)
1003
0
    return _("never     ");
1004
1005
0
  if (opt.flags.full_timestrings)
1006
0
    return isotimestamp (pk->revoked.date);
1007
1008
0
  return mk_datestr (buffer, sizeof buffer, pk->revoked.date);
1009
0
}
1010
1011
1012
const char *
1013
usagestr_from_pk (PKT_public_key *pk, int fill)
1014
0
{
1015
0
  static char buffer[10];
1016
0
  int i = 0;
1017
0
  unsigned int use = pk->pubkey_usage;
1018
1019
0
  if ( use & PUBKEY_USAGE_SIG )
1020
0
    buffer[i++] = 'S';
1021
1022
0
  if ( use & PUBKEY_USAGE_CERT )
1023
0
    buffer[i++] = 'C';
1024
1025
0
  if ( use & PUBKEY_USAGE_ENC )
1026
0
    buffer[i++] = 'E';
1027
1028
0
  if ( (use & PUBKEY_USAGE_AUTH) )
1029
0
    buffer[i++] = 'A';
1030
1031
0
  if ( (use & PUBKEY_USAGE_RENC) )
1032
0
    buffer[i++] = 'R';
1033
0
  if ( (use & PUBKEY_USAGE_TIME) )
1034
0
    buffer[i++] = 'T';
1035
0
  if ( (use & PUBKEY_USAGE_GROUP) )
1036
0
    buffer[i++] = 'G';
1037
1038
0
  while (fill && i < 4)
1039
0
    buffer[i++] = ' ';
1040
1041
0
  buffer[i] = 0;
1042
0
  return buffer;
1043
0
}
1044
1045
1046
const char *
1047
colon_strtime (u32 t)
1048
0
{
1049
0
  static char buf[20];
1050
1051
0
  if (!t)
1052
0
    return "";
1053
0
  snprintf (buf, sizeof buf, "%lu", (ulong)t);
1054
0
  return buf;
1055
0
}
1056
1057
const char *
1058
colon_datestr_from_pk (PKT_public_key *pk)
1059
0
{
1060
0
  static char buf[20];
1061
1062
0
  snprintf (buf, sizeof buf, "%lu", (ulong)pk->timestamp);
1063
0
  return buf;
1064
0
}
1065
1066
1067
const char *
1068
colon_datestr_from_sig (PKT_signature *sig)
1069
0
{
1070
0
  static char buf[20];
1071
1072
0
  snprintf (buf, sizeof buf, "%lu", (ulong)sig->timestamp);
1073
0
  return buf;
1074
0
}
1075
1076
const char *
1077
colon_expirestr_from_sig (PKT_signature *sig)
1078
0
{
1079
0
  static char buf[20];
1080
1081
0
  if (!sig->expiredate)
1082
0
    return "";
1083
1084
0
  snprintf (buf, sizeof buf,"%lu", (ulong)sig->expiredate);
1085
0
  return buf;
1086
0
}
1087
1088
1089
1090
/*
1091
 * Return a byte array with the fingerprint for the given PK/SK
1092
 * The length of the array is returned in ret_len. Caller must free
1093
 * the array or provide an array of length MAX_FINGERPRINT_LEN.
1094
 */
1095
byte *
1096
fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len)
1097
0
{
1098
0
  if (!pk->fprlen)
1099
0
    compute_fingerprint (pk);
1100
1101
0
  if (!array)
1102
0
    array = xmalloc (pk->fprlen);
1103
0
  memcpy (array, pk->fpr, pk->fprlen);
1104
1105
0
  if (ret_len)
1106
0
    *ret_len = pk->fprlen;
1107
0
  return array;
1108
0
}
1109
1110
1111
/*
1112
 * Return a byte array with the fingerprint for the given PK/SK The
1113
 * length of the array is returned in ret_len. Caller must free the
1114
 * array or provide an array of length MAX_FINGERPRINT_LEN.  This
1115
 * version creates a v5 fingerprint even for v4 keys.
1116
 */
1117
byte *
1118
v5_fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len)
1119
0
{
1120
0
  const byte *dp;
1121
0
  gcry_md_hd_t md;
1122
1123
0
  if (pk->version == 5)
1124
0
    return fingerprint_from_pk (pk, array, ret_len);
1125
1126
0
  if (gcry_md_open (&md, GCRY_MD_SHA256, 0))
1127
0
    BUG ();
1128
0
  do_hash_public_key (md, pk, 1);
1129
0
  gcry_md_final (md);
1130
0
  dp = gcry_md_read (md, 0);
1131
0
  if (!array)
1132
0
    array = xmalloc (32);
1133
0
  memcpy (array, dp, 32);
1134
0
  gcry_md_close (md);
1135
1136
0
  if (ret_len)
1137
0
    *ret_len = 32;
1138
0
  return array;
1139
0
}
1140
1141
1142
/*
1143
 * This is the core of fpr20_from_pk which directly takes a
1144
 * fingerprint and its length instead of the public key.  See below
1145
 * for details.
1146
 */
1147
void
1148
fpr20_from_fpr (const byte *fpr, unsigned int fprlen, byte array[20])
1149
0
{
1150
0
  if (fprlen >= 32)            /* v5 fingerprint (or larger) */
1151
0
    {
1152
0
      memcpy (array +  0, fpr + 20, 4);
1153
0
      memcpy (array +  4, fpr + 24, 4);
1154
0
      memcpy (array +  8, fpr + 28, 4);
1155
0
      memcpy (array + 12, fpr +  0, 4); /* kid[0] */
1156
0
      memcpy (array + 16, fpr +  4, 4); /* kid[1] */
1157
0
    }
1158
0
  else if (fprlen == 20)       /* v4 fingerprint */
1159
0
    memcpy (array, fpr, 20);
1160
0
  else                         /* v3 or too short: fill up with zeroes.  */
1161
0
    {
1162
0
      memset (array, 0, 20);
1163
0
      memcpy (array, fpr, fprlen);
1164
0
    }
1165
0
}
1166
1167
1168
/*
1169
 * Get FPR20 for the given PK/SK into ARRAY.
1170
 *
1171
 * FPR20 is special form of fingerprint of length 20 for the record of
1172
 * trustdb.  For v4key, having fingerprint with SHA-1, FPR20 is the
1173
 * same one.  For v5key, FPR20 is constructed from its fingerprint
1174
 * with SHA-2, so that its kid of last 8-byte can be as same as
1175
 * kid of v5key fingerprint.
1176
 *
1177
 */
1178
void
1179
fpr20_from_pk (PKT_public_key *pk, byte array[20])
1180
0
{
1181
0
  if (!pk->fprlen)
1182
0
    compute_fingerprint (pk);
1183
1184
0
  fpr20_from_fpr (pk->fpr, pk->fprlen, array);
1185
0
}
1186
1187
1188
/* Return an allocated buffer with the fingerprint of PK formatted as
1189
 * a plain hexstring.  If BUFFER is NULL the result is a malloc'd
1190
 * string.  If BUFFER is not NULL the result will be copied into this
1191
 * buffer.  In the latter case BUFLEN describes the length of the
1192
 * buffer; if this is too short the function terminates the process.
1193
 * Returns a malloc'ed string or BUFFER.  A suitable length for BUFFER
1194
 * is (2*MAX_FINGERPRINT_LEN + 1). */
1195
char *
1196
hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen)
1197
0
{
1198
0
  if (!pk->fprlen)
1199
0
    compute_fingerprint (pk);
1200
1201
0
  if (!buffer)
1202
0
    {
1203
0
      buffer = xtrymalloc (2 * pk->fprlen + 1);
1204
0
      if (!buffer)
1205
0
        return NULL;
1206
0
    }
1207
0
  else if (buflen < 2 * pk->fprlen + 1)
1208
0
    log_fatal ("%s: buffer too short (%zu)\n", __func__, buflen);
1209
1210
0
  bin2hex (pk->fpr, pk->fprlen, buffer);
1211
0
  return buffer;
1212
0
}
1213
1214
1215
/* Same as hexfingerprint but returns a v5 fingerprint also for a v4
1216
 * key.  */
1217
char *
1218
v5hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen)
1219
0
{
1220
0
  char fprbuf[32];
1221
1222
0
  if (pk->version == 5)
1223
0
    return hexfingerprint (pk, buffer, buflen);
1224
1225
0
  if (!buffer)
1226
0
    {
1227
0
      buffer = xtrymalloc (2 * 32 + 1);
1228
0
      if (!buffer)
1229
0
        return NULL;
1230
0
    }
1231
0
  else if (buflen < 2 * 32 + 1)
1232
0
    log_fatal ("%s: buffer too short (%zu)\n", __func__, buflen);
1233
1234
0
  v5_fingerprint_from_pk (pk, fprbuf, NULL);
1235
0
  return bin2hex (fprbuf, 32, buffer);
1236
0
}
1237
1238
1239
/* Pretty print a hex fingerprint.  If BUFFER is NULL the result is a
1240
   malloc'd string.  If BUFFER is not NULL the result will be copied
1241
   into this buffer.  In the latter case BUFLEN describes the length
1242
   of the buffer; if this is too short the function terminates the
1243
   process.  Returns a malloc'ed string or BUFFER.  A suitable length
1244
   for BUFFER is (MAX_FORMATTED_FINGERPRINT_LEN + 1).  */
1245
char *
1246
format_hexfingerprint (const char *fingerprint, char *buffer, size_t buflen)
1247
0
{
1248
0
  int hexlen = strlen (fingerprint);
1249
0
  int space;
1250
0
  int i, j;
1251
1252
0
  if (hexlen == 40)  /* v4 fingerprint */
1253
0
    {
1254
0
      space = (/* The characters and the NUL.  */
1255
0
         40 + 1
1256
         /* After every fourth character, we add a space (except
1257
      the last).  */
1258
0
         + 40 / 4 - 1
1259
         /* Half way through we add a second space.  */
1260
0
         + 1);
1261
0
    }
1262
0
  else if (hexlen == 64 || hexlen == 50)  /* v5 fingerprint */
1263
0
    {
1264
      /* The v5 fingerprint is commonly printed truncated to 25
1265
       * octets.  We accept the truncated as well as the full hex
1266
       * version here and format it like this:
1267
       * 19347 BC987 24640 25F99 DF3EC 2E000 0ED98 84892 E1F7B 3EA4C
1268
       */
1269
0
      hexlen = 50;
1270
0
      space = 10 * 5 + 9 + 1;
1271
0
    }
1272
0
  else  /* Other fingerprint versions - print as is.  */
1273
0
    {
1274
      /* We truncated here so that we do not need to provide a buffer
1275
       * of a length which is in reality never used.  */
1276
0
      if (hexlen > MAX_FORMATTED_FINGERPRINT_LEN - 1)
1277
0
        hexlen = MAX_FORMATTED_FINGERPRINT_LEN - 1;
1278
0
      space = hexlen + 1;
1279
0
    }
1280
1281
0
  if (!buffer)
1282
0
    buffer = xmalloc (space);
1283
0
  else if (buflen < space)
1284
0
    log_fatal ("%s: buffer too short (%zu)\n", __func__, buflen);
1285
1286
0
  if (hexlen == 40)  /* v4 fingerprint */
1287
0
    {
1288
0
      for (i = 0, j = 0; i < 40; i ++)
1289
0
        {
1290
0
          if (i && !(i % 4))
1291
0
            buffer[j ++] = ' ';
1292
0
          if (i == 40 / 2)
1293
0
            buffer[j ++] = ' ';
1294
1295
0
          buffer[j ++] = fingerprint[i];
1296
0
        }
1297
0
      buffer[j ++] = 0;
1298
0
      log_assert (j == space);
1299
0
    }
1300
0
  else if (hexlen == 50)  /* v5 fingerprint */
1301
0
    {
1302
0
      for (i=j=0; i < 50; i++)
1303
0
        {
1304
0
          if (i && !(i % 5))
1305
0
            buffer[j++] = ' ';
1306
0
          buffer[j++] = fingerprint[i];
1307
0
        }
1308
0
      buffer[j++] = 0;
1309
0
      log_assert (j == space);
1310
0
    }
1311
0
  else
1312
0
    {
1313
0
      mem2str (buffer, fingerprint, space);
1314
0
    }
1315
1316
0
  return buffer;
1317
0
}
1318
1319
1320

1321
/* Return the so called KEYGRIP which is the SHA-1 hash of the public
1322
 * key parameters expressed as an canonical encoded S-Exp.  ARRAY must
1323
 * be 20 bytes long.  Returns 0 on success or an error code.  If
1324
 * GET_SECOND Is one and PK has dual algorithm, the keygrip of the
1325
 * second algorithm is return; GPG_ERR_FALSE is returned if the algo
1326
 * is not a dual algorithm.  */
1327
gpg_error_t
1328
keygrip_from_pk (PKT_public_key *pk, unsigned char *array, int get_second)
1329
0
{
1330
0
  gpg_error_t err;
1331
0
  gcry_sexp_t s_pkey;
1332
1333
0
  if (DBG_PACKET)
1334
0
    log_debug ("get_keygrip for public key%s\n", get_second?" (second)":"");
1335
1336
0
  if (get_second && pk->pubkey_algo != PUBKEY_ALGO_KYBER)
1337
0
    return gpg_error (GPG_ERR_FALSE);
1338
1339
0
  switch (pk->pubkey_algo)
1340
0
    {
1341
0
    case GCRY_PK_DSA:
1342
0
      err = gcry_sexp_build (&s_pkey, NULL,
1343
0
                             "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
1344
0
                             pk->pkey[0], pk->pkey[1],
1345
0
                             pk->pkey[2], pk->pkey[3]);
1346
0
      break;
1347
1348
0
    case GCRY_PK_ELG:
1349
0
    case GCRY_PK_ELG_E:
1350
0
      err = gcry_sexp_build (&s_pkey, NULL,
1351
0
                             "(public-key(elg(p%m)(g%m)(y%m)))",
1352
0
                             pk->pkey[0], pk->pkey[1], pk->pkey[2]);
1353
0
      break;
1354
1355
0
    case GCRY_PK_RSA:
1356
0
    case GCRY_PK_RSA_S:
1357
0
    case GCRY_PK_RSA_E:
1358
0
      err = gcry_sexp_build (&s_pkey, NULL,
1359
0
                             "(public-key(rsa(n%m)(e%m)))",
1360
0
                             pk->pkey[0], pk->pkey[1]);
1361
0
      break;
1362
1363
0
    case PUBKEY_ALGO_EDDSA:
1364
0
    case PUBKEY_ALGO_ECDSA:
1365
0
    case PUBKEY_ALGO_ECDH:
1366
0
      {
1367
0
        char *curve = openpgp_oid_to_str (pk->pkey[0]);
1368
0
        if (!curve)
1369
0
          err = gpg_error_from_syserror ();
1370
0
        else
1371
0
          {
1372
0
            err = gcry_sexp_build (&s_pkey, NULL,
1373
0
                                   pk->pubkey_algo == PUBKEY_ALGO_EDDSA?
1374
0
                                   "(public-key(ecc(curve%s)(flags eddsa)(q%m)))":
1375
0
                                   (pk->pubkey_algo == PUBKEY_ALGO_ECDH
1376
0
                                    && openpgp_oid_is_cv25519 (pk->pkey[0]))?
1377
0
                                   "(public-key(ecc(curve%s)(flags djb-tweak)(q%m)))":
1378
0
                                   "(public-key(ecc(curve%s)(q%m)))",
1379
0
                                   curve, pk->pkey[1]);
1380
0
            xfree (curve);
1381
0
          }
1382
0
      }
1383
0
      break;
1384
1385
0
    case PUBKEY_ALGO_KYBER:
1386
0
      if (get_second)
1387
0
        {
1388
0
          char tmpname[15];
1389
1390
0
          snprintf (tmpname, sizeof tmpname, "kyber%u", nbits_from_pk (pk));
1391
0
          err = gcry_sexp_build (&s_pkey, NULL,
1392
0
                                 "(public-key(%s(p%m)))",
1393
0
                                 tmpname, pk->pkey[2]);
1394
0
        }
1395
0
      else
1396
0
        {
1397
0
          char *curve = openpgp_oid_to_str (pk->pkey[0]);
1398
0
          if (!curve)
1399
0
            err = gpg_error_from_syserror ();
1400
0
          else
1401
0
            {
1402
0
              err = gcry_sexp_build (&s_pkey, NULL,
1403
0
                           openpgp_oid_is_cv25519 (pk->pkey[0])
1404
0
                           ? "(public-key(ecc(curve%s)(flags djb-tweak)(q%m)))"
1405
0
                           : "(public-key(ecc(curve%s)(q%m)))",
1406
0
                           curve, pk->pkey[1]);
1407
0
              xfree (curve);
1408
0
            }
1409
0
        }
1410
0
      break;
1411
1412
0
    default:
1413
0
      err = gpg_error (GPG_ERR_PUBKEY_ALGO);
1414
0
      break;
1415
0
    }
1416
1417
0
  if (err)
1418
0
    return err;
1419
1420
0
  if (!gcry_pk_get_keygrip (s_pkey, array))
1421
0
    {
1422
0
      char *hexfpr;
1423
1424
0
      hexfpr = hexfingerprint (pk, NULL, 0);
1425
0
      log_info ("error computing keygrip (fpr=%s)\n", hexfpr);
1426
0
      xfree (hexfpr);
1427
1428
0
      memset (array, 0, 20);
1429
0
      err = gpg_error (GPG_ERR_GENERAL);
1430
0
    }
1431
0
  else
1432
0
    {
1433
0
      if (DBG_PACKET)
1434
0
        log_printhex (array, 20, "keygrip=");
1435
      /* FIXME: Save the keygrip in PK.  */
1436
0
    }
1437
0
  gcry_sexp_release (s_pkey);
1438
1439
0
  return err;
1440
0
}
1441
1442
1443
/* Store an allocated buffer with the keygrip of PK encoded as a
1444
 * hexstring at r_GRIP.  Returns 0 on success.  For dual algorithms
1445
 * the keygrips are delimited by a comma. */
1446
gpg_error_t
1447
hexkeygrip_from_pk (PKT_public_key *pk, char **r_grip)
1448
0
{
1449
0
  gpg_error_t err;
1450
0
  char *buf;
1451
0
  unsigned char grip[KEYGRIP_LEN];
1452
0
  unsigned char grip2[KEYGRIP_LEN];
1453
1454
0
  *r_grip = NULL;
1455
0
  err = keygrip_from_pk (pk, grip, 0);
1456
0
  if (!err)
1457
0
    {
1458
0
      if (pk->pubkey_algo == PUBKEY_ALGO_KYBER)
1459
0
        {
1460
0
          err = keygrip_from_pk (pk, grip2, 1);
1461
0
          if (err)
1462
0
            goto leave;
1463
0
          buf = xtrymalloc (2 * KEYGRIP_LEN * 2 + 1 + 1);
1464
0
        }
1465
0
      else
1466
0
        buf = xtrymalloc (KEYGRIP_LEN * 2 + 1);
1467
1468
0
      if (!buf)
1469
0
        {
1470
0
          err = gpg_error_from_syserror ();
1471
0
          goto leave;
1472
0
        }
1473
1474
0
      bin2hex (grip, KEYGRIP_LEN, buf);
1475
0
      if (pk->pubkey_algo == PUBKEY_ALGO_KYBER)
1476
0
        {
1477
0
          buf[2*KEYGRIP_LEN] = ',';
1478
0
          bin2hex (grip2, KEYGRIP_LEN, buf+2*KEYGRIP_LEN+1);
1479
0
        }
1480
0
      *r_grip = buf;
1481
0
    }
1482
0
 leave:
1483
0
  return err;
1484
0
}
1485
1486
1487
/* Return a hexfied malloced string of the ECDH parameters for an ECDH
1488
 * key from the public key PK.  Returns NULL on error.  */
1489
char *
1490
ecdh_param_str_from_pk (PKT_public_key *pk)
1491
0
{
1492
0
  const unsigned char *s;
1493
0
  unsigned int n;
1494
1495
0
  if (!pk
1496
0
      || pk->pubkey_algo != PUBKEY_ALGO_ECDH
1497
0
      || !gcry_mpi_get_flag (pk->pkey[2], GCRYMPI_FLAG_OPAQUE)
1498
0
      || !(s = gcry_mpi_get_opaque (pk->pkey[2], &n)) || !n)
1499
0
    {
1500
0
      gpg_err_set_errno (EINVAL);
1501
0
      return NULL;  /* Invalid parameter */
1502
0
    }
1503
1504
0
  n = (n+7)/8;
1505
  return bin2hex (s, n, NULL);
1506
0
}