Update head to match stable 1.0
[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 ( opt.expert )
56         compat = 0; /* PGP knows how to handle this mode. */
57     return encode_simple( filename, 1, compat );
58 }
59
60 /****************
61  * Encode FILENAME as a literal data packet only. Take input from
62  * stdin if FILENAME is NULL.
63  */
64 int
65 encode_store( const char *filename )
66 {
67     return encode_simple( filename, 0, 1 );
68 }
69
70 static void
71 encode_sesskey( DEK *dek, DEK **ret_dek, byte *enckey )
72 {
73     CIPHER_HANDLE hd;
74     DEK *c;
75     byte buf[33];
76
77     assert ( dek->keylen < 32 );
78     
79     c = m_alloc_clear( sizeof *c );
80     c->keylen = dek->keylen;
81     c->algo = dek->algo;
82     make_session_key( c );
83     /*log_hexdump( "thekey", c->key, c->keylen );*/
84
85     buf[0] = c->algo;
86     memcpy( buf + 1, c->key, c->keylen );
87     
88     hd = cipher_open( dek->algo, CIPHER_MODE_CFB, 1 );
89     cipher_setkey( hd, dek->key, dek->keylen );
90     cipher_setiv( hd, NULL, 0 );
91     cipher_encrypt( hd, buf, buf, c->keylen + 1 );
92     cipher_close( hd );
93
94     memcpy( enckey, buf, c->keylen + 1 );
95     memset( buf, 0, sizeof buf ); /* burn key */
96     *ret_dek = c;
97 }
98
99 static int
100 encode_simple( const char *filename, int mode, int compat )
101 {
102     IOBUF inp, out;
103     PACKET pkt;
104     DEK *dek = NULL;
105     PKT_plaintext *pt = NULL;
106     STRING2KEY *s2k = NULL;
107     byte enckey[33];
108     int rc = 0;
109     int seskeylen = 0;
110     u32 filesize;
111     cipher_filter_context_t cfx;
112     armor_filter_context_t afx;
113     compress_filter_context_t zfx;
114     text_filter_context_t tfx;
115     int do_compress = opt.compress && !opt.rfc1991;
116
117     memset( &cfx, 0, sizeof cfx);
118     memset( &afx, 0, sizeof afx);
119     memset( &zfx, 0, sizeof zfx);
120     memset( &tfx, 0, sizeof tfx);
121     init_packet(&pkt);
122     
123     if (opt.compress == -1 && is_file_compressed(filename, &rc))
124       {
125         if (opt.verbose)
126           log_info(_("`%s' already compressed\n"), filename);
127         do_compress = 0;        
128       }
129     if (rc)
130         return rc;
131
132     /* prepare iobufs */
133     if( !(inp = iobuf_open(filename)) ) {
134         log_error(_("%s: can't open: %s\n"), filename? filename: "[stdin]",
135                                         strerror(errno) );
136         return G10ERR_OPEN_FILE;
137     }
138
139     if( opt.textmode )
140         iobuf_push_filter( inp, text_filter, &tfx );
141
142     /* Due the the fact that we use don't use an IV to encrypt the
143        session key we can't use the new mode with RFC1991 because
144        it has no S2K salt. RFC1991 always uses simple S2K. */
145     if ( opt.rfc1991 && !compat )
146         compat = 1;
147     
148     cfx.dek = NULL;
149     if( mode ) {
150         s2k = m_alloc_clear( sizeof *s2k );
151         s2k->mode = opt.rfc1991? 0:opt.s2k_mode;
152         s2k->hash_algo = opt.def_digest_algo ? opt.def_digest_algo
153                                              : opt.s2k_digest_algo;
154         cfx.dek = passphrase_to_dek( NULL, 0,
155                   opt.def_cipher_algo ? opt.def_cipher_algo
156                                       : opt.s2k_cipher_algo , s2k, 2, NULL );
157         if( !cfx.dek || !cfx.dek->keylen ) {
158             rc = G10ERR_PASSPHRASE;
159             m_free(cfx.dek);
160             m_free(s2k);
161             iobuf_close(inp);
162             log_error(_("error creating passphrase: %s\n"), g10_errstr(rc) );
163             return rc;
164         }
165         if ( !compat ) {            
166             seskeylen = cipher_get_keylen( opt.def_cipher_algo ?
167                                            opt.def_cipher_algo:
168                                            opt.s2k_cipher_algo ) / 8;
169             encode_sesskey( cfx.dek, &dek, enckey );
170             m_free( cfx.dek ); cfx.dek = dek;
171         }
172     }
173
174     if( (rc = open_outfile( filename, opt.armor? 1:0, &out )) ) {
175         iobuf_cancel(inp);
176         m_free(cfx.dek);
177         m_free(s2k);
178         return rc;
179     }
180
181     if( opt.armor )
182         iobuf_push_filter( out, armor_filter, &afx );
183   #ifdef ENABLE_COMMENT_PACKETS
184     else {
185         write_comment( out, "#created by GNUPG v" VERSION " ("
186                                             PRINTABLE_OS_NAME ")");
187         if( opt.comment_string )
188             write_comment( out, opt.comment_string );
189     }
190   #endif
191     if( s2k && !opt.rfc1991 ) {
192         PKT_symkey_enc *enc = m_alloc_clear( sizeof *enc + seskeylen + 1 );
193         enc->version = 4;
194         enc->cipher_algo = cfx.dek->algo;
195         enc->s2k = *s2k;
196         if ( !compat && seskeylen ) {
197             enc->seskeylen = seskeylen + 1; /* algo id */
198             memcpy( enc->seskey, enckey, seskeylen + 1 );
199         }
200         pkt.pkttype = PKT_SYMKEY_ENC;
201         pkt.pkt.symkey_enc = enc;
202         if( (rc = build_packet( out, &pkt )) )
203             log_error("build symkey packet failed: %s\n", g10_errstr(rc) );
204         m_free(enc);
205     }
206
207     if (!opt.no_literal) {
208         /* setup the inner packet */
209         if( filename || opt.set_filename ) {
210             char *s = make_basename( opt.set_filename ? opt.set_filename
211                                                       : filename );
212             pt = m_alloc( sizeof *pt + strlen(s) - 1 );
213             pt->namelen = strlen(s);
214             memcpy(pt->name, s, pt->namelen );
215             m_free(s);
216         }
217         else { /* no filename */
218             pt = m_alloc( sizeof *pt - 1 );
219             pt->namelen = 0;
220         }
221     }
222
223     /* Note that PGP 5 has problems decrypting symmetrically encrypted
224        data if the file length is in the inner packet. It works when
225        only partial length headers are use.  In the past, we always
226        used partial body length here, but since PGP 2, PGP 6, and PGP
227        7 need the file length, and nobody should be using PGP 5
228        nowadays anyway, this is now set to the file length.  Note also
229        that this only applies to the RFC-1991 style symmetric
230        messages, and not the RFC-2440 style.  PGP 6 and 7 work with
231        either partial length or fixed length with the new style
232        messages. */
233
234     if( filename && !opt.textmode ) {
235         if( !(filesize = iobuf_get_filelength(inp)) )
236             log_info(_("%s: WARNING: empty file\n"), filename );
237         /* we can't yet encode the length of very large files,
238          * so we switch to partial lengthn encoding in this case */
239         if ( filesize >= IOBUF_FILELENGTH_LIMIT )
240             filesize = 0;
241
242     }
243     else
244         filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
245
246     if (!opt.no_literal) {
247         pt->timestamp = make_timestamp();
248         pt->mode = opt.textmode? 't' : 'b';
249         pt->len = filesize;
250         pt->new_ctb = !pt->len && !opt.rfc1991;
251         pt->buf = inp;
252         pkt.pkttype = PKT_PLAINTEXT;
253         pkt.pkt.plaintext = pt;
254         cfx.datalen = filesize && !do_compress ? calc_packet_length( &pkt ) : 0;
255     }
256     else
257       {
258         cfx.datalen = filesize && !do_compress ? filesize : 0;
259         pkt.pkttype = 0;
260         pkt.pkt.generic = NULL;
261       }
262
263     /* register the cipher filter */
264     if( mode )
265         iobuf_push_filter( out, cipher_filter, &cfx );
266     /* register the compress filter */
267     if( do_compress )
268         iobuf_push_filter( out, compress_filter, &zfx );
269
270     /* do the work */
271     if (!opt.no_literal) {
272         if( (rc = build_packet( out, &pkt )) )
273             log_error("build_packet failed: %s\n", g10_errstr(rc) );
274     }
275     else {
276         /* user requested not to create a literal packet,
277          * so we copy the plain data */
278         byte copy_buffer[4096];
279         int  bytes_copied;
280         while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
281             if (iobuf_write(out, copy_buffer, bytes_copied) == -1) {
282                 rc = G10ERR_WRITE_FILE;
283                 log_error("copying input to output failed: %s\n", g10_errstr(rc) );
284                 break;
285             }
286         memset(copy_buffer, 0, 4096); /* burn buffer */
287     }
288
289     /* finish the stuff */
290     iobuf_close(inp);
291     if (rc)
292         iobuf_cancel(out);
293     else {
294         iobuf_close(out); /* fixme: check returncode */
295         if (mode)
296             write_status( STATUS_END_ENCRYPTION );
297     }
298     if (pt)
299         pt->buf = NULL;
300     free_packet(&pkt);
301     m_free(cfx.dek);
302     m_free(s2k);
303     return rc;
304 }
305
306 /****************
307  * Encrypt the file with the given userids (or ask if none
308  * is supplied).
309  */
310 int
311 encode_crypt( const char *filename, STRLIST remusr )
312 {
313     IOBUF inp = NULL, out = NULL;
314     PACKET pkt;
315     PKT_plaintext *pt = NULL;
316     int rc = 0, rc2 = 0;
317     u32 filesize;
318     cipher_filter_context_t cfx;
319     armor_filter_context_t afx;
320     compress_filter_context_t zfx;
321     text_filter_context_t tfx;
322     PK_LIST pk_list,work_list;
323     int do_compress = opt.compress && !opt.rfc1991;
324
325
326     memset( &cfx, 0, sizeof cfx);
327     memset( &afx, 0, sizeof afx);
328     memset( &zfx, 0, sizeof zfx);
329     memset( &tfx, 0, sizeof tfx);
330     init_packet(&pkt);
331
332     if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC)) )
333         return rc;
334
335     if(opt.pgp2) {
336       for(work_list=pk_list; work_list; work_list=work_list->next)
337         if(!(is_RSA(work_list->pk->pubkey_algo) &&
338              nbits_from_pk(work_list->pk)<=2048))
339           {
340             log_info(_("you can only encrypt to RSA keys of 2048 bits or "
341                        "less in --pgp2 mode\n"));
342             log_info(_("this message may not be usable by PGP 2.x\n"));
343             opt.pgp2=0;
344             break;
345           }
346     }
347
348     if (opt.compress == -1 && is_file_compressed(filename, &rc2))
349       {
350         if (opt.verbose)
351           log_info(_("`%s' already compressed\n"), filename);
352         do_compress = 0;        
353       }
354     if (rc2)
355       {
356         rc = rc2;
357         goto leave;
358       }
359     
360     /* prepare iobufs */
361     if( !(inp = iobuf_open(filename)) ) {
362         log_error(_("can't open %s: %s\n"), filename? filename: "[stdin]",
363                                         strerror(errno) );
364         rc = G10ERR_OPEN_FILE;
365         goto leave;
366     }
367     else if( opt.verbose )
368         log_info(_("reading from `%s'\n"), filename? filename: "[stdin]");
369
370     if( opt.textmode )
371         iobuf_push_filter( inp, text_filter, &tfx );
372
373     if( (rc = open_outfile( filename, opt.armor? 1:0, &out )) )
374         goto leave;
375
376
377     if( opt.armor )
378         iobuf_push_filter( out, armor_filter, &afx );
379   #ifdef ENABLE_COMMENT_PACKETS
380     else {
381         write_comment( out, "#created by GNUPG v" VERSION " ("
382                                             PRINTABLE_OS_NAME ")");
383         if( opt.comment_string )
384             write_comment( out, opt.comment_string );
385     }
386   #endif
387     /* create a session key */
388     cfx.dek = m_alloc_secure_clear (sizeof *cfx.dek);
389     if( !opt.def_cipher_algo ) { /* try to get it from the prefs */
390         cfx.dek->algo = select_algo_from_prefs(pk_list,PREFTYPE_SYM,-1,NULL);
391         /* The only way select_algo_from_prefs can fail here is when
392            mixing v3 and v4 keys, as v4 keys have an implicit
393            preference entry for 3DES, and the pk_list cannot be empty.
394            In this case, use 3DES anyway as it's the safest choice -
395            perhaps the v3 key is being used in an OpenPGP
396            implementation and we know that the implementation behind
397            any v4 key can handle 3DES. */
398         if( cfx.dek->algo == -1 ) {
399             cfx.dek->algo = CIPHER_ALGO_3DES;
400
401             if( opt.pgp2 ) {
402               log_info(_("unable to use the IDEA cipher for all of the keys "
403                          "you are encrypting to.\n"));
404               log_info(_("this message may not be usable by PGP 2.x\n"));
405               opt.pgp2=0;
406             }
407         }
408     }
409     else {
410       if(!opt.expert &&
411          select_algo_from_prefs(pk_list,PREFTYPE_SYM,
412                                 opt.def_cipher_algo,NULL)!=opt.def_cipher_algo)
413         log_info(_("forcing symmetric cipher %s (%d) "
414                    "violates recipient preferences\n"),
415                  cipher_algo_to_string(opt.def_cipher_algo),
416                  opt.def_cipher_algo);
417
418       cfx.dek->algo = opt.def_cipher_algo;
419     }
420     cfx.dek->use_mdc = select_mdc_from_pklist (pk_list);
421
422     make_session_key( cfx.dek );
423     if( DBG_CIPHER )
424         log_hexdump("DEK is: ", cfx.dek->key, cfx.dek->keylen );
425
426     rc = write_pubkey_enc_from_list( pk_list, cfx.dek, out );
427     if( rc  )
428         goto leave;
429
430     if (!opt.no_literal) {
431         /* setup the inner packet */
432         if( filename || opt.set_filename ) {
433             char *s = make_basename( opt.set_filename ? opt.set_filename : filename );
434             pt = m_alloc( sizeof *pt + strlen(s) - 1 );
435             pt->namelen = strlen(s);
436             memcpy(pt->name, s, pt->namelen );
437             m_free(s);
438         }
439         else { /* no filename */
440             pt = m_alloc( sizeof *pt - 1 );
441             pt->namelen = 0;
442         }
443     }
444
445     if( filename && !opt.textmode ) {
446         if( !(filesize = iobuf_get_filelength(inp)) )
447             log_info(_("%s: WARNING: empty file\n"), filename );
448         /* we can't yet encode the length of very large files,
449          * so we switch to partial length encoding in this case */
450         if ( filesize >= IOBUF_FILELENGTH_LIMIT )
451             filesize = 0;
452     }
453     else
454         filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
455
456     if (!opt.no_literal) {
457         pt->timestamp = make_timestamp();
458         pt->mode = opt.textmode ? 't' : 'b';
459         pt->len = filesize;
460         pt->new_ctb = !pt->len && !opt.rfc1991;
461         pt->buf = inp;
462         pkt.pkttype = PKT_PLAINTEXT;
463         pkt.pkt.plaintext = pt;
464         cfx.datalen = filesize && !do_compress? calc_packet_length( &pkt ) : 0;
465     }
466     else
467         cfx.datalen = filesize && !do_compress ? filesize : 0;
468
469     /* register the cipher filter */
470     iobuf_push_filter( out, cipher_filter, &cfx );
471
472     /* register the compress filter */
473     if( do_compress ) {
474         int compr_algo = opt.def_compress_algo;
475
476         if(compr_algo==-1)
477           {
478             if((compr_algo=
479                 select_algo_from_prefs(pk_list,PREFTYPE_ZIP,-1,NULL))==-1)
480               compr_algo=DEFAULT_COMPRESS_ALGO;
481           }
482         else if(!opt.expert &&
483                 select_algo_from_prefs(pk_list,PREFTYPE_ZIP,
484                                        compr_algo,NULL)!=compr_algo)
485           log_info(_("forcing compression algorithm %s (%d) "
486                      "violates recipient preferences\n"),
487                    compress_algo_to_string(compr_algo),compr_algo);
488
489         /* algo 0 means no compression */
490         if( compr_algo )
491           {
492             zfx.algo = compr_algo;
493             iobuf_push_filter( out, compress_filter, &zfx );
494           }
495     }
496
497     /* do the work */
498     if (!opt.no_literal) {
499         if( (rc = build_packet( out, &pkt )) )
500             log_error("build_packet failed: %s\n", g10_errstr(rc) );
501     }
502     else {
503         /* user requested not to create a literal packet, so we copy the plain data */
504         byte copy_buffer[4096];
505         int  bytes_copied;
506         while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
507             if (iobuf_write(out, copy_buffer, bytes_copied) == -1) {
508                 rc = G10ERR_WRITE_FILE;
509                 log_error("copying input to output failed: %s\n", g10_errstr(rc) );
510                 break;
511             }
512         memset(copy_buffer, 0, 4096); /* burn buffer */
513     }
514
515     /* finish the stuff */
516   leave:
517     iobuf_close(inp);
518     if( rc )
519         iobuf_cancel(out);
520     else {
521         iobuf_close(out); /* fixme: check returncode */
522         write_status( STATUS_END_ENCRYPTION );
523     }
524     if( pt )
525         pt->buf = NULL;
526     free_packet(&pkt);
527     m_free(cfx.dek);
528     release_pk_list( pk_list );
529     return rc;
530 }
531
532
533
534
535 /****************
536  * Filter to do a complete public key encryption.
537  */
538 int
539 encrypt_filter( void *opaque, int control,
540                IOBUF a, byte *buf, size_t *ret_len)
541 {
542     size_t size = *ret_len;
543     encrypt_filter_context_t *efx = opaque;
544     int rc=0;
545
546     if( control == IOBUFCTRL_UNDERFLOW ) { /* decrypt */
547         BUG(); /* not used */
548     }
549     else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */
550         if( !efx->header_okay ) {
551             efx->cfx.dek = m_alloc_secure_clear( sizeof *efx->cfx.dek );
552
553             if( !opt.def_cipher_algo  ) { /* try to get it from the prefs */
554                 efx->cfx.dek->algo =
555                   select_algo_from_prefs(efx->pk_list,PREFTYPE_SYM,-1,NULL);
556                 if( efx->cfx.dek->algo == -1 ) {
557                     /* because 3DES is implicitly in the prefs, this can only
558                      * happen if we do not have any public keys in the list */
559                     efx->cfx.dek->algo = DEFAULT_CIPHER_ALGO;
560                 }
561             }
562             else {
563               if(!opt.expert &&
564                  select_algo_from_prefs(efx->pk_list,PREFTYPE_SYM,
565                                         opt.def_cipher_algo,
566                                         NULL)!=opt.def_cipher_algo)
567                 log_info(_("forcing symmetric cipher %s (%d) "
568                            "violates recipient preferences\n"),
569                          cipher_algo_to_string(opt.def_cipher_algo),
570                          opt.def_cipher_algo);
571
572               efx->cfx.dek->algo = opt.def_cipher_algo;
573             }
574
575             efx->cfx.dek->use_mdc = select_mdc_from_pklist (efx->pk_list);
576
577             make_session_key( efx->cfx.dek );
578             if( DBG_CIPHER )
579                 log_hexdump("DEK is: ",
580                              efx->cfx.dek->key, efx->cfx.dek->keylen );
581
582             rc = write_pubkey_enc_from_list( efx->pk_list, efx->cfx.dek, a );
583             if( rc )
584                 return rc;
585
586             iobuf_push_filter( a, cipher_filter, &efx->cfx );
587
588             efx->header_okay = 1;
589         }
590         rc = iobuf_write( a, buf, size );
591
592     }
593     else if( control == IOBUFCTRL_FREE ) {
594     }
595     else if( control == IOBUFCTRL_DESC ) {
596         *(char**)buf = "encrypt_filter";
597     }
598     return rc;
599 }
600
601
602 /****************
603  * Write pubkey-enc packets from the list of PKs to OUT.
604  */
605 static int
606 write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out )
607 {
608     PACKET pkt;
609     PKT_public_key *pk;
610     PKT_pubkey_enc  *enc;
611     int rc;
612
613     for( ; pk_list; pk_list = pk_list->next ) {
614         MPI frame;
615
616         pk = pk_list->pk;
617
618         print_pubkey_algo_note( pk->pubkey_algo );
619         enc = m_alloc_clear( sizeof *enc );
620         enc->pubkey_algo = pk->pubkey_algo;
621         keyid_from_pk( pk, enc->keyid );
622         enc->throw_keyid = opt.throw_keyid;
623
624         /* Okay, what's going on: We have the session key somewhere in
625          * the structure DEK and want to encode this session key in
626          * an integer value of n bits.  pubkey_nbits gives us the
627          * number of bits we have to use.  We then encode the session
628          * key in some way and we get it back in the big intger value
629          * FRAME.  Then we use FRAME, the public key PK->PKEY and the
630          * algorithm number PK->PUBKEY_ALGO and pass it to pubkey_encrypt
631          * which returns the encrypted value in the array ENC->DATA.
632          * This array has a size which depends on the used algorithm
633          * (e.g. 2 for ElGamal).  We don't need frame anymore because we
634          * have everything now in enc->data which is the passed to
635          * build_packet()
636          */
637         frame = encode_session_key( dek, pubkey_nbits( pk->pubkey_algo,
638                                                           pk->pkey ) );
639         rc = pubkey_encrypt( pk->pubkey_algo, enc->data, frame, pk->pkey );
640         mpi_free( frame );
641         if( rc )
642             log_error("pubkey_encrypt failed: %s\n", g10_errstr(rc) );
643         else {
644             if( opt.verbose ) {
645                 char *ustr = get_user_id_string_native( enc->keyid );
646                 log_info(_("%s/%s encrypted for: %s\n"),
647                     pubkey_algo_to_string(enc->pubkey_algo),
648                     cipher_algo_to_string(dek->algo), ustr );
649                 m_free(ustr);
650             }
651             /* and write it */
652             init_packet(&pkt);
653             pkt.pkttype = PKT_PUBKEY_ENC;
654             pkt.pkt.pubkey_enc = enc;
655             rc = build_packet( out, &pkt );
656             if( rc )
657                log_error("build_packet(pubkey_enc) failed: %s\n", g10_errstr(rc));
658         }
659         free_pubkey_enc(enc);
660         if( rc )
661             return rc;
662     }
663     return 0;
664 }
665
666 void
667 encode_crypt_files(int nfiles, char **files, STRLIST remusr)
668 {
669   int rc = 0;
670
671   if (opt.outfile)
672     {
673       log_error(_("--output doesn't work for this command\n"));
674       return;        
675     }
676     
677   if (!nfiles)
678     {
679       char line[2048];
680       unsigned int lno = 0;
681       while ( fgets(line, DIM(line), stdin) )
682         {
683           lno++;
684           if (!*line || line[strlen(line)-1] != '\n')
685             {
686               log_error("input line %u too long or missing LF\n", lno);
687               return;
688             }
689           line[strlen(line)-1] = '\0';
690           print_file_status(STATUS_FILE_START, line, 2);
691           if ( (rc = encode_crypt(line, remusr)) )
692             log_error("%s: encryption failed: %s\n",
693                       print_fname_stdin(line), g10_errstr(rc) );
694           write_status( STATUS_FILE_DONE );
695         }
696     }
697   else
698     {
699       while (nfiles--)
700         {
701           print_file_status(STATUS_FILE_START, *files, 2);
702           if ( (rc = encode_crypt(*files, remusr)) )
703             log_error("%s: encryption failed: %s\n",
704                       print_fname_stdin(*files), g10_errstr(rc) );
705           write_status( STATUS_FILE_DONE );
706           files++;
707         }
708     }
709 }