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