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 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/>.
36 struct decrypt_filter_parm_s
{
43 int any_data
; /* dod we push anything through the filter at all? */
44 unsigned char lastblock
[16]; /* to strip the padding we have to
46 char helpblock
[16]; /* needed because there is no block buffering in
53 /* Decrypt the session key and fill in the parm structure. The
54 algo and the IV is expected to be already in PARM. */
56 prepare_decryption (ctrl_t ctrl
, const char *hexkeygrip
, const char *desc
,
57 ksba_const_sexp_t enc_val
,
58 struct decrypt_filter_parm_s
*parm
)
64 rc
= gpgsm_agent_pkdecrypt (ctrl
, hexkeygrip
, desc
, enc_val
,
68 log_error ("error decrypting session key: %s\n", gpg_strerror (rc
));
73 log_printhex ("pkcs1 encoded session key:", seskey
, seskeylen
);
78 /* Smells like a 3-des key. This might happen because a SC has
79 already done the unpacking. */
83 if (n
+ 7 > seskeylen
)
85 rc
= gpg_error (GPG_ERR_INV_SESSION_KEY
);
89 /* FIXME: Actually the leading zero is required but due to the way
90 we encode the output in libgcrypt as an MPI we are not able to
91 encode that leading zero. However, when using a Smartcard we are
92 doing it the right way and therefore we have to skip the zero. This
93 should be fixed in gpg-agent of course. */
97 if (seskey
[n
] != 2 ) /* Wrong block type version. */
99 rc
= gpg_error (GPG_ERR_INV_SESSION_KEY
);
103 for (n
++; n
< seskeylen
&& seskey
[n
]; n
++) /* Skip the random bytes. */
105 n
++; /* and the zero byte */
108 rc
= gpg_error (GPG_ERR_INV_SESSION_KEY
);
114 log_printhex ("session key:", seskey
+n
, seskeylen
-n
);
116 rc
= gcry_cipher_open (&parm
->hd
, parm
->algo
, parm
->mode
, 0);
119 log_error ("error creating decryptor: %s\n", gpg_strerror (rc
));
123 rc
= gcry_cipher_setkey (parm
->hd
, seskey
+n
, seskeylen
-n
);
124 if (gpg_err_code (rc
) == GPG_ERR_WEAK_KEY
)
126 log_info (_("WARNING: message was encrypted with "
127 "a weak key in the symmetric cipher.\n"));
132 log_error("key setup failed: %s\n", gpg_strerror(rc
) );
136 gcry_cipher_setiv (parm
->hd
, parm
->iv
, parm
->ivlen
);
144 /* This function is called by the KSBA writer just before the actual
145 write is done. The function must take INLEN bytes from INBUF,
146 decrypt it and store it inoutbuf which has a maximum size of
147 maxoutlen. The valid bytes in outbuf should be return in outlen.
148 Due to different buffer sizes or different length of input and
149 output, it may happen that fewer bytes are processed or fewer bytes
152 decrypt_filter (void *arg
,
153 const void *inbuf
, size_t inlen
, size_t *inused
,
154 void *outbuf
, size_t maxoutlen
, size_t *outlen
)
156 struct decrypt_filter_parm_s
*parm
= arg
;
157 int blklen
= parm
->blklen
;
158 size_t orig_inlen
= inlen
;
160 /* fixme: Should we issue an error when we have not seen one full block? */
162 return gpg_error (GPG_ERR_BUG
);
164 if (maxoutlen
< 2*parm
->blklen
)
165 return gpg_error (GPG_ERR_BUG
);
166 /* Make some space because we will later need an extra block at the end. */
169 if (parm
->helpblocklen
)
173 for (i
=parm
->helpblocklen
,j
=0; i
< blklen
&& j
< inlen
; i
++, j
++)
174 parm
->helpblock
[i
] = ((const char*)inbuf
)[j
];
176 if (blklen
> maxoutlen
)
177 return gpg_error (GPG_ERR_BUG
);
180 parm
->helpblocklen
= i
;
185 parm
->helpblocklen
= 0;
188 memcpy (outbuf
, parm
->lastblock
, blklen
);
193 gcry_cipher_decrypt (parm
->hd
, parm
->lastblock
, blklen
,
194 parm
->helpblock
, blklen
);
197 *inused
= orig_inlen
- inlen
;
202 if (inlen
> maxoutlen
)
205 { /* store the remainder away */
206 parm
->helpblocklen
= inlen
%blklen
;
207 inlen
= inlen
/blklen
*blklen
;
208 memcpy (parm
->helpblock
, (const char*)inbuf
+inlen
, parm
->helpblocklen
);
211 *inused
= inlen
+ parm
->helpblocklen
;
214 assert (inlen
>= blklen
);
217 gcry_cipher_decrypt (parm
->hd
, (char*)outbuf
+blklen
, inlen
,
219 memcpy (outbuf
, parm
->lastblock
, blklen
);
220 memcpy (parm
->lastblock
,(char*)outbuf
+inlen
, blklen
);
225 gcry_cipher_decrypt (parm
->hd
, outbuf
, inlen
, inbuf
, inlen
);
226 memcpy (parm
->lastblock
, (char*)outbuf
+inlen
-blklen
, blklen
);
227 *outlen
= inlen
- blklen
;
238 /* Perform a decrypt operation. */
240 gpgsm_decrypt (ctrl_t ctrl
, int in_fd
, FILE *out_fp
)
243 Base64Context b64reader
= NULL
;
244 Base64Context b64writer
= NULL
;
245 ksba_reader_t reader
;
246 ksba_writer_t writer
;
247 ksba_cms_t cms
= NULL
;
248 ksba_stop_reason_t stopreason
;
252 struct decrypt_filter_parm_s dfparm
;
254 memset (&dfparm
, 0, sizeof dfparm
);
259 log_error (_("failed to allocated keyDB handle\n"));
260 rc
= gpg_error (GPG_ERR_GENERAL
);
265 in_fp
= fdopen ( dup (in_fd
), "rb");
268 rc
= gpg_error (gpg_err_code_from_errno (errno
));
269 log_error ("fdopen() failed: %s\n", strerror (errno
));
273 rc
= gpgsm_create_reader (&b64reader
, ctrl
, in_fp
, 0, &reader
);
276 log_error ("can't create reader: %s\n", gpg_strerror (rc
));
280 rc
= gpgsm_create_writer (&b64writer
, ctrl
, out_fp
, NULL
, &writer
);
283 log_error ("can't create writer: %s\n", gpg_strerror (rc
));
287 rc
= ksba_cms_new (&cms
);
291 rc
= ksba_cms_set_reader_writer (cms
, reader
, writer
);
294 log_debug ("ksba_cms_set_reader_writer failed: %s\n",
302 rc
= ksba_cms_parse (cms
, &stopreason
);
305 log_debug ("ksba_cms_parse failed: %s\n", gpg_strerror (rc
));
309 if (stopreason
== KSBA_SR_BEGIN_DATA
310 || stopreason
== KSBA_SR_DETACHED_DATA
)
316 algoid
= ksba_cms_get_content_oid (cms
, 2/* encryption algo*/);
317 algo
= gcry_cipher_map_name (algoid
);
318 mode
= gcry_cipher_mode_from_oid (algoid
);
321 rc
= gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM
);
322 log_error ("unsupported algorithm `%s'\n", algoid
? algoid
:"?");
323 if (algoid
&& !strcmp (algoid
, "1.2.840.113549.3.2"))
324 log_info (_("(this is the RC2 algorithm)\n"));
326 log_info (_("(this does not seem to be an encrypted"
330 sprintf (numbuf
, "%d", rc
);
331 gpgsm_status2 (ctrl
, STATUS_ERROR
, "decrypt.algorithm",
332 numbuf
, algoid
?algoid
:"?", NULL
);
335 /* If it seems that this is not an encrypted message we
336 return a more sensible error code. */
338 rc
= gpg_error (GPG_ERR_NO_DATA
);
344 dfparm
.blklen
= gcry_cipher_get_algo_blklen (algo
);
345 if (dfparm
.blklen
> sizeof (dfparm
.helpblock
))
346 return gpg_error (GPG_ERR_BUG
);
348 rc
= ksba_cms_get_content_enc_iv (cms
,
354 log_error ("error getting IV: %s\n", gpg_strerror (rc
));
358 for (recp
=0; !any_key
; recp
++)
363 char *hexkeygrip
= NULL
;
369 rc
= ksba_cms_get_issuer_serial (cms
, recp
, &issuer
, &serial
);
370 if (rc
== -1 && recp
)
371 break; /* no more recipients */
373 log_error ("recp %d - error getting info: %s\n",
374 recp
, gpg_strerror (rc
));
377 ksba_cert_t cert
= NULL
;
379 log_debug ("recp %d - issuer: `%s'\n",
380 recp
, issuer
? issuer
:"[NONE]");
381 log_debug ("recp %d - serial: ", recp
);
382 gpgsm_dump_serial (serial
);
385 keydb_search_reset (kh
);
386 rc
= keydb_search_issuer_sn (kh
, issuer
, serial
);
389 log_error ("failed to find the certificate: %s\n",
394 rc
= keydb_get_cert (kh
, &cert
);
397 log_error ("failed to get cert: %s\n", gpg_strerror (rc
));
401 /* Print the ENC_TO status line. Note that we can
402 do so only if we have the certificate. This is
403 in contrast to gpg where the keyID is commonly
404 included in the encrypted messages. It is too
405 cumbersome to retrieve the used algorithm, thus
406 we don't print it for now. We also record the
407 keyid for later use. */
409 unsigned long kid
[2];
411 kid
[0] = gpgsm_get_short_fingerprint (cert
, kid
+1);
412 snprintf (kidbuf
, sizeof kidbuf
, "%08lX%08lX",
414 gpgsm_status2 (ctrl
, STATUS_ENC_TO
,
415 kidbuf
, "0", "0", NULL
);
419 /* Just in case there is a problem with the own
420 certificate we print this message - should never
422 rc
= gpgsm_cert_use_decrypt_p (cert
);
426 sprintf (numbuf
, "%d", rc
);
427 gpgsm_status2 (ctrl
, STATUS_ERROR
, "decrypt.keyusage",
432 hexkeygrip
= gpgsm_get_keygrip_hexstring (cert
);
433 desc
= gpgsm_format_keydesc (cert
);
438 ksba_cert_release (cert
);
443 else if (!(enc_val
= ksba_cms_get_enc_val (cms
, recp
)))
444 log_error ("recp %d - error getting encrypted session key\n",
448 rc
= prepare_decryption (ctrl
,
449 hexkeygrip
, desc
, enc_val
, &dfparm
);
453 log_info ("decrypting session key failed: %s\n",
455 if (gpg_err_code (rc
) == GPG_ERR_NO_SECKEY
&& *kidbuf
)
456 gpgsm_status2 (ctrl
, STATUS_NO_SECKEY
, kidbuf
, NULL
);
459 { /* setup the bulk decrypter */
461 ksba_writer_set_filter (writer
,
471 rc
= gpg_error (GPG_ERR_NO_SECKEY
);
475 else if (stopreason
== KSBA_SR_END_DATA
)
477 ksba_writer_set_filter (writer
, NULL
, NULL
);
479 { /* write the last block with padding removed */
480 int i
, npadding
= dfparm
.lastblock
[dfparm
.blklen
-1];
481 if (!npadding
|| npadding
> dfparm
.blklen
)
483 log_error ("invalid padding with value %d\n", npadding
);
484 rc
= gpg_error (GPG_ERR_INV_DATA
);
487 rc
= ksba_writer_write (writer
,
489 dfparm
.blklen
- npadding
);
493 for (i
=dfparm
.blklen
- npadding
; i
< dfparm
.blklen
; i
++)
495 if (dfparm
.lastblock
[i
] != npadding
)
497 log_error ("inconsistent padding\n");
498 rc
= gpg_error (GPG_ERR_INV_DATA
);
506 while (stopreason
!= KSBA_SR_READY
);
508 rc
= gpgsm_finish_writer (b64writer
);
511 log_error ("write failed: %s\n", gpg_strerror (rc
));
514 gpgsm_status (ctrl
, STATUS_DECRYPTION_OKAY
, NULL
);
520 gpgsm_status (ctrl
, STATUS_DECRYPTION_FAILED
, NULL
);
521 log_error ("message decryption failed: %s <%s>\n",
522 gpg_strerror (rc
), gpg_strsource (rc
));
524 ksba_cms_release (cms
);
525 gpgsm_destroy_reader (b64reader
);
526 gpgsm_destroy_writer (b64writer
);
531 gcry_cipher_close (dfparm
.hd
);