LCOV - code coverage report
Current view: top level - g10 - free-packet.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 174 246 70.7 %
Date: 2015-11-05 17:10:59 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 <http://www.gnu.org/licenses/>.
      19             :  */
      20             : 
      21             : #include <config.h>
      22             : #include <stdio.h>
      23             : #include <stdlib.h>
      24             : #include <string.h>
      25             : #include <assert.h>
      26             : 
      27             : #include "gpg.h"
      28             : #include "util.h"
      29             : #include "packet.h"
      30             : #include "../common/iobuf.h"
      31             : #include "options.h"
      32             : 
      33             : 
      34             : /* This is mpi_copy with a fix for opaque MPIs which store a NULL
      35             :    pointer.  This will also be fixed in Libggcrypt 1.7.0.  */
      36             : static gcry_mpi_t
      37        6859 : my_mpi_copy (gcry_mpi_t a)
      38             : {
      39        6859 :   if (a
      40        6859 :       && gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)
      41         351 :       && !gcry_mpi_get_opaque (a, NULL))
      42           0 :     return NULL;
      43             : 
      44        6859 :   return gcry_mpi_copy (a);
      45             : }
      46             : 
      47             : 
      48             : void
      49         218 : free_symkey_enc( PKT_symkey_enc *enc )
      50             : {
      51         218 :     xfree(enc);
      52         218 : }
      53             : 
      54             : void
      55         489 : free_pubkey_enc( PKT_pubkey_enc *enc )
      56             : {
      57             :     int n, i;
      58         489 :     n = pubkey_get_nenc( enc->pubkey_algo );
      59         489 :     if( !n )
      60           0 :         mpi_release(enc->data[0]);
      61        1466 :     for(i=0; i < n; i++ )
      62         977 :         mpi_release( enc->data[i] );
      63         489 :     xfree(enc);
      64         489 : }
      65             : 
      66             : void
      67        6300 : free_seckey_enc( PKT_signature *sig )
      68             : {
      69             :   int n, i;
      70             : 
      71        6300 :   n = pubkey_get_nsig( sig->pubkey_algo );
      72        6300 :   if( !n )
      73           0 :     mpi_release(sig->data[0]);
      74       18438 :   for(i=0; i < n; i++ )
      75       12138 :     mpi_release( sig->data[i] );
      76             : 
      77        6300 :   xfree(sig->revkey);
      78        6300 :   xfree(sig->hashed);
      79        6300 :   xfree(sig->unhashed);
      80             : 
      81        6300 :   if (sig->pka_info)
      82             :     {
      83           0 :       xfree (sig->pka_info->uri);
      84           0 :       xfree (sig->pka_info);
      85             :     }
      86             : 
      87        6300 :   xfree(sig);
      88        6300 : }
      89             : 
      90             : 
      91             : void
      92        6330 : release_public_key_parts (PKT_public_key *pk)
      93             : {
      94             :   int n, i;
      95             : 
      96        6330 :   if (pk->seckey_info)
      97          14 :     n = pubkey_get_nskey (pk->pubkey_algo);
      98             :   else
      99        6316 :     n = pubkey_get_npkey (pk->pubkey_algo);
     100        6330 :   if (!n)
     101          60 :     mpi_release (pk->pkey[0]);
     102       27071 :   for (i=0; i < n; i++ )
     103             :     {
     104       20741 :       mpi_release (pk->pkey[i]);
     105       20741 :       pk->pkey[i] = NULL;
     106             :     }
     107        6330 :   if (pk->seckey_info)
     108             :     {
     109          14 :       xfree (pk->seckey_info);
     110          14 :       pk->seckey_info = NULL;
     111             :     }
     112        6330 :   if (pk->prefs)
     113             :     {
     114        5300 :       xfree (pk->prefs);
     115        5300 :       pk->prefs = NULL;
     116             :     }
     117        6330 :   if (pk->user_id)
     118             :     {
     119         292 :       free_user_id (pk->user_id);
     120         292 :       pk->user_id = NULL;
     121             :     }
     122        6330 :   if (pk->revkey)
     123             :     {
     124           2 :       xfree(pk->revkey);
     125           2 :       pk->revkey=NULL;
     126           2 :       pk->numrevkeys=0;
     127             :     }
     128        6330 :   if (pk->serialno)
     129             :     {
     130           0 :       xfree (pk->serialno);
     131           0 :       pk->serialno = NULL;
     132             :     }
     133        6330 : }
     134             : 
     135             : 
     136             : /* Free an allocated public key structure including all parts.
     137             :    Passing NULL is allowed.  */
     138             : void
     139        6181 : free_public_key (PKT_public_key *pk)
     140             : {
     141        6181 :   if (pk)
     142             :     {
     143        6181 :       release_public_key_parts (pk);
     144        6181 :       xfree(pk);
     145             :     }
     146        6181 : }
     147             : 
     148             : 
     149             : static subpktarea_t *
     150           0 : cp_subpktarea (subpktarea_t *s )
     151             : {
     152             :     subpktarea_t *d;
     153             : 
     154           0 :     if( !s )
     155           0 :         return NULL;
     156           0 :     d = xmalloc (sizeof (*d) + s->size - 1 );
     157           0 :     d->size = s->size;
     158           0 :     d->len = s->len;
     159           0 :     memcpy (d->data, s->data, s->len);
     160           0 :     return d;
     161             : }
     162             : 
     163             : /*
     164             :  * Return a copy of the preferences
     165             :  */
     166             : prefitem_t *
     167        6189 : copy_prefs (const prefitem_t *prefs)
     168             : {
     169             :     size_t n;
     170             :     prefitem_t *new;
     171             : 
     172        6189 :     if (!prefs)
     173          55 :         return NULL;
     174             : 
     175        6134 :     for (n=0; prefs[n].type; n++)
     176             :         ;
     177        6134 :     new = xmalloc ( sizeof (*new) * (n+1));
     178       51565 :     for (n=0; prefs[n].type; n++) {
     179       45431 :         new[n].type = prefs[n].type;
     180       45431 :         new[n].value = prefs[n].value;
     181             :     }
     182        6134 :     new[n].type = PREFTYPE_NONE;
     183        6134 :     new[n].value = 0;
     184             : 
     185        6134 :     return new;
     186             : }
     187             : 
     188             : 
     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
     191             :    copied.  */
     192             : PKT_public_key *
     193        2064 : copy_public_key (PKT_public_key *d, PKT_public_key *s)
     194             : {
     195             :   int n, i;
     196             : 
     197        2064 :   if (!d)
     198         648 :     d = xmalloc (sizeof *d);
     199        2064 :   memcpy (d, s, sizeof *d);
     200        2064 :   d->seckey_info = NULL;
     201        2064 :   d->user_id = scopy_user_id (s->user_id);
     202        2064 :   d->prefs = copy_prefs (s->prefs);
     203             : 
     204        2064 :   n = pubkey_get_npkey (s->pubkey_algo);
     205        2064 :   i = 0;
     206        2064 :   if (!n)
     207           0 :     d->pkey[i++] = my_mpi_copy (s->pkey[0]);
     208             :   else
     209             :     {
     210        8923 :       for (; i < n; i++ )
     211        6859 :         d->pkey[i] = my_mpi_copy (s->pkey[i]);
     212             :     }
     213        9653 :   for (; i < PUBKEY_MAX_NSKEY; i++)
     214        7589 :     d->pkey[i] = NULL;
     215             : 
     216        2064 :   if (!s->revkey && s->numrevkeys)
     217           0 :     BUG();
     218        2064 :   if (s->numrevkeys)
     219             :     {
     220           0 :       d->revkey = xmalloc(sizeof(struct revocation_key)*s->numrevkeys);
     221           0 :       memcpy(d->revkey,s->revkey,sizeof(struct revocation_key)*s->numrevkeys);
     222             :     }
     223             :   else
     224        2064 :     d->revkey = NULL;
     225        2064 :   return d;
     226             : }
     227             : 
     228             : 
     229             : 
     230             : static pka_info_t *
     231           0 : cp_pka_info (const pka_info_t *s)
     232             : {
     233           0 :   pka_info_t *d = xmalloc (sizeof *s + strlen (s->email));
     234             : 
     235           0 :   d->valid = s->valid;
     236           0 :   d->checked = s->checked;
     237           0 :   d->uri = s->uri? xstrdup (s->uri):NULL;
     238           0 :   memcpy (d->fpr, s->fpr, sizeof s->fpr);
     239           0 :   strcpy (d->email, s->email);
     240           0 :   return d;
     241             : }
     242             : 
     243             : 
     244             : PKT_signature *
     245           0 : copy_signature( PKT_signature *d, PKT_signature *s )
     246             : {
     247             :     int n, i;
     248             : 
     249           0 :     if( !d )
     250           0 :         d = xmalloc(sizeof *d);
     251           0 :     memcpy( d, s, sizeof *d );
     252           0 :     n = pubkey_get_nsig( s->pubkey_algo );
     253           0 :     if( !n )
     254           0 :         d->data[0] = my_mpi_copy(s->data[0]);
     255             :     else {
     256           0 :         for(i=0; i < n; i++ )
     257           0 :             d->data[i] = my_mpi_copy( s->data[i] );
     258             :     }
     259           0 :     d->pka_info = s->pka_info? cp_pka_info (s->pka_info) : NULL;
     260           0 :     d->hashed = cp_subpktarea (s->hashed);
     261           0 :     d->unhashed = cp_subpktarea (s->unhashed);
     262           0 :     if(s->numrevkeys)
     263             :       {
     264           0 :         d->revkey=NULL;
     265           0 :         d->numrevkeys=0;
     266           0 :         parse_revkeys(d);
     267             :       }
     268           0 :     return d;
     269             : }
     270             : 
     271             : 
     272             : /*
     273             :  * shallow copy of the user ID
     274             :  */
     275             : PKT_user_id *
     276        4137 : scopy_user_id (PKT_user_id *s)
     277             : {
     278        4137 :     if (s)
     279         292 :         s->ref++;
     280        4137 :     return s;
     281             : }
     282             : 
     283             : 
     284             : 
     285             : void
     286           0 : free_comment( PKT_comment *rem )
     287             : {
     288           0 :     xfree(rem);
     289           0 : }
     290             : 
     291             : void
     292        3141 : free_attributes(PKT_user_id *uid)
     293             : {
     294        3141 :   xfree(uid->attribs);
     295        3141 :   xfree(uid->attrib_data);
     296             : 
     297        3141 :   uid->attribs=NULL;
     298        3141 :   uid->attrib_data=NULL;
     299        3141 :   uid->attrib_len=0;
     300        3141 : }
     301             : 
     302             : void
     303        3433 : free_user_id (PKT_user_id *uid)
     304             : {
     305        3433 :     assert (uid->ref > 0);
     306        3433 :     if (--uid->ref)
     307        3725 :         return;
     308             : 
     309        3141 :     free_attributes(uid);
     310        3141 :     xfree (uid->prefs);
     311        3141 :     xfree (uid->namehash);
     312        3141 :     xfree (uid);
     313             : }
     314             : 
     315             : void
     316         540 : free_compressed( PKT_compressed *zd )
     317             : {
     318         540 :     if( zd->buf ) { /* have to skip some bytes */
     319             :         /* don't have any information about the length, so
     320             :          * we assume this is the last packet */
     321           0 :         while( iobuf_read( zd->buf, NULL, 1<<30 ) != -1 )
     322             :             ;
     323             :     }
     324         540 :     xfree(zd);
     325         540 : }
     326             : 
     327             : void
     328         470 : free_encrypted( PKT_encrypted *ed )
     329             : {
     330         470 :     if( ed->buf ) { /* have to skip some bytes */
     331           0 :         if( ed->is_partial ) {
     332           0 :             while( iobuf_read( ed->buf, NULL, 1<<30 ) != -1 )
     333             :                 ;
     334             :         }
     335             :         else {
     336           0 :            while( ed->len ) { /* skip the packet */
     337           0 :                int n = iobuf_read( ed->buf, NULL, ed->len );
     338           0 :                if( n == -1 )
     339           0 :                    ed->len = 0;
     340             :                else
     341           0 :                    ed->len -= n;
     342             :            }
     343             :         }
     344             :     }
     345         470 :     xfree(ed);
     346         470 : }
     347             : 
     348             : 
     349             : void
     350        1001 : free_plaintext( PKT_plaintext *pt )
     351             : {
     352        1001 :     if( pt->buf ) { /* have to skip some bytes */
     353         547 :         if( pt->is_partial ) {
     354           1 :             while( iobuf_read( pt->buf, NULL, 1<<30 ) != -1 )
     355             :                 ;
     356             :         }
     357             :         else {
     358        1100 :            while( pt->len ) { /* skip the packet */
     359           8 :                int n = iobuf_read( pt->buf, NULL, pt->len );
     360           8 :                if( n == -1 )
     361           0 :                    pt->len = 0;
     362             :                else
     363           8 :                    pt->len -= n;
     364             :            }
     365             :         }
     366             :     }
     367        1001 :     xfree(pt);
     368        1001 : }
     369             : 
     370             : /****************
     371             :  * Free the packet in pkt.
     372             :  */
     373             : void
     374       21737 : free_packet( PACKET *pkt )
     375             : {
     376       21737 :     if( !pkt || !pkt->pkt.generic )
     377       25907 :         return;
     378             : 
     379       17567 :     if( DBG_MEMORY )
     380           0 :         log_debug("free_packet() type=%d\n", pkt->pkttype );
     381             : 
     382       17567 :     switch( pkt->pkttype ) {
     383             :       case PKT_SIGNATURE:
     384        6298 :         free_seckey_enc( pkt->pkt.signature );
     385        6298 :         break;
     386             :       case PKT_PUBKEY_ENC:
     387         253 :         free_pubkey_enc( pkt->pkt.pubkey_enc );
     388         253 :         break;
     389             :       case PKT_SYMKEY_ENC:
     390         218 :         free_symkey_enc( pkt->pkt.symkey_enc );
     391         218 :         break;
     392             :       case PKT_PUBLIC_KEY:
     393             :       case PKT_PUBLIC_SUBKEY:
     394             :       case PKT_SECRET_KEY:
     395             :       case PKT_SECRET_SUBKEY:
     396        4853 :         free_public_key (pkt->pkt.public_key);
     397        4853 :         break;
     398             :       case PKT_COMMENT:
     399           0 :         free_comment( pkt->pkt.comment );
     400           0 :         break;
     401             :       case PKT_USER_ID:
     402        3141 :         free_user_id( pkt->pkt.user_id );
     403        3141 :         break;
     404             :       case PKT_COMPRESSED:
     405         540 :         free_compressed( pkt->pkt.compressed);
     406         540 :         break;
     407             :       case PKT_ENCRYPTED:
     408             :       case PKT_ENCRYPTED_MDC:
     409         470 :         free_encrypted( pkt->pkt.encrypted );
     410         470 :         break;
     411             :       case PKT_PLAINTEXT:
     412        1001 :         free_plaintext( pkt->pkt.plaintext );
     413        1001 :         break;
     414             :       default:
     415         793 :         xfree( pkt->pkt.generic );
     416         793 :         break;
     417             :     }
     418       17567 :     pkt->pkt.generic = NULL;
     419             : }
     420             : 
     421             : /****************
     422             :  * returns 0 if they match.
     423             :  */
     424             : int
     425          87 : cmp_public_keys( PKT_public_key *a, PKT_public_key *b )
     426             : {
     427             :     int n, i;
     428             : 
     429          87 :     if( a->timestamp != b->timestamp )
     430           0 :         return -1;
     431          87 :     if( a->version < 4 && a->expiredate != b->expiredate )
     432           0 :         return -1;
     433          87 :     if( a->pubkey_algo != b->pubkey_algo )
     434           0 :         return -1;
     435             : 
     436          87 :     n = pubkey_get_npkey( b->pubkey_algo );
     437          87 :     if( !n ) { /* unknown algorithm, rest is in opaque MPI */
     438           0 :         if( mpi_cmp( a->pkey[0], b->pkey[0] ) )
     439           0 :             return -1; /* can't compare due to unknown algorithm */
     440             :     } else {
     441         371 :         for(i=0; i < n; i++ ) {
     442         284 :             if( mpi_cmp( a->pkey[i], b->pkey[i] ) )
     443           0 :                 return -1;
     444             :         }
     445             :     }
     446             : 
     447          87 :     return 0;
     448             : }
     449             : 
     450             : 
     451             : 
     452             : int
     453        2641 : cmp_signatures( PKT_signature *a, PKT_signature *b )
     454             : {
     455             :     int n, i;
     456             : 
     457        2641 :     if( a->keyid[0] != b->keyid[0] )
     458        2335 :         return -1;
     459         306 :     if( a->keyid[1] != b->keyid[1] )
     460           0 :         return -1;
     461         306 :     if( a->pubkey_algo != b->pubkey_algo )
     462           0 :         return -1;
     463             : 
     464         306 :     n = pubkey_get_nsig( a->pubkey_algo );
     465         306 :     if( !n )
     466           0 :         return -1; /* can't compare due to unknown algorithm */
     467         481 :     for(i=0; i < n; i++ ) {
     468         391 :         if( mpi_cmp( a->data[i] , b->data[i] ) )
     469         216 :             return -1;
     470             :     }
     471          90 :     return 0;
     472             : }
     473             : 
     474             : 
     475             : /****************
     476             :  * Returns: true if the user ids do not match
     477             :  */
     478             : int
     479         143 : cmp_user_ids( PKT_user_id *a, PKT_user_id *b )
     480             : {
     481         143 :     int res=1;
     482             : 
     483         143 :     if( a == b )
     484           0 :         return 0;
     485             : 
     486         143 :     if( a->attrib_data && b->attrib_data )
     487             :       {
     488           0 :         res = a->attrib_len - b->attrib_len;
     489           0 :         if( !res )
     490           0 :           res = memcmp( a->attrib_data, b->attrib_data, a->attrib_len );
     491             :       }
     492         143 :     else if( !a->attrib_data && !b->attrib_data )
     493             :       {
     494         143 :         res = a->len - b->len;
     495         143 :         if( !res )
     496          82 :           res = memcmp( a->name, b->name, a->len );
     497             :       }
     498             : 
     499         143 :     return res;
     500             : }

Generated by: LCOV version 1.11