Coverage Report

Created: 2026-02-26 06:54

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
6.64M
{
69
6.64M
  const unsigned char *buf = *bufptr;
70
6.64M
  size_t len = *buflen;
71
6.64M
  int c, ctb, pkttype;
72
6.64M
  unsigned long pktlen;
73
74
6.64M
  if (!len)
75
0
    return gpg_error (GPG_ERR_NO_DATA);
76
77
6.64M
  ctb = *buf++; len--;
78
6.64M
  if ( !(ctb & 0x80) )
79
0
    return gpg_error (GPG_ERR_INV_PACKET); /* Invalid CTB. */
80
81
6.64M
  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
6.64M
  else /* Old style CTB.  */
111
6.64M
    {
112
6.64M
      int lenbytes;
113
114
6.64M
      pktlen = 0;
115
6.64M
      pkttype = (ctb>>2)&0xf;
116
6.64M
      lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3));
117
6.64M
      if (!lenbytes) /* Not allowed in key packets.  */
118
0
        return gpg_error (GPG_ERR_UNEXPECTED);
119
6.64M
      if (len < lenbytes)
120
0
        return gpg_error (GPG_ERR_INV_PACKET); /* Not enough length bytes.  */
121
13.3M
      for (; lenbytes; lenbytes--)
122
6.65M
        {
123
6.65M
          pktlen <<= 8;
124
6.65M
          pktlen |= *buf++; len--;
125
6.65M
  }
126
6.64M
    }
127
128
  /* Do some basic sanity check.  */
129
6.64M
  switch (pkttype)
130
6.64M
    {
131
3.24M
    case PKT_SIGNATURE:
132
3.24M
    case PKT_SECRET_KEY:
133
3.24M
    case PKT_PUBLIC_KEY:
134
3.24M
    case PKT_SECRET_SUBKEY:
135
3.24M
    case PKT_MARKER:
136
6.49M
    case PKT_RING_TRUST:
137
6.50M
    case PKT_USER_ID:
138
6.64M
    case PKT_PUBLIC_SUBKEY:
139
6.64M
    case PKT_OLD_COMMENT:
140
6.64M
    case PKT_ATTRIBUTE:
141
6.64M
    case PKT_COMMENT:
142
6.64M
    case PKT_GPG_CONTROL:
143
6.64M
      break; /* Okay these are allowed packets. */
144
0
    default:
145
0
      return gpg_error (GPG_ERR_UNEXPECTED);
146
6.64M
    }
147
148
6.64M
  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
6.64M
  if (pktlen > len)
159
0
    return gpg_error (GPG_ERR_INV_PACKET); /* Packet length header too long. */
160
161
6.64M
  *r_data = buf;
162
6.64M
  *r_datalen = pktlen;
163
6.64M
  *r_pkttype = pkttype;
164
6.64M
  *r_ntotal = (buf - *bufptr) + pktlen;
165
166
6.64M
  *bufptr = buf + pktlen;
167
6.64M
  *buflen = len - pktlen;
168
6.64M
  if (!*buflen)
169
2.20k
    *bufptr = NULL;
170
171
6.64M
  return 0;
