Coverage Report

Created: 2026-08-31 07:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gnupg/kbx/keybox-openpgp.c
Line
Count
Source
1
/* keybox-openpgp.c - OpenPGP key parsing
2
 * Copyright (C) 2001, 2003, 2011 Free Software Foundation, Inc.
3
 *
4
 * This file is part of GnuPG.
5
 *
6
 * GnuPG is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * GnuPG is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, see <https://www.gnu.org/licenses/>.
18
 */
19
20
/* This is a simple OpenPGP parser suitable for all OpenPGP key
21
   material.  It just provides the functionality required to build and
22
   parse an KBX OpenPGP key blob.  Thus it is not a complete parser.
23
   However it is self-contained and optimized for fast in-memory
24
   parsing.  Note that we don't support old ElGamal v3 keys
25
   anymore. */
26
27
#include <config.h>
28
#include <stdlib.h>
29
#include <stdio.h>
30
#include <string.h>
31
#include <errno.h>
32
#include <assert.h>
33
34
#include "keybox-defs.h"
35
36
#include <gcrypt.h>
37
38
#include "../common/openpgpdefs.h"
39
#include "../common/host2net.h"
40
41
struct keyparm_s
42
{
43
  const char *mpi;
44
  int len;   /* int to avoid a cast in gcry_sexp_build.  */
45
};
46
47
48
/* Assume a valid OpenPGP packet at the address pointed to by BUFBTR
49
   which has a maximum length as stored at BUFLEN.  Return the header
50
   information of that packet and advance the pointer stored at BUFPTR
51
   to the next packet; also adjust the length stored at BUFLEN to
52
   match the remaining bytes. If there are no more packets, store NULL
53
   at BUFPTR.  Return an non-zero error code on failure or the
54
   following data on success:
55
56
   R_DATAPKT = Pointer to the begin of the packet data.
57
   R_DATALEN = Length of this data.  This has already been checked to fit
58
               into the buffer.
59
   R_PKTTYPE = The packet type.
60
   R_NTOTAL  = The total number of bytes of this packet
61
62
   Note that these values are only updated on success.
63
*/
64
static gpg_error_t
65
next_packet (unsigned char const **bufptr, size_t *buflen,
66
             unsigned char const **r_data, size_t *r_datalen, int *r_pkttype,
67
             size_t *r_ntotal)
68
5.52M
{
69
5.52M
  const unsigned char *buf = *bufptr;
70
5.52M
  size_t len = *buflen;
71
5.52M
  int c, ctb, pkttype;
72
5.52M
  unsigned long pktlen;
73
74
5.52M
  if (!len)
75
0
    return gpg_error (GPG_ERR_NO_DATA);
76
77
5.52M
  ctb = *buf++; len--;
78
5.52M
  if ( !(ctb & 0x80) )
79
0
    return gpg_error (GPG_ERR_INV_PACKET); /* Invalid CTB. */
80
81
5.52M
  if ((ctb & 0x40))  /* New style (OpenPGP) CTB.  */
82
0
    {
83
0
      pkttype = (ctb & 0x3f);
84
0
      if (!len)
85
0
        return gpg_error (GPG_ERR_INV_PACKET); /* No 1st length byte. */
86
0
      c = *buf++; len--;
87
0
      if (pkttype == PKT_COMPRESSED)
88
0
        return gpg_error (GPG_ERR_UNEXPECTED); /* ... packet in a keyblock. */
89
0
      if ( c < 192 )
90
0
        pktlen = c;
91
0
      else if ( c < 224 )
92
0
        {
93
0
          pktlen = (c - 192) * 256;
94
0
          if (!len)
95
0
            return gpg_error (GPG_ERR_INV_PACKET); /* No 2nd length byte. */
96
0
          c = *buf++; len--;
97
0
          pktlen += c + 192;
98
0
        }
99
0
      else if (c == 255)
100
0
        {
101
0
          if (len <4 )
102
0
            return gpg_error (GPG_ERR_INV_PACKET); /* No length bytes. */
103
0
          pktlen = buf32_to_ulong (buf);
104
0
          buf += 4;
105
0
          len -= 4;
106
0
      }
107
0
      else /* Partial length encoding is not allowed for key packets. */
108
0
        return gpg_error (GPG_ERR_UNEXPECTED);
109
0
    }
110
5.52M
  else /* Old style CTB.  */
111
5.52M
    {
112
5.52M
      int lenbytes;
113
114
5.52M
      pktlen = 0;
115
5.52M
      pkttype = (ctb>>2)&0xf;
116
5.52M
      lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3));
