Coverage Report

Created: 2025-12-14 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gnupg/g10/free-packet.c
Line
Count
Source
1
/* free-packet.c - cleanup stuff for packets
2
 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
3
 *               2005, 2010  Free Software Foundation, Inc.
4
 *
5
 * This file is part of GnuPG.
6
 *
7
 * GnuPG is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * GnuPG is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, see <https://www.gnu.org/licenses/>.
19
 */
20
21
#include <config.h>
22
#include <stdio.h>
23
#include <stdlib.h>
24
#include <string.h>
25
26
#include "gpg.h"
27
#include "../common/util.h"
28
#include "packet.h"
29
#include "../common/iobuf.h"
30
#include "options.h"
31
32
33
/* This is a wrapper for mpi_copy which handles opaque MPIs with a
34
 * NULL pointer as opaque data; e.g. gcry_mpi_set_opaque(a, NULL, 0).
35
 * It seems that at least gcry_mpi_set_opaque_copy does not yet handle
36
 * this correctly.  */
37
static gcry_mpi_t
38
my_mpi_copy (gcry_mpi_t a)
39
11.8k
{
40
11.8k
  if (a
41
11.3k
      && gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)
42
4.82k
      && !gcry_mpi_get_opaque (a, NULL))
43
69
    return NULL;
44
45
11.7k
  return gcry_mpi_copy (a);
46
11.8k
}
47
48
49
void
50
free_symkey_enc( PKT_symkey_enc *enc )
51
5.15k
{
52
5.15k
  if (enc)
53
5.15k
    xfree (enc->seskey);
54
5.15k
  xfree(enc);
55
5.15k
}
56
57
58
/* This is the core of free_pubkey_enc but does only release the
59
 * allocated members of ENC.  */
60
void
61
release_pubkey_enc_parts (PKT_pubkey_enc *enc)
62
14.4k
{
63
14.4k
  int n, i;
64
14.4k
  n = pubkey_get_nenc( enc->pubkey_algo );
65
14.4k
  if (!n)
66
14.4k
    mpi_release (enc->data[0]);
67
22.2k
  for (i=0; i < n; i++ )
68
14.4k
    mpi_release (enc->data[i]);
69
14.4k
}
70
71
void
72
free_pubkey_enc (PKT_pubkey_enc *enc)
73
13.5k
{
74
13.5k
  release_pubkey_enc_parts (enc);
75
13.5k
  xfree (enc);
76
13.5k
}
77
78
79
/* Copy everything from SRC to DST.  This assumes that DST has been
80
 * malloced or statically allocated. */
