Updated FSF street address and preparations for a release candidate.
[gnupg.git] / g10 / free-packet.c
1 /* free-packet.c - cleanup stuff for packets
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
3  *                                             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 2 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, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20  * USA.
21  */
22
23 #include <config.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <assert.h>
28
29 #include "packet.h"
30 #include "iobuf.h"
31 #include "mpi.h"
32 #include "util.h"
33 #include "cipher.h"
34 #include "memory.h"
35 #include "options.h"
36
37 void
38 free_symkey_enc( PKT_symkey_enc *enc )
39 {
40     m_free(enc);
41 }
42
43 void
44 free_pubkey_enc( PKT_pubkey_enc *enc )
45 {
46     int n, i;
47     n = pubkey_get_nenc( enc->pubkey_algo );
48     if( !n )
49         mpi_free(enc->data[0]);
50     for(i=0; i < n; i++ )
51         mpi_free( enc->data[i] );
52     m_free(enc);
53 }
54
55 void
56 free_seckey_enc( PKT_signature *sig )
57 {
58   int n, i;
59
60   n = pubkey_get_nsig( sig->pubkey_algo );
61   if( !n )
62     mpi_free(sig->data[0]);
63   for(i=0; i < n; i++ )
64     mpi_free( sig->data[i] );
65   
66   m_free(sig->revkey);
67   m_free(sig->hashed);
68   m_free(sig->unhashed);
69   m_free(sig);
70 }
71
72
73 void
74 release_public_key_parts( PKT_public_key *pk )
75 {
76     int n, i;
77     n = pubkey_get_npkey( pk->pubkey_algo );
78     if( !n )
79         mpi_free(pk->pkey[0]);
80     for(i=0; i < n; i++ ) {
81         mpi_free( pk->pkey[i] );
82         pk->pkey[i] = NULL;
83     }
84     if (pk->prefs) {
85         m_free (pk->prefs);
86         pk->prefs = NULL;
87     }
88     if (pk->user_id) {
89         free_user_id (pk->user_id);
90         pk->user_id = NULL;
91     }
92     if (pk->revkey) {
93         m_free(pk->revkey);
94         pk->revkey=NULL;
95         pk->numrevkeys=0;
96     }
97 }
98
99
100 void
101 free_public_key( PKT_public_key *pk )
102 {
103     release_public_key_parts( pk );
104     m_free(pk);
105 }
106
107
108 static subpktarea_t *
109 cp_subpktarea (subpktarea_t *s )
110 {
111     subpktarea_t *d;
112
113     if( !s )
114         return NULL;
115     d = m_alloc (sizeof (*d) + s->size - 1 );
116     d->size = s->size;
117     d->len = s->len;
118     memcpy (d->data, s->data, s->len);
119     return d;
120 }
121
122 /*
123  * Return a copy of the preferences 
124  */
125 prefitem_t *
126 copy_prefs (const prefitem_t *prefs)
127 {
128     size_t n;
129     prefitem_t *new;
130
131     if (!prefs)
132         return NULL;
133     
134     for (n=0; prefs[n].type; n++)
135         ;
136     new = m_alloc ( sizeof (*new) * (n+1));
137     for (n=0; prefs[n].type; n++) {
138         new[n].type = prefs[n].type;
139         new[n].value = prefs[n].value;
140     }
141     new[n].type = PREFTYPE_NONE;
142     new[n].value = 0;
143
144     return new;
145 }
146
147
148 PKT_public_key *
149 copy_public_key ( PKT_public_key *d, PKT_public_key *s)
150 {
151     int n, i;
152
153     if( !d )
154         d = m_alloc(sizeof *d);
155     memcpy( d, s, sizeof *d );
156     d->user_id = scopy_user_id (s->user_id);
157     d->prefs = copy_prefs (s->prefs);
158     n = pubkey_get_npkey( s->pubkey_algo );
159     if( !n )
160         d->pkey[0] = mpi_copy(s->pkey[0]);
161     else {
162         for(i=0; i < n; i++ )
163             d->pkey[i] = mpi_copy( s->pkey[i] );
164     }
165     if( !s->revkey && s->numrevkeys )
166         BUG();
167     if( s->numrevkeys ) {
168         d->revkey = m_alloc(sizeof(struct revocation_key)*s->numrevkeys);
169         memcpy(d->revkey,s->revkey,sizeof(struct revocation_key)*s->numrevkeys);
170     }
171     else
172         d->revkey = NULL;
173     return d;
174 }
175
176 /****************
177  * Replace all common parts of a sk by the one from the public key.
178  * This is a hack and a better solution will be to just store the real secret
179  * parts somewhere and don't duplicate all the other stuff.
180  */
181 void
182 copy_public_parts_to_secret_key( PKT_public_key *pk, PKT_secret_key *sk )
183 {
184     sk->expiredate  = pk->expiredate;     
185     sk->pubkey_algo = pk->pubkey_algo;    
186     sk->pubkey_usage= pk->pubkey_usage;
187     sk->req_usage   = pk->req_usage;
188     sk->req_algo    = pk->req_algo;
189     sk->has_expired = pk->has_expired;    
190     sk->is_revoked  = pk->is_revoked;     
191     sk->is_valid    = pk->is_valid;    
192     sk->main_keyid[0]= pk->main_keyid[0];
193     sk->main_keyid[1]= pk->main_keyid[1];
194     sk->keyid[0]    = pk->keyid[0];
195     sk->keyid[1]    = pk->keyid[1];
196 }
197
198 PKT_signature *
199 copy_signature( PKT_signature *d, PKT_signature *s )
200 {
201     int n, i;
202
203     if( !d )
204         d = m_alloc(sizeof *d);
205     memcpy( d, s, sizeof *d );
206     n = pubkey_get_nsig( s->pubkey_algo );
207     if( !n )
208         d->data[0] = mpi_copy(s->data[0]);
209     else {
210         for(i=0; i < n; i++ )
211             d->data[i] = mpi_copy( s->data[i] );
212     }
213     d->hashed = cp_subpktarea (s->hashed);
214     d->unhashed = cp_subpktarea (s->unhashed);
215     if(s->numrevkeys)
216       {
217         d->revkey=NULL;
218         d->numrevkeys=0;
219         parse_revkeys(d);
220       }
221     return d;
222 }
223
224
225 /*
226  * shallow copy of the user ID
227  */
228 PKT_user_id *
229 scopy_user_id (PKT_user_id *s)
230 {
231     if (s)
232         s->ref++;
233     return s;
234 }
235
236
237
238 void
239 release_secret_key_parts( PKT_secret_key *sk )
240 {
241     int n, i;
242
243     n = pubkey_get_nskey( sk->pubkey_algo );
244     if( !n )
245         mpi_free(sk->skey[0]);
246     for(i=0; i < n; i++ ) {
247         mpi_free( sk->skey[i] );
248         sk->skey[i] = NULL;
249     }
250 }
251
252 void
253 free_secret_key( PKT_secret_key *sk )
254 {
255     release_secret_key_parts( sk );
256     m_free(sk);
257 }
258
259 PKT_secret_key *
260 copy_secret_key( PKT_secret_key *d, PKT_secret_key *s )
261 {
262     int n, i;
263
264     if( !d )
265         d = m_alloc(sizeof *d);
266     else
267         release_secret_key_parts (d);
268     memcpy( d, s, sizeof *d );
269     n = pubkey_get_nskey( s->pubkey_algo );
270     if( !n )
271         d->skey[0] = mpi_copy(s->skey[0]);
272     else {
273         for(i=0; i < n; i++ )
274             d->skey[i] = mpi_copy( s->skey[i] );
275     }
276
277     return d;
278 }
279
280 void
281 free_comment( PKT_comment *rem )
282 {
283     m_free(rem);
284 }
285
286 void
287 free_attributes(PKT_user_id *uid)
288 {
289   m_free(uid->attribs);
290   m_free(uid->attrib_data);
291
292   uid->attribs=NULL;
293   uid->attrib_data=NULL;
294   uid->attrib_len=0;
295 }
296
297 void
298 free_user_id (PKT_user_id *uid)
299 {
300     assert (uid->ref > 0);
301     if (--uid->ref)
302         return;
303
304     free_attributes(uid);
305     m_free (uid->prefs);
306     m_free (uid->namehash);
307     m_free (uid);
308 }
309
310 void
311 free_compressed( PKT_compressed *zd )
312 {
313     if( zd->buf ) { /* have to skip some bytes */
314         /* don't have any information about the length, so
315          * we assume this is the last packet */
316         while( iobuf_read( zd->buf, NULL, 1<<30 ) != -1 )
317             ;
318     }
319     m_free(zd);
320 }
321
322 void
323 free_encrypted( PKT_encrypted *ed )
324 {
325     if( ed->buf ) { /* have to skip some bytes */
326         if( ed->is_partial ) {
327             while( iobuf_read( ed->buf, NULL, 1<<30 ) != -1 )
328                 ;
329         }
330         else {
331            while( ed->len ) { /* skip the packet */
332                int n = iobuf_read( ed->buf, NULL, ed->len );
333                if( n == -1 )
334                    ed->len = 0;
335                else
336                    ed->len -= n;
337            }
338         }
339     }
340     m_free(ed);
341 }
342
343
344 void
345 free_plaintext( PKT_plaintext *pt )
346 {
347     if( pt->buf ) { /* have to skip some bytes */
348         if( pt->is_partial ) {
349             while( iobuf_read( pt->buf, NULL, 1<<30 ) != -1 )
350                 ;
351         }
352         else {
353            while( pt->len ) { /* skip the packet */
354                int n = iobuf_read( pt->buf, NULL, pt->len );
355                if( n == -1 )
356                    pt->len = 0;
357                else
358                    pt->len -= n;
359            }
360         }
361     }
362     m_free(pt);
363 }
364
365 /****************
366  * Free the packet in pkt.
367  */
368 void
369 free_packet( PACKET *pkt )
370 {
371     if( !pkt || !pkt->pkt.generic )
372         return;
373
374     if( DBG_MEMORY )
375         log_debug("free_packet() type=%d\n", pkt->pkttype );
376
377     switch( pkt->pkttype ) {
378       case PKT_SIGNATURE:
379         free_seckey_enc( pkt->pkt.signature );
380         break;
381       case PKT_PUBKEY_ENC:
382         free_pubkey_enc( pkt->pkt.pubkey_enc );
383         break;
384       case PKT_SYMKEY_ENC:
385         free_symkey_enc( pkt->pkt.symkey_enc );
386         break;
387       case PKT_PUBLIC_KEY:
388       case PKT_PUBLIC_SUBKEY:
389         free_public_key( pkt->pkt.public_key );
390         break;
391       case PKT_SECRET_KEY:
392       case PKT_SECRET_SUBKEY:
393         free_secret_key( pkt->pkt.secret_key );
394         break;
395       case PKT_COMMENT:
396         free_comment( pkt->pkt.comment );
397         break;
398       case PKT_USER_ID:
399         free_user_id( pkt->pkt.user_id );
400         break;
401       case PKT_COMPRESSED:
402         free_compressed( pkt->pkt.compressed);
403         break;
404       case PKT_ENCRYPTED:
405       case PKT_ENCRYPTED_MDC:
406         free_encrypted( pkt->pkt.encrypted );
407         break;
408       case PKT_PLAINTEXT:
409         free_plaintext( pkt->pkt.plaintext );
410         break;
411       default:
412         m_free( pkt->pkt.generic );
413         break;
414     }
415     pkt->pkt.generic = NULL;
416 }
417
418 /****************
419  * returns 0 if they match.
420  */
421 int
422 cmp_public_keys( PKT_public_key *a, PKT_public_key *b )
423 {
424     int n, i;
425
426     if( a->timestamp != b->timestamp )
427         return -1;
428     if( a->version < 4 && a->expiredate != b->expiredate )
429         return -1;
430     if( a->pubkey_algo != b->pubkey_algo )
431         return -1;
432
433     n = pubkey_get_npkey( b->pubkey_algo );
434     if( !n )
435         return -1; /* can't compare due to unknown algorithm */
436     for(i=0; i < n; i++ ) {
437         if( mpi_cmp( a->pkey[i], b->pkey[i] ) )
438             return -1;
439     }
440
441     return 0;
442 }
443
444 /****************
445  * Returns 0 if they match.
446  * We only compare the public parts.
447  */
448 int
449 cmp_secret_keys( PKT_secret_key *a, PKT_secret_key *b )
450 {
451     int n, i;
452
453     if( a->timestamp != b->timestamp )
454         return -1;
455     if( a->version < 4 && a->expiredate != b->expiredate )
456         return -1;
457     if( a->pubkey_algo != b->pubkey_algo )
458         return -1;
459
460     n = pubkey_get_npkey( b->pubkey_algo );
461     if( !n )
462         return -1; /* can't compare due to unknown algorithm */
463     for(i=0; i < n; i++ ) {
464         if( mpi_cmp( a->skey[i], b->skey[i] ) )
465             return -1;
466     }
467
468     return 0;
469 }
470
471 /****************
472  * Returns 0 if they match.
473  */
474 int
475 cmp_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk )
476 {
477     int n, i;
478
479     if( pk->timestamp != sk->timestamp )
480         return -1;
481     if( pk->version < 4 && pk->expiredate != sk->expiredate )
482         return -1;
483     if( pk->pubkey_algo != sk->pubkey_algo )
484         return -1;
485
486     n = pubkey_get_npkey( pk->pubkey_algo );
487     if( !n )
488         return -1; /* can't compare due to unknown algorithm */
489     for(i=0; i < n; i++ ) {
490         if( mpi_cmp( pk->pkey[i] , sk->skey[i] ) )
491             return -1;
492     }
493     return 0;
494 }
495
496
497
498 int
499 cmp_signatures( PKT_signature *a, PKT_signature *b )
500 {
501     int n, i;
502
503     if( a->keyid[0] != b->keyid[0] )
504         return -1;
505     if( a->keyid[1] != b->keyid[1] )
506         return -1;
507     if( a->pubkey_algo != b->pubkey_algo )
508         return -1;
509
510     n = pubkey_get_nsig( a->pubkey_algo );
511     if( !n )
512         return -1; /* can't compare due to unknown algorithm */
513     for(i=0; i < n; i++ ) {
514         if( mpi_cmp( a->data[i] , b->data[i] ) )
515             return -1;
516     }
517     return 0;
518 }
519
520
521 /****************
522  * Returns: true if the user ids do not match
523  */
524 int
525 cmp_user_ids( PKT_user_id *a, PKT_user_id *b )
526 {
527     int res=1;
528
529     if( a == b )
530         return 0;
531
532     if( a->attrib_data && b->attrib_data )
533       {
534         res = a->attrib_len - b->attrib_len;
535         if( !res )
536           res = memcmp( a->attrib_data, b->attrib_data, a->attrib_len );
537       }
538     else if( !a->attrib_data && !b->attrib_data )
539       {
540         res = a->len - b->len;
541         if( !res )
542           res = memcmp( a->name, b->name, a->len );
543       }
544
545     return res;
546 }