2003-06-05 07:14:21 +00:00
|
|
|
/* free-packet.c - cleanup stuff for packets
|
2006-04-19 11:26:11 +00:00
|
|
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
|
2010-09-06 19:57:42 +00:00
|
|
|
* 2005, 2010 Free Software Foundation, Inc.
|
2003-06-05 07:14:21 +00:00
|
|
|
*
|
|
|
|
* This file is part of GnuPG.
|
|
|
|
*
|
|
|
|
* GnuPG is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
2007-07-04 19:49:40 +00:00
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
2003-06-05 07:14:21 +00:00
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* GnuPG is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2016-11-05 12:02:19 +01:00
|
|
|
* along with this program; if not, see <https://www.gnu.org/licenses/>.
|
2003-06-05 07:14:21 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2006-04-19 11:26:11 +00:00
|
|
|
#include "gpg.h"
|
2017-03-07 20:21:23 +09:00
|
|
|
#include "../common/util.h"
|
2003-06-05 07:14:21 +00:00
|
|
|
#include "packet.h"
|
2006-04-19 11:26:11 +00:00
|
|
|
#include "../common/iobuf.h"
|
2011-02-04 12:57:53 +01:00
|
|
|
#include "options.h"
|
2006-04-19 11:26:11 +00:00
|
|
|
|
2003-06-05 07:14:21 +00:00
|
|
|
|
2020-06-09 18:16:44 +02:00
|
|
|
/* Run time check to see whether mpi_copy does not copy the flags
|
|
|
|
* properly. This was fixed in version 1.8.6. */
|
|
|
|
static int
|
|
|
|
is_mpi_copy_broken (void)
|
|
|
|
{
|
|
|
|
static char result;
|
|
|
|
|
|
|
|
if (!result)
|
|
|
|
{
|
|
|
|
result = !gcry_check_version ("1.8.6");
|
|
|
|
result |= 0x80;
|
|
|
|
}
|
|
|
|
return (result & 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-04-13 11:44:10 +02:00
|
|
|
/* This is mpi_copy with a fix for opaque MPIs which store a NULL
|
|
|
|
pointer. This will also be fixed in Libggcrypt 1.7.0. */
|
|
|
|
static gcry_mpi_t
|
|
|
|
my_mpi_copy (gcry_mpi_t a)
|
|
|
|
{
|
|
|
|
if (a
|
|
|
|
&& gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)
|
|
|
|
&& !gcry_mpi_get_opaque (a, NULL))
|
|
|
|
return NULL;
|
|
|
|
|
2020-06-09 18:16:44 +02:00
|
|
|
if (is_mpi_copy_broken ())
|
|
|
|
{
|
|
|
|
int flag_user2 = a? gcry_mpi_get_flag (a, GCRYMPI_FLAG_USER2) : 0;
|
|
|
|
gcry_mpi_t b;
|
|
|
|
|
|
|
|
b = gcry_mpi_copy (a);
|
|
|
|
if (b && flag_user2)
|
|
|
|
gcry_mpi_set_flag (b, GCRYMPI_FLAG_USER2);
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
2015-04-13 11:44:10 +02:00
|
|
|
return gcry_mpi_copy (a);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-06-05 07:14:21 +00:00
|
|
|
void
|
|
|
|
free_symkey_enc( PKT_symkey_enc *enc )
|
|
|
|
{
|
2006-04-19 11:26:11 +00:00
|
|
|
xfree(enc);
|
2003-06-05 07:14:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
free_pubkey_enc( PKT_pubkey_enc *enc )
|
|
|
|
{
|
|
|
|
int n, i;
|
|
|
|
n = pubkey_get_nenc( enc->pubkey_algo );
|
|
|
|
if( !n )
|
2006-04-19 11:26:11 +00:00
|
|
|
mpi_release(enc->data[0]);
|
2003-06-05 07:14:21 +00:00
|
|
|
for(i=0; i < n; i++ )
|
2006-04-19 11:26:11 +00:00
|
|
|
mpi_release( enc->data[i] );
|
|
|
|
xfree(enc);
|
2003-06-05 07:14:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
free_seckey_enc( PKT_signature *sig )
|
|
|
|
{
|
|
|
|
int n, i;
|
|
|
|
|
|
|
|
n = pubkey_get_nsig( sig->pubkey_algo );
|
|
|
|
if( !n )
|
2006-04-19 11:26:11 +00:00
|
|
|
mpi_release(sig->data[0]);
|
2003-06-05 07:14:21 +00:00
|
|
|
for(i=0; i < n; i++ )
|
2006-04-19 11:26:11 +00:00
|
|
|
mpi_release( sig->data[i] );
|
|
|
|
|
|
|
|
xfree(sig->revkey);
|
|
|
|
xfree(sig->hashed);
|
|
|
|
xfree(sig->unhashed);
|
|
|
|
|
2016-06-13 10:40:34 +02:00
|
|
|
xfree (sig->signers_uid);
|
2006-04-19 11:26:11 +00:00
|
|
|
|
|
|
|
xfree(sig);
|
2003-06-05 07:14:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2010-09-06 19:57:42 +00:00
|
|
|
release_public_key_parts (PKT_public_key *pk)
|
2003-06-05 07:14:21 +00:00
|
|
|
{
|
2010-09-06 19:57:42 +00:00
|
|
|
int n, i;
|
2011-02-04 12:57:53 +01:00
|
|
|
|
2010-09-06 19:57:42 +00:00
|
|
|
if (pk->seckey_info)
|
|
|
|
n = pubkey_get_nskey (pk->pubkey_algo);
|
|
|
|
else
|
|
|
|
n = pubkey_get_npkey (pk->pubkey_algo);
|
|
|
|
if (!n)
|
|
|
|
mpi_release (pk->pkey[0]);
|
|
|
|
for (i=0; i < n; i++ )
|
|
|
|
{
|
|
|
|
mpi_release (pk->pkey[i]);
|
|
|
|
pk->pkey[i] = NULL;
|
2003-06-05 07:14:21 +00:00
|
|
|
}
|
2010-09-06 19:57:42 +00:00
|
|
|
if (pk->seckey_info)
|
|
|
|
{
|
|
|
|
xfree (pk->seckey_info);
|
|
|
|
pk->seckey_info = NULL;
|
2003-06-05 07:14:21 +00:00
|
|
|
}
|
2010-09-06 19:57:42 +00:00
|
|
|
if (pk->prefs)
|
|
|
|
{
|
|
|
|
xfree (pk->prefs);
|
|
|
|
pk->prefs = NULL;
|
|
|
|
}
|
2016-11-15 16:23:41 +01:00
|
|
|
free_user_id (pk->user_id);
|
|
|
|
pk->user_id = NULL;
|
2010-09-06 19:57:42 +00:00
|
|
|
if (pk->revkey)
|
|
|
|
{
|
|
|
|
xfree(pk->revkey);
|
|
|
|
pk->revkey=NULL;
|
|
|
|
pk->numrevkeys=0;
|
2003-06-05 07:14:21 +00:00
|
|
|
}
|
2010-10-20 11:33:50 +00:00
|
|
|
if (pk->serialno)
|
|
|
|
{
|
|
|
|
xfree (pk->serialno);
|
|
|
|
pk->serialno = NULL;
|
|
|
|
}
|
gpg: Revamp reading and writing of ring trust packets.
* g10/parse-packet.c (parse_trust): Rename to ...
(parse_ring_trust): this. Change args and implement new ring trust
packet format.
(parse): Add special ring trust packet handling.
* g10/packet.h (PKT_user_id): New fields KEYUPDATE, UPDATEURL, and
KEYSRC.
(PKT_public_key): Ditto.
(RING_TRUST_SIG, RING_TRUST_KEY, RING_TRUST_UID): New consts.
(PKT_ring_trust): New.
(struct packet_struct): Remove member RING_TRUST.
(strcu parse_packet_ctx_s): Add field SKIP_META.
(init_parse_packet): Init SKIPT_META.
* g10/free-packet.c (release_public_key_parts): Free UDPATEURL.
(free_user_id): Ditto.
* g10/mainproc.c (list_node): Remove printing of non-documented "rtv"
lines.
* g10/build-packet.c (build_packet_and_meta): New.
(do_ring_trust): New.
* g10/export.c (write_keyblock_to_output): Use build_packet_and_meta
in backup mode.
(do_export_one_keyblock): Ditto.
* g10/import.c (read_block): Add arg WITH_META. Skip ring trust
packets if that ism not set.
(import): Call read_block WITH_META in restore mode.
* g10/keydb.h (KEYSRC_UNKNOWN, KEYSRC_FILE, KEYSRC_KS, KEYSRC_PREF_KS)
(KEYSRC_WKD, KEYSRC_WKD_SD, KEYSRC_DANE): New constants. They are not
yet used, though.
* g10/keydb.c (parse_keyblock_image): Allow ring trust packets.
(build_keyblock_image): Ditto. Use build_packet_and_meta.
* g10/keyring.c (keyring_get_keyblock): Remove specila treatment of
ring trust packets.
(write_keyblock): Use build_packet_and_meta. Remove special treatment
of ring trust packets and initialization of the signature caches.
--
This patch introduced the framework to store meta data for keys and
user ids in the keyrings/keyboxes. Ring trust packets are
implementation defined and have always been used in gpg to cache the
signature verification status.
Ring trust packets are only exported with the export option "backup"
and only imported with the import option "restore".
The new code uses a cleaner way to handle the ring trust packets: When
the parser reads a ring trust packet and the previously read packet
matches the type of that ring trust packet, the information is stored
in that previously read packet (signature, user id, or primary key)
and the next packet is read immediately. Thus only the parser sees
the ring trust packets. Ring trust packets are written by using the
new function build_packet_and_meta instead of build_packet. That
function writes a ring trust packet when the needed information is
available.
As a side-effect of this patch the signature status cache works again
and "gpg --check-sigs" is thus much faster.
Signed-off-by: Werner Koch <wk@gnupg.org>
2017-03-30 09:07:02 +02:00
|
|
|
if (pk->updateurl)
|
|
|
|
{
|
|
|
|
xfree (pk->updateurl);
|
|
|
|
pk->updateurl = NULL;
|
|
|
|
}
|
2003-06-05 07:14:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-09-20 19:24:52 +02:00
|
|
|
/* Free an allocated public key structure including all parts.
|
|
|
|
Passing NULL is allowed. */
|
2003-06-05 07:14:21 +00:00
|
|
|
void
|
2010-09-06 19:57:42 +00:00
|
|
|
free_public_key (PKT_public_key *pk)
|
2003-06-05 07:14:21 +00:00
|
|
|
{
|
2011-09-20 19:24:52 +02:00
|
|
|
if (pk)
|
|
|
|
{
|
|
|
|
release_public_key_parts (pk);
|
|
|
|
xfree(pk);
|
|
|
|
}
|
2003-06-05 07:14:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static subpktarea_t *
|
|
|
|
cp_subpktarea (subpktarea_t *s )
|
|
|
|
{
|
|
|
|
subpktarea_t *d;
|
|
|
|
|
|
|
|
if( !s )
|
|
|
|
return NULL;
|
2003-06-18 19:56:13 +00:00
|
|
|
d = xmalloc (sizeof (*d) + s->size - 1 );
|
2003-06-05 07:14:21 +00:00
|
|
|
d->size = s->size;
|
|
|
|
d->len = s->len;
|
|
|
|
memcpy (d->data, s->data, s->len);
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2011-02-04 12:57:53 +01:00
|
|
|
* Return a copy of the preferences
|
2003-06-05 07:14:21 +00:00
|
|
|
*/
|
|
|
|
prefitem_t *
|
|
|
|
copy_prefs (const prefitem_t *prefs)
|
|
|
|
{
|
|
|
|
size_t n;
|
|
|
|
prefitem_t *new;
|
|
|
|
|
|
|
|
if (!prefs)
|
|
|
|
return NULL;
|
2011-02-04 12:57:53 +01:00
|
|
|
|
2003-06-05 07:14:21 +00:00
|
|
|
for (n=0; prefs[n].type; n++)
|
|
|
|
;
|
2003-06-18 19:56:13 +00:00
|
|
|
new = xmalloc ( sizeof (*new) * (n+1));
|
2003-06-05 07:14:21 +00:00
|
|
|
for (n=0; prefs[n].type; n++) {
|
|
|
|
new[n].type = prefs[n].type;
|
|
|
|
new[n].value = prefs[n].value;
|
|
|
|
}
|
|
|
|
new[n].type = PREFTYPE_NONE;
|
|
|
|
new[n].value = 0;
|
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-09-06 19:57:42 +00:00
|
|
|
/* Copy the public key S to D. If D is NULL allocate a new public key
|
2023-03-01 17:22:20 +01:00
|
|
|
* structure. Only the basic stuff is copied; not any ancillary
|
|
|
|
* data. */
|
2003-06-05 07:14:21 +00:00
|
|
|
PKT_public_key *
|
2023-03-01 17:22:20 +01:00
|
|
|
copy_public_key_basics (PKT_public_key *d, PKT_public_key *s)
|
2003-06-05 07:14:21 +00:00
|
|
|
{
|
2010-09-06 19:57:42 +00:00
|
|
|
int n, i;
|
2011-02-04 12:57:53 +01:00
|
|
|
|
2010-09-06 19:57:42 +00:00
|
|
|
if (!d)
|
|
|
|
d = xmalloc (sizeof *d);
|
|
|
|
memcpy (d, s, sizeof *d);
|
2011-02-04 12:57:53 +01:00
|
|
|
d->seckey_info = NULL;
|
2023-03-01 17:22:20 +01:00
|
|
|
d->user_id = NULL;
|
|
|
|
d->prefs = NULL;
|
2010-09-06 19:57:42 +00:00
|
|
|
|
|
|
|
n = pubkey_get_npkey (s->pubkey_algo);
|
|
|
|
i = 0;
|
|
|
|
if (!n)
|
2015-04-13 11:44:10 +02:00
|
|
|
d->pkey[i++] = my_mpi_copy (s->pkey[0]);
|
2011-02-04 12:57:53 +01:00
|
|
|
else
|
2010-09-06 19:57:42 +00:00
|
|
|
{
|
|
|
|
for (; i < n; i++ )
|
2015-04-13 11:44:10 +02:00
|
|
|
d->pkey[i] = my_mpi_copy (s->pkey[i]);
|
2003-06-05 07:14:21 +00:00
|
|
|
}
|
2010-09-06 19:57:42 +00:00
|
|
|
for (; i < PUBKEY_MAX_NSKEY; i++)
|
|
|
|
d->pkey[i] = NULL;
|
|
|
|
|
2023-03-01 17:22:20 +01:00
|
|
|
d->revkey = NULL;
|
|
|
|
d->serialno = NULL;
|
|
|
|
d->updateurl = NULL;
|
|
|
|
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Copy the public key S to D. If D is NULL allocate a new public key
|
|
|
|
structure. If S has seckret key infos, only the public stuff is
|
|
|
|
copied. */
|
|
|
|
PKT_public_key *
|
|
|
|
copy_public_key (PKT_public_key *d, PKT_public_key *s)
|
|
|
|
{
|
|
|
|
d = copy_public_key_basics (d, s);
|
|
|
|
d->user_id = scopy_user_id (s->user_id);
|
|
|
|
d->prefs = copy_prefs (s->prefs);
|
|
|
|
|
2010-09-06 19:57:42 +00:00
|
|
|
if (!s->revkey && s->numrevkeys)
|
|
|
|
BUG();
|
|
|
|
if (s->numrevkeys)
|
|
|
|
{
|
|
|
|
d->revkey = xmalloc(sizeof(struct revocation_key)*s->numrevkeys);
|
|
|
|
memcpy(d->revkey,s->revkey,sizeof(struct revocation_key)*s->numrevkeys);
|
2003-06-05 07:14:21 +00:00
|
|
|
}
|
2017-07-21 17:48:40 +02:00
|
|
|
|
|
|
|
if (s->serialno)
|
|
|
|
d->serialno = xstrdup (s->serialno);
|
|
|
|
if (s->updateurl)
|
|
|
|
d->updateurl = xstrdup (s->updateurl);
|
|
|
|
|
2010-09-06 19:57:42 +00:00
|
|
|
return d;
|
2003-06-05 07:14:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-04-19 11:26:11 +00:00
|
|
|
|
2003-06-05 07:14:21 +00:00
|
|
|
PKT_signature *
|
|
|
|
copy_signature( PKT_signature *d, PKT_signature *s )
|
|
|
|
{
|
|
|
|
int n, i;
|
|
|
|
|
|
|
|
if( !d )
|
2006-04-19 11:26:11 +00:00
|
|
|
d = xmalloc(sizeof *d);
|
2003-06-05 07:14:21 +00:00
|
|
|
memcpy( d, s, sizeof *d );
|
|
|
|
n = pubkey_get_nsig( s->pubkey_algo );
|
|
|
|
if( !n )
|
2015-04-13 11:44:10 +02:00
|
|
|
d->data[0] = my_mpi_copy(s->data[0]);
|
2003-06-05 07:14:21 +00:00
|
|
|
else {
|
|
|
|
for(i=0; i < n; i++ )
|
2015-04-13 11:44:10 +02:00
|
|
|
d->data[i] = my_mpi_copy( s->data[i] );
|
2003-06-05 07:14:21 +00:00
|
|
|
}
|
|
|
|
d->hashed = cp_subpktarea (s->hashed);
|
|
|
|
d->unhashed = cp_subpktarea (s->unhashed);
|
2016-06-13 10:40:34 +02:00
|
|
|
if (s->signers_uid)
|
|
|
|
d->signers_uid = xstrdup (s->signers_uid);
|
2003-06-05 07:14:21 +00:00
|
|
|
if(s->numrevkeys)
|
|
|
|
{
|
|
|
|
d->revkey=NULL;
|
|
|
|
d->numrevkeys=0;
|
|
|
|
parse_revkeys(d);
|
|
|
|
}
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* shallow copy of the user ID
|
|
|
|
*/
|
|
|
|
PKT_user_id *
|
|
|
|
scopy_user_id (PKT_user_id *s)
|
|
|
|
{
|
|
|
|
if (s)
|
|
|
|
s->ref++;
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
free_comment( PKT_comment *rem )
|
|
|
|
{
|
2006-04-19 11:26:11 +00:00
|
|
|
xfree(rem);
|
2003-06-05 07:14:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
free_attributes(PKT_user_id *uid)
|
|
|
|
{
|
2016-11-15 16:23:41 +01:00
|
|
|
if (!uid)
|
|
|
|
return;
|
|
|
|
|
2006-04-19 11:26:11 +00:00
|
|
|
xfree(uid->attribs);
|
|
|
|
xfree(uid->attrib_data);
|
2003-06-05 07:14:21 +00:00
|
|
|
|
|
|
|
uid->attribs=NULL;
|
|
|
|
uid->attrib_data=NULL;
|
|
|
|
uid->attrib_len=0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
free_user_id (PKT_user_id *uid)
|
|
|
|
{
|
2016-11-15 16:23:41 +01:00
|
|
|
if (!uid)
|
|
|
|
return;
|
|
|
|
|
|
|
|
log_assert (uid->ref > 0);
|
|
|
|
if (--uid->ref)
|
|
|
|
return;
|
|
|
|
|
|
|
|
free_attributes(uid);
|
|
|
|
xfree (uid->prefs);
|
|
|
|
xfree (uid->namehash);
|
gpg: Revamp reading and writing of ring trust packets.
* g10/parse-packet.c (parse_trust): Rename to ...
(parse_ring_trust): this. Change args and implement new ring trust
packet format.
(parse): Add special ring trust packet handling.
* g10/packet.h (PKT_user_id): New fields KEYUPDATE, UPDATEURL, and
KEYSRC.
(PKT_public_key): Ditto.
(RING_TRUST_SIG, RING_TRUST_KEY, RING_TRUST_UID): New consts.
(PKT_ring_trust): New.
(struct packet_struct): Remove member RING_TRUST.
(strcu parse_packet_ctx_s): Add field SKIP_META.
(init_parse_packet): Init SKIPT_META.
* g10/free-packet.c (release_public_key_parts): Free UDPATEURL.
(free_user_id): Ditto.
* g10/mainproc.c (list_node): Remove printing of non-documented "rtv"
lines.
* g10/build-packet.c (build_packet_and_meta): New.
(do_ring_trust): New.
* g10/export.c (write_keyblock_to_output): Use build_packet_and_meta
in backup mode.
(do_export_one_keyblock): Ditto.
* g10/import.c (read_block): Add arg WITH_META. Skip ring trust
packets if that ism not set.
(import): Call read_block WITH_META in restore mode.
* g10/keydb.h (KEYSRC_UNKNOWN, KEYSRC_FILE, KEYSRC_KS, KEYSRC_PREF_KS)
(KEYSRC_WKD, KEYSRC_WKD_SD, KEYSRC_DANE): New constants. They are not
yet used, though.
* g10/keydb.c (parse_keyblock_image): Allow ring trust packets.
(build_keyblock_image): Ditto. Use build_packet_and_meta.
* g10/keyring.c (keyring_get_keyblock): Remove specila treatment of
ring trust packets.
(write_keyblock): Use build_packet_and_meta. Remove special treatment
of ring trust packets and initialization of the signature caches.
--
This patch introduced the framework to store meta data for keys and
user ids in the keyrings/keyboxes. Ring trust packets are
implementation defined and have always been used in gpg to cache the
signature verification status.
Ring trust packets are only exported with the export option "backup"
and only imported with the import option "restore".
The new code uses a cleaner way to handle the ring trust packets: When
the parser reads a ring trust packet and the previously read packet
matches the type of that ring trust packet, the information is stored
in that previously read packet (signature, user id, or primary key)
and the next packet is read immediately. Thus only the parser sees
the ring trust packets. Ring trust packets are written by using the
new function build_packet_and_meta instead of build_packet. That
function writes a ring trust packet when the needed information is
available.
As a side-effect of this patch the signature status cache works again
and "gpg --check-sigs" is thus much faster.
Signed-off-by: Werner Koch <wk@gnupg.org>
2017-03-30 09:07:02 +02:00
|
|
|
xfree (uid->updateurl);
|
2016-11-15 16:23:41 +01:00
|
|
|
xfree (uid->mbox);
|
|
|
|
xfree (uid);
|
2003-06-05 07:14:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
free_compressed( PKT_compressed *zd )
|
|
|
|
{
|
2016-11-15 16:23:41 +01:00
|
|
|
if (!zd)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (zd->buf)
|
|
|
|
{
|
|
|
|
/* We need to skip some bytes. Because don't have any
|
|
|
|
* information about the length, so we assume this is the last
|
|
|
|
* packet */
|
|
|
|
while (iobuf_read( zd->buf, NULL, 1<<30 ) != -1)
|
|
|
|
;
|
2003-06-05 07:14:21 +00:00
|
|
|
}
|
2016-11-15 16:23:41 +01:00
|
|
|
xfree(zd);
|
2003-06-05 07:14:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
free_encrypted( PKT_encrypted *ed )
|
|
|
|
{
|
2016-11-15 16:23:41 +01:00
|
|
|
if (!ed)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (ed->buf)
|
|
|
|
{
|
|
|
|
/* We need to skip some bytes. */
|
|
|
|
if (ed->is_partial)
|
|
|
|
{
|
|
|
|
while (iobuf_read( ed->buf, NULL, 1<<30 ) != -1)
|
|
|
|
;
|
2003-06-05 07:14:21 +00:00
|
|
|
}
|
2016-11-15 16:23:41 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
while (ed->len)
|
|
|
|
{
|
|
|
|
/* Skip the packet. */
|
|
|
|
int n = iobuf_read( ed->buf, NULL, ed->len );
|
|
|
|
if (n == -1)
|
|
|
|
ed->len = 0;
|
|
|
|
else
|
|
|
|
ed->len -= n;
|
|
|
|
}
|
2003-06-05 07:14:21 +00:00
|
|
|
}
|
|
|
|
}
|
2016-11-15 16:23:41 +01:00
|
|
|
xfree (ed);
|
2003-06-05 07:14:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
free_plaintext( PKT_plaintext *pt )
|
|
|
|
{
|
2016-11-15 16:23:41 +01:00
|
|
|
if (!pt)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (pt->buf)
|
|
|
|
{ /* We need to skip some bytes. */
|
|
|
|
if (pt->is_partial)
|
|
|
|
{
|
|
|
|
while (iobuf_read( pt->buf, NULL, 1<<30 ) != -1)
|
|
|
|
;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
while( pt->len )
|
|
|
|
{ /* Skip the packet. */
|
|
|
|
int n = iobuf_read( pt->buf, NULL, pt->len );
|
|
|
|
if (n == -1)
|
|
|
|
pt->len = 0;
|
|
|
|
else
|
|
|
|
pt->len -= n;
|
|
|
|
}
|
2003-06-05 07:14:21 +00:00
|
|
|
}
|
|
|
|
}
|
2016-11-15 16:23:41 +01:00
|
|
|
xfree (pt);
|
2003-06-05 07:14:21 +00:00
|
|
|
}
|
|
|
|
|
2017-03-29 11:57:40 +02:00
|
|
|
|
2003-06-05 07:14:21 +00:00
|
|
|
/****************
|
2017-03-29 11:28:30 +02:00
|
|
|
* Free the packet in PKT.
|
2003-06-05 07:14:21 +00:00
|
|
|
*/
|
|
|
|
void
|
2017-03-29 11:57:40 +02:00
|
|
|
free_packet (PACKET *pkt, parse_packet_ctx_t parsectx)
|
2003-06-05 07:14:21 +00:00
|
|
|
{
|
2017-03-29 11:28:30 +02:00
|
|
|
if (!pkt || !pkt->pkt.generic)
|
2017-03-29 11:57:40 +02:00
|
|
|
{
|
2017-03-30 16:01:52 +02:00
|
|
|
if (parsectx && parsectx->last_pkt.pkt.generic)
|
2017-03-29 11:57:40 +02:00
|
|
|
{
|
|
|
|
if (parsectx->free_last_pkt)
|
|
|
|
{
|
2017-03-30 16:01:52 +02:00
|
|
|
free_packet (&parsectx->last_pkt, NULL);
|
2017-03-29 11:57:40 +02:00
|
|
|
parsectx->free_last_pkt = 0;
|
|
|
|
}
|
2017-03-30 16:01:52 +02:00
|
|
|
parsectx->last_pkt.pkttype = 0;
|
|
|
|
parsectx->last_pkt.pkt.generic = NULL;
|
2017-03-29 11:57:40 +02:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2017-03-29 11:28:30 +02:00
|
|
|
|
|
|
|
if (DBG_MEMORY)
|
|
|
|
log_debug ("free_packet() type=%d\n", pkt->pkttype);
|
|
|
|
|
2017-03-29 11:57:40 +02:00
|
|
|
/* If we have a parser context holding PKT then do not free the
|
|
|
|
* packet but set a flag that the packet in the parser context is
|
|
|
|
* now a deep copy. */
|
2017-03-30 16:01:52 +02:00
|
|
|
if (parsectx && !parsectx->free_last_pkt
|
|
|
|
&& parsectx->last_pkt.pkttype == pkt->pkttype
|
|
|
|
&& parsectx->last_pkt.pkt.generic == pkt->pkt.generic)
|
2017-03-29 11:57:40 +02:00
|
|
|
{
|
2017-03-30 16:01:52 +02:00
|
|
|
parsectx->last_pkt = *pkt;
|
2017-03-29 11:57:40 +02:00
|
|
|
parsectx->free_last_pkt = 1;
|
|
|
|
pkt->pkt.generic = NULL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-03-29 11:28:30 +02:00
|
|
|
switch (pkt->pkttype)
|
|
|
|
{
|
|
|
|
case PKT_SIGNATURE:
|
|
|
|
free_seckey_enc (pkt->pkt.signature);
|
|
|
|
break;
|
|
|
|
case PKT_PUBKEY_ENC:
|
|
|
|
free_pubkey_enc (pkt->pkt.pubkey_enc);
|
|
|
|
break;
|
|
|
|
case PKT_SYMKEY_ENC:
|
|
|
|
free_symkey_enc (pkt->pkt.symkey_enc);
|
|
|
|
break;
|
|
|
|
case PKT_PUBLIC_KEY:
|
|
|
|
case PKT_PUBLIC_SUBKEY:
|
|
|
|
case PKT_SECRET_KEY:
|
|
|
|
case PKT_SECRET_SUBKEY:
|
|
|
|
free_public_key (pkt->pkt.public_key);
|
|
|
|
break;
|
|
|
|
case PKT_COMMENT:
|
|
|
|
free_comment (pkt->pkt.comment);
|
|
|
|
break;
|
|
|
|
case PKT_USER_ID:
|
|
|
|
free_user_id (pkt->pkt.user_id);
|
|
|
|
break;
|
|
|
|
case PKT_COMPRESSED:
|
|
|
|
free_compressed (pkt->pkt.compressed);
|
|
|
|
break;
|
|
|
|
case PKT_ENCRYPTED:
|
|
|
|
case PKT_ENCRYPTED_MDC:
|
2021-09-28 14:49:21 +09:00
|
|
|
case PKT_ENCRYPTED_AEAD:
|
2017-03-29 11:28:30 +02:00
|
|
|
free_encrypted (pkt->pkt.encrypted);
|
|
|
|
break;
|
|
|
|
case PKT_PLAINTEXT:
|
|
|
|
free_plaintext (pkt->pkt.plaintext);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
xfree (pkt->pkt.generic);
|
|
|
|
break;
|
2003-06-05 07:14:21 +00:00
|
|
|
}
|
2017-03-29 11:28:30 +02:00
|
|
|
|
|
|
|
pkt->pkt.generic = NULL;
|
2003-06-05 07:14:21 +00:00
|
|
|
}
|
|
|
|
|
2017-03-29 11:28:30 +02:00
|
|
|
|
2003-06-05 07:14:21 +00:00
|
|
|
/****************
|
|
|
|
* returns 0 if they match.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
cmp_public_keys( PKT_public_key *a, PKT_public_key *b )
|
|
|
|
{
|
|
|
|
int n, i;
|
|
|
|
|
|
|
|
if( a->timestamp != b->timestamp )
|
|
|
|
return -1;
|
|
|
|
if( a->version < 4 && a->expiredate != b->expiredate )
|
|
|
|
return -1;
|
|
|
|
if( a->pubkey_algo != b->pubkey_algo )
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
n = pubkey_get_npkey( b->pubkey_algo );
|
2015-04-30 17:02:42 +09:00
|
|
|
if( !n ) { /* unknown algorithm, rest is in opaque MPI */
|
|
|
|
if( mpi_cmp( a->pkey[0], b->pkey[0] ) )
|
|
|
|
return -1; /* can't compare due to unknown algorithm */
|
|
|
|
} else {
|
|
|
|
for(i=0; i < n; i++ ) {
|
|
|
|
if( mpi_cmp( a->pkey[i], b->pkey[i] ) )
|
|
|
|
return -1;
|
|
|
|
}
|
2003-06-05 07:14:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
cmp_signatures( PKT_signature *a, PKT_signature *b )
|
|
|
|
{
|
|
|
|
int n, i;
|
|
|
|
|
|
|
|
if( a->keyid[0] != b->keyid[0] )
|
|
|
|
return -1;
|
|
|
|
if( a->keyid[1] != b->keyid[1] )
|
|
|
|
return -1;
|
|
|
|
if( a->pubkey_algo != b->pubkey_algo )
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
n = pubkey_get_nsig( a->pubkey_algo );
|
|
|
|
if( !n )
|
|
|
|
return -1; /* can't compare due to unknown algorithm */
|
|
|
|
for(i=0; i < n; i++ ) {
|
|
|
|
if( mpi_cmp( a->data[i] , b->data[i] ) )
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/****************
|
|
|
|
* Returns: true if the user ids do not match
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
cmp_user_ids( PKT_user_id *a, PKT_user_id *b )
|
|
|
|
{
|
|
|
|
int res=1;
|
|
|
|
|
|
|
|
if( a == b )
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if( a->attrib_data && b->attrib_data )
|
|
|
|
{
|
|
|
|
res = a->attrib_len - b->attrib_len;
|
|
|
|
if( !res )
|
|
|
|
res = memcmp( a->attrib_data, b->attrib_data, a->attrib_len );
|
|
|
|
}
|
|
|
|
else if( !a->attrib_data && !b->attrib_data )
|
|
|
|
{
|
|
|
|
res = a->len - b->len;
|
|
|
|
if( !res )
|
|
|
|
res = memcmp( a->name, b->name, a->len );
|
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|