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