Fix for bug#1066.
[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   rc = make_canon_sexp (s_ciph, encval, NULL);
212   gcry_sexp_release (s_ciph);
213   return rc;
214 }
215
216
217 \f
218 /* do the actual encryption */
219 static int
220 encrypt_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
221 {
222   struct encrypt_cb_parm_s *parm = cb_value;
223   int blklen = parm->dek->ivlen;
224   unsigned char *p;
225   size_t n;
226
227   *nread = 0;
228   if (!buffer)
229     return -1; /* not supported */
230
231   if (parm->ready)
232     return -1;
233
234   if (count < blklen)
235     BUG ();
236      
237   if (!parm->eof_seen)
238     { /* fillup the buffer */
239       p = parm->buffer;
240       for (n=parm->buflen; n < parm->bufsize; n++)
241         {
242           int c = getc (parm->fp);
243           if (c == EOF)
244             {
245               if (ferror (parm->fp))
246                 {
247                   parm->readerror = errno;
248                   return -1;
249                 }
250               parm->eof_seen = 1;
251               break; 
252             }
253           p[n] = c;
254         }
255       parm->buflen = n;
256     }
257   
258   n = parm->buflen < count? parm->buflen : count;
259   n = n/blklen * blklen;
260   if (n)
261     { /* encrypt the stuff */
262       gcry_cipher_encrypt (parm->dek->chd, buffer, n, parm->buffer, n);
263       *nread = n;
264       /* Who cares about cycles, take the easy way and shift the buffer */
265       parm->buflen -= n;
266       memmove (parm->buffer, parm->buffer+n, parm->buflen);
267     }
268   else if (parm->eof_seen)
269     { /* no complete block but eof: add padding */
270       /* fixme: we should try to do this also in the above code path */
271       int i, npad = blklen - (parm->buflen % blklen);
272       p = parm->buffer;
273       for (n=parm->buflen, i=0; n < parm->bufsize && i < npad; n++, i++)
274         p[n] = npad;
275       gcry_cipher_encrypt (parm->dek->chd, buffer, n, parm->buffer, n);
276       *nread = n;
277       parm->ready = 1;
278     }
279
280   return 0;
281 }
282
283
284
285 \f
286 /* Perform an encrypt operation.  
287
288    Encrypt the data received on DATA-FD and write it to OUT_FP.  The
289    recipients are take from the certificate given in recplist; if this
290    is NULL it will be encrypted for a default recipient */
291 int
292 gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, FILE *out_fp)
293 {
294   int rc = 0;
295   Base64Context b64writer = NULL;
296   gpg_error_t err;
297   ksba_writer_t writer;
298   ksba_reader_t reader = NULL;
299   ksba_cms_t cms = NULL;
300   ksba_stop_reason_t stopreason;
301   KEYDB_HANDLE kh = NULL;
302   struct encrypt_cb_parm_s encparm;
303   DEK dek = NULL;
304   int recpno;
305   FILE *data_fp = NULL;
306   certlist_t cl;
307   int count;
308
309   memset (&encparm, 0, sizeof encparm);
310
311   audit_set_type (ctrl->audit, AUDIT_TYPE_ENCRYPT);
312
313   /* Check that the certificate list is not empty and that at least
314      one certificate is not flagged as encrypt_to; i.e. is a real
315      recipient. */
316   for (cl = recplist; cl; cl = cl->next)
317     if (!cl->is_encrypt_to)
318       break;
319   if (!cl)
320     {
321       log_error(_("no valid recipients given\n"));
322       gpgsm_status (ctrl, STATUS_NO_RECP, "0");
323       audit_log_i (ctrl->audit, AUDIT_GOT_RECIPIENTS, 0);
324       rc = gpg_error (GPG_ERR_NO_PUBKEY);
325       goto leave;
326     }
327
328   for (count = 0, cl = recplist; cl; cl = cl->next)
329     count++;
330   audit_log_i (ctrl->audit, AUDIT_GOT_RECIPIENTS, count);
331
332   kh = keydb_new (0);
333   if (!kh)
334     {
335       log_error (_("failed to allocated keyDB handle\n"));
336       rc = gpg_error (GPG_ERR_GENERAL);
337       goto leave;
338     }
339
340   data_fp = fdopen ( dup (data_fd), "rb");
341   if (!data_fp)
342     {
343       rc = gpg_error (gpg_err_code_from_errno (errno));
344       log_error ("fdopen() failed: %s\n", strerror (errno));
345       goto leave;
346     }
347
348   err = ksba_reader_new (&reader);
349   if (err)
350       rc = err;
351   if (!rc)
352     rc = ksba_reader_set_cb (reader, encrypt_cb, &encparm);
353   if (rc)
354       goto leave;
355
356   encparm.fp = data_fp;
357
358   ctrl->pem_name = "ENCRYPTED MESSAGE";
359   rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, NULL, &writer);
360   if (rc)
361     {
362       log_error ("can't create writer: %s\n", gpg_strerror (rc));
363       goto leave;
364     }
365
366   err = ksba_cms_new (&cms);
367   if (err)
368     {
369       rc = err;
370       goto leave;
371     }
372
373   err = ksba_cms_set_reader_writer (cms, reader, writer);
374   if (err)
375     {
376       log_debug ("ksba_cms_set_reader_writer failed: %s\n",
377                  gpg_strerror (err));
378       rc = err;
379       goto leave;
380     }
381
382   audit_log (ctrl->audit, AUDIT_GOT_DATA);
383
384   /* We are going to create enveloped data with uninterpreted data as
385      inner content */
386   err = ksba_cms_set_content_type (cms, 0, KSBA_CT_ENVELOPED_DATA);
387   if (!err)
388     err = ksba_cms_set_content_type (cms, 1, KSBA_CT_DATA);
389   if (err)
390     {
391       log_debug ("ksba_cms_set_content_type failed: %s\n",
392                  gpg_strerror (err));
393       rc = err;
394       goto leave;
395     }
396
397   /* Create a session key */
398   dek = xtrycalloc_secure (1, sizeof *dek); 
399   if (!dek)
400     rc = out_of_core ();
401   else
402   {
403     dek->algoid = opt.def_cipher_algoid;
404     rc = init_dek (dek);
405   }
406   if (rc)
407     {
408       log_error ("failed to create the session key: %s\n",
409                  gpg_strerror (rc));
410       goto leave;
411     }
412
413   err = ksba_cms_set_content_enc_algo (cms, dek->algoid, dek->iv, dek->ivlen);
414   if (err)
415     {
416       log_error ("ksba_cms_set_content_enc_algo failed: %s\n",
417                  gpg_strerror (err));
418       rc = err;
419       goto leave;
420     }
421
422   encparm.dek = dek;
423   /* Use a ~8k (AES) or ~4k (3DES) buffer */
424   encparm.bufsize = 500 * dek->ivlen;
425   encparm.buffer = xtrymalloc (encparm.bufsize);
426   if (!encparm.buffer)
427     {
428       rc = out_of_core ();
429       goto leave;
430     }
431   
432   audit_log_s (ctrl->audit, AUDIT_SESSION_KEY, dek->algoid);
433
434   /* Gather certificates of recipients, encrypt the session key for
435      each and store them in the CMS object */
436   for (recpno = 0, cl = recplist; cl; recpno++, cl = cl->next)
437     {
438       unsigned char *encval;
439       
440       rc = encrypt_dek (dek, cl->cert, &encval);
441       if (rc)
442         {
443           audit_log_cert (ctrl->audit, AUDIT_ENCRYPTED_TO, cl->cert, rc);
444           log_error ("encryption failed for recipient no. %d: %s\n",
445                      recpno, gpg_strerror (rc));
446           goto leave;
447         }
448       
449       err = ksba_cms_add_recipient (cms, cl->cert);
450       if (err)
451         {
452           audit_log_cert (ctrl->audit, AUDIT_ENCRYPTED_TO, cl->cert, err);
453           log_error ("ksba_cms_add_recipient failed: %s\n",
454                      gpg_strerror (err));
455           rc = err;
456           xfree (encval);
457           goto leave;
458         }
459       
460       err = ksba_cms_set_enc_val (cms, recpno, encval);
461       xfree (encval);
462       audit_log_cert (ctrl->audit, AUDIT_ENCRYPTED_TO, cl->cert, err);
463       if (err)
464         {
465           log_error ("ksba_cms_set_enc_val failed: %s\n",
466                      gpg_strerror (err));
467           rc = err;
468           goto leave;
469         }
470     }
471
472   /* Main control loop for encryption. */
473   recpno = 0;
474   do 
475     {
476       err = ksba_cms_build (cms, &stopreason);
477       if (err)
478         {
479           log_debug ("ksba_cms_build failed: %s\n", gpg_strerror (err));
480           rc = err;
481           goto leave;
482         }
483     }
484   while (stopreason != KSBA_SR_READY);   
485
486   if (encparm.readerror)
487     {
488       log_error ("error reading input: %s\n", strerror (encparm.readerror));
489       rc = gpg_error (gpg_err_code_from_errno (encparm.readerror));
490       goto leave;
491     }
492
493
494   rc = gpgsm_finish_writer (b64writer);
495   if (rc) 
496     {
497       log_error ("write failed: %s\n", gpg_strerror (rc));
498       goto leave;
499     }
500   audit_log (ctrl->audit, AUDIT_ENCRYPTION_DONE);
501   log_info ("encrypted data created\n");
502
503  leave:
504   ksba_cms_release (cms);
505   gpgsm_destroy_writer (b64writer);
506   ksba_reader_release (reader);
507   keydb_release (kh); 
508   xfree (dek);
509   if (data_fp)
510     fclose (data_fp);
511   xfree (encparm.buffer);
512   return rc;
513 }