117
5.52M
      if (!lenbytes) /* Not allowed in key packets.  */
118
0
        return gpg_error (GPG_ERR_UNEXPECTED);
119
5.52M
      if (len < lenbytes)
120
0
        return gpg_error (GPG_ERR_INV_PACKET); /* Not enough length bytes.  */
121
11.0M
      for (; lenbytes; lenbytes--)
122
5.53M
        {
123
5.53M
          pktlen <<= 8;
124
5.53M
          pktlen |= *buf++; len--;
125
5.53M
  }
126
5.52M
    }
127
128
  /* Do some basic sanity check.  */
129
5.52M
  switch (pkttype)
130
5.52M
    {
131
2.68M
    case PKT_SIGNATURE:
132
2.68M
    case PKT_SECRET_KEY:
133
2.68M
    case PKT_PUBLIC_KEY:
134
2.68M
    case PKT_SECRET_SUBKEY:
135
2.68M
    case PKT_MARKER:
136
5.37M
    case PKT_RING_TRUST:
137
5.38M
    case PKT_USER_ID:
138
5.52M
    case PKT_PUBLIC_SUBKEY:
139
5.52M
    case PKT_OLD_COMMENT:
140
5.52M
    case PKT_ATTRIBUTE:
141
5.52M
    case PKT_COMMENT:
142
5.52M
    case PKT_GPG_CONTROL:
143
5.52M
      break; /* Okay these are allowed packets. */
144
0
    default:
145
0
      return gpg_error (GPG_ERR_UNEXPECTED);
146
5.52M
    }
147
148
5.52M
  if (pkttype == 63 && pktlen == 0xFFFFFFFF)
149
    /* Sometimes the decompressing layer enters an error state in
150
       which it simply outputs 0xff for every byte read.  If we have a
151
       stream of 0xff bytes, then it will be detected as a new format
152
       packet with type 63 and a 4-byte encoded length that is 4G-1.
153
       Since packets with type 63 are private and we use them as a
154
       control packet, which won't be 4 GB, we reject such packets as
155
       invalid.  */
156
0
    return gpg_error (GPG_ERR_INV_PACKET);
157
158
5.52M
  if (pktlen > len)
159
0
    return gpg_error (GPG_ERR_INV_PACKET); /* Packet length header too long. */
160
161
5.52M
  *r_data = buf;
162
5.52M
  *r_datalen = pktlen;
163
5.52M
  *r_pkttype = pkttype;
164
5.52M
  *r_ntotal = (buf - *bufptr) + pktlen;
165
166
5.52M
  *bufptr = buf + pktlen;
167
5.52M
  *buflen = len - pktlen;
168
5.52M
  if (!*buflen)
169
1.82k
    *bufptr = NULL;
170
171
5.52M
  return 0;
172
5.52M
}
173
174
175
/* Take a list of key parameters KP for the OpenPGP ALGO and compute
176
 * the keygrip which will be stored at GRIP.  GRIP needs to be a
177
 * buffer of 20 bytes.  */
