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