1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-10-31 20:08:43 +01:00
gnupg/g10/free-packet.c
Werner Koch 7f3ce66ec5
gpg: Remove support for PKA.
* g10/gpg.c (oPrintPKARecords): Remove.
(opts): Remove --print-pka-records.
(main): Remove "pka-lookups","pka-trust-increase" and other PKA stuff.
* g10/options.h (EXPORT_DANE_FORMAT): Remove.
(VERIFY_PKA_LOOKUPS, VERIFY_PKA_TRUST_INCREASE): Remove.
(KEYSERVER_HONOR_PKA_RECORD): Remove.
* g10/packet.h (pka_info_t): Remove.
(PKT_signature): Remove flags.pka_tried and pka_info.
* g10/parse-packet.c (register_known_notation): Remove
"pka-address@gnupg.org".
* g10/pkclist.c (check_signatures_trust): Remove PKA stuff.
* g10/call-dirmngr.c (gpg_dirmngr_get_pka): Remove.
* g10/export.c (parse_export_options): Remove "export-pka".
(do_export): Adjust for this.
(write_keyblock_to_output): Ditto.
(do_export_stream): Ditto.
(print_pka_or_dane_records): Rename to ...
(print_dane_records): this and remove two args. Remove PKA printing.
* g10/free-packet.c (free_seckey_enc, cp_pka_info): Adjust for removed
pka_info field.
* g10/getkey.c (get_pubkey_byname): Make AKL_PKA a dummy.
* g10/keyserver.c: Remove "honor-pka-record".
(keyserver_import_pka): Remove.
* g10/mainproc.c (get_pka_address): Remove.
(pka_uri_from_sig): Remove.
(check_sig_and_print): Remove code for PKA.
--

PKA (Public Key Association) was a DNS based key discovery method
which looked up fingerprint by mail addresses in the DNS.  This goes
back to the conference where DKIM was suggested to show that we
already had a better method for this available with PGP/MIME.  PKA was
was later superseded by an experimental DANE method and is today not
anymore relevant.  It is anyway doubtful whether PKA was ever widely
used.

Signed-off-by: Werner Koch <wk@gnupg.org>
2021-02-02 19:53:21 +01:00

576 lines
11 KiB
C

