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