81
void
82
copy_pubkey_enc_parts (PKT_pubkey_enc *dst, PKT_pubkey_enc *src)
83
927
{
84
927
  int n, i;
85
86
927
  dst->keyid[0] = src->keyid[0];
87
927
  dst->keyid[1] = src->keyid[1];
88
927
  dst->version  = src->version;
89
927
  dst->pubkey_algo = src->pubkey_algo;
90
927
  dst->seskey_algo = src->seskey_algo;
91
927
  dst->throw_keyid = src->throw_keyid;
92
93
927
  if (!(n = pubkey_get_nenc (dst->pubkey_algo)))
94
463
    n = 1;  /* All data is in the first item as an opaque MPI. */
95
1.90k
  for (i=0; i < n; i++)
96
981
    dst->data[i] = my_mpi_copy (src->data[i]);
97
3.65k
  for (; i < PUBKEY_MAX_NENC; i++)
98
2.72k
    dst->data[i] = NULL;
99
927
}
100
101
102
void
103
free_seckey_enc( PKT_signature *sig )
104
8.43M
{
105
8.43M
  int n, i;
106
107
8.43M
  n = pubkey_get_nsig( sig->pubkey_algo );
108
8.43M
  if( !n )
109
8.43M
    mpi_release(sig->data[0]);
110
24.1M
  for(i=0; i < n; i++ )
111
15.7M
    mpi_release( sig->data[i] );
112
113
8.43M
  xfree(sig->revkey);
114
8.43M
  xfree(sig->hashed);
115
8.43M
  xfree(sig->unhashed);
116
117
8.43M
  xfree (sig->signers_uid);
118
119
8.43M
  xfree(sig);
120
8.43M
}
121
122
123
void
124
release_public_key_parts (PKT_public_key *pk)
125
555k
{
126
555k
  int n, i;
127
128
555k
  if (pk->seckey_info)
129
39.9k
    n = pubkey_get_nskey (pk->pubkey_algo);
130
515k
  else
131
515k
    n = pubkey_get_npkey (pk->pubkey_algo);
132
555k
  if (!n)
133
555k
    mpi_release (pk->pkey[0]);
134
2.18M
  for (i=0; i < n; i++ )
135
1.63M
    {
136
1.63M
      mpi_release (pk->pkey[i]);
137
1.63M
      pk->pkey[i] = NULL;
138
1.63M
    }
139
555k
  if (pk->seckey_info)
140
39.9k
    {
141
39.9k
      xfree (pk->seckey_info);
142
39.9k
      pk->seckey_info = NULL;
143
39.9k
    }
144
555k
  if (pk->prefs)
145
1.54k
    {
146
1.54k
      xfree (pk->prefs);
147
1.54k
      pk->prefs = NULL;
148
1.54k
    }
149
555k
  free_user_id (pk->user_id);
150
555k
  pk->user_id = NULL;
151
555k
  if (pk->revkey)
152
3
    {
153
3
      xfree(pk->revkey);
154
3
      pk->revkey=NULL;
155
3
      pk->numrevkeys=0;
156
3
    }
157
555k
  if (pk->serialno)
158
0
    {
159
0
      xfree (pk->serialno);
160
0
      pk->serialno = NULL;
161
0
    }
162
555k
  if (pk->updateurl)
163
24
    {
164
24
      xfree (pk->updateurl);
165
24
      pk->updateurl = NULL;
166
24
    }
167
555k
  if (pk->revoked.reason_comment)
168
0
    {
169
0
      xfree (pk->revoked.reason_comment);
170
0
      pk->revoked.reason_comment = NULL;
171
0
    }
172
555k
}
173
174
175
/* Free an allocated public key structure including all parts.
176
   Passing NULL is allowed.  */
177
void
178
free_public_key (PKT_public_key *pk)
179
653k
{
180
653k
  if (pk)
181
555k
    {
182
555k
      release_public_key_parts (pk);
183
555k
      xfree(pk);
184
555k
    }
185
653k
}
186
187
188
static subpktarea_t *
189
cp_subpktarea (subpktarea_t *s )
190
3.17k
{
191
3.17k
    subpktarea_t *d;
192
193
3.17k
    if( !s )
194
2.78k
  return NULL;
195
388
    d = xmalloc (sizeof (*d) + s->size - 1 );
196
388
    d->size = s->size;
197
388
    d->len = s->len;
198
388
    memcpy (d->data, s->data, s->len);
199
388
    return d;
200
3.17k
}
201
202
/*
203
 * Return a copy of the preferences
204
 */
205
prefitem_t *
206
copy_prefs (const prefitem_t *prefs)
207
55.9k
{
208
55.9k
    size_t n;
209
55.9k
    prefitem_t *new;
210
211
55.9k
    if (!prefs)
212
54.4k
        return NULL;
213
214
17.3k
    for (n=0; prefs[n].type; n++)
215
15.7k
        ;
216
1.54k
    new = xmalloc ( sizeof (*new) * (n+1));
217
17.3k
    for (n=0; prefs[n].type; n++) {
218
15.7k
        new[n].type = prefs[n].type;
219
15.7k
        new[n].value = prefs[n].value;
220
15.7k
    }
221
1.54k
    new[n].type = PREFTYPE_NONE;
222
1.54k
    new[n].value = 0;
223
224
1.54k
    return new;
225
55.9k
}
226
227
228
/* Copy the public key S to D.  If D is NULL allocate a new public key
229
 * structure.  Only the basic stuff is copied; not any ancillary
230
 * data.  */
