1 /* encrypt.c - Encrypt a message
2 * Copyright (C) 2001, 2003, 2004, 2007, 2008 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 3 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, see <http://www.gnu.org/licenses/>.
46 typedef struct dek_s
*DEK
;
48 struct encrypt_cb_parm_s
{
55 unsigned char *buffer
;
63 /* Initialize the data encryption key (session key). */
69 dek
->algo
= gcry_cipher_map_name (dek
->algoid
);
70 mode
= gcry_cipher_mode_from_oid (dek
->algoid
);
71 if (!dek
->algo
|| !mode
)
73 log_error ("unsupported algorithm `%s'\n", dek
->algoid
);
74 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM
);
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. */
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
);
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
);
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
);
99 /* Make sure we don't use weak keys. */
100 if (dek
->keylen
< 100/8)
102 log_error ("key length of `%s' too small\n", dek
->algoid
);
103 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM
);
106 rc
= gcry_cipher_open (&dek
->chd
, dek
->algo
, mode
, GCRY_CIPHER_SECURE
);
109 log_error ("failed to create cipher context: %s\n", gpg_strerror (rc
));
113 for (i
=0; i
< 8; i
++)
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
)
119 log_info(_("weak key created - retrying\n") );
123 log_error ("failed to set the key: %s\n", gpg_strerror (rc
));
124 gcry_cipher_close (dek
->chd
);
129 gcry_create_nonce (dek
->iv
, dek
->ivlen
);
130 rc
= gcry_cipher_setiv (dek
->chd
, dek
->iv
, dek
->ivlen
);
133 log_error ("failed to set the IV: %s\n", gpg_strerror (rc
));
134 gcry_cipher_close (dek
->chd
);
144 encode_session_key (DEK dek
, gcry_sexp_t
* r_data
)
150 p
= xtrymalloc (64 + 2 * dek
->keylen
);
152 return gpg_error_from_syserror ();
153 strcpy (p
, "(data\n (flags pkcs1)\n (value #");
154 bin2hex (dek
->key
, dek
->keylen
, p
+ strlen (p
));
156 rc
= gcry_sexp_sscan (&data
, NULL
, p
, strlen (p
));
163 /* Encrypt the DEK under the key contained in CERT and return it as a
164 canonical S-Exp in encval. */
166 encrypt_dek (const DEK dek
, ksba_cert_t cert
, unsigned char **encval
)
168 gcry_sexp_t s_ciph
, s_data
, s_pkey
;
175 /* get the key from the cert */
176 buf
= ksba_cert_get_public_key (cert
);
179 log_error ("no public key for recipient\n");
180 return gpg_error (GPG_ERR_NO_PUBKEY
);
182 len
= gcry_sexp_canon_len (buf
, 0, NULL
, NULL
);
185 log_error ("libksba did not return a proper S-Exp\n");
186 return gpg_error (GPG_ERR_BUG
);
188 rc
= gcry_sexp_sscan (&s_pkey
, NULL
, (char*)buf
, len
);
189 xfree (buf
); buf
= NULL
;
192 log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc
));
196 /* Put the encoded cleartext into a simple list. */
197 s_data
= NULL
; /* (avoid compiler warning) */
198 rc
= encode_session_key (dek
, &s_data
);
201 log_error ("encode_session_key failed: %s\n", gpg_strerror (rc
));
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
);
211 rc
= make_canon_sexp (s_ciph
, encval
, NULL
);
212 gcry_sexp_release (s_ciph
);
218 /* do the actual encryption */
220 encrypt_cb (void *cb_value
, char *buffer
, size_t count
, size_t *nread
)
222 struct encrypt_cb_parm_s
*parm
= cb_value
;
223 int blklen
= parm
->dek
->ivlen
;
229 return -1; /* not supported */
238 { /* fillup the buffer */
240 for (n
=parm
->buflen
; n
< parm
->bufsize
; n
++)
242 int c
= getc (parm
->fp
);
245 if (ferror (parm
->fp
))
247 parm
->readerror
= errno
;
258 n
= parm
->buflen
< count
? parm
->buflen
: count
;
259 n
= n
/blklen
* blklen
;
261 { /* encrypt the stuff */
262 gcry_cipher_encrypt (parm
->dek
->chd
, buffer
, n
, parm
->buffer
, n
);
264 /* Who cares about cycles, take the easy way and shift the buffer */
266 memmove (parm
->buffer
, parm
->buffer
+n
, parm
->buflen
);
268 else if (parm
->eof_seen
)
269 { /* no complete block but eof: add padding */
270 /* fixme: we should try to do this also in the above code path */
271 int i
, npad
= blklen
- (parm
->buflen
% blklen
);
273 for (n
=parm
->buflen
, i
=0; n
< parm
->bufsize
&& i
< npad
; n
++, i
++)
275 gcry_cipher_encrypt (parm
->dek
->chd
, buffer
, n
, parm
->buffer
, n
);
286 /* Perform an encrypt operation.
288 Encrypt the data received on DATA-FD and write it to OUT_FP. The
289 recipients are take from the certificate given in recplist; if this
290 is NULL it will be encrypted for a default recipient */
292 gpgsm_encrypt (ctrl_t ctrl
, certlist_t recplist
, int data_fd
, FILE *out_fp
)
295 Base64Context b64writer
= NULL
;
297 ksba_writer_t writer
;
298 ksba_reader_t reader
= NULL
;
299 ksba_cms_t cms
= NULL
;
300 ksba_stop_reason_t stopreason
;
301 KEYDB_HANDLE kh
= NULL
;
302 struct encrypt_cb_parm_s encparm
;
305 FILE *data_fp
= NULL
;
309 memset (&encparm
, 0, sizeof encparm
);
311 audit_set_type (ctrl
->audit
, AUDIT_TYPE_ENCRYPT
);
313 /* Check that the certificate list is not empty and that at least
314 one certificate is not flagged as encrypt_to; i.e. is a real
316 for (cl
= recplist
; cl
; cl
= cl
->next
)
317 if (!cl
->is_encrypt_to
)
321 log_error(_("no valid recipients given\n"));
322 gpgsm_status (ctrl
, STATUS_NO_RECP
, "0");
323 audit_log_i (ctrl
->audit
, AUDIT_GOT_RECIPIENTS
, 0);
324 rc
= gpg_error (GPG_ERR_NO_PUBKEY
);
328 for (count
= 0, cl
= recplist
; cl
; cl
= cl
->next
)
330 audit_log_i (ctrl
->audit
, AUDIT_GOT_RECIPIENTS
, count
);
335 log_error (_("failed to allocated keyDB handle\n"));
336 rc
= gpg_error (GPG_ERR_GENERAL
);
340 data_fp
= fdopen ( dup (data_fd
), "rb");
343 rc
= gpg_error (gpg_err_code_from_errno (errno
));
344 log_error ("fdopen() failed: %s\n", strerror (errno
));
348 err
= ksba_reader_new (&reader
);
352 rc
= ksba_reader_set_cb (reader
, encrypt_cb
, &encparm
);
356 encparm
.fp
= data_fp
;
358 ctrl
->pem_name
= "ENCRYPTED MESSAGE";
359 rc
= gpgsm_create_writer (&b64writer
, ctrl
, out_fp
, NULL
, &writer
);
362 log_error ("can't create writer: %s\n", gpg_strerror (rc
));
366 err
= ksba_cms_new (&cms
);
373 err
= ksba_cms_set_reader_writer (cms
, reader
, writer
);
376 log_debug ("ksba_cms_set_reader_writer failed: %s\n",
382 audit_log (ctrl
->audit
, AUDIT_GOT_DATA
);
384 /* We are going to create enveloped data with uninterpreted data as
386 err
= ksba_cms_set_content_type (cms
, 0, KSBA_CT_ENVELOPED_DATA
);
388 err
= ksba_cms_set_content_type (cms
, 1, KSBA_CT_DATA
);
391 log_debug ("ksba_cms_set_content_type failed: %s\n",
397 /* Create a session key */
398 dek
= xtrycalloc_secure (1, sizeof *dek
);
403 dek
->algoid
= opt
.def_cipher_algoid
;
408 log_error ("failed to create the session key: %s\n",
413 err
= ksba_cms_set_content_enc_algo (cms
, dek
->algoid
, dek
->iv
, dek
->ivlen
);
416 log_error ("ksba_cms_set_content_enc_algo failed: %s\n",
423 /* Use a ~8k (AES) or ~4k (3DES) buffer */
424 encparm
.bufsize
= 500 * dek
->ivlen
;
425 encparm
.buffer
= xtrymalloc (encparm
.bufsize
);
432 audit_log_s (ctrl
->audit
, AUDIT_SESSION_KEY
, dek
->algoid
);
434 /* Gather certificates of recipients, encrypt the session key for
435 each and store them in the CMS object */
436 for (recpno
= 0, cl
= recplist
; cl
; recpno
++, cl
= cl
->next
)
438 unsigned char *encval
;
440 rc
= encrypt_dek (dek
, cl
->cert
, &encval
);
443 audit_log_cert (ctrl
->audit
, AUDIT_ENCRYPTED_TO
, cl
->cert
, rc
);
444 log_error ("encryption failed for recipient no. %d: %s\n",
445 recpno
, gpg_strerror (rc
));
449 err
= ksba_cms_add_recipient (cms
, cl
->cert
);
452 audit_log_cert (ctrl
->audit
, AUDIT_ENCRYPTED_TO
, cl
->cert
, err
);
453 log_error ("ksba_cms_add_recipient failed: %s\n",
460 err
= ksba_cms_set_enc_val (cms
, recpno
, encval
);
462 audit_log_cert (ctrl
->audit
, AUDIT_ENCRYPTED_TO
, cl
->cert
, err
);
465 log_error ("ksba_cms_set_enc_val failed: %s\n",
472 /* Main control loop for encryption. */
476 err
= ksba_cms_build (cms
, &stopreason
);
479 log_debug ("ksba_cms_build failed: %s\n", gpg_strerror (err
));
484 while (stopreason
!= KSBA_SR_READY
);
486 if (encparm
.readerror
)
488 log_error ("error reading input: %s\n", strerror (encparm
.readerror
));
489 rc
= gpg_error (gpg_err_code_from_errno (encparm
.readerror
));
494 rc
= gpgsm_finish_writer (b64writer
);
497 log_error ("write failed: %s\n", gpg_strerror (rc
));
500 audit_log (ctrl
->audit
, AUDIT_ENCRYPTION_DONE
);
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
);