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