231
PKT_public_key *
232
copy_public_key_basics (PKT_public_key *d, PKT_public_key *s)
233
3.67k
{
234
3.67k
  int n, i;
235
236
3.67k
  if (!d)
237
1.70k
    d = xmalloc (sizeof *d);
238
3.67k
  memcpy (d, s, sizeof *d);
239
3.67k
  d->seckey_info = NULL;
240
3.67k
  d->user_id = NULL;
241
3.67k
  d->prefs = NULL;
242
3.67k
  d->revoked.got_reason = 0;
243
3.67k
  d->revoked.reason_code = 0;
244
3.67k
  d->revoked.reason_comment = NULL;
245
3.67k
  d->revoked.reason_comment_len = 0;
246
247
3.67k
  n = pubkey_get_npkey (s->pubkey_algo);
248
3.67k
  i = 0;
249
3.67k
  if (!n)
250
209
    d->pkey[i++] = my_mpi_copy (s->pkey[0]);
251
3.46k
  else
252
3.46k
    {
253
11.8k
      for (; i < n; i++ )
254
8.39k
        d->pkey[i] = my_mpi_copy (s->pkey[i]);
255
3.46k
    }
256
20.7k
  for (; i < PUBKEY_MAX_NSKEY; i++)
257
17.0k
    d->pkey[i] = NULL;
258
259
3.67k
  d->revkey = NULL;
260
3.67k
  d->serialno = NULL;
261
3.67k
  d->updateurl = NULL;
262
263
3.67k
  return d;
264
3.67k
}
265
266
267
/* Copy the public key S to D.  If D is NULL allocate a new public key
268
   structure.  If S has seckret key infos, only the public stuff is
269
   copied.  */
270
PKT_public_key *
271
copy_public_key (PKT_public_key *d, PKT_public_key *s)
272
3.67k
{
273
3.67k
  d = copy_public_key_basics (d, s);
274
3.67k
  d->user_id = scopy_user_id (s->user_id);
275
3.67k
  d->prefs = copy_prefs (s->prefs);
276
277
3.67k
  if (!s->revkey && s->numrevkeys)
278
0
    BUG();
279
3.67k
  if (s->numrevkeys)
280
0
    {
281
0
      d->revkey = xmalloc(sizeof(struct revocation_key)*s->numrevkeys);
282
0
      memcpy(d->revkey,s->revkey,sizeof(struct revocation_key)*s->numrevkeys);
283
0
    }
284
285
3.67k
  if (s->serialno)
286
0
    d->serialno = xstrdup (s->serialno);
287
3.67k
  if (s->updateurl)
288
0
    d->updateurl = xstrdup (s->updateurl);
289
3.67k
  if (s->revoked.got_reason)
290
161
    {
291
161
      d->revoked.got_reason = s->revoked.got_reason;
292
161
      d->revoked.reason_code = s->revoked.reason_code;
293
161
      if (s->revoked.reason_comment_len)
294
0
        {
295
0
          d->revoked.reason_comment = xmalloc (s->revoked.reason_comment_len);
296
0
          memcpy (d->revoked.reason_comment, s->revoked.reason_comment,
297
0
                  s->revoked.reason_comment_len);
298
0
          d->revoked.reason_comment_len = s->revoked.reason_comment_len;
299
0
        }
300
161
    }
301
302
3.67k
  return d;
303
3.67k
}
304
305
306
307
PKT_signature *
308
copy_signature( PKT_signature *d, PKT_signature *s )
309
1.58k
{
310
1.58k
    int n, i;
311
312
1.58k
    if( !d )
313
1.58k
  d = xmalloc(sizeof *d);
314
1.58k
    memcpy( d, s, sizeof *d );
315
1.58k
    n = pubkey_get_nsig( s->pubkey_algo );
316
1.58k
    if( !n )
317
800
  d->data[0] = my_mpi_copy(s->data[0]);
318
787
    else {
319
2.24k
  for(i=0; i < n; i++ )
320
1.45k
      d->data[i] = my_mpi_copy( s->data[i] );
321
787
    }
322
1.58k
    d->hashed = cp_subpktarea (s->hashed);
323
1.58k
    d->unhashed = cp_subpktarea (s->unhashed);
324
1.58k
    if (s->signers_uid)
325
0
      d->signers_uid = xstrdup (s->signers_uid);
326
1.58k
    if(s->numrevkeys)
327
0
      {
328
0
  d->revkey=NULL;
329
0
  d->numrevkeys=0;
330
0
  parse_revkeys(d);
331
0
      }
332
1.58k
    return d;
333
1.58k
}
334
335
336
/*
337
 * shallow copy of the user ID
338
 */
