comment type fix
[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     memset( buf, 0, 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             pt = m_alloc( sizeof *pt + strlen(s) - 1 );
272             pt->namelen = strlen(s);
273             memcpy(pt->name, s, pt->namelen );
274             m_free(s);
275         }
276         else { /* no filename */
277             pt = m_alloc( sizeof *pt - 1 );
278             pt->namelen = 0;
279         }
280     }
281
282     /* Note that PGP 5 has problems decrypting symmetrically encrypted
283        data if the file length is in the inner packet. It works when
284        only partial length headers are use.  In the past, we always
285        used partial body length here, but since PGP 2, PGP 6, and PGP
286        7 need the file length, and nobody should be using PGP 5
287        nowadays anyway, this is now set to the file length.  Note also
288        that this only applies to the RFC-1991 style symmetric
289        messages, and not the RFC-2440 style.  PGP 6 and 7 work with
290        either partial length or fixed length with the new style
291        messages. */
292
293     if( filename && !opt.textmode ) {
294         if( !(filesize = iobuf_get_filelength(inp)) )
295             log_info(_("%s: WARNING: empty file\n"), filename );
296         /* we can't yet encode the length of very large files,
297          * so we switch to partial lengthn encoding in this case */
298         if ( filesize >= IOBUF_FILELENGTH_LIMIT )
299             filesize = 0;
300
301     }
302     else
303         filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
304
305     if (!opt.no_literal) {
306         pt->timestamp = make_timestamp();
307         pt->mode = opt.textmode? 't' : 'b';
308         pt->len = filesize;
309         pt->new_ctb = !pt->len && !opt.rfc1991;
310         pt->buf = inp;
311         pkt.pkttype = PKT_PLAINTEXT;
312         pkt.pkt.plaintext = pt;
313         cfx.datalen = filesize && !do_compress ? calc_packet_length( &pkt ) : 0;
314     }
315     else
316       {
317         cfx.datalen = filesize && !do_compress ? filesize : 0;
318         pkt.pkttype = 0;
319         pkt.pkt.generic = NULL;
320       }
321
322     /* register the cipher filter */
323     if( mode )
324         iobuf_push_filter( out, cipher_filter, &cfx );
325     /* register the compress filter */
326     if( do_compress )
327       {
328         if (cfx.dek && cfx.dek->use_mdc)
329           zfx.new_ctb = 1;
330         zfx.algo=opt.def_compress_algo;
331         if(zfx.algo==-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         memset(copy_buffer, 0, 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 : filename );
507             pt = m_alloc( sizeof *pt + strlen(s) - 1 );
508             pt->namelen = strlen(s);
509             memcpy(pt->name, s, pt->namelen );
510             m_free(s);
511         }
512         else { /* no filename */
513             pt = m_alloc( sizeof *pt - 1 );
514             pt->namelen = 0;
515         }
516     }
517
518     if( filename && !opt.textmode ) {
519         if( !(filesize = iobuf_get_filelength(inp)) )
520             log_info(_("%s: WARNING: empty file\n"), filename );
521         /* we can't yet encode the length of very large files,
522          * so we switch to partial length encoding in this case */
523         if ( filesize >= IOBUF_FILELENGTH_LIMIT )
524             filesize = 0;
525     }
526     else
527         filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
528
529     if (!opt.no_literal) {
530         pt->timestamp = make_timestamp();
531         pt->mode = opt.textmode ? 't' : 'b';
532         pt->len = filesize;
533         pt->new_ctb = !pt->len && !opt.rfc1991;
534         pt->buf = inp;
535         pkt.pkttype = PKT_PLAINTEXT;
536         pkt.pkt.plaintext = pt;
537         cfx.datalen = filesize && !do_compress? calc_packet_length( &pkt ) : 0;
538     }
539     else
540         cfx.datalen = filesize && !do_compress ? filesize : 0;
541
542     /* register the cipher filter */
543     iobuf_push_filter( out, cipher_filter, &cfx );
544
545     /* register the compress filter */
546     if( do_compress ) {
547         int compr_algo = opt.def_compress_algo;
548
549         if(compr_algo==-1)
550           {
551             if((compr_algo=
552                 select_algo_from_prefs(pk_list,PREFTYPE_ZIP,-1,NULL))==-1)
553               compr_algo=DEFAULT_COMPRESS_ALGO;
554           }
555         else if(!opt.expert &&
556                 select_algo_from_prefs(pk_list,PREFTYPE_ZIP,
557                                        compr_algo,NULL)!=compr_algo)
558           log_info(_("forcing compression algorithm %s (%d) "
559                      "violates recipient preferences\n"),
560                    compress_algo_to_string(compr_algo),compr_algo);
561
562         /* algo 0 means no compression */
563         if( compr_algo )
564           {
565             if (cfx.dek && cfx.dek->use_mdc)
566               zfx.new_ctb = 1;
567             zfx.algo = compr_algo;
568             iobuf_push_filter( out, compress_filter, &zfx );
569           }
570     }
571
572     /* do the work */
573     if (!opt.no_literal) {
574         if( (rc = build_packet( out, &pkt )) )
575             log_error("build_packet failed: %s\n", g10_errstr(rc) );
576     }
577     else {
578         /* user requested not to create a literal packet, so we copy
579            the plain data */
580         byte copy_buffer[4096];
581         int  bytes_copied;
582         while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
583             if (iobuf_write(out, copy_buffer, bytes_copied) == -1) {
584                 rc = G10ERR_WRITE_FILE;
585                 log_error("copying input to output failed: %s\n",
586                           g10_errstr(rc) );
587                 break;
588             }
589         memset(copy_buffer, 0, 4096); /* burn buffer */
590     }
591
592     /* finish the stuff */
593   leave:
594     iobuf_close(inp);
595     if( rc )
596         iobuf_cancel(out);
597     else {
598         iobuf_close(out); /* fixme: check returncode */
599         write_status( STATUS_END_ENCRYPTION );
600     }
601     if( pt )
602         pt->buf = NULL;
603     free_packet(&pkt);
604     m_free(cfx.dek);
605     release_pk_list( pk_list );
606     return rc;
607 }
608
609
610
611
612 /****************
613  * Filter to do a complete public key encryption.
614  */
615 int
616 encrypt_filter( void *opaque, int control,
617                IOBUF a, byte *buf, size_t *ret_len)
618 {
619     size_t size = *ret_len;
620     encrypt_filter_context_t *efx = opaque;
621     int rc=0;
622
623     if( control == IOBUFCTRL_UNDERFLOW ) { /* decrypt */
624         BUG(); /* not used */
625     }
626     else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */
627         if( !efx->header_okay ) {
628             efx->cfx.dek = m_alloc_secure_clear( sizeof *efx->cfx.dek );
629
630             if( !opt.def_cipher_algo  ) { /* try to get it from the prefs */
631                 efx->cfx.dek->algo =
632                   select_algo_from_prefs(efx->pk_list,PREFTYPE_SYM,-1,NULL);
633                 if( efx->cfx.dek->algo == -1 ) {
634                     /* because 3DES is implicitly in the prefs, this can only
635                      * happen if we do not have any public keys in the list */
636                     efx->cfx.dek->algo = DEFAULT_CIPHER_ALGO;
637                 }
638             }
639             else {
640               if(!opt.expert &&
641                  select_algo_from_prefs(efx->pk_list,PREFTYPE_SYM,
642                                         opt.def_cipher_algo,
643                                         NULL)!=opt.def_cipher_algo)
644                 log_info(_("forcing symmetric cipher %s (%d) "
645                            "violates recipient preferences\n"),
646                          cipher_algo_to_string(opt.def_cipher_algo),
647                          opt.def_cipher_algo);
648
649               efx->cfx.dek->algo = opt.def_cipher_algo;
650             }
651
652             efx->cfx.dek->use_mdc = use_mdc(efx->pk_list,efx->cfx.dek->algo);
653
654             make_session_key( efx->cfx.dek );
655             if( DBG_CIPHER )
656                 log_hexdump("DEK is: ",
657                              efx->cfx.dek->key, efx->cfx.dek->keylen );
658
659             rc = write_pubkey_enc_from_list( efx->pk_list, efx->cfx.dek, a );
660             if( rc )
661                 return rc;
662
663             iobuf_push_filter( a, cipher_filter, &efx->cfx );
664
665             efx->header_okay = 1;
666         }
667         rc = iobuf_write( a, buf, size );
668
669     }
670     else if( control == IOBUFCTRL_FREE ) {
671     }
672     else if( control == IOBUFCTRL_DESC ) {
673         *(char**)buf = "encrypt_filter";
674     }
675     return rc;
676 }
677
678
679 /****************
680  * Write pubkey-enc packets from the list of PKs to OUT.
681  */
682 static int
683 write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out )
684 {
685     PACKET pkt;
686     PKT_public_key *pk;
687     PKT_pubkey_enc  *enc;
688     int rc;
689
690     for( ; pk_list; pk_list = pk_list->next ) {
691         MPI frame;
692
693         pk = pk_list->pk;
694
695         print_pubkey_algo_note( pk->pubkey_algo );
696         enc = m_alloc_clear( sizeof *enc );
697         enc->pubkey_algo = pk->pubkey_algo;
698         keyid_from_pk( pk, enc->keyid );
699         enc->throw_keyid = opt.throw_keyid;
700
701         if(opt.throw_keyid && (opt.pgp2 || opt.pgp6 || opt.pgp7))
702           {
703             log_info(_("you may not use %s while in %s mode\n"),
704                      "--throw-keyid",
705                      opt.pgp2?"--pgp2":opt.pgp6?"--pgp6":"--pgp7");
706
707             log_info(_("this message may not be usable by %s\n"),
708                      opt.pgp2?"PGP 2.x":opt.pgp6?"PGP 6.x":"PGP 7.x");
709
710             opt.pgp2=opt.pgp6=opt.pgp7=0;
711           }
712
713         /* Okay, what's going on: We have the session key somewhere in
714          * the structure DEK and want to encode this session key in
715          * an integer value of n bits.  pubkey_nbits gives us the
716          * number of bits we have to use.  We then encode the session
717          * key in some way and we get it back in the big intger value
718          * FRAME.  Then we use FRAME, the public key PK->PKEY and the
719          * algorithm number PK->PUBKEY_ALGO and pass it to pubkey_encrypt
720          * which returns the encrypted value in the array ENC->DATA.
721          * This array has a size which depends on the used algorithm
722          * (e.g. 2 for ElGamal).  We don't need frame anymore because we
723          * have everything now in enc->data which is the passed to
724          * build_packet()
725          */
726         frame = encode_session_key( dek, pubkey_nbits( pk->pubkey_algo,
727                                                           pk->pkey ) );
728         rc = pubkey_encrypt( pk->pubkey_algo, enc->data, frame, pk->pkey );
729         mpi_free( frame );
730         if( rc )
731             log_error("pubkey_encrypt failed: %s\n", g10_errstr(rc) );
732         else {
733             if( opt.verbose ) {
734                 char *ustr = get_user_id_string_printable (enc->keyid);
735                 log_info(_("%s/%s encrypted for: \"%s\"\n"),
736                     pubkey_algo_to_string(enc->pubkey_algo),
737                     cipher_algo_to_string(dek->algo), ustr );
738                 m_free(ustr);
739             }
740             /* and write it */
741             init_packet(&pkt);
742             pkt.pkttype = PKT_PUBKEY_ENC;
743             pkt.pkt.pubkey_enc = enc;
744             rc = build_packet( out, &pkt );
745             if( rc )
746                log_error("build_packet(pubkey_enc) failed: %s\n", g10_errstr(rc));
747         }
748         free_pubkey_enc(enc);
749         if( rc )
750             return rc;
751     }
752     return 0;
753 }
754
755 void
756 encode_crypt_files(int nfiles, char **files, STRLIST remusr)
757 {
758   int rc = 0;
759
760   if (opt.outfile)
761     {
762       log_error(_("--output doesn't work for this command\n"));
763       return;        
764     }
765     
766   if (!nfiles)
767     {
768       char line[2048];
769       unsigned int lno = 0;
770       while ( fgets(line, DIM(line), stdin) )
771         {
772           lno++;
773           if (!*line || line[strlen(line)-1] != '\n')
774             {
775               log_error("input line %u too long or missing LF\n", lno);
776               return;
777             }
778           line[strlen(line)-1] = '\0';
779           print_file_status(STATUS_FILE_START, line, 2);
780           if ( (rc = encode_crypt(line, remusr)) )
781             log_error("%s: encryption failed: %s\n",
782                       print_fname_stdin(line), g10_errstr(rc) );
783           write_status( STATUS_FILE_DONE );
784         }
785     }
786   else
787     {
788       while (nfiles--)
789         {
790           print_file_status(STATUS_FILE_START, *files, 2);
791           if ( (rc = encode_crypt(*files, remusr)) )
792             log_error("%s: encryption failed: %s\n",
793                       print_fname_stdin(*files), g10_errstr(rc) );
794           write_status( STATUS_FILE_DONE );
795           files++;
796         }
797     }
798 }