LCOV - code coverage report
Current view: top level - g10 - encrypt.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 292 450 64.9 %
Date: 2016-09-12 12:29:17 Functions: 10 12 83.3 %

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

Generated by: LCOV version 1.11