1
1
/* encr-data.c - process an encrypted data packet
2
* Copyright (C) 1998, 1999, 2000, 2001, 2005 Free Software Foundation, Inc.
2
* Copyright (C) 1998, 1999, 2000, 2001, 2005,
3
* 2006 Free Software Foundation, Inc.
4
5
* This file is part of GnuPG.
81
105
if( ed->mdc_method ) {
82
dfx.mdc_hash = md_open( ed->mdc_method, 0 );
106
dfx->mdc_hash = md_open ( ed->mdc_method, 0 );
83
107
if ( DBG_HASHING )
84
md_start_debug(dfx.mdc_hash, "checkmdc");
108
md_start_debug (dfx->mdc_hash, "checkmdc");
86
dfx.cipher_hd = cipher_open( dek->algo,
87
ed->mdc_method? CIPHER_MODE_CFB
88
: CIPHER_MODE_AUTO_CFB, 1 );
110
dfx->cipher_hd = cipher_open ( dek->algo,
111
ed->mdc_method? CIPHER_MODE_CFB
112
: CIPHER_MODE_AUTO_CFB, 1 );
89
113
/* log_hexdump( "thekey", dek->key, dek->keylen );*/
90
rc = cipher_setkey( dfx.cipher_hd, dek->key, dek->keylen );
114
rc = cipher_setkey ( dfx->cipher_hd, dek->key, dek->keylen );
91
115
if( rc == G10ERR_WEAK_KEY )
93
117
log_info(_("WARNING: message was encrypted with"
137
md_write( dfx.mdc_hash, temp, nprefix+2 );
161
md_write ( dfx->mdc_hash, temp, nprefix+2 );
140
iobuf_push_filter( ed->buf, mdc_decode_filter, &dfx );
164
if ( ed->mdc_method )
165
iobuf_push_filter( ed->buf, mdc_decode_filter, dfx );
142
iobuf_push_filter( ed->buf, decode_filter, &dfx );
167
iobuf_push_filter( ed->buf, decode_filter, dfx );
144
169
proc_packets( procctx, ed->buf );
146
if( ed->mdc_method && dfx.eof_seen == 2 )
171
if( ed->mdc_method && dfx->eof_seen == 2 )
147
172
rc = G10ERR_INVALID_PACKET;
148
173
else if( ed->mdc_method ) { /* check the mdc */
174
/* We used to let parse-packet.c handle the MDC packet but
175
this turned out to be a problem with compressed packets:
176
With old style packets there is no length information
177
available and the decompressor uses an implicit end.
178
However we can't know this implicit end beforehand (:-) and
179
thus may feed the decompressor with more bytes than
180
actually needed. It would be possible to unread the extra
181
bytes but due to our weird iobuf system any unread is non
182
reliable due to filters already popped off. The easy and
183
sane solution is to care about the MDC packet only here and
184
never pass it to the packet parser. Fortunatley the
185
OpenPGP spec requires a strict format for the MDC packet so
186
that we know that 22 bytes are appended. */
149
187
int datalen = md_digest_length( ed->mdc_method );
151
cipher_decrypt( dfx.cipher_hd, dfx.defer, dfx.defer, 20);
152
md_final( dfx.mdc_hash );
154
|| memcmp(md_read( dfx.mdc_hash, 0 ), dfx.defer, datalen) )
189
assert (dfx->cipher_hd);
190
assert (dfx->mdc_hash);
191
cipher_decrypt ( dfx->cipher_hd, dfx->defer, dfx->defer, 22);
192
md_write ( dfx->mdc_hash, dfx->defer, 2);
193
md_final ( dfx->mdc_hash );
194
if (dfx->defer[0] != '\xd3' || dfx->defer[1] != '\x14' ) {
195
log_error("mdc_packet with invalid encoding\n");
196
rc = G10ERR_INVALID_PACKET;
198
else if ( datalen != 20
199
|| memcmp(md_read( dfx->mdc_hash, 0 ), dfx->defer+2, datalen) )
155
200
rc = G10ERR_BAD_SIGN;
156
/*log_hexdump("MDC calculated:", md_read( dfx.mdc_hash, 0), datalen);*/
157
/*log_hexdump("MDC message :", dfx.defer, 20);*/
201
/*log_hexdump("MDC calculated:",md_read( dfx->mdc_hash, 0), datalen);*/
202
/*log_hexdump("MDC message :", dfx->defer, 20);*/
162
cipher_close(dfx.cipher_hd);
163
md_close( dfx.mdc_hash );
207
release_dfx_context (dfx);
183
227
else if( control == IOBUFCTRL_UNDERFLOW ) {
187
231
/* get at least 20 bytes and put it somewhere ahead in the buffer */
188
for(n=20; n < 40 ; n++ ) {
232
for(n=22; n < 44 ; n++ ) {
189
233
if( (c = iobuf_get(a)) == -1 )
194
238
/* we have enough stuff - flush the deferred stuff */
195
239
/* (we have asserted that the buffer is large enough) */
196
240
if( !dfx->defer_filled ) { /* the first time */
197
memcpy(buf, buf+20, 20 );
241
memcpy(buf, buf+22, 22 );
201
memcpy(buf, dfx->defer, 20 );
245
memcpy(buf, dfx->defer, 22 );
203
247
/* now fill up */
204
248
for(; n < size; n++ ) {
209
/* move the last 20 bytes back to the defer buffer */
210
/* (okay, we are wasting 20 bytes of supplied buffer) */
212
memcpy( dfx->defer, buf+n, 20 );
253
/* Move the last 22 bytes back to the defer buffer. */
254
/* (okay, we are wasting 22 bytes of supplied buffer) */
256
memcpy( dfx->defer, buf+n, 22 );
213
257
dfx->defer_filled = 1;
215
259
else if( !dfx->defer_filled ) { /* eof seen buf empty defer */
216
260
/* this is bad because there is an incomplete hash */
218
memcpy(buf, buf+20, n );
262
memcpy(buf, buf+22, n );
219
263
dfx->eof_seen = 2; /* eof with incomplete hash */
221
265
else { /* eof seen */
222
memcpy(buf, dfx->defer, 20 );
224
memcpy( dfx->defer, buf+n, 20 );
266
memcpy (buf, dfx->defer, 22 );
268
memcpy( dfx->defer, buf+n, 22 );
225
269
dfx->eof_seen = 1; /* normal eof */
229
cipher_decrypt( dfx->cipher_hd, buf, buf, n);
230
md_write( dfx->mdc_hash, buf, n );
274
cipher_decrypt( dfx->cipher_hd, buf, buf, n);
276
md_write( dfx->mdc_hash, buf, n );
233
279
assert( dfx->eof_seen );
253
302
n = iobuf_read( a, buf, size );
254
303
if( n == -1 ) n = 0;
256
cipher_decrypt( fc->cipher_hd, buf, buf, n);
306
cipher_decrypt( fc->cipher_hd, buf, buf, n);
258
309
rc = -1; /* eof */
312
else if ( control == IOBUFCTRL_FREE ) {
313
release_dfx_context (fc);
261
315
else if( control == IOBUFCTRL_DESC ) {
262
316
*(char**)buf = "decode_filter";