1 /* free-packet.c - cleanup stuff for packets
2 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
3 * 2005, 2010 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
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.
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.
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/>.
29 #include "../common/iobuf.h"
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. */
36 my_mpi_copy (gcry_mpi_t a)
39 && gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)
40 && !gcry_mpi_get_opaque (a, NULL))
43 return gcry_mpi_copy (a);
48 free_symkey_enc( PKT_symkey_enc *enc )
54 free_pubkey_enc( PKT_pubkey_enc *enc )
57 n = pubkey_get_nenc( enc->pubkey_algo );
59 mpi_release(enc->data[0]);
61 mpi_release( enc->data[i] );
66 free_seckey_enc( PKT_signature *sig )
70 n = pubkey_get_nsig( sig->pubkey_algo );
72 mpi_release(sig->data[0]);
74 mpi_release( sig->data[i] );
82 xfree (sig->pka_info->uri);
83 xfree (sig->pka_info);
85 xfree (sig->signers_uid);
92 release_public_key_parts (PKT_public_key *pk)
97 n = pubkey_get_nskey (pk->pubkey_algo);
99 n = pubkey_get_npkey (pk->pubkey_algo);
101 mpi_release (pk->pkey[0]);
102 for (i=0; i < n; i++ )
104 mpi_release (pk->pkey[i]);
109 xfree (pk->seckey_info);
110 pk->seckey_info = NULL;
119 free_user_id (pk->user_id);
130 xfree (pk->serialno);
136 /* Free an allocated public key structure including all parts.
137 Passing NULL is allowed. */
139 free_public_key (PKT_public_key *pk)
143 release_public_key_parts (pk);
149 static subpktarea_t *
150 cp_subpktarea (subpktarea_t *s )
156 d = xmalloc (sizeof (*d) + s->size - 1 );
159 memcpy (d->data, s->data, s->len);
164 * Return a copy of the preferences
167 copy_prefs (const prefitem_t *prefs)
175 for (n=0; prefs[n].type; n++)
177 new = xmalloc ( sizeof (*new) * (n+1));
178 for (n=0; prefs[n].type; n++) {
179 new[n].type = prefs[n].type;
180 new[n].value = prefs[n].value;
182 new[n].type = PREFTYPE_NONE;
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
193 copy_public_key (PKT_public_key *d, PKT_public_key *s)
198 d = xmalloc (sizeof *d);
199 memcpy (d, s, sizeof *d);
200 d->seckey_info = NULL;
201 d->user_id = scopy_user_id (s->user_id);
202 d->prefs = copy_prefs (s->prefs);
204 n = pubkey_get_npkey (s->pubkey_algo);
207 d->pkey[i++] = my_mpi_copy (s->pkey[0]);
211 d->pkey[i] = my_mpi_copy (s->pkey[i]);
213 for (; i < PUBKEY_MAX_NSKEY; i++)
216 if (!s->revkey && s->numrevkeys)
220 d->revkey = xmalloc(sizeof(struct revocation_key)*s->numrevkeys);
221 memcpy(d->revkey,s->revkey,sizeof(struct revocation_key)*s->numrevkeys);
231 cp_pka_info (const pka_info_t *s)
233 pka_info_t *d = xmalloc (sizeof *s + strlen (s->email));
236 d->checked = s->checked;
237 d->uri = s->uri? xstrdup (s->uri):NULL;
238 memcpy (d->fpr, s->fpr, sizeof s->fpr);
239 strcpy (d->email, s->email);
245 copy_signature( PKT_signature *d, PKT_signature *s )
250 d = xmalloc(sizeof *d);
251 memcpy( d, s, sizeof *d );
252 n = pubkey_get_nsig( s->pubkey_algo );
254 d->data[0] = my_mpi_copy(s->data[0]);
256 for(i=0; i < n; i++ )
257 d->data[i] = my_mpi_copy( s->data[i] );
259 d->pka_info = s->pka_info? cp_pka_info (s->pka_info) : NULL;
260 d->hashed = cp_subpktarea (s->hashed);
261 d->unhashed = cp_subpktarea (s->unhashed);
263 d->signers_uid = xstrdup (s->signers_uid);
275 * shallow copy of the user ID
278 scopy_user_id (PKT_user_id *s)
288 free_comment( PKT_comment *rem )
294 free_attributes(PKT_user_id *uid)
297 xfree(uid->attrib_data);
300 uid->attrib_data=NULL;
305 free_user_id (PKT_user_id *uid)
307 log_assert (uid->ref > 0);
311 free_attributes(uid);
313 xfree (uid->namehash);
318 free_compressed( PKT_compressed *zd )
320 if( zd->buf ) { /* have to skip some bytes */
321 /* don't have any information about the length, so
322 * we assume this is the last packet */
323 while( iobuf_read( zd->buf, NULL, 1<<30 ) != -1 )
330 free_encrypted( PKT_encrypted *ed )
332 if( ed->buf ) { /* have to skip some bytes */
333 if( ed->is_partial ) {
334 while( iobuf_read( ed->buf, NULL, 1<<30 ) != -1 )
338 while( ed->len ) { /* skip the packet */
339 int n = iobuf_read( ed->buf, NULL, ed->len );
352 free_plaintext( PKT_plaintext *pt )
354 if( pt->buf ) { /* have to skip some bytes */
355 if( pt->is_partial ) {
356 while( iobuf_read( pt->buf, NULL, 1<<30 ) != -1 )
360 while( pt->len ) { /* skip the packet */
361 int n = iobuf_read( pt->buf, NULL, pt->len );
373 * Free the packet in pkt.
376 free_packet( PACKET *pkt )
378 if( !pkt || !pkt->pkt.generic )
382 log_debug("free_packet() type=%d\n", pkt->pkttype );
384 switch( pkt->pkttype ) {
386 free_seckey_enc( pkt->pkt.signature );
389 free_pubkey_enc( pkt->pkt.pubkey_enc );
392 free_symkey_enc( pkt->pkt.symkey_enc );
395 case PKT_PUBLIC_SUBKEY:
397 case PKT_SECRET_SUBKEY:
398 free_public_key (pkt->pkt.public_key);
401 free_comment( pkt->pkt.comment );
404 free_user_id( pkt->pkt.user_id );
407 free_compressed( pkt->pkt.compressed);
410 case PKT_ENCRYPTED_MDC:
411 free_encrypted( pkt->pkt.encrypted );
414 free_plaintext( pkt->pkt.plaintext );
417 xfree( pkt->pkt.generic );
420 pkt->pkt.generic = NULL;
424 * returns 0 if they match.
427 cmp_public_keys( PKT_public_key *a, PKT_public_key *b )
431 if( a->timestamp != b->timestamp )
433 if( a->version < 4 && a->expiredate != b->expiredate )
435 if( a->pubkey_algo != b->pubkey_algo )
438 n = pubkey_get_npkey( b->pubkey_algo );
439 if( !n ) { /* unknown algorithm, rest is in opaque MPI */
440 if( mpi_cmp( a->pkey[0], b->pkey[0] ) )
441 return -1; /* can't compare due to unknown algorithm */
443 for(i=0; i < n; i++ ) {
444 if( mpi_cmp( a->pkey[i], b->pkey[i] ) )
455 cmp_signatures( PKT_signature *a, PKT_signature *b )
459 if( a->keyid[0] != b->keyid[0] )
461 if( a->keyid[1] != b->keyid[1] )
463 if( a->pubkey_algo != b->pubkey_algo )
466 n = pubkey_get_nsig( a->pubkey_algo );
468 return -1; /* can't compare due to unknown algorithm */
469 for(i=0; i < n; i++ ) {
470 if( mpi_cmp( a->data[i] , b->data[i] ) )
478 * Returns: true if the user ids do not match
481 cmp_user_ids( PKT_user_id *a, PKT_user_id *b )
488 if( a->attrib_data && b->attrib_data )
490 res = a->attrib_len - b->attrib_len;
492 res = memcmp( a->attrib_data, b->attrib_data, a->attrib_len );
494 else if( !a->attrib_data && !b->attrib_data )
496 res = a->len - b->len;
498 res = memcmp( a->name, b->name, a->len );