Coverage Report

Created: 2026-01-10 07:04

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
7.01k
{
40
7.01k
  if (a
41
1.00k
      && gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)
42
106
      && !gcry_mpi_get_opaque (a, NULL))
43
0
    return NULL;
44
45
7.01k
  return gcry_mpi_copy (a);
46
7.01k
}
47
48
49
void
50
free_symkey_enc( PKT_symkey_enc *enc )
51
11.6k
{
52
11.6k
  if (enc)
53
11.6k
    xfree (enc->seskey);
54
11.6k
  xfree(enc);
55
11.6k
}
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.0k
{
63
14.0k
  int n, i;
64
14.0k
  n = pubkey_get_nenc( enc->pubkey_algo );
65
14.0k
  if (!n)
66
14.0k
    mpi_release (enc->data[0]);
67
16.1k
  for (i=0; i < n; i++ )
68
14.0k
    mpi_release (enc->data[i]);
69
14.0k
}
70
71
void
72
free_pubkey_enc (PKT_pubkey_enc *enc)
73
7.09k
{
74
7.09k
  release_pubkey_enc_parts (enc);
75
7.09k
  xfree (enc);
76
7.09k
}
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
6.94k
{
84
6.94k
  int n, i;
85
86
6.94k
  dst->keyid[0] = src->keyid[0];
87
6.94k
  dst->keyid[1] = src->keyid[1];
88
6.94k
  dst->version  = src->version;
89
6.94k
  dst->pubkey_algo = src->pubkey_algo;
90
6.94k
  dst->seskey_algo = src->seskey_algo;
91
6.94k
  dst->throw_keyid = src->throw_keyid;
92
93
6.94k
  if (!(n = pubkey_get_nenc (dst->pubkey_algo)))
94
6.01k
    n = 1;  /* All data is in the first item as an opaque MPI. */
95
13.9k
  for (i=0; i < n; i++)
96
7.01k
    dst->data[i] = my_mpi_copy (src->data[i]);
97
27.7k
  for (; i < PUBKEY_MAX_NENC; i++)
98
20.7k
    dst->data[i] = NULL;
99
6.94k
}
100
101
102
void
103
free_seckey_enc( PKT_signature *sig )
104
24.5k
{
105
24.5k
  int n, i;
106
107
24.5k
  n = pubkey_get_nsig( sig->pubkey_algo );
108
24.5k
  if( !n )
109
24.5k
    mpi_release(sig->data[0]);
110
32.5k
  for(i=0; i < n; i++ )
111
24.5k
    mpi_release( sig->data[i] );
112
113
24.5k
  xfree(sig->revkey);
114
24.5k
  xfree(sig->hashed);
115
24.5k
  xfree(sig->unhashed);
116
117
24.5k
  xfree (sig->signers_uid);
118
119
24.5k
  xfree(sig);
120
24.5k
}
121
122
123
void
124
release_public_key_parts (PKT_public_key *pk)
125
920k
{
126
920k
  int n, i;
127
128
920k
  if (pk->seckey_info)
129
6.58k
    n = pubkey_get_nskey (pk->pubkey_algo);
130
914k
  else
131
914k
    n = pubkey_get_npkey (pk->pubkey_algo);
132
920k
  if (!n)
133
920k
    mpi_release (pk->pkey[0]);
134
2.89M
  for (i=0; i < n; i++ )
135
1.97M
    {
136
1.97M
      mpi_release (pk->pkey[i]);
137
1.97M
      pk->pkey[i] = NULL;
138
1.97M
    }
139
920k
  if (pk->seckey_info)
140
6.58k
    {
141
6.58k
      xfree (pk->seckey_info);
142
6.58k
      pk->seckey_info = NULL;
143
6.58k
    }
144
920k
  if (pk->prefs)
145
1.21k
    {
146
1.21k
      xfree (pk->prefs);
147
1.21k
      pk->prefs = NULL;
148
1.21k
    }
149
920k
  free_user_id (pk->user_id);
150
920k
  pk->user_id = NULL;
151
920k
  if (pk->revkey)
152
0
    {
153
0
      xfree(pk->revkey);
154
0
      pk->revkey=NULL;
155
0
      pk->numrevkeys=0;
156
0
    }
157
920k
  if (pk->serialno)
158
0
    {
159
0
      xfree (pk->serialno);
160
0
      pk->serialno = NULL;
161
0
    }
162
920k
  if (pk->updateurl)
163
15
    {
164
15
      xfree (pk->updateurl);
165
15
      pk->updateurl = NULL;
166
15
    }
167
920k
  if (pk->revoked.reason_comment)
168
0
    {
169
0
      xfree (pk->revoked.reason_comment);
170
0
      pk->revoked.reason_comment = NULL;
171
0
    }
172
920k
}
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
935k
{
180
935k
  if (pk)
181
920k
    {
182
920k
      release_public_key_parts (pk);
183
920k
      xfree(pk);
184
920k
    }
185
935k
}
186
187
188
static subpktarea_t *
189
cp_subpktarea (subpktarea_t *s )
190
0
{
191
0
    subpktarea_t *d;
192
193
0
    if( !s )
194
0
  return NULL;
195
0
    d = xmalloc (sizeof (*d) + s->size - 1 );
196
0
    d->size = s->size;
197
0
    d->len = s->len;
198
0
    memcpy (d->data, s->data, s->len);
199
0
    return d;
200
0
}
201
202
/*
203
 * Return a copy of the preferences
204
 */
