* ccid-driver.c (ccid_slot_status): Fixed debug messages.
[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     else
266         release_secret_key_parts (d);
267     memcpy( d, s, sizeof *d );
268     n = pubkey_get_nskey( s->pubkey_algo );
269     if( !n )
270         d->skey[0] = mpi_copy(s->skey[0]);
271     else {
272         for(i=0; i < n; i++ )
273             d->skey[i] = mpi_copy( s->skey[i] );
274     }
275
276     return d;
277 }
278
279 void
280 free_comment( PKT_comment *rem )
281 {
282     m_free(rem);
283 }
284
285 void
286 free_attributes(PKT_user_id *uid)
287 {
288   m_free(uid->attribs);
289   m_free(uid->attrib_data);
290
291   uid->attribs=NULL;
292   uid->attrib_data=NULL;
293   uid->attrib_len=0;
294 }
295
296 void
297 free_user_id (PKT_user_id *uid)
298 {
299     assert (uid->ref > 0);
300     if (--uid->ref)
301         return;
302
303     free_attributes(uid);
304     m_free (uid->prefs);
305     m_free (uid->namehash);
306     m_free (uid);
307 }
308
309 void
310 free_compressed( PKT_compressed *zd )
311 {
312     if( zd->buf ) { /* have to skip some bytes */
313         /* don't have any information about the length, so
314          * we assume this is the last packet */
315         while( iobuf_read( zd->buf, NULL, 1<<30 ) != -1 )
316             ;
317     }
318     m_free(zd);
319 }
320
321 void
322 free_encrypted( PKT_encrypted *ed )
323 {
324     if( ed->buf ) { /* have to skip some bytes */
325         if( ed->is_partial ) {
326             while( iobuf_read( ed->buf, NULL, 1<<30 ) != -1 )
327                 ;
328         }
329         else {
330            while( ed->len ) { /* skip the packet */
331                int n = iobuf_read( ed->buf, NULL, ed->len );
332                if( n == -1 )
333                    ed->len = 0;
334                else
335                    ed->len -= n;
336            }
337         }
338     }
339     m_free(ed);
340 }
341
342
343 void
344 free_plaintext( PKT_plaintext *pt )
345 {
346     if( pt->buf ) { /* have to skip some bytes */
347         if( pt->is_partial ) {
348             while( iobuf_read( pt->buf, NULL, 1<<30 ) != -1 )
349                 ;
350         }
351         else {
352            while( pt->len ) { /* skip the packet */
353                int n = iobuf_read( pt->buf, NULL, pt->len );
354                if( n == -1 )
355                    pt->len = 0;
356                else
357                    pt->len -= n;
358            }
359         }
360     }
361     m_free(pt);
362 }
363
364 /****************
365  * Free the packet in pkt.
366  */
367 void
368 free_packet( PACKET *pkt )
369 {
370     if( !pkt || !pkt->pkt.generic )
371         return;
372
373     if( DBG_MEMORY )
374         log_debug("free_packet() type=%d\n", pkt->pkttype );
375
376     switch( pkt->pkttype ) {
377       case PKT_SIGNATURE:
378         free_seckey_enc( pkt->pkt.signature );
379         break;
380       case PKT_PUBKEY_ENC:
381         free_pubkey_enc( pkt->pkt.pubkey_enc );
382         break;
383       case PKT_SYMKEY_ENC:
384         free_symkey_enc( pkt->pkt.symkey_enc );
385         break;
386       case PKT_PUBLIC_KEY:
387       case PKT_PUBLIC_SUBKEY:
388         free_public_key( pkt->pkt.public_key );
389         break;
390       case PKT_SECRET_KEY:
391       case PKT_SECRET_SUBKEY:
392         free_secret_key( pkt->pkt.secret_key );
393         break;
394       case PKT_COMMENT:
395         free_comment( pkt->pkt.comment );
396         break;
397       case PKT_USER_ID:
398         free_user_id( pkt->pkt.user_id );
399         break;
400       case PKT_COMPRESSED:
401         free_compressed( pkt->pkt.compressed);
402         break;
403       case PKT_ENCRYPTED:
404       case PKT_ENCRYPTED_MDC:
405         free_encrypted( pkt->pkt.encrypted );
406         break;
407       case PKT_PLAINTEXT:
408         free_plaintext( pkt->pkt.plaintext );
409         break;
410       default:
411         m_free( pkt->pkt.generic );
412         break;
413     }
414     pkt->pkt.generic = NULL;
415 }
416
417 /****************
418  * returns 0 if they match.
419  */
420 int
421 cmp_public_keys( PKT_public_key *a, PKT_public_key *b )
422 {
423     int n, i;
424
425     if( a->timestamp != b->timestamp )
426         return -1;
427     if( a->version < 4 && a->expiredate != b->expiredate )
428         return -1;
429     if( a->pubkey_algo != b->pubkey_algo )
430         return -1;
431
432     n = pubkey_get_npkey( b->pubkey_algo );
433     if( !n )
434         return -1; /* can't compare due to unknown algorithm */
435     for(i=0; i < n; i++ ) {
436         if( mpi_cmp( a->pkey[i], b->pkey[i] ) )
437             return -1;
438     }
439
440     return 0;
441 }
442
443 /****************
444  * Returns 0 if they match.
445  * We only compare the public parts.
446  */
447 int
448 cmp_secret_keys( PKT_secret_key *a, PKT_secret_key *b )
449 {
450     int n, i;
451
452     if( a->timestamp != b->timestamp )
453         return -1;
454     if( a->version < 4 && a->expiredate != b->expiredate )
455         return -1;
456     if( a->pubkey_algo != b->pubkey_algo )
457         return -1;
458
459     n = pubkey_get_npkey( b->pubkey_algo );
460     if( !n )
461         return -1; /* can't compare due to unknown algorithm */
462     for(i=0; i < n; i++ ) {
463         if( mpi_cmp( a->skey[i], b->skey[i] ) )
464             return -1;
465     }
466
467     return 0;
468 }
469
470 /****************
471  * Returns 0 if they match.
472  */
473 int
474 cmp_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk )
475 {
476     int n, i;
477
478     if( pk->timestamp != sk->timestamp )
479         return -1;
480     if( pk->version < 4 && pk->expiredate != sk->expiredate )
481         return -1;
482     if( pk->pubkey_algo != sk->pubkey_algo )
483         return -1;
484
485     n = pubkey_get_npkey( pk->pubkey_algo );
486     if( !n )
487         return -1; /* can't compare due to unknown algorithm */
488     for(i=0; i < n; i++ ) {
489         if( mpi_cmp( pk->pkey[i] , sk->skey[i] ) )
490             return -1;
491     }
492     return 0;
493 }
494
495
496
497 int
498 cmp_signatures( PKT_signature *a, PKT_signature *b )
499 {
500     int n, i;
501
502     if( a->keyid[0] != b->keyid[0] )
503         return -1;
504     if( a->keyid[1] != b->keyid[1] )
505         return -1;
506     if( a->pubkey_algo != b->pubkey_algo )
507         return -1;
508
509     n = pubkey_get_nsig( a->pubkey_algo );
510     if( !n )
511         return -1; /* can't compare due to unknown algorithm */
512     for(i=0; i < n; i++ ) {
513         if( mpi_cmp( a->data[i] , b->data[i] ) )
514             return -1;
515     }
516     return 0;
517 }
518
519
520 /****************
521  * Returns: true if the user ids do not match
522  */
523 int
524 cmp_user_ids( PKT_user_id *a, PKT_user_id *b )
525 {
526     int res=1;
527
528     if( a == b )
529         return 0;
530
531     if( a->attrib_data && b->attrib_data )
532       {
533         res = a->attrib_len - b->attrib_len;
534         if( !res )
535           res = memcmp( a->attrib_data, b->attrib_data, a->attrib_len );
536       }
537     else if( !a->attrib_data && !b->attrib_data )
538       {
539         res = a->len - b->len;
540         if( !res )
541           res = memcmp( a->name, b->name, a->len );
542       }
543
544     return res;
545 }