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