edit-key is now complete
[gnupg.git] / g10 / free-packet.c
1 /* free-packet.c - cleanup stuff for packets
2  *      Copyright (C) 1998 Free Software Foundation, Inc.
3  *
4  * This file is part of GNUPG.
5  *
6  * GNUPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GNUPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <assert.h>
26
27 #include "packet.h"
28 #include "iobuf.h"
29 #include "mpi.h"
30 #include "util.h"
31 #include "cipher.h"
32 #include "memory.h"
33
34 void
35 free_symkey_enc( PKT_symkey_enc *enc )
36 {
37     m_free(enc);
38 }
39
40 void
41 free_pubkey_enc( PKT_pubkey_enc *enc )
42 {
43     int n, i;
44     n = pubkey_get_nenc( enc->pubkey_algo );
45     if( !n ) {
46         m_free(enc->data[0]);
47         enc->data[0] = NULL;
48     }
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     n = pubkey_get_nsig( sig->pubkey_algo );
59     if( !n ) {
60         m_free(sig->data[0]);
61         sig->data[0] = NULL;
62     }
63     for(i=0; i < n; i++ )
64         mpi_free( sig->data[i] );
65     m_free(sig->hashed_data);
66     m_free(sig->unhashed_data);
67     m_free(sig);
68 }
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         m_free(pk->pkey[0]);
79         pk->pkey[0] = NULL;
80     }
81     for(i=0; i < n; i++ ) {
82         mpi_free( pk->pkey[i] );
83         pk->pkey[i] = NULL;
84     }
85 }
86
87
88 void
89 free_public_key( PKT_public_key *pk )
90 {
91     release_public_key_parts( pk );
92     m_free(pk);
93 }
94
95 static void *
96 cp_fake_data( MPI a )
97 {
98     byte *d, *s;
99     u16 len;
100
101     if( !a )
102         return NULL;
103     s = (byte*)a;
104     len = (s[0] << 8) | s[1];
105     d = m_alloc( len+2 );
106     memcpy(d, s, len+2);
107     return d;
108 }
109
110 static void *
111 cp_data_block( byte *s )
112 {
113     byte *d;
114     u16 len;
115
116     if( !s )
117         return NULL;
118     len = (s[0] << 8) | s[1];
119     d = m_alloc( len+2 );
120     memcpy(d, s, len+2);
121     return d;
122 }
123
124
125 PKT_public_key *
126 copy_public_key( PKT_public_key *d, PKT_public_key *s )
127 {
128     int n, i;
129
130     if( !d )
131         d = m_alloc(sizeof *d);
132     memcpy( d, s, sizeof *d );
133     n = pubkey_get_npkey( s->pubkey_algo );
134     if( !n )
135         d->pkey[0] = cp_fake_data(s->pkey[0]);
136     else {
137         for(i=0; i < n; i++ )
138             d->pkey[i] = mpi_copy( s->pkey[i] );
139     }
140     return d;
141 }
142
143
144 PKT_signature *
145 copy_signature( PKT_signature *d, PKT_signature *s )
146 {
147     int n, i;
148
149     if( !d )
150         d = m_alloc(sizeof *d);
151     memcpy( d, s, sizeof *d );
152     n = pubkey_get_nsig( s->pubkey_algo );
153     if( !n )
154         d->data[0] = cp_fake_data(s->data[0]);
155     else {
156         for(i=0; i < n; i++ )
157             d->data[i] = mpi_copy( s->data[i] );
158     }
159     d->hashed_data = cp_data_block(s->hashed_data);
160     d->unhashed_data = cp_data_block(s->unhashed_data);
161     return d;
162 }
163
164
165 PKT_user_id *
166 copy_user_id( PKT_user_id *d, PKT_user_id *s )
167 {
168     if( !d )
169         d = m_alloc(sizeof *d + s->len - 1 );
170     memcpy( d, s, sizeof *d + s->len - 1 );
171     return d;
172 }
173
174
175
176 void
177 release_secret_key_parts( PKT_secret_key *sk )
178 {
179     int n, i;
180
181     n = pubkey_get_nskey( sk->pubkey_algo );
182     if( !n ) {
183         m_free(sk->skey[0]);
184         sk->skey[0] = NULL;
185     }
186     for(i=0; i < n; i++ ) {
187         mpi_free( sk->skey[i] );
188         sk->skey[i] = NULL;
189     }
190 }
191
192 void
193 free_secret_key( PKT_secret_key *sk )
194 {
195     release_secret_key_parts( sk );
196     m_free(sk);
197 }
198
199 PKT_secret_key *
200 copy_secret_key( PKT_secret_key *d, PKT_secret_key *s )
201 {
202     int n, i;
203
204     if( !d )
205         d = m_alloc(sizeof *d);
206     memcpy( d, s, sizeof *d );
207     n = pubkey_get_nskey( s->pubkey_algo );
208     if( !n )
209         d->skey[0] = cp_fake_data(s->skey[0]);
210     else {
211         for(i=0; i < n; i++ )
212             d->skey[i] = mpi_copy( s->skey[i] );
213     }
214     return d;
215 }
216
217 void
218 free_comment( PKT_comment *rem )
219 {
220     m_free(rem);
221 }
222
223 void
224 free_user_id( PKT_user_id *uid )
225 {
226     m_free(uid);
227 }
228
229 void
230 free_compressed( PKT_compressed *zd )
231 {
232     if( zd->buf ) { /* have to skip some bytes */
233         /* don't have any information about the length, so
234          * we assume this is the last packet */
235         while( iobuf_get(zd->buf) != -1 )
236             ;
237     }
238     m_free(zd);
239 }
240
241 void
242 free_encrypted( PKT_encrypted *ed )
243 {
244     if( ed->buf ) { /* have to skip some bytes */
245         if( iobuf_in_block_mode(ed->buf) ) {
246             while( iobuf_get(ed->buf) != -1 )
247                 ;
248             iobuf_set_block_mode(ed->buf, 0);
249         }
250         else {
251             for( ; ed->len; ed->len-- ) /* skip the packet */
252                 iobuf_get(ed->buf);
253         }
254     }
255     m_free(ed);
256 }
257
258
259 void
260 free_plaintext( PKT_plaintext *pt )
261 {
262     if( pt->buf ) { /* have to skip some bytes */
263         if( iobuf_in_block_mode(pt->buf) ) {
264             while( iobuf_get(pt->buf) != -1 )
265                 ;
266             iobuf_set_block_mode(pt->buf, 0);
267         }
268         else {
269             for( ; pt->len; pt->len-- ) /* skip the packet */
270                 iobuf_get(pt->buf);
271         }
272     }
273     m_free(pt);
274 }
275
276 /****************
277  * Free the packet in pkt.
278  */
279 void
280 free_packet( PACKET *pkt )
281 {
282     if( !pkt || !pkt->pkt.generic )
283         return;
284
285     if( DBG_MEMORY )
286         log_debug("free_packet() type=%d\n", pkt->pkttype );
287
288     switch( pkt->pkttype ) {
289       case PKT_SIGNATURE:
290         free_seckey_enc( pkt->pkt.signature );
291         break;
292       case PKT_PUBKEY_ENC:
293         free_pubkey_enc( pkt->pkt.pubkey_enc );
294         break;
295       case PKT_SYMKEY_ENC:
296         free_symkey_enc( pkt->pkt.symkey_enc );
297         break;
298       case PKT_PUBLIC_KEY:
299       case PKT_PUBLIC_SUBKEY:
300         free_public_key( pkt->pkt.public_key );
301         break;
302       case PKT_SECRET_KEY:
303       case PKT_SECRET_SUBKEY:
304         free_secret_key( pkt->pkt.secret_key );
305         break;
306       case PKT_COMMENT:
307         free_comment( pkt->pkt.comment );
308         break;
309       case PKT_USER_ID:
310         free_user_id( pkt->pkt.user_id );
311         break;
312       case PKT_COMPRESSED:
313         free_compressed( pkt->pkt.compressed);
314         break;
315       case PKT_ENCRYPTED:
316         free_encrypted( pkt->pkt.encrypted );
317         break;
318       case PKT_PLAINTEXT:
319         free_plaintext( pkt->pkt.plaintext );
320         break;
321       default:
322         m_free( pkt->pkt.generic );
323         break;
324     }
325     pkt->pkt.generic = NULL;
326 }
327
328 /****************
329  * Returns 0 if they match.
330  */
331 int
332 cmp_public_keys( PKT_public_key *a, PKT_public_key *b )
333 {
334     int n, i;
335
336     if( a->timestamp != b->timestamp )
337         return -1;
338     if( a->valid_days != b->valid_days )
339         return -1;
340     if( a->pubkey_algo != b->pubkey_algo )
341         return -1;
342
343     n = pubkey_get_npkey( b->pubkey_algo );
344     if( !n )
345         return -1; /* can't compare due to unknown algorithm */
346     for(i=0; i < n; i++ ) {
347         if( mpi_cmp( a->pkey[i], b->pkey[i] ) )
348             return -1;
349     }
350
351     return 0;
352 }
353
354 /****************
355  * Returns 0 if they match.
356  */
357 int
358 cmp_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk )
359 {
360     int n, i;
361
362     if( pk->timestamp != sk->timestamp )
363         return -1;
364     if( pk->valid_days != sk->valid_days )
365         return -1;
366     if( pk->pubkey_algo != sk->pubkey_algo )
367         return -1;
368
369     n = pubkey_get_npkey( pk->pubkey_algo );
370     if( !n )
371         return -1; /* can't compare due to unknown algorithm */
372     for(i=0; i < n; i++ ) {
373         if( mpi_cmp( pk->pkey[i] , sk->skey[i] ) )
374             return -1;
375     }
376     return 0;
377 }
378
379 int
380 cmp_user_ids( PKT_user_id *a, PKT_user_id *b )
381 {
382     int res;
383
384     res = a->len - b->len;
385     if( !res )
386         res = memcmp( a->name, b->name, a->len );
387     return res;
388 }
389
390