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 /* Run time check to see whether mpi_copy does not copy the flags
34 * properly. This was fixed in version 1.8.6. */
35 static int
is_mpi_copy_broken(void)36 is_mpi_copy_broken (void)
37 {
38 static char result;
39
40 if (!result)
41 {
42 result = !gcry_check_version ("1.8.6");
43 result |= 0x80;
44 }
45 return (result & 1);
46 }
47
48
49 /* This is mpi_copy with a fix for opaque MPIs which store a NULL
50 pointer. This will also be fixed in Libggcrypt 1.7.0. */
51 static gcry_mpi_t
my_mpi_copy(gcry_mpi_t a)52 my_mpi_copy (gcry_mpi_t a)
53 {
54 if (a
55 && gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)
56 && !gcry_mpi_get_opaque (a, NULL))
57 return NULL;
58
59 if (is_mpi_copy_broken ())
60 {
61 int flag_user2 = a? gcry_mpi_get_flag (a, GCRYMPI_FLAG_USER2) : 0;
62 gcry_mpi_t b;
63
64 b = gcry_mpi_copy (a);
65 if (b && flag_user2)
66 gcry_mpi_set_flag (b, GCRYMPI_FLAG_USER2);
67 return b;
68 }
69
70 return gcry_mpi_copy (a);
71 }
72
73
74 void
free_symkey_enc(PKT_symkey_enc * enc)75 free_symkey_enc( PKT_symkey_enc *enc )
76 {
77 xfree(enc);
78 }
79
80 void
free_pubkey_enc(PKT_pubkey_enc * enc)81 free_pubkey_enc( PKT_pubkey_enc *enc )
82 {
83 int n, i;
84 n = pubkey_get_nenc( enc->pubkey_algo );
85 if( !n )
86 mpi_release(enc->data[0]);
87 for(i=0; i < n; i++ )
88 mpi_release( enc->data[i] );
89 xfree(enc);
90 }
91
92 void
free_seckey_enc(PKT_signature * sig)93 free_seckey_enc( PKT_signature *sig )
94 {
95 int n, i;
96
97 n = pubkey_get_nsig( sig->pubkey_algo );
98 if( !n )
99 mpi_release(sig->data[0]);
100 for(i=0; i < n; i++ )
101 mpi_release( sig->data[i] );
102
103 xfree(sig->revkey);
104 xfree(sig->hashed);
105 xfree(sig->unhashed);
106
107 xfree (sig->signers_uid);
108
109 xfree(sig);
110 }
111
112
113 void
release_public_key_parts(PKT_public_key * pk)114 release_public_key_parts (PKT_public_key *pk)
115 {
116 int n, i;
117
118 if (pk->seckey_info)
119 n = pubkey_get_nskey (pk->pubkey_algo);
120 else
121 n = pubkey_get_npkey (pk->pubkey_algo);
122 if (!n)
123 mpi_release (pk->pkey[0]);
124 for (i=0; i < n; i++ )
125 {
126 mpi_release (pk->pkey[i]);
127 pk->pkey[i] = NULL;
128 }
129 if (pk->seckey_info)
130 {
131 xfree (pk->seckey_info);
132 pk->seckey_info = NULL;
133 }
134 if (pk->prefs)
135 {
136 xfree (pk->prefs);
137 pk->prefs = NULL;
138 }
139 free_user_id (pk->user_id);
140 pk->user_id = NULL;
141 if (pk->revkey)
142 {
143 xfree(pk->revkey);
144 pk->revkey=NULL;
145 pk->numrevkeys=0;
146 }
147 if (pk->serialno)
148 {
149 xfree (pk->serialno);
150 pk->serialno = NULL;
151 }
152 if (pk->updateurl)
153 {
154 xfree (pk->updateurl);
155 pk->updateurl = NULL;
156 }
157 }
158
159
160 /* Free an allocated public key structure including all parts.
161 Passing NULL is allowed. */
162 void
free_public_key(PKT_public_key * pk)163 free_public_key (PKT_public_key *pk)
164 {
165 if (pk)
166 {
167 release_public_key_parts (pk);
168 xfree(pk);
169 }
170 }
171
172
173 static subpktarea_t *
cp_subpktarea(subpktarea_t * s)174 cp_subpktarea (subpktarea_t *s )
175 {
176 subpktarea_t *d;
177
178 if( !s )
179 return NULL;
180 d = xmalloc (sizeof (*d) + s->size - 1 );
181 d->size = s->size;
182 d->len = s->len;
183 memcpy (d->data, s->data, s->len);
184 return d;
185 }
186
187 /*
188 * Return a copy of the preferences
189 */
190 prefitem_t *
copy_prefs(const prefitem_t * prefs)191 copy_prefs (const prefitem_t *prefs)
192 {
193 size_t n;
194 prefitem_t *new;
195
196 if (!prefs)
197 return NULL;
198
199 for (n=0; prefs[n].type; n++)
200 ;
201 new = xmalloc ( sizeof (*new) * (n+1));
202 for (n=0; prefs[n].type; n++) {
203 new[n].type = prefs[n].type;
204 new[n].value = prefs[n].value;
205 }
206 new[n].type = PREFTYPE_NONE;
207 new[n].value = 0;
208
209 return new;
210 }
211
212
213 /* Copy the public key S to D. If D is NULL allocate a new public key
214 structure. If S has seckret key infos, only the public stuff is
215 copied. */
216 PKT_public_key *
copy_public_key(PKT_public_key * d,PKT_public_key * s)217 copy_public_key (PKT_public_key *d, PKT_public_key *s)
218 {
219 int n, i;
220
221 if (!d)
222 d = xmalloc (sizeof *d);
223 memcpy (d, s, sizeof *d);
224 d->seckey_info = NULL;
225 d->user_id = scopy_user_id (s->user_id);
226 d->prefs = copy_prefs (s->prefs);
227
228 n = pubkey_get_npkey (s->pubkey_algo);
229 i = 0;
230 if (!n)
231 d->pkey[i++] = my_mpi_copy (s->pkey[0]);
232 else
233 {
234 for (; i < n; i++ )
235 d->pkey[i] = my_mpi_copy (s->pkey[i]);
236 }
237 for (; i < PUBKEY_MAX_NSKEY; i++)
238 d->pkey[i] = NULL;
239
240 if (!s->revkey && s->numrevkeys)
241 BUG();
242 if (s->numrevkeys)
243 {
244 d->revkey = xmalloc(sizeof(struct revocation_key)*s->numrevkeys);
245 memcpy(d->revkey,s->revkey,sizeof(struct revocation_key)*s->numrevkeys);
246 }
247 else
248 d->revkey = NULL;
249
250 if (s->serialno)
251 d->serialno = xstrdup (s->serialno);
252 if (s->updateurl)
253 d->updateurl = xstrdup (s->updateurl);
254
255 return d;
256 }
257
258
259
260 PKT_signature *
copy_signature(PKT_signature * d,PKT_signature * s)261 copy_signature( PKT_signature *d, PKT_signature *s )
262 {
263 int n, i;
264
265 if( !d )
266 d = xmalloc(sizeof *d);
267 memcpy( d, s, sizeof *d );
268 n = pubkey_get_nsig( s->pubkey_algo );
269 if( !n )
270 d->data[0] = my_mpi_copy(s->data[0]);
271 else {
272 for(i=0; i < n; i++ )
273 d->data[i] = my_mpi_copy( s->data[i] );
274 }
275 d->hashed = cp_subpktarea (s->hashed);
276 d->unhashed = cp_subpktarea (s->unhashed);
277 if (s->signers_uid)
278 d->signers_uid = xstrdup (s->signers_uid);
279 if(s->numrevkeys)
280 {
281 d->revkey=NULL;
282 d->numrevkeys=0;
283 parse_revkeys(d);
284 }
285 return d;
286 }
287
288
289 /*
290 * shallow copy of the user ID
291 */
292 PKT_user_id *
scopy_user_id(PKT_user_id * s)293 scopy_user_id (PKT_user_id *s)
294 {
295 if (s)
296 s->ref++;
297 return s;
298 }
299
300
301
302 void
free_comment(PKT_comment * rem)303 free_comment( PKT_comment *rem )
304 {
305 xfree(rem);
306 }
307
308 void
free_attributes(PKT_user_id * uid)309 free_attributes(PKT_user_id *uid)
310 {
311 if (!uid)
312 return;
313
314 xfree(uid->attribs);
315 xfree(uid->attrib_data);
316
317 uid->attribs=NULL;
318 uid->attrib_data=NULL;
319 uid->attrib_len=0;
320 }
321
322 void
free_user_id(PKT_user_id * uid)323 free_user_id (PKT_user_id *uid)
324 {
325 if (!uid)
326 return;
327
328 log_assert (uid->ref > 0);
329 if (--uid->ref)
330 return;
331
332 free_attributes(uid);
333 xfree (uid->prefs);
334 xfree (uid->namehash);
335 xfree (uid->updateurl);
336 xfree (uid->mbox);
337 xfree (uid);
338 }
339
340 void
free_compressed(PKT_compressed * zd)341 free_compressed( PKT_compressed *zd )
342 {
343 if (!zd)
344 return;
345
346 if (zd->buf)
347 {
348 /* We need to skip some bytes. Because don't have any
349 * information about the length, so we assume this is the last
350 * packet */
351 while (iobuf_read( zd->buf, NULL, 1<<30 ) != -1)
352 ;
353 }
354 xfree(zd);
355 }
356
357 void
free_encrypted(PKT_encrypted * ed)358 free_encrypted( PKT_encrypted *ed )
359 {
360 if (!ed)
361 return;
362
363 if (ed->buf)
364 {
365 /* We need to skip some bytes. */
366 if (ed->is_partial)
367 {
368 while (iobuf_read( ed->buf, NULL, 1<<30 ) != -1)
369 ;
370 }
371 else
372 {
373 while (ed->len)
374 {
375 /* Skip the packet. */
376 int n = iobuf_read( ed->buf, NULL, ed->len );
377 if (n == -1)
378 ed->len = 0;
379 else
380 ed->len -= n;
381 }
382 }
383 }
384 xfree (ed);
385 }
386
387
388 void
free_plaintext(PKT_plaintext * pt)389 free_plaintext( PKT_plaintext *pt )
390 {
391 if (!pt)
392 return;
393
394 if (pt->buf)
395 { /* We need to skip some bytes. */
396 if (pt->is_partial)
397 {
398 while (iobuf_read( pt->buf, NULL, 1<<30 ) != -1)
399 ;
400 }
401 else
402 {
403 while( pt->len )
404 { /* Skip the packet. */
405 int n = iobuf_read( pt->buf, NULL, pt->len );
406 if (n == -1)
407 pt->len = 0;
408 else
409 pt->len -= n;
410 }
411 }
412 }
413 xfree (pt);
414 }
415
416
417 /****************
418 * Free the packet in PKT.
419 */
420 void
free_packet(PACKET * pkt,parse_packet_ctx_t parsectx)421 free_packet (PACKET *pkt, parse_packet_ctx_t parsectx)
422 {
423 if (!pkt || !pkt->pkt.generic)
424 {
425 if (parsectx && parsectx->last_pkt.pkt.generic)
426 {
427 if (parsectx->free_last_pkt)
428 {
429 free_packet (&parsectx->last_pkt, NULL);
430 parsectx->free_last_pkt = 0;
431 }
432 parsectx->last_pkt.pkttype = 0;
433 parsectx->last_pkt.pkt.generic = NULL;
434 }
435 return;
436 }
437
438 if (DBG_MEMORY)
439 log_debug ("free_packet() type=%d\n", pkt->pkttype);
440
441 /* If we have a parser context holding PKT then do not free the
442 * packet but set a flag that the packet in the parser context is
443 * now a deep copy. */
444 if (parsectx && !parsectx->free_last_pkt
445 && parsectx->last_pkt.pkttype == pkt->pkttype
446 && parsectx->last_pkt.pkt.generic == pkt->pkt.generic)
447 {
448 parsectx->last_pkt = *pkt;
449 parsectx->free_last_pkt = 1;
450 pkt->pkt.generic = NULL;
451 return;
452 }
453
454 switch (pkt->pkttype)
455 {
456 case PKT_SIGNATURE:
457 free_seckey_enc (pkt->pkt.signature);
458 break;
459 case PKT_PUBKEY_ENC:
460 free_pubkey_enc (pkt->pkt.pubkey_enc);
461 break;
462 case PKT_SYMKEY_ENC:
463 free_symkey_enc (pkt->pkt.symkey_enc);
464 break;
465 case PKT_PUBLIC_KEY:
466 case PKT_PUBLIC_SUBKEY:
467 case PKT_SECRET_KEY:
468 case PKT_SECRET_SUBKEY:
469 free_public_key (pkt->pkt.public_key);
470 break;
471 case PKT_COMMENT:
472 free_comment (pkt->pkt.comment);
473 break;
474 case PKT_USER_ID:
475 free_user_id (pkt->pkt.user_id);
476 break;
477 case PKT_COMPRESSED:
478 free_compressed (pkt->pkt.compressed);
479 break;
480 case PKT_ENCRYPTED:
481 case PKT_ENCRYPTED_MDC:
482 case PKT_ENCRYPTED_AEAD:
483 free_encrypted (pkt->pkt.encrypted);
484 break;
485 case PKT_PLAINTEXT:
486 free_plaintext (pkt->pkt.plaintext);
487 break;
488 default:
489 xfree (pkt->pkt.generic);
490 break;
491 }
492
493 pkt->pkt.generic = NULL;
494 }
495
496
497 /****************
498 * returns 0 if they match.
499 */
500 int
cmp_public_keys(PKT_public_key * a,PKT_public_key * b)501 cmp_public_keys( PKT_public_key *a, PKT_public_key *b )
502 {
503 int n, i;
504
505 if( a->timestamp != b->timestamp )
506 return -1;
507 if( a->version < 4 && a->expiredate != b->expiredate )
508 return -1;
509 if( a->pubkey_algo != b->pubkey_algo )
510 return -1;
511
512 n = pubkey_get_npkey( b->pubkey_algo );
513 if( !n ) { /* unknown algorithm, rest is in opaque MPI */
514 if( mpi_cmp( a->pkey[0], b->pkey[0] ) )
515 return -1; /* can't compare due to unknown algorithm */
516 } else {
517 for(i=0; i < n; i++ ) {
518 if( mpi_cmp( a->pkey[i], b->pkey[i] ) )
519 return -1;
520 }
521 }
522
523 return 0;
524 }
525
526
527
528 int
cmp_signatures(PKT_signature * a,PKT_signature * b)529 cmp_signatures( PKT_signature *a, PKT_signature *b )
530 {
531 int n, i;
532
533 if( a->keyid[0] != b->keyid[0] )
534 return -1;
535 if( a->keyid[1] != b->keyid[1] )
536 return -1;
537 if( a->pubkey_algo != b->pubkey_algo )
538 return -1;
539
540 n = pubkey_get_nsig( a->pubkey_algo );
541 if( !n )
542 return -1; /* can't compare due to unknown algorithm */
543 for(i=0; i < n; i++ ) {
544 if( mpi_cmp( a->data[i] , b->data[i] ) )
545 return -1;
546 }
547 return 0;
548 }
549
550
551 /****************
552 * Returns: true if the user ids do not match
553 */
554 int
cmp_user_ids(PKT_user_id * a,PKT_user_id * b)555 cmp_user_ids( PKT_user_id *a, PKT_user_id *b )
556 {
557 int res=1;
558
559 if( a == b )
560 return 0;
561
562 if( a->attrib_data && b->attrib_data )
563 {
564 res = a->attrib_len - b->attrib_len;
565 if( !res )
566 res = memcmp( a->attrib_data, b->attrib_data, a->attrib_len );
567 }
568 else if( !a->attrib_data && !b->attrib_data )
569 {
570 res = a->len - b->len;
571 if( !res )
572 res = memcmp( a->name, b->name, a->len );
573 }
574
575 return res;
576 }
577