* misc.c (compress_algo_to_string, string_to_compress_algo,
[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         push_compress_filter(out,&zfx,opt.def_compress_algo);
336       }
337
338     /* do the work */
339     if (!opt.no_literal) {
340         if( (rc = build_packet( out, &pkt )) )
341             log_error("build_packet failed: %s\n", g10_errstr(rc) );
342     }
343     else {
344         /* user requested not to create a literal packet,
345          * so we copy the plain data */
346         byte copy_buffer[4096];
347         int  bytes_copied;
348         while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
349             if (iobuf_write(out, copy_buffer, bytes_copied) == -1) {
350                 rc = G10ERR_WRITE_FILE;
351                 log_error("copying input to output failed: %s\n", g10_errstr(rc) );
352                 break;
353             }
354         wipememory(copy_buffer, 4096); /* burn buffer */
355     }
356
357     /* finish the stuff */
358     iobuf_close(inp);
359     if (rc)
360         iobuf_cancel(out);
361     else {
362         iobuf_close(out); /* fixme: check returncode */
363         if (mode)
364             write_status( STATUS_END_ENCRYPTION );
365     }
366     if (pt)
367         pt->buf = NULL;
368     free_packet(&pkt);
369     m_free(cfx.dek);
370     m_free(s2k);
371     return rc;
372 }
373
374 /****************
375  * Encrypt the file with the given userids (or ask if none
376  * is supplied).
377  */
378 int
379 encode_crypt( const char *filename, STRLIST remusr, int use_symkey )
380 {
381     IOBUF inp = NULL, out = NULL;
382     PACKET pkt;
383     PKT_plaintext *pt = NULL;
384     DEK *symkey_dek = NULL;
385     STRING2KEY *symkey_s2k = NULL;
386     int rc = 0, rc2 = 0;
387     u32 filesize;
388     cipher_filter_context_t cfx;
389     armor_filter_context_t afx;
390     compress_filter_context_t zfx;
391     text_filter_context_t tfx;
392     progress_filter_context_t pfx;
393     PK_LIST pk_list,work_list;
394     int do_compress = opt.compress && !RFC1991;
395
396     memset( &cfx, 0, sizeof cfx);
397     memset( &afx, 0, sizeof afx);
398     memset( &zfx, 0, sizeof zfx);
399     memset( &tfx, 0, sizeof tfx);
400     init_packet(&pkt);
401
402     if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC)) )
403         return rc;
404
405     if(use_symkey)
406       {
407         symkey_s2k=m_alloc_clear(sizeof(STRING2KEY));
408         symkey_s2k->mode = opt.s2k_mode;
409         symkey_s2k->hash_algo = opt.s2k_digest_algo;
410
411         symkey_dek=passphrase_to_dek(NULL,0,opt.s2k_cipher_algo,
412                                      symkey_s2k,2,NULL,NULL);
413         if(!symkey_dek || !symkey_dek->keylen)
414           {
415             m_free(symkey_dek);
416             m_free(symkey_s2k);
417             return G10ERR_PASSPHRASE;
418           }
419       }
420
421     if(PGP2) {
422       for(work_list=pk_list; work_list; work_list=work_list->next)
423         if(!(is_RSA(work_list->pk->pubkey_algo) &&
424              nbits_from_pk(work_list->pk)<=2048))
425           {
426             log_info(_("you can only encrypt to RSA keys of 2048 bits or "
427                        "less in --pgp2 mode\n"));
428             compliance_failure();
429             break;
430           }
431     }
432
433     /* prepare iobufs */
434     if( !(inp = iobuf_open(filename)) ) {
435         log_error(_("can't open %s: %s\n"), filename? filename: "[stdin]",
436                                         strerror(errno) );
437         rc = G10ERR_OPEN_FILE;
438         goto leave;
439     }
440     else if( opt.verbose )
441         log_info(_("reading from `%s'\n"), filename? filename: "[stdin]");
442
443     handle_progress (&pfx, inp, filename);
444
445     if( opt.textmode )
446         iobuf_push_filter( inp, text_filter, &tfx );
447
448     if( (rc = open_outfile( filename, opt.armor? 1:0, &out )) )
449         goto leave;
450
451
452     if( opt.armor )
453         iobuf_push_filter( out, armor_filter, &afx );
454 #ifdef ENABLE_COMMENT_PACKETS
455     else {
456         write_comment( out, "#created by GNUPG v" VERSION " ("
457                                             PRINTABLE_OS_NAME ")");
458         if( opt.comment_string )
459             write_comment( out, opt.comment_string );
460     }
461 #endif
462     /* create a session key */
463     cfx.dek = m_alloc_secure_clear (sizeof *cfx.dek);
464     if( !opt.def_cipher_algo ) { /* try to get it from the prefs */
465         cfx.dek->algo = select_algo_from_prefs(pk_list,PREFTYPE_SYM,-1,NULL);
466         /* The only way select_algo_from_prefs can fail here is when
467            mixing v3 and v4 keys, as v4 keys have an implicit
468            preference entry for 3DES, and the pk_list cannot be empty.
469            In this case, use 3DES anyway as it's the safest choice -
470            perhaps the v3 key is being used in an OpenPGP
471            implementation and we know that the implementation behind
472            any v4 key can handle 3DES. */
473         if( cfx.dek->algo == -1 ) {
474             cfx.dek->algo = CIPHER_ALGO_3DES;
475
476             if( PGP2 ) {
477               log_info(_("unable to use the IDEA cipher for all of the keys "
478                          "you are encrypting to.\n"));
479               compliance_failure();
480             }
481         }
482     }
483     else {
484       if(!opt.expert &&
485          select_algo_from_prefs(pk_list,PREFTYPE_SYM,
486                                 opt.def_cipher_algo,NULL)!=opt.def_cipher_algo)
487         log_info(_("forcing symmetric cipher %s (%d) "
488                    "violates recipient preferences\n"),
489                  cipher_algo_to_string(opt.def_cipher_algo),
490                  opt.def_cipher_algo);
491
492       cfx.dek->algo = opt.def_cipher_algo;
493     }
494
495     cfx.dek->use_mdc=use_mdc(pk_list,cfx.dek->algo);
496
497     /* Only do the is-file-already-compressed check if we are using a
498        MDC.  This forces compressed files to be re-compressed if we do
499        not have a MDC to give some protection against chosen
500        ciphertext attacks. */
501
502     if (opt.compress == -1 && cfx.dek->use_mdc &&
503         is_file_compressed(filename, &rc2) )
504       {
505         if (opt.verbose)
506           log_info(_("`%s' already compressed\n"), filename);
507         do_compress = 0;        
508       }
509     if (rc2)
510       {
511         rc = rc2;
512         goto leave;
513       }
514
515     make_session_key( cfx.dek );
516     if( DBG_CIPHER )
517         log_hexdump("DEK is: ", cfx.dek->key, cfx.dek->keylen );
518
519     rc = write_pubkey_enc_from_list( pk_list, cfx.dek, out );
520     if( rc  )
521         goto leave;
522
523     /* We put the passphrase (if any) after any public keys as this
524        seems to be the most useful on the recipient side - there is no
525        point in prompting a user for a passphrase if they have the
526        secret key needed to decrypt. */
527     if(use_symkey)
528       {
529         int seskeylen=cipher_get_keylen(cfx.dek->algo)/8;
530         PKT_symkey_enc *enc;
531         byte enckey[33];
532
533         enc=m_alloc_clear(sizeof(PKT_symkey_enc)+seskeylen+1);
534         encode_seskey(symkey_dek,&cfx.dek,enckey);
535
536         enc->version = 4;
537         enc->cipher_algo = opt.s2k_cipher_algo;
538         enc->s2k = *symkey_s2k;
539         enc->seskeylen = seskeylen + 1; /* algo id */
540         memcpy( enc->seskey, enckey, seskeylen + 1 );
541
542         pkt.pkttype = PKT_SYMKEY_ENC;
543         pkt.pkt.symkey_enc = enc;
544         if( (rc = build_packet( out, &pkt )) )
545           {
546             log_error("build symkey packet failed: %s\n", g10_errstr(rc) );
547             m_free(enc);
548             goto leave;
549           }
550
551         m_free(enc);
552       }
553
554     if (!opt.no_literal) {
555         /* setup the inner packet */
556         if( filename || opt.set_filename ) {
557             char *s = make_basename( opt.set_filename ? opt.set_filename
558                                                       : filename,
559                                      iobuf_get_real_fname( inp ) );
560             pt = m_alloc( sizeof *pt + strlen(s) - 1 );
561             pt->namelen = strlen(s);
562             memcpy(pt->name, s, pt->namelen );
563             m_free(s);
564         }
565         else { /* no filename */
566             pt = m_alloc( sizeof *pt - 1 );
567             pt->namelen = 0;
568         }
569     }
570
571     if (filename && *filename && !(*filename == '-' && !filename[1])
572         && !opt.textmode ) {
573         off_t tmpsize;
574
575         if ( !(tmpsize = iobuf_get_filelength(inp)) )
576           log_info(_("%s: WARNING: empty file\n"), filename );
577         /* We can't encode the length of very large files because
578            OpenPGP uses only 32 bit for file sizes.  So if the the
579            size of a file is larger than 2^32 minus some bytes for
580            packet headers, we switch to partial length encoding. */
581         if ( tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) )
582           filesize = tmpsize;
583         else
584           filesize = 0;
585     }
586     else
587         filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
588
589     if (!opt.no_literal) {
590         pt->timestamp = make_timestamp();
591         pt->mode = opt.textmode ? 't' : 'b';
592         pt->len = filesize;
593         pt->new_ctb = !pt->len && !RFC1991;
594         pt->buf = inp;
595         pkt.pkttype = PKT_PLAINTEXT;
596         pkt.pkt.plaintext = pt;
597         cfx.datalen = filesize && !do_compress? calc_packet_length( &pkt ) : 0;
598     }
599     else
600         cfx.datalen = filesize && !do_compress ? filesize : 0;
601
602     /* register the cipher filter */
603     iobuf_push_filter( out, cipher_filter, &cfx );
604
605     /* register the compress filter */
606     if( do_compress ) {
607         int compr_algo = opt.def_compress_algo;
608
609         if(compr_algo==-1)
610           {
611             if((compr_algo=
612                 select_algo_from_prefs(pk_list,PREFTYPE_ZIP,-1,NULL))==-1)
613               compr_algo=DEFAULT_COMPRESS_ALGO;
614             /* Theoretically impossible to get here since uncompressed
615                is implicit. */
616           }
617         else if(!opt.expert &&
618                 select_algo_from_prefs(pk_list,PREFTYPE_ZIP,
619                                        compr_algo,NULL)!=compr_algo)
620           log_info(_("forcing compression algorithm %s (%d) "
621                      "violates recipient preferences\n"),
622                    compress_algo_to_string(compr_algo),compr_algo);
623
624         /* algo 0 means no compression */
625         if( compr_algo )
626           {
627             if (cfx.dek && cfx.dek->use_mdc)
628               zfx.new_ctb = 1;
629             push_compress_filter(out,&zfx,compr_algo);
630           }
631     }
632
633     /* do the work */
634     if (!opt.no_literal) {
635         if( (rc = build_packet( out, &pkt )) )
636             log_error("build_packet failed: %s\n", g10_errstr(rc) );
637     }
638     else {
639         /* user requested not to create a literal packet, so we copy
640            the plain data */
641         byte copy_buffer[4096];
642         int  bytes_copied;
643         while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
644             if (iobuf_write(out, copy_buffer, bytes_copied) == -1) {
645                 rc = G10ERR_WRITE_FILE;
646                 log_error("copying input to output failed: %s\n",
647                           g10_errstr(rc) );
648                 break;
649             }
650         wipememory(copy_buffer, 4096); /* burn buffer */
651     }
652
653     /* finish the stuff */
654   leave:
655     iobuf_close(inp);
656     if( rc )
657         iobuf_cancel(out);
658     else {
659         iobuf_close(out); /* fixme: check returncode */
660         write_status( STATUS_END_ENCRYPTION );
661     }
662     if( pt )
663         pt->buf = NULL;
664     free_packet(&pkt);
665     m_free(cfx.dek);
666     m_free(symkey_dek);
667     m_free(symkey_s2k);
668     release_pk_list( pk_list );
669     return rc;
670 }
671
672
673
674
675 /****************
676  * Filter to do a complete public key encryption.
677  */
678 int
679 encrypt_filter( void *opaque, int control,
680                IOBUF a, byte *buf, size_t *ret_len)
681 {
682     size_t size = *ret_len;
683     encrypt_filter_context_t *efx = opaque;
684     int rc=0;
685
686     if( control == IOBUFCTRL_UNDERFLOW ) { /* decrypt */
687         BUG(); /* not used */
688     }
689     else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */
690         if( !efx->header_okay ) {
691             efx->cfx.dek = m_alloc_secure_clear( sizeof *efx->cfx.dek );
692
693             if( !opt.def_cipher_algo  ) { /* try to get it from the prefs */
694                 efx->cfx.dek->algo =
695                   select_algo_from_prefs(efx->pk_list,PREFTYPE_SYM,-1,NULL);
696                 if( efx->cfx.dek->algo == -1 ) {
697                     /* because 3DES is implicitly in the prefs, this can only
698                      * happen if we do not have any public keys in the list */
699                     efx->cfx.dek->algo = DEFAULT_CIPHER_ALGO;
700                 }
701             }
702             else {
703               if(!opt.expert &&
704                  select_algo_from_prefs(efx->pk_list,PREFTYPE_SYM,
705                                         opt.def_cipher_algo,
706                                         NULL)!=opt.def_cipher_algo)
707                 log_info(_("forcing symmetric cipher %s (%d) "
708                            "violates recipient preferences\n"),
709                          cipher_algo_to_string(opt.def_cipher_algo),
710                          opt.def_cipher_algo);
711
712               efx->cfx.dek->algo = opt.def_cipher_algo;
713             }
714
715             efx->cfx.dek->use_mdc = use_mdc(efx->pk_list,efx->cfx.dek->algo);
716
717             make_session_key( efx->cfx.dek );
718             if( DBG_CIPHER )
719                 log_hexdump("DEK is: ",
720                              efx->cfx.dek->key, efx->cfx.dek->keylen );
721
722             rc = write_pubkey_enc_from_list( efx->pk_list, efx->cfx.dek, a );
723             if( rc )
724                 return rc;
725
726             iobuf_push_filter( a, cipher_filter, &efx->cfx );
727
728             efx->header_okay = 1;
729         }
730         rc = iobuf_write( a, buf, size );
731
732     }
733     else if( control == IOBUFCTRL_FREE ) {
734     }
735     else if( control == IOBUFCTRL_DESC ) {
736         *(char**)buf = "encrypt_filter";
737     }
738     return rc;
739 }
740
741
742 /****************
743  * Write pubkey-enc packets from the list of PKs to OUT.
744  */
745 static int
746 write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out )
747 {
748     PACKET pkt;
749     PKT_public_key *pk;
750     PKT_pubkey_enc  *enc;
751     int rc;
752
753     for( ; pk_list; pk_list = pk_list->next ) {
754         MPI frame;
755
756         pk = pk_list->pk;
757
758         print_pubkey_algo_note( pk->pubkey_algo );
759         enc = m_alloc_clear( sizeof *enc );
760         enc->pubkey_algo = pk->pubkey_algo;
761         keyid_from_pk( pk, enc->keyid );
762         enc->throw_keyid = (opt.throw_keyid || (pk_list->flags&1));
763
764         if(opt.throw_keyid && (PGP2 || PGP6 || PGP7 || PGP8))
765           {
766             log_info(_("you may not use %s while in %s mode\n"),
767                      "--throw-keyid",compliance_option_string());
768             compliance_failure();
769           }
770
771         /* Okay, what's going on: We have the session key somewhere in
772          * the structure DEK and want to encode this session key in
773          * an integer value of n bits.  pubkey_nbits gives us the
774          * number of bits we have to use.  We then encode the session
775          * key in some way and we get it back in the big intger value
776          * FRAME.  Then we use FRAME, the public key PK->PKEY and the
777          * algorithm number PK->PUBKEY_ALGO and pass it to pubkey_encrypt
778          * which returns the encrypted value in the array ENC->DATA.
779          * This array has a size which depends on the used algorithm
780          * (e.g. 2 for ElGamal).  We don't need frame anymore because we
781          * have everything now in enc->data which is the passed to
782          * build_packet()
783          */
784         frame = encode_session_key( dek, pubkey_nbits( pk->pubkey_algo,
785                                                           pk->pkey ) );
786         rc = pubkey_encrypt( pk->pubkey_algo, enc->data, frame, pk->pkey );
787         mpi_free( frame );
788         if( rc )
789             log_error("pubkey_encrypt failed: %s\n", g10_errstr(rc) );
790         else {
791             if( opt.verbose ) {
792                 char *ustr = get_user_id_string_printable (enc->keyid);
793                 log_info(_("%s/%s encrypted for: \"%s\"\n"),
794                     pubkey_algo_to_string(enc->pubkey_algo),
795                     cipher_algo_to_string(dek->algo), ustr );
796                 m_free(ustr);
797             }
798             /* and write it */
799             init_packet(&pkt);
800             pkt.pkttype = PKT_PUBKEY_ENC;
801             pkt.pkt.pubkey_enc = enc;
802             rc = build_packet( out, &pkt );
803             if( rc )
804                log_error("build_packet(pubkey_enc) failed: %s\n", g10_errstr(rc));
805         }
806         free_pubkey_enc(enc);
807         if( rc )
808             return rc;
809     }
810     return 0;
811 }
812
813 void
814 encode_crypt_files(int nfiles, char **files, STRLIST remusr)
815 {
816   int rc = 0;
817
818   if (opt.outfile)
819     {
820       log_error(_("--output doesn't work for this command\n"));
821       return;        
822     }
823     
824   if (!nfiles)
825     {
826       char line[2048];
827       unsigned int lno = 0;
828       while ( fgets(line, DIM(line), stdin) )
829         {
830           lno++;
831           if (!*line || line[strlen(line)-1] != '\n')
832             {
833               log_error("input line %u too long or missing LF\n", lno);
834               return;
835             }
836           line[strlen(line)-1] = '\0';
837           print_file_status(STATUS_FILE_START, line, 2);
838           if ( (rc = encode_crypt(line, remusr, 0)) )
839             log_error("%s: encryption failed: %s\n",
840                       print_fname_stdin(line), g10_errstr(rc) );
841           write_status( STATUS_FILE_DONE );
842         }
843     }
844   else
845     {
846       while (nfiles--)
847         {
848           print_file_status(STATUS_FILE_START, *files, 2);
849           if ( (rc = encode_crypt(*files, remusr, 0)) )
850             log_error("%s: encryption failed: %s\n",
851                       print_fname_stdin(*files), g10_errstr(rc) );
852           write_status( STATUS_FILE_DONE );
853           files++;
854         }
855     }
856 }