gpg: Screen keyserver responses.
[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 <http://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <assert.h>
26
27 #include "gpg.h"
28 #include "util.h"
29 #include "packet.h"
30 #include "../common/iobuf.h"
31 #include "options.h"
32
33
34 void
35 free_symkey_enc( PKT_symkey_enc *enc )
36 {
37     xfree(enc);
38 }
39
40 void
41 free_pubkey_enc( PKT_pubkey_enc *enc )
42 {
43     int n, i;
44     n = pubkey_get_nenc( enc->pubkey_algo );
45     if( !n )
46         mpi_release(enc->data[0]);
47     for(i=0; i < n; i++ )
48         mpi_release( enc->data[i] );
49     xfree(enc);
50 }
51
52 void
53 free_seckey_enc( PKT_signature *sig )
54 {
55   int n, i;
56
57   n = pubkey_get_nsig( sig->pubkey_algo );
58   if( !n )
59     mpi_release(sig->data[0]);
60   for(i=0; i < n; i++ )
61     mpi_release( sig->data[i] );
62
63   xfree(sig->revkey);
64   xfree(sig->hashed);
65   xfree(sig->unhashed);
66
67   if (sig->pka_info)
68     {
69       xfree (sig->pka_info->uri);
70       xfree (sig->pka_info);
71     }
72
73   xfree(sig);
74 }
75
76
77 void
78 release_public_key_parts (PKT_public_key *pk)
79 {
80   int n, i;
81
82   if (pk->seckey_info)
83     n = pubkey_get_nskey (pk->pubkey_algo);
84   else
85     n = pubkey_get_npkey (pk->pubkey_algo);
86   if (!n)
87     mpi_release (pk->pkey[0]);
88   for (i=0; i < n; i++ )
89     {
90       mpi_release (pk->pkey[i]);
91       pk->pkey[i] = NULL;
92     }
93   if (pk->seckey_info)
94     {
95       xfree (pk->seckey_info);
96       pk->seckey_info = NULL;
97     }
98   if (pk->prefs)
99     {
100       xfree (pk->prefs);
101       pk->prefs = NULL;
102     }
103   if (pk->user_id)
104     {
105       free_user_id (pk->user_id);
106       pk->user_id = NULL;
107     }
108   if (pk->revkey)
109     {
110       xfree(pk->revkey);
111       pk->revkey=NULL;
112       pk->numrevkeys=0;
113     }
114   if (pk->serialno)
115     {
116       xfree (pk->serialno);
117       pk->serialno = NULL;
118     }
119 }
120
121
122 /* Free an allocated public key structure including all parts.
123    Passing NULL is allowed.  */
124 void
125 free_public_key (PKT_public_key *pk)
126 {
127   if (pk)
128     {
129       release_public_key_parts (pk);
130       xfree(pk);
131     }
132 }
133
134
135 static subpktarea_t *
136 cp_subpktarea (subpktarea_t *s )
137 {
138     subpktarea_t *d;
139
140     if( !s )
141         return NULL;
142     d = xmalloc (sizeof (*d) + s->size - 1 );
143     d->size = s->size;
144     d->len = s->len;
145     memcpy (d->data, s->data, s->len);
146     return d;
147 }
148
149 /*
150  * Return a copy of the preferences
151  */
152 prefitem_t *
153 copy_prefs (const prefitem_t *prefs)
154 {
155     size_t n;
156     prefitem_t *new;
157
158     if (!prefs)
159         return NULL;
160
161     for (n=0; prefs[n].type; n++)
162         ;
163     new = xmalloc ( sizeof (*new) * (n+1));
164     for (n=0; prefs[n].type; n++) {
165         new[n].type = prefs[n].type;
166         new[n].value = prefs[n].value;
167     }
168     new[n].type = PREFTYPE_NONE;
169     new[n].value = 0;
170
171     return new;
172 }
173
174
175 /* Copy the public key S to D.  If D is NULL allocate a new public key
176    structure.  If S has seckret key infos, only the public stuff is
177    copied.  */
178 PKT_public_key *
179 copy_public_key (PKT_public_key *d, PKT_public_key *s)
180 {
181   int n, i;
182
183   if (!d)
184     d = xmalloc (sizeof *d);
185   memcpy (d, s, sizeof *d);
186   d->seckey_info = NULL;
187   d->user_id = scopy_user_id (s->user_id);
188   d->prefs = copy_prefs (s->prefs);
189
190   n = pubkey_get_npkey (s->pubkey_algo);
191   i = 0;
192   if (!n)
193     d->pkey[i++] = mpi_copy (s->pkey[0]);
194   else
195     {
196       for (; i < n; i++ )
197         d->pkey[i] = mpi_copy( s->pkey[i] );
198     }
199   for (; i < PUBKEY_MAX_NSKEY; i++)
200     d->pkey[i] = NULL;
201
202   if (!s->revkey && s->numrevkeys)
203     BUG();
204   if (s->numrevkeys)
205     {
206       d->revkey = xmalloc(sizeof(struct revocation_key)*s->numrevkeys);
207       memcpy(d->revkey,s->revkey,sizeof(struct revocation_key)*s->numrevkeys);
208     }
209   else
210     d->revkey = NULL;
211   return d;
212 }
213
214
215
216 static pka_info_t *
217 cp_pka_info (const pka_info_t *s)
218 {
219   pka_info_t *d = xmalloc (sizeof *s + strlen (s->email));
220
221   d->valid = s->valid;
222   d->checked = s->checked;
223   d->uri = s->uri? xstrdup (s->uri):NULL;
224   memcpy (d->fpr, s->fpr, sizeof s->fpr);
225   strcpy (d->email, s->email);
226   return d;
227 }
228
229
230 PKT_signature *
231 copy_signature( PKT_signature *d, PKT_signature *s )
232 {
233     int n, i;
234
235     if( !d )
236         d = xmalloc(sizeof *d);
237     memcpy( d, s, sizeof *d );
238     n = pubkey_get_nsig( s->pubkey_algo );
239     if( !n )
240         d->data[0] = mpi_copy(s->data[0]);
241     else {
242         for(i=0; i < n; i++ )
243             d->data[i] = mpi_copy( s->data[i] );
244     }
245     d->pka_info = s->pka_info? cp_pka_info (s->pka_info) : NULL;
246     d->hashed = cp_subpktarea (s->hashed);
247     d->unhashed = cp_subpktarea (s->unhashed);
248     if(s->numrevkeys)
249       {
250         d->revkey=NULL;
251         d->numrevkeys=0;
252         parse_revkeys(d);
253       }
254     return d;
255 }
256
257
258 /*
259  * shallow copy of the user ID
260  */
261 PKT_user_id *
262 scopy_user_id (PKT_user_id *s)
263 {
264     if (s)
265         s->ref++;
266     return s;
267 }
268
269
270
271 void
272 free_comment( PKT_comment *rem )
273 {
274     xfree(rem);
275 }
276
277 void
278 free_attributes(PKT_user_id *uid)
279 {
280   xfree(uid->attribs);
281   xfree(uid->attrib_data);
282
283   uid->attribs=NULL;
284   uid->attrib_data=NULL;
285   uid->attrib_len=0;
286 }
287
288 void
289 free_user_id (PKT_user_id *uid)
290 {
291     assert (uid->ref > 0);
292     if (--uid->ref)
293         return;
294
295     free_attributes(uid);
296     xfree (uid->prefs);
297     xfree (uid->namehash);
298     xfree (uid);
299 }
300
301 void
302 free_compressed( PKT_compressed *zd )
303 {
304     if( zd->buf ) { /* have to skip some bytes */
305         /* don't have any information about the length, so
306          * we assume this is the last packet */
307         while( iobuf_read( zd->buf, NULL, 1<<30 ) != -1 )
308             ;
309     }
310     xfree(zd);
311 }
312
313 void
314 free_encrypted( PKT_encrypted *ed )
315 {
316     if( ed->buf ) { /* have to skip some bytes */
317         if( ed->is_partial ) {
318             while( iobuf_read( ed->buf, NULL, 1<<30 ) != -1 )
319                 ;
320         }
321         else {
322            while( ed->len ) { /* skip the packet */
323                int n = iobuf_read( ed->buf, NULL, ed->len );
324                if( n == -1 )
325                    ed->len = 0;
326                else
327                    ed->len -= n;
328            }
329         }
330     }
331     xfree(ed);
332 }
333
334
335 void
336 free_plaintext( PKT_plaintext *pt )
337 {
338     if( pt->buf ) { /* have to skip some bytes */
339         if( pt->is_partial ) {
340             while( iobuf_read( pt->buf, NULL, 1<<30 ) != -1 )
341                 ;
342         }
343         else {
344            while( pt->len ) { /* skip the packet */
345                int n = iobuf_read( pt->buf, NULL, pt->len );
346                if( n == -1 )
347                    pt->len = 0;
348                else
349                    pt->len -= n;
350            }
351         }
352     }
353     xfree(pt);
354 }
355
356 /****************
357  * Free the packet in pkt.
358  */
359 void
360 free_packet( PACKET *pkt )
361 {
362     if( !pkt || !pkt->pkt.generic )
363         return;
364
365     if( DBG_MEMORY )
366         log_debug("free_packet() type=%d\n", pkt->pkttype );
367
368     switch( pkt->pkttype ) {
369       case PKT_SIGNATURE:
370         free_seckey_enc( pkt->pkt.signature );
371         break;
372       case PKT_PUBKEY_ENC:
373         free_pubkey_enc( pkt->pkt.pubkey_enc );
374         break;
375       case PKT_SYMKEY_ENC:
376         free_symkey_enc( pkt->pkt.symkey_enc );
377         break;
378       case PKT_PUBLIC_KEY:
379       case PKT_PUBLIC_SUBKEY:
380       case PKT_SECRET_KEY:
381       case PKT_SECRET_SUBKEY:
382         free_public_key (pkt->pkt.public_key);
383         break;
384       case PKT_COMMENT:
385         free_comment( pkt->pkt.comment );
386         break;
387       case PKT_USER_ID:
388         free_user_id( pkt->pkt.user_id );
389         break;
390       case PKT_COMPRESSED:
391         free_compressed( pkt->pkt.compressed);
392         break;
393       case PKT_ENCRYPTED:
394       case PKT_ENCRYPTED_MDC:
395         free_encrypted( pkt->pkt.encrypted );
396         break;
397       case PKT_PLAINTEXT:
398         free_plaintext( pkt->pkt.plaintext );
399         break;
400       default:
401         xfree( pkt->pkt.generic );
402         break;
403     }
404     pkt->pkt.generic = NULL;
405 }
406
407 /****************
408  * returns 0 if they match.
409  */
410 int
411 cmp_public_keys( PKT_public_key *a, PKT_public_key *b )
412 {
413     int n, i;
414
415     if( a->timestamp != b->timestamp )
416         return -1;
417     if( a->version < 4 && a->expiredate != b->expiredate )
418         return -1;
419     if( a->pubkey_algo != b->pubkey_algo )
420         return -1;
421
422     n = pubkey_get_npkey( b->pubkey_algo );
423     if( !n )
424         return -1; /* can't compare due to unknown algorithm */
425     for(i=0; i < n; i++ ) {
426         if( mpi_cmp( a->pkey[i], b->pkey[i] ) )
427             return -1;
428     }
429
430     return 0;
431 }
432
433
434
435 int
436 cmp_signatures( PKT_signature *a, PKT_signature *b )
437 {
438     int n, i;
439
440     if( a->keyid[0] != b->keyid[0] )
441         return -1;
442     if( a->keyid[1] != b->keyid[1] )
443         return -1;
444     if( a->pubkey_algo != b->pubkey_algo )
445         return -1;
446
447     n = pubkey_get_nsig( a->pubkey_algo );
448     if( !n )
449         return -1; /* can't compare due to unknown algorithm */
450     for(i=0; i < n; i++ ) {
451         if( mpi_cmp( a->data[i] , b->data[i] ) )
452             return -1;
453     }
454     return 0;
455 }
456
457
458 /****************
459  * Returns: true if the user ids do not match
460  */
461 int
462 cmp_user_ids( PKT_user_id *a, PKT_user_id *b )
463 {
464     int res=1;
465
466     if( a == b )
467         return 0;
468
469     if( a->attrib_data && b->attrib_data )
470       {
471         res = a->attrib_len - b->attrib_len;
472         if( !res )
473           res = memcmp( a->attrib_data, b->attrib_data, a->attrib_len );
474       }
475     else if( !a->attrib_data && !b->attrib_data )
476       {
477         res = a->len - b->len;
478         if( !res )
479           res = memcmp( a->name, b->name, a->len );
480       }
481
482     return res;
483 }