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 len
= gcry_sexp_sprint (s_ciph
, GCRYSEXP_FMT_CANON
, NULL
, 0);
213 buf
= xtrymalloc (len
);
216 gpg_error_t tmperr
= out_of_core ();
217 gcry_sexp_release (s_ciph
);
220 len
= gcry_sexp_sprint (s_ciph
, GCRYSEXP_FMT_CANON
, (char*)buf
, len
);
222 gcry_sexp_release (s_ciph
);
230 /* do the actual encryption */
232 encrypt_cb (void *cb_value
, char *buffer
, size_t count
, size_t *nread
)
234 struct encrypt_cb_parm_s
*parm
= cb_value
;
235 int blklen
= parm
->dek
->ivlen
;
241 return -1; /* not supported */
250 { /* fillup the buffer */
252 for (n
=parm
->buflen
; n
< parm
->bufsize
; n
++)
254 int c
= getc (parm
->fp
);
257 if (ferror (parm
->fp
))
259 parm
->readerror
= errno
;
270 n
= parm
->buflen
< count
? parm
->buflen
: count
;
271 n
= n
/blklen
* blklen
;
273 { /* encrypt the stuff */
274 gcry_cipher_encrypt (parm
->dek
->chd
, buffer
, n
, parm
->buffer
, n
);
276 /* Who cares about cycles, take the easy way and shift the buffer */
278 memmove (parm
->buffer
, parm
->buffer
+n
, parm
->buflen
);
280 else if (parm
->eof_seen
)
281 { /* no complete block but eof: add padding */
282 /* fixme: we should try to do this also in the above code path */
283 int i
, npad
= blklen
- (parm
->buflen
% blklen
);
285 for (n
=parm
->buflen
, i
=0; n
< parm
->bufsize
&& i
< npad
; n
++, i
++)
287 gcry_cipher_encrypt (parm
->dek
->chd
, buffer
, n
, parm
->buffer
, n
);
298 /* Perform an encrypt operation.
300 Encrypt the data received on DATA-FD and write it to OUT_FP. The
301 recipients are take from the certificate given in recplist; if this
302 is NULL it will be encrypted for a default recipient */
304 gpgsm_encrypt (ctrl_t ctrl
, certlist_t recplist
, int data_fd
, FILE *out_fp
)
307 Base64Context b64writer
= NULL
;
309 ksba_writer_t writer
;
310 ksba_reader_t reader
= NULL
;
311 ksba_cms_t cms
= NULL
;
312 ksba_stop_reason_t stopreason
;
313 KEYDB_HANDLE kh
= NULL
;
314 struct encrypt_cb_parm_s encparm
;
317 FILE *data_fp
= NULL
;
321 memset (&encparm
, 0, sizeof encparm
);
323 audit_set_type (ctrl
->audit
, AUDIT_TYPE_ENCRYPT
);
325 /* Check that the certificate list is not empty and that at least
326 one certificate is not flagged as encrypt_to; i.e. is a real
328 for (cl
= recplist
; cl
; cl
= cl
->next
)
329 if (!cl
->is_encrypt_to
)
333 log_error(_("no valid recipients given\n"));
334 gpgsm_status (ctrl
, STATUS_NO_RECP
, "0");
335 audit_log_i (ctrl
->audit
, AUDIT_GOT_RECIPIENTS
, 0);
336 rc
= gpg_error (GPG_ERR_NO_PUBKEY
);
340 for (count
= 0, cl
= recplist
; cl
; cl
= cl
->next
)
342 audit_log_i (ctrl
->audit
, AUDIT_GOT_RECIPIENTS
, count
);
347 log_error (_("failed to allocated keyDB handle\n"));
348 rc
= gpg_error (GPG_ERR_GENERAL
);
352 data_fp
= fdopen ( dup (data_fd
), "rb");
355 rc
= gpg_error (gpg_err_code_from_errno (errno
));
356 log_error ("fdopen() failed: %s\n", strerror (errno
));
360 err
= ksba_reader_new (&reader
);
364 rc
= ksba_reader_set_cb (reader
, encrypt_cb
, &encparm
);
368 encparm
.fp
= data_fp
;
370 ctrl
->pem_name
= "ENCRYPTED MESSAGE";
371 rc
= gpgsm_create_writer (&b64writer
, ctrl
, out_fp
, NULL
, &writer
);
374 log_error ("can't create writer: %s\n", gpg_strerror (rc
));
378 err
= ksba_cms_new (&cms
);
385 err
= ksba_cms_set_reader_writer (cms
, reader
, writer
);
388 log_debug ("ksba_cms_set_reader_writer failed: %s\n",
394 audit_log (ctrl
->audit
, AUDIT_GOT_DATA
);
396 /* We are going to create enveloped data with uninterpreted data as
398 err
= ksba_cms_set_content_type (cms
, 0, KSBA_CT_ENVELOPED_DATA
);
400 err
= ksba_cms_set_content_type (cms
, 1, KSBA_CT_DATA
);
403 log_debug ("ksba_cms_set_content_type failed: %s\n",
409 /* Create a session key */
410 dek
= xtrycalloc_secure (1, sizeof *dek
);
415 dek
->algoid
= opt
.def_cipher_algoid
;
420 log_error ("failed to create the session key: %s\n",
425 err
= ksba_cms_set_content_enc_algo (cms
, dek
->algoid
, dek
->iv
, dek
->ivlen
);
428 log_error ("ksba_cms_set_content_enc_algo failed: %s\n",
435 /* Use a ~8k (AES) or ~4k (3DES) buffer */
436 encparm
.bufsize
= 500 * dek
->ivlen
;
437 encparm
.buffer
= xtrymalloc (encparm
.bufsize
);
444 audit_log_s (ctrl
->audit
, AUDIT_SESSION_KEY
, dek
->algoid
);
446 /* Gather certificates of recipients, encrypt the session key for
447 each and store them in the CMS object */
448 for (recpno
= 0, cl
= recplist
; cl
; recpno
++, cl
= cl
->next
)
450 unsigned char *encval
;
452 rc
= encrypt_dek (dek
, cl
->cert
, &encval
);
455 audit_log_cert (ctrl
->audit
, AUDIT_ENCRYPTED_TO
, cl
->cert
, rc
);
456 log_error ("encryption failed for recipient no. %d: %s\n",
457 recpno
, gpg_strerror (rc
));
461 err
= ksba_cms_add_recipient (cms
, cl
->cert
);
464 audit_log_cert (ctrl
->audit
, AUDIT_ENCRYPTED_TO
, cl
->cert
, err
);
465 log_error ("ksba_cms_add_recipient failed: %s\n",
472 err
= ksba_cms_set_enc_val (cms
, recpno
, encval
);
474 audit_log_cert (ctrl
->audit
, AUDIT_ENCRYPTED_TO
, cl
->cert
, err
);
477 log_error ("ksba_cms_set_enc_val failed: %s\n",
484 /* Main control loop for encryption. */
488 err
= ksba_cms_build (cms
, &stopreason
);
491 log_debug ("ksba_cms_build failed: %s\n", gpg_strerror (err
));
496 while (stopreason
!= KSBA_SR_READY
);
498 if (encparm
.readerror
)
500 log_error ("error reading input: %s\n", strerror (encparm
.readerror
));
501 rc
= gpg_error (gpg_err_code_from_errno (encparm
.readerror
));
506 rc
= gpgsm_finish_writer (b64writer
);
509 log_error ("write failed: %s\n", gpg_strerror (rc
));
512 audit_log (ctrl
->audit
, AUDIT_ENCRYPTION_DONE
);
513 log_info ("encrypted data created\n");
516 ksba_cms_release (cms
);
517 gpgsm_destroy_writer (b64writer
);
518 ksba_reader_release (reader
);
523 xfree (encparm
.buffer
);