1
/* decrypt.c - Decrypt a message
2
* Copyright (C) 2001, 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
37
struct decrypt_filter_parm_s {
44
int any_data; /* dod we push anything through the filter at all? */
45
unsigned char lastblock[16]; /* to strip the padding we have to
47
char helpblock[16]; /* needed because there is no block buffering in
54
/* Decrypt the session key and fill in the parm structure. The
55
algo and the IV is expected to be already in PARM. */
57
prepare_decryption (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
58
ksba_const_sexp_t enc_val,
59
struct decrypt_filter_parm_s *parm)
65
rc = gpgsm_agent_pkdecrypt (ctrl, hexkeygrip, desc, enc_val,
69
log_error ("error decrypting session key: %s\n", gpg_strerror (rc));
74
log_printhex ("pkcs1 encoded session key:", seskey, seskeylen);
79
/* Smells like a 3-des key. This might happen because a SC has
80
already done the unpacking. */
84
if (n + 7 > seskeylen )
86
rc = gpg_error (GPG_ERR_INV_SESSION_KEY);
90
/* FIXME: Actually the leading zero is required but due to the way
91
we encode the output in libgcrypt as an MPI we are not able to
92
encode that leading zero. However, when using a Smartcard we are
93
doing it the right way and therefore we have to skip the zero. This
94
should be fixed in gpg-agent of course. */
98
if (seskey[n] != 2 ) /* Wrong block type version. */
100
rc = gpg_error (GPG_ERR_INV_SESSION_KEY);
104
for (n++; n < seskeylen && seskey[n]; n++) /* Skip the random bytes. */
106
n++; /* and the zero byte */
109
rc = gpg_error (GPG_ERR_INV_SESSION_KEY);
115
log_printhex ("session key:", seskey+n, seskeylen-n);
117
rc = gcry_cipher_open (&parm->hd, parm->algo, parm->mode, 0);
120
log_error ("error creating decryptor: %s\n", gpg_strerror (rc));
124
rc = gcry_cipher_setkey (parm->hd, seskey+n, seskeylen-n);
125
if (gpg_err_code (rc) == GPG_ERR_WEAK_KEY)
127
log_info (_("WARNING: message was encrypted with "
128
"a weak key in the symmetric cipher.\n"));
133
log_error("key setup failed: %s\n", gpg_strerror(rc) );
137
gcry_cipher_setiv (parm->hd, parm->iv, parm->ivlen);
145
/* This function is called by the KSBA writer just before the actual
146
write is done. The function must take INLEN bytes from INBUF,
147
decrypt it and store it inoutbuf which has a maximum size of
148
maxoutlen. The valid bytes in outbuf should be return in outlen.
149
Due to different buffer sizes or different length of input and
150
output, it may happen that fewer bytes are process or fewer bytes
153
decrypt_filter (void *arg,
154
const void *inbuf, size_t inlen, size_t *inused,
155
void *outbuf, size_t maxoutlen, size_t *outlen)
157
struct decrypt_filter_parm_s *parm = arg;
158
int blklen = parm->blklen;
159
size_t orig_inlen = inlen;
161
/* fixme: Should we issue an error when we have not seen one full block? */
163
return gpg_error (GPG_ERR_BUG);
165
if (maxoutlen < 2*parm->blklen)
166
return gpg_error (GPG_ERR_BUG);
167
/* make some space becuase we will later need an extra block at the end */
170
if (parm->helpblocklen)
174
for (i=parm->helpblocklen,j=0; i < blklen && j < inlen; i++, j++)
175
parm->helpblock[i] = ((const char*)inbuf)[j];
177
if (blklen > maxoutlen)
178
return gpg_error (GPG_ERR_BUG);
181
parm->helpblocklen = i;
186
parm->helpblocklen = 0;
189
memcpy (outbuf, parm->lastblock, blklen);
194
gcry_cipher_decrypt (parm->hd, parm->lastblock, blklen,
195
parm->helpblock, blklen);
198
*inused = orig_inlen - inlen;
203
if (inlen > maxoutlen)
206
{ /* store the remainder away */
207
parm->helpblocklen = inlen%blklen;
208
inlen = inlen/blklen*blklen;
209
memcpy (parm->helpblock, (const char*)inbuf+inlen, parm->helpblocklen);
212
*inused = inlen + parm->helpblocklen;
215
assert (inlen >= blklen);
218
gcry_cipher_decrypt (parm->hd, (char*)outbuf+blklen, inlen,
220
memcpy (outbuf, parm->lastblock, blklen);
221
memcpy (parm->lastblock,(char*)outbuf+inlen, blklen);
226
gcry_cipher_decrypt (parm->hd, outbuf, inlen, inbuf, inlen);
227
memcpy (parm->lastblock, (char*)outbuf+inlen-blklen, blklen);
228
*outlen = inlen - blklen;
239
/* Perform a decrypt operation. */
241
gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp)
244
Base64Context b64reader = NULL;
245
Base64Context b64writer = NULL;
246
ksba_reader_t reader;
247
ksba_writer_t writer;
248
ksba_cms_t cms = NULL;
249
ksba_stop_reason_t stopreason;
253
struct decrypt_filter_parm_s dfparm;
255
memset (&dfparm, 0, sizeof dfparm);
260
log_error (_("failed to allocated keyDB handle\n"));
261
rc = gpg_error (GPG_ERR_GENERAL);
266
in_fp = fdopen ( dup (in_fd), "rb");
269
rc = gpg_error (gpg_err_code_from_errno (errno));
270
log_error ("fdopen() failed: %s\n", strerror (errno));
274
rc = gpgsm_create_reader (&b64reader, ctrl, in_fp, 0, &reader);
277
log_error ("can't create reader: %s\n", gpg_strerror (rc));
281
rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
284
log_error ("can't create writer: %s\n", gpg_strerror (rc));
288
rc = ksba_cms_new (&cms);
292
rc = ksba_cms_set_reader_writer (cms, reader, writer);
295
log_debug ("ksba_cms_set_reader_writer failed: %s\n",
303
rc = ksba_cms_parse (cms, &stopreason);
306
log_debug ("ksba_cms_parse failed: %s\n", gpg_strerror (rc));
310
if (stopreason == KSBA_SR_BEGIN_DATA
311
|| stopreason == KSBA_SR_DETACHED_DATA)
317
algoid = ksba_cms_get_content_oid (cms, 2/* encryption algo*/);
318
algo = gcry_cipher_map_name (algoid);
319
mode = gcry_cipher_mode_from_oid (algoid);
322
rc = gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
323
log_error ("unsupported algorithm `%s'\n", algoid? algoid:"?");
324
if (algoid && !strcmp (algoid, "1.2.840.113549.3.2"))
325
log_info (_("(this is the RC2 algorithm)\n"));
327
log_info (_("(this does not seem to be an encrypted"
331
sprintf (numbuf, "%d", rc);
332
gpgsm_status2 (ctrl, STATUS_ERROR, "decrypt.algorithm",
333
numbuf, algoid?algoid:"?", NULL);
336
/* If it seems that this is not an encrypted message we
337
return a more sensible error code. */
339
rc = gpg_error (GPG_ERR_NO_DATA);
345
dfparm.blklen = gcry_cipher_get_algo_blklen (algo);
346
if (dfparm.blklen > sizeof (dfparm.helpblock))
347
return gpg_error (GPG_ERR_BUG);
349
rc = ksba_cms_get_content_enc_iv (cms,
355
log_error ("error getting IV: %s\n", gpg_strerror (rc));
359
for (recp=0; !any_key; recp++)
364
char *hexkeygrip = NULL;
367
rc = ksba_cms_get_issuer_serial (cms, recp, &issuer, &serial);
368
if (rc == -1 && recp)
369
break; /* no more recipients */
371
log_error ("recp %d - error getting info: %s\n",
372
recp, gpg_strerror (rc));
375
ksba_cert_t cert = NULL;
377
log_debug ("recp %d - issuer: `%s'\n",
378
recp, issuer? issuer:"[NONE]");
379
log_debug ("recp %d - serial: ", recp);
380
gpgsm_dump_serial (serial);
383
keydb_search_reset (kh);
384
rc = keydb_search_issuer_sn (kh, issuer, serial);
387
log_error ("failed to find the certificate: %s\n",
392
rc = keydb_get_cert (kh, &cert);
395
log_error ("failed to get cert: %s\n", gpg_strerror (rc));
398
/* Just in case there is a problem with the own
399
certificate we print this message - should never
401
rc = gpgsm_cert_use_decrypt_p (cert);
405
sprintf (numbuf, "%d", rc);
406
gpgsm_status2 (ctrl, STATUS_ERROR, "decrypt.keyusage",
411
hexkeygrip = gpgsm_get_keygrip_hexstring (cert);
412
desc = gpgsm_format_keydesc (cert);
417
ksba_cert_release (cert);
422
else if (!(enc_val = ksba_cms_get_enc_val (cms, recp)))
423
log_error ("recp %d - error getting encrypted session key\n",
427
rc = prepare_decryption (ctrl,
428
hexkeygrip, desc, enc_val, &dfparm);
432
log_info ("decrypting session key failed: %s\n",
436
{ /* setup the bulk decrypter */
438
ksba_writer_set_filter (writer,
448
rc = gpg_error (GPG_ERR_NO_SECKEY);
452
else if (stopreason == KSBA_SR_END_DATA)
454
ksba_writer_set_filter (writer, NULL, NULL);
456
{ /* write the last block with padding removed */
457
int i, npadding = dfparm.lastblock[dfparm.blklen-1];
458
if (!npadding || npadding > dfparm.blklen)
460
log_error ("invalid padding with value %d\n", npadding);
461
rc = gpg_error (GPG_ERR_INV_DATA);
464
rc = ksba_writer_write (writer,
466
dfparm.blklen - npadding);
470
for (i=dfparm.blklen - npadding; i < dfparm.blklen; i++)
472
if (dfparm.lastblock[i] != npadding)
474
log_error ("inconsistent padding\n");
475
rc = gpg_error (GPG_ERR_INV_DATA);
483
while (stopreason != KSBA_SR_READY);
485
rc = gpgsm_finish_writer (b64writer);
488
log_error ("write failed: %s\n", gpg_strerror (rc));
491
gpgsm_status (ctrl, STATUS_DECRYPTION_OKAY, NULL);
497
gpgsm_status (ctrl, STATUS_DECRYPTION_FAILED, NULL);
498
log_error ("message decryption failed: %s <%s>\n",
499
gpg_strerror (rc), gpg_strsource (rc));
501
ksba_cms_release (cms);
502
gpgsm_destroy_reader (b64reader);
503
gpgsm_destroy_writer (b64writer);
508
gcry_cipher_close (dfparm.hd);