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