LCOV - code coverage report
Current view: top level - g10 - build-packet.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 341 647 52.7 %
Date: 2015-11-05 17:10:59 Functions: 25 30 83.3 %

          Line data    Source code
       1             : /* build-packet.c - assemble packets and write them
       2             :  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
       3             :  *               2006, 2010, 2011  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             : #include <ctype.h>
      27             : 
      28             : #include "gpg.h"
      29             : #include "util.h"
      30             : #include "packet.h"
      31             : #include "status.h"
      32             : #include "iobuf.h"
      33             : #include "i18n.h"
      34             : #include "options.h"
      35             : #include "host2net.h"
      36             : 
      37             : static int do_user_id( IOBUF out, int ctb, PKT_user_id *uid );
      38             : static int do_key (iobuf_t out, int ctb, PKT_public_key *pk);
      39             : static int do_symkey_enc( IOBUF out, int ctb, PKT_symkey_enc *enc );
      40             : static int do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc );
      41             : static u32 calc_plaintext( PKT_plaintext *pt );
      42             : static int do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt );
      43             : static int do_encrypted( IOBUF out, int ctb, PKT_encrypted *ed );
      44             : static int do_encrypted_mdc( IOBUF out, int ctb, PKT_encrypted *ed );
      45             : static int do_compressed( IOBUF out, int ctb, PKT_compressed *cd );
      46             : static int do_signature( IOBUF out, int ctb, PKT_signature *sig );
      47             : static int do_onepass_sig( IOBUF out, int ctb, PKT_onepass_sig *ops );
      48             : 
      49             : static int calc_header_length( u32 len, int new_ctb );
      50             : static int write_16(IOBUF inp, u16 a);
      51             : static int write_32(IOBUF inp, u32 a);
      52             : static int write_header( IOBUF out, int ctb, u32 len );
      53             : static int write_sign_packet_header( IOBUF out, int ctb, u32 len );
      54             : static int write_header2( IOBUF out, int ctb, u32 len, int hdrlen );
      55             : static int write_new_header( IOBUF out, int ctb, u32 len, int hdrlen );
      56             : 
      57             : /****************
      58             :  * Build a packet and write it to INP
      59             :  * Returns: 0 := okay
      60             :  *         >0 := error
      61             :  * Note: Caller must free the packet
      62             :  */
      63             : int
      64        2583 : build_packet( IOBUF out, PACKET *pkt )
      65             : {
      66        2583 :     int new_ctb=0, rc=0, ctb;
      67             :     int pkttype;
      68             : 
      69        2583 :     if( DBG_PACKET )
      70           0 :         log_debug("build_packet() type=%d\n", pkt->pkttype );
      71        2583 :     assert( pkt->pkt.generic );
      72             : 
      73        2583 :     switch ((pkttype = pkt->pkttype))
      74             :       {
      75             :       case PKT_PUBLIC_KEY:
      76          61 :         if (pkt->pkt.public_key->seckey_info)
      77           0 :           pkttype = PKT_SECRET_KEY;
      78          61 :         break;
      79             :       case PKT_PUBLIC_SUBKEY:
      80          47 :         if (pkt->pkt.public_key->seckey_info)
      81           0 :           pkttype = PKT_SECRET_SUBKEY;
      82          47 :         break;
      83         510 :       case PKT_PLAINTEXT: new_ctb = pkt->pkt.plaintext->new_ctb; break;
      84             :       case PKT_ENCRYPTED:
      85         454 :       case PKT_ENCRYPTED_MDC: new_ctb = pkt->pkt.encrypted->new_ctb; break;
      86         510 :       case PKT_COMPRESSED:new_ctb = pkt->pkt.compressed->new_ctb; break;
      87             :       case PKT_USER_ID:
      88          75 :         if( pkt->pkt.user_id->attrib_data )
      89           0 :           pkttype = PKT_ATTRIBUTE;
      90          75 :         break;
      91         926 :       default: break;
      92             :       }
      93             : 
      94        2583 :     if( new_ctb || pkttype > 15 ) /* new format */
      95         482 :         ctb = 0xc0 | (pkttype & 0x3f);
      96             :     else
      97        2101 :         ctb = 0x80 | ((pkttype & 15)<<2);
      98        2583 :     switch( pkttype )
      99             :       {
     100             :       case PKT_ATTRIBUTE:
     101             :       case PKT_USER_ID:
     102          75 :         rc = do_user_id( out, ctb, pkt->pkt.user_id );
     103          75 :         break;
     104             :       case PKT_OLD_COMMENT:
     105             :       case PKT_COMMENT:
     106             :         /*
     107             :           Ignore these.  Theoretically, this will never be called as
     108             :           we have no way to output comment packets any longer, but
     109             :           just in case there is some code path that would end up
     110             :           outputting a comment that was written before comments were
     111             :           dropped (in the public key?) this is a no-op.
     112             :         */
     113           0 :         break;
     114             :       case PKT_PUBLIC_SUBKEY:
     115             :       case PKT_PUBLIC_KEY:
     116             :       case PKT_SECRET_SUBKEY:
     117             :       case PKT_SECRET_KEY:
     118         108 :         rc = do_key (out, ctb, pkt->pkt.public_key);
     119         108 :         break;
     120             :       case PKT_SYMKEY_ENC:
     121         218 :         rc = do_symkey_enc( out, ctb, pkt->pkt.symkey_enc );
     122         218 :         break;
     123             :       case PKT_PUBKEY_ENC:
     124         236 :         rc = do_pubkey_enc( out, ctb, pkt->pkt.pubkey_enc );
     125         236 :         break;
     126             :       case PKT_PLAINTEXT:
     127         510 :         rc = do_plaintext( out, ctb, pkt->pkt.plaintext );
     128         510 :         break;
     129             :       case PKT_ENCRYPTED:
     130          52 :         rc = do_encrypted( out, ctb, pkt->pkt.encrypted );
     131          52 :         break;
     132             :       case PKT_ENCRYPTED_MDC:
     133         402 :         rc = do_encrypted_mdc( out, ctb, pkt->pkt.encrypted );
     134         402 :         break;
     135             :       case PKT_COMPRESSED:
     136         510 :         rc = do_compressed( out, ctb, pkt->pkt.compressed );
     137         510 :         break;
     138             :       case PKT_SIGNATURE:
     139         383 :         rc = do_signature( out, ctb, pkt->pkt.signature );
     140         383 :         break;
     141             :       case PKT_ONEPASS_SIG:
     142          89 :         rc = do_onepass_sig( out, ctb, pkt->pkt.onepass_sig );
     143          89 :         break;
     144             :       case PKT_RING_TRUST:
     145           0 :         break; /* ignore it (keyring.c does write it directly)*/
     146             :       case PKT_MDC: /* we write it directly, so we should never see it here. */
     147             :       default:
     148           0 :         log_bug("invalid packet type in build_packet()\n");
     149             :         break;
     150             :       }
     151             : 
     152        2583 :     return rc;
     153             : }
     154             : 
     155             : 
     156             : /*
     157             :  * Write the mpi A to OUT.
     158             :  */
     159             : gpg_error_t
     160        1463 : gpg_mpi_write (iobuf_t out, gcry_mpi_t a)
     161             : {
     162             :   int rc;
     163             : 
     164        1463 :   if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
     165             :     {
     166             :       unsigned int nbits;
     167             :       const unsigned char *p;
     168             :       unsigned char lenhdr[2];
     169             : 
     170             :       /* gcry_log_debugmpi ("a", a); */
     171           0 :       p = gcry_mpi_get_opaque (a, &nbits);
     172           0 :       if (p)
     173             :         {
     174             :           /* Strip leading zero bits.  */
     175           0 :           for (; nbits >= 8 && !*p; p++, nbits -= 8)
     176             :             ;
     177           0 :           if (nbits >= 8 && !(*p & 0x80))
     178           0 :             if (--nbits >= 7 && !(*p & 0x40))
     179           0 :               if (--nbits >= 6 && !(*p & 0x20))
     180           0 :                 if (--nbits >= 5 && !(*p & 0x10))
     181           0 :                   if (--nbits >= 4 && !(*p & 0x08))
     182           0 :                     if (--nbits >= 3 && !(*p & 0x04))
     183           0 :                       if (--nbits >= 2 && !(*p & 0x02))
     184           0 :                         if (--nbits >= 1 && !(*p & 0x01))
     185           0 :                           --nbits;
     186             :         }
     187             :       /* gcry_log_debug ("   [%u bit]\n", nbits); */
     188             :       /* gcry_log_debughex (" ", p, (nbits+7)/8); */
     189           0 :       lenhdr[0] = nbits >> 8;
     190           0 :       lenhdr[1] = nbits;
     191           0 :       rc = iobuf_write (out, lenhdr, 2);
     192           0 :       if (!rc && p)
     193           0 :         rc = iobuf_write (out, p, (nbits+7)/8);
     194             :     }
     195             :   else
     196             :     {
     197             :       char buffer[(MAX_EXTERN_MPI_BITS+7)/8+2]; /* 2 is for the mpi length. */
     198             :       size_t nbytes;
     199             : 
     200        1463 :       nbytes = DIM(buffer);
     201        1463 :       rc = gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, &nbytes, a );
     202        1463 :       if( !rc )
     203        1463 :         rc = iobuf_write( out, buffer, nbytes );
     204           0 :       else if (gpg_err_code(rc) == GPG_ERR_TOO_SHORT )
     205             :         {
     206           0 :           log_info ("mpi too large (%u bits)\n", gcry_mpi_get_nbits (a));
     207             :           /* The buffer was too small. We better tell the user about the MPI. */
     208           0 :           rc = gpg_error (GPG_ERR_TOO_LARGE);
     209             :         }
     210             :     }
     211             : 
     212        1463 :   return rc;
     213             : }
     214             : 
     215             : 
     216             : /*
     217             :  * Write an opaque MPI to the output stream without length info.
     218             :  */
     219             : gpg_error_t
     220         125 : gpg_mpi_write_nohdr (iobuf_t out, gcry_mpi_t a)
     221             : {
     222             :   int rc;
     223             : 
     224         125 :   if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
     225             :     {
     226             :       unsigned int nbits;
     227             :       const void *p;
     228             : 
     229         125 :       p = gcry_mpi_get_opaque (a, &nbits);
     230         125 :       rc = p ? iobuf_write (out, p, (nbits+7)/8) : 0;
     231             :     }
     232             :   else
     233           0 :     rc = gpg_error (GPG_ERR_BAD_MPI);
     234             : 
     235         125 :   return rc;
     236             : }
     237             : 
     238             : 
     239             : /* Calculate the length of a packet described by PKT.  */
     240             : u32
     241           0 : calc_packet_length( PACKET *pkt )
     242             : {
     243           0 :     u32 n=0;
     244           0 :     int new_ctb = 0;
     245             : 
     246           0 :     assert( pkt->pkt.generic );
     247           0 :     switch( pkt->pkttype ) {
     248             :       case PKT_PLAINTEXT:
     249           0 :         n = calc_plaintext( pkt->pkt.plaintext );
     250           0 :         new_ctb = pkt->pkt.plaintext->new_ctb;
     251           0 :         break;
     252             :       case PKT_ATTRIBUTE:
     253             :       case PKT_USER_ID:
     254             :       case PKT_COMMENT:
     255             :       case PKT_PUBLIC_KEY:
     256             :       case PKT_SECRET_KEY:
     257             :       case PKT_SYMKEY_ENC:
     258             :       case PKT_PUBKEY_ENC:
     259             :       case PKT_ENCRYPTED:
     260             :       case PKT_SIGNATURE:
     261             :       case PKT_ONEPASS_SIG:
     262             :       case PKT_RING_TRUST:
     263             :       case PKT_COMPRESSED:
     264             :       default:
     265           0 :         log_bug("invalid packet type in calc_packet_length()");
     266             :         break;
     267             :     }
     268             : 
     269           0 :     n += calc_header_length(n, new_ctb);
     270           0 :     return n;
     271             : }
     272             : 
     273             : 
     274             : static gpg_error_t
     275           0 : write_fake_data (IOBUF out, gcry_mpi_t a)
     276             : {
     277             :   unsigned int n;
     278             :   void *p;
     279             : 
     280           0 :   if (!a)
     281           0 :     return 0;
     282           0 :   p = gcry_mpi_get_opaque ( a, &n);
     283           0 :   if (!p)
     284           0 :     return 0; /* For example due to a read error in
     285             :                  parse-packet.c:read_rest.  */
     286           0 :   return iobuf_write (out, p, (n+7)/8 );
     287             : }
     288             : 
     289             : 
     290             : static int
     291          75 : do_user_id( IOBUF out, int ctb, PKT_user_id *uid )
     292             : {
     293             :   int rc;
     294             : 
     295          75 :   if (uid->attrib_data)
     296             :     {
     297           0 :       write_header(out, ctb, uid->attrib_len);
     298           0 :       rc = iobuf_write( out, uid->attrib_data, uid->attrib_len );
     299             :     }
     300             :   else
     301             :     {
     302          75 :       write_header2( out, ctb, uid->len, 2 );
     303          75 :       rc = iobuf_write( out, uid->name, uid->len );
     304             :     }
     305          75 :   return rc;
     306             : }
     307             : 
     308             : 
     309             : static int
     310         108 : do_key (iobuf_t out, int ctb, PKT_public_key *pk)
     311             : {
     312         108 :   gpg_error_t err = 0;
     313             :   int i, nskey, npkey;
     314         108 :   iobuf_t a = iobuf_temp(); /* Build in a self-enlarging buffer.  */
     315             : 
     316             :   /* Write the version number - if none is specified, use 4 */
     317         108 :   if ( !pk->version )
     318           0 :     iobuf_put ( a, 4 );
     319             :   else
     320         108 :     iobuf_put ( a, pk->version );
     321         108 :   write_32 (a, pk->timestamp );
     322             : 
     323         108 :   iobuf_put (a, pk->pubkey_algo );
     324             : 
     325             :   /* Get number of secret and public parameters.  They are held in one
     326             :      array first the public ones, then the secret ones.  */
     327         108 :   nskey = pubkey_get_nskey (pk->pubkey_algo);
     328         108 :   npkey = pubkey_get_npkey (pk->pubkey_algo);
     329             : 
     330             :   /* If we don't have any public parameters - which is for example the
     331             :      case if we don't know the algorithm used - the parameters are
     332             :      stored as one blob in a faked (opaque) MPI. */
     333         108 :   if (!npkey)
     334             :     {
     335           0 :       write_fake_data (a, pk->pkey[0]);
     336           0 :       goto leave;
     337             :     }
     338         108 :   assert (npkey < nskey);
     339             : 
     340         448 :   for (i=0; i < npkey; i++ )
     341             :     {
     342         340 :       if (   (pk->pubkey_algo == PUBKEY_ALGO_ECDSA && (i == 0))
     343         334 :           || (pk->pubkey_algo == PUBKEY_ALGO_EDDSA && (i == 0))
     344         334 :           || (pk->pubkey_algo == PUBKEY_ALGO_ECDH  && (i == 0 || i == 2)))
     345          14 :         err = gpg_mpi_write_nohdr (a, pk->pkey[i]);
     346             :       else
     347         326 :         err = gpg_mpi_write (a, pk->pkey[i]);
     348         340 :       if (err)
     349           0 :         goto leave;
     350             :     }
     351             : 
     352             : 
     353         108 :   if (pk->seckey_info)
     354             :     {
     355             :       /* This is a secret key packet.  */
     356           0 :       struct seckey_info *ski = pk->seckey_info;
     357             : 
     358             :       /* Build the header for protected (encrypted) secret parameters.  */
     359           0 :       if (ski->is_protected)
     360             :         {
     361             :           /* OpenPGP protection according to rfc2440. */
     362           0 :           iobuf_put (a, ski->sha1chk? 0xfe : 0xff);
     363           0 :           iobuf_put (a, ski->algo);
     364           0 :           if (ski->s2k.mode >= 1000)
     365             :             {
     366             :               /* These modes are not possible in OpenPGP, we use them
     367             :                  to implement our extensions, 101 can be viewed as a
     368             :                  private/experimental extension (this is not specified
     369             :                  in rfc2440 but the same scheme is used for all other
     370             :                  algorithm identifiers). */
     371           0 :               iobuf_put (a, 101);
     372           0 :               iobuf_put (a, ski->s2k.hash_algo);
     373           0 :               iobuf_write (a, "GNU", 3 );
     374           0 :               iobuf_put (a, ski->s2k.mode - 1000);
     375             :             }
     376             :           else
     377             :             {
     378           0 :               iobuf_put (a, ski->s2k.mode);
     379           0 :               iobuf_put (a, ski->s2k.hash_algo);
     380             :             }
     381             : 
     382           0 :           if (ski->s2k.mode == 1 || ski->s2k.mode == 3)
     383           0 :             iobuf_write (a, ski->s2k.salt, 8);
     384             : 
     385           0 :           if (ski->s2k.mode == 3)
     386           0 :             iobuf_put (a, ski->s2k.count);
     387             : 
     388             :           /* For our special modes 1001, 1002 we do not need an IV. */
     389           0 :           if (ski->s2k.mode != 1001 && ski->s2k.mode != 1002)
     390           0 :             iobuf_write (a, ski->iv, ski->ivlen);
     391             : 
     392             :         }
     393             :       else /* Not protected. */
     394           0 :         iobuf_put (a, 0 );
     395             : 
     396           0 :       if (ski->s2k.mode == 1001)
     397             :         ; /* GnuPG extension - don't write a secret key at all. */
     398           0 :       else if (ski->s2k.mode == 1002)
     399             :         {
     400             :           /* GnuPG extension - divert to OpenPGP smartcard. */
     401             :           /* Length of the serial number or 0 for no serial number. */
     402           0 :           iobuf_put (a, ski->ivlen );
     403             :           /* The serial number gets stored in the IV field.  */
     404           0 :           iobuf_write (a, ski->iv, ski->ivlen);
     405             :         }
     406           0 :       else if (ski->is_protected)
     407             :         {
     408             :           /* The secret key is protected - write it out as it is.  */
     409             :           byte *p;
     410             :           unsigned int ndatabits;
     411             : 
     412           0 :           assert (gcry_mpi_get_flag (pk->pkey[npkey], GCRYMPI_FLAG_OPAQUE));
     413           0 :           p = gcry_mpi_get_opaque (pk->pkey[npkey], &ndatabits);
     414           0 :           if (p)
     415           0 :             iobuf_write (a, p, (ndatabits+7)/8 );
     416             :         }
     417             :       else
     418             :         {
     419             :           /* Non-protected key. */
     420           0 :           for ( ; i < nskey; i++ )
     421           0 :             if ( (err = gpg_mpi_write (a, pk->pkey[i])))
     422           0 :               goto leave;
     423           0 :           write_16 (a, ski->csum );
     424             :         }
     425             :     }
     426             : 
     427             :  leave:
     428         108 :   if (!err)
     429             :     {
     430             :       /* Build the header of the packet - which we must do after
     431             :          writing all the other stuff, so that we know the length of
     432             :          the packet */
     433         108 :       write_header2 (out, ctb, iobuf_get_temp_length(a), pk->hdrbytes);
     434             :       /* And finally write it out to the real stream. */
     435         108 :       err = iobuf_write_temp (out, a);
     436             :     }
     437             : 
     438         108 :   iobuf_close (a); /* Close the temporary buffer */
     439         108 :   return err;
     440             : }
     441             : 
     442             : static int
     443         218 : do_symkey_enc( IOBUF out, int ctb, PKT_symkey_enc *enc )
     444             : {
     445         218 :     int rc = 0;
     446         218 :     IOBUF a = iobuf_temp();
     447             : 
     448         218 :     assert( enc->version == 4 );
     449         218 :     switch( enc->s2k.mode ) {
     450         218 :       case 0: case 1: case 3: break;
     451           0 :       default: log_bug("do_symkey_enc: s2k=%d\n", enc->s2k.mode );
     452             :     }
     453         218 :     iobuf_put( a, enc->version );
     454         218 :     iobuf_put( a, enc->cipher_algo );
     455         218 :     iobuf_put( a, enc->s2k.mode );
     456         218 :     iobuf_put( a, enc->s2k.hash_algo );
     457         218 :     if( enc->s2k.mode == 1 || enc->s2k.mode == 3 ) {
     458         218 :         iobuf_write(a, enc->s2k.salt, 8 );
     459         218 :         if( enc->s2k.mode == 3 )
     460         218 :             iobuf_put(a, enc->s2k.count);
     461             :     }
     462         218 :     if( enc->seskeylen )
     463           0 :         iobuf_write(a, enc->seskey, enc->seskeylen );
     464             : 
     465         218 :     write_header(out, ctb, iobuf_get_temp_length(a) );
     466         218 :     rc = iobuf_write_temp( out, a );
     467             : 
     468         218 :     iobuf_close(a);
     469         218 :     return rc;
     470             : }
     471             : 
     472             : 
     473             : static int
     474         236 : do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc )
     475             : {
     476         236 :   int rc = 0;
     477             :   int n, i;
     478         236 :   IOBUF a = iobuf_temp();
     479             : 
     480         236 :   iobuf_put (a, 3); /* Version.  */
     481             : 
     482         236 :   if ( enc->throw_keyid )
     483             :     {
     484           0 :       write_32(a, 0 );  /* Don't tell Eve who can decrypt the message.  */
     485           0 :       write_32(a, 0 );
     486             :     }
     487             :   else
     488             :     {
     489         236 :       write_32(a, enc->keyid[0] );
     490         236 :       write_32(a, enc->keyid[1] );
     491             :     }
     492         236 :   iobuf_put(a,enc->pubkey_algo );
     493         236 :   n = pubkey_get_nenc( enc->pubkey_algo );
     494         236 :   if ( !n )
     495           0 :     write_fake_data( a, enc->data[0] );
     496             : 
     497         708 :   for (i=0; i < n && !rc ; i++ )
     498             :     {
     499         472 :       if (enc->pubkey_algo == PUBKEY_ALGO_ECDH && i == 1)
     500          21 :         rc = gpg_mpi_write_nohdr (a, enc->data[i]);
     501             :       else
     502         451 :         rc = gpg_mpi_write (a, enc->data[i]);
     503             :     }
     504             : 
     505         236 :   if (!rc)
     506             :     {
     507         236 :       write_header (out, ctb, iobuf_get_temp_length(a) );
     508         236 :       rc = iobuf_write_temp (out, a);
     509             :     }
     510         236 :   iobuf_close(a);
     511         236 :   return rc;
     512             : }
     513             : 
     514             : 
     515             : static u32
     516         510 : calc_plaintext( PKT_plaintext *pt )
     517             : {
     518             :   /* Truncate namelen to the maximum 255 characters.  Note this means
     519             :      that a function that calls build_packet with an illegal literal
     520             :      packet will get it back legalized. */
     521             : 
     522         510 :   if(pt->namelen>255)
     523           0 :     pt->namelen=255;
     524             : 
     525         510 :   return pt->len? (1 + 1 + pt->namelen + 4 + pt->len) : 0;
     526             : }
     527             : 
     528             : static int
     529         510 : do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt )
     530             : {
     531         510 :     int i, rc = 0;
     532             :     u32 n;
     533             :     byte buf[1000]; /* this buffer has the plaintext! */
     534             :     int nbytes;
     535             : 
     536         510 :     write_header(out, ctb, calc_plaintext( pt ) );
     537         510 :     iobuf_put(out, pt->mode );
     538         510 :     iobuf_put(out, pt->namelen );
     539        3238 :     for(i=0; i < pt->namelen; i++ )
     540        2728 :         iobuf_put(out, pt->name[i] );
     541         510 :     rc = write_32(out, pt->timestamp );
     542         510 :     if (rc)
     543           0 :       return rc;
     544             : 
     545         510 :     n = 0;
     546        7678 :     while( (nbytes=iobuf_read(pt->buf, buf, 1000)) != -1 ) {
     547        6658 :       rc = iobuf_write (out, buf, nbytes);
     548        6658 :       if (rc)
     549           0 :         break;
     550        6658 :       n += nbytes;
     551             :     }
     552         510 :     wipememory(buf,1000); /* burn the buffer */
     553         510 :     if( (ctb&0x40) && !pt->len )
     554          28 :       iobuf_set_partial_block_mode(out, 0 ); /* turn off partial */
     555         510 :     if( pt->len && n != pt->len )
     556           0 :       log_error("do_plaintext(): wrote %lu bytes but expected %lu bytes\n",
     557           0 :                 (ulong)n, (ulong)pt->len );
     558             : 
     559         510 :     return rc;
     560             : }
     561             : 
     562             : 
     563             : 
     564             : static int
     565          52 : do_encrypted( IOBUF out, int ctb, PKT_encrypted *ed )
     566             : {
     567          52 :     int rc = 0;
     568             :     u32 n;
     569             : 
     570          52 :     n = ed->len ? (ed->len + ed->extralen) : 0;
     571          52 :     write_header(out, ctb, n );
     572             : 
     573             :     /* This is all. The caller has to write the real data */
     574             : 
     575          52 :     return rc;
     576             : }
     577             : 
     578             : static int
     579         402 : do_encrypted_mdc( IOBUF out, int ctb, PKT_encrypted *ed )
     580             : {
     581         402 :     int rc = 0;
     582             :     u32 n;
     583             : 
     584         402 :     assert( ed->mdc_method );
     585             : 
     586             :     /* Take version number and the following MDC packet in account. */
     587         402 :     n = ed->len ? (ed->len + ed->extralen + 1 + 22) : 0;
     588         402 :     write_header(out, ctb, n );
     589         402 :     iobuf_put(out, 1 );  /* version */
     590             : 
     591             :     /* This is all. The caller has to write the real data */
     592             : 
     593         402 :     return rc;
     594             : }
     595             : 
     596             : 
     597             : static int
     598         510 : do_compressed( IOBUF out, int ctb, PKT_compressed *cd )
     599             : {
     600         510 :     int rc = 0;
     601             : 
     602             :     /* We must use the old convention and don't use blockmode for the
     603             :        sake of PGP 2 compatibility.  However if the new_ctb flag was
     604             :        set, CTB is already formatted as new style and write_header2
     605             :        does create a partial length encoding using new the new
     606             :        style. */
     607         510 :     write_header2(out, ctb, 0, 0);
     608         510 :     iobuf_put(out, cd->algorithm );
     609             : 
     610             :     /* This is all. The caller has to write the real data */
     611             : 
     612         510 :     return rc;
     613             : }
     614             : 
     615             : 
     616             : /****************
     617             :  * Delete all subpackets of type REQTYPE and return a bool whether a packet
     618             :  * was deleted.
     619             :  */
     620             : int
     621         520 : delete_sig_subpkt (subpktarea_t *area, sigsubpkttype_t reqtype )
     622             : {
     623             :     int buflen;
     624             :     sigsubpkttype_t type;
     625             :     byte *buffer, *bufstart;
     626             :     size_t n;
     627         520 :     size_t unused = 0;
     628         520 :     int okay = 0;
     629             : 
     630         520 :     if( !area )
     631         360 :         return 0;
     632         160 :     buflen = area->len;
     633         160 :     buffer = area->data;
     634             :     for(;;) {
     635         391 :         if( !buflen ) {
     636         160 :             okay = 1;
     637         160 :             break;
     638             :         }
     639         231 :         bufstart = buffer;
     640         231 :         n = *buffer++; buflen--;
     641         231 :         if( n == 255 ) {
     642           0 :             if( buflen < 4 )
     643           0 :                 break;
     644           0 :             n = buf32_to_size_t (buffer);
     645           0 :             buffer += 4;
     646           0 :             buflen -= 4;
     647             :         }
     648         231 :         else if( n >= 192 ) {
     649           0 :             if( buflen < 2 )
     650           0 :                 break;
     651           0 :             n = (( n - 192 ) << 8) + *buffer + 192;
     652           0 :             buffer++;
     653           0 :             buflen--;
     654             :         }
     655         231 :         if( buflen < n )
     656           0 :             break;
     657             : 
     658         231 :         type = *buffer & 0x7f;
     659         231 :         if( type == reqtype ) {
     660           0 :             buffer++;
     661           0 :             buflen--;
     662           0 :             n--;
     663           0 :             if( n > buflen )
     664           0 :                 break;
     665           0 :             buffer += n; /* point to next subpkt */
     666           0 :             buflen -= n;
     667           0 :             memmove (bufstart, buffer, buflen); /* shift */
     668           0 :             unused +=  buffer - bufstart;
     669           0 :             buffer = bufstart;
     670             :         }
     671             :         else {
     672         231 :             buffer += n; buflen -=n;
     673             :         }
     674         231 :     }
     675             : 
     676         160 :     if (!okay)
     677           0 :         log_error ("delete_subpkt: buffer shorter than subpacket\n");
     678         160 :     assert (unused <= area->len);
     679         160 :     area->len -= unused;
     680         160 :     return !!unused;
     681             : }
     682             : 
     683             : 
     684             : /****************
     685             :  * Create or update a signature subpacket for SIG of TYPE.  This
     686             :  * functions knows where to put the data (hashed or unhashed).  The
     687             :  * function may move data from the unhashed part to the hashed one.
     688             :  * Note: All pointers into sig->[un]hashed (e.g. returned by
     689             :  * parse_sig_subpkt) are not valid after a call to this function.  The
     690             :  * data to put into the subpaket should be in a buffer with a length
     691             :  * of buflen.
     692             :  */
     693             : void
     694         258 : build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type,
     695             :                   const byte *buffer, size_t buflen )
     696             : {
     697             :     byte *p;
     698             :     int critical, hashed;
     699             :     subpktarea_t *oldarea, *newarea;
     700             :     size_t nlen, n, n0;
     701             : 
     702         258 :     critical = (type & SIGSUBPKT_FLAG_CRITICAL);
     703         258 :     type &= ~SIGSUBPKT_FLAG_CRITICAL;
     704             : 
     705             :     /* Sanity check buffer sizes */
     706         258 :     if(parse_one_sig_subpkt(buffer,buflen,type)<0)
     707           0 :       BUG();
     708             : 
     709         258 :     switch(type)
     710             :       {
     711             :       case SIGSUBPKT_NOTATION:
     712             :       case SIGSUBPKT_POLICY:
     713             :       case SIGSUBPKT_REV_KEY:
     714             :       case SIGSUBPKT_SIGNATURE:
     715             :         /* we do allow multiple subpackets */
     716           0 :         break;
     717             : 
     718             :       default:
     719             :         /* we don't allow multiple subpackets */
     720         258 :         delete_sig_subpkt(sig->hashed,type);
     721         258 :         delete_sig_subpkt(sig->unhashed,type);
     722         258 :         break;
     723             :       }
     724             : 
     725             :     /* Any special magic that needs to be done for this type so the
     726             :        packet doesn't need to be reparsed? */
     727         258 :     switch(type)
     728             :       {
     729             :       case SIGSUBPKT_NOTATION:
     730           0 :         sig->flags.notation=1;
     731           0 :         break;
     732             : 
     733             :       case SIGSUBPKT_POLICY:
     734           0 :         sig->flags.policy_url=1;
     735           0 :         break;
     736             : 
     737             :       case SIGSUBPKT_PREF_KS:
     738           0 :         sig->flags.pref_ks=1;
     739           0 :         break;
     740             : 
     741             :       case SIGSUBPKT_EXPORTABLE:
     742           0 :         if(buffer[0])
     743           0 :           sig->flags.exportable=1;
     744             :         else
     745           0 :           sig->flags.exportable=0;
     746           0 :         break;
     747             : 
     748             :       case SIGSUBPKT_REVOCABLE:
     749           0 :         if(buffer[0])
     750           0 :           sig->flags.revocable=1;
     751             :         else
     752           0 :           sig->flags.revocable=0;
     753           0 :         break;
     754             : 
     755             :       case SIGSUBPKT_TRUST:
     756           0 :         sig->trust_depth=buffer[0];
     757           0 :         sig->trust_value=buffer[1];
     758           0 :         break;
     759             : 
     760             :       case SIGSUBPKT_REGEXP:
     761           0 :         sig->trust_regexp=buffer;
     762           0 :         break;
     763             : 
     764             :         /* This should never happen since we don't currently allow
     765             :            creating such a subpacket, but just in case... */
     766             :       case SIGSUBPKT_SIG_EXPIRE:
     767           0 :         if(buf32_to_u32(buffer)+sig->timestamp<=make_timestamp())
     768           0 :           sig->flags.expired=1;
     769             :         else
     770           0 :           sig->flags.expired=0;
     771           0 :         break;
     772             : 
     773             :       default:
     774         258 :         break;
     775             :       }
     776             : 
     777         258 :     if( (buflen+1) >= 8384 )
     778           0 :         nlen = 5; /* write 5 byte length header */
     779         258 :     else if( (buflen+1) >= 192 )
     780           0 :         nlen = 2; /* write 2 byte length header */
     781             :     else
     782         258 :         nlen = 1; /* just a 1 byte length header */
     783             : 
     784         258 :     switch( type )
     785             :       {
     786             :         /* The issuer being unhashed is a historical oddity.  It
     787             :            should work equally as well hashed.  Of course, if even an
     788             :            unhashed issuer is tampered with, it makes it awfully hard
     789             :            to verify the sig... */
     790             :       case SIGSUBPKT_ISSUER:
     791             :       case SIGSUBPKT_SIGNATURE:
     792         120 :         hashed = 0;
     793         120 :         break;
     794             :       default:
     795         138 :         hashed = 1;
     796         138 :         break;
     797             :       }
     798             : 
     799         258 :     if( critical )
     800           0 :         type |= SIGSUBPKT_FLAG_CRITICAL;
     801             : 
     802         258 :     oldarea = hashed? sig->hashed : sig->unhashed;
     803             : 
     804             :     /* Calculate new size of the area and allocate */
     805         258 :     n0 = oldarea? oldarea->len : 0;
     806         258 :     n = n0 + nlen + 1 + buflen; /* length, type, buffer */
     807         258 :     if (oldarea && n <= oldarea->size) { /* fits into the unused space */
     808           0 :         newarea = oldarea;
     809             :         /*log_debug ("updating area for type %d\n", type );*/
     810             :     }
     811         258 :     else if (oldarea) {
     812          18 :         newarea = xrealloc (oldarea, sizeof (*newarea) + n - 1);
     813          18 :         newarea->size = n;
     814             :         /*log_debug ("reallocating area for type %d\n", type );*/
     815             :     }
     816             :     else {
     817         240 :         newarea = xmalloc (sizeof (*newarea) + n - 1);
     818         240 :         newarea->size = n;
     819             :         /*log_debug ("allocating area for type %d\n", type );*/
     820             :     }
     821         258 :     newarea->len = n;
     822             : 
     823         258 :     p = newarea->data + n0;
     824         258 :     if (nlen == 5) {
     825           0 :         *p++ = 255;
     826           0 :         *p++ = (buflen+1) >> 24;
     827           0 :         *p++ = (buflen+1) >> 16;
     828           0 :         *p++ = (buflen+1) >>  8;
     829           0 :         *p++ = (buflen+1);
     830           0 :         *p++ = type;
     831           0 :         memcpy (p, buffer, buflen);
     832             :     }
     833         258 :     else if (nlen == 2) {
     834           0 :         *p++ = (buflen+1-192) / 256 + 192;
     835           0 :         *p++ = (buflen+1-192) % 256;
     836           0 :         *p++ = type;
     837           0 :         memcpy (p, buffer, buflen);
     838             :     }
     839             :     else {
     840         258 :         *p++ = buflen+1;
     841         258 :         *p++ = type;
     842         258 :         memcpy (p, buffer, buflen);
     843             :     }
     844             : 
     845         258 :     if (hashed)
     846         138 :         sig->hashed = newarea;
     847             :     else
     848         120 :         sig->unhashed = newarea;
     849         258 : }
     850             : 
     851             : /****************
     852             :  * Put all the required stuff from SIG into subpackets of sig.
     853             :  * Hmmm, should we delete those subpackets which are in a wrong area?
     854             :  */
     855             : void
     856         120 : build_sig_subpkt_from_sig( PKT_signature *sig )
     857             : {
     858             :     u32  u;
     859             :     byte buf[8];
     860             : 
     861         120 :     u = sig->keyid[0];
     862         120 :     buf[0] = (u >> 24) & 0xff;
     863         120 :     buf[1] = (u >> 16) & 0xff;
     864         120 :     buf[2] = (u >>  8) & 0xff;
     865         120 :     buf[3] = u & 0xff;
     866         120 :     u = sig->keyid[1];
     867         120 :     buf[4] = (u >> 24) & 0xff;
     868         120 :     buf[5] = (u >> 16) & 0xff;
     869         120 :     buf[6] = (u >>  8) & 0xff;
     870         120 :     buf[7] = u & 0xff;
     871         120 :     build_sig_subpkt( sig, SIGSUBPKT_ISSUER, buf, 8 );
     872             : 
     873         120 :     u = sig->timestamp;
     874         120 :     buf[0] = (u >> 24) & 0xff;
     875         120 :     buf[1] = (u >> 16) & 0xff;
     876         120 :     buf[2] = (u >>  8) & 0xff;
     877         120 :     buf[3] = u & 0xff;
     878         120 :     build_sig_subpkt( sig, SIGSUBPKT_SIG_CREATED, buf, 4 );
     879             : 
     880         120 :     if(sig->expiredate)
     881             :       {
     882           0 :         if(sig->expiredate>sig->timestamp)
     883           0 :           u=sig->expiredate-sig->timestamp;
     884             :         else
     885           0 :           u=1; /* A 1-second expiration time is the shortest one
     886             :                   OpenPGP has */
     887             : 
     888           0 :         buf[0] = (u >> 24) & 0xff;
     889           0 :         buf[1] = (u >> 16) & 0xff;
     890           0 :         buf[2] = (u >>  8) & 0xff;
     891           0 :         buf[3] = u & 0xff;
     892             : 
     893             :         /* Mark this CRITICAL, so if any implementation doesn't
     894             :            understand sigs that can expire, it'll just disregard this
     895             :            sig altogether. */
     896             : 
     897           0 :         build_sig_subpkt( sig, SIGSUBPKT_SIG_EXPIRE | SIGSUBPKT_FLAG_CRITICAL,
     898             :                           buf, 4 );
     899             :       }
     900         120 : }
     901             : 
     902             : void
     903           0 : build_attribute_subpkt(PKT_user_id *uid,byte type,
     904             :                        const void *buf,u32 buflen,
     905             :                        const void *header,u32 headerlen)
     906             : {
     907             :   byte *attrib;
     908             :   int idx;
     909             : 
     910           0 :   if(1+headerlen+buflen>8383)
     911           0 :     idx=5;
     912           0 :   else if(1+headerlen+buflen>191)
     913           0 :     idx=2;
     914             :   else
     915           0 :     idx=1;
     916             : 
     917             :   /* realloc uid->attrib_data to the right size */
     918             : 
     919           0 :   uid->attrib_data=xrealloc(uid->attrib_data,
     920             :                              uid->attrib_len+idx+1+headerlen+buflen);
     921             : 
     922           0 :   attrib=&uid->attrib_data[uid->attrib_len];
     923             : 
     924           0 :   if(idx==5)
     925             :     {
     926           0 :       attrib[0]=255;
     927           0 :       attrib[1]=(1+headerlen+buflen) >> 24;
     928           0 :       attrib[2]=(1+headerlen+buflen) >> 16;
     929           0 :       attrib[3]=(1+headerlen+buflen) >> 8;
     930           0 :       attrib[4]=1+headerlen+buflen;
     931             :     }
     932           0 :   else if(idx==2)
     933             :     {
     934           0 :       attrib[0]=(1+headerlen+buflen-192) / 256 + 192;
     935           0 :       attrib[1]=(1+headerlen+buflen-192) % 256;
     936             :     }
     937             :   else
     938           0 :     attrib[0]=1+headerlen+buflen; /* Good luck finding a JPEG this small! */
     939             : 
     940           0 :   attrib[idx++]=type;
     941             : 
     942             :   /* Tack on our data at the end */
     943             : 
     944           0 :   if(headerlen>0)
     945           0 :     memcpy(&attrib[idx],header,headerlen);
     946           0 :   memcpy(&attrib[idx+headerlen],buf,buflen);
     947           0 :   uid->attrib_len+=idx+headerlen+buflen;
     948           0 : }
     949             : 
     950             : struct notation *
     951           0 : string_to_notation(const char *string,int is_utf8)
     952             : {
     953             :   const char *s;
     954           0 :   int saw_at=0;
     955             :   struct notation *notation;
     956             : 
     957           0 :   notation=xmalloc_clear(sizeof(*notation));
     958             : 
     959           0 :   if(*string=='-')
     960             :     {
     961           0 :       notation->flags.ignore=1;
     962           0 :       string++;
     963             :     }
     964             : 
     965           0 :   if(*string=='!')
     966             :     {
     967           0 :       notation->flags.critical=1;
     968           0 :       string++;
     969             :     }
     970             : 
     971             :   /* If and when the IETF assigns some official name tags, we'll have
     972             :      to add them here. */
     973             : 
     974           0 :   for( s=string ; *s != '='; s++ )
     975             :     {
     976           0 :       if( *s=='@')
     977           0 :         saw_at++;
     978             : 
     979             :       /* -notationname is legal without an = sign */
     980           0 :       if(!*s && notation->flags.ignore)
     981           0 :         break;
     982             : 
     983           0 :       if( !*s || !isascii (*s) || (!isgraph(*s) && !isspace(*s)) )
     984             :         {
     985           0 :           log_error(_("a notation name must have only printable characters"
     986             :                       " or spaces, and end with an '='\n") );
     987           0 :           goto fail;
     988             :         }
     989             :     }
     990             : 
     991           0 :   notation->name=xmalloc((s-string)+1);
     992           0 :   strncpy(notation->name,string,s-string);
     993           0 :   notation->name[s-string]='\0';
     994             : 
     995           0 :   if(!saw_at && !opt.expert)
     996             :     {
     997           0 :       log_error(_("a user notation name must contain the '@' character\n"));
     998           0 :       goto fail;
     999             :     }
    1000             : 
    1001           0 :   if (saw_at > 1)
    1002             :     {
    1003           0 :       log_error(_("a notation name must not contain more than"
    1004             :                   " one '@' character\n"));
    1005           0 :       goto fail;
    1006             :     }
    1007             : 
    1008           0 :   if(*s)
    1009             :     {
    1010           0 :       const char *i=s+1;
    1011           0 :       int highbit=0;
    1012             : 
    1013             :       /* we only support printable text - therefore we enforce the use
    1014             :          of only printable characters (an empty value is valid) */
    1015           0 :       for(s++; *s ; s++ )
    1016             :         {
    1017           0 :           if ( !isascii (*s) )
    1018           0 :             highbit=1;
    1019           0 :           else if (iscntrl(*s))
    1020             :             {
    1021           0 :               log_error(_("a notation value must not use any"
    1022             :                           " control characters\n"));
    1023           0 :               goto fail;
    1024             :             }
    1025             :         }
    1026             : 
    1027           0 :       if(!highbit || is_utf8)
    1028           0 :         notation->value=xstrdup(i);
    1029             :       else
    1030           0 :         notation->value=native_to_utf8(i);
    1031             :     }
    1032             : 
    1033           0 :   return notation;
    1034             : 
    1035             :  fail:
    1036           0 :   free_notation(notation);
    1037           0 :   return NULL;
    1038             : }
    1039             : 
    1040             : struct notation *
    1041         143 : sig_to_notation(PKT_signature *sig)
    1042             : {
    1043             :   const byte *p;
    1044             :   size_t len;
    1045         143 :   int seq=0,crit;
    1046         143 :   struct notation *list=NULL;
    1047             : 
    1048         286 :   while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION,&len,&seq,&crit)))
    1049             :     {
    1050             :       int n1,n2;
    1051           0 :       struct notation *n=NULL;
    1052             : 
    1053           0 :       if(len<8)
    1054             :         {
    1055           0 :           log_info(_("WARNING: invalid notation data found\n"));
    1056           0 :           continue;
    1057             :         }
    1058             : 
    1059           0 :       n1=(p[4]<<8)|p[5];
    1060           0 :       n2=(p[6]<<8)|p[7];
    1061             : 
    1062           0 :       if(8+n1+n2!=len)
    1063             :         {
    1064           0 :           log_info(_("WARNING: invalid notation data found\n"));
    1065           0 :           continue;
    1066             :         }
    1067             : 
    1068           0 :       n=xmalloc_clear(sizeof(*n));
    1069           0 :       n->name=xmalloc(n1+1);
    1070             : 
    1071           0 :       memcpy(n->name,&p[8],n1);
    1072           0 :       n->name[n1]='\0';
    1073             : 
    1074           0 :       if(p[0]&0x80)
    1075             :         {
    1076           0 :           n->value=xmalloc(n2+1);
    1077           0 :           memcpy(n->value,&p[8+n1],n2);
    1078           0 :           n->value[n2]='\0';
    1079             :         }
    1080             :       else
    1081             :         {
    1082           0 :           n->bdat=xmalloc(n2);
    1083           0 :           n->blen=n2;
    1084           0 :           memcpy(n->bdat,&p[8+n1],n2);
    1085             : 
    1086           0 :           n->value=xmalloc(2+strlen(_("not human readable"))+2+1);
    1087           0 :           strcpy(n->value,"[ ");
    1088           0 :           strcat(n->value,_("not human readable"));
    1089           0 :           strcat(n->value," ]");
    1090             :         }
    1091             : 
    1092           0 :       n->flags.critical=crit;
    1093             : 
    1094           0 :       n->next=list;
    1095           0 :       list=n;
    1096             :     }
    1097             : 
    1098         143 :   return list;
    1099             : }
    1100             : 
    1101             : void
    1102         143 : free_notation(struct notation *notation)
    1103             : {
    1104         286 :   while(notation)
    1105             :     {
    1106           0 :       struct notation *n=notation;
    1107             : 
    1108           0 :       xfree(n->name);
    1109           0 :       xfree(n->value);
    1110           0 :       xfree(n->altvalue);
    1111           0 :       xfree(n->bdat);
    1112           0 :       notation=n->next;
    1113           0 :       xfree(n);
    1114             :     }
    1115         143 : }
    1116             : 
    1117             : static int
    1118         383 : do_signature( IOBUF out, int ctb, PKT_signature *sig )
    1119             : {
    1120         383 :   int rc = 0;
    1121             :   int n, i;
    1122         383 :   IOBUF a = iobuf_temp();
    1123             : 
    1124         383 :   if ( !sig->version )
    1125           0 :     iobuf_put( a, 3 );
    1126             :   else
    1127         383 :     iobuf_put( a, sig->version );
    1128         383 :   if ( sig->version < 4 )
    1129           2 :     iobuf_put (a, 5 ); /* Constant */
    1130         383 :   iobuf_put (a, sig->sig_class );
    1131         383 :   if ( sig->version < 4 )
    1132             :     {
    1133           2 :       write_32(a, sig->timestamp );
    1134           2 :       write_32(a, sig->keyid[0] );
    1135           2 :       write_32(a, sig->keyid[1] );
    1136             :     }
    1137         383 :   iobuf_put(a, sig->pubkey_algo );
    1138         383 :   iobuf_put(a, sig->digest_algo );
    1139         383 :   if ( sig->version >= 4 )
    1140             :     {
    1141             :       size_t nn;
    1142             :       /* Timestamp and keyid must have been packed into the subpackets
    1143             :          prior to the call of this function, because these subpackets
    1144             :          are hashed. */
    1145         381 :       nn = sig->hashed? sig->hashed->len : 0;
    1146         381 :       write_16(a, nn);
    1147         381 :       if (nn)
    1148         381 :         iobuf_write( a, sig->hashed->data, nn );
    1149         381 :       nn = sig->unhashed? sig->unhashed->len : 0;
    1150         381 :       write_16(a, nn);
    1151         381 :       if (nn)
    1152         381 :         iobuf_write( a, sig->unhashed->data, nn );
    1153             :     }
    1154         383 :   iobuf_put(a, sig->digest_start[0] );
    1155         383 :   iobuf_put(a, sig->digest_start[1] );
    1156         383 :   n = pubkey_get_nsig( sig->pubkey_algo );
    1157         383 :   if ( !n )
    1158           0 :     write_fake_data( a, sig->data[0] );
    1159        1069 :   for (i=0; i < n && !rc ; i++ )
    1160         686 :     rc = gpg_mpi_write (a, sig->data[i] );
    1161             : 
    1162         383 :   if (!rc)
    1163             :     {
    1164         383 :       if ( is_RSA(sig->pubkey_algo) && sig->version < 4 )
    1165           1 :         write_sign_packet_header(out, ctb, iobuf_get_temp_length(a) );
    1166             :       else
    1167         382 :         write_header(out, ctb, iobuf_get_temp_length(a) );
    1168         383 :       rc = iobuf_write_temp( out, a );
    1169             :     }
    1170             : 
    1171         383 :   iobuf_close(a);
    1172         383 :   return rc;
    1173             : }
    1174             : 
    1175             : 
    1176             : static int
    1177          89 : do_onepass_sig( IOBUF out, int ctb, PKT_onepass_sig *ops )
    1178             : {
    1179          89 :     int rc = 0;
    1180          89 :     IOBUF a = iobuf_temp();
    1181             : 
    1182          89 :     iobuf_put (a, 3);  /* Version.  */
    1183          89 :     iobuf_put(a, ops->sig_class );
    1184          89 :     iobuf_put(a, ops->digest_algo );
    1185          89 :     iobuf_put(a, ops->pubkey_algo );
    1186          89 :     write_32(a, ops->keyid[0] );
    1187          89 :     write_32(a, ops->keyid[1] );
    1188          89 :     iobuf_put(a, ops->last );
    1189             : 
    1190          89 :     write_header(out, ctb, iobuf_get_temp_length(a) );
    1191          89 :     rc = iobuf_write_temp( out, a );
    1192             : 
    1193          89 :     iobuf_close(a);
    1194          89 :     return rc;
    1195             : }
    1196             : 
    1197             : 
    1198             : static int
    1199         762 : write_16(IOBUF out, u16 a)
    1200             : {
    1201         762 :     iobuf_put(out, a>>8);
    1202         762 :     if( iobuf_put(out,a) )
    1203           0 :         return -1;
    1204         762 :     return 0;
    1205             : }
    1206             : 
    1207             : static int
    1208        1274 : write_32(IOBUF out, u32 a)
    1209             : {
    1210        1274 :     iobuf_put(out, a>> 24);
    1211        1274 :     iobuf_put(out, a>> 16);
    1212        1274 :     iobuf_put(out, a>> 8);
    1213        1274 :     return iobuf_put(out, a);
    1214             : }
    1215             : 
    1216             : 
    1217             : /****************
    1218             :  * calculate the length of a header
    1219             :  */
    1220             : static int
    1221           0 : calc_header_length( u32 len, int new_ctb )
    1222             : {
    1223           0 :     if( !len )
    1224           0 :         return 1; /* only the ctb */
    1225             : 
    1226           0 :     if( new_ctb ) {
    1227           0 :         if( len < 192 )
    1228           0 :             return 2;
    1229           0 :         if( len < 8384 )
    1230           0 :             return 3;
    1231             :         else
    1232           0 :             return 6;
    1233             :     }
    1234           0 :     if( len < 256 )
    1235           0 :         return 2;
    1236           0 :     if( len < 65536 )
    1237           0 :         return 3;
    1238             : 
    1239           0 :     return 5;
    1240             : }
    1241             : 
    1242             : /****************
    1243             :  * Write the CTB and the packet length
    1244             :  */
    1245             : static int
    1246        1889 : write_header( IOBUF out, int ctb, u32 len )
    1247             : {
    1248        1889 :     return write_header2( out, ctb, len, 0 );
    1249             : }
    1250             : 
    1251             : 
    1252             : static int
    1253           1 : write_sign_packet_header (IOBUF out, int ctb, u32 len)
    1254             : {
    1255             :   (void)ctb;
    1256             : 
    1257             :   /* Work around a bug in the pgp read function for signature packets,
    1258             :      which are not correctly coded and silently assume at some point 2
    1259             :      byte length headers.*/
    1260           1 :   iobuf_put (out, 0x89 );
    1261           1 :   iobuf_put (out, len >> 8 );
    1262           1 :   return iobuf_put (out, len) == -1 ? -1:0;
    1263             : }
    1264             : 
    1265             : /****************
    1266             :  * If HDRLEN is > 0, try to build a header of this length.  We need
    1267             :  * this so that we can hash packets without reading them again.  If
    1268             :  * len is 0, write a partial or indeterminate length header, unless
    1269             :  * hdrlen is specified in which case write an actual zero length
    1270             :  * (using the specified hdrlen).
    1271             :  */
    1272             : static int
    1273        2582 : write_header2( IOBUF out, int ctb, u32 len, int hdrlen )
    1274             : {
    1275        2582 :   if( ctb & 0x40 )
    1276         482 :     return write_new_header( out, ctb, len, hdrlen );
    1277             : 
    1278        2100 :   if( hdrlen )
    1279             :     {
    1280         180 :       if( hdrlen == 2 && len < 256 )
    1281             :         ;
    1282          86 :       else if( hdrlen == 3 && len < 65536 )
    1283          86 :         ctb |= 1;
    1284             :       else
    1285           0 :         ctb |= 2;
    1286             :     }
    1287             :   else
    1288             :     {
    1289        1920 :       if( !len )
    1290         510 :         ctb |= 3;
    1291        1410 :       else if( len < 256 )
    1292             :         ;
    1293         469 :       else if( len < 65536 )
    1294         420 :         ctb |= 1;
    1295             :       else
    1296          49 :         ctb |= 2;
    1297             :     }
    1298             : 
    1299        2100 :   if( iobuf_put(out, ctb ) )
    1300           0 :     return -1;
    1301             : 
    1302        2100 :   if( len || hdrlen )
    1303             :     {
    1304        1590 :       if( ctb & 2 )
    1305             :         {
    1306          49 :           if(iobuf_put(out, len >> 24 ))
    1307           0 :             return -1;
    1308          49 :           if(iobuf_put(out, len >> 16 ))
    1309           0 :             return -1;
    1310             :         }
    1311             : 
    1312        1590 :       if( ctb & 3 )
    1313         555 :         if(iobuf_put(out, len >> 8 ))
    1314           0 :           return -1;
    1315             : 
    1316        1590 :       if( iobuf_put(out, len ) )
    1317           0 :         return -1;
    1318             :     }
    1319             : 
    1320        2100 :   return 0;
    1321             : }
    1322             : 
    1323             : 
    1324             : static int
    1325         482 : write_new_header( IOBUF out, int ctb, u32 len, int hdrlen )
    1326             : {
    1327         482 :     if( hdrlen )
    1328           0 :         log_bug("can't cope with hdrlen yet\n");
    1329             : 
    1330         482 :     if( iobuf_put(out, ctb ) )
    1331           0 :         return -1;
    1332         482 :     if( !len ) {
    1333         482 :         iobuf_set_partial_block_mode(out, 512 );
    1334             :     }
    1335             :     else {
    1336           0 :         if( len < 192 ) {
    1337           0 :             if( iobuf_put(out, len ) )
    1338           0 :                 return -1;
    1339             :         }
    1340           0 :         else if( len < 8384 ) {
    1341           0 :             len -= 192;
    1342           0 :             if( iobuf_put( out, (len / 256) + 192) )
    1343           0 :                 return -1;
    1344           0 :             if( iobuf_put( out, (len % 256) )  )
    1345           0 :                 return -1;
    1346             :         }
    1347             :         else {
    1348           0 :             if( iobuf_put( out, 0xff ) )
    1349           0 :                 return -1;
    1350           0 :             if( iobuf_put( out, (len >> 24)&0xff ) )
    1351           0 :                 return -1;
    1352           0 :             if( iobuf_put( out, (len >> 16)&0xff ) )
    1353           0 :                 return -1;
    1354           0 :             if( iobuf_put( out, (len >> 8)&0xff )  )
    1355           0 :                 return -1;
    1356           0 :             if( iobuf_put( out, len & 0xff ) )
    1357           0 :                 return -1;
    1358             :         }
    1359             :     }
    1360         482 :     return 0;
    1361             : }

Generated by: LCOV version 1.11