LCOV - code coverage report
Current view: top level - g10 - free-packet.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 181 255 71.0 %
Date: 2016-11-29 15:00:56 Functions: 18 22 81.8 %

          Line data    Source code
       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 "util.h"
      28             : #include "packet.h"
      29             : #include "../common/iobuf.h"
      30             : #include "options.h"
      31             : 
      32             : 
      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.  */
      35             : static gcry_mpi_t
      36        7611 : my_mpi_copy (gcry_mpi_t a)
      37             : {
      38        7611 :   if (a
      39        7611 :       && gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)
      40         363 :       && !gcry_mpi_get_opaque (a, NULL))
      41           0 :     return NULL;
      42             : 
      43        7611 :   return gcry_mpi_copy (a);
      44             : }
      45             : 
      46             : 
      47             : void
      48          59 : free_symkey_enc( PKT_symkey_enc *enc )
      49             : {
      50          59 :     xfree(enc);
      51          59 : }
      52             : 
      53             : void
      54         526 : free_pubkey_enc( PKT_pubkey_enc *enc )
      55             : {
      56             :     int n, i;
      57         526 :     n = pubkey_get_nenc( enc->pubkey_algo );
      58         526 :     if( !n )
      59           0 :         mpi_release(enc->data[0]);
      60        1561 :     for(i=0; i < n; i++ )
      61        1035 :         mpi_release( enc->data[i] );
      62         526 :     xfree(enc);
      63         526 : }
      64             : 
      65             : void
      66        9226 : free_seckey_enc( PKT_signature *sig )
      67             : {
      68             :   int n, i;
      69             : 
      70        9226 :   n = pubkey_get_nsig( sig->pubkey_algo );
      71        9226 :   if( !n )
      72           0 :     mpi_release(sig->data[0]);
      73       24789 :   for(i=0; i < n; i++ )
      74       15563 :     mpi_release( sig->data[i] );
      75             : 
      76        9226 :   xfree(sig->revkey);
      77        9226 :   xfree(sig->hashed);
      78        9226 :   xfree(sig->unhashed);
      79             : 
      80        9226 :   if (sig->pka_info)
      81             :     {
      82           0 :       xfree (sig->pka_info->uri);
      83           0 :       xfree (sig->pka_info);
      84             :     }
      85        9226 :   xfree (sig->signers_uid);
      86             : 
      87        9226 :   xfree(sig);
      88        9226 : }
      89             : 
      90             : 
      91             : void
      92        9140 : release_public_key_parts (PKT_public_key *pk)
      93             : {
      94             :   int n, i;
      95             : 
      96        9140 :   if (pk->seckey_info)
      97          38 :     n = pubkey_get_nskey (pk->pubkey_algo);
      98             :   else
      99        9102 :     n = pubkey_get_npkey (pk->pubkey_algo);
     100        9140 :   if (!n)
     101         184 :     mpi_release (pk->pkey[0]);
     102       36101 :   for (i=0; i < n; i++ )
     103             :     {
     104       26961 :       mpi_release (pk->pkey[i]);
     105       26961 :       pk->pkey[i] = NULL;
     106             :     }
     107        9140 :   if (pk->seckey_info)
     108             :     {
     109          38 :       xfree (pk->seckey_info);
     110          38 :       pk->seckey_info = NULL;
     111             :     }
     112        9140 :   if (pk->prefs)
     113             :     {
     114        6832 :       xfree (pk->prefs);
     115        6832 :       pk->prefs = NULL;
     116             :     }
     117        9140 :   free_user_id (pk->user_id);
     118        9140 :   pk->user_id = NULL;
     119        9140 :   if (pk->revkey)
     120             :     {
     121           2 :       xfree(pk->revkey);
     122           2 :       pk->revkey=NULL;
     123           2 :       pk->numrevkeys=0;
     124             :     }
     125        9140 :   if (pk->serialno)
     126             :     {
     127           0 :       xfree (pk->serialno);
     128           0 :       pk->serialno = NULL;
     129             :     }
     130        9140 : }
     131             : 
     132             : 
     133             : /* Free an allocated public key structure including all parts.
     134             :    Passing NULL is allowed.  */
     135             : void
     136        9062 : free_public_key (PKT_public_key *pk)
     137             : {
     138        9062 :   if (pk)
     139             :     {
     140        9062 :       release_public_key_parts (pk);
     141        9062 :       xfree(pk);
     142             :     }
     143        9062 : }
     144             : 
     145             : 
     146             : static subpktarea_t *
     147           0 : cp_subpktarea (subpktarea_t *s )
     148             : {
     149             :     subpktarea_t *d;
     150             : 
     151           0 :     if( !s )
     152           0 :         return NULL;
     153           0 :     d = xmalloc (sizeof (*d) + s->size - 1 );
     154           0 :     d->size = s->size;
     155           0 :     d->len = s->len;
     156           0 :     memcpy (d->data, s->data, s->len);
     157           0 :     return d;
     158             : }
     159             : 
     160             : /*
     161             :  * Return a copy of the preferences
     162             :  */
     163             : prefitem_t *
     164        7671 : copy_prefs (const prefitem_t *prefs)
     165             : {
     166             :     size_t n;
     167             :     prefitem_t *new;
     168             : 
     169        7671 :     if (!prefs)
     170         103 :         return NULL;
     171             : 
     172        7568 :     for (n=0; prefs[n].type; n++)
     173             :         ;
     174        7568 :     new = xmalloc ( sizeof (*new) * (n+1));
     175       69276 :     for (n=0; prefs[n].type; n++) {
     176       61708 :         new[n].type = prefs[n].type;
     177       61708 :         new[n].value = prefs[n].value;
     178             :     }
     179        7568 :     new[n].type = PREFTYPE_NONE;
     180        7568 :     new[n].value = 0;
     181             : 
     182        7568 :     return new;
     183             : }
     184             : 
     185             : 
     186             : /* Copy the public key S to D.  If D is NULL allocate a new public key
     187             :    structure.  If S has seckret key infos, only the public stuff is
     188             :    copied.  */
     189             : PKT_public_key *
     190        2371 : copy_public_key (PKT_public_key *d, PKT_public_key *s)
     191             : {
     192             :   int n, i;
     193             : 
     194        2371 :   if (!d)
     195         734 :     d = xmalloc (sizeof *d);
     196        2371 :   memcpy (d, s, sizeof *d);
     197        2371 :   d->seckey_info = NULL;
     198        2371 :   d->user_id = scopy_user_id (s->user_id);
     199        2371 :   d->prefs = copy_prefs (s->prefs);
     200             : 
     201        2371 :   n = pubkey_get_npkey (s->pubkey_algo);
     202        2371 :   i = 0;
     203        2371 :   if (!n)
     204           0 :     d->pkey[i++] = my_mpi_copy (s->pkey[0]);
     205             :   else
     206             :     {
     207        9982 :       for (; i < n; i++ )
     208        7611 :         d->pkey[i] = my_mpi_copy (s->pkey[i]);
     209             :     }
     210       11357 :   for (; i < PUBKEY_MAX_NSKEY; i++)
     211        8986 :     d->pkey[i] = NULL;
     212             : 
     213        2371 :   if (!s->revkey && s->numrevkeys)
     214           0 :     BUG();
     215        2371 :   if (s->numrevkeys)
     216             :     {
     217           0 :       d->revkey = xmalloc(sizeof(struct revocation_key)*s->numrevkeys);
     218           0 :       memcpy(d->revkey,s->revkey,sizeof(struct revocation_key)*s->numrevkeys);
     219             :     }
     220             :   else
     221        2371 :     d->revkey = NULL;
     222        2371 :   return d;
     223             : }
     224             : 
     225             : 
     226             : 
     227             : static pka_info_t *
     228           0 : cp_pka_info (const pka_info_t *s)
     229             : {
     230           0 :   pka_info_t *d = xmalloc (sizeof *s + strlen (s->email));
     231             : 
     232           0 :   d->valid = s->valid;
     233           0 :   d->checked = s->checked;
     234           0 :   d->uri = s->uri? xstrdup (s->uri):NULL;
     235           0 :   memcpy (d->fpr, s->fpr, sizeof s->fpr);
     236           0 :   strcpy (d->email, s->email);
     237           0 :   return d;
     238             : }
     239             : 
     240             : 
     241             : PKT_signature *
     242           0 : copy_signature( PKT_signature *d, PKT_signature *s )
     243             : {
     244             :     int n, i;
     245             : 
     246           0 :     if( !d )
     247           0 :         d = xmalloc(sizeof *d);
     248           0 :     memcpy( d, s, sizeof *d );
     249           0 :     n = pubkey_get_nsig( s->pubkey_algo );
     250           0 :     if( !n )
     251           0 :         d->data[0] = my_mpi_copy(s->data[0]);
     252             :     else {
     253           0 :         for(i=0; i < n; i++ )
     254           0 :             d->data[i] = my_mpi_copy( s->data[i] );
     255             :     }
     256           0 :     d->pka_info = s->pka_info? cp_pka_info (s->pka_info) : NULL;
     257           0 :     d->hashed = cp_subpktarea (s->hashed);
     258           0 :     d->unhashed = cp_subpktarea (s->unhashed);
     259           0 :     if (s->signers_uid)
     260           0 :       d->signers_uid = xstrdup (s->signers_uid);
     261           0 :     if(s->numrevkeys)
     262             :       {
     263           0 :         d->revkey=NULL;
     264           0 :         d->numrevkeys=0;
     265           0 :         parse_revkeys(d);
     266             :       }
     267           0 :     return d;
     268             : }
     269             : 
     270             : 
     271             : /*
     272             :  * shallow copy of the user ID
     273             :  */
     274             : PKT_user_id *
     275        4902 : scopy_user_id (PKT_user_id *s)
     276             : {
     277        4902 :     if (s)
     278         459 :         s->ref++;
     279        4902 :     return s;
     280             : }
     281             : 
     282             : 
     283             : 
     284             : void
     285           0 : free_comment( PKT_comment *rem )
     286             : {
     287           0 :     xfree(rem);
     288           0 : }
     289             : 
     290             : void
     291        4405 : free_attributes(PKT_user_id *uid)
     292             : {
     293        4405 :   if (!uid)
     294        4405 :     return;
     295             : 
     296        4405 :   xfree(uid->attribs);
     297        4405 :   xfree(uid->attrib_data);
     298             : 
     299        4405 :   uid->attribs=NULL;
     300        4405 :   uid->attrib_data=NULL;
     301        4405 :   uid->attrib_len=0;
     302             : }
     303             : 
     304             : void
     305       16232 : free_user_id (PKT_user_id *uid)
     306             : {
     307       16232 :   if (!uid)
     308       11368 :     return;
     309             : 
     310        4864 :   log_assert (uid->ref > 0);
     311        4864 :   if (--uid->ref)
     312         459 :     return;
     313             : 
     314        4405 :   free_attributes(uid);
     315        4405 :   xfree (uid->prefs);
     316        4405 :   xfree (uid->namehash);
     317        4405 :   xfree (uid->mbox);
     318        4405 :   xfree (uid);
     319             : }
     320             : 
     321             : void
     322         424 : free_compressed( PKT_compressed *zd )
     323             : {
     324         424 :   if (!zd)
     325         424 :     return;
     326             : 
     327         424 :   if (zd->buf)
     328             :     {
     329             :       /* We need to skip some bytes.  Because don't have any
     330             :        * information about the length, so we assume this is the last
     331             :        * packet */
     332           0 :       while (iobuf_read( zd->buf, NULL, 1<<30 ) != -1)
     333             :         ;
     334             :     }
     335         424 :   xfree(zd);
     336             : }
     337             : 
     338             : void
     339         319 : free_encrypted( PKT_encrypted *ed )
     340             : {
     341         319 :   if (!ed)
     342         319 :     return;
     343             : 
     344         319 :   if (ed->buf)
     345             :     {
     346             :       /* We need to skip some bytes. */
     347           0 :       if (ed->is_partial)
     348             :         {
     349           0 :           while (iobuf_read( ed->buf, NULL, 1<<30 ) != -1)
     350             :             ;
     351             :         }
     352             :       else
     353             :         {
     354           0 :           while (ed->len)
     355             :             {
     356             :               /* Skip the packet. */
     357           0 :               int n = iobuf_read( ed->buf, NULL, ed->len );
     358           0 :               if (n == -1)
     359           0 :                 ed->len = 0;
     360             :               else
     361           0 :                 ed->len -= n;
     362             :             }
     363             :         }
     364             :     }
     365         319 :   xfree (ed);
     366             : }
     367             : 
     368             : 
     369             : void
     370         835 : free_plaintext( PKT_plaintext *pt )
     371             : {
     372         835 :   if (!pt)
     373         835 :     return;
     374             : 
     375         835 :   if (pt->buf)
     376             :     { /* We need to skip some bytes.  */
     377         421 :       if (pt->is_partial)
     378             :         {
     379           0 :           while (iobuf_read( pt->buf, NULL, 1<<30 ) != -1)
     380             :             ;
     381             :         }
     382             :       else
     383             :         {
     384         849 :           while( pt->len )
     385             :             { /* Skip the packet.  */
     386           7 :               int n = iobuf_read( pt->buf, NULL, pt->len );
     387           7 :               if (n == -1)
     388           0 :                 pt->len = 0;
     389             :               else
     390           7 :                 pt->len -= n;
     391             :             }
     392             :         }
     393             :     }
     394         835 :   xfree (pt);
     395             : }
     396             : 
     397             : /****************
     398             :  * Free the packet in pkt.
     399             :  */
     400             : void
     401       28687 : free_packet( PACKET *pkt )
     402             : {
     403       28687 :     if( !pkt || !pkt->pkt.generic )
     404       33511 :         return;
     405             : 
     406       23863 :     if( DBG_MEMORY )
     407           0 :         log_debug("free_packet() type=%d\n", pkt->pkttype );
     408             : 
     409       23863 :     switch( pkt->pkttype ) {
     410             :       case PKT_SIGNATURE:
     411        9097 :         free_seckey_enc( pkt->pkt.signature );
     412        9097 :         break;
     413             :       case PKT_PUBKEY_ENC:
     414         271 :         free_pubkey_enc( pkt->pkt.pubkey_enc );
     415         271 :         break;
     416             :       case PKT_SYMKEY_ENC:
     417          59 :         free_symkey_enc( pkt->pkt.symkey_enc );
     418          59 :         break;
     419             :       case PKT_PUBLIC_KEY:
     420             :       case PKT_PUBLIC_SUBKEY:
     421             :       case PKT_SECRET_KEY:
     422             :       case PKT_SECRET_SUBKEY:
     423        7318 :         free_public_key (pkt->pkt.public_key);
     424        7318 :         break;
     425             :       case PKT_COMMENT:
     426           0 :         free_comment( pkt->pkt.comment );
     427           0 :         break;
     428             :       case PKT_USER_ID:
     429        4404 :         free_user_id( pkt->pkt.user_id );
     430        4404 :         break;
     431             :       case PKT_COMPRESSED:
     432         424 :         free_compressed( pkt->pkt.compressed);
     433         424 :         break;
     434             :       case PKT_ENCRYPTED:
     435             :       case PKT_ENCRYPTED_MDC:
     436         319 :         free_encrypted( pkt->pkt.encrypted );
     437         319 :         break;
     438             :       case PKT_PLAINTEXT:
     439         835 :         free_plaintext( pkt->pkt.plaintext );
     440         835 :         break;
     441             :       default:
     442        1136 :         xfree( pkt->pkt.generic );
     443        1136 :         break;
     444             :     }
     445       23863 :     pkt->pkt.generic = NULL;
     446             : }
     447             : 
     448             : /****************
     449             :  * returns 0 if they match.
     450             :  */
     451             : int
     452         140 : cmp_public_keys( PKT_public_key *a, PKT_public_key *b )
     453             : {
     454             :     int n, i;
     455             : 
     456         140 :     if( a->timestamp != b->timestamp )
     457           8 :         return -1;
     458         132 :     if( a->version < 4 && a->expiredate != b->expiredate )
     459           0 :         return -1;
     460         132 :     if( a->pubkey_algo != b->pubkey_algo )
     461           0 :         return -1;
     462             : 
     463         132 :     n = pubkey_get_npkey( b->pubkey_algo );
     464         132 :     if( !n ) { /* unknown algorithm, rest is in opaque MPI */
     465           0 :         if( mpi_cmp( a->pkey[0], b->pkey[0] ) )
     466           0 :             return -1; /* can't compare due to unknown algorithm */
     467             :     } else {
     468         530 :         for(i=0; i < n; i++ ) {
     469         398 :             if( mpi_cmp( a->pkey[i], b->pkey[i] ) )
     470           0 :                 return -1;
     471             :         }
     472             :     }
     473             : 
     474         132 :     return 0;
     475             : }
     476             : 
     477             : 
     478             : 
     479             : int
     480        2692 : cmp_signatures( PKT_signature *a, PKT_signature *b )
     481             : {
     482             :     int n, i;
     483             : 
     484        2692 :     if( a->keyid[0] != b->keyid[0] )
     485        2357 :         return -1;
     486         335 :     if( a->keyid[1] != b->keyid[1] )
     487           0 :         return -1;
     488         335 :     if( a->pubkey_algo != b->pubkey_algo )
     489           0 :         return -1;
     490             : 
     491         335 :     n = pubkey_get_nsig( a->pubkey_algo );
     492         335 :     if( !n )
     493           0 :         return -1; /* can't compare due to unknown algorithm */
     494         545 :     for(i=0; i < n; i++ ) {
     495         429 :         if( mpi_cmp( a->data[i] , b->data[i] ) )
     496         219 :             return -1;
     497             :     }
     498         116 :     return 0;
     499             : }
     500             : 
     501             : 
     502             : /****************
     503             :  * Returns: true if the user ids do not match
     504             :  */
     505             : int
     506         195 : cmp_user_ids( PKT_user_id *a, PKT_user_id *b )
     507             : {
     508         195 :     int res=1;
     509             : 
     510         195 :     if( a == b )
     511           0 :         return 0;
     512             : 
     513         195 :     if( a->attrib_data && b->attrib_data )
     514             :       {
     515           0 :         res = a->attrib_len - b->attrib_len;
     516           0 :         if( !res )
     517           0 :           res = memcmp( a->attrib_data, b->attrib_data, a->attrib_len );
     518             :       }
     519         195 :     else if( !a->attrib_data && !b->attrib_data )
     520             :       {
     521         195 :         res = a->len - b->len;
     522         195 :         if( !res )
     523         122 :           res = memcmp( a->name, b->name, a->len );
     524             :       }
     525             : 
     526         195 :     return res;
     527             : }

Generated by: LCOV version 1.11