chiark / gitweb /
Import gnupg2_2.1.17.orig.tar.bz2
[gnupg2.git] / sm / encrypt.c
1 /* encrypt.c - Encrypt a message
2  * Copyright (C) 2001, 2003, 2004, 2007, 2008,
3  *               2010 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 3 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, see <https://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <unistd.h>
27 #include <time.h>
28 #include <assert.h>
29
30 #include "gpgsm.h"
31 #include <gcrypt.h>
32 #include <ksba.h>
33
34 #include "keydb.h"
35 #include "i18n.h"
36
37
38 struct dek_s {
39   const char *algoid;
40   int algo;
41   gcry_cipher_hd_t chd;
42   char key[32];
43   int keylen;
44   char iv[32];
45   int ivlen;
46 };
47 typedef struct dek_s *DEK;
48
49
50 /* Callback parameters for the encryption.  */
51 struct encrypt_cb_parm_s
52 {
53   estream_t fp;
54   DEK dek;
55   int eof_seen;
56   int ready;
57   int readerror;
58   int bufsize;
59   unsigned char *buffer;
60   int buflen;
61 };
62
63
64
65
66 \f
67 /* Initialize the data encryption key (session key). */
68 static int
69 init_dek (DEK dek)
70 {
71   int rc=0, mode, i;
72
73   dek->algo = gcry_cipher_map_name (dek->algoid);
74   mode = gcry_cipher_mode_from_oid (dek->algoid);
75   if (!dek->algo || !mode)
76     {
77       log_error ("unsupported algorithm '%s'\n", dek->algoid);
78       return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
79     }
80
81   /* Extra check for algorithms we consider to be too weak for
82      encryption, although we support them for decryption.  Note that
83      there is another check below discriminating on the key length. */
84   switch (dek->algo)
85     {
86     case GCRY_CIPHER_DES:
87     case GCRY_CIPHER_RFC2268_40:
88       log_error ("cipher algorithm '%s' not allowed: too weak\n",
89                  gnupg_cipher_algo_name (dek->algo));
90       return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
91     default:
92       break;
93     }
94
95   dek->keylen = gcry_cipher_get_algo_keylen (dek->algo);
96   if (!dek->keylen || dek->keylen > sizeof (dek->key))
97     return gpg_error (GPG_ERR_BUG);
98
99   dek->ivlen = gcry_cipher_get_algo_blklen (dek->algo);
100   if (!dek->ivlen || dek->ivlen > sizeof (dek->iv))
101     return gpg_error (GPG_ERR_BUG);
102
103   /* Make sure we don't use weak keys. */
104   if (dek->keylen < 100/8)
105     {
106       log_error ("key length of '%s' too small\n", dek->algoid);
107       return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
108     }
109
110   rc = gcry_cipher_open (&dek->chd, dek->algo, mode, GCRY_CIPHER_SECURE);
111   if (rc)
112     {
113       log_error ("failed to create cipher context: %s\n", gpg_strerror (rc));
114       return rc;
115     }
116
117   for (i=0; i < 8; i++)
118     {
119       gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM );
120       rc = gcry_cipher_setkey (dek->chd, dek->key, dek->keylen);
121       if (gpg_err_code (rc) != GPG_ERR_WEAK_KEY)
122         break;
123       log_info(_("weak key created - retrying\n") );
124     }
125   if (rc)
126     {
127       log_error ("failed to set the key: %s\n", gpg_strerror (rc));
128       gcry_cipher_close (dek->chd);
129       dek->chd = NULL;
130       return rc;
131     }
132
133   gcry_create_nonce (dek->iv, dek->ivlen);
134   rc = gcry_cipher_setiv (dek->chd, dek->iv, dek->ivlen);
135   if (rc)
136     {
137       log_error ("failed to set the IV: %s\n", gpg_strerror (rc));
138       gcry_cipher_close (dek->chd);
139       dek->chd = NULL;
140       return rc;
141     }
142
143   return 0;
144 }
145
146
147 static int
148 encode_session_key (DEK dek, gcry_sexp_t * r_data)
149 {
150   gcry_sexp_t data;
151   char *p;
152   int rc;
153
154   p = xtrymalloc (64 + 2 * dek->keylen);
155   if (!p)
156     return gpg_error_from_syserror ();
157   strcpy (p, "(data\n (flags pkcs1)\n (value #");
158   bin2hex (dek->key, dek->keylen, p + strlen (p));
159   strcat (p, "#))\n");
160   rc = gcry_sexp_sscan (&data, NULL, p, strlen (p));
161   xfree (p);
162   *r_data = data;
163   return rc;
164 }
165
166
167 /* Encrypt the DEK under the key contained in CERT and return it as a
168    canonical S-Exp in encval. */
169 static int
170 encrypt_dek (const DEK dek, ksba_cert_t cert, unsigned char **encval)
171 {
172   gcry_sexp_t s_ciph, s_data, s_pkey;
173   int rc;
174   ksba_sexp_t buf;
175   size_t len;
176
177   *encval = NULL;
178
179   /* get the key from the cert */
180   buf = ksba_cert_get_public_key (cert);
181   if (!buf)
182     {
183       log_error ("no public key for recipient\n");
184       return gpg_error (GPG_ERR_NO_PUBKEY);
185     }
186   len = gcry_sexp_canon_len (buf, 0, NULL, NULL);
187   if (!len)
188     {
189       log_error ("libksba did not return a proper S-Exp\n");
190       return gpg_error (GPG_ERR_BUG);
191     }
192   rc = gcry_sexp_sscan (&s_pkey, NULL, (char*)buf, len);
193   xfree (buf); buf = NULL;
194   if (rc)
195     {
196       log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
197       return rc;
198     }
199
200   /* Put the encoded cleartext into a simple list. */
201   s_data = NULL; /* (avoid compiler warning) */
202   rc = encode_session_key (dek, &s_data);
203   if (rc)
204     {
205       log_error ("encode_session_key failed: %s\n", gpg_strerror (rc));
206       return rc;
207     }
208
209   /* pass it to libgcrypt */
210   rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey);
211   gcry_sexp_release (s_data);
212   gcry_sexp_release (s_pkey);
213
214   /* Reformat it. */
215   if (!rc)
216     {
217       rc = make_canon_sexp (s_ciph, encval, NULL);
218       gcry_sexp_release (s_ciph);
219     }
220   return rc;
221 }
222
223
224 \f
225 /* do the actual encryption */
226 static int
227 encrypt_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
228 {
229   struct encrypt_cb_parm_s *parm = cb_value;
230   int blklen = parm->dek->ivlen;
231   unsigned char *p;
232   size_t n;
233
234   *nread = 0;
235   if (!buffer)
236     return -1; /* not supported */
237
238   if (parm->ready)
239     return -1;
240
241   if (count < blklen)
242     BUG ();
243
244   if (!parm->eof_seen)
245     { /* fillup the buffer */
246       p = parm->buffer;
247       for (n=parm->buflen; n < parm->bufsize; n++)
248         {
249           int c = es_getc (parm->fp);
250           if (c == EOF)
251             {
252               if (es_ferror (parm->fp))
253                 {
254                   parm->readerror = errno;
255                   return -1;
256                 }
257               parm->eof_seen = 1;
258               break;
259             }
260           p[n] = c;
261         }
262       parm->buflen = n;
263     }
264
265   n = parm->buflen < count? parm->buflen : count;
266   n = n/blklen * blklen;
267   if (n)
268     { /* encrypt the stuff */
269       gcry_cipher_encrypt (parm->dek->chd, buffer, n, parm->buffer, n);
270       *nread = n;
271       /* Who cares about cycles, take the easy way and shift the buffer */
272       parm->buflen -= n;
273       memmove (parm->buffer, parm->buffer+n, parm->buflen);
274     }
275   else if (parm->eof_seen)
276     { /* no complete block but eof: add padding */
277       /* fixme: we should try to do this also in the above code path */
278       int i, npad = blklen - (parm->buflen % blklen);
279       p = parm->buffer;
280       for (n=parm->buflen, i=0; n < parm->bufsize && i < npad; n++, i++)
281         p[n] = npad;
282       gcry_cipher_encrypt (parm->dek->chd, buffer, n, parm->buffer, n);
283       *nread = n;
284       parm->ready = 1;
285     }
286
287   return 0;
288 }
289
290
291
292 \f
293 /* Perform an encrypt operation.
294
295    Encrypt the data received on DATA-FD and write it to OUT_FP.  The
296    recipients are take from the certificate given in recplist; if this
297    is NULL it will be encrypted for a default recipient */
298 int
299 gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, estream_t out_fp)
300 {
301   int rc = 0;
302   Base64Context b64writer = NULL;
303   gpg_error_t err;
304   ksba_writer_t writer;
305   ksba_reader_t reader = NULL;
306   ksba_cms_t cms = NULL;
307   ksba_stop_reason_t stopreason;
308   KEYDB_HANDLE kh = NULL;
309   struct encrypt_cb_parm_s encparm;
310   DEK dek = NULL;
311   int recpno;
312   estream_t data_fp = NULL;
313   certlist_t cl;
314   int count;
315
316   memset (&encparm, 0, sizeof encparm);
317
318   audit_set_type (ctrl->audit, AUDIT_TYPE_ENCRYPT);
319
320   /* Check that the certificate list is not empty and that at least
321      one certificate is not flagged as encrypt_to; i.e. is a real
322      recipient. */
323   for (cl = recplist; cl; cl = cl->next)
324     if (!cl->is_encrypt_to)
325       break;
326   if (!cl)
327     {
328       log_error(_("no valid recipients given\n"));
329       gpgsm_status (ctrl, STATUS_NO_RECP, "0");
330       audit_log_i (ctrl->audit, AUDIT_GOT_RECIPIENTS, 0);
331       rc = gpg_error (GPG_ERR_NO_PUBKEY);
332       goto leave;
333     }
334
335   for (count = 0, cl = recplist; cl; cl = cl->next)
336     count++;
337   audit_log_i (ctrl->audit, AUDIT_GOT_RECIPIENTS, count);
338
339   kh = keydb_new ();
340   if (!kh)
341     {
342       log_error (_("failed to allocate keyDB handle\n"));
343       rc = gpg_error (GPG_ERR_GENERAL);
344       goto leave;
345     }
346
347   /* Fixme:  We should use the unlocked version of the es functions.  */
348   data_fp = es_fdopen_nc (data_fd, "rb");
349   if (!data_fp)
350     {
351       rc = gpg_error_from_syserror ();
352       log_error ("fdopen() failed: %s\n", strerror (errno));
353       goto leave;
354     }
355
356   err = ksba_reader_new (&reader);
357   if (err)
358       rc = err;
359   if (!rc)
360     rc = ksba_reader_set_cb (reader, encrypt_cb, &encparm);
361   if (rc)
362       goto leave;
363
364   encparm.fp = data_fp;
365
366   ctrl->pem_name = "ENCRYPTED MESSAGE";
367   rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
368   if (rc)
369     {
370       log_error ("can't create writer: %s\n", gpg_strerror (rc));
371       goto leave;
372     }
373
374   err = ksba_cms_new (&cms);
375   if (err)
376     {
377       rc = err;
378       goto leave;
379     }
380
381   err = ksba_cms_set_reader_writer (cms, reader, writer);
382   if (err)
383     {
384       log_debug ("ksba_cms_set_reader_writer failed: %s\n",
385                  gpg_strerror (err));
386       rc = err;
387       goto leave;
388     }
389
390   audit_log (ctrl->audit, AUDIT_GOT_DATA);
391
392   /* We are going to create enveloped data with uninterpreted data as
393      inner content */
394   err = ksba_cms_set_content_type (cms, 0, KSBA_CT_ENVELOPED_DATA);
395   if (!err)
396     err = ksba_cms_set_content_type (cms, 1, KSBA_CT_DATA);
397   if (err)
398     {
399       log_debug ("ksba_cms_set_content_type failed: %s\n",
400                  gpg_strerror (err));
401       rc = err;
402       goto leave;
403     }
404
405   /* Create a session key */
406   dek = xtrycalloc_secure (1, sizeof *dek);
407   if (!dek)
408     rc = out_of_core ();
409   else
410   {
411     dek->algoid = opt.def_cipher_algoid;
412     rc = init_dek (dek);
413   }
414   if (rc)
415     {
416       log_error ("failed to create the session key: %s\n",
417                  gpg_strerror (rc));
418       goto leave;
419     }
420
421   err = ksba_cms_set_content_enc_algo (cms, dek->algoid, dek->iv, dek->ivlen);
422   if (err)
423     {
424       log_error ("ksba_cms_set_content_enc_algo failed: %s\n",
425                  gpg_strerror (err));
426       rc = err;
427       goto leave;
428     }
429
430   encparm.dek = dek;
431   /* Use a ~8k (AES) or ~4k (3DES) buffer */
432   encparm.bufsize = 500 * dek->ivlen;
433   encparm.buffer = xtrymalloc (encparm.bufsize);
434   if (!encparm.buffer)
435     {
436       rc = out_of_core ();
437       goto leave;
438     }
439
440   audit_log_s (ctrl->audit, AUDIT_SESSION_KEY, dek->algoid);
441
442   /* Gather certificates of recipients, encrypt the session key for
443      each and store them in the CMS object */
444   for (recpno = 0, cl = recplist; cl; recpno++, cl = cl->next)
445     {
446       unsigned char *encval;
447
448       rc = encrypt_dek (dek, cl->cert, &encval);
449       if (rc)
450         {
451           audit_log_cert (ctrl->audit, AUDIT_ENCRYPTED_TO, cl->cert, rc);
452           log_error ("encryption failed for recipient no. %d: %s\n",
453                      recpno, gpg_strerror (rc));
454           goto leave;
455         }
456
457       err = ksba_cms_add_recipient (cms, cl->cert);
458       if (err)
459         {
460           audit_log_cert (ctrl->audit, AUDIT_ENCRYPTED_TO, cl->cert, err);
461           log_error ("ksba_cms_add_recipient failed: %s\n",
462                      gpg_strerror (err));
463           rc = err;
464           xfree (encval);
465           goto leave;
466         }
467
468       err = ksba_cms_set_enc_val (cms, recpno, encval);
469       xfree (encval);
470       audit_log_cert (ctrl->audit, AUDIT_ENCRYPTED_TO, cl->cert, err);
471       if (err)
472         {
473           log_error ("ksba_cms_set_enc_val failed: %s\n",
474                      gpg_strerror (err));
475           rc = err;
476           goto leave;
477         }
478     }
479
480   /* Main control loop for encryption. */
481   recpno = 0;
482   do
483     {
484       err = ksba_cms_build (cms, &stopreason);
485       if (err)
486         {
487           log_debug ("ksba_cms_build failed: %s\n", gpg_strerror (err));
488           rc = err;
489           goto leave;
490         }
491     }
492   while (stopreason != KSBA_SR_READY);
493
494   if (encparm.readerror)
495     {
496       log_error ("error reading input: %s\n", strerror (encparm.readerror));
497       rc = gpg_error (gpg_err_code_from_errno (encparm.readerror));
498       goto leave;
499     }
500
501
502   rc = gpgsm_finish_writer (b64writer);
503   if (rc)
504     {
505       log_error ("write failed: %s\n", gpg_strerror (rc));
506       goto leave;
507     }
508   audit_log (ctrl->audit, AUDIT_ENCRYPTION_DONE);
509   log_info ("encrypted data created\n");
510
511  leave:
512   ksba_cms_release (cms);
513   gpgsm_destroy_writer (b64writer);
514   ksba_reader_release (reader);
515   keydb_release (kh);
516   xfree (dek);
517   es_fclose (data_fp);
518   xfree (encparm.buffer);
519   return rc;
520 }