178
static gpg_error_t
179
keygrip_from_keyparm (int algo, struct keyparm_s *kp, unsigned char *grip)
180
151k
{
181
151k
  gpg_error_t err;
182
151k
  gcry_sexp_t s_pkey = NULL;
183
184
151k
  switch (algo)
185
151k
    {
186
7
    case PUBKEY_ALGO_DSA:
187
7
      err = gcry_sexp_build (&s_pkey, NULL,
188
7
                             "(public-key(dsa(p%b)(q%b)(g%b)(y%b)))",
189
7
                             kp[0].len, kp[0].mpi,
190
7
                             kp[1].len, kp[1].mpi,
191
7
                             kp[2].len, kp[2].mpi,
192
7
                             kp[3].len, kp[3].mpi);
193
7
      break;
194
195
0
    case PUBKEY_ALGO_ELGAMAL:
196
4
    case PUBKEY_ALGO_ELGAMAL_E:
197
4
      err = gcry_sexp_build (&s_pkey, NULL,
198
4
                             "(public-key(elg(p%b)(g%b)(y%b)))",
199
4
                             kp[0].len, kp[0].mpi,
200
4
                             kp[1].len, kp[1].mpi,
201
4
                             kp[2].len, kp[2].mpi);
202
4
      break;
203
204
165
    case PUBKEY_ALGO_RSA:
205
165
    case PUBKEY_ALGO_RSA_S:
206
165
    case PUBKEY_ALGO_RSA_E:
207
165
      err = gcry_sexp_build (&s_pkey, NULL,
208
165
                             "(public-key(rsa(n%b)(e%b)))",
209
165
                             kp[0].len, kp[0].mpi,
210
165
                             kp[1].len, kp[1].mpi);
211
165
      break;
212
213
1.66k
    case PUBKEY_ALGO_EDDSA:
214
1.73k
    case PUBKEY_ALGO_ECDSA:
215
150k
    case PUBKEY_ALGO_ECDH:
216
150k
      {
217
150k
        char *curve = openpgp_oidbuf_to_str (kp[0].mpi, kp[0].len);
218
150k
        if (!curve)
219
0
          err = gpg_error_from_syserror ();
220
150k
        else
221
150k
          {
222
150k
            err = gcry_sexp_build
223
150k
              (&s_pkey, NULL,
224
150k
               (algo == PUBKEY_ALGO_EDDSA)?
225
1.66k
               "(public-key(ecc(curve%s)(flags eddsa)(q%b)))":
226
150k
               (algo == PUBKEY_ALGO_ECDH
227
149k
                && openpgp_oidbuf_is_cv25519 (kp[0].mpi, kp[0].len))?
228
148k
               "(public-key(ecc(curve%s)(flags djb-tweak)(q%b)))":
229
149k
               "(public-key(ecc(curve%s)(q%b)))",
230
150k
               curve, kp[1].len, kp[1].mpi);
231
150k
            xfree (curve);
232
150k
          }
233
150k
      }
234
150k
      break;
235
236
0
    case PUBKEY_ALGO_KYBER:
237
      /* There is no space in the BLOB for a second grip, thus for now
238
       * we store only the ECC keygrip.  */
239
0
      {
240
0
        char *curve = openpgp_oidbuf_to_str (kp[0].mpi, kp[0].len);
241
0
        if (!curve)
242
0
          err = gpg_error_from_syserror ();
243
0
        else
244
0
          {
245
0
            err = gcry_sexp_build
246
0
              (&s_pkey, NULL,
247
0
               openpgp_oidbuf_is_cv25519 (kp[0].mpi, kp[0].len)
248
0
               ?"(public-key(ecc(curve%s)(flags djb-tweak)(q%b)))"
249
0
               : "(public-key(ecc(curve%s)(q%b)))",
250
0
               curve, kp[1].len, kp[1].mpi);
251
0
            xfree (curve);
252
0
          }
253
0
      }
254
0
      break;
255
256
0
    default:
257
0
      err = gpg_error (GPG_ERR_PUBKEY_ALGO);
258
0
      break;
259
151k
    }
260
261
151k
  if (!err && !gcry_pk_get_keygrip (s_pkey, grip))
262
0
    {
263
      /* Some Linux distributions remove certain curves from Libgcrypt
264
       * but not from GnuPG and thus the keygrip can't be computed.
265
       * Emit a better error message for this case.  */
266
0
      if (!gcry_pk_get_curve (s_pkey, 0, NULL))
267
0
        err = gpg_error (GPG_ERR_UNKNOWN_CURVE);
268
0
      else
269
0
        {
270
0
          log_info ("kbx: error computing keygrip\n");
271
0
          err = gpg_error (GPG_ERR_GENERAL);
272
0
        }
273
0
    }
274
275
151k
  gcry_sexp_release (s_pkey);
276
277
151k
  if (err)
278
0
    memset (grip, 0, 20);
279
151k
  return err;
280
151k
}
281
282
283
/* Parse a key packet and store the information in KI. */
284
static gpg_error_t
285
parse_key (const unsigned char *data, size_t datalen,
286
           struct _keybox_openpgp_key_info *ki)
