/src/gnupg/g10/free-packet.c
Line | Count | Source |
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 "../common/util.h" |
28 | | #include "packet.h" |
29 | | #include "../common/iobuf.h" |
30 | | #include "options.h" |
31 | | |
32 | | |
33 | | /* This is a wrapper for mpi_copy which handles opaque MPIs with a |
34 | | * NULL pointer as opaque data; e.g. gcry_mpi_set_opaque(a, NULL, 0). |
35 | | * It seems that at least gcry_mpi_set_opaque_copy does not yet handle |
36 | | * this correctly. */ |
37 | | static gcry_mpi_t |
38 | | my_mpi_copy (gcry_mpi_t a) |
39 | 0 | { |
40 | 0 | if (a |
41 | 0 | && gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE) |
42 | 0 | && !gcry_mpi_get_opaque (a, NULL)) |
43 | 0 | return NULL; |
44 | | |
45 | 0 | return gcry_mpi_copy (a); |
46 | 0 | } |
47 | | |
48 | | |
49 | | void |
50 | | free_symkey_enc( PKT_symkey_enc *enc ) |
51 | 1.41k | { |
52 | 1.41k | if (enc) |
53 | 1.41k | xfree (enc->seskey); |
54 | 1.41k | xfree(enc); |
55 | 1.41k | } |
56 | | |
57 | | |
58 | | /* This is the core of free_pubkey_enc but does only release the |
59 | | * allocated members of ENC. */ |
60 | | void |
61 | | release_pubkey_enc_parts (PKT_pubkey_enc *enc) |
62 | 21.2k | { |
63 | 21.2k | int n, i; |
64 | 21.2k | n = pubkey_get_nenc( enc->pubkey_algo ); |
65 | 21.2k | if (!n) |
66 | 21.2k | mpi_release (enc->data[0]); |
67 | 41.0k | for (i=0; i < n; i++ ) |
68 | 21.2k | mpi_release (enc->data[i]); |
69 | 21.2k | } |
70 | | |
71 | | void |
72 | | free_pubkey_enc (PKT_pubkey_enc *enc) |
73 | 21.2k | { |
74 | 21.2k | release_pubkey_enc_parts (enc); |
75 | 21.2k | xfree (enc); |
76 | 21.2k | } |
77 | | |
78 | | |
79 | | /* Copy everything from SRC to DST. This assumes that DST has been |
80 | | * malloced or statically allocated. */ |
81 | | void |
82 | | copy_pubkey_enc_parts (PKT_pubkey_enc *dst, PKT_pubkey_enc *src) |
83 | 0 | { |
84 | 0 | int n, i; |
85 | |
|
86 | 0 | dst->keyid[0] = src->keyid[0]; |
87 | 0 | dst->keyid[1] = src->keyid[1]; |
88 | 0 | dst->version = src->version; |
89 | 0 | dst->pubkey_algo = src->pubkey_algo; |
90 | 0 | dst->seskey_algo = src->seskey_algo; |
91 | 0 | dst->throw_keyid = src->throw_keyid; |
92 | 0 | dst->fprlen = src->fprlen; |
93 | 0 | memcpy (dst->fpr, src->fpr, sizeof src->fpr); |
94 | |
|
95 | 0 | if (!(n = pubkey_get_nenc (dst->pubkey_algo))) |
96 | 0 | n = 1; /* All data is in the first item as an opaque MPI. */ |
97 | 0 | for (i=0; i < n; i++) |
98 | 0 | dst->data[i] = my_mpi_copy (src->data[i]); |
99 | 0 | for (; i < PUBKEY_MAX_NENC; i++) |
100 | 0 | dst->data[i] = NULL; |
101 | 0 | } |
102 | | |
103 | | |
104 | | static void |
105 | | free_onepass_sig (PKT_onepass_sig *ops) |
106 | 40.3k | { |
107 | 40.3k | if (ops) |
108 | 40.3k | { |
109 | 40.3k | mpi_release (ops->salt); |
110 | 40.3k | xfree (ops); |
111 | 40.3k | } |
112 | 40.3k | } |
113 | | |
114 | | |
115 | | void |
116 | | free_seckey_enc( PKT_signature *sig ) |
117 | 519k | { |
118 | 519k | int n, i; |
119 | | |
120 | 519k | n = pubkey_get_nsig( sig->pubkey_algo ); |
121 | 519k | if( !n ) |
122 | 519k | mpi_release(sig->data[0]); |
123 | 525k | for(i=0; i < n; i++ ) |
124 | 519k | mpi_release( sig->data[i] ); |
125 | | |
126 | 519k | xfree(sig->revkey); |
127 | 519k | xfree(sig->hashed); |
128 | 519k | xfree(sig->unhashed); |
129 | 519k | mpi_release (sig->salt); |
130 | | |
131 | | /* Do not forget to update copy_signature() too. */ |
132 | 519k | xfree(sig->rev_subject_info); |
133 | 519k | xfree (sig->signers_uid); |
134 | | |
135 | 519k | xfree(sig); |
136 | 519k | } |
137 | | |
138 | | |
139 | | void |
140 | | release_public_key_parts (PKT_public_key *pk) |
141 | 87.4k | { |
142 | 87.4k | int n, i; |
143 | | |
144 | 87.4k | if (pk->seckey_info) |
145 | 42.6k | n = pubkey_get_nskey (pk->pubkey_algo); |
146 | 44.7k | else |
147 | 44.7k | n = pubkey_get_npkey (pk->pubkey_algo); |
148 | 87.4k | if (!n) |
149 | 87.4k | mpi_release (pk->pkey[0]); |
150 | 369k | for (i=0; i < n; i++ ) |
151 | 281k | { |
152 | 281k | mpi_release (pk->pkey[i]); |
153 | 281k | pk->pkey[i] = NULL; |
154 | 281k | } |
155 | 87.4k | if (pk->seckey_info) |
156 | 42.6k | { |
157 | 42.6k | xfree (pk->seckey_info); |
158 | 42.6k | pk->seckey_info = NULL; |
159 | 42.6k | } |
160 | 87.4k | if (pk->prefs) |
161 | 0 | { |
162 | 0 | xfree (pk->prefs); |
163 | 0 | pk->prefs = NULL; |
164 | 0 | } |
165 | 87.4k | if (pk->dks_prefs) |
166 | 0 | { |
167 | 0 | xfree (pk->dks_prefs); |
168 | 0 | pk->dks_prefs = NULL; |
169 | 0 | } |
170 | 87.4k | free_user_id (pk->user_id); |
171 | 87.4k | pk->user_id = NULL; |
172 | 87.4k | if (pk->revkey) |
173 | 0 | { |
174 | 0 | xfree(pk->revkey); |
175 | 0 | pk->revkey=NULL; |
176 | 0 | pk->numrevkeys=0; |
177 | 0 | } |
178 | 87.4k | if (pk->serialno) |
179 | 0 | { |
180 | 0 | xfree (pk->serialno); |
181 | 0 | pk->serialno = NULL; |
182 | 0 | } |
183 | 87.4k | if (pk->updateurl) |
184 | 0 | { |
185 | 0 | xfree (pk->updateurl); |
186 | 0 | pk->updateurl = NULL; |
187 | 0 | } |
188 | 87.4k | if (pk->revoked.reason_comment) |
189 | 0 | { |
190 | 0 | xfree (pk->revoked.reason_comment); |
191 | 0 | pk->revoked.reason_comment = NULL; |
192 | 0 | } |
193 | 87.4k | } |
194 | | |
195 | | |
196 | | /* Free an allocated public key structure including all parts. |
197 | | Passing NULL is allowed. */ |
198 | | void |
199 | | free_public_key (PKT_public_key *pk) |
200 | 167k | { |
201 | 167k | if (pk) |
202 | 87.4k | { |
203 | 87.4k | release_public_key_parts (pk); |
204 | 87.4k | xfree(pk); |
205 | 87.4k | } |
206 | 167k | } |
207 | | |
208 | | |
209 | | static subpktarea_t * |
210 | | cp_subpktarea (subpktarea_t *s ) |
211 | 0 | { |
212 | 0 | subpktarea_t *d; |
213 | |
|
214 | 0 | if( !s ) |
215 | 0 | return NULL; |
216 | 0 | d = xmalloc (sizeof (*d) + s->size - 1 ); |
217 | 0 | d->size = s->size; |
218 | 0 | d->len = s->len; |
219 | 0 | memcpy (d->data, s->data, s->len); |
220 | 0 | return d; |
221 | 0 | } |
222 | | |
223 | | /* |
224 | | * Return a copy of the preferences |
225 | | */ |
226 | | prefitem_t * |
227 | | copy_prefs (const prefitem_t *prefs) |
228 | 0 | { |
229 | 0 | size_t n; |
230 | 0 | prefitem_t *new; |
231 | |
|
232 | 0 | if (!prefs) |
233 | 0 | return NULL; |
234 | | |
235 | 0 | for (n=0; prefs[n].type; n++) |
236 | 0 | ; |
237 | 0 | new = xmalloc ( sizeof (*new) * (n+1)); |
238 | 0 | for (n=0; prefs[n].type; n++) { |
239 | 0 | new[n].type = prefs[n].type; |
240 | 0 | new[n].value = prefs[n].value; |
241 | 0 | } |
242 | 0 | new[n].type = PREFTYPE_NONE; |
243 | 0 | new[n].value = 0; |
244 | |
|
245 | 0 | return new; |
246 | 0 | } |
247 | | |
248 | | |
249 | | /* Copy the public key S to D. If D is NULL allocate a new public key |
250 | | * structure. Only the basic stuff is copied; not any ancillary |
251 | | * data. */ |
252 | | PKT_public_key * |
253 | | copy_public_key_basics (PKT_public_key *d, PKT_public_key *s) |
254 | 0 | { |
255 | 0 | int n, i; |
256 | |
|
257 | 0 | if (!d) |
258 | 0 | d = xmalloc (sizeof *d); |
259 | 0 | memcpy (d, s, sizeof *d); |
260 | 0 | d->seckey_info = NULL; |
261 | 0 | d->user_id = NULL; |
262 | 0 | d->prefs = NULL; |
263 | 0 | d->dks_prefs = NULL; |
264 | 0 | d->revoked.got_reason = 0; |
265 | 0 | d->revoked.reason_code = 0; |
266 | 0 | d->revoked.reason_comment = NULL; |
267 | 0 | d->revoked.reason_comment_len = 0; |
268 | |
|
269 | 0 | n = pubkey_get_npkey (s->pubkey_algo); |
270 | 0 | i = 0; |
271 | 0 | if (!n) |
272 | 0 | d->pkey[i++] = my_mpi_copy (s->pkey[0]); |
273 | 0 | else |
274 | 0 | { |
275 | 0 | for (; i < n; i++ ) |
276 | 0 | d->pkey[i] = my_mpi_copy (s->pkey[i]); |
277 | 0 | } |
278 | 0 | for (; i < PUBKEY_MAX_NSKEY; i++) |
279 | 0 | d->pkey[i] = NULL; |
280 | |
|
281 | 0 | d->revkey = NULL; |
282 | 0 | d->serialno = NULL; |
283 | 0 | d->updateurl = NULL; |
284 | |
|
285 | 0 | return d; |
286 | 0 | } |
287 | | |
288 | | |
289 | | /* Copy the public key S to D. If D is NULL allocate a new public key |
290 | | structure. If S has seckret key infos, only the public stuff is |
291 | | copied. */ |
292 | | PKT_public_key * |
293 | | copy_public_key (PKT_public_key *d, PKT_public_key *s) |
294 | 0 | { |
295 | 0 | d = copy_public_key_basics (d, s); |
296 | 0 | d->user_id = scopy_user_id (s->user_id); |
297 | 0 | d->prefs = copy_prefs (s->prefs); |
298 | 0 | d->dks_prefs = copy_prefs (s->dks_prefs); |
299 | |
|
300 | 0 | if (!s->revkey && s->numrevkeys) |
301 | 0 | BUG(); |
302 | 0 | if (s->numrevkeys) |
303 | 0 | { |
304 | 0 | d->revkey = xmalloc(sizeof(struct revocation_key)*s->numrevkeys); |
305 | 0 | memcpy(d->revkey,s->revkey,sizeof(struct revocation_key)*s->numrevkeys); |
306 | 0 | } |
307 | |
|
308 | 0 | if (s->serialno) |
309 | 0 | d->serialno = xstrdup (s->serialno); |
310 | 0 | if (s->updateurl) |
311 | 0 | d->updateurl = xstrdup (s->updateurl); |
312 | 0 | if (s->revoked.got_reason) |
313 | 0 | { |
314 | 0 | d->revoked.got_reason = s->revoked.got_reason; |
315 | 0 | d->revoked.reason_code = s->revoked.reason_code; |
316 | 0 | if (s->revoked.reason_comment_len) |
317 | 0 | { |
318 | 0 | d->revoked.reason_comment = xmalloc (s->revoked.reason_comment_len); |
319 | 0 | memcpy (d->revoked.reason_comment, s->revoked.reason_comment, |
320 | 0 | s->revoked.reason_comment_len); |
321 | 0 | d->revoked.reason_comment_len = s->revoked.reason_comment_len; |
322 | 0 | } |
323 | 0 | } |
324 | |
|
325 | 0 | return d; |
326 | 0 | } |
327 | | |
328 | | |
329 | | |
330 | | /* When modifying the signature struct adjust copy_signature() |
331 | | * such that the changes are considered too (e.g. pointers are set to NULL |
332 | | * if they are not copied. */ |
333 | | PKT_signature * |
334 | | copy_signature( PKT_signature *d, PKT_signature *s ) |
335 | 0 | { |
336 | 0 | int n, i; |
337 | |
|
338 | 0 | if( !d ) |
339 | 0 | d = xmalloc(sizeof *d); |
340 | 0 | memcpy( d, s, sizeof *d ); |
341 | 0 | n = pubkey_get_nsig( s->pubkey_algo ); |
342 | 0 | if( !n ) |
343 | 0 | d->data[0] = my_mpi_copy(s->data[0]); |
344 | 0 | else { |
345 | 0 | for(i=0; i < n; i++ ) |
346 | 0 | d->data[i] = my_mpi_copy( s->data[i] ); |
347 | 0 | } |
348 | 0 | d->hashed = cp_subpktarea (s->hashed); |
349 | 0 | d->unhashed = cp_subpktarea (s->unhashed); |
350 | 0 | d->salt = s->salt? my_mpi_copy (s->salt) : NULL; |
351 | 0 | if (s->signers_uid) |
352 | 0 | d->signers_uid = xstrdup (s->signers_uid); |
353 | 0 | else |
354 | 0 | d->signers_uid = NULL; |
355 | |
|
356 | 0 | if(s->numrevkeys) |
357 | 0 | { |
358 | 0 | d->revkey=NULL; |
359 | 0 | d->numrevkeys=0; |
360 | 0 | parse_revkeys(d); |
361 | 0 | } |
362 | |
|
363 | 0 | if (s->rev_subject_info) |
364 | 0 | { |
365 | 0 | d->rev_subject_info = xmalloc (sizeof *d->rev_subject_info); |
366 | 0 | memcpy (d->rev_subject_info, s->rev_subject_info, sizeof *d->rev_subject_info); |
367 | 0 | } |
368 | 0 | else |
369 | 0 | d->rev_subject_info = NULL; |
370 | |
|
371 | 0 | return d; |
372 | 0 | } |
373 | | |
374 | | |
375 | | /* |
376 | | * shallow copy of the user ID |
377 | | */ |
378 | | PKT_user_id * |
379 | | scopy_user_id (PKT_user_id *s) |
380 | 0 | { |
381 | 0 | if (s) |
382 | 0 | s->ref++; |
383 | 0 | return s; |
384 | 0 | } |
385 | | |
386 | | |
387 | | |
388 | | void |
389 | | free_comment( PKT_comment *rem ) |
390 | 606 | { |
391 | 606 | xfree(rem); |
392 | 606 | } |
393 | | |
394 | | void |
395 | | free_attributes(PKT_user_id *uid) |
396 | 2.41k | { |
397 | 2.41k | if (!uid) |
398 | 0 | return; |
399 | | |
400 | 2.41k | xfree(uid->attribs); |
401 | 2.41k | xfree(uid->attrib_data); |
402 | | |
403 | 2.41k | uid->attribs=NULL; |
404 | 2.41k | uid->attrib_data=NULL; |
405 | 2.41k | uid->attrib_len=0; |
406 | 2.41k | } |
407 | | |
408 | | void |
409 | | free_user_id (PKT_user_id *uid) |
410 | 89.8k | { |
411 | 89.8k | if (!uid) |
412 | 87.4k | return; |
413 | | |
414 | 89.8k | log_assert (uid->ref > 0); |
415 | 2.41k | if (--uid->ref) |
416 | 0 | return; |
417 | | |
418 | 2.41k | free_attributes(uid); |
419 | 2.41k | xfree (uid->prefs); |
420 | 2.41k | xfree (uid->namehash); |
421 | 2.41k | xfree (uid->updateurl); |
422 | 2.41k | xfree (uid->mbox); |
423 | 2.41k | xfree (uid); |
424 | 2.41k | } |
425 | | |
426 | | void |
427 | | free_compressed( PKT_compressed *zd ) |
428 | 411k | { |
429 | 411k | if (!zd) |
430 | 0 | return; |
431 | | |
432 | 411k | if (zd->buf) |
433 | 624 | { |
434 | | /* We need to skip some bytes. Because don't have any |
435 | | * information about the length, so we assume this is the last |
436 | | * packet */ |
437 | 1.00k | while (iobuf_read( zd->buf, NULL, 1<<30 ) != -1) |
438 | 385 | ; |
439 | 624 | } |
440 | 411k | xfree(zd); |
441 | 411k | } |
442 | | |
443 | | void |
444 | | free_encrypted( PKT_encrypted *ed ) |
445 | 5.86k | { |
446 | 5.86k | if (!ed) |
447 | 0 | return; |
448 | | |
449 | 5.86k | if (ed->buf) |
450 | 670 | { |
451 | | /* We need to skip some bytes. */ |
452 | 670 | if (ed->is_partial) |
453 | 122 | { |
454 | 218 | while (iobuf_read( ed->buf, NULL, 1<<30 ) != -1) |
455 | 96 | ; |
456 | 122 | } |
457 | 548 | else |
458 | 548 | { |
459 | 856 | while (ed->len) |
460 | 308 | { |
461 | | /* Skip the packet. */ |
462 | 308 | int n = iobuf_read( ed->buf, NULL, ed->len ); |
463 | 308 | if (n == -1) |
464 | 184 | ed->len = 0; |
465 | 124 | else |
466 | 124 | ed->len -= n; |
467 | 308 | } |
468 | 548 | } |
469 | 670 | } |
470 | 5.86k | xfree (ed); |
471 | 5.86k | } |
472 | | |
473 | | |
474 | | void |
475 | | free_plaintext( PKT_plaintext *pt ) |
476 | 93.3k | { |
477 | 93.3k | if (!pt) |
478 | 0 | return; |
479 | | |
480 | 93.3k | if (pt->buf) |
481 | 92.0k | { /* We need to skip some bytes. */ |
482 | 92.0k | if (pt->is_partial) |
483 | 5.22k | { |
484 | 10.0k | while (iobuf_read( pt->buf, NULL, 1<<30 ) != -1) |
485 | 4.84k | ; |
486 | 5.22k | } |
487 | 86.8k | else |
488 | 86.8k | { |
489 | 133k | while( pt->len ) |
490 | 46.9k | { /* Skip the packet. */ |
491 | 46.9k | int n = iobuf_read( pt->buf, NULL, pt->len ); |
492 | 46.9k | if (n == -1) |
493 | 11.8k | pt->len = 0; |
494 | 35.0k | else |
495 | 35.0k | pt->len -= n; |
496 | 46.9k | } |
497 | 86.8k | } |
498 | 92.0k | } |
499 | 93.3k | xfree (pt); |
500 | 93.3k | } |
501 | | |
502 | | |
503 | | /**************** |
504 | | * Free the packet in PKT. |
505 | | */ |
506 | | void |
507 | | free_packet (PACKET *pkt, parse_packet_ctx_t parsectx) |
508 | 3.38M | { |
509 | 3.38M | if (!pkt || !pkt->pkt.generic) |
510 | 2.09M | { |
511 | 2.09M | if (parsectx && parsectx->last_pkt.pkt.generic) |
512 | 503k | { |
513 | 503k | if (parsectx->free_last_pkt) |
514 | 2.52k | { |
515 | 2.52k | free_packet (&parsectx->last_pkt, NULL); |
516 | 2.52k | parsectx->free_last_pkt = 0; |
517 | 2.52k | } |
518 | 503k | parsectx->last_pkt.pkttype = 0; |
519 | 503k | parsectx->last_pkt.pkt.generic = NULL; |
520 | 503k | } |
521 | 2.09M | return; |
522 | 2.09M | } |
523 | | |
524 | 1.29M | if (DBG_MEMORY) |
525 | 1.29M | log_debug ("free_packet() type=%d\n", pkt->pkttype); |
526 | | |
527 | | /* If we have a parser context holding PKT then do not free the |
528 | | * packet but set a flag that the packet in the parser context is |
529 | | * now a deep copy. */ |
530 | 1.29M | if (parsectx && !parsectx->free_last_pkt |
531 | 154k | && parsectx->last_pkt.pkttype == pkt->pkttype |
532 | 2.52k | && parsectx->last_pkt.pkt.generic == pkt->pkt.generic) |
533 | 2.52k | { |
534 | 2.52k | parsectx->last_pkt = *pkt; |
535 | 2.52k | parsectx->free_last_pkt = 1; |
536 | 2.52k | pkt->pkt.generic = NULL; |
537 | 2.52k | return; |
538 | 2.52k | } |
539 | | |
540 | 1.28M | switch (pkt->pkttype) |
541 | 1.28M | { |
542 | 519k | case PKT_SIGNATURE: |
543 | 519k | free_seckey_enc (pkt->pkt.signature); |
544 | 519k | break; |
545 | 40.3k | case PKT_ONEPASS_SIG: |
546 | 40.3k | free_onepass_sig (pkt->pkt.onepass_sig); |
547 | 40.3k | break; |
548 | 21.2k | case PKT_PUBKEY_ENC: |
549 | 21.2k | free_pubkey_enc (pkt->pkt.pubkey_enc); |
550 | 21.2k | break; |
551 | 1.41k | case PKT_SYMKEY_ENC: |
552 | 1.41k | free_symkey_enc (pkt->pkt.symkey_enc); |
553 | 1.41k | break; |
554 | 789 | case PKT_PUBLIC_KEY: |
555 | 1.41k | case PKT_PUBLIC_SUBKEY: |
556 | 15.0k | case PKT_SECRET_KEY: |
557 | 81.5k | case PKT_SECRET_SUBKEY: |
558 | 81.5k | free_public_key (pkt->pkt.public_key); |
559 | 81.5k | break; |
560 | 606 | case PKT_COMMENT: |
561 | 606 | free_comment (pkt->pkt.comment); |
562 | 606 | break; |
563 | 2.41k | case PKT_USER_ID: |
564 | 2.41k | free_user_id (pkt->pkt.user_id); |
565 | 2.41k | break; |
566 | 411k | case PKT_COMPRESSED: |
567 | 411k | free_compressed (pkt->pkt.compressed); |
568 | 411k | break; |
569 | 632 | case PKT_ENCRYPTED: |
570 | 4.00k | case PKT_ENCRYPTED_MDC: |
571 | 5.86k | case PKT_ENCRYPTED_OCB: |
572 | 5.86k | free_encrypted (pkt->pkt.encrypted); |
573 | 5.86k | break; |
574 | 93.3k | case PKT_PLAINTEXT: |
575 | 93.3k | free_plaintext (pkt->pkt.plaintext); |
576 | 93.3k | break; |
577 | 110k | default: |
578 | 110k | xfree (pkt->pkt.generic); |
579 | 110k | break; |
580 | 1.28M | } |
581 | | |
582 | 1.28M | pkt->pkt.generic = NULL; |
583 | 1.28M | } |
584 | | |
585 | | |
586 | | /* Free an entire list of public or symmetric key encrypted data. */ |
587 | | void |
588 | | free_seskey_enc_list (struct seskey_enc_list *sesenc_list) |
589 | 429k | { |
590 | 429k | while (sesenc_list) |
591 | 0 | { |
592 | 0 | struct seskey_enc_list *tmp = sesenc_list->next; |
593 | |
|
594 | 0 | if (!sesenc_list->u_sym) |
595 | 0 | release_pubkey_enc_parts (&sesenc_list->u.pub); |
596 | 0 | xfree (sesenc_list); |
597 | 0 | sesenc_list = tmp; |
598 | 0 | } |
599 | 429k | } |
600 | | |
601 | | |
602 | | /**************** |
603 | | * returns 0 if they match. |
604 | | */ |
605 | | int |
606 | | cmp_public_keys( PKT_public_key *a, PKT_public_key *b ) |
607 | 0 | { |
608 | 0 | int n, i; |
609 | |
|
610 | 0 | if( a->timestamp != b->timestamp ) |
611 | 0 | return -1; |
612 | 0 | if( a->version < 4 && a->expiredate != b->expiredate ) |
613 | 0 | return -1; |
614 | 0 | if( a->pubkey_algo != b->pubkey_algo ) |
615 | 0 | return -1; |
616 | | |
617 | 0 | n = pubkey_get_npkey( b->pubkey_algo ); |
618 | 0 | if( !n ) { /* unknown algorithm, rest is in opaque MPI */ |
619 | 0 | if( mpi_cmp( a->pkey[0], b->pkey[0] ) ) |
620 | 0 | return -1; /* can't compare due to unknown algorithm */ |
621 | 0 | } else { |
622 | 0 | for(i=0; i < n; i++ ) { |
623 | 0 | if( mpi_cmp( a->pkey[i], b->pkey[i] ) ) |
624 | 0 | return -1; |
625 | 0 | } |
626 | 0 | } |
627 | | |
628 | 0 | return 0; |
629 | 0 | } |
630 | | |
631 | | |
632 | | |
633 | | int |
634 | | cmp_signatures( PKT_signature *a, PKT_signature *b ) |
635 | 0 | { |
636 | 0 | int n, i; |
637 | |
|
638 | 0 | if( a->keyid[0] != b->keyid[0] ) |
639 | 0 | return -1; |
640 | 0 | if( a->keyid[1] != b->keyid[1] ) |
641 | 0 | return -1; |
642 | 0 | if( a->pubkey_algo != b->pubkey_algo ) |
643 | 0 | return -1; |
644 | | |
645 | 0 | n = pubkey_get_nsig( a->pubkey_algo ); |
646 | 0 | if( !n ) |
647 | 0 | return -1; /* can't compare due to unknown algorithm */ |
648 | 0 | for(i=0; i < n; i++ ) { |
649 | 0 | if( mpi_cmp( a->data[i] , b->data[i] ) ) |
650 | 0 | return -1; |
651 | 0 | } |
652 | 0 | return 0; |
653 | 0 | } |
654 | | |
655 | | |
656 | | /**************** |
657 | | * Returns: true if the user ids do not match |
658 | | */ |
659 | | int |
660 | | cmp_user_ids( PKT_user_id *a, PKT_user_id *b ) |
661 | 0 | { |
662 | 0 | int res=1; |
663 | |
|
664 | 0 | if( a == b ) |
665 | 0 | return 0; |
666 | | |
667 | 0 | if( a->attrib_data && b->attrib_data ) |
668 | 0 | { |
669 | 0 | res = a->attrib_len - b->attrib_len; |
670 | 0 | if( !res ) |
671 | 0 | res = memcmp( a->attrib_data, b->attrib_data, a->attrib_len ); |
672 | 0 | } |
673 | 0 | else if( !a->attrib_data && !b->attrib_data ) |
674 | 0 | { |
675 | 0 | res = a->len - b->len; |
676 | 0 | if( !res ) |
677 | 0 | res = memcmp( a->name, b->name, a->len ); |
678 | 0 | } |
679 | |
|
680 | 0 | return res; |
681 | 0 | } |