/src/gnupg/g10/free-packet.c
Line | Count | Source (jump to first uncovered line) |
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 | | /* Run time check to see whether mpi_copy does not copy the flags |
34 | | * properly. This was fixed in version 1.8.6. */ |
35 | | static int |
36 | | is_mpi_copy_broken (void) |
37 | 0 | { |
38 | 0 | static char result; |
39 | |
|
40 | 0 | if (!result) |
41 | 0 | { |
42 | 0 | result = !gcry_check_version ("1.8.6"); |
43 | 0 | result |= 0x80; |
44 | 0 | } |
45 | 0 | return (result & 1); |
46 | 0 | } |
47 | | |
48 | | |
49 | | /* This is mpi_copy with a fix for opaque MPIs which store a NULL |
50 | | pointer. This will also be fixed in Libggcrypt 1.7.0. */ |
51 | | static gcry_mpi_t |
52 | | my_mpi_copy (gcry_mpi_t a) |
53 | 0 | { |
54 | 0 | if (a |
55 | 0 | && gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE) |
56 | 0 | && !gcry_mpi_get_opaque (a, NULL)) |
57 | 0 | return NULL; |
58 | | |
59 | 0 | if (is_mpi_copy_broken ()) |
60 | 0 | { |
61 | 0 | int flag_user2 = a? gcry_mpi_get_flag (a, GCRYMPI_FLAG_USER2) : 0; |
62 | 0 | gcry_mpi_t b; |
63 | |
|
64 | 0 | b = gcry_mpi_copy (a); |
65 | 0 | if (b && flag_user2) |
66 | 0 | gcry_mpi_set_flag (b, GCRYMPI_FLAG_USER2); |
67 | 0 | return b; |
68 | 0 | } |
69 | | |
70 | 0 | return gcry_mpi_copy (a); |
71 | 0 | } |
72 | | |
73 | | |
74 | | void |
75 | | free_symkey_enc( PKT_symkey_enc *enc ) |
76 | 3.48k | { |
77 | 3.48k | xfree(enc); |
78 | 3.48k | } |
79 | | |
80 | | void |
81 | | free_pubkey_enc( PKT_pubkey_enc *enc ) |
82 | 8.37k | { |
83 | 8.37k | int n, i; |
84 | 8.37k | n = pubkey_get_nenc( enc->pubkey_algo ); |
85 | 8.37k | if( !n ) |
86 | 4.50k | mpi_release(enc->data[0]); |
87 | 15.7k | for(i=0; i < n; i++ ) |
88 | 7.35k | mpi_release( enc->data[i] ); |
89 | 8.37k | xfree(enc); |
90 | 8.37k | } |
91 | | |
92 | | void |
93 | | free_seckey_enc( PKT_signature *sig ) |
94 | 137k | { |
95 | 137k | int n, i; |
96 | | |
97 | 137k | n = pubkey_get_nsig( sig->pubkey_algo ); |
98 | 137k | if( !n ) |
99 | 113k | mpi_release(sig->data[0]); |
100 | 175k | for(i=0; i < n; i++ ) |
101 | 37.7k | mpi_release( sig->data[i] ); |
102 | | |
103 | 137k | xfree(sig->revkey); |
104 | 137k | xfree(sig->hashed); |
105 | 137k | xfree(sig->unhashed); |
106 | | |
107 | 137k | xfree (sig->signers_uid); |
108 | | |
109 | 137k | xfree(sig); |
110 | 137k | } |
111 | | |
112 | | |
113 | | void |
114 | | release_public_key_parts (PKT_public_key *pk) |
115 | 67.8k | { |
116 | 67.8k | int n, i; |
117 | | |
118 | 67.8k | if (pk->seckey_info) |
119 | 10.8k | n = pubkey_get_nskey (pk->pubkey_algo); |
120 | 56.9k | else |
121 | 56.9k | n = pubkey_get_npkey (pk->pubkey_algo); |
122 | 67.8k | if (!n) |
123 | 39.8k | mpi_release (pk->pkey[0]); |
124 | 173k | for (i=0; i < n; i++ ) |
125 | 106k | { |
126 | 106k | mpi_release (pk->pkey[i]); |
127 | 106k | pk->pkey[i] = NULL; |
128 | 106k | } |
129 | 67.8k | if (pk->seckey_info) |
130 | 10.8k | { |
131 | 10.8k | xfree (pk->seckey_info); |
132 | 10.8k | pk->seckey_info = NULL; |
133 | 10.8k | } |
134 | 67.8k | if (pk->prefs) |
135 | 262 | { |
136 | 262 | xfree (pk->prefs); |
137 | 262 | pk->prefs = NULL; |
138 | 262 | } |
139 | 67.8k | free_user_id (pk->user_id); |
140 | 67.8k | pk->user_id = NULL; |
141 | 67.8k | if (pk->revkey) |
142 | 123 | { |
143 | 123 | xfree(pk->revkey); |
144 | 123 | pk->revkey=NULL; |
145 | 123 | pk->numrevkeys=0; |
146 | 123 | } |
147 | 67.8k | if (pk->serialno) |
148 | 0 | { |
149 | 0 | xfree (pk->serialno); |
150 | 0 | pk->serialno = NULL; |
151 | 0 | } |
152 | 67.8k | if (pk->updateurl) |
153 | 1.25k | { |
154 | 1.25k | xfree (pk->updateurl); |
155 | 1.25k | pk->updateurl = NULL; |
156 | 1.25k | } |
157 | 67.8k | } |
158 | | |
159 | | |
160 | | /* Free an allocated public key structure including all parts. |
161 | | Passing NULL is allowed. */ |
162 | | void |
163 | | free_public_key (PKT_public_key *pk) |
164 | 75.7k | { |
165 | 75.7k | if (pk) |
166 | 67.8k | { |
167 | 67.8k | release_public_key_parts (pk); |
168 | 67.8k | xfree(pk); |
169 | 67.8k | } |
170 | 75.7k | } |
171 | | |
172 | | |
173 | | static subpktarea_t * |
174 | | cp_subpktarea (subpktarea_t *s ) |
175 | 0 | { |
176 | 0 | subpktarea_t *d; |
177 | |
|
178 | 0 | if( !s ) |
179 | 0 | return NULL; |
180 | 0 | d = xmalloc (sizeof (*d) + s->size - 1 ); |
181 | 0 | d->size = s->size; |
182 | 0 | d->len = s->len; |
183 | 0 | memcpy (d->data, s->data, s->len); |
184 | 0 | return d; |
185 | 0 | } |
186 | | |
187 | | /* |
188 | | * Return a copy of the preferences |
189 | | */ |
190 | | prefitem_t * |
191 | | copy_prefs (const prefitem_t *prefs) |
192 | 4.10k | { |
193 | 4.10k | size_t n; |
194 | 4.10k | prefitem_t *new; |
195 | | |
196 | 4.10k | if (!prefs) |
197 | 3.84k | return NULL; |
198 | | |
199 | 2.84k | for (n=0; prefs[n].type; n++) |
200 | 2.57k | ; |
201 | 262 | new = xmalloc ( sizeof (*new) * (n+1)); |
202 | 2.84k | for (n=0; prefs[n].type; n++) { |
203 | 2.57k | new[n].type = prefs[n].type; |
204 | 2.57k | new[n].value = prefs[n].value; |
205 | 2.57k | } |
206 | 262 | new[n].type = PREFTYPE_NONE; |
207 | 262 | new[n].value = 0; |
208 | | |
209 | 262 | return new; |
210 | 4.10k | } |
211 | | |
212 | | |
213 | | /* Copy the public key S to D. If D is NULL allocate a new public key |
214 | | structure. If S has seckret key infos, only the public stuff is |
215 | | copied. */ |
216 | | PKT_public_key * |
217 | | copy_public_key (PKT_public_key *d, PKT_public_key *s) |
218 | 0 | { |
219 | 0 | int n, i; |
220 | |
|
221 | 0 | if (!d) |
222 | 0 | d = xmalloc (sizeof *d); |
223 | 0 | memcpy (d, s, sizeof *d); |
224 | 0 | d->seckey_info = NULL; |
225 | 0 | d->user_id = scopy_user_id (s->user_id); |
226 | 0 | d->prefs = copy_prefs (s->prefs); |
227 | |
|
228 | 0 | n = pubkey_get_npkey (s->pubkey_algo); |
229 | 0 | i = 0; |
230 | 0 | if (!n) |
231 | 0 | d->pkey[i++] = my_mpi_copy (s->pkey[0]); |
232 | 0 | else |
233 | 0 | { |
234 | 0 | for (; i < n; i++ ) |
235 | 0 | d->pkey[i] = my_mpi_copy (s->pkey[i]); |
236 | 0 | } |
237 | 0 | for (; i < PUBKEY_MAX_NSKEY; i++) |
238 | 0 | d->pkey[i] = NULL; |
239 | |
|
240 | 0 | if (!s->revkey && s->numrevkeys) |
241 | 0 | BUG(); |
242 | 0 | if (s->numrevkeys) |
243 | 0 | { |
244 | 0 | d->revkey = xmalloc(sizeof(struct revocation_key)*s->numrevkeys); |
245 | 0 | memcpy(d->revkey,s->revkey,sizeof(struct revocation_key)*s->numrevkeys); |
246 | 0 | } |
247 | 0 | else |
248 | 0 | d->revkey = NULL; |
249 | |
|
250 | 0 | if (s->serialno) |
251 | 0 | d->serialno = xstrdup (s->serialno); |
252 | 0 | if (s->updateurl) |
253 | 0 | d->updateurl = xstrdup (s->updateurl); |
254 | |
|
255 | 0 | return d; |
256 | 0 | } |
257 | | |
258 | | |
259 | | |
260 | | PKT_signature * |
261 | | copy_signature( PKT_signature *d, PKT_signature *s ) |
262 | 0 | { |
263 | 0 | int n, i; |
264 | |
|
265 | 0 | if( !d ) |
266 | 0 | d = xmalloc(sizeof *d); |
267 | 0 | memcpy( d, s, sizeof *d ); |
268 | 0 | n = pubkey_get_nsig( s->pubkey_algo ); |
269 | 0 | if( !n ) |
270 | 0 | d->data[0] = my_mpi_copy(s->data[0]); |
271 | 0 | else { |
272 | 0 | for(i=0; i < n; i++ ) |
273 | 0 | d->data[i] = my_mpi_copy( s->data[i] ); |
274 | 0 | } |
275 | 0 | d->hashed = cp_subpktarea (s->hashed); |
276 | 0 | d->unhashed = cp_subpktarea (s->unhashed); |
277 | 0 | if (s->signers_uid) |
278 | 0 | d->signers_uid = xstrdup (s->signers_uid); |
279 | 0 | if(s->numrevkeys) |
280 | 0 | { |
281 | 0 | d->revkey=NULL; |
282 | 0 | d->numrevkeys=0; |
283 | 0 | parse_revkeys(d); |
284 | 0 | } |
285 | 0 | return d; |
286 | 0 | } |
287 | | |
288 | | |
289 | | /* |
290 | | * shallow copy of the user ID |
291 | | */ |
292 | | PKT_user_id * |
293 | | scopy_user_id (PKT_user_id *s) |
294 | 0 | { |
295 | 0 | if (s) |
296 | 0 | s->ref++; |
297 | 0 | return s; |
298 | 0 | } |
299 | | |
300 | | |
301 | | |
302 | | void |
303 | | free_comment( PKT_comment *rem ) |
304 | 997 | { |
305 | 997 | xfree(rem); |
306 | 997 | } |
307 | | |
308 | | void |
309 | | free_attributes(PKT_user_id *uid) |
310 | 51.9k | { |
311 | 51.9k | if (!uid) |
312 | 0 | return; |
313 | | |
314 | 51.9k | xfree(uid->attribs); |
315 | 51.9k | xfree(uid->attrib_data); |
316 | | |
317 | 51.9k | uid->attribs=NULL; |
318 | 51.9k | uid->attrib_data=NULL; |
319 | 51.9k | uid->attrib_len=0; |
320 | 51.9k | } |
321 | | |
322 | | void |
323 | | free_user_id (PKT_user_id *uid) |
324 | 119k | { |
325 | 119k | if (!uid) |
326 | 67.8k | return; |
327 | | |
328 | 51.9k | log_assert (uid->ref > 0); |
329 | 51.9k | if (--uid->ref) |
330 | 0 | return; |
331 | | |
332 | 51.9k | free_attributes(uid); |
333 | 51.9k | xfree (uid->prefs); |
334 | 51.9k | xfree (uid->namehash); |
335 | 51.9k | xfree (uid->updateurl); |
336 | 51.9k | xfree (uid->mbox); |
337 | 51.9k | xfree (uid); |
338 | 51.9k | } |
339 | | |
340 | | void |
341 | | free_compressed( PKT_compressed *zd ) |
342 | 142k | { |
343 | 142k | if (!zd) |
344 | 0 | return; |
345 | | |
346 | 142k | if (zd->buf) |
347 | 424 | { |
348 | | /* We need to skip some bytes. Because don't have any |
349 | | * information about the length, so we assume this is the last |
350 | | * packet */ |
351 | 899 | while (iobuf_read( zd->buf, NULL, 1<<30 ) != -1) |
352 | 475 | ; |
353 | 424 | } |
354 | 142k | xfree(zd); |
355 | 142k | } |
356 | | |
357 | | void |
358 | | free_encrypted( PKT_encrypted *ed ) |
359 | 131k | { |
360 | 131k | if (!ed) |
361 | 0 | return; |
362 | | |
363 | 131k | if (ed->buf) |
364 | 126k | { |
365 | | /* We need to skip some bytes. */ |
366 | 126k | if (ed->is_partial) |
367 | 1.12k | { |
368 | 1.37k | while (iobuf_read( ed->buf, NULL, 1<<30 ) != -1) |
369 | 257 | ; |
370 | 1.12k | } |
371 | 125k | else |
372 | 125k | { |
373 | 127k | while (ed->len) |
374 | 2.07k | { |
375 | | /* Skip the packet. */ |
376 | 2.07k | int n = iobuf_read( ed->buf, NULL, ed->len ); |
377 | 2.07k | if (n == -1) |
378 | 285 | ed->len = 0; |
379 | 1.78k | else |
380 | 1.78k | ed->len -= n; |
381 | 2.07k | } |
382 | 125k | } |
383 | 126k | } |
384 | 131k | xfree (ed); |
385 | 131k | } |
386 | | |
387 | | |
388 | | void |
389 | | free_plaintext( PKT_plaintext *pt ) |
390 | 29.6k | { |
391 | 29.6k | if (!pt) |
392 | 0 | return; |
393 | | |
394 | 29.6k | if (pt->buf) |
395 | 28.4k | { /* We need to skip some bytes. */ |
396 | 28.4k | if (pt->is_partial) |
397 | 5.24k | { |
398 | 11.1k | while (iobuf_read( pt->buf, NULL, 1<<30 ) != -1) |
399 | 5.90k | ; |
400 | 5.24k | } |
401 | 23.1k | else |
402 | 23.1k | { |
403 | 25.1k | while( pt->len ) |
404 | 1.97k | { /* Skip the packet. */ |
405 | 1.97k | int n = iobuf_read( pt->buf, NULL, pt->len ); |
406 | 1.97k | if (n == -1) |
407 | 886 | pt->len = 0; |
408 | 1.08k | else |
409 | 1.08k | pt->len -= n; |
410 | 1.97k | } |
411 | 23.1k | } |
412 | 28.4k | } |
413 | 29.6k | xfree (pt); |
414 | 29.6k | } |
415 | | |
416 | | |
417 | | /**************** |
418 | | * Free the packet in PKT. |
419 | | */ |
420 | | void |
421 | | free_packet (PACKET *pkt, parse_packet_ctx_t parsectx) |
422 | 1.54M | { |
423 | 1.54M | if (!pkt || !pkt->pkt.generic) |
424 | 918k | { |
425 | 918k | if (parsectx && parsectx->last_pkt.pkt.generic) |
426 | 205k | { |
427 | 205k | if (parsectx->free_last_pkt) |
428 | 10.5k | { |
429 | 10.5k | free_packet (&parsectx->last_pkt, NULL); |
430 | 10.5k | parsectx->free_last_pkt = 0; |
431 | 10.5k | } |
432 | 205k | parsectx->last_pkt.pkttype = 0; |
433 | 205k | parsectx->last_pkt.pkt.generic = NULL; |
434 | 205k | } |
435 | 918k | return; |
436 | 918k | } |
437 | | |
438 | 630k | if (DBG_MEMORY) |
439 | 0 | log_debug ("free_packet() type=%d\n", pkt->pkttype); |
440 | | |
441 | | /* If we have a parser context holding PKT then do not free the |
442 | | * packet but set a flag that the packet in the parser context is |
443 | | * now a deep copy. */ |
444 | 630k | if (parsectx && !parsectx->free_last_pkt |
445 | 630k | && parsectx->last_pkt.pkttype == pkt->pkttype |
446 | 630k | && parsectx->last_pkt.pkt.generic == pkt->pkt.generic) |
447 | 10.5k | { |
448 | 10.5k | parsectx->last_pkt = *pkt; |
449 | 10.5k | parsectx->free_last_pkt = 1; |
450 | 10.5k | pkt->pkt.generic = NULL; |
451 | 10.5k | return; |
452 | 10.5k | } |
453 | | |
454 | 620k | switch (pkt->pkttype) |
455 | 620k | { |
456 | 135k | case PKT_SIGNATURE: |
457 | 135k | free_seckey_enc (pkt->pkt.signature); |
458 | 135k | break; |
459 | 8.37k | case PKT_PUBKEY_ENC: |
460 | 8.37k | free_pubkey_enc (pkt->pkt.pubkey_enc); |
461 | 8.37k | break; |
462 | 3.48k | case PKT_SYMKEY_ENC: |
463 | 3.48k | free_symkey_enc (pkt->pkt.symkey_enc); |
464 | 3.48k | break; |
465 | 24.2k | case PKT_PUBLIC_KEY: |
466 | 35.8k | case PKT_PUBLIC_SUBKEY: |
467 | 47.7k | case PKT_SECRET_KEY: |
468 | 52.1k | case PKT_SECRET_SUBKEY: |
469 | 52.1k | free_public_key (pkt->pkt.public_key); |
470 | 52.1k | break; |
471 | 997 | case PKT_COMMENT: |
472 | 997 | free_comment (pkt->pkt.comment); |
473 | 997 | break; |
474 | 51.9k | case PKT_USER_ID: |
475 | 51.9k | free_user_id (pkt->pkt.user_id); |
476 | 51.9k | break; |
477 | 142k | case PKT_COMPRESSED: |
478 | 142k | free_compressed (pkt->pkt.compressed); |
479 | 142k | break; |
480 | 5.98k | case PKT_ENCRYPTED: |
481 | 9.59k | case PKT_ENCRYPTED_MDC: |
482 | 131k | case PKT_ENCRYPTED_AEAD: |
483 | 131k | free_encrypted (pkt->pkt.encrypted); |
484 | 131k | break; |
485 | 29.6k | case PKT_PLAINTEXT: |
486 | 29.6k | free_plaintext (pkt->pkt.plaintext); |
487 | 29.6k | break; |
488 | 64.1k | default: |
489 | 64.1k | xfree (pkt->pkt.generic); |
490 | 64.1k | break; |
491 | 620k | } |
492 | | |
493 | 620k | pkt->pkt.generic = NULL; |
494 | 620k | } |
495 | | |
496 | | |
497 | | /**************** |
498 | | * returns 0 if they match. |
499 | | */ |
500 | | int |
501 | | cmp_public_keys( PKT_public_key *a, PKT_public_key *b ) |
502 | 0 | { |
503 | 0 | int n, i; |
504 | |
|
505 | 0 | if( a->timestamp != b->timestamp ) |
506 | 0 | return -1; |
507 | 0 | if( a->version < 4 && a->expiredate != b->expiredate ) |
508 | 0 | return -1; |
509 | 0 | if( a->pubkey_algo != b->pubkey_algo ) |
510 | 0 | return -1; |
511 | | |
512 | 0 | n = pubkey_get_npkey( b->pubkey_algo ); |
513 | 0 | if( !n ) { /* unknown algorithm, rest is in opaque MPI */ |
514 | 0 | if( mpi_cmp( a->pkey[0], b->pkey[0] ) ) |
515 | 0 | return -1; /* can't compare due to unknown algorithm */ |
516 | 0 | } else { |
517 | 0 | for(i=0; i < n; i++ ) { |
518 | 0 | if( mpi_cmp( a->pkey[i], b->pkey[i] ) ) |
519 | 0 | return -1; |
520 | 0 | } |
521 | 0 | } |
522 | | |
523 | 0 | return 0; |
524 | 0 | } |
525 | | |
526 | | |
527 | | |
528 | | int |
529 | | cmp_signatures( PKT_signature *a, PKT_signature *b ) |
530 | 0 | { |
531 | 0 | int n, i; |
532 | |
|
533 | 0 | if( a->keyid[0] != b->keyid[0] ) |
534 | 0 | return -1; |
535 | 0 | if( a->keyid[1] != b->keyid[1] ) |
536 | 0 | return -1; |
537 | 0 | if( a->pubkey_algo != b->pubkey_algo ) |
538 | 0 | return -1; |
539 | | |
540 | 0 | n = pubkey_get_nsig( a->pubkey_algo ); |
541 | 0 | if( !n ) |
542 | 0 | return -1; /* can't compare due to unknown algorithm */ |
543 | 0 | for(i=0; i < n; i++ ) { |
544 | 0 | if( mpi_cmp( a->data[i] , b->data[i] ) ) |
545 | 0 | return -1; |
546 | 0 | } |
547 | 0 | return 0; |
548 | 0 | } |
549 | | |
550 | | |
551 | | /**************** |
552 | | * Returns: true if the user ids do not match |
553 | | */ |
554 | | int |
555 | | cmp_user_ids( PKT_user_id *a, PKT_user_id *b ) |
556 | 17.7k | { |
557 | 17.7k | int res=1; |
558 | | |
559 | 17.7k | if( a == b ) |
560 | 0 | return 0; |
561 | | |
562 | 17.7k | if( a->attrib_data && b->attrib_data ) |
563 | 0 | { |
564 | 0 | res = a->attrib_len - b->attrib_len; |
565 | 0 | if( !res ) |
566 | 0 | res = memcmp( a->attrib_data, b->attrib_data, a->attrib_len ); |
567 | 0 | } |
568 | 17.7k | else if( !a->attrib_data && !b->attrib_data ) |
569 | 17.7k | { |
570 | 17.7k | res = a->len - b->len; |
571 | 17.7k | if( !res ) |
572 | 12.1k | res = memcmp( a->name, b->name, a->len ); |
573 | 17.7k | } |
574 | | |
575 | 17.7k | return res; |
576 | 17.7k | } |