205
prefitem_t *
206
copy_prefs (const prefitem_t *prefs)
207
1.21k
{
208
1.21k
    size_t n;
209
1.21k
    prefitem_t *new;
210
211
1.21k
    if (!prefs)
212
0
        return NULL;
213
214
10.1k
    for (n=0; prefs[n].type; n++)
215
8.95k
        ;
216
1.21k
    new = xmalloc ( sizeof (*new) * (n+1));
217
10.1k
    for (n=0; prefs[n].type; n++) {
218
8.95k
        new[n].type = prefs[n].type;
219
8.95k
        new[n].value = prefs[n].value;
220
8.95k
    }
221
1.21k
    new[n].type = PREFTYPE_NONE;
222
1.21k
    new[n].value = 0;
223
224
1.21k
    return new;
225
1.21k
}
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
0
{
234
0
  int n, i;
235
236
0
  if (!d)
237
0
    d = xmalloc (sizeof *d);
238
0
  memcpy (d, s, sizeof *d);
239
0
  d->seckey_info = NULL;
240
0
  d->user_id = NULL;
241
0
  d->prefs = NULL;
242
0
  d->revoked.got_reason = 0;
243
0
  d->revoked.reason_code = 0;
244
0
  d->revoked.reason_comment = NULL;
245
0
  d->revoked.reason_comment_len = 0;
246
247
0
  n = pubkey_get_npkey (s->pubkey_algo);
248
0
  i = 0;
249
0
  if (!n)
250
0
    d->pkey[i++] = my_mpi_copy (s->pkey[0]);
251
0
  else
252
0
    {
253
0
      for (; i < n; i++ )
254
0
        d->pkey[i] = my_mpi_copy (s->pkey[i]);
255
0
    }
256
0
  for (; i < PUBKEY_MAX_NSKEY; i++)
257
0
    d->pkey[i] = NULL;
258
259
0
  d->revkey = NULL;
260
0
  d->serialno = NULL;
261
0
  d->updateurl = NULL;
262
263
0
  return d;
264
0
}
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
0
{
273
0
  d = copy_public_key_basics (d, s);
274
0
  d->user_id = scopy_user_id (s->user_id);
275
0
  d->prefs = copy_prefs (s->prefs);
276
277
0
  if (!s->revkey && s->numrevkeys)
278
0
    BUG();
279
0
  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
0
  if (s->serialno)
286
0
    d->serialno = xstrdup (s->serialno);
287
0
  if (s->updateurl)
288
0
    d->updateurl = xstrdup (s->updateurl);
289
0
  if (s->revoked.got_reason)
290
0
    {
291
0
      d->revoked.got_reason = s->revoked.got_reason;
292
0
      d->revoked.reason_code = s->revoked.reason_code;
293
0
      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
0
    }
301
302
0
  return d;
303
0
}
304
305
306
307
PKT_signature *
308
copy_signature( PKT_signature *d, PKT_signature *s )
309
0
{
310
0
    int n, i;
311
312
0
    if( !d )
313
0
  d = xmalloc(sizeof *d);
314
0
    memcpy( d, s, sizeof *d );
315
0
    n = pubkey_get_nsig( s->pubkey_algo );
316
0
    if( !n )
317
0
  d->data[0] = my_mpi_copy(s->data[0]);
318
0
    else {
319
0
  for(i=0; i < n; i++ )
320
0
      d->data[i] = my_mpi_copy( s->data[i] );
321
0
    }
322
0
    d->hashed = cp_subpktarea (s->hashed);
323
0
    d->unhashed = cp_subpktarea (s->unhashed);
324
0
    if (s->signers_uid)
325
0
      d->signers_uid = xstrdup (s->signers_uid);
326
0
    if(s->numrevkeys)
327
0
      {
328
0
  d->revkey=NULL;
329
0
  d->numrevkeys=0;
330
0
  parse_revkeys(d);
331
0
      }
332
0
    return d;
333
0
}
334
335
336
/*
337
 * shallow copy of the user ID
338
 */
