39
39
static int decode_filter ( void *opaque, int control, IOBUF a,
40
40
byte *buf, size_t *ret_len);
42
typedef struct decode_filter_context_s
44
44
gcry_cipher_hd_t cipher_hd;
45
45
gcry_md_hd_t mdc_hash;
49
} decode_filter_ctx_t;
50
} *decode_filter_ctx_t;
53
/* Helper to release the decode context. */
55
release_dfx_context (decode_filter_ctx_t dfx)
60
assert (dfx->refcount);
61
if ( !--dfx->refcount )
63
gcry_cipher_close (dfx->cipher_hd);
64
dfx->cipher_hd = NULL;
65
gcry_md_close (dfx->mdc_hash);
62
83
unsigned blocksize;
65
memset( &dfx, 0, sizeof dfx );
86
dfx = xtrycalloc (1, sizeof *dfx);
88
return gpg_error_from_syserror ();
66
91
if ( opt.verbose && !dek->algo_info_printed )
68
93
const char *s = gcry_cipher_algo_name (dek->algo);
78
103
blocksize = gcry_cipher_get_algo_blklen (dek->algo);
79
104
if ( !blocksize || blocksize > 16 )
80
log_fatal("unsupported blocksize %u\n", blocksize );
105
log_fatal ("unsupported blocksize %u\n", blocksize );
81
106
nprefix = blocksize;
82
107
if ( ed->len && ed->len < (nprefix+2) )
85
110
if ( ed->mdc_method )
87
if (gcry_md_open (&dfx.mdc_hash, ed->mdc_method, 0 ))
112
if (gcry_md_open (&dfx->mdc_hash, ed->mdc_method, 0 ))
89
114
if ( DBG_HASHING )
90
gcry_md_start_debug (dfx.mdc_hash, "checkmdc");
115
gcry_md_start_debug (dfx->mdc_hash, "checkmdc");
93
rc = gcry_cipher_open (&dfx.cipher_hd, dek->algo,
118
rc = gcry_cipher_open (&dfx->cipher_hd, dek->algo,
94
119
GCRY_CIPHER_MODE_CFB,
95
120
(GCRY_CIPHER_SECURE
96
121
| ((ed->mdc_method || dek->algo >= 100)?
106
131
/* log_hexdump( "thekey", dek->key, dek->keylen );*/
107
rc = gcry_cipher_setkey (dfx.cipher_hd, dek->key, dek->keylen);
132
rc = gcry_cipher_setkey (dfx->cipher_hd, dek->key, dek->keylen);
108
133
if ( gpg_err_code (rc) == GPG_ERR_WEAK_KEY )
110
135
log_info(_("WARNING: message was encrypted with"
147
gcry_cipher_decrypt (dfx.cipher_hd, temp, nprefix+2, NULL, 0);
148
gcry_cipher_sync (dfx.cipher_hd);
172
gcry_cipher_decrypt (dfx->cipher_hd, temp, nprefix+2, NULL, 0);
173
gcry_cipher_sync (dfx->cipher_hd);
150
175
/* log_hexdump( "prefix", temp, nprefix+2 ); */
151
176
if (dek->symmetric
159
gcry_md_write (dfx.mdc_hash, temp, nprefix+2);
184
gcry_md_write (dfx->mdc_hash, temp, nprefix+2);
161
187
if ( ed->mdc_method )
162
iobuf_push_filter( ed->buf, mdc_decode_filter, &dfx );
188
iobuf_push_filter ( ed->buf, mdc_decode_filter, dfx );
164
iobuf_push_filter( ed->buf, decode_filter, &dfx );
190
iobuf_push_filter ( ed->buf, decode_filter, dfx );
166
192
proc_packets ( procctx, ed->buf );
168
if ( ed->mdc_method && dfx.eof_seen == 2 )
194
if ( ed->mdc_method && dfx->eof_seen == 2 )
169
195
rc = gpg_error (GPG_ERR_INV_PACKET);
170
196
else if ( ed->mdc_method )
184
210
bytes are appended. */
185
211
int datalen = gcry_md_get_algo_dlen (ed->mdc_method);
187
gcry_cipher_decrypt (dfx.cipher_hd, dfx.defer, 22, NULL, 0);
188
gcry_md_write (dfx.mdc_hash, dfx.defer, 2);
189
gcry_md_final (dfx.mdc_hash);
213
assert (dfx->cipher_hd);
214
assert (dfx->mdc_hash);
215
gcry_cipher_decrypt (dfx->cipher_hd, dfx->defer, 22, NULL, 0);
216
gcry_md_write (dfx->mdc_hash, dfx->defer, 2);
217
gcry_md_final (dfx->mdc_hash);
191
if (dfx.defer[0] != '\xd3' || dfx.defer[1] != '\x14' )
219
if (dfx->defer[0] != '\xd3' || dfx->defer[1] != '\x14' )
193
221
log_error("mdc_packet with invalid encoding\n");
194
222
rc = gpg_error (GPG_ERR_INV_PACKET);
196
224
else if (datalen != 20
197
|| memcmp (gcry_md_read (dfx.mdc_hash, 0),dfx.defer+2,datalen))
225
|| memcmp (gcry_md_read (dfx->mdc_hash, 0),
226
dfx->defer+2,datalen ))
198
227
rc = gpg_error (GPG_ERR_BAD_SIGNATURE);
199
/* log_printhex("MDC message:", dfx.defer, 22); */
200
/* log_printhex("MDC calc:", gcry_md_read (dfx.mdc_hash,0), datalen); */
228
/* log_printhex("MDC message:", dfx->defer, 22); */
229
/* log_printhex("MDC calc:", gcry_md_read (dfx->mdc_hash,0), datalen); */
205
gcry_cipher_close (dfx.cipher_hd);
206
gcry_md_close (dfx.mdc_hash);
234
release_dfx_context (dfx);
214
242
mdc_decode_filter (void *opaque, int control, IOBUF a,
215
243
byte *buf, size_t *ret_len)
217
decode_filter_ctx_t *dfx = opaque;
245
decode_filter_ctx_t dfx = opaque;
218
246
size_t n, size = *ret_len;
282
gcry_cipher_decrypt (dfx->cipher_hd, buf, n, NULL, 0);
283
gcry_md_write (dfx->mdc_hash, buf, n);
310
if ( dfx->cipher_hd )
311
gcry_cipher_decrypt (dfx->cipher_hd, buf, n, NULL, 0);
313
gcry_md_write (dfx->mdc_hash, buf, n);
301
335
decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len)
303
decode_filter_ctx_t *fc = opaque;
337
decode_filter_ctx_t fc = opaque;
304
338
size_t n, size = *ret_len;
314
gcry_cipher_decrypt (fc->cipher_hd, buf, n, NULL, 0);
350
gcry_cipher_decrypt (fc->cipher_hd, buf, n, NULL, 0);
316
353
rc = -1; /* EOF */
356
else if ( control == IOBUFCTRL_FREE )
358
release_dfx_context (fc);
319
360
else if ( control == IOBUFCTRL_DESC )
321
362
*(char**)buf = "decode_filter";