1e36e960ceecdde83b3646ddcd929dd4d1daf72d
[gnupg.git] / sm / encrypt.c
1 /* encrypt.c - Encrypt a message
2  *      Copyright (C) 2001, 2003, 2004 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
322   memset (&encparm, 0, sizeof encparm);
323
324   /* Check that the certificate list is not empty and that at least
325      one certificate is not flagged as encrypt_to; i.e. is a real
326      recipient. */
327   for (cl = recplist; cl; cl = cl->next)
328     if (!cl->is_encrypt_to)
329       break;
330   if (!cl)
331     {
332       log_error(_("no valid recipients given\n"));
333       gpgsm_status (ctrl, STATUS_NO_RECP, "0");
334       rc = gpg_error (GPG_ERR_NO_PUBKEY);
335       goto leave;
336     }
337
338   kh = keydb_new (0);
339   if (!kh)
340     {
341       log_error (_("failed to allocated keyDB handle\n"));
342       rc = gpg_error (GPG_ERR_GENERAL);
343       goto leave;
344     }
345
346   data_fp = fdopen ( dup (data_fd), "rb");
347   if (!data_fp)
348     {
349       rc = gpg_error (gpg_err_code_from_errno (errno));
350       log_error ("fdopen() failed: %s\n", strerror (errno));
351       goto leave;
352     }
353
354   err = ksba_reader_new (&reader);
355   if (err)
356       rc = err;
357   if (!rc)
358     rc = ksba_reader_set_cb (reader, encrypt_cb, &encparm);
359   if (rc)
360       goto leave;
361
362   encparm.fp = data_fp;
363
364   ctrl->pem_name = "ENCRYPTED MESSAGE";
365   rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, NULL, &writer);
366   if (rc)
367     {
368       log_error ("can't create writer: %s\n", gpg_strerror (rc));
369       goto leave;
370     }
371
372   err = ksba_cms_new (&cms);
373   if (err)
374     {
375       rc = err;
376       goto leave;
377     }
378
379   err = ksba_cms_set_reader_writer (cms, reader, writer);
380   if (err)
381     {
382       log_debug ("ksba_cms_set_reader_writer failed: %s\n",
383                  gpg_strerror (err));
384       rc = err;
385       goto leave;
386     }
387
388   /* We are going to create enveloped data with uninterpreted data as
389      inner content */
390   err = ksba_cms_set_content_type (cms, 0, KSBA_CT_ENVELOPED_DATA);
391   if (!err)
392     err = ksba_cms_set_content_type (cms, 1, KSBA_CT_DATA);
393   if (err)
394     {
395       log_debug ("ksba_cms_set_content_type failed: %s\n",
396                  gpg_strerror (err));
397       rc = err;
398       goto leave;
399     }
400
401   /* Create a session key */
402   dek = xtrycalloc_secure (1, sizeof *dek); 
403   if (!dek)
404     rc = out_of_core ();
405   else
406   {
407     dek->algoid = opt.def_cipher_algoid;
408     rc = init_dek (dek);
409   }
410   if (rc)
411     {
412       log_error ("failed to create the session key: %s\n",
413                  gpg_strerror (rc));
414       goto leave;
415     }
416
417   err = ksba_cms_set_content_enc_algo (cms, dek->algoid, dek->iv, dek->ivlen);
418   if (err)
419     {
420       log_error ("ksba_cms_set_content_enc_algo failed: %s\n",
421                  gpg_strerror (err));
422       rc = err;
423       goto leave;
424     }
425
426   encparm.dek = dek;
427   /* Use a ~8k (AES) or ~4k (3DES) buffer */
428   encparm.bufsize = 500 * dek->ivlen;
429   encparm.buffer = xtrymalloc (encparm.bufsize);
430   if (!encparm.buffer)
431     {
432       rc = out_of_core ();
433       goto leave;
434     }
435
436   /* Gather certificates of recipients, encrypt the session key for
437      each and store them in the CMS object */
438   for (recpno = 0, cl = recplist; cl; recpno++, cl = cl->next)
439     {
440       unsigned char *encval;
441       
442       rc = encrypt_dek (dek, cl->cert, &encval);
443       if (rc)
444         {
445           log_error ("encryption failed for recipient no. %d: %s\n",
446                      recpno, gpg_strerror (rc));
447           goto leave;
448         }
449       
450       err = ksba_cms_add_recipient (cms, cl->cert);
451       if (err)
452         {
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       if (err)
463         {
464           log_error ("ksba_cms_set_enc_val failed: %s\n",
465                      gpg_strerror (err));
466           rc = err;
467           goto leave;
468         }
469   }
470
471   /* Main control loop for encryption. */
472   recpno = 0;
473   do 
474     {
475       err = ksba_cms_build (cms, &stopreason);
476       if (err)
477         {
478           log_debug ("ksba_cms_build failed: %s\n", gpg_strerror (err));
479           rc = err;
480           goto leave;
481         }
482     }
483   while (stopreason != KSBA_SR_READY);   
484
485   if (encparm.readerror)
486     {
487       log_error ("error reading input: %s\n", strerror (encparm.readerror));
488       rc = gpg_error (gpg_err_code_from_errno (encparm.readerror));
489       goto leave;
490     }
491
492
493   rc = gpgsm_finish_writer (b64writer);
494   if (rc) 
495     {
496       log_error ("write failed: %s\n", gpg_strerror (rc));
497       goto leave;
498     }
499   log_info ("encrypted data created\n");
500
501  leave:
502   ksba_cms_release (cms);
503   gpgsm_destroy_writer (b64writer);
504   ksba_reader_release (reader);
505   keydb_release (kh); 
506   xfree (dek);
507   if (data_fp)
508     fclose (data_fp);
509   xfree (encparm.buffer);
510   return rc;
511 }