Line data Source code
1 : /* encrypt.c - Main encryption driver
2 : * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3 : * 2006, 2009 Free Software Foundation, Inc.
4 : * Copyright (C) 2016 g10 Code GmbH
5 : *
6 : * This file is part of GnuPG.
7 : *
8 : * GnuPG is free software; you can redistribute it and/or modify
9 : * it under the terms of the GNU General Public License as published by
10 : * the Free Software Foundation; either version 3 of the License, or
11 : * (at your option) any later version.
12 : *
13 : * GnuPG is distributed in the hope that it will be useful,
14 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : * GNU General Public License for more details.
17 : *
18 : * You should have received a copy of the GNU General Public License
19 : * along with this program; if not, see <https://www.gnu.org/licenses/>.
20 : */
21 :
22 : #include <config.h>
23 : #include <stdio.h>
24 : #include <stdlib.h>
25 : #include <string.h>
26 : #include <errno.h>
27 :
28 : #include "gpg.h"
29 : #include "options.h"
30 : #include "packet.h"
31 : #include "status.h"
32 : #include "iobuf.h"
33 : #include "keydb.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 : #include "pkglue.h"
41 :
42 :
43 : static int encrypt_simple( const char *filename, int mode, int use_seskey );
44 : static int write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, iobuf_t out );
45 :
46 : /****************
47 : * Encrypt FILENAME with only the symmetric cipher. Take input from
48 : * stdin if FILENAME is NULL.
49 : */
50 : int
51 48 : encrypt_symmetric (const char *filename)
52 : {
53 48 : return encrypt_simple( filename, 1, 0 );
54 : }
55 :
56 :
57 : /****************
58 : * Encrypt FILENAME as a literal data packet only. Take input from
59 : * stdin if FILENAME is NULL.
60 : */
61 : int
62 0 : encrypt_store (const char *filename)
63 : {
64 0 : return encrypt_simple( filename, 0, 0 );
65 : }
66 :
67 :
68 : /* *SESKEY contains the unencrypted session key ((*SESKEY)->KEY) and
69 : the algorithm that will be used to encrypt the contents of the SED
70 : packet ((*SESKEY)->ALGO). If *SESKEY is NULL, then a random
71 : session key that is appropriate for DEK->ALGO is generated and
72 : stored there.
73 :
74 : Encrypt that session key using DEK and store the result in ENCKEY,
75 : which must be large enough to hold (*SESKEY)->KEYLEN + 1 bytes. */
76 : void
77 1 : encrypt_seskey (DEK *dek, DEK **seskey, byte *enckey)
78 : {
79 : gcry_cipher_hd_t hd;
80 : byte buf[33];
81 :
82 1 : log_assert ( dek->keylen <= 32 );
83 1 : if (!*seskey)
84 : {
85 0 : *seskey=xmalloc_clear(sizeof(DEK));
86 0 : (*seskey)->algo=dek->algo;
87 0 : make_session_key(*seskey);
88 : /*log_hexdump( "thekey", c->key, c->keylen );*/
89 : }
90 :
91 : /* The encrypted session key is prefixed with a one-octet algorithm id. */
92 1 : buf[0] = (*seskey)->algo;
93 1 : memcpy( buf + 1, (*seskey)->key, (*seskey)->keylen );
94 :
95 : /* We only pass already checked values to the following function,
96 : thus we consider any failure as fatal. */
97 1 : if (openpgp_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, 1))
98 0 : BUG ();
99 1 : if (gcry_cipher_setkey (hd, dek->key, dek->keylen))
100 0 : BUG ();
101 1 : gcry_cipher_setiv (hd, NULL, 0);
102 1 : gcry_cipher_encrypt (hd, buf, (*seskey)->keylen + 1, NULL, 0);
103 1 : gcry_cipher_close (hd);
104 :
105 1 : memcpy( enckey, buf, (*seskey)->keylen + 1 );
106 1 : wipememory( buf, sizeof buf ); /* burn key */
107 1 : }
108 :
109 :
110 : /* We try very hard to use a MDC */
111 : int
112 302 : use_mdc (pk_list_t pk_list,int algo)
113 : {
114 : /* RFC-2440 don't has MDC */
115 302 : if (RFC2440)
116 0 : return 0;
117 :
118 : /* --force-mdc overrides --disable-mdc */
119 302 : if(opt.force_mdc)
120 22 : return 1;
121 :
122 280 : if(opt.disable_mdc)
123 0 : return 0;
124 :
125 : /* Do the keys really support MDC? */
126 :
127 280 : if(select_mdc_from_pklist(pk_list))
128 149 : return 1;
129 :
130 : /* The keys don't support MDC, so now we do a bit of a hack - if any
131 : of the AESes or TWOFISH are in the prefs, we assume that the user
132 : can handle a MDC. This is valid for PGP 7, which can handle MDCs
133 : though it will not generate them. 2440bis allows this, by the
134 : way. */
135 :
136 131 : if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
137 : CIPHER_ALGO_AES,NULL)==CIPHER_ALGO_AES)
138 0 : return 1;
139 :
140 131 : if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
141 : CIPHER_ALGO_AES192,NULL)==CIPHER_ALGO_AES192)
142 0 : return 1;
143 :
144 131 : if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
145 : CIPHER_ALGO_AES256,NULL)==CIPHER_ALGO_AES256)
146 0 : return 1;
147 :
148 131 : if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
149 : CIPHER_ALGO_TWOFISH,NULL)==CIPHER_ALGO_TWOFISH)
150 0 : return 1;
151 :
152 : /* Last try. Use MDC for the modern ciphers. */
153 :
154 131 : if (openpgp_cipher_get_algo_blklen (algo) != 8)
155 73 : return 1;
156 :
157 58 : if (opt.verbose)
158 0 : warn_missing_mdc_from_pklist (pk_list);
159 :
160 58 : return 0; /* No MDC */
161 : }
162 :
163 :
164 : /* We don't want to use use_seskey yet because older gnupg versions
165 : can't handle it, and there isn't really any point unless we're
166 : making a message that can be decrypted by a public key or
167 : passphrase. */
168 : static int
169 48 : encrypt_simple (const char *filename, int mode, int use_seskey)
170 : {
171 : iobuf_t inp, out;
172 : PACKET pkt;
173 48 : PKT_plaintext *pt = NULL;
174 48 : STRING2KEY *s2k = NULL;
175 : byte enckey[33];
176 48 : int rc = 0;
177 48 : int seskeylen = 0;
178 : u32 filesize;
179 : cipher_filter_context_t cfx;
180 48 : armor_filter_context_t *afx = NULL;
181 : compress_filter_context_t zfx;
182 : text_filter_context_t tfx;
183 : progress_filter_context_t *pfx;
184 48 : int do_compress = !!default_compress_algo();
185 :
186 48 : pfx = new_progress_context ();
187 48 : memset( &cfx, 0, sizeof cfx);
188 48 : memset( &zfx, 0, sizeof zfx);
189 48 : memset( &tfx, 0, sizeof tfx);
190 48 : init_packet(&pkt);
191 :
192 : /* Prepare iobufs. */
193 48 : inp = iobuf_open(filename);
194 48 : if (inp)
195 48 : iobuf_ioctl (inp, IOBUF_IOCTL_NO_CACHE, 1, NULL);
196 48 : if (inp && is_secured_file (iobuf_get_fd (inp)))
197 : {
198 0 : iobuf_close (inp);
199 0 : inp = NULL;
200 0 : gpg_err_set_errno (EPERM);
201 : }
202 48 : if (!inp)
203 : {
204 0 : rc = gpg_error_from_syserror ();
205 0 : log_error(_("can't open '%s': %s\n"), filename? filename: "[stdin]",
206 0 : strerror(errno) );
207 0 : release_progress_context (pfx);
208 0 : return rc;
209 : }
210 :
211 48 : handle_progress (pfx, inp, filename);
212 :
213 48 : if (opt.textmode)
214 0 : iobuf_push_filter( inp, text_filter, &tfx );
215 :
216 48 : cfx.dek = NULL;
217 48 : if ( mode )
218 : {
219 : int canceled;
220 :
221 48 : s2k = xmalloc_clear( sizeof *s2k );
222 48 : s2k->mode = opt.s2k_mode;
223 48 : s2k->hash_algo = S2K_DIGEST_ALGO;
224 48 : cfx.dek = passphrase_to_dek (default_cipher_algo (), s2k, 1, 0,
225 : NULL, &canceled);
226 48 : if ( !cfx.dek || !cfx.dek->keylen )
227 : {
228 0 : rc = gpg_error (canceled? GPG_ERR_CANCELED:GPG_ERR_INV_PASSPHRASE);
229 0 : xfree (cfx.dek);
230 0 : xfree (s2k);
231 0 : iobuf_close (inp);
232 0 : log_error (_("error creating passphrase: %s\n"), gpg_strerror (rc));
233 0 : release_progress_context (pfx);
234 0 : return rc;
235 : }
236 48 : if (use_seskey && s2k->mode != 1 && s2k->mode != 3)
237 : {
238 0 : use_seskey = 0;
239 0 : log_info (_("can't use a symmetric ESK packet "
240 : "due to the S2K mode\n"));
241 : }
242 :
243 48 : if ( use_seskey )
244 : {
245 0 : DEK *dek = NULL;
246 :
247 0 : seskeylen = openpgp_cipher_get_algo_keylen (default_cipher_algo ());
248 0 : encrypt_seskey( cfx.dek, &dek, enckey );
249 0 : xfree( cfx.dek ); cfx.dek = dek;
250 : }
251 :
252 48 : if (opt.verbose)
253 0 : log_info(_("using cipher %s\n"),
254 0 : openpgp_cipher_algo_name (cfx.dek->algo));
255 :
256 48 : cfx.dek->use_mdc=use_mdc(NULL,cfx.dek->algo);
257 : }
258 :
259 48 : if (do_compress && cfx.dek && cfx.dek->use_mdc
260 39 : && is_file_compressed(filename, &rc))
261 : {
262 0 : if (opt.verbose)
263 0 : log_info(_("'%s' already compressed\n"), filename);
264 0 : do_compress = 0;
265 : }
266 :
267 48 : if ( rc || (rc = open_outfile (-1, filename, opt.armor? 1:0, 0, &out )))
268 : {
269 0 : iobuf_cancel (inp);
270 0 : xfree (cfx.dek);
271 0 : xfree (s2k);
272 0 : release_progress_context (pfx);
273 0 : return rc;
274 : }
275 :
276 48 : if ( opt.armor )
277 : {
278 0 : afx = new_armor_context ();
279 0 : push_armor_filter (afx, out);
280 : }
281 :
282 48 : if ( s2k )
283 : {
284 48 : PKT_symkey_enc *enc = xmalloc_clear( sizeof *enc + seskeylen + 1 );
285 48 : enc->version = 4;
286 48 : enc->cipher_algo = cfx.dek->algo;
287 48 : enc->s2k = *s2k;
288 48 : if ( use_seskey && seskeylen )
289 : {
290 0 : enc->seskeylen = seskeylen + 1; /* algo id */
291 0 : memcpy (enc->seskey, enckey, seskeylen + 1 );
292 : }
293 48 : pkt.pkttype = PKT_SYMKEY_ENC;
294 48 : pkt.pkt.symkey_enc = enc;
295 48 : if ((rc = build_packet( out, &pkt )))
296 0 : log_error("build symkey packet failed: %s\n", gpg_strerror (rc) );
297 48 : xfree (enc);
298 : }
299 :
300 48 : if (!opt.no_literal)
301 48 : pt = setup_plaintext_name (filename, inp);
302 :
303 : /* Note that PGP 5 has problems decrypting symmetrically encrypted
304 : data if the file length is in the inner packet. It works when
305 : only partial length headers are use. In the past, we always used
306 : partial body length here, but since PGP 2, PGP 6, and PGP 7 need
307 : the file length, and nobody should be using PGP 5 nowadays
308 : anyway, this is now set to the file length. Note also that this
309 : only applies to the RFC-1991 style symmetric messages, and not
310 : the RFC-2440 style. PGP 6 and 7 work with either partial length
311 : or fixed length with the new style messages. */
312 :
313 48 : if ( !iobuf_is_pipe_filename (filename) && *filename && !opt.textmode )
314 46 : {
315 : off_t tmpsize;
316 : int overflow;
317 :
318 46 : if ( !(tmpsize = iobuf_get_filelength(inp, &overflow))
319 0 : && !overflow && opt.verbose)
320 0 : log_info(_("WARNING: '%s' is an empty file\n"), filename );
321 : /* We can't encode the length of very large files because
322 : OpenPGP uses only 32 bit for file sizes. So if the the
323 : size of a file is larger than 2^32 minus some bytes for
324 : packet headers, we switch to partial length encoding. */
325 46 : if ( tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) )
326 46 : filesize = tmpsize;
327 : else
328 0 : filesize = 0;
329 : }
330 : else
331 2 : filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
332 :
333 48 : if (!opt.no_literal)
334 : {
335 : /* Note that PT has been initialized above in !no_literal mode. */
336 48 : pt->timestamp = make_timestamp();
337 48 : pt->mode = opt.mimemode? 'm' : opt.textmode? 't' : 'b';
338 48 : pt->len = filesize;
339 48 : pt->new_ctb = !pt->len;
340 48 : pt->buf = inp;
341 48 : pkt.pkttype = PKT_PLAINTEXT;
342 48 : pkt.pkt.plaintext = pt;
343 48 : cfx.datalen = filesize && !do_compress ? calc_packet_length( &pkt ) : 0;
344 : }
345 : else
346 : {
347 0 : cfx.datalen = filesize && !do_compress ? filesize : 0;
348 0 : pkt.pkttype = 0;
349 0 : pkt.pkt.generic = NULL;
350 : }
351 :
352 : /* Register the cipher filter. */
353 48 : if (mode)
354 48 : iobuf_push_filter ( out, cipher_filter, &cfx );
355 :
356 : /* Register the compress filter. */
357 48 : if ( do_compress )
358 : {
359 48 : if (cfx.dek && cfx.dek->use_mdc)
360 39 : zfx.new_ctb = 1;
361 48 : push_compress_filter (out, &zfx, default_compress_algo());
362 : }
363 :
364 : /* Do the work. */
365 48 : if (!opt.no_literal)
366 : {
367 48 : if ( (rc = build_packet( out, &pkt )) )
368 0 : log_error("build_packet failed: %s\n", gpg_strerror (rc) );
369 : }
370 : else
371 : {
372 : /* User requested not to create a literal packet, so we copy the
373 : plain data. */
374 : byte copy_buffer[4096];
375 : int bytes_copied;
376 0 : while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
377 0 : if ( (rc=iobuf_write(out, copy_buffer, bytes_copied)) ) {
378 0 : log_error ("copying input to output failed: %s\n",
379 : gpg_strerror (rc) );
380 0 : break;
381 : }
382 0 : wipememory (copy_buffer, 4096); /* burn buffer */
383 : }
384 :
385 : /* Finish the stuff. */
386 48 : iobuf_close (inp);
387 48 : if (rc)
388 0 : iobuf_cancel(out);
389 : else
390 : {
391 48 : iobuf_close (out); /* fixme: check returncode */
392 48 : if (mode)
393 48 : write_status ( STATUS_END_ENCRYPTION );
394 : }
395 48 : if (pt)
396 48 : pt->buf = NULL;
397 48 : free_packet (&pkt);
398 48 : xfree (cfx.dek);
399 48 : xfree (s2k);
400 48 : release_armor_context (afx);
401 48 : release_progress_context (pfx);
402 48 : return rc;
403 : }
404 :
405 :
406 : int
407 1 : setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek)
408 : {
409 : int canceled;
410 :
411 1 : *symkey_s2k=xmalloc_clear(sizeof(STRING2KEY));
412 1 : (*symkey_s2k)->mode = opt.s2k_mode;
413 1 : (*symkey_s2k)->hash_algo = S2K_DIGEST_ALGO;
414 :
415 1 : *symkey_dek = passphrase_to_dek (opt.s2k_cipher_algo,
416 : *symkey_s2k, 1, 0, NULL, &canceled);
417 1 : if(!*symkey_dek || !(*symkey_dek)->keylen)
418 : {
419 0 : xfree(*symkey_dek);
420 0 : xfree(*symkey_s2k);
421 0 : return gpg_error (canceled?GPG_ERR_CANCELED:GPG_ERR_BAD_PASSPHRASE);
422 : }
423 :
424 1 : return 0;
425 : }
426 :
427 :
428 : static int
429 1 : write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek,
430 : iobuf_t out)
431 : {
432 1 : int rc, seskeylen = openpgp_cipher_get_algo_keylen (dek->algo);
433 :
434 : PKT_symkey_enc *enc;
435 : byte enckey[33];
436 : PACKET pkt;
437 :
438 1 : enc=xmalloc_clear(sizeof(PKT_symkey_enc)+seskeylen+1);
439 1 : encrypt_seskey(symkey_dek,&dek,enckey);
440 :
441 1 : enc->version = 4;
442 1 : enc->cipher_algo = opt.s2k_cipher_algo;
443 1 : enc->s2k = *symkey_s2k;
444 1 : enc->seskeylen = seskeylen + 1; /* algo id */
445 1 : memcpy( enc->seskey, enckey, seskeylen + 1 );
446 :
447 1 : pkt.pkttype = PKT_SYMKEY_ENC;
448 1 : pkt.pkt.symkey_enc = enc;
449 :
450 1 : if ((rc=build_packet(out,&pkt)))
451 0 : log_error("build symkey_enc packet failed: %s\n",gpg_strerror (rc));
452 :
453 1 : xfree(enc);
454 1 : return rc;
455 : }
456 :
457 :
458 : /*
459 : * Encrypt the file with the given userids (or ask if none is
460 : * supplied). Either FILENAME or FILEFD must be given, but not both.
461 : * The caller may provide a checked list of public keys in
462 : * PROVIDED_PKS; if not the function builds a list of keys on its own.
463 : *
464 : * Note that FILEFD is currently only used by cmd_encrypt in the the
465 : * not yet finished server.c.
466 : */
467 : int
468 219 : encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
469 : strlist_t remusr, int use_symkey, pk_list_t provided_keys,
470 : int outputfd)
471 : {
472 219 : iobuf_t inp = NULL;
473 219 : iobuf_t out = NULL;
474 : PACKET pkt;
475 219 : PKT_plaintext *pt = NULL;
476 219 : DEK *symkey_dek = NULL;
477 219 : STRING2KEY *symkey_s2k = NULL;
478 219 : int rc = 0, rc2 = 0;
479 : u32 filesize;
480 : cipher_filter_context_t cfx;
481 219 : armor_filter_context_t *afx = NULL;
482 : compress_filter_context_t zfx;
483 : text_filter_context_t tfx;
484 : progress_filter_context_t *pfx;
485 : PK_LIST pk_list;
486 : int do_compress;
487 :
488 219 : if (filefd != -1 && filename)
489 0 : return gpg_error (GPG_ERR_INV_ARG); /* Both given. */
490 :
491 219 : do_compress = !!opt.compress_algo;
492 :
493 219 : pfx = new_progress_context ();
494 219 : memset( &cfx, 0, sizeof cfx);
495 219 : memset( &zfx, 0, sizeof zfx);
496 219 : memset( &tfx, 0, sizeof tfx);
497 219 : init_packet(&pkt);
498 :
499 219 : if (use_symkey
500 0 : && (rc=setup_symkey(&symkey_s2k,&symkey_dek)))
501 : {
502 0 : release_progress_context (pfx);
503 0 : return rc;
504 : }
505 :
506 219 : if (provided_keys)
507 0 : pk_list = provided_keys;
508 : else
509 : {
510 219 : if ((rc = build_pk_list (ctrl, remusr, &pk_list)))
511 : {
512 0 : release_progress_context (pfx);
513 0 : return rc;
514 : }
515 : }
516 :
517 : /* Prepare iobufs. */
518 : #ifdef HAVE_W32_SYSTEM
519 : if (filefd == -1)
520 : inp = iobuf_open (filename);
521 : else
522 : {
523 : inp = NULL;
524 : gpg_err_set_errno (ENOSYS);
525 : }
526 : #else
527 219 : if (filefd == GNUPG_INVALID_FD)
528 219 : inp = iobuf_open (filename);
529 : else
530 0 : inp = iobuf_fdopen_nc (FD2INT(filefd), "rb");
531 : #endif
532 219 : if (inp)
533 219 : iobuf_ioctl (inp, IOBUF_IOCTL_NO_CACHE, 1, NULL);
534 219 : if (inp && is_secured_file (iobuf_get_fd (inp)))
535 : {
536 0 : iobuf_close (inp);
537 0 : inp = NULL;
538 0 : gpg_err_set_errno (EPERM);
539 : }
540 219 : if (!inp)
541 : {
542 : char xname[64];
543 :
544 0 : rc = gpg_error_from_syserror ();
545 0 : if (filefd != -1)
546 0 : snprintf (xname, sizeof xname, "[fd %d]", filefd);
547 0 : else if (!filename)
548 0 : strcpy (xname, "[stdin]");
549 : else
550 0 : *xname = 0;
551 0 : log_error (_("can't open '%s': %s\n"),
552 0 : *xname? xname : filename, gpg_strerror (rc) );
553 0 : goto leave;
554 : }
555 :
556 219 : if (opt.verbose)
557 3 : log_info (_("reading from '%s'\n"), iobuf_get_fname_nonnull (inp));
558 :
559 219 : handle_progress (pfx, inp, filename);
560 :
561 219 : if (opt.textmode)
562 0 : iobuf_push_filter (inp, text_filter, &tfx);
563 :
564 219 : rc = open_outfile (outputfd, filename, opt.armor? 1:0, 0, &out);
565 219 : if (rc)
566 0 : goto leave;
567 :
568 219 : if (opt.armor)
569 : {
570 14 : afx = new_armor_context ();
571 14 : push_armor_filter (afx, out);
572 : }
573 :
574 : /* Create a session key. */
575 219 : cfx.dek = xmalloc_secure_clear (sizeof *cfx.dek);
576 219 : if (!opt.def_cipher_algo)
577 : {
578 : /* Try to get it from the prefs. */
579 65 : cfx.dek->algo = select_algo_from_prefs (pk_list, PREFTYPE_SYM, -1, NULL);
580 : /* The only way select_algo_from_prefs can fail here is when
581 : mixing v3 and v4 keys, as v4 keys have an implicit preference
582 : entry for 3DES, and the pk_list cannot be empty. In this
583 : case, use 3DES anyway as it's the safest choice - perhaps the
584 : v3 key is being used in an OpenPGP implementation and we know
585 : that the implementation behind any v4 key can handle 3DES. */
586 65 : if (cfx.dek->algo == -1)
587 : {
588 0 : cfx.dek->algo = CIPHER_ALGO_3DES;
589 : }
590 :
591 : /* In case 3DES has been selected, print a warning if any key
592 : does not have a preference for AES. This should help to
593 : indentify why encrypting to several recipients falls back to
594 : 3DES. */
595 65 : if (opt.verbose && cfx.dek->algo == CIPHER_ALGO_3DES)
596 0 : warn_missing_aes_from_pklist (pk_list);
597 : }
598 : else
599 : {
600 154 : if (!opt.expert
601 308 : && (select_algo_from_prefs (pk_list, PREFTYPE_SYM,
602 : opt.def_cipher_algo, NULL)
603 154 : != opt.def_cipher_algo))
604 : {
605 182 : log_info(_("WARNING: forcing symmetric cipher %s (%d)"
606 : " violates recipient preferences\n"),
607 91 : openpgp_cipher_algo_name (opt.def_cipher_algo),
608 : opt.def_cipher_algo);
609 : }
610 :
611 154 : cfx.dek->algo = opt.def_cipher_algo;
612 : }
613 :
614 219 : cfx.dek->use_mdc = use_mdc (pk_list,cfx.dek->algo);
615 :
616 : /* Only do the is-file-already-compressed check if we are using a
617 : MDC. This forces compressed files to be re-compressed if we do
618 : not have a MDC to give some protection against chosen ciphertext
619 : attacks. */
620 :
621 219 : if (do_compress && cfx.dek->use_mdc && is_file_compressed(filename, &rc2))
622 : {
623 0 : if (opt.verbose)
624 0 : log_info(_("'%s' already compressed\n"), filename);
625 0 : do_compress = 0;
626 : }
627 219 : if (rc2)
628 : {
629 0 : rc = rc2;
630 0 : goto leave;
631 : }
632 :
633 219 : make_session_key (cfx.dek);
634 219 : if (DBG_CRYPTO)
635 0 : log_printhex ("DEK is: ", cfx.dek->key, cfx.dek->keylen );
636 :
637 219 : rc = write_pubkey_enc_from_list (pk_list, cfx.dek, out);
638 219 : if (rc)
639 0 : goto leave;
640 :
641 : /* We put the passphrase (if any) after any public keys as this
642 : seems to be the most useful on the recipient side - there is no
643 : point in prompting a user for a passphrase if they have the
644 : secret key needed to decrypt. */
645 219 : if(use_symkey && (rc = write_symkey_enc(symkey_s2k,symkey_dek,cfx.dek,out)))
646 0 : goto leave;
647 :
648 219 : if (!opt.no_literal)
649 219 : pt = setup_plaintext_name (filename, inp);
650 :
651 : /* Get the size of the file if possible, i.e., if it is a real file. */
652 219 : if (filename && *filename
653 218 : && !iobuf_is_pipe_filename (filename) && !opt.textmode )
654 199 : {
655 : off_t tmpsize;
656 : int overflow;
657 :
658 199 : if ( !(tmpsize = iobuf_get_filelength(inp, &overflow))
659 0 : && !overflow && opt.verbose)
660 0 : log_info(_("WARNING: '%s' is an empty file\n"), filename );
661 : /* We can't encode the length of very large files because
662 : OpenPGP uses only 32 bit for file sizes. So if the the size
663 : of a file is larger than 2^32 minus some bytes for packet
664 : headers, we switch to partial length encoding. */
665 199 : if (tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) )
666 199 : filesize = tmpsize;
667 : else
668 0 : filesize = 0;
669 : }
670 : else
671 20 : filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
672 :
673 219 : if (!opt.no_literal)
674 : {
675 219 : pt->timestamp = make_timestamp();
676 219 : pt->mode = opt.mimemode? 'm' : opt.textmode ? 't' : 'b';
677 219 : pt->len = filesize;
678 219 : pt->new_ctb = !pt->len;
679 219 : pt->buf = inp;
680 219 : pkt.pkttype = PKT_PLAINTEXT;
681 219 : pkt.pkt.plaintext = pt;
682 219 : cfx.datalen = filesize && !do_compress? calc_packet_length( &pkt ) : 0;
683 : }
684 : else
685 0 : cfx.datalen = filesize && !do_compress ? filesize : 0;
686 :
687 : /* Register the cipher filter. */
688 219 : iobuf_push_filter (out, cipher_filter, &cfx);
689 :
690 : /* Register the compress filter. */
691 219 : if (do_compress)
692 : {
693 219 : int compr_algo = opt.compress_algo;
694 :
695 219 : if (compr_algo == -1)
696 : {
697 219 : compr_algo = select_algo_from_prefs (pk_list, PREFTYPE_ZIP, -1, NULL);
698 219 : if (compr_algo == -1)
699 0 : compr_algo = DEFAULT_COMPRESS_ALGO;
700 : /* Theoretically impossible to get here since uncompressed
701 : is implicit. */
702 : }
703 0 : else if (!opt.expert
704 0 : && select_algo_from_prefs(pk_list, PREFTYPE_ZIP,
705 : compr_algo, NULL) != compr_algo)
706 : {
707 0 : log_info (_("WARNING: forcing compression algorithm %s (%d)"
708 : " violates recipient preferences\n"),
709 : compress_algo_to_string(compr_algo), compr_algo);
710 : }
711 :
712 : /* Algo 0 means no compression. */
713 219 : if (compr_algo)
714 : {
715 219 : if (cfx.dek && cfx.dek->use_mdc)
716 179 : zfx.new_ctb = 1;
717 219 : push_compress_filter (out,&zfx,compr_algo);
718 : }
719 : }
720 :
721 : /* Do the work. */
722 219 : if (!opt.no_literal)
723 : {
724 219 : if ((rc = build_packet( out, &pkt )))
725 0 : log_error ("build_packet failed: %s\n", gpg_strerror (rc));
726 : }
727 : else
728 : {
729 : /* User requested not to create a literal packet, so we copy the
730 : plain data. */
731 : byte copy_buffer[4096];
732 : int bytes_copied;
733 0 : while ((bytes_copied = iobuf_read (inp, copy_buffer, 4096)) != -1)
734 : {
735 0 : rc = iobuf_write (out, copy_buffer, bytes_copied);
736 0 : if (rc)
737 : {
738 0 : log_error ("copying input to output failed: %s\n",
739 : gpg_strerror (rc));
740 0 : break;
741 : }
742 : }
743 0 : wipememory (copy_buffer, 4096); /* Burn the buffer. */
744 : }
745 :
746 : /* Finish the stuff. */
747 : leave:
748 219 : iobuf_close (inp);
749 219 : if (rc)
750 0 : iobuf_cancel (out);
751 : else
752 : {
753 219 : iobuf_close (out); /* fixme: check returncode */
754 219 : write_status (STATUS_END_ENCRYPTION);
755 : }
756 219 : if (pt)
757 219 : pt->buf = NULL;
758 219 : free_packet (&pkt);
759 219 : xfree (cfx.dek);
760 219 : xfree (symkey_dek);
761 219 : xfree (symkey_s2k);
762 219 : if (!provided_keys)
763 219 : release_pk_list (pk_list);
764 219 : release_armor_context (afx);
765 219 : release_progress_context (pfx);
766 219 : return rc;
767 : }
768 :
769 :
770 : /*
771 : * Filter to do a complete public key encryption.
772 : */
773 : int
774 181 : encrypt_filter (void *opaque, int control,
775 : iobuf_t a, byte *buf, size_t *ret_len)
776 : {
777 181 : size_t size = *ret_len;
778 181 : encrypt_filter_context_t *efx = opaque;
779 181 : int rc = 0;
780 :
781 181 : if (control == IOBUFCTRL_UNDERFLOW) /* decrypt */
782 : {
783 0 : BUG(); /* not used */
784 : }
785 181 : else if ( control == IOBUFCTRL_FLUSH ) /* encrypt */
786 : {
787 125 : if ( !efx->header_okay )
788 : {
789 28 : efx->cfx.dek = xmalloc_secure_clear ( sizeof *efx->cfx.dek );
790 28 : if ( !opt.def_cipher_algo )
791 : {
792 : /* Try to get it from the prefs. */
793 56 : efx->cfx.dek->algo =
794 28 : select_algo_from_prefs (efx->pk_list, PREFTYPE_SYM, -1, NULL);
795 28 : if (efx->cfx.dek->algo == -1 )
796 : {
797 : /* Because 3DES is implicitly in the prefs, this can
798 : only happen if we do not have any public keys in
799 : the list. */
800 0 : efx->cfx.dek->algo = DEFAULT_CIPHER_ALGO;
801 : }
802 :
803 : /* In case 3DES has been selected, print a warning if
804 : any key does not have a preference for AES. This
805 : should help to indentify why encrypting to several
806 : recipients falls back to 3DES. */
807 28 : if (opt.verbose
808 0 : && efx->cfx.dek->algo == CIPHER_ALGO_3DES)
809 0 : warn_missing_aes_from_pklist (efx->pk_list);
810 : }
811 : else
812 : {
813 0 : if (!opt.expert
814 0 : && select_algo_from_prefs (efx->pk_list,PREFTYPE_SYM,
815 : opt.def_cipher_algo,
816 0 : NULL) != opt.def_cipher_algo)
817 0 : log_info(_("forcing symmetric cipher %s (%d) "
818 : "violates recipient preferences\n"),
819 0 : openpgp_cipher_algo_name (opt.def_cipher_algo),
820 : opt.def_cipher_algo);
821 :
822 0 : efx->cfx.dek->algo = opt.def_cipher_algo;
823 : }
824 :
825 28 : efx->cfx.dek->use_mdc = use_mdc (efx->pk_list,efx->cfx.dek->algo);
826 :
827 28 : make_session_key ( efx->cfx.dek );
828 28 : if (DBG_CRYPTO)
829 0 : log_printhex ("DEK is: ", efx->cfx.dek->key, efx->cfx.dek->keylen);
830 :
831 28 : rc = write_pubkey_enc_from_list (efx->pk_list, efx->cfx.dek, a);
832 28 : if (rc)
833 0 : return rc;
834 :
835 28 : if(efx->symkey_s2k && efx->symkey_dek)
836 : {
837 1 : rc=write_symkey_enc(efx->symkey_s2k,efx->symkey_dek,
838 : efx->cfx.dek,a);
839 1 : if(rc)
840 0 : return rc;
841 : }
842 :
843 28 : iobuf_push_filter (a, cipher_filter, &efx->cfx);
844 :
845 28 : efx->header_okay = 1;
846 : }
847 125 : rc = iobuf_write (a, buf, size);
848 :
849 : }
850 56 : else if (control == IOBUFCTRL_FREE)
851 : {
852 28 : xfree (efx->symkey_dek);
853 28 : xfree (efx->symkey_s2k);
854 : }
855 28 : else if ( control == IOBUFCTRL_DESC )
856 : {
857 0 : mem2str (buf, "encrypt_filter", *ret_len);
858 : }
859 181 : return rc;
860 : }
861 :
862 :
863 : /*
864 : * Write a pubkey-enc packet for the public key PK to OUT.
865 : */
866 : int
867 255 : write_pubkey_enc (PKT_public_key *pk, int throw_keyid, DEK *dek, iobuf_t out)
868 : {
869 : PACKET pkt;
870 : PKT_pubkey_enc *enc;
871 : int rc;
872 : gcry_mpi_t frame;
873 :
874 255 : print_pubkey_algo_note ( pk->pubkey_algo );
875 255 : enc = xmalloc_clear ( sizeof *enc );
876 255 : enc->pubkey_algo = pk->pubkey_algo;
877 255 : keyid_from_pk( pk, enc->keyid );
878 255 : enc->throw_keyid = throw_keyid;
879 :
880 : /* Okay, what's going on: We have the session key somewhere in
881 : * the structure DEK and want to encode this session key in an
882 : * integer value of n bits. pubkey_nbits gives us the number of
883 : * bits we have to use. We then encode the session key in some
884 : * way and we get it back in the big intger value FRAME. Then
885 : * we use FRAME, the public key PK->PKEY and the algorithm
886 : * number PK->PUBKEY_ALGO and pass it to pubkey_encrypt which
887 : * returns the encrypted value in the array ENC->DATA. This
888 : * array has a size which depends on the used algorithm (e.g. 2
889 : * for Elgamal). We don't need frame anymore because we have
890 : * everything now in enc->data which is the passed to
891 : * build_packet(). */
892 255 : frame = encode_session_key (pk->pubkey_algo, dek,
893 255 : pubkey_nbits (pk->pubkey_algo, pk->pkey));
894 255 : rc = pk_encrypt (pk->pubkey_algo, enc->data, frame, pk, pk->pkey);
895 255 : gcry_mpi_release (frame);
896 255 : if (rc)
897 0 : log_error ("pubkey_encrypt failed: %s\n", gpg_strerror (rc) );
898 : else
899 : {
900 255 : if ( opt.verbose )
901 : {
902 6 : char *ustr = get_user_id_string_native (enc->keyid);
903 12 : log_info (_("%s/%s encrypted for: \"%s\"\n"),
904 6 : openpgp_pk_algo_name (enc->pubkey_algo),
905 6 : openpgp_cipher_algo_name (dek->algo),
906 : ustr );
907 6 : xfree (ustr);
908 : }
909 : /* And write it. */
910 255 : init_packet (&pkt);
911 255 : pkt.pkttype = PKT_PUBKEY_ENC;
912 255 : pkt.pkt.pubkey_enc = enc;
913 255 : rc = build_packet (out, &pkt);
914 255 : if (rc)
915 0 : log_error ("build_packet(pubkey_enc) failed: %s\n",
916 : gpg_strerror (rc));
917 : }
918 255 : free_pubkey_enc(enc);
919 255 : return rc;
920 : }
921 :
922 :
923 : /*
924 : * Write pubkey-enc packets from the list of PKs to OUT.
925 : */
926 : static int
927 247 : write_pubkey_enc_from_list (PK_LIST pk_list, DEK *dek, iobuf_t out)
928 : {
929 247 : if (opt.throw_keyids && (PGP6 || PGP7 || PGP8))
930 : {
931 0 : log_info(_("you may not use %s while in %s mode\n"),
932 : "--throw-keyids",compliance_option_string());
933 0 : compliance_failure();
934 : }
935 :
936 502 : for ( ; pk_list; pk_list = pk_list->next )
937 : {
938 255 : PKT_public_key *pk = pk_list->pk;
939 255 : int throw_keyid = (opt.throw_keyids || (pk_list->flags&1));
940 255 : int rc = write_pubkey_enc (pk, throw_keyid, dek, out);
941 255 : if (rc)
942 0 : return rc;
943 : }
944 :
945 247 : return 0;
946 : }
947 :
948 : void
949 0 : encrypt_crypt_files (ctrl_t ctrl, int nfiles, char **files, strlist_t remusr)
950 : {
951 0 : int rc = 0;
952 :
953 0 : if (opt.outfile)
954 : {
955 0 : log_error(_("--output doesn't work for this command\n"));
956 0 : return;
957 : }
958 :
959 0 : if (!nfiles)
960 : {
961 : char line[2048];
962 0 : unsigned int lno = 0;
963 0 : while ( fgets(line, DIM(line), stdin) )
964 : {
965 0 : lno++;
966 0 : if (!*line || line[strlen(line)-1] != '\n')
967 : {
968 0 : log_error("input line %u too long or missing LF\n", lno);
969 0 : return;
970 : }
971 0 : line[strlen(line)-1] = '\0';
972 0 : print_file_status(STATUS_FILE_START, line, 2);
973 0 : rc = encrypt_crypt (ctrl, -1, line, remusr, 0, NULL, -1);
974 0 : if (rc)
975 0 : log_error ("encryption of '%s' failed: %s\n",
976 : print_fname_stdin(line), gpg_strerror (rc) );
977 0 : write_status( STATUS_FILE_DONE );
978 : }
979 : }
980 : else
981 : {
982 0 : while (nfiles--)
983 : {
984 0 : print_file_status(STATUS_FILE_START, *files, 2);
985 0 : if ( (rc = encrypt_crypt (ctrl, -1, *files, remusr, 0, NULL, -1)) )
986 0 : log_error("encryption of '%s' failed: %s\n",
987 : print_fname_stdin(*files), gpg_strerror (rc) );
988 0 : write_status( STATUS_FILE_DONE );
989 0 : files++;
990 : }
991 : }
992 : }
|