(show_key_with_all_names): Print the card S/N.
[gnupg.git] / g10 / encode.c
1 /* encode.c - encode data
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002,
3  *               2003 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 2 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, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #include <config.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <assert.h>
28
29 #include "gpg.h"
30 #include "options.h"
31 #include "packet.h"
32 #include "errors.h"
33 #include "iobuf.h"
34 #include "keydb.h"
35 #include "memory.h"
36 #include "util.h"
37 #include "main.h"
38 #include "filter.h"
39 #include "trustdb.h"
40 #include "i18n.h"
41 #include "status.h"
42 #include "pkglue.h"
43
44
45 static int encode_simple( const char *filename, int mode, int compat );
46 static int write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, iobuf_t out );
47
48
49
50 /****************
51  * Encode FILENAME with only the symmetric cipher.  Take input from
52  * stdin if FILENAME is NULL.
53  */
54 int
55 encode_symmetric( const char *filename )
56 {
57     int compat = 1;
58
59 #if 0    
60     /* We don't want to use it because older gnupg version can't
61        handle it and we can presume that a lot of scripts are running
62        with the expert mode set.  Some time in the future we might
63        want to allow for it. */
64     if ( opt.expert )
65         compat = 0; /* PGP knows how to handle this mode. */
66 #endif
67     return encode_simple( filename, 1, compat );
68 }
69
70 /****************
71  * Encode FILENAME as a literal data packet only. Take input from
72  * stdin if FILENAME is NULL.
73  */
74 int
75 encode_store( const char *filename )
76 {
77     return encode_simple( filename, 0, 1 );
78 }
79
80 static void
81 encode_sesskey (DEK * dek, DEK ** ret_dek, byte * enckey)
82 {
83   CIPHER_HANDLE hd;
84   DEK * c;
85   byte buf[33];
86
87   assert (dek->keylen < 32);
88     
89   c = xcalloc (1, sizeof *c);
90   c->keylen = dek->keylen;
91   c->algo = dek->algo;
92   make_session_key (c);
93   /*log_hexdump ("thekey", c->key, c->keylen);*/
94
95   /* the encrypted session key is prefixed with a one-octet algorithm id */
96   buf[0] = c->algo;
97   memcpy (buf + 1, c->key, c->keylen);
98     
99   /* due to the fact that we use only checked values, consider each
100      failure as fatal. */
101   if (gcry_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, 1))
102     BUG();
103   if (gcry_cipher_setkey (hd, dek->key, dek->keylen))
104     BUG();
105   gcry_cipher_setiv (hd, NULL, 0);
106   gcry_cipher_encrypt (hd, buf, c->keylen + 1, NULL, 0);
107   gcry_cipher_close (hd);
108
109   memcpy (enckey, buf, c->keylen + 1);
110   wipememory (buf, sizeof buf); /* burn key */
111   *ret_dek = c;
112 }
113
114 /* We try very hard to use a MDC */
115 static int
116 use_mdc (PK_LIST pk_list,int algo)
117 {
118   byte cipher_algid[4] = {
119     CIPHER_ALGO_AES,
120     CIPHER_ALGO_AES192,
121     CIPHER_ALGO_AES256,
122     CIPHER_ALGO_TWOFISH
123   };
124   int i;
125
126   /* RFC-1991 and 2440 don't have MDC */
127   if(RFC1991 || RFC2440)
128     return 0;
129   
130   /* --force-mdc overrides --disable-mdc */
131   if (opt.force_mdc)
132     return 1;
133
134   if (opt.disable_mdc)
135     return 0;
136
137   /* Do the keys really support MDC? */
138
139   if (select_mdc_from_pklist (pk_list))
140     return 1;
141   
142   /* The keys don't support MDC, so now we do a bit of a hack - if any
143      of the AESes or TWOFISH are in the prefs, we assume that the user
144      can handle a MDC.  This is valid for PGP 7, which can handle MDCs
145      though it will not generate them.  2440bis allows this, by the
146      way. */
147   for (i=0; i < DIM (cipher_algid); i++)
148     {
149       if (select_algo_from_prefs (pk_list, PREFTYPE_SYM, cipher_algid[i],
150                                   NULL) == cipher_algid[i])
151         return 1;
152     }
153
154   /* Last try.  Use MDC for the modern ciphers. */
155   if (gcry_cipher_get_algo_blklen (algo) != 8)
156     return 1;
157
158   return 0; /* No MDC */
159 }
160
161 static int
162 encode_simple( const char *filename, int mode, int compat )
163 {
164     iobuf_t inp, out;
165     PACKET pkt;
166     DEK *dek = NULL;
167     PKT_plaintext *pt = NULL;
168     STRING2KEY *s2k = NULL;
169     byte enckey[33];
170     int rc = 0;
171     int seskeylen = 0;
172     u32 filesize;
173     cipher_filter_context_t cfx;
174     armor_filter_context_t afx;
175     compress_filter_context_t zfx;
176     text_filter_context_t tfx;
177     progress_filter_context_t pfx;
178     int do_compress = opt.compress && !RFC1991;
179
180     memset( &cfx, 0, sizeof cfx);
181     memset( &afx, 0, sizeof afx);
182     memset( &zfx, 0, sizeof zfx);
183     memset( &tfx, 0, sizeof tfx);
184     init_packet(&pkt);
185     
186     /* prepare iobufs */
187     if( !(inp = iobuf_open(filename)) ) {
188         rc = gpg_error_from_errno (errno);
189         log_error(_("%s: can't open: %s\n"), filename? filename: "[stdin]",
190                                         strerror(errno) );
191         return rc;
192     }
193
194     handle_progress (&pfx, inp, filename);
195
196     if( opt.textmode )
197         iobuf_push_filter( inp, text_filter, &tfx );
198
199     /* Due the the fact that we use don't use an IV to encrypt the
200        session key we can't use the new mode with RFC1991 because
201        it has no S2K salt. RFC1991 always uses simple S2K. */
202     if ( RFC1991 && !compat )
203         compat = 1;
204     
205     cfx.dek = NULL;
206     if( mode ) {
207         s2k = xcalloc (1, sizeof *s2k );
208         s2k->mode = RFC1991? 0:opt.s2k_mode;
209         s2k->hash_algo = opt.s2k_digest_algo;
210         cfx.dek = passphrase_to_dek( NULL, 0,
211                                      default_cipher_algo(), s2k, 2,
212                                      NULL, NULL);
213         if( !cfx.dek || !cfx.dek->keylen ) {
214             rc = gpg_error (GPG_ERR_INV_PASSPHRASE);
215             xfree (cfx.dek);
216             xfree (s2k);
217             iobuf_close(inp);
218             log_error(_("error creating passphrase: %s\n"), gpg_strerror (rc) );
219             return rc;
220         }
221         if (!compat && s2k->mode != 1 && s2k->mode != 3) {
222             compat = 1;
223             log_info (_("can't use a symmetric ESK packet "
224                         "due to the S2K mode\n"));
225         }
226
227         if ( !compat ) {            
228             seskeylen = gcry_cipher_get_algo_keylen (default_cipher_algo());
229             encode_sesskey( cfx.dek, &dek, enckey );
230             xfree (cfx.dek); cfx.dek = dek;
231         }
232
233         cfx.dek->use_mdc=use_mdc(NULL,cfx.dek->algo);
234     }
235
236     if (opt.compress == -1 && cfx.dek && cfx.dek->use_mdc &&
237         is_file_compressed(filename, &rc))
238       {
239         if (opt.verbose)
240           log_info(_("`%s' already compressed\n"), filename);
241         do_compress = 0;        
242       }
243
244     if( rc || (rc = open_outfile( filename, opt.armor? 1:0, &out )) ) {
245         iobuf_cancel(inp);
246         xfree (cfx.dek);
247         xfree (s2k);
248         return rc;
249     }
250
251     if( opt.armor )
252         iobuf_push_filter( out, armor_filter, &afx );
253 #ifdef ENABLE_COMMENT_PACKETS
254     else {
255         write_comment( out, "#created by GNUPG v" VERSION " ("
256                                             PRINTABLE_OS_NAME ")");
257         if( opt.comment_string )
258             write_comment( out, opt.comment_string );
259     }
260 #endif
261     if( s2k && !RFC1991 ) {
262         PKT_symkey_enc *enc = xcalloc (1, sizeof *enc + seskeylen + 1 );
263         enc->version = 4;
264         enc->cipher_algo = cfx.dek->algo;
265         enc->s2k = *s2k;
266         if ( !compat && seskeylen ) {
267             enc->seskeylen = seskeylen + 1; /* algo id */
268             memcpy( enc->seskey, enckey, seskeylen + 1 );
269         }
270         pkt.pkttype = PKT_SYMKEY_ENC;
271         pkt.pkt.symkey_enc = enc;
272         if( (rc = build_packet( out, &pkt )) )
273             log_error("build symkey packet failed: %s\n", gpg_strerror (rc) );
274         xfree (enc);
275     }
276
277     if (!opt.no_literal) {
278         /* setup the inner packet */
279         if( filename || opt.set_filename ) {
280             char *s = make_basename ( opt.set_filename ? opt.set_filename
281                                                       : filename
282                                       /* for riscos?
283                                          .iobuf_get_real_fname( inp ) */
284                                       );
285             pt = xmalloc ( sizeof *pt + strlen(s) - 1 );
286             pt->namelen = strlen(s);
287             memcpy(pt->name, s, pt->namelen );
288             xfree (s);
289         }
290         else { /* no filename */
291             pt = xmalloc ( sizeof *pt - 1 );
292             pt->namelen = 0;
293         }
294     }
295
296     /* Note that PGP 5 has problems decrypting symmetrically encrypted
297        data if the file length is in the inner packet. It works when
298        only partial length headers are use.  In the past, we always
299        used partial body length here, but since PGP 2, PGP 6, and PGP
300        7 need the file length, and nobody should be using PGP 5
301        nowadays anyway, this is now set to the file length.  Note also
302        that this only applies to the RFC-1991 style symmetric
303        messages, and not the RFC-2440 style.  PGP 6 and 7 work with
304        either partial length or fixed length with the new style
305        messages. */
306
307     if (filename && *filename && !(*filename == '-' && !filename[1])
308         && !opt.textmode ) {
309         off_t tmpsize;
310
311         if ( !(tmpsize = iobuf_get_filelength(inp)) )
312           log_info(_("%s: WARNING: empty file\n"), filename );
313         /* We can't encode the length of very large files because
314            OpenPGP uses only 32 bit for file sizes.  So if the the
315            size of a file is larger than 2^32 minus some bytes for
316            packet headers, we switch to partial length encoding. */
317         if ( tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) )
318           filesize = tmpsize;
319         else
320           filesize = 0;
321     }
322     else
323         filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
324
325     if (!opt.no_literal) {
326         pt->timestamp = make_timestamp();
327         pt->mode = opt.textmode? 't' : 'b';
328         pt->len = filesize;
329         pt->new_ctb = !pt->len && !RFC1991;
330         pt->buf = inp;
331         pkt.pkttype = PKT_PLAINTEXT;
332         pkt.pkt.plaintext = pt;
333         cfx.datalen = filesize && !do_compress ? calc_packet_length( &pkt ) : 0;
334     }
335     else
336       {
337         cfx.datalen = filesize && !do_compress ? filesize : 0;
338         pkt.pkttype = 0;
339         pkt.pkt.generic = NULL;
340       }
341
342     /* register the cipher filter */
343     if( mode )
344         iobuf_push_filter( out, cipher_filter, &cfx );
345     /* register the compress filter */
346     if( do_compress )
347       {
348         if (cfx.dek && cfx.dek->use_mdc)
349           zfx.new_ctb = 1;
350         zfx.algo=default_compress_algo();
351         iobuf_push_filter( out, compress_filter, &zfx );
352       }
353
354     /* do the work */
355     if (!opt.no_literal) {
356         if( (rc = build_packet( out, &pkt )) )
357             log_error("build_packet failed: %s\n", gpg_strerror (rc) );
358     }
359     else {
360         /* user requested not to create a literal packet,
361          * so we copy the plain data */
362         byte copy_buffer[4096];
363         int  bytes_copied;
364         while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
365             if ( (rc=iobuf_write(out, copy_buffer, bytes_copied))) {
366                 log_error("copying input to output failed: %s\n", gpg_strerror (rc) );
367                 break;
368             }
369         wipememory(copy_buffer, 4096); /* burn buffer */
370     }
371
372     /* finish the stuff */
373     iobuf_close(inp);
374     if (rc)
375         iobuf_cancel(out);
376     else {
377         iobuf_close(out); /* fixme: check returncode */
378         if (mode)
379             write_status( STATUS_END_ENCRYPTION );
380     }
381     if (pt)
382         pt->buf = NULL;
383     free_packet(&pkt);
384     xfree (cfx.dek);
385     xfree (s2k);
386     return rc;
387 }
388
389 /****************
390  * Encrypt the file with the given userids (or ask if none
391  * is supplied).
392  */
393 int
394 encode_crypt( const char *filename, STRLIST remusr )
395 {
396     iobuf_t inp = NULL, out = NULL;
397     PACKET pkt;
398     PKT_plaintext *pt = NULL;
399     int rc = 0, rc2 = 0;
400     u32 filesize;
401     cipher_filter_context_t cfx;
402     armor_filter_context_t afx;
403     compress_filter_context_t zfx;
404     text_filter_context_t tfx;
405     progress_filter_context_t pfx;
406     PK_LIST pk_list,work_list;
407     int do_compress = opt.compress && !RFC1991;
408
409
410     memset( &cfx, 0, sizeof cfx);
411     memset( &afx, 0, sizeof afx);
412     memset( &zfx, 0, sizeof zfx);
413     memset( &tfx, 0, sizeof tfx);
414     init_packet(&pkt);
415
416     if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC)) )
417         return rc;
418
419     if(PGP2) {
420       for(work_list=pk_list; work_list; work_list=work_list->next)
421         if(!(is_RSA(work_list->pk->pubkey_algo) &&
422              nbits_from_pk(work_list->pk)<=2048))
423           {
424             log_info(_("you can only encrypt to RSA keys of 2048 bits or "
425                        "less in --pgp2 mode\n"));
426             compliance_failure();
427             break;
428           }
429     }
430
431     /* prepare iobufs */
432     if( !(inp = iobuf_open(filename)) ) {
433         rc = gpg_error_from_errno (errno);
434         log_error(_("can't open %s: %s\n"), filename? filename: "[stdin]",
435                                         strerror(errno) );
436         goto leave;
437     }
438     else if( opt.verbose )
439         log_info(_("reading from `%s'\n"), filename? filename: "[stdin]");
440
441     handle_progress (&pfx, inp, filename);
442
443     if( opt.textmode )
444         iobuf_push_filter( inp, text_filter, &tfx );
445
446     if( (rc = open_outfile( filename, opt.armor? 1:0, &out )) )
447         goto leave;
448
449
450     if( opt.armor )
451         iobuf_push_filter( out, armor_filter, &afx );
452 #ifdef ENABLE_COMMENT_PACKETS
453     else {
454         write_comment( out, "#created by GNUPG v" VERSION " ("
455                                             PRINTABLE_OS_NAME ")");
456         if( opt.comment_string )
457             write_comment( out, opt.comment_string );
458     }
459 #endif
460     /* create a session key */
461     cfx.dek = xcalloc_secure (1, sizeof *cfx.dek);
462     if( !opt.def_cipher_algo ) { /* try to get it from the prefs */
463         cfx.dek->algo = select_algo_from_prefs(pk_list,PREFTYPE_SYM,-1,NULL);
464         /* The only way select_algo_from_prefs can fail here is when
465            mixing v3 and v4 keys, as v4 keys have an implicit
466            preference entry for 3DES, and the pk_list cannot be empty.
467            In this case, use 3DES anyway as it's the safest choice -
468            perhaps the v3 key is being used in an OpenPGP
469            implementation and we know that the implementation behind
470            any v4 key can handle 3DES. */
471         if( cfx.dek->algo == -1 ) {
472             cfx.dek->algo = CIPHER_ALGO_3DES;
473
474             if( PGP2 ) {
475               log_info(_("unable to use the IDEA cipher for all of the keys "
476                          "you are encrypting to.\n"));
477               compliance_failure();
478             }
479         }
480     }
481     else {
482       if(!opt.expert &&
483          select_algo_from_prefs(pk_list,PREFTYPE_SYM,
484                                 opt.def_cipher_algo,NULL)!=opt.def_cipher_algo)
485         log_info(_("forcing symmetric cipher %s (%d) "
486                    "violates recipient preferences\n"),
487                  gcry_cipher_algo_name (opt.def_cipher_algo),
488                  opt.def_cipher_algo);
489
490       cfx.dek->algo = opt.def_cipher_algo;
491     }
492
493     cfx.dek->use_mdc=use_mdc(pk_list,cfx.dek->algo);
494
495     /* Only do the is-file-already-compressed check if we are using a
496        MDC.  This forces compressed files to be re-compressed if we do
497        not have a MDC to give some protection against chosen
498        ciphertext attacks. */
499
500     if (opt.compress == -1 && cfx.dek->use_mdc &&
501         is_file_compressed(filename, &rc2) )
502       {
503         if (opt.verbose)
504           log_info(_("`%s' already compressed\n"), filename);
505         do_compress = 0;        
506       }
507     if (rc2)
508       {
509         rc = rc2;
510         goto leave;
511       }
512
513     make_session_key( cfx.dek );
514     if( DBG_CIPHER )
515         log_printhex ("DEK is: ", cfx.dek->key, cfx.dek->keylen );
516
517     rc = write_pubkey_enc_from_list( pk_list, cfx.dek, out );
518     if( rc  )
519         goto leave;
520
521     if (!opt.no_literal) {
522         /* setup the inner packet */
523         if( filename || opt.set_filename ) {
524             char *s = make_basename( opt.set_filename ? opt.set_filename
525                                                       : filename
526                                      /* ,iobuf_get_real_fname( inp )*/ );
527             pt = xmalloc ( sizeof *pt + strlen(s) - 1 );
528             pt->namelen = strlen(s);
529             memcpy(pt->name, s, pt->namelen );
530             xfree (s);
531         }
532         else { /* no filename */
533             pt = xmalloc ( sizeof *pt - 1 );
534             pt->namelen = 0;
535         }
536     }
537
538     if (filename && *filename && !(*filename == '-' && !filename[1])
539         && !opt.textmode ) {
540         off_t tmpsize;
541
542         if ( !(tmpsize = iobuf_get_filelength(inp)) )
543           log_info(_("%s: WARNING: empty file\n"), filename );
544         /* We can't encode the length of very large files because
545            OpenPGP uses only 32 bit for file sizes.  So if the the
546            size of a file is larger than 2^32 minus some bytes for
547            packet headers, we switch to partial length encoding. */
548         if ( tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) )
549           filesize = tmpsize;
550         else
551           filesize = 0;
552     }
553     else
554         filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
555
556     if (!opt.no_literal) {
557         pt->timestamp = make_timestamp();
558         pt->mode = opt.textmode ? 't' : 'b';
559         pt->len = filesize;
560         pt->new_ctb = !pt->len && !RFC1991;
561         pt->buf = inp;
562         pkt.pkttype = PKT_PLAINTEXT;
563         pkt.pkt.plaintext = pt;
564         cfx.datalen = filesize && !do_compress? calc_packet_length( &pkt ) : 0;
565     }
566     else
567         cfx.datalen = filesize && !do_compress ? filesize : 0;
568
569     /* register the cipher filter */
570     iobuf_push_filter( out, cipher_filter, &cfx );
571
572     /* register the compress filter */
573     if( do_compress ) {
574         int compr_algo = opt.def_compress_algo;
575
576         if(compr_algo==-1)
577           {
578             if((compr_algo=
579                 select_algo_from_prefs(pk_list,PREFTYPE_ZIP,-1,NULL))==-1)
580               compr_algo=DEFAULT_COMPRESS_ALGO;
581             /* Theoretically impossible to get here since uncompressed
582                is implicit. */
583           }
584         else if(!opt.expert &&
585                 select_algo_from_prefs(pk_list,PREFTYPE_ZIP,
586                                        compr_algo,NULL)!=compr_algo)
587           log_info(_("forcing compression algorithm %s (%d) "
588                      "violates recipient preferences\n"),
589                    compress_algo_to_string(compr_algo),compr_algo);
590
591         /* algo 0 means no compression */
592         if( compr_algo )
593           {
594             if (cfx.dek && cfx.dek->use_mdc)
595               zfx.new_ctb = 1;
596             zfx.algo = compr_algo;
597             iobuf_push_filter( out, compress_filter, &zfx );
598           }
599     }
600
601     /* do the work */
602     if (!opt.no_literal) {
603         if( (rc = build_packet( out, &pkt )) )
604             log_error("build_packet failed: %s\n", gpg_strerror (rc) );
605     }
606     else {
607         /* user requested not to create a literal packet, so we copy
608            the plain data */
609         byte copy_buffer[4096];
610         int  bytes_copied;
611         while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
612             if ((rc=iobuf_write(out, copy_buffer, bytes_copied))) {
613                 log_error("copying input to output failed: %s\n",
614                           gpg_strerror (rc) );
615                 break;
616             }
617         wipememory(copy_buffer, 4096); /* burn buffer */
618     }
619
620     /* finish the stuff */
621   leave:
622     iobuf_close(inp);
623     if( rc )
624         iobuf_cancel(out);
625     else {
626         iobuf_close(out); /* fixme: check returncode */
627         write_status( STATUS_END_ENCRYPTION );
628     }
629     if( pt )
630         pt->buf = NULL;
631     free_packet(&pkt);
632     xfree (cfx.dek);
633     release_pk_list( pk_list );
634     return rc;
635 }
636
637
638
639
640 /****************
641  * Filter to do a complete public key encryption.
642  */
643 int
644 encrypt_filter( void *opaque, int control,
645                iobuf_t a, byte *buf, size_t *ret_len)
646 {
647     size_t size = *ret_len;
648     encrypt_filter_context_t *efx = opaque;
649     int rc=0;
650
651     if( control == IOBUFCTRL_UNDERFLOW ) { /* decrypt */
652         BUG(); /* not used */
653     }
654     else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */
655         if( !efx->header_okay ) {
656             efx->cfx.dek = xcalloc_secure (1, sizeof *efx->cfx.dek );
657
658             if( !opt.def_cipher_algo  ) { /* try to get it from the prefs */
659                 efx->cfx.dek->algo =
660                   select_algo_from_prefs(efx->pk_list,PREFTYPE_SYM,-1,NULL);
661                 if( efx->cfx.dek->algo == -1 ) {
662                     /* because 3DES is implicitly in the prefs, this can only
663                      * happen if we do not have any public keys in the list */
664                     efx->cfx.dek->algo = DEFAULT_CIPHER_ALGO;
665                 }
666             }
667             else {
668               if(!opt.expert &&
669                  select_algo_from_prefs(efx->pk_list,PREFTYPE_SYM,
670                                         opt.def_cipher_algo,
671                                         NULL)!=opt.def_cipher_algo)
672                 log_info(_("forcing symmetric cipher %s (%d) "
673                            "violates recipient preferences\n"),
674                          gcry_cipher_algo_name (opt.def_cipher_algo),
675                          opt.def_cipher_algo);
676
677               efx->cfx.dek->algo = opt.def_cipher_algo;
678             }
679
680             efx->cfx.dek->use_mdc = use_mdc(efx->pk_list,efx->cfx.dek->algo);
681
682             make_session_key( efx->cfx.dek );
683             if( DBG_CIPHER )
684                 log_printhex ("DEK is: ",
685                               efx->cfx.dek->key, efx->cfx.dek->keylen );
686
687             rc = write_pubkey_enc_from_list( efx->pk_list, efx->cfx.dek, a );
688             if( rc )
689                 return rc;
690
691             iobuf_push_filter( a, cipher_filter, &efx->cfx );
692
693             efx->header_okay = 1;
694         }
695         rc = iobuf_write( a, buf, size );
696
697     }
698     else if( control == IOBUFCTRL_FREE ) {
699     }
700     else if( control == IOBUFCTRL_DESC ) {
701         *(char**)buf = "encrypt_filter";
702     }
703     return rc;
704 }
705
706
707 /****************
708  * Write pubkey-enc packets from the list of PKs to OUT.
709  */
710 static int
711 write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, iobuf_t out )
712 {
713     PACKET pkt;
714     PKT_public_key *pk;
715     PKT_pubkey_enc  *enc;
716     int rc;
717
718     for( ; pk_list; pk_list = pk_list->next ) {
719         gcry_mpi_t frame;
720
721         pk = pk_list->pk;
722
723         print_pubkey_algo_note( pk->pubkey_algo );
724         enc = xcalloc (1, sizeof *enc );
725         enc->pubkey_algo = pk->pubkey_algo;
726         keyid_from_pk( pk, enc->keyid );
727         enc->throw_keyid = (opt.throw_keyid || (pk_list->flags&1));
728
729         if(opt.throw_keyid && (PGP2 || PGP6 || PGP7 || PGP8))
730           {
731             log_info(_("you may not use %s while in %s mode\n"),
732                      "--throw-keyid",compliance_option_string());
733             compliance_failure();
734           }
735
736         /* Okay, what's going on: We have the session key somewhere in
737          * the structure DEK and want to encode this session key in
738          * an integer value of n bits.  pubkey_nbits gives us the
739          * number of bits we have to use.  We then encode the session
740          * key in some way and we get it back in the big intger value
741          * FRAME.  Then we use FRAME, the public key PK->PKEY and the
742          * algorithm number PK->PUBKEY_ALGO and pass it to pubkey_encrypt
743          * which returns the encrypted value in the array ENC->DATA.
744          * This array has a size which depends on the used algorithm
745          * (e.g. 2 for ElGamal).  We don't need frame anymore because we
746          * have everything now in enc->data which is the passed to
747          * build_packet()
748          */
749         frame = encode_session_key( dek, pubkey_nbits( pk->pubkey_algo,
750                                                           pk->pkey ) );
751         rc = pk_encrypt( pk->pubkey_algo, enc->data, frame, pk->pkey );
752         gcry_mpi_release ( frame );
753         if( rc )
754             log_error("pubkey_encrypt failed: %s\n", gpg_strerror (rc) );
755         else {
756             if( opt.verbose ) {
757                 char *ustr = get_user_id_string_printable (enc->keyid);
758                 log_info(_("%s/%s encrypted for: \"%s\"\n"),
759                     gcry_pk_algo_name (enc->pubkey_algo),
760                     gcry_cipher_algo_name (dek->algo), ustr );
761                 xfree (ustr);
762             }
763             /* and write it */
764             init_packet(&pkt);
765             pkt.pkttype = PKT_PUBKEY_ENC;
766             pkt.pkt.pubkey_enc = enc;
767             rc = build_packet( out, &pkt );
768             if( rc )
769                log_error("build_packet(pubkey_enc) failed: %s\n", gpg_strerror (rc));
770         }
771         free_pubkey_enc(enc);
772         if( rc )
773             return rc;
774     }
775     return 0;
776 }
777
778 void
779 encode_crypt_files(int nfiles, char **files, STRLIST remusr)
780 {
781   int rc = 0;
782
783   if (opt.outfile)
784     {
785       log_error(_("--output doesn't work for this command\n"));
786       return;        
787     }
788     
789   if (!nfiles)
790     {
791       char line[2048];
792       unsigned int lno = 0;
793       while ( fgets(line, DIM(line), stdin) )
794         {
795           lno++;
796           if (!*line || line[strlen(line)-1] != '\n')
797             {
798               log_error("input line %u too long or missing LF\n", lno);
799               return;
800             }
801           line[strlen(line)-1] = '\0';
802           print_file_status(STATUS_FILE_START, line, 2);
803           if ( (rc = encode_crypt(line, remusr)) )
804             log_error("%s: encryption failed: %s\n",
805                       print_fname_stdin(line), gpg_strerror (rc) );
806           write_status( STATUS_FILE_DONE );
807         }
808     }
809   else
810     {
811       while (nfiles--)
812         {
813           print_file_status(STATUS_FILE_START, *files, 2);
814           if ( (rc = encode_crypt(*files, remusr)) )
815             log_error("%s: encryption failed: %s\n",
816                       print_fname_stdin(*files), gpg_strerror (rc) );
817           write_status( STATUS_FILE_DONE );
818           files++;
819         }
820     }
821 }