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