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