Coverage Report

Created: 2026-10-08 07:05

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