172
6.64M
}
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
148k
{
181
148k
  gpg_error_t err;
182
148k
  gcry_sexp_t s_pkey = NULL;
183
184
148k
  switch (algo)
185
148k
    {
186
9
    case PUBKEY_ALGO_DSA:
187
9
      err = gcry_sexp_build (&s_pkey, NULL,
188
9
                             "(public-key(dsa(p%b)(q%b)(g%b)(y%b)))",
189
9
                             kp[0].len, kp[0].mpi,
190
9
                             kp[1].len, kp[1].mpi,
191
9
                             kp[2].len, kp[2].mpi,
192
9
                             kp[3].len, kp[3].mpi);
193
9
      break;
194
195
0
    case PUBKEY_ALGO_ELGAMAL:
196
3
    case PUBKEY_ALGO_ELGAMAL_E:
197
3
      err = gcry_sexp_build (&s_pkey, NULL,
198
3
                             "(public-key(elg(p%b)(g%b)(y%b)))",
199
3
                             kp[0].len, kp[0].mpi,
200
3
                             kp[1].len, kp[1].mpi,
201
3
                             kp[2].len, kp[2].mpi);
202
3
      break;
203
204
220
    case PUBKEY_ALGO_RSA:
205
220
    case PUBKEY_ALGO_RSA_S:
206
220
    case PUBKEY_ALGO_RSA_E:
207
220
      err = gcry_sexp_build (&s_pkey, NULL,
208
220
                             "(public-key(rsa(n%b)(e%b)))",
209
220
                             kp[0].len, kp[0].mpi,
210
220
                             kp[1].len, kp[1].mpi);
211
220
      break;
212
213
2.03k
    case PUBKEY_ALGO_EDDSA:
214
2.07k
    case PUBKEY_ALGO_ECDSA:
215
148k
    case PUBKEY_ALGO_ECDH:
216
148k
      {
217
148k
        char *curve = openpgp_oidbuf_to_str (kp[0].mpi, kp[0].len);
218
148k
        if (!curve)
219
0
          err = gpg_error_from_syserror ();
220
148k
        else
221
148k
          {
222
148k
            err = gcry_sexp_build
223
148k
              (&s_pkey, NULL,
224
148k
               (algo == PUBKEY_ALGO_EDDSA)?
225
2.03k
               "(public-key(ecc(curve%s)(flags eddsa)(q%b)))":
226
148k
               (algo == PUBKEY_ALGO_ECDH
227
146k
                && openpgp_oidbuf_is_cv25519 (kp[0].mpi, kp[0].len))?
228
145k
               "(public-key(ecc(curve%s)(flags djb-tweak)(q%b)))":
229
146k
               "(public-key(ecc(curve%s)(q%b)))",
230
148k
               curve, kp[1].len, kp[1].mpi);
231
148k
            xfree (curve);
232
148k
          }
233
148k
      }
234
148k
      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
148k
    }
260
261
148k
  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
148k
  gcry_sexp_release (s_pkey);
276
277
148k
  if (err)
278
0
    memset (grip, 0, 20);
279
148k
  return err;
280
148k
}
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
148k
{
288
148k
  gpg_error_t err;
289
148k
  const unsigned char *data_start = data;
290
148k
  int i, version, algorithm;
291
148k
  size_t n;
292
148k
  int npkey;
293
148k
  unsigned char hashbuffer[768];
294
148k
  gcry_md_hd_t md;
295
148k
  int is_ecc = 0;
296
148k
  int is_kyber = 0;
297
148k
  int is_v5;
298
  /* unsigned int pkbytes;  for v5: # of octets of the public key params.  */
299
148k
  struct keyparm_s keyparm[OPENPGP_MAX_NPKEY];
300
148k
  unsigned char *helpmpibuf[OPENPGP_MAX_NPKEY] = { NULL };
301
302
148k
  if (datalen < 5)
303
0
    return gpg_error (GPG_ERR_INV_PACKET);
304
148k
  version = *data++; datalen--;
305
148k
  if (version < 2 || version > 5 )
306
0
    return gpg_error (GPG_ERR_INV_PACKET); /* Invalid version. */
307
148k
  is_v5 = version == 5;
308
309
  /*timestamp = ((data[0]<<24)|(data[1]<<16)|(data[2]<<8)|(data[3]));*/
310
148k
  data +=4; datalen -=4;
311
312
148k
  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
148k
  if (!datalen)
320
0
    return gpg_error (GPG_ERR_INV_PACKET);
321
148k
  algorithm = *data++; datalen--;
322
323
148k
  if (is_v5)
324
2
    {
325
2
      if (datalen < 4)
326
0
        return gpg_error (GPG_ERR_INV_PACKET);
327
      /* pkbytes = buf32_to_uint (data); */
328
2
      data += 4;
329
2
      datalen -= 4;
330
2
    }
331
332
148k
  switch (algorithm)
333
148k
    {
334
220
    case PUBKEY_ALGO_RSA:
335
220
    case PUBKEY_ALGO_RSA_E:
336
220
    case PUBKEY_ALGO_RSA_S:
337
220
      npkey = 2;
338
220
      break;
339
3
    case PUBKEY_ALGO_ELGAMAL_E:
340
3
    case PUBKEY_ALGO_ELGAMAL:
341
3
      npkey = 3;
342
3
      break;
343
9
    case PUBKEY_ALGO_DSA:
344
9
      npkey = 4;
345
9
      break;
346
146k
    case PUBKEY_ALGO_ECDH:
347
146k
      npkey = 3;
348
146k
      is_ecc = 1;
349
146k
      break;
350
42
    case PUBKEY_ALGO_ECDSA:
351
2.07k
    case PUBKEY_ALGO_EDDSA:
352
2.07k
      npkey = 2;
353
2.07k
      is_ecc = 1;
354
2.07k
      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
148k
    }
362
363
148k
  ki->version = version;
364
148k
  ki->algo = algorithm;
365
366
590k
  for (i=0; i < npkey; i++ )
367
442k
    {
368
442k
      unsigned int nbits, nbytes;
369
370
442k
      if (datalen < 2)
371
0
        return gpg_error (GPG_ERR_INV_PACKET);
372
373
442k
      if ((is_ecc && (i == 0 || i == 2))
374
148k
          || (is_kyber && i == 0 ))
375
294k
        {
376
294k
          nbytes = data[0];
377
294k
          if (nbytes < 2 || nbytes > 254)
378
0
            return gpg_error (GPG_ERR_INV_PACKET);
379
294k
          nbytes++; /* The size byte itself.  */
380
294k
          if (datalen < nbytes)
381
0
            return gpg_error (GPG_ERR_INV_PACKET);
382
383
294k
          keyparm[i].mpi = data;
384
294k
          keyparm[i].len = nbytes;
385
294k
        }
386
148k
      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
148k
      else
401
148k
        {
402
148k
          nbits = ((data[0]<<8)|(data[1]));
403
148k
          data += 2;
404
148k
          datalen -= 2;
405
148k
          nbytes = (nbits+7) / 8;
406
148k
          if (datalen < nbytes)
407
0
            return gpg_error (GPG_ERR_INV_PACKET);
408
409
148k
          keyparm[i].mpi = data;
410
148k
          keyparm[i].len = nbytes;
411
148k
        }
412
413
442k
      data += nbytes; datalen -= nbytes;
414
442k
    }
415
148k
  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
148k
  if (!is_ecc && !is_kyber)
422
717
    for (i=0; i < npkey; i++)
423
485
      {
424
485
        if (!keyparm[i].len || (keyparm[i].mpi[0] & 0x80))
425
245
          {
426
245
            helpmpibuf[i] = xtrymalloc (1+keyparm[i].len);
427
245
            if (!helpmpibuf[i])
428
0
              {
429
0
                err = gpg_error_from_syserror ();
430
0
                goto leave;
431
0
              }
432
245
            helpmpibuf[i][0] = 0;
433
245
            memcpy (helpmpibuf[i]+1, keyparm[i].mpi, keyparm[i].len);
434
245
            keyparm[i].mpi = helpmpibuf[i];
435
245
            keyparm[i].len++;
436
245
          }
437
485
      }
438
439
148k
  err = keygrip_from_keyparm (algorithm, keyparm, ki->grip);
440
148k
  if (err)
441
0
    goto leave;
442
443
148k
  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
148k
  else
469
148k
    {
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
148k
      if (version == 5)
480
2
        {
481
2
          if (5 + n < sizeof hashbuffer )
482
2
            {
483
2
              hashbuffer[0] = 0x9a;     /* CTB */
484
2
              hashbuffer[1] = (n >> 24);/* 4 byte length header. */
485
2
              hashbuffer[2] = (n >> 16);
486
2
              hashbuffer[3] = (n >>  8);
487
2
              hashbuffer[4] = (n      );
488
2
              memcpy (hashbuffer + 5, data_start, n);
489
2
              gcry_md_hash_buffer (GCRY_MD_SHA256, ki->fpr, hashbuffer, 5 + n);
490
2
            }
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
2
          ki->fprlen = 32;
506
2
          memcpy (ki->keyid, ki->fpr, 8);
507
2
        }
508
148k
      else
509
148k
        {
510
148k
          if ( 3 + n < sizeof hashbuffer )
511
148k
            {
512
148k
              hashbuffer[0] = 0x99;     /* CTB */
513
148k
              hashbuffer[1] = (n >> 8); /* 2 byte length header. */
514
148k
              hashbuffer[2] = (n     );
515
148k
              memcpy (hashbuffer + 3, data_start, n);
516
148k
              gcry_md_hash_buffer (GCRY_MD_SHA1, ki->fpr, hashbuffer, 3 + n);
517
148k
            }
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
148k
          ki->fprlen = 20;
531
148k
          memcpy (ki->keyid, ki->fpr+12, 8);
532
148k
        }
533
148k
    }
534
535
148k
 leave:
536
590k
  for (i=0; i < npkey; i++)
537
442k
    xfree (helpmpibuf[i]);
538
539
148k
  return err;
540
148k
}
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
2.20k
{
556
2.20k
  gpg_error_t err = 0;
557
2.20k
  const unsigned char *image_start, *data;
558
2.20k
  size_t n, datalen;
559
2.20k
  int pkttype;
560
2.20k
  int first = 1;
561
2.20k
  int read_error = 0;
562
2.20k
  struct _keybox_openpgp_key_info *k, **ktail = NULL;
563
2.20k
  struct _keybox_openpgp_uid_info *u, **utail = NULL;
564
565
2.20k
  memset (info, 0, sizeof *info);
566
2.20k
  if (nparsed)
567
2.20k
    *nparsed = 0;
568
569
2.20k
  image_start = image;
570
6.65M
  while (image)
571
6.64M
    {
572
6.64M
      err = next_packet (&image, &imagelen, &data, &datalen, &pkttype, &n);
573
6.64M
      if (err)
574
0
        {
575
0
          read_error = 1;
576
0
          break;
577
0
        }
578
579
6.64M
      if (first)
580
2.20k
        {
581
2.20k
          if (pkttype == PKT_PUBLIC_KEY)
582
2.20k
            ;
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
2.20k
          first = 0;
593
2.20k
        }
594
6.64M
      else if (pkttype == PKT_PUBLIC_KEY || pkttype == PKT_SECRET_KEY)
595
0
        break; /* Next keyblock encountered - ready. */
596
597
6.64M
      if (nparsed)
598
6.64M
        *nparsed += n;
599
600
6.64M
      if (pkttype == PKT_SIGNATURE)
601
3.24M
        {
602
          /* For now we only count the total number of signatures. */
603
3.24M
          info->nsigs++;
604
3.24M
        }
605
3.40M
      else if (pkttype == PKT_USER_ID)
606
4.16k
        {
607
4.16k
          info->nuids++;
608
4.16k
          if (info->nuids == 1)
609
2.20k
            {
610
2.20k
              info->uids.off = data - image_start;
611
2.20k
              info->uids.len = datalen;
612
2.20k
              utail = &info->uids.next;
613
2.20k
            }
614
1.95k
          else
615
1.95k
            {
616
1.95k
              u = xtrycalloc (1, sizeof *u);
617
1.95k
              if (!u)
618
0
                {
619
0
                  err = gpg_error_from_syserror ();
620
0
                  break;
621
0
                }
622
1.95k
              u->off = data - image_start;
623
1.95k
              u->len = datalen;
624
1.95k
              *utail = u;
625
1.95k
              utail = &u->next;
626
1.95k
            }
627
4.16k
        }
628
3.39M
      else if (pkttype == PKT_PUBLIC_KEY || pkttype == PKT_SECRET_KEY)
629
2.20k
        {
630
2.20k
          err = parse_key (data, datalen, &info->primary);
631
2.20k
          if (err || only_primary)
632
0
            break;
633
2.20k
        }
634
3.39M
      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
3.39M
      else if (pkttype == PKT_PUBLIC_SUBKEY || pkttype == PKT_SECRET_SUBKEY)
641
146k
        {
642
146k
          info->nsubkeys++;
643
146k
          if (info->nsubkeys == 1)
644
1.95k
            {
645
1.95k
              err = parse_key (data, datalen, &info->subkeys);
646
1.95k
              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.95k
              else
657
1.95k
                ktail = &info->subkeys.next;
658
1.95k
            }
659
144k
          else
660
144k
            {
661
144k
              k = xtrycalloc (1, sizeof *k);
662
144k
              if (!k)
663
0
                {
664
0
                  err = gpg_error_from_syserror ();
665
0
                  break;
666
0
                }
667
144k
              err = parse_key (data, datalen, k);
668
144k
              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
144k
              else
680
144k
                {
681
144k
                  *ktail = k;
682
144k
                  ktail = &k->next;
683
144k
                }
684
144k
            }
685
146k
        }
686
6.64M
    }
687
688
2.20k
  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
2.20k
  return err;
711
2.20k
}
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
2.20k
{
718
2.20k
  struct _keybox_openpgp_key_info *k, *k2;
719
2.20k
  struct _keybox_openpgp_uid_info *u, *u2;
720
721
2.20k
  log_assert (!info->primary.next);
722
146k
  for (k=info->subkeys.next; k; k = k2)
723
144k
    {
724
144k
      k2 = k->next;
725
144k
      xfree (k);
726
144k
    }
727
728
4.16k
  for (u=info->uids.next; u; u = u2)
729
1.95k
    {
730
1.95k
      u2 = u->next;
731
1.95k
      xfree (u);
732
1.95k
    }
733
2.20k
}
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
}