339
PKT_user_id *
340
scopy_user_id (PKT_user_id *s)
341
0
{
342
0
    if (s)
343
0
        s->ref++;
344
0
    return s;
345
0
}
346
347
348
349
void
350
free_comment( PKT_comment *rem )
351
243
{
352
243
    xfree(rem);
353
243
}
354
355
void
356
free_attributes(PKT_user_id *uid)
357
8.34k
{
358
8.34k
  if (!uid)
359
0
    return;
360
361
8.34k
  xfree(uid->attribs);
362
8.34k
  xfree(uid->attrib_data);
363
364
8.34k
  uid->attribs=NULL;
365
8.34k
  uid->attrib_data=NULL;
366
8.34k
  uid->attrib_len=0;
367
8.34k
}
368
369
void
370
free_user_id (PKT_user_id *uid)
371
929k
{
372
929k
  if (!uid)
373
920k
    return;
374
375
929k
  log_assert (uid->ref > 0);
376
8.34k
  if (--uid->ref)
377
0
    return;
378
379
8.34k
  free_attributes(uid);
380
8.34k
  xfree (uid->prefs);
381
8.34k
  xfree (uid->namehash);
382
8.34k
  xfree (uid->updateurl);
383
8.34k
  xfree (uid->mbox);
384
8.34k
  xfree (uid);
385
8.34k
}
386
387
void
388
free_compressed( PKT_compressed *zd )
389
14.0k
{
390
14.0k
  if (!zd)
391
0
    return;
392
393
14.0k
  if (zd->buf)
394
99
    {
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
136
      while (iobuf_read( zd->buf, NULL, 1<<30 ) != -1)
399
37
        ;
400
99
    }
401
14.0k
  xfree(zd);
402
14.0k
}
403
404
void
405
free_encrypted( PKT_encrypted *ed )
406
115k
{
407
115k
  if (!ed)
408
0
    return;
409
410
115k
  if (ed->buf)
411
114k
    {
412
      /* We need to skip some bytes. */
413
114k
      if (ed->is_partial)
414
1.73k
        {
415
2.40k
          while (iobuf_read( ed->buf, NULL, 1<<30 ) != -1)
416
665
            ;
417
1.73k
  }
418
113k
      else
419
113k
        {
420
114k
          while (ed->len)
421
1.34k
            {
422
              /* Skip the packet. */
423
1.34k
              int n = iobuf_read( ed->buf, NULL, ed->len );
424
1.34k
              if (n == -1)
425
136
                ed->len = 0;
426
1.20k
              else
427
1.20k
                ed->len -= n;
428
1.34k
            }
429
113k
  }
430
114k
    }
431
115k
  xfree (ed);
432
115k
}
433
434
435
void
436
free_plaintext( PKT_plaintext *pt )
437
3.89k
{
438
3.89k
  if (!pt)
439
0
    return;
440
441
3.89k
  if (pt->buf)
442
3.89k
    { /* We need to skip some bytes.  */
443
3.89k
      if (pt->is_partial)
444
1.26k
        {
445
2.64k
          while (iobuf_read( pt->buf, NULL, 1<<30 ) != -1)
446
1.37k
            ;
447
1.26k
        }
448
2.62k
      else
449
2.62k
        {
450
4.21k
          while( pt->len )
451
1.58k
            { /* Skip the packet.  */
452
1.58k
              int n = iobuf_read( pt->buf, NULL, pt->len );
453
1.58k
              if (n == -1)
454
159
                pt->len = 0;
455
1.42k
              else
456
1.42k
                pt->len -= n;
457
1.58k
            }
458
2.62k
  }
459
3.89k
    }
460
3.89k
  xfree (pt);
461
3.89k
}
462
463
464
/****************
465
 * Free the packet in PKT.
466
 */
