LCOV - code coverage report
Current view: top level - g10 - encrypt.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 245 447 54.8 %
Date: 2015-11-05 17:10:59 Functions: 6 11 54.5 %

          Line data    Source code
       1             : /* encrypt.c - Main encryption driver
       2             :  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
       3             :  *               2006, 2009 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 <errno.h>
      26             : #include <assert.h>
      27             : 
      28             : #include "gpg.h"
      29             : #include "options.h"
      30             : #include "packet.h"
      31             : #include "status.h"
      32             : #include "iobuf.h"
      33             : #include "keydb.h"
      34             : #include "util.h"
      35             : #include "main.h"
      36             : #include "filter.h"
      37             : #include "trustdb.h"
      38             : #include "i18n.h"
      39             : #include "status.h"
      40             : #include "pkglue.h"
      41             : 
      42             : 
      43             : static int encrypt_simple( const char *filename, int mode, int use_seskey );
      44             : static int write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, iobuf_t out );
      45             : 
      46             : /****************
      47             :  * Encrypt FILENAME with only the symmetric cipher.  Take input from
      48             :  * stdin if FILENAME is NULL.
      49             :  */
      50             : int
      51         211 : encrypt_symmetric (const char *filename)
      52             : {
      53         211 :   return encrypt_simple( filename, 1, 0 );
      54             : }
      55             : 
      56             : 
      57             : /****************
      58             :  * Encrypt FILENAME as a literal data packet only. Take input from
      59             :  * stdin if FILENAME is NULL.
      60             :  */
      61             : int
      62           0 : encrypt_store (const char *filename)
      63             : {
      64           0 :   return encrypt_simple( filename, 0, 0 );
      65             : }
      66             : 
      67             : 
      68             : static void
      69           0 : encrypt_seskey (DEK *dek, DEK **seskey, byte *enckey)
      70             : {
      71             :   gcry_cipher_hd_t hd;
      72             :   byte buf[33];
      73             : 
      74           0 :   assert ( dek->keylen <= 32 );
      75           0 :   if (!*seskey)
      76             :     {
      77           0 :       *seskey=xmalloc_clear(sizeof(DEK));
      78           0 :       (*seskey)->keylen=dek->keylen;
      79           0 :       (*seskey)->algo=dek->algo;
      80           0 :       make_session_key(*seskey);
      81             :       /*log_hexdump( "thekey", c->key, c->keylen );*/
      82             :     }
      83             : 
      84             :   /* The encrypted session key is prefixed with a one-octet algorithm id.  */
      85           0 :   buf[0] = (*seskey)->algo;
      86           0 :   memcpy( buf + 1, (*seskey)->key, (*seskey)->keylen );
      87             : 
      88             :   /* We only pass already checked values to the following fucntion,
      89             :      thus we consider any failure as fatal.  */
      90           0 :   if (openpgp_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, 1))
      91           0 :     BUG ();
      92           0 :   if (gcry_cipher_setkey (hd, dek->key, dek->keylen))
      93           0 :     BUG ();
      94           0 :   gcry_cipher_setiv (hd, NULL, 0);
      95           0 :   gcry_cipher_encrypt (hd, buf, (*seskey)->keylen + 1, NULL, 0);
      96           0 :   gcry_cipher_close (hd);
      97             : 
      98           0 :   memcpy( enckey, buf, (*seskey)->keylen + 1 );
      99           0 :   wipememory( buf, sizeof buf ); /* burn key */
     100           0 : }
     101             : 
     102             : 
     103             : /* We try very hard to use a MDC */
     104             : int
     105         454 : use_mdc (pk_list_t pk_list,int algo)
     106             : {
     107             :   /* RFC-2440 don't has MDC */
     108         454 :   if (RFC2440)
     109           0 :     return 0;
     110             : 
     111             :   /* --force-mdc overrides --disable-mdc */
     112         454 :   if(opt.force_mdc)
     113         187 :     return 1;
     114             : 
     115         267 :   if(opt.disable_mdc)
     116           0 :     return 0;
     117             : 
     118             :   /* Do the keys really support MDC? */
     119             : 
     120         267 :   if(select_mdc_from_pklist(pk_list))
     121         143 :     return 1;
     122             : 
     123             :   /* The keys don't support MDC, so now we do a bit of a hack - if any
     124             :      of the AESes or TWOFISH are in the prefs, we assume that the user
     125             :      can handle a MDC.  This is valid for PGP 7, which can handle MDCs
     126             :      though it will not generate them.  2440bis allows this, by the
     127             :      way. */
     128             : 
     129         124 :   if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
     130             :                             CIPHER_ALGO_AES,NULL)==CIPHER_ALGO_AES)
     131           0 :     return 1;
     132             : 
     133         124 :   if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
     134             :                             CIPHER_ALGO_AES192,NULL)==CIPHER_ALGO_AES192)
     135           0 :     return 1;
     136             : 
     137         124 :   if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
     138             :                             CIPHER_ALGO_AES256,NULL)==CIPHER_ALGO_AES256)
     139           0 :     return 1;
     140             : 
     141         124 :   if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
     142             :                             CIPHER_ALGO_TWOFISH,NULL)==CIPHER_ALGO_TWOFISH)
     143           0 :     return 1;
     144             : 
     145             :   /* Last try.  Use MDC for the modern ciphers. */
     146             : 
     147         124 :   if (openpgp_cipher_get_algo_blklen (algo) != 8)
     148          72 :     return 1;
     149             : 
     150          52 :   if (opt.verbose)
     151           0 :     warn_missing_mdc_from_pklist (pk_list);
     152             : 
     153          52 :   return 0; /* No MDC */
     154             : }
     155             : 
     156             : 
     157             : /* We don't want to use use_seskey yet because older gnupg versions
     158             :    can't handle it, and there isn't really any point unless we're
     159             :    making a message that can be decrypted by a public key or
     160             :    passphrase. */
     161             : static int
     162         211 : encrypt_simple (const char *filename, int mode, int use_seskey)
     163             : {
     164             :   iobuf_t inp, out;
     165             :   PACKET pkt;
     166         211 :   PKT_plaintext *pt = NULL;
     167         211 :   STRING2KEY *s2k = NULL;
     168             :   byte enckey[33];
     169         211 :   int rc = 0;
     170         211 :   int seskeylen = 0;
     171             :   u32 filesize;
     172             :   cipher_filter_context_t cfx;
     173         211 :   armor_filter_context_t  *afx = NULL;
     174             :   compress_filter_context_t zfx;
     175             :   text_filter_context_t tfx;
     176             :   progress_filter_context_t *pfx;
     177         211 :   int do_compress = !!default_compress_algo();
     178             : 
     179         211 :   pfx = new_progress_context ();
     180         211 :   memset( &cfx, 0, sizeof cfx);
     181         211 :   memset( &zfx, 0, sizeof zfx);
     182         211 :   memset( &tfx, 0, sizeof tfx);
     183         211 :   init_packet(&pkt);
     184             : 
     185             :   /* Prepare iobufs. */
     186         211 :   inp = iobuf_open(filename);
     187         211 :   if (inp)
     188         211 :     iobuf_ioctl (inp, IOBUF_IOCTL_NO_CACHE, 1, NULL);
     189         211 :   if (inp && is_secured_file (iobuf_get_fd (inp)))
     190             :     {
     191           0 :       iobuf_close (inp);
     192           0 :       inp = NULL;
     193           0 :       gpg_err_set_errno (EPERM);
     194             :     }
     195         211 :   if (!inp)
     196             :     {
     197           0 :       rc = gpg_error_from_syserror ();
     198           0 :       log_error(_("can't open '%s': %s\n"), filename? filename: "[stdin]",
     199           0 :                 strerror(errno) );
     200           0 :       release_progress_context (pfx);
     201           0 :       return rc;
     202             :     }
     203             : 
     204         211 :   handle_progress (pfx, inp, filename);
     205             : 
     206         211 :   if (opt.textmode)
     207           0 :     iobuf_push_filter( inp, text_filter, &tfx );
     208             : 
     209         211 :   cfx.dek = NULL;
     210         211 :   if ( mode )
     211             :     {
     212             :       int canceled;
     213             : 
     214         211 :       s2k = xmalloc_clear( sizeof *s2k );
     215         211 :       s2k->mode = opt.s2k_mode;
     216         211 :       s2k->hash_algo = S2K_DIGEST_ALGO;
     217         211 :       cfx.dek = passphrase_to_dek (NULL, 0,
     218             :                                    default_cipher_algo(), s2k, 4,
     219             :                                    NULL, &canceled);
     220         211 :       if ( !cfx.dek || !cfx.dek->keylen )
     221             :         {
     222           0 :           rc = gpg_error (canceled? GPG_ERR_CANCELED:GPG_ERR_INV_PASSPHRASE);
     223           0 :           xfree (cfx.dek);
     224           0 :           xfree (s2k);
     225           0 :           iobuf_close (inp);
     226           0 :           log_error (_("error creating passphrase: %s\n"), gpg_strerror (rc));
     227           0 :           release_progress_context (pfx);
     228           0 :           return rc;
     229             :         }
     230         211 :       if (use_seskey && s2k->mode != 1 && s2k->mode != 3)
     231             :         {
     232           0 :           use_seskey = 0;
     233           0 :           log_info (_("can't use a symmetric ESK packet "
     234             :                       "due to the S2K mode\n"));
     235             :         }
     236             : 
     237         211 :       if ( use_seskey )
     238             :         {
     239           0 :           DEK *dek = NULL;
     240             : 
     241           0 :           seskeylen = openpgp_cipher_get_algo_keylen (default_cipher_algo ());
     242           0 :           encrypt_seskey( cfx.dek, &dek, enckey );
     243           0 :           xfree( cfx.dek ); cfx.dek = dek;
     244             :         }
     245             : 
     246         211 :       if (opt.verbose)
     247           0 :         log_info(_("using cipher %s\n"),
     248           0 :                  openpgp_cipher_algo_name (cfx.dek->algo));
     249             : 
     250         211 :       cfx.dek->use_mdc=use_mdc(NULL,cfx.dek->algo);
     251             :     }
     252             : 
     253         211 :   if (do_compress && cfx.dek && cfx.dek->use_mdc
     254         203 :       && is_file_compressed(filename, &rc))
     255             :     {
     256           0 :       if (opt.verbose)
     257           0 :         log_info(_("'%s' already compressed\n"), filename);
     258           0 :       do_compress = 0;
     259             :     }
     260             : 
     261         211 :   if ( rc || (rc = open_outfile (-1, filename, opt.armor? 1:0, 0, &out )))
     262             :     {
     263           0 :       iobuf_cancel (inp);
     264           0 :       xfree (cfx.dek);
     265           0 :       xfree (s2k);
     266           0 :       release_progress_context (pfx);
     267           0 :       return rc;
     268             :     }
     269             : 
     270         211 :   if ( opt.armor )
     271             :     {
     272           0 :       afx = new_armor_context ();
     273           0 :       push_armor_filter (afx, out);
     274             :     }
     275             : 
     276         211 :   if ( s2k )
     277             :     {
     278         211 :       PKT_symkey_enc *enc = xmalloc_clear( sizeof *enc + seskeylen + 1 );
     279         211 :       enc->version = 4;
     280         211 :       enc->cipher_algo = cfx.dek->algo;
     281         211 :       enc->s2k = *s2k;
     282         211 :       if ( use_seskey && seskeylen )
     283             :         {
     284           0 :           enc->seskeylen = seskeylen + 1; /* algo id */
     285           0 :           memcpy (enc->seskey, enckey, seskeylen + 1 );
     286             :         }
     287         211 :       pkt.pkttype = PKT_SYMKEY_ENC;
     288         211 :       pkt.pkt.symkey_enc = enc;
     289         211 :       if ((rc = build_packet( out, &pkt )))
     290           0 :         log_error("build symkey packet failed: %s\n", gpg_strerror (rc) );
     291         211 :       xfree (enc);
     292             :     }
     293             : 
     294         211 :   if (!opt.no_literal)
     295         211 :     pt = setup_plaintext_name (filename, inp);
     296             : 
     297             :   /* Note that PGP 5 has problems decrypting symmetrically encrypted
     298             :      data if the file length is in the inner packet. It works when
     299             :      only partial length headers are use.  In the past, we always used
     300             :      partial body length here, but since PGP 2, PGP 6, and PGP 7 need
     301             :      the file length, and nobody should be using PGP 5 nowadays
     302             :      anyway, this is now set to the file length.  Note also that this
     303             :      only applies to the RFC-1991 style symmetric messages, and not
     304             :      the RFC-2440 style.  PGP 6 and 7 work with either partial length
     305             :      or fixed length with the new style messages. */
     306             : 
     307         211 :   if ( !iobuf_is_pipe_filename (filename) && *filename && !opt.textmode )
     308         211 :     {
     309             :       off_t tmpsize;
     310             :       int overflow;
     311             : 
     312         211 :       if ( !(tmpsize = iobuf_get_filelength(inp, &overflow))
     313          11 :            && !overflow && opt.verbose)
     314           0 :         log_info(_("WARNING: '%s' is an empty file\n"), filename );
     315             :       /* We can't encode the length of very large files because
     316             :          OpenPGP uses only 32 bit for file sizes.  So if the the
     317             :          size of a file is larger than 2^32 minus some bytes for
     318             :          packet headers, we switch to partial length encoding. */
     319         211 :       if ( tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) )
     320         211 :         filesize = tmpsize;
     321             :       else
     322           0 :         filesize = 0;
     323             :     }
     324             :   else
     325           0 :     filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
     326             : 
     327         211 :   if (!opt.no_literal)
     328             :     {
     329         211 :       pt->timestamp = make_timestamp();
     330         211 :       pt->mode = opt.textmode? 't' : 'b';
     331         211 :       pt->len = filesize;
     332         211 :       pt->new_ctb = !pt->len;
     333         211 :       pt->buf = inp;
     334         211 :       pkt.pkttype = PKT_PLAINTEXT;
     335         211 :       pkt.pkt.plaintext = pt;
     336         211 :       cfx.datalen = filesize && !do_compress ? calc_packet_length( &pkt ) : 0;
     337             :     }
     338             :   else
     339             :     {
     340           0 :       cfx.datalen = filesize && !do_compress ? filesize : 0;
     341           0 :       pkt.pkttype = 0;
     342           0 :       pkt.pkt.generic = NULL;
     343             :     }
     344             : 
     345             :   /* Register the cipher filter. */
     346         211 :   if (mode)
     347         211 :     iobuf_push_filter ( out, cipher_filter, &cfx );
     348             : 
     349             :   /* Register the compress filter. */
     350         211 :   if ( do_compress )
     351             :     {
     352         211 :       if (cfx.dek && cfx.dek->use_mdc)
     353         203 :         zfx.new_ctb = 1;
     354         211 :       push_compress_filter (out, &zfx, default_compress_algo());
     355             :     }
     356             : 
     357             :   /* Do the work. */
     358         211 :   if (!opt.no_literal)
     359             :     {
     360         211 :       if ( (rc = build_packet( out, &pkt )) )
     361           0 :         log_error("build_packet failed: %s\n", gpg_strerror (rc) );
     362             :     }
     363             :   else
     364             :     {
     365             :       /* User requested not to create a literal packet, so we copy the
     366             :          plain data.  */
     367             :     byte copy_buffer[4096];
     368             :     int  bytes_copied;
     369           0 :     while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
     370           0 :       if ( (rc=iobuf_write(out, copy_buffer, bytes_copied)) ) {
     371           0 :         log_error ("copying input to output failed: %s\n",
     372             :                    gpg_strerror (rc) );
     373           0 :         break;
     374             :       }
     375           0 :     wipememory (copy_buffer, 4096); /* burn buffer */
     376             :     }
     377             : 
     378             :   /* Finish the stuff.  */
     379         211 :   iobuf_close (inp);
     380         211 :   if (rc)
     381           0 :     iobuf_cancel(out);
     382             :   else
     383             :     {
     384         211 :       iobuf_close (out); /* fixme: check returncode */
     385         211 :       if (mode)
     386         211 :         write_status ( STATUS_END_ENCRYPTION );
     387             :     }
     388         211 :   if (pt)
     389         211 :     pt->buf = NULL;
     390         211 :   free_packet (&pkt);
     391         211 :   xfree (cfx.dek);
     392         211 :   xfree (s2k);
     393         211 :   release_armor_context (afx);
     394         211 :   release_progress_context (pfx);
     395         211 :   return rc;
     396             : }
     397             : 
     398             : 
     399             : int
     400           0 : setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek)
     401             : {
     402             :   int canceled;
     403             : 
     404           0 :   *symkey_s2k=xmalloc_clear(sizeof(STRING2KEY));
     405           0 :   (*symkey_s2k)->mode = opt.s2k_mode;
     406           0 :   (*symkey_s2k)->hash_algo = S2K_DIGEST_ALGO;
     407             : 
     408           0 :   *symkey_dek=passphrase_to_dek(NULL,0,opt.s2k_cipher_algo,
     409             :                                 *symkey_s2k, 4, NULL, &canceled);
     410           0 :   if(!*symkey_dek || !(*symkey_dek)->keylen)
     411             :     {
     412           0 :       xfree(*symkey_dek);
     413           0 :       xfree(*symkey_s2k);
     414           0 :       return gpg_error (canceled?GPG_ERR_CANCELED:GPG_ERR_BAD_PASSPHRASE);
     415             :     }
     416             : 
     417           0 :   return 0;
     418             : }
     419             : 
     420             : 
     421             : static int
     422           0 : write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek,
     423             :                   iobuf_t out)
     424             : {
     425           0 :   int rc, seskeylen = openpgp_cipher_get_algo_keylen (dek->algo);
     426             : 
     427             :   PKT_symkey_enc *enc;
     428             :   byte enckey[33];
     429             :   PACKET pkt;
     430             : 
     431           0 :   enc=xmalloc_clear(sizeof(PKT_symkey_enc)+seskeylen+1);
     432           0 :   encrypt_seskey(symkey_dek,&dek,enckey);
     433             : 
     434           0 :   enc->version = 4;
     435           0 :   enc->cipher_algo = opt.s2k_cipher_algo;
     436           0 :   enc->s2k = *symkey_s2k;
     437           0 :   enc->seskeylen = seskeylen + 1; /* algo id */
     438           0 :   memcpy( enc->seskey, enckey, seskeylen + 1 );
     439             : 
     440           0 :   pkt.pkttype = PKT_SYMKEY_ENC;
     441           0 :   pkt.pkt.symkey_enc = enc;
     442             : 
     443           0 :   if ((rc=build_packet(out,&pkt)))
     444           0 :     log_error("build symkey_enc packet failed: %s\n",gpg_strerror (rc));
     445             : 
     446           0 :   xfree(enc);
     447           0 :   return rc;
     448             : }
     449             : 
     450             : 
     451             : /*
     452             :  * Encrypt the file with the given userids (or ask if none is
     453             :  * supplied).  Either FILENAME or FILEFD must be given, but not both.
     454             :  * The caller may provide a checked list of public keys in
     455             :  * PROVIDED_PKS; if not the function builds a list of keys on its own.
     456             :  *
     457             :  * Note that FILEFD is currently only used by cmd_encrypt in the the
     458             :  * not yet finished server.c.
     459             :  */
     460             : int
     461         210 : encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
     462             :                strlist_t remusr, int use_symkey, pk_list_t provided_keys,
     463             :                int outputfd)
     464             : {
     465         210 :   iobuf_t inp = NULL;
     466         210 :   iobuf_t out = NULL;
     467             :   PACKET pkt;
     468         210 :   PKT_plaintext *pt = NULL;
     469         210 :   DEK *symkey_dek = NULL;
     470         210 :   STRING2KEY *symkey_s2k = NULL;
     471         210 :   int rc = 0, rc2 = 0;
     472             :   u32 filesize;
     473             :   cipher_filter_context_t cfx;
     474         210 :   armor_filter_context_t *afx = NULL;
     475             :   compress_filter_context_t zfx;
     476             :   text_filter_context_t tfx;
     477             :   progress_filter_context_t *pfx;
     478             :   PK_LIST pk_list;
     479             :   int do_compress;
     480             : 
     481         210 :   if (filefd != -1 && filename)
     482           0 :     return gpg_error (GPG_ERR_INV_ARG);  /* Both given.  */
     483             : 
     484         210 :   do_compress = !!opt.compress_algo;
     485             : 
     486         210 :   pfx = new_progress_context ();
     487         210 :   memset( &cfx, 0, sizeof cfx);
     488         210 :   memset( &zfx, 0, sizeof zfx);
     489         210 :   memset( &tfx, 0, sizeof tfx);
     490         210 :   init_packet(&pkt);
     491             : 
     492         210 :   if (use_symkey
     493           0 :       && (rc=setup_symkey(&symkey_s2k,&symkey_dek)))
     494             :     {
     495           0 :       release_progress_context (pfx);
     496           0 :       return rc;
     497             :     }
     498             : 
     499         210 :   if (provided_keys)
     500           0 :     pk_list = provided_keys;
     501             :   else
     502             :     {
     503         210 :       if ((rc = build_pk_list (ctrl, remusr, &pk_list, PUBKEY_USAGE_ENC)))
     504             :         {
     505           0 :           release_progress_context (pfx);
     506           0 :           return rc;
     507             :         }
     508             :     }
     509             : 
     510             :   /* Prepare iobufs. */
     511             : #ifdef HAVE_W32_SYSTEM
     512             :   if (filefd == -1)
     513             :     inp = iobuf_open (filename);
     514             :   else
     515             :     {
     516             :       inp = NULL;
     517             :       gpg_err_set_errno (ENOSYS);
     518             :     }
     519             : #else
     520         210 :   if (filefd == GNUPG_INVALID_FD)
     521         210 :     inp = iobuf_open (filename);
     522             :   else
     523           0 :     inp = iobuf_fdopen_nc (FD2INT(filefd), "rb");
     524             : #endif
     525         210 :   if (inp)
     526         210 :     iobuf_ioctl (inp, IOBUF_IOCTL_NO_CACHE, 1, NULL);
     527         210 :   if (inp && is_secured_file (iobuf_get_fd (inp)))
     528             :     {
     529           0 :       iobuf_close (inp);
     530           0 :       inp = NULL;
     531           0 :       gpg_err_set_errno (EPERM);
     532             :     }
     533         210 :   if (!inp)
     534             :     {
     535             :       char xname[64];
     536             : 
     537           0 :       rc = gpg_error_from_syserror ();
     538           0 :       if (filefd != -1)
     539           0 :         snprintf (xname, sizeof xname, "[fd %d]", filefd);
     540           0 :       else if (!filename)
     541           0 :         strcpy (xname, "[stdin]");
     542             :       else
     543           0 :         *xname = 0;
     544           0 :       log_error (_("can't open '%s': %s\n"),
     545           0 :                  *xname? xname : filename, gpg_strerror (rc) );
     546           0 :       goto leave;
     547             :     }
     548             : 
     549         210 :   if (opt.verbose)
     550           0 :     log_info (_("reading from '%s'\n"), iobuf_get_fname_nonnull (inp));
     551             : 
     552         210 :   handle_progress (pfx, inp, filename);
     553             : 
     554         210 :   if (opt.textmode)
     555           0 :     iobuf_push_filter (inp, text_filter, &tfx);
     556             : 
     557         210 :   rc = open_outfile (outputfd, filename, opt.armor? 1:0, 0, &out);
     558         210 :   if (rc)
     559           0 :     goto leave;
     560             : 
     561         210 :   if (opt.armor)
     562             :     {
     563          14 :       afx = new_armor_context ();
     564          14 :       push_armor_filter (afx, out);
     565             :     }
     566             : 
     567             :   /* Create a session key. */
     568         210 :   cfx.dek = xmalloc_secure_clear (sizeof *cfx.dek);
     569         210 :   if (!opt.def_cipher_algo)
     570             :     {
     571             :       /* Try to get it from the prefs.  */
     572          56 :       cfx.dek->algo = select_algo_from_prefs (pk_list, PREFTYPE_SYM, -1, NULL);
     573             :       /* The only way select_algo_from_prefs can fail here is when
     574             :          mixing v3 and v4 keys, as v4 keys have an implicit preference
     575             :          entry for 3DES, and the pk_list cannot be empty.  In this
     576             :          case, use 3DES anyway as it's the safest choice - perhaps the
     577             :          v3 key is being used in an OpenPGP implementation and we know
     578             :          that the implementation behind any v4 key can handle 3DES. */
     579          56 :       if (cfx.dek->algo == -1)
     580             :         {
     581           0 :           cfx.dek->algo = CIPHER_ALGO_3DES;
     582             :         }
     583             : 
     584             :       /* In case 3DES has been selected, print a warning if any key
     585             :          does not have a preference for AES.  This should help to
     586             :          indentify why encrypting to several recipients falls back to
     587             :          3DES. */
     588          56 :       if (opt.verbose && cfx.dek->algo == CIPHER_ALGO_3DES)
     589           0 :         warn_missing_aes_from_pklist (pk_list);
     590             :     }
     591             :   else
     592             :     {
     593         154 :       if (!opt.expert
     594         308 :           && (select_algo_from_prefs (pk_list, PREFTYPE_SYM,
     595             :                                       opt.def_cipher_algo, NULL)
     596         154 :               != opt.def_cipher_algo))
     597             :         {
     598         182 :           log_info(_("WARNING: forcing symmetric cipher %s (%d)"
     599             :                      " violates recipient preferences\n"),
     600          91 :                    openpgp_cipher_algo_name (opt.def_cipher_algo),
     601             :                    opt.def_cipher_algo);
     602             :         }
     603             : 
     604         154 :       cfx.dek->algo = opt.def_cipher_algo;
     605             :     }
     606             : 
     607         210 :   cfx.dek->use_mdc = use_mdc (pk_list,cfx.dek->algo);
     608             : 
     609             :   /* Only do the is-file-already-compressed check if we are using a
     610             :      MDC.  This forces compressed files to be re-compressed if we do
     611             :      not have a MDC to give some protection against chosen ciphertext
     612             :      attacks. */
     613             : 
     614         210 :   if (do_compress && cfx.dek->use_mdc && is_file_compressed(filename, &rc2))
     615             :     {
     616           0 :       if (opt.verbose)
     617           0 :         log_info(_("'%s' already compressed\n"), filename);
     618           0 :       do_compress = 0;
     619             :     }
     620         210 :   if (rc2)
     621             :     {
     622           0 :       rc = rc2;
     623           0 :       goto leave;
     624             :     }
     625             : 
     626         210 :   make_session_key (cfx.dek);
     627         210 :   if (DBG_CRYPTO)
     628           0 :     log_printhex ("DEK is: ", cfx.dek->key, cfx.dek->keylen );
     629             : 
     630         210 :   rc = write_pubkey_enc_from_list (pk_list, cfx.dek, out);
     631         210 :   if (rc)
     632           0 :     goto leave;
     633             : 
     634             :   /* We put the passphrase (if any) after any public keys as this
     635             :      seems to be the most useful on the recipient side - there is no
     636             :      point in prompting a user for a passphrase if they have the
     637             :      secret key needed to decrypt.  */
     638         210 :   if(use_symkey && (rc = write_symkey_enc(symkey_s2k,symkey_dek,cfx.dek,out)))
     639           0 :     goto leave;
     640             : 
     641         210 :   if (!opt.no_literal)
     642         210 :     pt = setup_plaintext_name (filename, inp);
     643             : 
     644             :   /* Get the size of the file if possible, i.e., if it is a real file.  */
     645         210 :   if (filename && *filename
     646         196 :       && !iobuf_is_pipe_filename (filename) && !opt.textmode )
     647         196 :     {
     648             :       off_t tmpsize;
     649             :       int overflow;
     650             : 
     651         196 :       if ( !(tmpsize = iobuf_get_filelength(inp, &overflow))
     652           0 :            && !overflow && opt.verbose)
     653           0 :         log_info(_("WARNING: '%s' is an empty file\n"), filename );
     654             :       /* We can't encode the length of very large files because
     655             :          OpenPGP uses only 32 bit for file sizes.  So if the the size
     656             :          of a file is larger than 2^32 minus some bytes for packet
     657             :          headers, we switch to partial length encoding. */
     658         196 :       if (tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) )
     659         196 :         filesize = tmpsize;
     660             :       else
     661           0 :         filesize = 0;
     662             :     }
     663             :   else
     664          14 :     filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
     665             : 
     666         210 :   if (!opt.no_literal)
     667             :     {
     668         210 :       pt->timestamp = make_timestamp();
     669         210 :       pt->mode = opt.textmode ? 't' : 'b';
     670         210 :       pt->len = filesize;
     671         210 :       pt->new_ctb = !pt->len;
     672         210 :       pt->buf = inp;
     673         210 :       pkt.pkttype = PKT_PLAINTEXT;
     674         210 :       pkt.pkt.plaintext = pt;
     675         210 :       cfx.datalen = filesize && !do_compress? calc_packet_length( &pkt ) : 0;
     676             :     }
     677             :   else
     678           0 :     cfx.datalen = filesize && !do_compress ? filesize : 0;
     679             : 
     680             :   /* Register the cipher filter. */
     681         210 :   iobuf_push_filter (out, cipher_filter, &cfx);
     682             : 
     683             :   /* Register the compress filter. */
     684         210 :   if (do_compress)
     685             :     {
     686         210 :       int compr_algo = opt.compress_algo;
     687             : 
     688         210 :       if (compr_algo == -1)
     689             :         {
     690         210 :           compr_algo = select_algo_from_prefs (pk_list, PREFTYPE_ZIP, -1, NULL);
     691         210 :           if (compr_algo == -1)
     692           0 :             compr_algo = DEFAULT_COMPRESS_ALGO;
     693             :           /* Theoretically impossible to get here since uncompressed
     694             :              is implicit.  */
     695             :         }
     696           0 :       else if (!opt.expert
     697           0 :                && select_algo_from_prefs(pk_list, PREFTYPE_ZIP,
     698             :                                          compr_algo, NULL) != compr_algo)
     699             :         {
     700           0 :           log_info (_("WARNING: forcing compression algorithm %s (%d)"
     701             :                       " violates recipient preferences\n"),
     702             :                     compress_algo_to_string(compr_algo), compr_algo);
     703             :         }
     704             : 
     705             :       /* Algo 0 means no compression. */
     706         210 :       if (compr_algo)
     707             :         {
     708         210 :           if (cfx.dek && cfx.dek->use_mdc)
     709         175 :             zfx.new_ctb = 1;
     710         210 :           push_compress_filter (out,&zfx,compr_algo);
     711             :         }
     712             :     }
     713             : 
     714             :   /* Do the work. */
     715         210 :   if (!opt.no_literal)
     716             :     {
     717         210 :       if ((rc = build_packet( out, &pkt )))
     718           0 :         log_error ("build_packet failed: %s\n", gpg_strerror (rc));
     719             :     }
     720             :   else
     721             :     {
     722             :       /* User requested not to create a literal packet, so we copy the
     723             :          plain data. */
     724             :       byte copy_buffer[4096];
     725             :       int  bytes_copied;
     726           0 :       while ((bytes_copied = iobuf_read (inp, copy_buffer, 4096)) != -1)
     727             :         {
     728           0 :           rc = iobuf_write (out, copy_buffer, bytes_copied);
     729           0 :           if (rc)
     730             :             {
     731           0 :               log_error ("copying input to output failed: %s\n",
     732             :                          gpg_strerror (rc));
     733           0 :               break;
     734             :             }
     735             :         }
     736           0 :       wipememory (copy_buffer, 4096); /* Burn the buffer. */
     737             :     }
     738             : 
     739             :   /* Finish the stuff. */
     740             :  leave:
     741         210 :   iobuf_close (inp);
     742         210 :   if (rc)
     743           0 :     iobuf_cancel (out);
     744             :   else
     745             :     {
     746         210 :       iobuf_close (out); /* fixme: check returncode */
     747         210 :       write_status (STATUS_END_ENCRYPTION);
     748             :     }
     749         210 :   if (pt)
     750         210 :     pt->buf = NULL;
     751         210 :   free_packet (&pkt);
     752         210 :   xfree (cfx.dek);
     753         210 :   xfree (symkey_dek);
     754         210 :   xfree (symkey_s2k);
     755         210 :   if (!provided_keys)
     756         210 :     release_pk_list (pk_list);
     757         210 :   release_armor_context (afx);
     758         210 :   release_progress_context (pfx);
     759         210 :   return rc;
     760             : }
     761             : 
     762             : 
     763             : /*
     764             :  * Filter to do a complete public key encryption.
     765             :  */
     766             : int
     767         143 : encrypt_filter (void *opaque, int control,
     768             :                 iobuf_t a, byte *buf, size_t *ret_len)
     769             : {
     770         143 :   size_t size = *ret_len;
     771         143 :   encrypt_filter_context_t *efx = opaque;
     772         143 :   int rc = 0;
     773             : 
     774         143 :   if (control == IOBUFCTRL_UNDERFLOW) /* decrypt */
     775             :     {
     776           0 :       BUG(); /* not used */
     777             :     }
     778         143 :   else if ( control == IOBUFCTRL_FLUSH ) /* encrypt */
     779             :     {
     780          91 :       if ( !efx->header_okay )
     781             :         {
     782          26 :           efx->cfx.dek = xmalloc_secure_clear ( sizeof *efx->cfx.dek );
     783          26 :           if ( !opt.def_cipher_algo  )
     784             :             {
     785             :               /* Try to get it from the prefs. */
     786          52 :               efx->cfx.dek->algo =
     787          26 :                 select_algo_from_prefs (efx->pk_list, PREFTYPE_SYM, -1, NULL);
     788          26 :               if (efx->cfx.dek->algo == -1 )
     789             :                 {
     790             :                   /* Because 3DES is implicitly in the prefs, this can
     791             :                      only happen if we do not have any public keys in
     792             :                      the list.  */
     793           0 :                   efx->cfx.dek->algo = DEFAULT_CIPHER_ALGO;
     794             :                 }
     795             : 
     796             :               /* In case 3DES has been selected, print a warning if
     797             :                  any key does not have a preference for AES.  This
     798             :                  should help to indentify why encrypting to several
     799             :                  recipients falls back to 3DES. */
     800          26 :               if (opt.verbose
     801           0 :                   && efx->cfx.dek->algo == CIPHER_ALGO_3DES)
     802           0 :                 warn_missing_aes_from_pklist (efx->pk_list);
     803             :             }
     804             :           else
     805             :             {
     806           0 :               if (!opt.expert
     807           0 :                   && select_algo_from_prefs (efx->pk_list,PREFTYPE_SYM,
     808             :                                              opt.def_cipher_algo,
     809           0 :                                              NULL) != opt.def_cipher_algo)
     810           0 :                 log_info(_("forcing symmetric cipher %s (%d) "
     811             :                            "violates recipient preferences\n"),
     812           0 :                          openpgp_cipher_algo_name (opt.def_cipher_algo),
     813             :                          opt.def_cipher_algo);
     814             : 
     815           0 :               efx->cfx.dek->algo = opt.def_cipher_algo;
     816             :             }
     817             : 
     818          26 :           efx->cfx.dek->use_mdc = use_mdc (efx->pk_list,efx->cfx.dek->algo);
     819             : 
     820          26 :           make_session_key ( efx->cfx.dek );
     821          26 :           if (DBG_CRYPTO)
     822           0 :             log_printhex ("DEK is: ", efx->cfx.dek->key, efx->cfx.dek->keylen);
     823             : 
     824          26 :           rc = write_pubkey_enc_from_list (efx->pk_list, efx->cfx.dek, a);
     825          26 :           if (rc)
     826           0 :             return rc;
     827             : 
     828          26 :             if(efx->symkey_s2k && efx->symkey_dek)
     829             :               {
     830           0 :                 rc=write_symkey_enc(efx->symkey_s2k,efx->symkey_dek,
     831             :                                     efx->cfx.dek,a);
     832           0 :                 if(rc)
     833           0 :                   return rc;
     834             :               }
     835             : 
     836          26 :             iobuf_push_filter (a, cipher_filter, &efx->cfx);
     837             : 
     838          26 :             efx->header_okay = 1;
     839             :         }
     840          91 :       rc = iobuf_write (a, buf, size);
     841             : 
     842             :     }
     843          52 :   else if (control == IOBUFCTRL_FREE)
     844             :     {
     845          26 :       xfree (efx->symkey_dek);
     846          26 :       xfree (efx->symkey_s2k);
     847             :     }
     848          26 :   else if ( control == IOBUFCTRL_DESC )
     849             :     {
     850           0 :       *(char**)buf = "encrypt_filter";
     851             :     }
     852         143 :   return rc;
     853             : }
     854             : 
     855             : 
     856             : /*
     857             :  * Write pubkey-enc packets from the list of PKs to OUT.
     858             :  */
     859             : static int
     860         236 : write_pubkey_enc_from_list (PK_LIST pk_list, DEK *dek, iobuf_t out)
     861             : {
     862             :   PACKET pkt;
     863             :   PKT_public_key *pk;
     864             :   PKT_pubkey_enc  *enc;
     865             :   int rc;
     866             : 
     867         472 :   for ( ; pk_list; pk_list = pk_list->next )
     868             :     {
     869             :       gcry_mpi_t frame;
     870             : 
     871         236 :       pk = pk_list->pk;
     872             : 
     873         236 :       print_pubkey_algo_note ( pk->pubkey_algo );
     874         236 :       enc = xmalloc_clear ( sizeof *enc );
     875         236 :       enc->pubkey_algo = pk->pubkey_algo;
     876         236 :       keyid_from_pk( pk, enc->keyid );
     877         236 :       enc->throw_keyid = (opt.throw_keyids || (pk_list->flags&1));
     878             : 
     879         236 :       if (opt.throw_keyids && (PGP6 || PGP7 || PGP8))
     880             :         {
     881           0 :           log_info(_("you may not use %s while in %s mode\n"),
     882             :                    "--throw-keyids",compliance_option_string());
     883           0 :           compliance_failure();
     884             :         }
     885             : 
     886             :       /* Okay, what's going on: We have the session key somewhere in
     887             :        * the structure DEK and want to encode this session key in an
     888             :        * integer value of n bits. pubkey_nbits gives us the number of
     889             :        * bits we have to use.  We then encode the session key in some
     890             :        * way and we get it back in the big intger value FRAME.  Then
     891             :        * we use FRAME, the public key PK->PKEY and the algorithm
     892             :        * number PK->PUBKEY_ALGO and pass it to pubkey_encrypt which
     893             :        * returns the encrypted value in the array ENC->DATA.  This
     894             :        * array has a size which depends on the used algorithm (e.g. 2
     895             :        * for Elgamal).  We don't need frame anymore because we have
     896             :        * everything now in enc->data which is the passed to
     897             :        * build_packet().  */
     898         236 :       frame = encode_session_key (pk->pubkey_algo, dek,
     899         236 :                                   pubkey_nbits (pk->pubkey_algo, pk->pkey));
     900         236 :       rc = pk_encrypt (pk->pubkey_algo, enc->data, frame, pk, pk->pkey);
     901         236 :       gcry_mpi_release (frame);
     902         236 :       if (rc)
     903           0 :         log_error ("pubkey_encrypt failed: %s\n", gpg_strerror (rc) );
     904             :       else
     905             :         {
     906         236 :           if ( opt.verbose )
     907             :             {
     908           0 :               char *ustr = get_user_id_string_native (enc->keyid);
     909           0 :               log_info (_("%s/%s encrypted for: \"%s\"\n"),
     910           0 :                         openpgp_pk_algo_name (enc->pubkey_algo),
     911           0 :                         openpgp_cipher_algo_name (dek->algo),
     912             :                         ustr );
     913           0 :               xfree (ustr);
     914             :             }
     915             :           /* And write it. */
     916         236 :           init_packet (&pkt);
     917         236 :           pkt.pkttype = PKT_PUBKEY_ENC;
     918         236 :           pkt.pkt.pubkey_enc = enc;
     919         236 :           rc = build_packet (out, &pkt);
     920         236 :           if (rc)
     921           0 :             log_error ("build_packet(pubkey_enc) failed: %s\n",
     922             :                        gpg_strerror (rc));
     923             :         }
     924         236 :       free_pubkey_enc(enc);
     925         236 :       if (rc)
     926           0 :         return rc;
     927             :     }
     928         236 :   return 0;
     929             : }
     930             : 
     931             : 
     932             : void
     933           0 : encrypt_crypt_files (ctrl_t ctrl, int nfiles, char **files, strlist_t remusr)
     934             : {
     935           0 :   int rc = 0;
     936             : 
     937           0 :   if (opt.outfile)
     938             :     {
     939           0 :       log_error(_("--output doesn't work for this command\n"));
     940           0 :       return;
     941             :     }
     942             : 
     943           0 :   if (!nfiles)
     944             :     {
     945             :       char line[2048];
     946           0 :       unsigned int lno = 0;
     947           0 :       while ( fgets(line, DIM(line), stdin) )
     948             :         {
     949           0 :           lno++;
     950           0 :           if (!*line || line[strlen(line)-1] != '\n')
     951             :             {
     952           0 :               log_error("input line %u too long or missing LF\n", lno);
     953           0 :               return;
     954             :             }
     955           0 :           line[strlen(line)-1] = '\0';
     956           0 :           print_file_status(STATUS_FILE_START, line, 2);
     957           0 :           rc = encrypt_crypt (ctrl, -1, line, remusr, 0, NULL, -1);
     958           0 :           if (rc)
     959           0 :             log_error ("encryption of '%s' failed: %s\n",
     960             :                        print_fname_stdin(line), gpg_strerror (rc) );
     961           0 :           write_status( STATUS_FILE_DONE );
     962             :         }
     963             :     }
     964             :   else
     965             :     {
     966           0 :       while (nfiles--)
     967             :         {
     968           0 :           print_file_status(STATUS_FILE_START, *files, 2);
     969           0 :           if ( (rc = encrypt_crypt (ctrl, -1, *files, remusr, 0, NULL, -1)) )
     970           0 :             log_error("encryption of '%s' failed: %s\n",
     971             :                       print_fname_stdin(*files), gpg_strerror (rc) );
     972           0 :           write_status( STATUS_FILE_DONE );
     973           0 :           files++;
     974             :         }
     975             :     }
     976             : }

Generated by: LCOV version 1.11