287
151k
{
288
151k
  gpg_error_t err;
289
151k
  const unsigned char *data_start = data;
290
151k
  int i, version, algorithm;
291
151k
  size_t n;
292
151k
  int npkey;
293
151k
  unsigned char hashbuffer[768];
294
151k
  gcry_md_hd_t md;
295
151k
  int is_ecc = 0;
296
151k
  int is_kyber = 0;
297
151k
  int is_v5;
298
  /* unsigned int pkbytes;  for v5: # of octets of the public key params.  */
299
151k
  struct keyparm_s keyparm[OPENPGP_MAX_NPKEY];
300
151k
  unsigned char *helpmpibuf[OPENPGP_MAX_NPKEY] = { NULL };
301
302
151k
  if (datalen < 5)
303
0
    return gpg_error (GPG_ERR_INV_PACKET);
304
151k
  version = *data++; datalen--;
305
151k
  if (version < 2 || version > 5 )
306
0
    return gpg_error (GPG_ERR_INV_PACKET); /* Invalid version. */
307
151k
  is_v5 = version == 5;
308
309
  /*timestamp = ((data[0]<<24)|(data[1]<<16)|(data[2]<<8)|(data[3]));*/
310
151k
  data +=4; datalen -=4;
311
312
151k
  if (version < 4)
313
0
    {
314
0
      if (datalen < 2)
315
0
        return gpg_error (GPG_ERR_INV_PACKET);
316
0
      data +=2; datalen -= 2;
317
0
    }
318
319
151k
  if (!datalen)
320
0
    return gpg_error (GPG_ERR_INV_PACKET);
321
151k
  algorithm = *data++; datalen--;
322
323
151k
  if (is_v5)
324
3
    {
325
3
      if (datalen < 4)
326
0
        return gpg_error (GPG_ERR_INV_PACKET);
327
      /* pkbytes = buf32_to_uint (data); */
328
3
      data += 4;
329
3
      datalen -= 4;
330
3
    }
331
332
151k
  switch (algorithm)
333
151k
    {
334
165
    case PUBKEY_ALGO_RSA:
335
165
    case PUBKEY_ALGO_RSA_E:
336
165
    case PUBKEY_ALGO_RSA_S:
337
165
      npkey = 2;
338
165
      break;
339
4
    case PUBKEY_ALGO_ELGAMAL_E:
340
4
    case PUBKEY_ALGO_ELGAMAL:
341
4
      npkey = 3;
342
4
      break;
343
7
    case PUBKEY_ALGO_DSA:
344
7
      npkey = 4;
345
7
      break;
346
149k
    case PUBKEY_ALGO_ECDH:
347
149k
      npkey = 3;
348
149k
      is_ecc = 1;
349
149k
      break;
350
69
    case PUBKEY_ALGO_ECDSA:
351
1.73k
    case PUBKEY_ALGO_EDDSA:
352
1.73k
      npkey = 2;
353
1.73k
      is_ecc = 1;
354
1.73k
      break;
355
0
    case PUBKEY_ALGO_KYBER:
356
0
      npkey = 3;
357
0
      is_kyber = 1;
358
0
      break;
359
0
    default: /* Unknown algorithm. */
360
0
      return gpg_error (GPG_ERR_UNKNOWN_ALGORITHM);
361
151k
    }
362
363
151k
  ki->version = version;
364
151k
  ki->algo = algorithm;
365
366
602k
  for (i=0; i < npkey; i++ )
367
451k
    {
368
451k
      unsigned int nbits, nbytes;
369
370
451k
      if (datalen < 2)
371
0
        return gpg_error (GPG_ERR_INV_PACKET);
372
373
451k
      if ((is_ecc && (i == 0 || i == 2))
374
151k
          || (is_kyber && i == 0 ))
375
299k
        {
376
299k
          nbytes = data[0];
377
299k
          if (nbytes < 2 || nbytes > 254)
378
0
            return gpg_error (GPG_ERR_INV_PACKET);
379
299k
          nbytes++; /* The size byte itself.  */
380
299k
          if (datalen < nbytes)
381
0
            return gpg_error (GPG_ERR_INV_PACKET);
382
383
299k
          keyparm[i].mpi = data;
384
299k
          keyparm[i].len = nbytes;
385
299k
        }
386
151k
      else if (is_kyber && i == 2)
387
0
        {
388
0
          if (datalen < 4)
389
0
            return gpg_error (GPG_ERR_INV_PACKET);
390
0
          nbytes = ((data[0]<<24)|(data[1]<<16)|(data[2]<<8)|(data[3]));
391
0
          data += 4;
392
0
          datalen -= 4;
393
          /* (for the limit see also MAX_EXTERN_MPI_BITS in g10/gpg.h) */
394
0
          if (datalen < nbytes || nbytes > (32768*8))
395
0
            return gpg_error (GPG_ERR_INV_PACKET);
396
397
0
          keyparm[i].mpi = data;
398
0
          keyparm[i].len = nbytes;
399
0
        }
400
151k
      else
401
151k
        {
402
151k
          nbits = ((data[0]<<8)|(data[1]));
403
151k
          data += 2;
404
151k
          datalen -= 2;
405
151k
          nbytes = (nbits+7) / 8;
406
151k
          if (datalen < nbytes)
407
0
            return gpg_error (GPG_ERR_INV_PACKET);
408
409
151k
          keyparm[i].mpi = data;
410
151k
          keyparm[i].len = nbytes;
411
151k
        }
412
413
451k
      data += nbytes; datalen -= nbytes;
414
451k
    }
415
151k
  n = data - data_start;
416
417
418
  /* Note: Starting here we need to jump to leave on error. */
419
420
  /* For non-ECC, make sure the MPIs are unsigned.  */
421
151k
  if (!is_ecc && !is_kyber)
422
546
    for (i=0; i < npkey; i++)
423
370
      {
424
370
        if (!keyparm[i].len || (keyparm[i].mpi[0] & 0x80))
425
187
          {
426
187
            helpmpibuf[i] = xtrymalloc (1+keyparm[i].len);
427
187
            if (!helpmpibuf[i])
428
0
              {
429
0
                err = gpg_error_from_syserror ();
430
0
                goto leave;
431
0
              }
432
187
            helpmpibuf[i][0] = 0;
433
187
            memcpy (helpmpibuf[i]+1, keyparm[i].mpi, keyparm[i].len);
434
187
            keyparm[i].mpi = helpmpibuf[i];
435
187
            keyparm[i].len++;
436
187
          }
437
370
      }
438
439
151k
  err = keygrip_from_keyparm (algorithm, keyparm, ki->grip);
440
151k
  if (err)
441
0
    goto leave;
442
443
151k
  if (version < 4)
444
0
    {
445
      /* We do not support any other algorithm than RSA in v3
446
         packets. */
447
0
      if (algorithm < 1 || algorithm > 3)
448
0
        return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
449
450
0
      err = gcry_md_open (&md, GCRY_MD_MD5, 0);
451
0
      if (err)
452
0
        return err; /* Oops */
453
0
      gcry_md_write (md, keyparm[0].mpi, keyparm[0].len);
454
0
      gcry_md_write (md, keyparm[1].mpi, keyparm[1].len);
455
0
      memcpy (ki->fpr, gcry_md_read (md, 0), 16);
456
0
      gcry_md_close (md);
457
0
      ki->fprlen = 16;
458
459
0
      if (keyparm[0].len < 8)
460
0
        {
461
          /* Moduli less than 64 bit are out of the specs scope.  Zero
462
             them out because this is what gpg does too. */
463
0
          memset (ki->keyid, 0, 8);
464
0
        }
465
0
      else
466
0
        memcpy (ki->keyid, keyparm[0].mpi + keyparm[0].len - 8, 8);
467
0
    }
468
151k
  else
469
151k
    {
470
      /* Its a pity that we need to prefix the buffer with the tag
471
         and a length header: We can't simply pass it to the fast
472
         hashing function for that reason.  It might be a good idea to
473
         have a scatter-gather enabled hash function. What we do here
474
         is to use a static buffer if this one is large enough and
475
         only use the regular hash functions if this buffer is not
476
         large enough.
477
         FIXME: Factor this out to a shared fingerprint function.
478
       */
479
151k
      if (version == 5)
480
3
        {
481
3
          if (5 + n < sizeof hashbuffer )
482
3
            {
483
3
              hashbuffer[0] = 0x9a;     /* CTB */
484
3
              hashbuffer[1] = (n >> 24);/* 4 byte length header. */
485
3
              hashbuffer[2] = (n >> 16);
486
3
              hashbuffer[3] = (n >>  8);
487
3
              hashbuffer[4] = (n      );
488
3
              memcpy (hashbuffer + 5, data_start, n);
489
3
              gcry_md_hash_buffer (GCRY_MD_SHA256, ki->fpr, hashbuffer, 5 + n);
490
3
            }
491
0
          else
492
0
            {
493
0
              err = gcry_md_open (&md, GCRY_MD_SHA256, 0);
494
0
              if (err)
495
0
                return err; /* Oops */
496
0
              gcry_md_putc (md, 0x9a );     /* CTB */
497
0
              gcry_md_putc (md, (n >> 24)); /* 4 byte length header. */
498
0
              gcry_md_putc (md, (n >> 16));
499
0
              gcry_md_putc (md, (n >>  8));
500
0
              gcry_md_putc (md, (n      ));
501
0
              gcry_md_write (md, data_start, n);
502
0
              memcpy (ki->fpr, gcry_md_read (md, 0), 32);
503
0
              gcry_md_close (md);
504
0
            }
505
3
          ki->fprlen = 32;
506
3
          memcpy (ki->keyid, ki->fpr, 8);
507
3
        }
508
151k
      else
509
151k
        {
510
151k
          if ( 3 + n < sizeof hashbuffer )
511
151k
            {
512
151k
              hashbuffer[0] = 0x99;     /* CTB */
513
151k
              hashbuffer[1] = (n >> 8); /* 2 byte length header. */
514
151k
              hashbuffer[2] = (n     );
515
151k
              memcpy (hashbuffer + 3, data_start, n);
516
151k
              gcry_md_hash_buffer (GCRY_MD_SHA1, ki->fpr, hashbuffer, 3 + n);
517
151k
            }
518
0
          else
519
0
            {
520
0
              err = gcry_md_open (&md, GCRY_MD_SHA1, 0);
521
0
              if (err)
522
0
                return err; /* Oops */
523
0
              gcry_md_putc (md, 0x99 );     /* CTB */
524
0
              gcry_md_putc (md, (n >> 8));  /* 2 byte length header. */
525
0
              gcry_md_putc (md, (n     ));
526
0
              gcry_md_write (md, data_start, n);
527
0
              memcpy (ki->fpr, gcry_md_read (md, 0), 20);
528
0
              gcry_md_close (md);
529
0
            }
530
151k
          ki->fprlen = 20;
531
151k
          memcpy (ki->keyid, ki->fpr+12, 8);
532
151k
        }
533
151k
    }
534
535
151k
 leave:
536
602k
  for (i=0; i < npkey; i++)
537
451k
    xfree (helpmpibuf[i]);
538
539
151k
  return err;
540
151k
}
541
542
543
544
/* The caller must pass the address of an INFO structure which will
545
   get filled on success with information pertaining to the OpenPGP
546
   keyblock IMAGE of length IMAGELEN.  Note that a caller does only
547
   need to release this INFO structure if the function returns
548
   success.  If NPARSED is not NULL the actual number of bytes parsed
549
   will be stored at this address.  If ONLY_PRIMARY is set the parsing
550
   stops right after the primart key packet.  */
