LCOV - code coverage report
Current view: top level - g10 - free-packet.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 176 250 70.4 %
Date: 2016-09-12 12:29:17 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             : 
      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        7320 : my_mpi_copy (gcry_mpi_t a)
      37             : {
      38        7320 :   if (a
      39        7320 :       && gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)
      40         363 :       && !gcry_mpi_get_opaque (a, NULL))
      41           0 :     return NULL;
      42             : 
      43        7320 :   return gcry_mpi_copy (a);
      44             : }
      45             : 
      46             : 
      47             : void
      48         224 : free_symkey_enc( PKT_symkey_enc *enc )
      49             : {
      50         224 :     xfree(enc);
      51         224 : }
      52             : 
      53             : void
      54         523 : free_pubkey_enc( PKT_pubkey_enc *enc )
      55             : {
      56             :     int n, i;
      57         523 :     n = pubkey_get_nenc( enc->pubkey_algo );
      58         523 :     if( !n )
      59           0 :         mpi_release(enc->data[0]);
      60        1552 :     for(i=0; i < n; i++ )
      61        1029 :         mpi_release( enc->data[i] );
      62         523 :     xfree(enc);
      63         523 : }
      64             : 
      65             : void
      66        7268 : free_seckey_enc( PKT_signature *sig )
      67             : {
      68             :   int n, i;
      69             : 
      70        7268 :   n = pubkey_get_nsig( sig->pubkey_algo );
      71        7268 :   if( !n )
      72           0 :     mpi_release(sig->data[0]);
      73       20801 :   for(i=0; i < n; i++ )
      74       13533 :     mpi_release( sig->data[i] );
      75             : 
      76        7268 :   xfree(sig->revkey);
      77        7268 :   xfree(sig->hashed);
      78        7268 :   xfree(sig->unhashed);
      79             : 
      80        7268 :   if (sig->pka_info)
      81             :     {
      82           0 :       xfree (sig->pka_info->uri);
      83           0 :       xfree (sig->pka_info);
      84             :     }
      85        7268 :   xfree (sig->signers_uid);
      86             : 
      87        7268 :   xfree(sig);
      88        7268 : }
      89             : 
      90             : 
      91             : void
      92        7142 : release_public_key_parts (PKT_public_key *pk)
      93             : {
      94             :   int n, i;
      95             : 
      96        7142 :   if (pk->seckey_info)
      97          36 :     n = pubkey_get_nskey (pk->pubkey_algo);
      98             :   else
      99        7106 :     n = pubkey_get_npkey (pk->pubkey_algo);
     100        7142 :   if (!n)
     101          71 :     mpi_release (pk->pkey[0]);
     102       30004 :   for (i=0; i < n; i++ )
     103             :     {
     104       22862 :       mpi_release (pk->pkey[i]);
     105       22862 :       pk->pkey[i] = NULL;
     106             :     }
     107        7142 :   if (pk->seckey_info)
     108             :     {
     109          36 :       xfree (pk->seckey_info);
     110          36 :       pk->seckey_info = NULL;
     111             :     }
     112        7142 :   if (pk->prefs)
     113             :     {
     114        5778 :       xfree (pk->prefs);
     115        5778 :       pk->prefs = NULL;
     116             :     }
     117        7142 :   if (pk->user_id)
     118             :     {
     119         275 :       free_user_id (pk->user_id);
     120         275 :       pk->user_id = NULL;
     121             :     }
     122        7142 :   if (pk->revkey)
     123             :     {
     124           2 :       xfree(pk->revkey);
     125           2 :       pk->revkey=NULL;
     126           2 :       pk->numrevkeys=0;
     127             :     }
     128        7142 :   if (pk->serialno)
     129             :     {
     130           0 :       xfree (pk->serialno);
     131           0 :       pk->serialno = NULL;
     132             :     }
     133        7142 : }
     134             : 
     135             : 
     136             : /* Free an allocated public key structure including all parts.
     137             :    Passing NULL is allowed.  */
     138             : void
     139        7140 : free_public_key (PKT_public_key *pk)
     140             : {
     141        7140 :   if (pk)
     142             :     {
     143        7140 :       release_public_key_parts (pk);
     144        7140 :       xfree(pk);
     145             :     }
     146        7140 : }
     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        6730 : copy_prefs (const prefitem_t *prefs)
     168             : {
     169             :     size_t n;
     170             :     prefitem_t *new;
     171             : 
     172        6730 :     if (!prefs)
     173          83 :         return NULL;
     174             : 
     175        6647 :     for (n=0; prefs[n].type; n++)
     176             :         ;
     177        6647 :     new = xmalloc ( sizeof (*new) * (n+1));
     178       57750 :     for (n=0; prefs[n].type; n++) {
     179       51103 :         new[n].type = prefs[n].type;
     180       51103 :         new[n].value = prefs[n].value;
     181             :     }
     182        6647 :     new[n].type = PREFTYPE_NONE;
     183        6647 :     new[n].value = 0;
     184             : 
     185        6647 :     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        2229 : copy_public_key (PKT_public_key *d, PKT_public_key *s)
     194             : {
     195             :   int n, i;
     196             : 
     197        2229 :   if (!d)
     198         705 :     d = xmalloc (sizeof *d);
     199        2229 :   memcpy (d, s, sizeof *d);
     200        2229 :   d->seckey_info = NULL;
     201        2229 :   d->user_id = scopy_user_id (s->user_id);
     202        2229 :   d->prefs = copy_prefs (s->prefs);
     203             : 
     204        2229 :   n = pubkey_get_npkey (s->pubkey_algo);
     205        2229 :   i = 0;
     206        2229 :   if (!n)
     207           0 :     d->pkey[i++] = my_mpi_copy (s->pkey[0]);
     208             :   else
     209             :     {
     210        9549 :       for (; i < n; i++ )
     211        7320 :         d->pkey[i] = my_mpi_copy (s->pkey[i]);
     212             :     }
     213       10512 :   for (; i < PUBKEY_MAX_NSKEY; i++)
     214        8283 :     d->pkey[i] = NULL;
     215             : 
     216        2229 :   if (!s->revkey && s->numrevkeys)
     217           0 :     BUG();
     218        2229 :   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        2229 :     d->revkey = NULL;
     225        2229 :   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->signers_uid)
     263           0 :       d->signers_uid = xstrdup (s->signers_uid);
     264           0 :     if(s->numrevkeys)
     265             :       {
     266           0 :         d->revkey=NULL;
     267           0 :         d->numrevkeys=0;
     268           0 :         parse_revkeys(d);
     269             :       }
     270           0 :     return d;
     271             : }
     272             : 
     273             : 
     274             : /*
     275             :  * shallow copy of the user ID
     276             :  */
     277             : PKT_user_id *
     278        4367 : scopy_user_id (PKT_user_id *s)
     279             : {
     280        4367 :     if (s)
     281         275 :         s->ref++;
     282        4367 :     return s;
     283             : }
     284             : 
     285             : 
     286             : 
     287             : void
     288           0 : free_comment( PKT_comment *rem )
     289             : {
     290           0 :     xfree(rem);
     291           0 : }
     292             : 
     293             : void
     294        3511 : free_attributes(PKT_user_id *uid)
     295             : {
     296        3511 :   xfree(uid->attribs);
     297        3511 :   xfree(uid->attrib_data);
     298             : 
     299        3511 :   uid->attribs=NULL;
     300        3511 :   uid->attrib_data=NULL;
     301        3511 :   uid->attrib_len=0;
     302        3511 : }
     303             : 
     304             : void
     305        3786 : free_user_id (PKT_user_id *uid)
     306             : {
     307        3786 :     log_assert (uid->ref > 0);
     308        3786 :     if (--uid->ref)
     309        4061 :         return;
     310             : 
     311        3511 :     free_attributes(uid);
     312        3511 :     xfree (uid->prefs);
     313        3511 :     xfree (uid->namehash);
     314        3511 :     xfree (uid->mbox);
     315        3511 :     xfree (uid);
     316             : }
     317             : 
     318             : void
     319         563 : free_compressed( PKT_compressed *zd )
     320             : {
     321         563 :     if( zd->buf ) { /* have to skip some bytes */
     322             :         /* don't have any information about the length, so
     323             :          * we assume this is the last packet */
     324           0 :         while( iobuf_read( zd->buf, NULL, 1<<30 ) != -1 )
     325             :             ;
     326             :     }
     327         563 :     xfree(zd);
     328         563 : }
     329             : 
     330             : void
     331         481 : free_encrypted( PKT_encrypted *ed )
     332             : {
     333         481 :     if( ed->buf ) { /* have to skip some bytes */
     334           0 :         if( ed->is_partial ) {
     335           0 :             while( iobuf_read( ed->buf, NULL, 1<<30 ) != -1 )
     336             :                 ;
     337             :         }
     338             :         else {
     339           0 :            while( ed->len ) { /* skip the packet */
     340           0 :                int n = iobuf_read( ed->buf, NULL, ed->len );
     341           0 :                if( n == -1 )
     342           0 :                    ed->len = 0;
     343             :                else
     344           0 :                    ed->len -= n;
     345             :            }
     346             :         }
     347             :     }
     348         481 :     xfree(ed);
     349         481 : }
     350             : 
     351             : 
     352             : void
     353        1139 : free_plaintext( PKT_plaintext *pt )
     354             : {
     355        1139 :     if( pt->buf ) { /* have to skip some bytes */
     356         560 :         if( pt->is_partial ) {
     357           0 :             while( iobuf_read( pt->buf, NULL, 1<<30 ) != -1 )
     358             :                 ;
     359             :         }
     360             :         else {
     361        1127 :            while( pt->len ) { /* skip the packet */
     362           7 :                int n = iobuf_read( pt->buf, NULL, pt->len );
     363           7 :                if( n == -1 )
     364           0 :                    pt->len = 0;
     365             :                else
     366           7 :                    pt->len -= n;
     367             :            }
     368             :         }
     369             :     }
     370        1139 :     xfree(pt);
     371        1139 : }
     372             : 
     373             : /****************
     374             :  * Free the packet in pkt.
     375             :  */
     376             : void
     377       24665 : free_packet( PACKET *pkt )
     378             : {
     379       24665 :     if( !pkt || !pkt->pkt.generic )
     380       29039 :         return;
     381             : 
     382       20291 :     if( DBG_MEMORY )
     383           0 :         log_debug("free_packet() type=%d\n", pkt->pkttype );
     384             : 
     385       20291 :     switch( pkt->pkttype ) {
     386             :       case PKT_SIGNATURE:
     387        7140 :         free_seckey_enc( pkt->pkt.signature );
     388        7140 :         break;
     389             :       case PKT_PUBKEY_ENC:
     390         268 :         free_pubkey_enc( pkt->pkt.pubkey_enc );
     391         268 :         break;
     392             :       case PKT_SYMKEY_ENC:
     393         224 :         free_symkey_enc( pkt->pkt.symkey_enc );
     394         224 :         break;
     395             :       case PKT_PUBLIC_KEY:
     396             :       case PKT_PUBLIC_SUBKEY:
     397             :       case PKT_SECRET_KEY:
     398             :       case PKT_SECRET_SUBKEY:
     399        5709 :         free_public_key (pkt->pkt.public_key);
     400        5709 :         break;
     401             :       case PKT_COMMENT:
     402           0 :         free_comment( pkt->pkt.comment );
     403           0 :         break;
     404             :       case PKT_USER_ID:
     405        3511 :         free_user_id( pkt->pkt.user_id );
     406        3511 :         break;
     407             :       case PKT_COMPRESSED:
     408         563 :         free_compressed( pkt->pkt.compressed);
     409         563 :         break;
     410             :       case PKT_ENCRYPTED:
     411             :       case PKT_ENCRYPTED_MDC:
     412         481 :         free_encrypted( pkt->pkt.encrypted );
     413         481 :         break;
     414             :       case PKT_PLAINTEXT:
     415        1139 :         free_plaintext( pkt->pkt.plaintext );
     416        1139 :         break;
     417             :       default:
     418        1256 :         xfree( pkt->pkt.generic );
     419        1256 :         break;
     420             :     }
     421       20291 :     pkt->pkt.generic = NULL;
     422             : }
     423             : 
     424             : /****************
     425             :  * returns 0 if they match.
     426             :  */
     427             : int
     428         116 : cmp_public_keys( PKT_public_key *a, PKT_public_key *b )
     429             : {
     430             :     int n, i;
     431             : 
     432         116 :     if( a->timestamp != b->timestamp )
     433           8 :         return -1;
     434         108 :     if( a->version < 4 && a->expiredate != b->expiredate )
     435           0 :         return -1;
     436         108 :     if( a->pubkey_algo != b->pubkey_algo )
     437           0 :         return -1;
     438             : 
     439         108 :     n = pubkey_get_npkey( b->pubkey_algo );
     440         108 :     if( !n ) { /* unknown algorithm, rest is in opaque MPI */
     441           0 :         if( mpi_cmp( a->pkey[0], b->pkey[0] ) )
     442           0 :             return -1; /* can't compare due to unknown algorithm */
     443             :     } else {
     444         458 :         for(i=0; i < n; i++ ) {
     445         350 :             if( mpi_cmp( a->pkey[i], b->pkey[i] ) )
     446           0 :                 return -1;
     447             :         }
     448             :     }
     449             : 
     450         108 :     return 0;
     451             : }
     452             : 
     453             : 
     454             : 
     455             : int
     456        2656 : cmp_signatures( PKT_signature *a, PKT_signature *b )
     457             : {
     458             :     int n, i;
     459             : 
     460        2656 :     if( a->keyid[0] != b->keyid[0] )
     461        2335 :         return -1;
     462         321 :     if( a->keyid[1] != b->keyid[1] )
     463           0 :         return -1;
     464         321 :     if( a->pubkey_algo != b->pubkey_algo )
     465           0 :         return -1;
     466             : 
     467         321 :     n = pubkey_get_nsig( a->pubkey_algo );
     468         321 :     if( !n )
     469           0 :         return -1; /* can't compare due to unknown algorithm */
     470         517 :     for(i=0; i < n; i++ ) {
     471         415 :         if( mpi_cmp( a->data[i] , b->data[i] ) )
     472         219 :             return -1;
     473             :     }
     474         102 :     return 0;
     475             : }
     476             : 
     477             : 
     478             : /****************
     479             :  * Returns: true if the user ids do not match
     480             :  */
     481             : int
     482         166 : cmp_user_ids( PKT_user_id *a, PKT_user_id *b )
     483             : {
     484         166 :     int res=1;
     485             : 
     486         166 :     if( a == b )
     487           0 :         return 0;
     488             : 
     489         166 :     if( a->attrib_data && b->attrib_data )
     490             :       {
     491           0 :         res = a->attrib_len - b->attrib_len;
     492           0 :         if( !res )
     493           0 :           res = memcmp( a->attrib_data, b->attrib_data, a->attrib_len );
     494             :       }
     495         166 :     else if( !a->attrib_data && !b->attrib_data )
     496             :       {
     497         166 :         res = a->len - b->len;
     498         166 :         if( !res )
     499         100 :           res = memcmp( a->name, b->name, a->len );
     500             :       }
     501             : 
     502         166 :     return res;
     503             : }

Generated by: LCOV version 1.11