Fix buglet.
[gnupg.git] / g10 / encode.c
blob7794bdb7ced0bb3555a1315c414b152b601629ed
1 /* encode.c - encode data
2 * Copyright (C) 1998, 1999, 2000, 2001, 2002,
3 * 2003 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
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.
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.
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
22 #include <config.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <assert.h>
29 #include "gpg.h"
30 #include "options.h"
31 #include "packet.h"
32 #include "errors.h"
33 #include "iobuf.h"
34 #include "keydb.h"
35 #include "memory.h"
36 #include "util.h"
37 #include "main.h"
38 #include "filter.h"
39 #include "trustdb.h"
40 #include "i18n.h"
41 #include "status.h"
42 #include "pkglue.h"
45 static int encode_simple( const char *filename, int mode, int compat );
46 static int write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, iobuf_t out );
50 /****************
51 * Encode FILENAME with only the symmetric cipher. Take input from
52 * stdin if FILENAME is NULL.
54 int
55 encode_symmetric( const char *filename )
57 int compat = 1;
59 #if 0
60 /* We don't want to use it because older gnupg version can't
61 handle it and we can presume that a lot of scripts are running
62 with the expert mode set. Some time in the future we might
63 want to allow for it. */
64 if ( opt.expert )
65 compat = 0; /* PGP knows how to handle this mode. */
66 #endif
67 return encode_simple( filename, 1, compat );
70 /****************
71 * Encode FILENAME as a literal data packet only. Take input from
72 * stdin if FILENAME is NULL.
74 int
75 encode_store( const char *filename )
77 return encode_simple( filename, 0, 1 );
80 static void
81 encode_sesskey (DEK * dek, DEK ** ret_dek, byte * enckey)
83 CIPHER_HANDLE hd;
84 DEK * c;
85 byte buf[33];
87 assert (dek->keylen < 32);
89 c = xcalloc (1, sizeof *c);
90 c->keylen = dek->keylen;
91 c->algo = dek->algo;
92 make_session_key (c);
93 /*log_hexdump ("thekey", c->key, c->keylen);*/
95 /* the encrypted session key is prefixed with a one-octet algorithm id */
96 buf[0] = c->algo;
97 memcpy (buf + 1, c->key, c->keylen);
99 /* due to the fact that we use only checked values, consider each
100 failure as fatal. */
101 if (gcry_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, 1))
102 BUG();
103 if (gcry_cipher_setkey (hd, dek->key, dek->keylen))
104 BUG();
105 gcry_cipher_setiv (hd, NULL, 0);
106 gcry_cipher_encrypt (hd, buf, c->keylen + 1, NULL, 0);
107 gcry_cipher_close (hd);
109 memcpy (enckey, buf, c->keylen + 1);
110 wipememory (buf, sizeof buf); /* burn key */
111 *ret_dek = c;
114 /* We try very hard to use a MDC */
115 static int
116 use_mdc (PK_LIST pk_list,int algo)
118 byte cipher_algid[4] = {
119 CIPHER_ALGO_AES,
120 CIPHER_ALGO_AES192,
121 CIPHER_ALGO_AES256,
122 CIPHER_ALGO_TWOFISH
124 int i;
126 /* RFC-1991 and 2440 don't have MDC */
127 if(RFC1991 || RFC2440)
128 return 0;
130 /* --force-mdc overrides --disable-mdc */
131 if (opt.force_mdc)
132 return 1;
134 if (opt.disable_mdc)
135 return 0;
137 /* Do the keys really support MDC? */
139 if (select_mdc_from_pklist (pk_list))
140 return 1;
142 /* The keys don't support MDC, so now we do a bit of a hack - if any
143 of the AESes or TWOFISH are in the prefs, we assume that the user
144 can handle a MDC. This is valid for PGP 7, which can handle MDCs
145 though it will not generate them. 2440bis allows this, by the
146 way. */
147 for (i=0; i < DIM (cipher_algid); i++)
149 if (select_algo_from_prefs (pk_list, PREFTYPE_SYM, cipher_algid[i],
150 NULL) == cipher_algid[i])
151 return 1;
154 /* Last try. Use MDC for the modern ciphers. */
155 if (gcry_cipher_get_algo_blklen (algo) != 8)
156 return 1;
158 return 0; /* No MDC */
161 static int
162 encode_simple( const char *filename, int mode, int compat )
164 iobuf_t inp, out;
165 PACKET pkt;
166 DEK *dek = NULL;
167 PKT_plaintext *pt = NULL;
168 STRING2KEY *s2k = NULL;
169 byte enckey[33];
170 int rc = 0;
171 int seskeylen = 0;
172 u32 filesize;
173 cipher_filter_context_t cfx;
174 armor_filter_context_t afx;
175 compress_filter_context_t zfx;
176 text_filter_context_t tfx;
177 progress_filter_context_t pfx;
178 int do_compress = opt.compress && !RFC1991;
180 memset( &cfx, 0, sizeof cfx);
181 memset( &afx, 0, sizeof afx);
182 memset( &zfx, 0, sizeof zfx);
183 memset( &tfx, 0, sizeof tfx);
184 init_packet(&pkt);
186 /* prepare iobufs */
187 if( !(inp = iobuf_open(filename)) ) {
188 rc = gpg_error_from_errno (errno);
189 log_error(_("%s: can't open: %s\n"), filename? filename: "[stdin]",
190 strerror(errno) );
191 return rc;
194 handle_progress (&pfx, inp, filename);
196 if( opt.textmode )
197 iobuf_push_filter( inp, text_filter, &tfx );
199 /* Due the the fact that we use don't use an IV to encrypt the
200 session key we can't use the new mode with RFC1991 because
201 it has no S2K salt. RFC1991 always uses simple S2K. */
202 if ( RFC1991 && !compat )
203 compat = 1;
205 cfx.dek = NULL;
206 if( mode ) {
207 s2k = xcalloc (1, sizeof *s2k );
208 s2k->mode = RFC1991? 0:opt.s2k_mode;
209 s2k->hash_algo = opt.s2k_digest_algo;
210 cfx.dek = passphrase_to_dek( NULL, 0,
211 default_cipher_algo(), s2k, 2,
212 NULL, NULL);
213 if( !cfx.dek || !cfx.dek->keylen ) {
214 rc = gpg_error (GPG_ERR_INV_PASSPHRASE);
215 xfree (cfx.dek);
216 xfree (s2k);
217 iobuf_close(inp);
218 log_error(_("error creating passphrase: %s\n"), gpg_strerror (rc) );
219 return rc;
221 if (!compat && s2k->mode != 1 && s2k->mode != 3) {
222 compat = 1;
223 log_info (_("can't use a symmetric ESK packet "
224 "due to the S2K mode\n"));
227 if ( !compat ) {
228 seskeylen = gcry_cipher_get_algo_keylen (default_cipher_algo());
229 encode_sesskey( cfx.dek, &dek, enckey );
230 xfree (cfx.dek); cfx.dek = dek;
233 cfx.dek->use_mdc=use_mdc(NULL,cfx.dek->algo);
236 if (opt.compress == -1 && cfx.dek && cfx.dek->use_mdc &&
237 is_file_compressed(filename, &rc))
239 if (opt.verbose)
240 log_info(_("`%s' already compressed\n"), filename);
241 do_compress = 0;
244 if( rc || (rc = open_outfile( filename, opt.armor? 1:0, &out )) ) {
245 iobuf_cancel(inp);
246 xfree (cfx.dek);
247 xfree (s2k);
248 return rc;
251 if( opt.armor )
252 iobuf_push_filter( out, armor_filter, &afx );
253 #ifdef ENABLE_COMMENT_PACKETS
254 else {
255 write_comment( out, "#created by GNUPG v" VERSION " ("
256 PRINTABLE_OS_NAME ")");
257 if( opt.comment_string )
258 write_comment( out, opt.comment_string );
260 #endif
261 if( s2k && !RFC1991 ) {
262 PKT_symkey_enc *enc = xcalloc (1, sizeof *enc + seskeylen + 1 );
263 enc->version = 4;
264 enc->cipher_algo = cfx.dek->algo;
265 enc->s2k = *s2k;
266 if ( !compat && seskeylen ) {
267 enc->seskeylen = seskeylen + 1; /* algo id */
268 memcpy( enc->seskey, enckey, seskeylen + 1 );
270 pkt.pkttype = PKT_SYMKEY_ENC;
271 pkt.pkt.symkey_enc = enc;
272 if( (rc = build_packet( out, &pkt )) )
273 log_error("build symkey packet failed: %s\n", gpg_strerror (rc) );
274 xfree (enc);
277 if (!opt.no_literal) {
278 /* setup the inner packet */
279 if( filename || opt.set_filename ) {
280 char *s = make_basename ( opt.set_filename ? opt.set_filename
281 : filename
282 /* for riscos?
283 .iobuf_get_real_fname( inp ) */
285 pt = xmalloc ( sizeof *pt + strlen(s) - 1 );
286 pt->namelen = strlen(s);
287 memcpy(pt->name, s, pt->namelen );
288 xfree (s);
290 else { /* no filename */
291 pt = xmalloc ( sizeof *pt - 1 );
292 pt->namelen = 0;
296 /* Note that PGP 5 has problems decrypting symmetrically encrypted
297 data if the file length is in the inner packet. It works when
298 only partial length headers are use. In the past, we always
299 used partial body length here, but since PGP 2, PGP 6, and PGP
300 7 need the file length, and nobody should be using PGP 5
301 nowadays anyway, this is now set to the file length. Note also
302 that this only applies to the RFC-1991 style symmetric
303 messages, and not the RFC-2440 style. PGP 6 and 7 work with
304 either partial length or fixed length with the new style
305 messages. */
307 if (filename && *filename && !(*filename == '-' && !filename[1])
308 && !opt.textmode ) {
309 off_t tmpsize;
311 if ( !(tmpsize = iobuf_get_filelength(inp)) )
312 log_info(_("%s: WARNING: empty file\n"), filename );
313 /* We can't encode the length of very large files because
314 OpenPGP uses only 32 bit for file sizes. So if the the
315 size of a file is larger than 2^32 minus some bytes for
316 packet headers, we switch to partial length encoding. */
317 if ( tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) )
318 filesize = tmpsize;
319 else
320 filesize = 0;
322 else
323 filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
325 if (!opt.no_literal) {
326 pt->timestamp = make_timestamp();
327 pt->mode = opt.textmode? 't' : 'b';
328 pt->len = filesize;
329 pt->new_ctb = !pt->len && !RFC1991;
330 pt->buf = inp;
331 pkt.pkttype = PKT_PLAINTEXT;
332 pkt.pkt.plaintext = pt;
333 cfx.datalen = filesize && !do_compress ? calc_packet_length( &pkt ) : 0;
335 else
337 cfx.datalen = filesize && !do_compress ? filesize : 0;
338 pkt.pkttype = 0;
339 pkt.pkt.generic = NULL;
342 /* register the cipher filter */
343 if( mode )
344 iobuf_push_filter( out, cipher_filter, &cfx );
345 /* register the compress filter */
346 if( do_compress )
348 if (cfx.dek && cfx.dek->use_mdc)
349 zfx.new_ctb = 1;
350 zfx.algo=default_compress_algo();
351 iobuf_push_filter( out, compress_filter, &zfx );
354 /* do the work */
355 if (!opt.no_literal) {
356 if( (rc = build_packet( out, &pkt )) )
357 log_error("build_packet failed: %s\n", gpg_strerror (rc) );
359 else {
360 /* user requested not to create a literal packet,
361 * so we copy the plain data */
362 byte copy_buffer[4096];
363 int bytes_copied;
364 while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
365 if ( (rc=iobuf_write(out, copy_buffer, bytes_copied))) {
366 log_error("copying input to output failed: %s\n", gpg_strerror (rc) );
367 break;
369 wipememory(copy_buffer, 4096); /* burn buffer */
372 /* finish the stuff */
373 iobuf_close(inp);
374 if (rc)
375 iobuf_cancel(out);
376 else {
377 iobuf_close(out); /* fixme: check returncode */
378 if (mode)
379 write_status( STATUS_END_ENCRYPTION );
381 if (pt)
382 pt->buf = NULL;
383 free_packet(&pkt);
384 xfree (cfx.dek);
385 xfree (s2k);
386 return rc;
389 /****************
390 * Encrypt the file with the given userids (or ask if none
391 * is supplied).
394 encode_crypt( const char *filename, STRLIST remusr )
396 iobuf_t inp = NULL, out = NULL;
397 PACKET pkt;
398 PKT_plaintext *pt = NULL;
399 int rc = 0, rc2 = 0;
400 u32 filesize;
401 cipher_filter_context_t cfx;
402 armor_filter_context_t afx;
403 compress_filter_context_t zfx;
404 text_filter_context_t tfx;
405 progress_filter_context_t pfx;
406 PK_LIST pk_list,work_list;
407 int do_compress = opt.compress && !RFC1991;
410 memset( &cfx, 0, sizeof cfx);
411 memset( &afx, 0, sizeof afx);
412 memset( &zfx, 0, sizeof zfx);
413 memset( &tfx, 0, sizeof tfx);
414 init_packet(&pkt);
416 if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC)) )
417 return rc;
419 if(PGP2) {
420 for(work_list=pk_list; work_list; work_list=work_list->next)
421 if(!(is_RSA(work_list->pk->pubkey_algo) &&
422 nbits_from_pk(work_list->pk)<=2048))
424 log_info(_("you can only encrypt to RSA keys of 2048 bits or "
425 "less in --pgp2 mode\n"));
426 compliance_failure();
427 break;
431 /* prepare iobufs */
432 if( !(inp = iobuf_open(filename)) ) {
433 rc = gpg_error_from_errno (errno);
434 log_error(_("can't open %s: %s\n"), filename? filename: "[stdin]",
435 strerror(errno) );
436 goto leave;
438 else if( opt.verbose )
439 log_info(_("reading from `%s'\n"), filename? filename: "[stdin]");
441 handle_progress (&pfx, inp, filename);
443 if( opt.textmode )
444 iobuf_push_filter( inp, text_filter, &tfx );
446 if( (rc = open_outfile( filename, opt.armor? 1:0, &out )) )
447 goto leave;
450 if( opt.armor )
451 iobuf_push_filter( out, armor_filter, &afx );
452 #ifdef ENABLE_COMMENT_PACKETS
453 else {
454 write_comment( out, "#created by GNUPG v" VERSION " ("
455 PRINTABLE_OS_NAME ")");
456 if( opt.comment_string )
457 write_comment( out, opt.comment_string );
459 #endif
460 /* create a session key */
461 cfx.dek = xcalloc_secure (1, sizeof *cfx.dek);
462 if( !opt.def_cipher_algo ) { /* try to get it from the prefs */
463 cfx.dek->algo = select_algo_from_prefs(pk_list,PREFTYPE_SYM,-1,NULL);
464 /* The only way select_algo_from_prefs can fail here is when
465 mixing v3 and v4 keys, as v4 keys have an implicit
466 preference entry for 3DES, and the pk_list cannot be empty.
467 In this case, use 3DES anyway as it's the safest choice -
468 perhaps the v3 key is being used in an OpenPGP
469 implementation and we know that the implementation behind
470 any v4 key can handle 3DES. */
471 if( cfx.dek->algo == -1 ) {
472 cfx.dek->algo = CIPHER_ALGO_3DES;
474 if( PGP2 ) {
475 log_info(_("unable to use the IDEA cipher for all of the keys "
476 "you are encrypting to.\n"));
477 compliance_failure();
481 else {
482 if(!opt.expert &&
483 select_algo_from_prefs(pk_list,PREFTYPE_SYM,
484 opt.def_cipher_algo,NULL)!=opt.def_cipher_algo)
485 log_info(_("forcing symmetric cipher %s (%d) "
486 "violates recipient preferences\n"),
487 gcry_cipher_algo_name (opt.def_cipher_algo),
488 opt.def_cipher_algo);
490 cfx.dek->algo = opt.def_cipher_algo;
493 cfx.dek->use_mdc=use_mdc(pk_list,cfx.dek->algo);
495 /* Only do the is-file-already-compressed check if we are using a
496 MDC. This forces compressed files to be re-compressed if we do
497 not have a MDC to give some protection against chosen
498 ciphertext attacks. */
500 if (opt.compress == -1 && cfx.dek->use_mdc &&
501 is_file_compressed(filename, &rc2) )
503 if (opt.verbose)
504 log_info(_("`%s' already compressed\n"), filename);
505 do_compress = 0;
507 if (rc2)
509 rc = rc2;
510 goto leave;
513 make_session_key( cfx.dek );
514 if( DBG_CIPHER )
515 log_printhex ("DEK is: ", cfx.dek->key, cfx.dek->keylen );
517 rc = write_pubkey_enc_from_list( pk_list, cfx.dek, out );
518 if( rc )
519 goto leave;
521 if (!opt.no_literal) {
522 /* setup the inner packet */
523 if( filename || opt.set_filename ) {
524 char *s = make_basename( opt.set_filename ? opt.set_filename
525 : filename
526 /* ,iobuf_get_real_fname( inp )*/ );
527 pt = xmalloc ( sizeof *pt + strlen(s) - 1 );
528 pt->namelen = strlen(s);
529 memcpy(pt->name, s, pt->namelen );
530 xfree (s);
532 else { /* no filename */
533 pt = xmalloc ( sizeof *pt - 1 );
534 pt->namelen = 0;
538 if (filename && *filename && !(*filename == '-' && !filename[1])
539 && !opt.textmode ) {
540 off_t tmpsize;
542 if ( !(tmpsize = iobuf_get_filelength(inp)) )
543 log_info(_("%s: WARNING: empty file\n"), filename );
544 /* We can't encode the length of very large files because
545 OpenPGP uses only 32 bit for file sizes. So if the the
546 size of a file is larger than 2^32 minus some bytes for
547 packet headers, we switch to partial length encoding. */
548 if ( tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) )
549 filesize = tmpsize;
550 else
551 filesize = 0;
553 else
554 filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
556 if (!opt.no_literal) {
557 pt->timestamp = make_timestamp();
558 pt->mode = opt.textmode ? 't' : 'b';
559 pt->len = filesize;
560 pt->new_ctb = !pt->len && !RFC1991;
561 pt->buf = inp;
562 pkt.pkttype = PKT_PLAINTEXT;
563 pkt.pkt.plaintext = pt;
564 cfx.datalen = filesize && !do_compress? calc_packet_length( &pkt ) : 0;
566 else
567 cfx.datalen = filesize && !do_compress ? filesize : 0;
569 /* register the cipher filter */
570 iobuf_push_filter( out, cipher_filter, &cfx );
572 /* register the compress filter */
573 if( do_compress ) {
574 int compr_algo = opt.def_compress_algo;
576 if(compr_algo==-1)
578 if((compr_algo=
579 select_algo_from_prefs(pk_list,PREFTYPE_ZIP,-1,NULL))==-1)
580 compr_algo=DEFAULT_COMPRESS_ALGO;
581 /* Theoretically impossible to get here since uncompressed
582 is implicit. */
584 else if(!opt.expert &&
585 select_algo_from_prefs(pk_list,PREFTYPE_ZIP,
586 compr_algo,NULL)!=compr_algo)
587 log_info(_("forcing compression algorithm %s (%d) "
588 "violates recipient preferences\n"),
589 compress_algo_to_string(compr_algo),compr_algo);
591 /* algo 0 means no compression */
592 if( compr_algo )
594 if (cfx.dek && cfx.dek->use_mdc)
595 zfx.new_ctb = 1;
596 zfx.algo = compr_algo;
597 iobuf_push_filter( out, compress_filter, &zfx );
601 /* do the work */
602 if (!opt.no_literal) {
603 if( (rc = build_packet( out, &pkt )) )
604 log_error("build_packet failed: %s\n", gpg_strerror (rc) );
606 else {
607 /* user requested not to create a literal packet, so we copy
608 the plain data */
609 byte copy_buffer[4096];
610 int bytes_copied;
611 while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
612 if ((rc=iobuf_write(out, copy_buffer, bytes_copied))) {
613 log_error("copying input to output failed: %s\n",
614 gpg_strerror (rc) );
615 break;
617 wipememory(copy_buffer, 4096); /* burn buffer */
620 /* finish the stuff */
621 leave:
622 iobuf_close(inp);
623 if( rc )
624 iobuf_cancel(out);
625 else {
626 iobuf_close(out); /* fixme: check returncode */
627 write_status( STATUS_END_ENCRYPTION );
629 if( pt )
630 pt->buf = NULL;
631 free_packet(&pkt);
632 xfree (cfx.dek);
633 release_pk_list( pk_list );
634 return rc;
640 /****************
641 * Filter to do a complete public key encryption.
644 encrypt_filter( void *opaque, int control,
645 iobuf_t a, byte *buf, size_t *ret_len)
647 size_t size = *ret_len;
648 encrypt_filter_context_t *efx = opaque;
649 int rc=0;
651 if( control == IOBUFCTRL_UNDERFLOW ) { /* decrypt */
652 BUG(); /* not used */
654 else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */
655 if( !efx->header_okay ) {
656 efx->cfx.dek = xcalloc_secure (1, sizeof *efx->cfx.dek );
658 if( !opt.def_cipher_algo ) { /* try to get it from the prefs */
659 efx->cfx.dek->algo =
660 select_algo_from_prefs(efx->pk_list,PREFTYPE_SYM,-1,NULL);
661 if( efx->cfx.dek->algo == -1 ) {
662 /* because 3DES is implicitly in the prefs, this can only
663 * happen if we do not have any public keys in the list */
664 efx->cfx.dek->algo = DEFAULT_CIPHER_ALGO;
667 else {
668 if(!opt.expert &&
669 select_algo_from_prefs(efx->pk_list,PREFTYPE_SYM,
670 opt.def_cipher_algo,
671 NULL)!=opt.def_cipher_algo)
672 log_info(_("forcing symmetric cipher %s (%d) "
673 "violates recipient preferences\n"),
674 gcry_cipher_algo_name (opt.def_cipher_algo),
675 opt.def_cipher_algo);
677 efx->cfx.dek->algo = opt.def_cipher_algo;
680 efx->cfx.dek->use_mdc = use_mdc(efx->pk_list,efx->cfx.dek->algo);
682 make_session_key( efx->cfx.dek );
683 if( DBG_CIPHER )
684 log_printhex ("DEK is: ",
685 efx->cfx.dek->key, efx->cfx.dek->keylen );
687 rc = write_pubkey_enc_from_list( efx->pk_list, efx->cfx.dek, a );
688 if( rc )
689 return rc;
691 iobuf_push_filter( a, cipher_filter, &efx->cfx );
693 efx->header_okay = 1;
695 rc = iobuf_write( a, buf, size );
698 else if( control == IOBUFCTRL_FREE ) {
700 else if( control == IOBUFCTRL_DESC ) {
701 *(char**)buf = "encrypt_filter";
703 return rc;
707 /****************
708 * Write pubkey-enc packets from the list of PKs to OUT.
710 static int
711 write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, iobuf_t out )
713 PACKET pkt;
714 PKT_public_key *pk;
715 PKT_pubkey_enc *enc;
716 int rc;
718 for( ; pk_list; pk_list = pk_list->next ) {
719 gcry_mpi_t frame;
721 pk = pk_list->pk;
723 print_pubkey_algo_note( pk->pubkey_algo );
724 enc = xcalloc (1, sizeof *enc );
725 enc->pubkey_algo = pk->pubkey_algo;
726 keyid_from_pk( pk, enc->keyid );
727 enc->throw_keyid = (opt.throw_keyid || (pk_list->flags&1));
729 if(opt.throw_keyid && (PGP2 || PGP6 || PGP7 || PGP8))
731 log_info(_("you may not use %s while in %s mode\n"),
732 "--throw-keyid",compliance_option_string());
733 compliance_failure();
736 /* Okay, what's going on: We have the session key somewhere in
737 * the structure DEK and want to encode this session key in
738 * an integer value of n bits. pubkey_nbits gives us the
739 * number of bits we have to use. We then encode the session
740 * key in some way and we get it back in the big intger value
741 * FRAME. Then we use FRAME, the public key PK->PKEY and the
742 * algorithm number PK->PUBKEY_ALGO and pass it to pubkey_encrypt
743 * which returns the encrypted value in the array ENC->DATA.
744 * This array has a size which depends on the used algorithm
745 * (e.g. 2 for ElGamal). We don't need frame anymore because we
746 * have everything now in enc->data which is the passed to
747 * build_packet()
749 frame = encode_session_key( dek, pubkey_nbits( pk->pubkey_algo,
750 pk->pkey ) );
751 rc = pk_encrypt( pk->pubkey_algo, enc->data, frame, pk->pkey );
752 gcry_mpi_release ( frame );
753 if( rc )
754 log_error("pubkey_encrypt failed: %s\n", gpg_strerror (rc) );
755 else {
756 if( opt.verbose ) {
757 char *ustr = get_user_id_string_printable (enc->keyid);
758 log_info(_("%s/%s encrypted for: \"%s\"\n"),
759 gcry_pk_algo_name (enc->pubkey_algo),
760 gcry_cipher_algo_name (dek->algo), ustr );
761 xfree (ustr);
763 /* and write it */
764 init_packet(&pkt);
765 pkt.pkttype = PKT_PUBKEY_ENC;
766 pkt.pkt.pubkey_enc = enc;
767 rc = build_packet( out, &pkt );
768 if( rc )
769 log_error("build_packet(pubkey_enc) failed: %s\n", gpg_strerror (rc));
771 free_pubkey_enc(enc);
772 if( rc )
773 return rc;
775 return 0;
778 void
779 encode_crypt_files(int nfiles, char **files, STRLIST remusr)
781 int rc = 0;
783 if (opt.outfile)
785 log_error(_("--output doesn't work for this command\n"));
786 return;
789 if (!nfiles)
791 char line[2048];
792 unsigned int lno = 0;
793 while ( fgets(line, DIM(line), stdin) )
795 lno++;
796 if (!*line || line[strlen(line)-1] != '\n')
798 log_error("input line %u too long or missing LF\n", lno);
799 return;
801 line[strlen(line)-1] = '\0';
802 print_file_status(STATUS_FILE_START, line, 2);
803 if ( (rc = encode_crypt(line, remusr)) )
804 log_error("%s: encryption failed: %s\n",
805 print_fname_stdin(line), gpg_strerror (rc) );
806 write_status( STATUS_FILE_DONE );
809 else
811 while (nfiles--)
813 print_file_status(STATUS_FILE_START, *files, 2);
814 if ( (rc = encode_crypt(*files, remusr)) )
815 log_error("%s: encryption failed: %s\n",
816 print_fname_stdin(*files), gpg_strerror (rc) );
817 write_status( STATUS_FILE_DONE );
818 files++;