467
void
468
free_packet (PACKET *pkt, parse_packet_ctx_t parsectx)
469
536k
{
470
536k
  if (!pkt || !pkt->pkt.generic)
471
303k
    {
472
303k
      if (parsectx && parsectx->last_pkt.pkt.generic)
473
54.7k
        {
474
54.7k
          if (parsectx->free_last_pkt)
475
4.17k
            {
476
4.17k
              free_packet (&parsectx->last_pkt, NULL);
477
4.17k
              parsectx->free_last_pkt = 0;
478
4.17k
            }
479
54.7k
          parsectx->last_pkt.pkttype = 0;
480
54.7k
          parsectx->last_pkt.pkt.generic = NULL;
481
54.7k
        }
482
303k
      return;
483
303k
    }
484
485
232k
  if (DBG_MEMORY)
486
232k
    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
232k
  if (parsectx && !parsectx->free_last_pkt
492
19.1k
      && parsectx->last_pkt.pkttype == pkt->pkttype
493
4.17k
      && parsectx->last_pkt.pkt.generic == pkt->pkt.generic)
494
4.17k
    {
495
4.17k
      parsectx->last_pkt = *pkt;
496
4.17k
      parsectx->free_last_pkt = 1;
497
4.17k
      pkt->pkt.generic = NULL;
498
4.17k
      return;
499
4.17k
    }
500
501
227k
  switch (pkt->pkttype)
502
227k
    {
503
24.5k
    case PKT_SIGNATURE:
504
24.5k
      free_seckey_enc (pkt->pkt.signature);
505
24.5k
      break;
506
7.09k
    case PKT_PUBKEY_ENC:
507
7.09k
      free_pubkey_enc (pkt->pkt.pubkey_enc);
508
7.09k
      break;
509
11.6k
    case PKT_SYMKEY_ENC:
510
11.6k
      free_symkey_enc (pkt->pkt.symkey_enc);
511
11.6k
      break;
512
22.3k
    case PKT_PUBLIC_KEY:
513
23.7k
    case PKT_PUBLIC_SUBKEY:
514
24.7k
    case PKT_SECRET_KEY:
515
30.9k
    case PKT_SECRET_SUBKEY:
516
30.9k
      free_public_key (pkt->pkt.public_key);
517
30.9k
      break;
518
243
    case PKT_COMMENT:
519
243
      free_comment (pkt->pkt.comment);
520
243
      break;
521
8.34k
    case PKT_USER_ID:
522
8.34k
      free_user_id (pkt->pkt.user_id);
523
8.34k
      break;
524
14.0k
    case PKT_COMPRESSED:
525
14.0k
      free_compressed (pkt->pkt.compressed);
526
14.0k
      break;
527
103k
    case PKT_ENCRYPTED:
528
104k
    case PKT_ENCRYPTED_MDC:
529
115k
    case PKT_ENCRYPTED_AEAD:
530
115k
      free_encrypted (pkt->pkt.encrypted);
531
115k
      break;
532
3.89k
    case PKT_PLAINTEXT:
533
3.89k
      free_plaintext (pkt->pkt.plaintext);
534
3.89k
      break;
535
11.7k
    default:
536
11.7k
      xfree (pkt->pkt.generic);
537
11.7k
      break;
538
227k
    }
539
540
227k
  pkt->pkt.generic = NULL;
541
227k
}
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
44.4k
{
548
51.4k
  while (sesenc_list)
549
6.94k
    {
550
6.94k
      struct seskey_enc_list *tmp = sesenc_list->next;
551
552
6.94k
      if (!sesenc_list->u_sym)
553
6.94k
        release_pubkey_enc_parts (&sesenc_list->u.pub);
554
6.94k
      xfree (sesenc_list);
555
6.94k
      sesenc_list = tmp;
556
6.94k
    }
557
44.4k
}
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
0
{
566
0
    int n, i;
567
568
0
    if( a->timestamp != b->timestamp )
569
0
  return -1;
570
0
    if( a->version < 4 && a->expiredate != b->expiredate )
571
0
  return -1;
572
0
    if( a->pubkey_algo != b->pubkey_algo )
573
0
  return -1;
574
575
0
    n = pubkey_get_npkey( b->pubkey_algo );
576
0
    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
0
    } else {
580
0
  for(i=0; i < n; i++ ) {
581
0
      if( mpi_cmp( a->pkey[i], b->pkey[i] ) )
582
0
    return -1;
583
0
  }
584
0
    }
585
586
0
    return 0;
587
0
}
588
589
590
591
int
592
cmp_signatures( PKT_signature *a, PKT_signature *b )
593
0
{
594
0
    int n, i;
595
596
0
    if( a->keyid[0] != b->keyid[0] )
597
0
  return -1;
598
0
    if( a->keyid[1] != b->keyid[1] )
599
0
  return -1;
600
0
    if( a->pubkey_algo != b->pubkey_algo )
601
0
  return -1;
602
603
0
    n = pubkey_get_nsig( a->pubkey_algo );
604
0
    if( !n )
605
0
  return -1; /* can't compare due to unknown algorithm */
606
0
    for(i=0; i < n; i++ ) {
607
0
  if( mpi_cmp( a->data[i] , b->data[i] ) )
608
0
      return -1;
609
0
    }
610
0
    return 0;
611
0
}
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
1.88k
{
620
1.88k
    int res=1;
621
622
1.88k
    if( a == b )
623
0
        return 0;
624
625
1.88k
    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
1.88k
    else if( !a->attrib_data && !b->attrib_data )
632
1.88k
      {
633
1.88k
  res = a->len - b->len;
634
1.88k
  if( !res )
635
627
    res = memcmp( a->name, b->name, a->len );
636
1.88k
      }
637
638
1.88k
    return res;
639
1.88k
}