339
PKT_user_id *
340
scopy_user_id (PKT_user_id *s)
341
5.76k
{
342
5.76k
    if (s)
343
0
        s->ref++;
344
5.76k
    return s;
345
5.76k
}
346
347
348
349
void
350
free_comment( PKT_comment *rem )
351
759
{
352
759
    xfree(rem);
353
759
}
354
355
void
356
free_attributes(PKT_user_id *uid)
357
52.6k
{
358
52.6k
  if (!uid)
359
0
    return;
360
361
52.6k
  xfree(uid->attribs);
362
52.6k
  xfree(uid->attrib_data);
363
364
52.6k
  uid->attribs=NULL;
365
52.6k
  uid->attrib_data=NULL;
366
52.6k
  uid->attrib_len=0;
367
52.6k
}
368
369
void
370
free_user_id (PKT_user_id *uid)
371
610k
{
372
610k
  if (!uid)
373
557k
    return;
374
375
610k
  log_assert (uid->ref > 0);
376
52.6k
  if (--uid->ref)
377
0
    return;
378
379
52.6k
  free_attributes(uid);
380
52.6k
  xfree (uid->prefs);
381
52.6k
  xfree (uid->namehash);
382
52.6k
  xfree (uid->updateurl);
383
52.6k
  xfree (uid->mbox);
384
52.6k
  xfree (uid);
385
52.6k
}
386
387
void
388
free_compressed( PKT_compressed *zd )
389
303k
{
390
303k
  if (!zd)
391
0
    return;
392
393
303k
  if (zd->buf)
394
995
    {
395
      /* We need to skip some bytes.  Because don't have any
396
       * information about the length, so we assume this is the last
397
       * packet */
398
1.57k
      while (iobuf_read( zd->buf, NULL, 1<<30 ) != -1)
399
583
        ;
400
995
    }
401
303k
  xfree(zd);
402
303k
}
403
404
void
405
free_encrypted( PKT_encrypted *ed )
406
10.4k
{
407
10.4k
  if (!ed)
408
0
    return;
409
410
10.4k
  if (ed->buf)
411
7.01k
    {
412
      /* We need to skip some bytes. */
413
7.01k
      if (ed->is_partial)
414
2.84k
        {
415
3.06k
          while (iobuf_read( ed->buf, NULL, 1<<30 ) != -1)
416
218
            ;
417
2.84k
  }
418
4.17k
      else
419
4.17k
        {
420
4.92k
          while (ed->len)
421
749
            {
422
              /* Skip the packet. */
423
749
              int n = iobuf_read( ed->buf, NULL, ed->len );
424
749
              if (n == -1)
425
416
                ed->len = 0;
426
333
              else
427
333
                ed->len -= n;
428
749
            }
429
4.17k
  }
430
7.01k
    }
431
10.4k
  xfree (ed);
432
10.4k
}
433
434
435
void
436
free_plaintext( PKT_plaintext *pt )
437
98.1k
{
438
98.1k
  if (!pt)
439
0
    return;
440
441
98.1k
  if (pt->buf)
442
97.4k
    { /* We need to skip some bytes.  */
443
97.4k
      if (pt->is_partial)
444
2.67k
        {
445
3.73k
          while (iobuf_read( pt->buf, NULL, 1<<30 ) != -1)
446
1.05k
            ;
447
2.67k
        }
448
94.7k
      else
449
94.7k
        {
450
144k
          while( pt->len )
451
49.9k
            { /* Skip the packet.  */
452
49.9k
              int n = iobuf_read( pt->buf, NULL, pt->len );
453
49.9k
              if (n == -1)
454
13.2k
                pt->len = 0;
455
36.7k
              else
456
36.7k
                pt->len -= n;
457
49.9k
            }
458
94.7k
  }
459
97.4k
    }
460
98.1k
  xfree (pt);
461
98.1k
}
462
463
464
/****************
465
 * Free the packet in PKT.
466
 */
