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