55
75
decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
57
decode_filter_ctx_t dfx;
64
memset( &dfx, 0, sizeof dfx );
65
if( opt.verbose && !dek->algo_info_printed ) {
66
const char *s = gcry_cipher_algo_name (dek->algo);
68
log_info(_("%s encrypted data\n"), s );
70
log_info(_("encrypted with unknown algorithm %d\n"), dek->algo );
71
dek->algo_info_printed = 1;
73
if( (rc=openpgp_cipher_test_algo(dek->algo)) )
75
blocksize = gcry_cipher_get_algo_blklen (dek->algo);
76
if( !blocksize || blocksize > 16 )
77
log_fatal("unsupported blocksize %u\n", blocksize );
79
if( ed->len && ed->len < (nprefix+2) )
82
if( ed->mdc_method ) {
83
gcry_md_open (&dfx.mdc_hash, ed->mdc_method, 0 );
85
gcry_md_start_debug (dfx.mdc_hash, "checkmdc");
87
rc = gcry_cipher_open (&dfx.cipher_hd, dek->algo,
90
| ((ed->mdc_method || dek->algo >= 100)?
91
0 : GCRY_CIPHER_ENABLE_SYNC) );
94
/* we should never get an error here cause we already
95
* checked, that the algorithm is available. What about a
96
* flag to let the function die in this case? */
99
/* log_hexdump( "thekey", dek->key, dek->keylen );*/
100
rc = gcry_cipher_setkey (dfx.cipher_hd, dek->key, dek->keylen);
101
if( gpg_err_code (rc) == GPG_ERR_WEAK_KEY )
102
log_info(_("WARNING: message was encrypted with "
103
"a weak key in the symmetric cipher.\n"));
105
log_error("key setup failed: %s\n", gpg_strerror (rc) );
109
log_error(_("problem handling encrypted packet\n"));
113
gcry_cipher_setiv (dfx.cipher_hd, NULL, 0);
116
for(i=0; i < (nprefix+2) && ed->len; i++, ed->len-- ) {
117
if( (c=iobuf_get(ed->buf)) == -1 )
124
for(i=0; i < (nprefix+2); i++ )
125
if( (c=iobuf_get(ed->buf)) == -1 )
130
gcry_cipher_decrypt( dfx.cipher_hd, temp, nprefix+2, NULL, 0);
131
gcry_cipher_sync( dfx.cipher_hd );
133
/* log_hexdump( "prefix", temp, nprefix+2 ); */
134
if( p[nprefix-2] != p[nprefix] || p[nprefix-1] != p[nprefix+1] ) {
135
rc = GPG_ERR_BAD_KEY;
140
gcry_md_write( dfx.mdc_hash, temp, nprefix+2 );
143
iobuf_push_filter( ed->buf, mdc_decode_filter, &dfx );
145
iobuf_push_filter( ed->buf, decode_filter, &dfx );
147
proc_packets( procctx, ed->buf );
149
if( ed->mdc_method && dfx.eof_seen == 2 )
150
rc = gpg_error (GPG_ERR_INV_PACKET);
151
else if( ed->mdc_method ) { /* check the mdc */
152
int datalen = gcry_md_get_algo_dlen (ed->mdc_method);
154
gcry_cipher_decrypt (dfx.cipher_hd, dfx.defer, 20, NULL, 0);
155
gcry_md_final ( dfx.mdc_hash );
157
|| memcmp(gcry_md_read ( dfx.mdc_hash, 0 ), dfx.defer, datalen) )
158
rc = gpg_error (GPG_ERR_BAD_SIGNATURE);
159
/*log_hexdump("MDC calculated:", gcry_md_read ( dfx.mdc_hash, 0), datalen);*/
160
/*log_hexdump("MDC message :", dfx.defer, 20);*/
165
gcry_cipher_close(dfx.cipher_hd);
166
gcry_md_close ( dfx.mdc_hash );
77
decode_filter_ctx_t dfx;
84
dfx = xtrycalloc (1, sizeof *dfx);
86
return gpg_error_from_syserror ();
89
if ( opt.verbose && !dek->algo_info_printed )
91
if (!openpgp_cipher_test_algo (dek->algo))
92
log_info (_("%s encrypted data\n"),
93
openpgp_cipher_algo_name (dek->algo));
95
log_info (_("encrypted with unknown algorithm %d\n"), dek->algo );
96
dek->algo_info_printed = 1;
98
rc = openpgp_cipher_test_algo (dek->algo);
101
blocksize = gcry_cipher_get_algo_blklen (dek->algo);
102
if ( !blocksize || blocksize > 16 )
103
log_fatal ("unsupported blocksize %u\n", blocksize );
105
if ( ed->len && ed->len < (nprefix+2) )
108
if ( ed->mdc_method )
110
if (gcry_md_open (&dfx->mdc_hash, ed->mdc_method, 0 ))
113
gcry_md_start_debug (dfx->mdc_hash, "checkmdc");
116
rc = gcry_cipher_open (&dfx->cipher_hd, dek->algo,
117
GCRY_CIPHER_MODE_CFB,
119
| ((ed->mdc_method || dek->algo >= 100)?
120
0 : GCRY_CIPHER_ENABLE_SYNC)));
123
/* We should never get an error here cause we already checked
124
* that the algorithm is available. */
129
/* log_hexdump( "thekey", dek->key, dek->keylen );*/
130
rc = gcry_cipher_setkey (dfx->cipher_hd, dek->key, dek->keylen);
131
if ( gpg_err_code (rc) == GPG_ERR_WEAK_KEY )
133
log_info(_("WARNING: message was encrypted with"
134
" a weak key in the symmetric cipher.\n"));
139
log_error("key setup failed: %s\n", g10_errstr(rc) );
145
log_error(_("problem handling encrypted packet\n"));
149
gcry_cipher_setiv (dfx->cipher_hd, NULL, 0);
153
for (i=0; i < (nprefix+2) && ed->len; i++, ed->len-- )
155
if ( (c=iobuf_get(ed->buf)) == -1 )
163
for (i=0; i < (nprefix+2); i++ )
164
if ( (c=iobuf_get(ed->buf)) == -1 )
170
gcry_cipher_decrypt (dfx->cipher_hd, temp, nprefix+2, NULL, 0);
171
gcry_cipher_sync (dfx->cipher_hd);
173
/* log_hexdump( "prefix", temp, nprefix+2 ); */
175
&& (p[nprefix-2] != p[nprefix] || p[nprefix-1] != p[nprefix+1]) )
177
rc = gpg_error (GPG_ERR_BAD_KEY);
182
gcry_md_write (dfx->mdc_hash, temp, nprefix+2);
185
if ( ed->mdc_method )
186
iobuf_push_filter ( ed->buf, mdc_decode_filter, dfx );
188
iobuf_push_filter ( ed->buf, decode_filter, dfx );
190
proc_packets ( procctx, ed->buf );
192
if ( ed->mdc_method && dfx->eof_seen == 2 )
193
rc = gpg_error (GPG_ERR_INV_PACKET);
194
else if ( ed->mdc_method )
196
/* We used to let parse-packet.c handle the MDC packet but this
197
turned out to be a problem with compressed packets: With old
198
style packets there is no length information available and
199
the decompressor uses an implicit end. However we can't know
200
this implicit end beforehand (:-) and thus may feed the
201
decompressor with more bytes than actually needed. It would
202
be possible to unread the extra bytes but due to our weird
203
iobuf system any unread is non reliable due to filters
204
already popped off. The easy and sane solution is to care
205
about the MDC packet only here and never pass it to the
206
packet parser. Fortunatley the OpenPGP spec requires a
207
strict format for the MDC packet so that we know that 22
208
bytes are appended. */
209
int datalen = gcry_md_get_algo_dlen (ed->mdc_method);
211
assert (dfx->cipher_hd);
212
assert (dfx->mdc_hash);
213
gcry_cipher_decrypt (dfx->cipher_hd, dfx->defer, 22, NULL, 0);
214
gcry_md_write (dfx->mdc_hash, dfx->defer, 2);
215
gcry_md_final (dfx->mdc_hash);
217
if (dfx->defer[0] != '\xd3' || dfx->defer[1] != '\x14' )
219
log_error("mdc_packet with invalid encoding\n");
220
rc = gpg_error (GPG_ERR_INV_PACKET);
222
else if (datalen != 20
223
|| memcmp (gcry_md_read (dfx->mdc_hash, 0),
224
dfx->defer+2,datalen ))
225
rc = gpg_error (GPG_ERR_BAD_SIGNATURE);
226
/* log_printhex("MDC message:", dfx->defer, 22); */
227
/* log_printhex("MDC calc:", gcry_md_read (dfx->mdc_hash,0), datalen); */
232
release_dfx_context (dfx);
172
238
/* I think we should merge this with cipher_filter */
174
mdc_decode_filter( void *opaque, int control, iobuf_t a,
175
byte *buf, size_t *ret_len)
240
mdc_decode_filter (void *opaque, int control, IOBUF a,
241
byte *buf, size_t *ret_len)
177
decode_filter_ctx_t *dfx = opaque;
178
size_t n, size = *ret_len;
182
if( control == IOBUFCTRL_UNDERFLOW && dfx->eof_seen ) {
186
else if( control == IOBUFCTRL_UNDERFLOW ) {
190
/* get at least 20 bytes and put it somewhere ahead in the buffer */
191
for(n=20; n < 40 ; n++ ) {
192
if( (c = iobuf_get(a)) == -1 )
197
/* we have enough stuff - flush the deferred stuff */
198
/* (we have asserted that the buffer is large enough) */
199
if( !dfx->defer_filled ) { /* the first time */
200
memcpy(buf, buf+20, 20 );
204
memcpy(buf, dfx->defer, 20 );
207
for(; n < size; n++ ) {
208
if( (c = iobuf_get(a)) == -1 )
212
/* move the last 20 bytes back to the defer buffer */
213
/* (okay, we are wasting 20 bytes of supplied buffer) */
215
memcpy( dfx->defer, buf+n, 20 );
216
dfx->defer_filled = 1;
218
else if( !dfx->defer_filled ) { /* eof seen buf empty defer */
219
/* this is bad because there is an incomplete hash */
221
memcpy(buf, buf+20, n );
222
dfx->eof_seen = 2; /* eof with incomplete hash */
224
else { /* eof seen */
225
memcpy(buf, dfx->defer, 20 );
227
memcpy( dfx->defer, buf+n, 20 );
228
dfx->eof_seen = 1; /* normal eof */
232
gcry_cipher_decrypt( dfx->cipher_hd, buf, n, NULL, 0);
233
gcry_md_write( dfx->mdc_hash, buf, n );
236
assert( dfx->eof_seen );
241
else if( control == IOBUFCTRL_DESC ) {
242
*(char**)buf = "mdc_decode_filter";
243
decode_filter_ctx_t dfx = opaque;
244
size_t n, size = *ret_len;
248
if ( control == IOBUFCTRL_UNDERFLOW && dfx->eof_seen )
253
else if( control == IOBUFCTRL_UNDERFLOW )
256
assert ( size > 44 );
258
/* Get at least 22 bytes and put it somewhere ahead in the buffer. */
259
for (n=22; n < 44 ; n++ )
261
if( (c = iobuf_get(a)) == -1 )
267
/* We have enough stuff - flush the deferred stuff. */
268
/* (we asserted that the buffer is large enough) */
269
if ( !dfx->defer_filled ) /* First time. */
271
memcpy (buf, buf+22, 22 );
276
memcpy (buf, dfx->defer, 22 );
279
for (; n < size; n++ )
281
if ( (c = iobuf_get(a)) == -1 )
285
/* Move the last 22 bytes back to the defer buffer. */
286
/* (right, we are wasting 22 bytes of the supplied buffer.) */
288
memcpy (dfx->defer, buf+n, 22 );
289
dfx->defer_filled = 1;
291
else if ( !dfx->defer_filled ) /* EOF seen but empty defer buffer. */
293
/* This is bad because it means an incomplete hash. */
295
memcpy (buf, buf+22, n );
296
dfx->eof_seen = 2; /* EOF with incomplete hash. */
298
else /* EOF seen (i.e. read less than 22 bytes). */
300
memcpy (buf, dfx->defer, 22 );
302
memcpy (dfx->defer, buf+n, 22 );
303
dfx->eof_seen = 1; /* Normal EOF. */
308
if ( dfx->cipher_hd )
309
gcry_cipher_decrypt (dfx->cipher_hd, buf, n, NULL, 0);
311
gcry_md_write (dfx->mdc_hash, buf, n);
315
assert ( dfx->eof_seen );
320
else if ( control == IOBUFCTRL_FREE )
322
release_dfx_context (dfx);
324
else if ( control == IOBUFCTRL_DESC )
326
*(char**)buf = "mdc_decode_filter";
248
decode_filter( void *opaque, int control, iobuf_t a, byte *buf, size_t *ret_len)
333
decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len)
250
decode_filter_ctx_t *fc = opaque;
251
size_t n, size = *ret_len;
254
if( control == IOBUFCTRL_UNDERFLOW ) {
256
n = iobuf_read( a, buf, size );
259
gcry_cipher_decrypt( fc->cipher_hd, buf, n, NULL, 0);
264
else if( control == IOBUFCTRL_DESC ) {
265
*(char**)buf = "decode_filter";
335
decode_filter_ctx_t fc = opaque;
336
size_t n, size = *ret_len;
339
if ( control == IOBUFCTRL_UNDERFLOW )
342
n = iobuf_read ( a, buf, size );
348
gcry_cipher_decrypt (fc->cipher_hd, buf, n, NULL, 0);
354
else if ( control == IOBUFCTRL_FREE )
356
release_dfx_context (fc);
358
else if ( control == IOBUFCTRL_DESC )
360
*(char**)buf = "decode_filter";