467
void
468
free_packet (PACKET *pkt, parse_packet_ctx_t parsectx)
469
27.8M
{
470
27.8M
  if (!pkt || !pkt->pkt.generic)
471
18.2M
    {
472
18.2M
      if (parsectx && parsectx->last_pkt.pkt.generic)
473
8.48M
        {
474
8.48M
          if (parsectx->free_last_pkt)
475
12.4k
            {
476
12.4k
              free_packet (&parsectx->last_pkt, NULL);
477
12.4k
              parsectx->free_last_pkt = 0;
478
12.4k
            }
479
8.48M
          parsectx->last_pkt.pkttype = 0;
480
8.48M
          parsectx->last_pkt.pkt.generic = NULL;
481
8.48M
        }
482
18.2M
      return;
483
18.2M
    }
484
485
9.61M
  if (DBG_MEMORY)
486
9.61M
    log_debug ("free_packet() type=%d\n", pkt->pkttype);
487
488
  /* If we have a parser context holding PKT then do not free the
489
   * packet but set a flag that the packet in the parser context is
490
   * now a deep copy.  */
491
9.61M
  if (parsectx && !parsectx->free_last_pkt
492
140k
      && parsectx->last_pkt.pkttype == pkt->pkttype
493
12.4k
      && parsectx->last_pkt.pkt.generic == pkt->pkt.generic)
494
12.4k
    {
495
12.4k
      parsectx->last_pkt = *pkt;
496
12.4k
      parsectx->free_last_pkt = 1;
497
12.4k
      pkt->pkt.generic = NULL;
498
12.4k
      return;
499
12.4k
    }
500
501
9.59M
  switch (pkt->pkttype)
502
9.59M
    {
503
8.43M
    case PKT_SIGNATURE:
504
8.43M
      free_seckey_enc (pkt->pkt.signature);
505
8.43M
      break;
506
13.5k
    case PKT_PUBKEY_ENC:
507
13.5k
      free_pubkey_enc (pkt->pkt.pubkey_enc);
508
13.5k
      break;
509
5.15k
    case PKT_SYMKEY_ENC:
510
5.15k
      free_symkey_enc (pkt->pkt.symkey_enc);
511
5.15k
      break;
512
18.4k
    case PKT_PUBLIC_KEY:
513
466k
    case PKT_PUBLIC_SUBKEY:
514
488k
    case PKT_SECRET_KEY:
515
542k
    case PKT_SECRET_SUBKEY:
516
542k
      free_public_key (pkt->pkt.public_key);
517
542k
      break;
518
759
    case PKT_COMMENT:
519
759
      free_comment (pkt->pkt.comment);
520
759
      break;
521
52.6k
    case PKT_USER_ID:
522
52.6k
      free_user_id (pkt->pkt.user_id);
523
52.6k
      break;
524
303k
    case PKT_COMPRESSED:
525
303k
      free_compressed (pkt->pkt.compressed);
526
303k
      break;
527
3.35k
    case PKT_ENCRYPTED:
528
7.17k
    case PKT_ENCRYPTED_MDC:
529
10.4k
    case PKT_ENCRYPTED_AEAD:
530
10.4k
      free_encrypted (pkt->pkt.encrypted);
531
10.4k
      break;
532
98.1k
    case PKT_PLAINTEXT:
533
98.1k
      free_plaintext (pkt->pkt.plaintext);
534
98.1k
      break;
535
138k
    default:
536
138k
      xfree (pkt->pkt.generic);
537
138k
      break;
538
9.59M
    }
539
540
9.59M
  pkt->pkt.generic = NULL;
541
9.59M
}
542
543
544
/* Free an entire list of public or symmetric key encrypted data.  */
545
void
546
free_seskey_enc_list (struct seskey_enc_list *sesenc_list)
547
320k
{
548
321k
  while (sesenc_list)
549
927
    {
550
927
      struct seskey_enc_list *tmp = sesenc_list->next;
551
552
927
      if (!sesenc_list->u_sym)
553
927
        release_pubkey_enc_parts (&sesenc_list->u.pub);
554
927
      xfree (sesenc_list);
555
927
      sesenc_list = tmp;
556
927
    }
557
320k
}
558
559
560
/****************
561
 * returns 0 if they match.
562
 */
