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,
48 typedef struct dek_s
*DEK
;
50 struct encrypt_cb_parm_s
{
57 unsigned char *buffer
;
65 /* Initialize the data encryption key (session key). */
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. */
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
);
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
);
111 log_error ("failed to create cipher context: %s\n", gpg_strerror (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
)
121 log_info(_("weak key created - retrying\n") );
125 log_error ("failed to set the key: %s\n", gpg_strerror (rc
));
126 gcry_cipher_close (dek
->chd
);
131 gcry_create_nonce (dek
->iv
, dek
->ivlen
);
132 rc
= gcry_cipher_setiv (dek
->chd
, dek
->iv
, dek
->ivlen
);
135 log_error ("failed to set the IV: %s\n", gpg_strerror (rc
));
136 gcry_cipher_close (dek
->chd
);
146 encode_session_key (DEK dek
, gcry_sexp_t
* r_data
)
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
]);
161 rc
= gcry_sexp_sscan (&data
, NULL
, p
, strlen (p
));
168 /* Encrypt the DEK under the key contained in CERT and return it as a
169 canonical S-Exp in encval. */
171 encrypt_dek (const DEK dek
, ksba_cert_t cert
, unsigned char **encval
)
173 gcry_sexp_t s_ciph
, s_data
, s_pkey
;
180 /* get the key from the cert */
181 buf
= ksba_cert_get_public_key (cert
);
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
);
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
;
197 log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc
));
201 /* put the encoded cleartext into a simple list */
202 rc
= encode_session_key (dek
, &s_data
);
205 log_error ("encode_session_key failed: %s\n", gpg_strerror (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
);
215 len
= gcry_sexp_sprint (s_ciph
, GCRYSEXP_FMT_CANON
, NULL
, 0);
217 buf
= xtrymalloc (len
);
220 gpg_error_t tmperr
= out_of_core ();
221 gcry_sexp_release (s_ciph
);
224 len
= gcry_sexp_sprint (s_ciph
, GCRYSEXP_FMT_CANON
, (char*)buf
, len
);
226 gcry_sexp_release (s_ciph
);
234 /* do the actual encryption */
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
;
245 return -1; /* not supported */
254 { /* fillup the buffer */
256 for (n
=parm
->buflen
; n
< parm
->bufsize
; n
++)
258 int c
= getc (parm
->fp
);
261 if (ferror (parm
->fp
))
263 parm
->readerror
= errno
;
274 n
= parm
->buflen
< count
? parm
->buflen
: count
;
275 n
= n
/blklen
* blklen
;
277 { /* encrypt the stuff */
278 gcry_cipher_encrypt (parm
->dek
->chd
, buffer
, n
, parm
->buffer
, n
);
280 /* Who cares about cycles, take the easy way and shift the buffer */
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
);
289 for (n
=parm
->buflen
, i
=0; n
< parm
->bufsize
&& i
< npad
; n
++, i
++)
291 gcry_cipher_encrypt (parm
->dek
->chd
, buffer
, n
, parm
->buffer
, n
);
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
)
311 Base64Context b64writer
= NULL
;
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
;
321 FILE *data_fp
= NULL
;
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
329 for (cl
= recplist
; cl
; cl
= cl
->next
)
330 if (!cl
->is_encrypt_to
)
334 log_error(_("no valid recipients given\n"));
335 gpgsm_status (ctrl
, STATUS_NO_RECP
, "0");
336 rc
= gpg_error (GPG_ERR_NO_PUBKEY
);
343 log_error (_("failed to allocated keyDB handle\n"));
344 rc
= gpg_error (GPG_ERR_GENERAL
);
348 data_fp
= fdopen ( dup (data_fd
), "rb");
351 rc
= gpg_error (gpg_err_code_from_errno (errno
));
352 log_error ("fdopen() failed: %s\n", strerror (errno
));
356 err
= ksba_reader_new (&reader
);
360 rc
= ksba_reader_set_cb (reader
, encrypt_cb
, &encparm
);
364 encparm
.fp
= data_fp
;
366 ctrl
->pem_name
= "ENCRYPTED MESSAGE";
367 rc
= gpgsm_create_writer (&b64writer
, ctrl
, out_fp
, &writer
);
370 log_error ("can't create writer: %s\n", gpg_strerror (rc
));
374 err
= ksba_cms_new (&cms
);
381 err
= ksba_cms_set_reader_writer (cms
, reader
, writer
);
384 log_debug ("ksba_cms_set_reader_writer failed: %s\n",
390 /* We are going to create enveloped data with uninterpreted data as
392 err
= ksba_cms_set_content_type (cms
, 0, KSBA_CT_ENVELOPED_DATA
);
394 err
= ksba_cms_set_content_type (cms
, 1, KSBA_CT_DATA
);
397 log_debug ("ksba_cms_set_content_type failed: %s\n",
403 /* Create a session key */
404 dek
= xtrycalloc_secure (1, sizeof *dek
);
409 dek
->algoid
= opt
.def_cipher_algoid
;
414 log_error ("failed to create the session key: %s\n",
419 err
= ksba_cms_set_content_enc_algo (cms
, dek
->algoid
, dek
->iv
, dek
->ivlen
);
422 log_error ("ksba_cms_set_content_enc_algo failed: %s\n",
429 /* Use a ~8k (AES) or ~4k (3DES) buffer */
430 encparm
.bufsize
= 500 * dek
->ivlen
;
431 encparm
.buffer
= xtrymalloc (encparm
.bufsize
);
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
);
447 log_error ("encryption failed for recipient no. %d: %s\n",
448 recpno
, gpg_strerror (rc
));
452 err
= ksba_cms_add_recipient (cms
, cl
->cert
);
455 log_error ("ksba_cms_add_recipient failed: %s\n",
462 err
= ksba_cms_set_enc_val (cms
, recpno
, encval
);
466 log_error ("ksba_cms_set_enc_val failed: %s\n",
473 /* Main control loop for encryption. */
477 err
= ksba_cms_build (cms
, &stopreason
);
480 log_debug ("ksba_cms_build failed: %s\n", gpg_strerror (err
));
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
));
495 rc
= gpgsm_finish_writer (b64writer
);
498 log_error ("write failed: %s\n", gpg_strerror (rc
));
501 log_info ("encrypted data created\n");
504 ksba_cms_release (cms
);
505 gpgsm_destroy_writer (b64writer
);
506 ksba_reader_release (reader
);
511 xfree (encparm
.buffer
);