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