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