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