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