/* free-packet.c - cleanup stuff for packets
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
* 2005, 2010 Free Software Foundation, Inc.
*
* 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
* the Free Software Foundation; either version 3 of the License, or
* (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
* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "gpg.h"
#include "../common/util.h"
#include "packet.h"
#include "../common/iobuf.h"
#include "options.h"
/* 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);
}
/* 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;
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;
}
return gcry_mpi_copy (a);
}
void
free_symkey_enc( PKT_symkey_enc *enc )
{
xfree(enc);
}
void
free_pubkey_enc( PKT_pubkey_enc *enc )
{
int n, i;
n = pubkey_get_nenc( enc->pubkey_algo );
if( !n )
mpi_release(enc->data[0]);
for(i=0; i < n; i++ )
mpi_release( enc->data[i] );
xfree(enc);
}
void
free_seckey_enc( PKT_signature *sig )
{
int n, i;
n = pubkey_get_nsig( sig->pubkey_algo );
if( !n )
mpi_release(sig->data[0]);
for(i=0; i < n; i++ )
mpi_release( sig->data[i] );
xfree(sig->revkey);
xfree(sig->hashed);
xfree(sig->unhashed);
xfree (sig->signers_uid);
xfree(sig);
}
void
release_public_key_parts (PKT_public_key *pk)
{
int n, i;
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;
}
if (pk->seckey_info)
{
xfree (pk->seckey_info);
pk->seckey_info = NULL;
}
if (pk->prefs)
{
xfree (pk->prefs);
pk->prefs = NULL;
}
free_user_id (pk->user_id);
pk->user_id = NULL;
if (pk->revkey)
{
xfree(pk->revkey);
pk->revkey=NULL;
pk->numrevkeys=0;
}
if (pk->serialno)
{
xfree (pk->serialno);
pk->serialno = NULL;
}
if (pk->updateurl)
{
xfree (pk->updateurl);
pk->updateurl = NULL;
}
}
/* Free an allocated public key structure including all parts.
Passing NULL is allowed. */
void
free_public_key (PKT_public_key *pk)
{
if (pk)
{
release_public_key_parts (pk);
xfree(pk);
}
}
static subpktarea_t *
cp_subpktarea (subpktarea_t *s )
{
subpktarea_t *d;
if( !s )
return NULL;
d = xmalloc (sizeof (*d) + s->size - 1 );
d->size = s->size;
d->len = s->len;
memcpy (d->data, s->data, s->len);
return d;
}
/*
* Return a copy of the preferences
*/
prefitem_t *
copy_prefs (const prefitem_t *prefs)
{
size_t n;
prefitem_t *new;
if (!prefs)
return NULL;
for (n=0; prefs[n].type; n++)
;
new = xmalloc ( sizeof (*new) * (n+1));
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;
}
/* 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)
{
int n, i;
if (!d)
d = xmalloc (sizeof *d);
memcpy (d, s, sizeof *d);
d->seckey_info = NULL;
d->user_id = scopy_user_id (s->user_id);
d->prefs = copy_prefs (s->prefs);
n = pubkey_get_npkey (s->pubkey_algo);
i = 0;
if (!n)
d->pkey[i++] = my_mpi_copy (s->pkey[0]);
else
{
for (; i < n; i++ )
d->pkey[i] = my_mpi_copy (s->pkey[i]);
}
for (; i < PUBKEY_MAX_NSKEY; i++)
d->pkey[i] = NULL;
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);
}
else
d->revkey = NULL;
if (s->serialno)
d->serialno = xstrdup (s->serialno);
if (s->updateurl)
d->updateurl = xstrdup (s->updateurl);
return d;
}
PKT_signature *
copy_signature( PKT_signature *d, PKT_signature *s )
{
int n, i;
if( !d )
d = xmalloc(sizeof *d);
memcpy( d, s, sizeof *d );
n = pubkey_get_nsig( s->pubkey_algo );
if( !n )
d->data[0] = my_mpi_copy(s->data[0]);
else {
for(i=0; i < n; i++ )
d->data[i] = my_mpi_copy( s->data[i] );
}
d->hashed = cp_subpktarea (s->hashed);
d->unhashed = cp_subpktarea (s->unhashed);
if (s->signers_uid)
d->signers_uid = xstrdup (s->signers_uid);
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 )
{
xfree(rem);
}
void
free_attributes(PKT_user_id *uid)
{
if (!uid)
return;
xfree(uid->attribs);
xfree(uid->attrib_data);
uid->attribs=NULL;
uid->attrib_data=NULL;
uid->attrib_len=0;
}
void
free_user_id (PKT_user_id *uid)
{
if (!uid)
return;
log_assert (uid->ref > 0);
if (--uid->ref)
return;
free_attributes(uid);
xfree (uid->prefs);
xfree (uid->namehash);
xfree (uid->updateurl);
xfree (uid->mbox);
xfree (uid);
}
void
free_compressed( PKT_compressed *zd )
{
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)
;
}
xfree(zd);
}
void
free_encrypted( PKT_encrypted *ed )
{
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)
;
}
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;
}
}
}
xfree (ed);
}
void
free_plaintext( PKT_plaintext *pt )
{
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;
}
}
}
xfree (pt);
}
/****************
* Free the packet in PKT.
*/
void
free_packet (PACKET *pkt, parse_packet_ctx_t parsectx)
{
if (!pkt || !pkt->pkt.generic)
{
if (parsectx && parsectx->last_pkt.pkt.generic)
{
if (parsectx->free_last_pkt)
{
free_packet (&parsectx->last_pkt, NULL);
parsectx->free_last_pkt = 0;
}
parsectx->last_pkt.pkttype = 0;
parsectx->last_pkt.pkt.generic = NULL;
}
return;
}
if (DBG_MEMORY)
log_debug ("free_packet() type=%d\n", pkt->pkttype);
/* 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. */
if (parsectx && !parsectx->free_last_pkt
&& parsectx->last_pkt.pkttype == pkt->pkttype
&& parsectx->last_pkt.pkt.generic == pkt->pkt.generic)
{
parsectx->last_pkt = *pkt;
parsectx->free_last_pkt = 1;
pkt->pkt.generic = NULL;
return;
}
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:
free_encrypted (pkt->pkt.encrypted);
break;
case PKT_PLAINTEXT:
free_plaintext (pkt->pkt.plaintext);
break;
default:
xfree (pkt->pkt.generic);
break;
}
pkt->pkt.generic = NULL;
}
/****************
* 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 );
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;
}
}
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;
}