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