563
int
564
cmp_public_keys( PKT_public_key *a, PKT_public_key *b )
565
49.4k
{
566
49.4k
    int n, i;
567
568
49.4k
    if( a->timestamp != b->timestamp )
569
243
  return -1;
570
49.2k
    if( a->version < 4 && a->expiredate != b->expiredate )
571
0
  return -1;
572
49.2k
    if( a->pubkey_algo != b->pubkey_algo )
573
0
  return -1;
574
575
49.2k
    n = pubkey_get_npkey( b->pubkey_algo );
576
49.2k
    if( !n ) { /* unknown algorithm, rest is in opaque MPI */
577
0
  if( mpi_cmp( a->pkey[0], b->pkey[0] ) )
578
0
      return -1; /* can't compare due to unknown algorithm */
579
49.2k
    } else {
580
118k
  for(i=0; i < n; i++ ) {
581
106k
      if( mpi_cmp( a->pkey[i], b->pkey[i] ) )
582
37.8k
    return -1;
583
106k
  }
584
49.2k
    }
585
586
11.3k
    return 0;
587
49.2k
}
588
589
590
591
int
592
cmp_signatures( PKT_signature *a, PKT_signature *b )
593
2.12M
{
594
2.12M
    int n, i;
595
596
2.12M
    if( a->keyid[0] != b->keyid[0] )
597
27.0k
  return -1;
598
2.10M
    if( a->keyid[1] != b->keyid[1] )
599
10.7k
  return -1;
600
2.09M
    if( a->pubkey_algo != b->pubkey_algo )
601
992
  return -1;
602
603
2.09M
    n = pubkey_get_nsig( a->pubkey_algo );
604
2.09M
    if( !n )
605
164
  return -1; /* can't compare due to unknown algorithm */
606
3.86M
    for(i=0; i < n; i++ ) {
607
3.86M
  if( mpi_cmp( a->data[i] , b->data[i] ) )
608
2.08M
      return -1;
609
3.86M
    }
610
584
    return 0;
611
2.09M
}
612
613
614
/****************
615
 * Returns: true if the user ids do not match
616
 */
617
int
618
cmp_user_ids( PKT_user_id *a, PKT_user_id *b )
619
11.2k
{
620
11.2k
    int res=1;
621
622
11.2k
    if( a == b )
623
0
        return 0;
624
625
11.2k
    if( a->attrib_data && b->attrib_data )
626
0
      {
627
0
  res = a->attrib_len - b->attrib_len;
628
0
  if( !res )
629
0
    res = memcmp( a->attrib_data, b->attrib_data, a->attrib_len );
630
0
      }
631
11.2k
    else if( !a->attrib_data && !b->attrib_data )
632
11.2k
      {
633
11.2k
  res = a->len - b->len;
634
11.2k
  if( !res )
635
6.11k
    res = memcmp( a->name, b->name, a->len );
636
11.2k
      }
637
638
11.2k
    return res;
639
11.2k
}