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