intermediate release
[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_nenc( 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
111 PKT_public_key *
112 copy_public_key( PKT_public_key *d, PKT_public_key *s )
113 {
114     int n, i;
115
116     if( !d )
117         d = m_alloc(sizeof *d);
118     memcpy( d, s, sizeof *d );
119     n = pubkey_get_npkey( s->pubkey_algo );
120     if( !n )
121         d->pkey[0] = cp_fake_data(s->pkey[0]);
122     else {
123         for(i=0; i < n; i++ )
124             d->pkey[i] = mpi_copy( s->pkey[i] );
125     }
126     return d;
127 }
128
129 void
130 release_secret_key_parts( PKT_secret_key *sk )
131 {
132     int n, i;
133
134     n = pubkey_get_nskey( sk->pubkey_algo );
135     if( !n ) {
136         m_free(sk->skey[0]);
137         sk->skey[0] = NULL;
138     }
139     for(i=0; i < n; i++ ) {
140         mpi_free( sk->skey[i] );
141         sk->skey[i] = NULL;
142     }
143 }
144
145 void
146 free_secret_key( PKT_secret_key *sk )
147 {
148     release_secret_key_parts( sk );
149     m_free(sk);
150 }
151
152 PKT_secret_key *
153 copy_secret_key( PKT_secret_key *d, PKT_secret_key *s )
154 {
155     int n, i;
156
157     if( !d )
158         d = m_alloc(sizeof *d);
159     memcpy( d, s, sizeof *d );
160     n = pubkey_get_nskey( s->pubkey_algo );
161     if( !n )
162         d->skey[0] = cp_fake_data(s->skey[0]);
163     else {
164         for(i=0; i < n; i++ )
165             d->skey[i] = mpi_copy( s->skey[i] );
166     }
167     return d;
168 }
169
170 void
171 free_comment( PKT_comment *rem )
172 {
173     m_free(rem);
174 }
175
176 void
177 free_user_id( PKT_user_id *uid )
178 {
179     m_free(uid);
180 }
181
182 void
183 free_compressed( PKT_compressed *zd )
184 {
185     if( zd->buf ) { /* have to skip some bytes */
186         /* don't have any information about the length, so
187          * we assume this is the last packet */
188         while( iobuf_get(zd->buf) != -1 )
189             ;
190     }
191     m_free(zd);
192 }
193
194 void
195 free_encrypted( PKT_encrypted *ed )
196 {
197     if( ed->buf ) { /* have to skip some bytes */
198         if( iobuf_in_block_mode(ed->buf) ) {
199             while( iobuf_get(ed->buf) != -1 )
200                 ;
201             iobuf_set_block_mode(ed->buf, 0);
202         }
203         else {
204             for( ; ed->len; ed->len-- ) /* skip the packet */
205                 iobuf_get(ed->buf);
206         }
207     }
208     m_free(ed);
209 }
210
211
212 void
213 free_plaintext( PKT_plaintext *pt )
214 {
215     if( pt->buf ) { /* have to skip some bytes */
216         if( iobuf_in_block_mode(pt->buf) ) {
217             while( iobuf_get(pt->buf) != -1 )
218                 ;
219             iobuf_set_block_mode(pt->buf, 0);
220         }
221         else {
222             for( ; pt->len; pt->len-- ) /* skip the packet */
223                 iobuf_get(pt->buf);
224         }
225     }
226     m_free(pt);
227 }
228
229 /****************
230  * Free the packet in pkt.
231  */
232 void
233 free_packet( PACKET *pkt )
234 {
235     if( !pkt || !pkt->pkt.generic )
236         return;
237
238     if( DBG_MEMORY )
239         log_debug("free_packet() type=%d\n", pkt->pkttype );
240
241     switch( pkt->pkttype ) {
242       case PKT_SIGNATURE:
243         free_seckey_enc( pkt->pkt.signature );
244         break;
245       case PKT_PUBKEY_ENC:
246         free_pubkey_enc( pkt->pkt.pubkey_enc );
247         break;
248       case PKT_SYMKEY_ENC:
249         free_symkey_enc( pkt->pkt.symkey_enc );
250         break;
251       case PKT_PUBLIC_KEY:
252       case PKT_PUBLIC_SUBKEY:
253         free_public_key( pkt->pkt.public_key );
254         break;
255       case PKT_SECRET_KEY:
256       case PKT_SECRET_SUBKEY:
257         free_secret_key( pkt->pkt.secret_key );
258         break;
259       case PKT_COMMENT:
260         free_comment( pkt->pkt.comment );
261         break;
262       case PKT_USER_ID:
263         free_user_id( pkt->pkt.user_id );
264         break;
265       case PKT_COMPRESSED:
266         free_compressed( pkt->pkt.compressed);
267         break;
268       case PKT_ENCRYPTED:
269         free_encrypted( pkt->pkt.encrypted );
270         break;
271       case PKT_PLAINTEXT:
272         free_plaintext( pkt->pkt.plaintext );
273         break;
274       default:
275         m_free( pkt->pkt.generic );
276         break;
277     }
278     pkt->pkt.generic = NULL;
279 }
280
281 /****************
282  * Returns 0 if they match.
283  */
284 int
285 cmp_public_keys( PKT_public_key *a, PKT_public_key *b )
286 {
287     int n, i;
288
289     if( a->timestamp != b->timestamp )
290         return -1;
291     if( a->valid_days != b->valid_days )
292         return -1;
293     if( a->pubkey_algo != b->pubkey_algo )
294         return -1;
295
296     n = pubkey_get_npkey( b->pubkey_algo );
297     if( !n )
298         return -1; /* can't compare due to unknown algorithm */
299     for(i=0; i < n; i++ ) {
300         if( mpi_cmp( a->pkey[i], b->pkey[i] ) )
301             return -1;
302     }
303
304     return 0;
305 }
306
307 /****************
308  * Returns 0 if they match.
309  */
310 int
311 cmp_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk )
312 {
313     int n, i;
314
315     if( pk->timestamp != sk->timestamp )
316         return -1;
317     if( pk->valid_days != sk->valid_days )
318         return -1;
319     if( pk->pubkey_algo != sk->pubkey_algo )
320         return -1;
321
322     n = pubkey_get_npkey( pk->pubkey_algo );
323     if( !n )
324         return -1; /* can't compare due to unknown algorithm */
325     for(i=0; i < n; i++ ) {
326         if( mpi_cmp( pk->pkey[i] , sk->skey[i] ) )
327             return -1;
328     }
329     return 0;
330 }
331
332 int
333 cmp_user_ids( PKT_user_id *a, PKT_user_id *b )
334 {
335     int res;
336
337     res = a->len - b->len;
338     if( !res )
339         res = memcmp( a->name, b->name, a->len );
340     return res;
341 }
342
343