2006-12-21 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / sm / encrypt.c
blob056599a64eb82822a5c4e4504d7ed3b85514c211
1 /* encrypt.c - Encrypt a message
2 * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
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 2 of the License, or
9 * (at your option) any later version.
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.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19 * USA.
22 #include <config.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <unistd.h>
28 #include <time.h>
29 #include <assert.h>
31 #include "gpgsm.h"
32 #include <gcrypt.h>
33 #include <ksba.h>
35 #include "keydb.h"
36 #include "i18n.h"
39 struct dek_s {
40 const char *algoid;
41 int algo;
42 gcry_cipher_hd_t chd;
43 char key[32];
44 int keylen;
45 char iv[32];
46 int ivlen;
48 typedef struct dek_s *DEK;
50 struct encrypt_cb_parm_s {
51 FILE *fp;
52 DEK dek;
53 int eof_seen;
54 int ready;
55 int readerror;
56 int bufsize;
57 unsigned char *buffer;
58 int buflen;
65 /* Initialize the data encryption key (session key). */
66 static int
67 init_dek (DEK dek)
69 int rc=0, mode, i;
71 dek->algo = gcry_cipher_map_name (dek->algoid);
72 mode = gcry_cipher_mode_from_oid (dek->algoid);
73 if (!dek->algo || !mode)
75 log_error ("unsupported algorithm `%s'\n", dek->algoid);
76 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
79 /* Extra check for algorithms we considere to be to weak for
80 encryption, qlthough we suppor them fro decryption. Note that
81 there is another check below discriminating on the key length. */
82 switch (dek->algo)
84 case GCRY_CIPHER_DES:
85 case GCRY_CIPHER_RFC2268_40:
86 log_error ("cipher algorithm `%s' not allowed: too weak\n",
87 gcry_cipher_algo_name (dek->algo));
88 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
89 default:
90 break;
93 dek->keylen = gcry_cipher_get_algo_keylen (dek->algo);
94 if (!dek->keylen || dek->keylen > sizeof (dek->key))
95 return gpg_error (GPG_ERR_BUG);
97 dek->ivlen = gcry_cipher_get_algo_blklen (dek->algo);
98 if (!dek->ivlen || dek->ivlen > sizeof (dek->iv))
99 return gpg_error (GPG_ERR_BUG);
101 /* Make sure we don't use weak keys. */
102 if (dek->keylen < 100/8)
104 log_error ("key length of `%s' too small\n", dek->algoid);
105 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
108 rc = gcry_cipher_open (&dek->chd, dek->algo, mode, GCRY_CIPHER_SECURE);
109 if (rc)
111 log_error ("failed to create cipher context: %s\n", gpg_strerror (rc));
112 return rc;
115 for (i=0; i < 8; i++)
117 gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM );
118 rc = gcry_cipher_setkey (dek->chd, dek->key, dek->keylen);
119 if (gpg_err_code (rc) != GPG_ERR_WEAK_KEY)
120 break;
121 log_info(_("weak key created - retrying\n") );
123 if (rc)
125 log_error ("failed to set the key: %s\n", gpg_strerror (rc));
126 gcry_cipher_close (dek->chd);
127 dek->chd = NULL;
128 return rc;
131 gcry_create_nonce (dek->iv, dek->ivlen);
132 rc = gcry_cipher_setiv (dek->chd, dek->iv, dek->ivlen);
133 if (rc)
135 log_error ("failed to set the IV: %s\n", gpg_strerror (rc));
136 gcry_cipher_close (dek->chd);
137 dek->chd = NULL;
138 return rc;
141 return 0;
145 static int
146 encode_session_key (DEK dek, gcry_sexp_t * r_data)
148 gcry_sexp_t data;
149 char * p, tmp[3];
150 int i;
151 int rc;
153 p = xmalloc (64 + 2 * dek->keylen);
154 strcpy (p, "(data\n (flags pkcs1)\n (value #");
155 for (i=0; i < dek->keylen; i++)
157 sprintf (tmp, "%02x", (unsigned char) dek->key[i]);
158 strcat (p, tmp);
160 strcat (p, "#))\n");
161 rc = gcry_sexp_sscan (&data, NULL, p, strlen (p));
162 xfree (p);
163 *r_data = data;
164 return rc;
168 /* Encrypt the DEK under the key contained in CERT and return it as a
169 canonical S-Exp in encval. */
170 static int
171 encrypt_dek (const DEK dek, ksba_cert_t cert, unsigned char **encval)
173 gcry_sexp_t s_ciph, s_data, s_pkey;
174 int rc;
175 ksba_sexp_t buf;
176 size_t len;
178 *encval = NULL;
180 /* get the key from the cert */
181 buf = ksba_cert_get_public_key (cert);
182 if (!buf)
184 log_error ("no public key for recipient\n");
185 return gpg_error (GPG_ERR_NO_PUBKEY);
187 len = gcry_sexp_canon_len (buf, 0, NULL, NULL);
188 if (!len)
190 log_error ("libksba did not return a proper S-Exp\n");
191 return gpg_error (GPG_ERR_BUG);
193 rc = gcry_sexp_sscan (&s_pkey, NULL, (char*)buf, len);
194 xfree (buf); buf = NULL;
195 if (rc)
197 log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
198 return rc;
201 /* put the encoded cleartext into a simple list */
202 rc = encode_session_key (dek, &s_data);
203 if (rc)
205 log_error ("encode_session_key failed: %s\n", gpg_strerror (rc));
206 return rc;
209 /* pass it to libgcrypt */
210 rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey);
211 gcry_sexp_release (s_data);
212 gcry_sexp_release (s_pkey);
214 /* reformat it */
215 len = gcry_sexp_sprint (s_ciph, GCRYSEXP_FMT_CANON, NULL, 0);
216 assert (len);
217 buf = xtrymalloc (len);
218 if (!buf)
220 gpg_error_t tmperr = out_of_core ();
221 gcry_sexp_release (s_ciph);
222 return tmperr;
224 len = gcry_sexp_sprint (s_ciph, GCRYSEXP_FMT_CANON, (char*)buf, len);
225 assert (len);
226 gcry_sexp_release (s_ciph);
228 *encval = buf;
229 return 0;
234 /* do the actual encryption */
235 static int
236 encrypt_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
238 struct encrypt_cb_parm_s *parm = cb_value;
239 int blklen = parm->dek->ivlen;
240 unsigned char *p;
241 size_t n;
243 *nread = 0;
244 if (!buffer)
245 return -1; /* not supported */
247 if (parm->ready)
248 return -1;
250 if (count < blklen)
251 BUG ();
253 if (!parm->eof_seen)
254 { /* fillup the buffer */
255 p = parm->buffer;
256 for (n=parm->buflen; n < parm->bufsize; n++)
258 int c = getc (parm->fp);
259 if (c == EOF)
261 if (ferror (parm->fp))
263 parm->readerror = errno;
264 return -1;
266 parm->eof_seen = 1;
267 break;
269 p[n] = c;
271 parm->buflen = n;
274 n = parm->buflen < count? parm->buflen : count;
275 n = n/blklen * blklen;
276 if (n)
277 { /* encrypt the stuff */
278 gcry_cipher_encrypt (parm->dek->chd, buffer, n, parm->buffer, n);
279 *nread = n;
280 /* Who cares about cycles, take the easy way and shift the buffer */
281 parm->buflen -= n;
282 memmove (parm->buffer, parm->buffer+n, parm->buflen);
284 else if (parm->eof_seen)
285 { /* no complete block but eof: add padding */
286 /* fixme: we should try to do this also in the above code path */
287 int i, npad = blklen - (parm->buflen % blklen);
288 p = parm->buffer;
289 for (n=parm->buflen, i=0; n < parm->bufsize && i < npad; n++, i++)
290 p[n] = npad;
291 gcry_cipher_encrypt (parm->dek->chd, buffer, n, parm->buffer, n);
292 *nread = n;
293 parm->ready = 1;
296 return 0;
302 /* Perform an encrypt operation.
304 Encrypt the data received on DATA-FD and write it to OUT_FP. The
305 recipients are take from the certificate given in recplist; if this
306 is NULL it will be encrypted for a default recipient */
308 gpgsm_encrypt (ctrl_t ctrl, certlist_t recplist, int data_fd, FILE *out_fp)
310 int rc = 0;
311 Base64Context b64writer = NULL;
312 gpg_error_t err;
313 ksba_writer_t writer;
314 ksba_reader_t reader = NULL;
315 ksba_cms_t cms = NULL;
316 ksba_stop_reason_t stopreason;
317 KEYDB_HANDLE kh = NULL;
318 struct encrypt_cb_parm_s encparm;
319 DEK dek = NULL;
320 int recpno;
321 FILE *data_fp = NULL;
322 certlist_t cl;
324 memset (&encparm, 0, sizeof encparm);
326 /* Check that the certificate list is not empty and that at least
327 one certificate is not flagged as encrypt_to; i.e. is a real
328 recipient. */
329 for (cl = recplist; cl; cl = cl->next)
330 if (!cl->is_encrypt_to)
331 break;
332 if (!cl)
334 log_error(_("no valid recipients given\n"));
335 gpgsm_status (ctrl, STATUS_NO_RECP, "0");
336 rc = gpg_error (GPG_ERR_NO_PUBKEY);
337 goto leave;
340 kh = keydb_new (0);
341 if (!kh)
343 log_error (_("failed to allocated keyDB handle\n"));
344 rc = gpg_error (GPG_ERR_GENERAL);
345 goto leave;
348 data_fp = fdopen ( dup (data_fd), "rb");
349 if (!data_fp)
351 rc = gpg_error (gpg_err_code_from_errno (errno));
352 log_error ("fdopen() failed: %s\n", strerror (errno));
353 goto leave;
356 err = ksba_reader_new (&reader);
357 if (err)
358 rc = err;
359 if (!rc)
360 rc = ksba_reader_set_cb (reader, encrypt_cb, &encparm);
361 if (rc)
362 goto leave;
364 encparm.fp = data_fp;
366 ctrl->pem_name = "ENCRYPTED MESSAGE";
367 rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
368 if (rc)
370 log_error ("can't create writer: %s\n", gpg_strerror (rc));
371 goto leave;
374 err = ksba_cms_new (&cms);
375 if (err)
377 rc = err;
378 goto leave;
381 err = ksba_cms_set_reader_writer (cms, reader, writer);
382 if (err)
384 log_debug ("ksba_cms_set_reader_writer failed: %s\n",
385 gpg_strerror (err));
386 rc = err;
387 goto leave;
390 /* We are going to create enveloped data with uninterpreted data as
391 inner content */
392 err = ksba_cms_set_content_type (cms, 0, KSBA_CT_ENVELOPED_DATA);
393 if (!err)
394 err = ksba_cms_set_content_type (cms, 1, KSBA_CT_DATA);
395 if (err)
397 log_debug ("ksba_cms_set_content_type failed: %s\n",
398 gpg_strerror (err));
399 rc = err;
400 goto leave;
403 /* Create a session key */
404 dek = xtrycalloc_secure (1, sizeof *dek);
405 if (!dek)
406 rc = out_of_core ();
407 else
409 dek->algoid = opt.def_cipher_algoid;
410 rc = init_dek (dek);
412 if (rc)
414 log_error ("failed to create the session key: %s\n",
415 gpg_strerror (rc));
416 goto leave;
419 err = ksba_cms_set_content_enc_algo (cms, dek->algoid, dek->iv, dek->ivlen);
420 if (err)
422 log_error ("ksba_cms_set_content_enc_algo failed: %s\n",
423 gpg_strerror (err));
424 rc = err;
425 goto leave;
428 encparm.dek = dek;
429 /* Use a ~8k (AES) or ~4k (3DES) buffer */
430 encparm.bufsize = 500 * dek->ivlen;
431 encparm.buffer = xtrymalloc (encparm.bufsize);
432 if (!encparm.buffer)
434 rc = out_of_core ();
435 goto leave;
438 /* Gather certificates of recipients, encrypt the session key for
439 each and store them in the CMS object */
440 for (recpno = 0, cl = recplist; cl; recpno++, cl = cl->next)
442 unsigned char *encval;
444 rc = encrypt_dek (dek, cl->cert, &encval);
445 if (rc)
447 log_error ("encryption failed for recipient no. %d: %s\n",
448 recpno, gpg_strerror (rc));
449 goto leave;
452 err = ksba_cms_add_recipient (cms, cl->cert);
453 if (err)
455 log_error ("ksba_cms_add_recipient failed: %s\n",
456 gpg_strerror (err));
457 rc = err;
458 xfree (encval);
459 goto leave;
462 err = ksba_cms_set_enc_val (cms, recpno, encval);
463 xfree (encval);
464 if (err)
466 log_error ("ksba_cms_set_enc_val failed: %s\n",
467 gpg_strerror (err));
468 rc = err;
469 goto leave;
473 /* Main control loop for encryption. */
474 recpno = 0;
477 err = ksba_cms_build (cms, &stopreason);
478 if (err)
480 log_debug ("ksba_cms_build failed: %s\n", gpg_strerror (err));
481 rc = err;
482 goto leave;
485 while (stopreason != KSBA_SR_READY);
487 if (encparm.readerror)
489 log_error ("error reading input: %s\n", strerror (encparm.readerror));
490 rc = gpg_error (gpg_err_code_from_errno (encparm.readerror));
491 goto leave;
495 rc = gpgsm_finish_writer (b64writer);
496 if (rc)
498 log_error ("write failed: %s\n", gpg_strerror (rc));
499 goto leave;
501 log_info ("encrypted data created\n");
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;