551
gpg_error_t
552
_keybox_parse_openpgp (const unsigned char *image, size_t imagelen,
553
                       int only_primary,
554
                       size_t *nparsed, keybox_openpgp_info_t info)
555
1.82k
{
556
1.82k
  gpg_error_t err = 0;
557
1.82k
  const unsigned char *image_start, *data;
558
1.82k
  size_t n, datalen;
559
1.82k
  int pkttype;
560
1.82k
  int first = 1;
561
1.82k
  int read_error = 0;
562
1.82k
  struct _keybox_openpgp_key_info *k, **ktail = NULL;
563
1.82k
  struct _keybox_openpgp_uid_info *u, **utail = NULL;
564
565
1.82k
  memset (info, 0, sizeof *info);
566
1.82k
  if (nparsed)
567
1.82k
    *nparsed = 0;
568
569
1.82k
  image_start = image;
570
5.53M
  while (image)
571
5.52M
    {
572
5.52M
      err = next_packet (&image, &imagelen, &data, &datalen, &pkttype, &n);
573
5.52M
      if (err)
574
0
        {
575
0
          read_error = 1;
576
0
          break;
577
0
        }
578
579
5.52M
      if (first)
580
1.82k
        {
581
1.82k
          if (pkttype == PKT_PUBLIC_KEY)
582
1.82k
            ;
583
0
          else if (pkttype == PKT_SECRET_KEY)
584
0
            info->is_secret = 1;
585
0
          else
586
0
            {
587
0
              err = gpg_error (GPG_ERR_UNEXPECTED);
588
0
              if (nparsed)
589
0
                *nparsed += n;
590
0
              break;
591
0
            }
592
1.82k
          first = 0;
593
1.82k
        }
594
5.52M
      else if (pkttype == PKT_PUBLIC_KEY || pkttype == PKT_SECRET_KEY)
595
0
        break; /* Next keyblock encountered - ready. */
596
597
5.52M
      if (nparsed)
598
5.52M
        *nparsed += n;
599
600
5.52M
      if (pkttype == PKT_SIGNATURE)
601
2.68M
        {
602
          /* For now we only count the total number of signatures. */
603
2.68M
          info->nsigs++;
604
2.68M
        }
605
2.84M
      else if (pkttype == PKT_USER_ID)
606
3.48k
        {
607
3.48k
          info->nuids++;
608
3.48k
          if (info->nuids == 1)
609
1.82k
            {
610
1.82k
              info->uids.off = data - image_start;
611
1.82k
              info->uids.len = datalen;
612
1.82k
              utail = &info->uids.next;
613
1.82k
            }
614
1.65k
          else
615
1.65k
            {
616
1.65k
              u = xtrycalloc (1, sizeof *u);
617
1.65k
              if (!u)
618
0
                {
619
0
                  err = gpg_error_from_syserror ();
620
0
                  break;
621
0
                }
622
1.65k
              u->off = data - image_start;
623
1.65k
              u->len = datalen;
624
1.65k
              *utail = u;
625
1.65k
              utail = &u->next;
626
1.65k
            }
627
3.48k
        }
628
2.84M
      else if (pkttype == PKT_PUBLIC_KEY || pkttype == PKT_SECRET_KEY)
629
1.82k
        {
630
1.82k
          err = parse_key (data, datalen, &info->primary);
631
1.82k
          if (err || only_primary)
632
0
            break;
633
1.82k
        }
634
2.83M
      else if( pkttype == PKT_PUBLIC_SUBKEY && datalen && *data == '#' )
635
0
        {
636
          /* Early versions of GnuPG used old PGP comment packets;
637
           * luckily all those comments are prefixed by a hash
638
           * sign - ignore these packets. */
639
0
        }
640
2.83M
      else if (pkttype == PKT_PUBLIC_SUBKEY || pkttype == PKT_SECRET_SUBKEY)
641
149k
        {
642
149k
          info->nsubkeys++;
643
149k
          if (info->nsubkeys == 1)
644
1.68k
            {
645
1.68k
              err = parse_key (data, datalen, &info->subkeys);
646
1.68k
              if (err)
647
0
                {
648
0
                  info->nsubkeys--;
649
                  /* We ignore subkeys with unknown algorithms. */
650
0
                  if (gpg_err_code (err) == GPG_ERR_UNKNOWN_ALGORITHM
651
0
                      || gpg_err_code (err) == GPG_ERR_UNSUPPORTED_ALGORITHM)
652
0
                    err = 0;
653
0
                  if (err)
654
0
                    break;
655
0
                }
656
1.68k
              else
657
1.68k
                ktail = &info->subkeys.next;
658
1.68k
            }
659
147k
          else
660
147k
            {
661
147k
              k = xtrycalloc (1, sizeof *k);
662
147k
              if (!k)
663
0
                {
664
0
                  err = gpg_error_from_syserror ();
665
0
                  break;
666
0
                }
667
147k
              err = parse_key (data, datalen, k);
668
147k
              if (err)
669
0
                {
670
0
                  xfree (k);
671
0
                  info->nsubkeys--;
672
                  /* We ignore subkeys with unknown algorithms. */
673
0
                  if (gpg_err_code (err) == GPG_ERR_UNKNOWN_ALGORITHM
674
0
                      || gpg_err_code (err) == GPG_ERR_UNSUPPORTED_ALGORITHM)
675
0
                    err = 0;
676
0
                  if (err)
677
0
                    break;
678
0
                }
679
147k
              else
680
147k
                {
681
147k
                  *ktail = k;
682
147k
                  ktail = &k->next;
683
147k
                }
684
147k
            }
685
149k
        }
686
5.52M
    }
687
688
1.82k
  if (err)
689
0
    {
690
0
      _keybox_destroy_openpgp_info (info);
691
0
      if (!read_error)
692
0
        {
693
          /* Packet parsing worked, thus we should be able to skip the
694
             rest of the keyblock.  */
695
0
          while (image)
696
0
            {
697
0
              if (next_packet (&image, &imagelen,
698
0
                               &data, &datalen, &pkttype, &n) )
699
0
                break; /* Another error - stop here. */
700
701
0
              if (pkttype == PKT_PUBLIC_KEY || pkttype == PKT_SECRET_KEY)
702
0
                break; /* Next keyblock encountered - ready. */
703
704
0
              if (nparsed)
705
0
                *nparsed += n;
706
0
            }
707
0
        }
708
0
    }
709
710
1.82k
  return err;
711
1.82k
}
712
713
714
/* Release any malloced data in INFO but not INFO itself! */
715
void
716
_keybox_destroy_openpgp_info (keybox_openpgp_info_t info)
717
1.82k
{
718
1.82k
  struct _keybox_openpgp_key_info *k, *k2;
719
1.82k
  struct _keybox_openpgp_uid_info *u, *u2;
720
721
1.82k
  log_assert (!info->primary.next);
722
149k
  for (k=info->subkeys.next; k; k = k2)
723
147k
    {
724
147k
      k2 = k->next;
725
147k
      xfree (k);
726
147k
    }
727
728
3.48k
  for (u=info->uids.next; u; u = u2)
729
1.65k
    {
730
1.65k
      u2 = u->next;
731
1.65k
      xfree (u);
732
1.65k
    }
733
1.82k
}
734
735
736
gpg_error_t
737
kbx_get_first_opgp_keyid (const void *buffer, size_t len, u32 *kid)
738
0
{
739
0
  struct _keybox_openpgp_info info;
740
0
  gpg_error_t err;
741
742
0
  err = _keybox_parse_openpgp (buffer, len, 1 /*only primary*/, NULL, &info);
743
0
  if (err)
744
0
    return err;
745
746
0
  kid[0] = buf32_to_u32 (info.primary.keyid);
747
0
  kid[1] = buf32_to_u32 (info.primary.keyid+4);
748
0
  _keybox_destroy_openpgp_info (&info);
749
0
  return 0;
750
0
}