Line data Source code
1 : /* free-packet.c - cleanup stuff for packets
2 : * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
3 : * 2005, 2010 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 3 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, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include <config.h>
22 : #include <stdio.h>
23 : #include <stdlib.h>
24 : #include <string.h>
25 :
26 : #include "gpg.h"
27 : #include "util.h"
28 : #include "packet.h"
29 : #include "../common/iobuf.h"
30 : #include "options.h"
31 :
32 :
33 : /* This is mpi_copy with a fix for opaque MPIs which store a NULL
34 : pointer. This will also be fixed in Libggcrypt 1.7.0. */
35 : static gcry_mpi_t
36 7320 : my_mpi_copy (gcry_mpi_t a)
37 : {
38 7320 : if (a
39 7320 : && gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)
40 363 : && !gcry_mpi_get_opaque (a, NULL))
41 0 : return NULL;
42 :
43 7320 : return gcry_mpi_copy (a);
44 : }
45 :
46 :
47 : void
48 224 : free_symkey_enc( PKT_symkey_enc *enc )
49 : {
50 224 : xfree(enc);
51 224 : }
52 :
53 : void
54 523 : free_pubkey_enc( PKT_pubkey_enc *enc )
55 : {
56 : int n, i;
57 523 : n = pubkey_get_nenc( enc->pubkey_algo );
58 523 : if( !n )
59 0 : mpi_release(enc->data[0]);
60 1552 : for(i=0; i < n; i++ )
61 1029 : mpi_release( enc->data[i] );
62 523 : xfree(enc);
63 523 : }
64 :
65 : void
66 7268 : free_seckey_enc( PKT_signature *sig )
67 : {
68 : int n, i;
69 :
70 7268 : n = pubkey_get_nsig( sig->pubkey_algo );
71 7268 : if( !n )
72 0 : mpi_release(sig->data[0]);
73 20801 : for(i=0; i < n; i++ )
74 13533 : mpi_release( sig->data[i] );
75 :
76 7268 : xfree(sig->revkey);
77 7268 : xfree(sig->hashed);
78 7268 : xfree(sig->unhashed);
79 :
80 7268 : if (sig->pka_info)
81 : {
82 0 : xfree (sig->pka_info->uri);
83 0 : xfree (sig->pka_info);
84 : }
85 7268 : xfree (sig->signers_uid);
86 :
87 7268 : xfree(sig);
88 7268 : }
89 :
90 :
91 : void
92 7142 : release_public_key_parts (PKT_public_key *pk)
93 : {
94 : int n, i;
95 :
96 7142 : if (pk->seckey_info)
97 36 : n = pubkey_get_nskey (pk->pubkey_algo);
98 : else
99 7106 : n = pubkey_get_npkey (pk->pubkey_algo);
100 7142 : if (!n)
101 71 : mpi_release (pk->pkey[0]);
102 30004 : for (i=0; i < n; i++ )
103 : {
104 22862 : mpi_release (pk->pkey[i]);
105 22862 : pk->pkey[i] = NULL;
106 : }
107 7142 : if (pk->seckey_info)
108 : {
109 36 : xfree (pk->seckey_info);
110 36 : pk->seckey_info = NULL;
111 : }
112 7142 : if (pk->prefs)
113 : {
114 5778 : xfree (pk->prefs);
115 5778 : pk->prefs = NULL;
116 : }
117 7142 : if (pk->user_id)
118 : {
119 275 : free_user_id (pk->user_id);
120 275 : pk->user_id = NULL;
121 : }
122 7142 : if (pk->revkey)
123 : {
124 2 : xfree(pk->revkey);
125 2 : pk->revkey=NULL;
126 2 : pk->numrevkeys=0;
127 : }
128 7142 : if (pk->serialno)
129 : {
130 0 : xfree (pk->serialno);
131 0 : pk->serialno = NULL;
132 : }
133 7142 : }
134 :
135 :
136 : /* Free an allocated public key structure including all parts.
137 : Passing NULL is allowed. */
138 : void
139 7140 : free_public_key (PKT_public_key *pk)
140 : {
141 7140 : if (pk)
142 : {
143 7140 : release_public_key_parts (pk);
144 7140 : xfree(pk);
145 : }
146 7140 : }
147 :
148 :
149 : static subpktarea_t *
150 0 : cp_subpktarea (subpktarea_t *s )
151 : {
152 : subpktarea_t *d;
153 :
154 0 : if( !s )
155 0 : return NULL;
156 0 : d = xmalloc (sizeof (*d) + s->size - 1 );
157 0 : d->size = s->size;
158 0 : d->len = s->len;
159 0 : memcpy (d->data, s->data, s->len);
160 0 : return d;
161 : }
162 :
163 : /*
164 : * Return a copy of the preferences
165 : */
166 : prefitem_t *
167 6730 : copy_prefs (const prefitem_t *prefs)
168 : {
169 : size_t n;
170 : prefitem_t *new;
171 :
172 6730 : if (!prefs)
173 83 : return NULL;
174 :
175 6647 : for (n=0; prefs[n].type; n++)
176 : ;
177 6647 : new = xmalloc ( sizeof (*new) * (n+1));
178 57750 : for (n=0; prefs[n].type; n++) {
179 51103 : new[n].type = prefs[n].type;
180 51103 : new[n].value = prefs[n].value;
181 : }
182 6647 : new[n].type = PREFTYPE_NONE;
183 6647 : new[n].value = 0;
184 :
185 6647 : return new;
186 : }
187 :
188 :
189 : /* Copy the public key S to D. If D is NULL allocate a new public key
190 : structure. If S has seckret key infos, only the public stuff is
191 : copied. */
192 : PKT_public_key *
193 2229 : copy_public_key (PKT_public_key *d, PKT_public_key *s)
194 : {
195 : int n, i;
196 :
197 2229 : if (!d)
198 705 : d = xmalloc (sizeof *d);
199 2229 : memcpy (d, s, sizeof *d);
200 2229 : d->seckey_info = NULL;
201 2229 : d->user_id = scopy_user_id (s->user_id);
202 2229 : d->prefs = copy_prefs (s->prefs);
203 :
204 2229 : n = pubkey_get_npkey (s->pubkey_algo);
205 2229 : i = 0;
206 2229 : if (!n)
207 0 : d->pkey[i++] = my_mpi_copy (s->pkey[0]);
208 : else
209 : {
210 9549 : for (; i < n; i++ )
211 7320 : d->pkey[i] = my_mpi_copy (s->pkey[i]);
212 : }
213 10512 : for (; i < PUBKEY_MAX_NSKEY; i++)
214 8283 : d->pkey[i] = NULL;
215 :
216 2229 : if (!s->revkey && s->numrevkeys)
217 0 : BUG();
218 2229 : if (s->numrevkeys)
219 : {
220 0 : d->revkey = xmalloc(sizeof(struct revocation_key)*s->numrevkeys);
221 0 : memcpy(d->revkey,s->revkey,sizeof(struct revocation_key)*s->numrevkeys);
222 : }
223 : else
224 2229 : d->revkey = NULL;
225 2229 : return d;
226 : }
227 :
228 :
229 :
230 : static pka_info_t *
231 0 : cp_pka_info (const pka_info_t *s)
232 : {
233 0 : pka_info_t *d = xmalloc (sizeof *s + strlen (s->email));
234 :
235 0 : d->valid = s->valid;
236 0 : d->checked = s->checked;
237 0 : d->uri = s->uri? xstrdup (s->uri):NULL;
238 0 : memcpy (d->fpr, s->fpr, sizeof s->fpr);
239 0 : strcpy (d->email, s->email);
240 0 : return d;
241 : }
242 :
243 :
244 : PKT_signature *
245 0 : copy_signature( PKT_signature *d, PKT_signature *s )
246 : {
247 : int n, i;
248 :
249 0 : if( !d )
250 0 : d = xmalloc(sizeof *d);
251 0 : memcpy( d, s, sizeof *d );
252 0 : n = pubkey_get_nsig( s->pubkey_algo );
253 0 : if( !n )
254 0 : d->data[0] = my_mpi_copy(s->data[0]);
255 : else {
256 0 : for(i=0; i < n; i++ )
257 0 : d->data[i] = my_mpi_copy( s->data[i] );
258 : }
259 0 : d->pka_info = s->pka_info? cp_pka_info (s->pka_info) : NULL;
260 0 : d->hashed = cp_subpktarea (s->hashed);
261 0 : d->unhashed = cp_subpktarea (s->unhashed);
262 0 : if (s->signers_uid)
263 0 : d->signers_uid = xstrdup (s->signers_uid);
264 0 : if(s->numrevkeys)
265 : {
266 0 : d->revkey=NULL;
267 0 : d->numrevkeys=0;
268 0 : parse_revkeys(d);
269 : }
270 0 : return d;
271 : }
272 :
273 :
274 : /*
275 : * shallow copy of the user ID
276 : */
277 : PKT_user_id *
278 4367 : scopy_user_id (PKT_user_id *s)
279 : {
280 4367 : if (s)
281 275 : s->ref++;
282 4367 : return s;
283 : }
284 :
285 :
286 :
287 : void
288 0 : free_comment( PKT_comment *rem )
289 : {
290 0 : xfree(rem);
291 0 : }
292 :
293 : void
294 3511 : free_attributes(PKT_user_id *uid)
295 : {
296 3511 : xfree(uid->attribs);
297 3511 : xfree(uid->attrib_data);
298 :
299 3511 : uid->attribs=NULL;
300 3511 : uid->attrib_data=NULL;
301 3511 : uid->attrib_len=0;
302 3511 : }
303 :
304 : void
305 3786 : free_user_id (PKT_user_id *uid)
306 : {
307 3786 : log_assert (uid->ref > 0);
308 3786 : if (--uid->ref)
309 4061 : return;
310 :
311 3511 : free_attributes(uid);
312 3511 : xfree (uid->prefs);
313 3511 : xfree (uid->namehash);
314 3511 : xfree (uid->mbox);
315 3511 : xfree (uid);
316 : }
317 :
318 : void
319 563 : free_compressed( PKT_compressed *zd )
320 : {
321 563 : if( zd->buf ) { /* have to skip some bytes */
322 : /* don't have any information about the length, so
323 : * we assume this is the last packet */
324 0 : while( iobuf_read( zd->buf, NULL, 1<<30 ) != -1 )
325 : ;
326 : }
327 563 : xfree(zd);
328 563 : }
329 :
330 : void
331 481 : free_encrypted( PKT_encrypted *ed )
332 : {
333 481 : if( ed->buf ) { /* have to skip some bytes */
334 0 : if( ed->is_partial ) {
335 0 : while( iobuf_read( ed->buf, NULL, 1<<30 ) != -1 )
336 : ;
337 : }
338 : else {
339 0 : while( ed->len ) { /* skip the packet */
340 0 : int n = iobuf_read( ed->buf, NULL, ed->len );
341 0 : if( n == -1 )
342 0 : ed->len = 0;
343 : else
344 0 : ed->len -= n;
345 : }
346 : }
347 : }
348 481 : xfree(ed);
349 481 : }
350 :
351 :
352 : void
353 1139 : free_plaintext( PKT_plaintext *pt )
354 : {
355 1139 : if( pt->buf ) { /* have to skip some bytes */
356 560 : if( pt->is_partial ) {
357 0 : while( iobuf_read( pt->buf, NULL, 1<<30 ) != -1 )
358 : ;
359 : }
360 : else {
361 1127 : while( pt->len ) { /* skip the packet */
362 7 : int n = iobuf_read( pt->buf, NULL, pt->len );
363 7 : if( n == -1 )
364 0 : pt->len = 0;
365 : else
366 7 : pt->len -= n;
367 : }
368 : }
369 : }
370 1139 : xfree(pt);
371 1139 : }
372 :
373 : /****************
374 : * Free the packet in pkt.
375 : */
376 : void
377 24665 : free_packet( PACKET *pkt )
378 : {
379 24665 : if( !pkt || !pkt->pkt.generic )
380 29039 : return;
381 :
382 20291 : if( DBG_MEMORY )
383 0 : log_debug("free_packet() type=%d\n", pkt->pkttype );
384 :
385 20291 : switch( pkt->pkttype ) {
386 : case PKT_SIGNATURE:
387 7140 : free_seckey_enc( pkt->pkt.signature );
388 7140 : break;
389 : case PKT_PUBKEY_ENC:
390 268 : free_pubkey_enc( pkt->pkt.pubkey_enc );
391 268 : break;
392 : case PKT_SYMKEY_ENC:
393 224 : free_symkey_enc( pkt->pkt.symkey_enc );
394 224 : break;
395 : case PKT_PUBLIC_KEY:
396 : case PKT_PUBLIC_SUBKEY:
397 : case PKT_SECRET_KEY:
398 : case PKT_SECRET_SUBKEY:
399 5709 : free_public_key (pkt->pkt.public_key);
400 5709 : break;
401 : case PKT_COMMENT:
402 0 : free_comment( pkt->pkt.comment );
403 0 : break;
404 : case PKT_USER_ID:
405 3511 : free_user_id( pkt->pkt.user_id );
406 3511 : break;
407 : case PKT_COMPRESSED:
408 563 : free_compressed( pkt->pkt.compressed);
409 563 : break;
410 : case PKT_ENCRYPTED:
411 : case PKT_ENCRYPTED_MDC:
412 481 : free_encrypted( pkt->pkt.encrypted );
413 481 : break;
414 : case PKT_PLAINTEXT:
415 1139 : free_plaintext( pkt->pkt.plaintext );
416 1139 : break;
417 : default:
418 1256 : xfree( pkt->pkt.generic );
419 1256 : break;
420 : }
421 20291 : pkt->pkt.generic = NULL;
422 : }
423 :
424 : /****************
425 : * returns 0 if they match.
426 : */
427 : int
428 116 : cmp_public_keys( PKT_public_key *a, PKT_public_key *b )
429 : {
430 : int n, i;
431 :
432 116 : if( a->timestamp != b->timestamp )
433 8 : return -1;
434 108 : if( a->version < 4 && a->expiredate != b->expiredate )
435 0 : return -1;
436 108 : if( a->pubkey_algo != b->pubkey_algo )
437 0 : return -1;
438 :
439 108 : n = pubkey_get_npkey( b->pubkey_algo );
440 108 : if( !n ) { /* unknown algorithm, rest is in opaque MPI */
441 0 : if( mpi_cmp( a->pkey[0], b->pkey[0] ) )
442 0 : return -1; /* can't compare due to unknown algorithm */
443 : } else {
444 458 : for(i=0; i < n; i++ ) {
445 350 : if( mpi_cmp( a->pkey[i], b->pkey[i] ) )
446 0 : return -1;
447 : }
448 : }
449 :
450 108 : return 0;
451 : }
452 :
453 :
454 :
455 : int
456 2656 : cmp_signatures( PKT_signature *a, PKT_signature *b )
457 : {
458 : int n, i;
459 :
460 2656 : if( a->keyid[0] != b->keyid[0] )
461 2335 : return -1;
462 321 : if( a->keyid[1] != b->keyid[1] )
463 0 : return -1;
464 321 : if( a->pubkey_algo != b->pubkey_algo )
465 0 : return -1;
466 :
467 321 : n = pubkey_get_nsig( a->pubkey_algo );
468 321 : if( !n )
469 0 : return -1; /* can't compare due to unknown algorithm */
470 517 : for(i=0; i < n; i++ ) {
471 415 : if( mpi_cmp( a->data[i] , b->data[i] ) )
472 219 : return -1;
473 : }
474 102 : return 0;
475 : }
476 :
477 :
478 : /****************
479 : * Returns: true if the user ids do not match
480 : */
481 : int
482 166 : cmp_user_ids( PKT_user_id *a, PKT_user_id *b )
483 : {
484 166 : int res=1;
485 :
486 166 : if( a == b )
487 0 : return 0;
488 :
489 166 : if( a->attrib_data && b->attrib_data )
490 : {
491 0 : res = a->attrib_len - b->attrib_len;
492 0 : if( !res )
493 0 : res = memcmp( a->attrib_data, b->attrib_data, a->attrib_len );
494 : }
495 166 : else if( !a->attrib_data && !b->attrib_data )
496 : {
497 166 : res = a->len - b->len;
498 166 : if( !res )
499 100 : res = memcmp( a->name, b->name, a->len );
500 : }
501 :
502 166 : return res;
503 : }
|