Lines 39-54
Link Here
|
39 |
static int decode_filter ( void *opaque, int control, IOBUF a, |
39 |
static int decode_filter ( void *opaque, int control, IOBUF a, |
40 |
byte *buf, size_t *ret_len); |
40 |
byte *buf, size_t *ret_len); |
41 |
|
41 |
|
42 |
typedef struct |
42 |
typedef struct decode_filter_context_s |
43 |
{ |
43 |
{ |
44 |
gcry_cipher_hd_t cipher_hd; |
44 |
gcry_cipher_hd_t cipher_hd; |
45 |
gcry_md_hd_t mdc_hash; |
45 |
gcry_md_hd_t mdc_hash; |
46 |
char defer[22]; |
46 |
char defer[22]; |
47 |
int defer_filled; |
47 |
int defer_filled; |
48 |
int eof_seen; |
48 |
int eof_seen; |
49 |
} decode_filter_ctx_t; |
49 |
int refcount; |
|
|
50 |
} *decode_filter_ctx_t; |
50 |
|
51 |
|
51 |
|
52 |
|
|
|
53 |
/* Helper to release the decode context. */ |
54 |
static void |
55 |
release_dfx_context (decode_filter_ctx_t dfx) |
56 |
{ |
57 |
if (!dfx) |
58 |
return; |
59 |
|
60 |
assert (dfx->refcount); |
61 |
if ( !--dfx->refcount ) |
62 |
{ |
63 |
gcry_cipher_close (dfx->cipher_hd); |
64 |
dfx->cipher_hd = NULL; |
65 |
gcry_md_close (dfx->mdc_hash); |
66 |
dfx->mdc_hash = NULL; |
67 |
xfree (dfx); |
68 |
} |
69 |
} |
70 |
|
71 |
|
72 |
|
52 |
/**************** |
73 |
/**************** |
53 |
* Decrypt the data, specified by ED with the key DEK. |
74 |
* Decrypt the data, specified by ED with the key DEK. |
54 |
*/ |
75 |
*/ |
Lines 62-68
Link Here
|
62 |
unsigned blocksize; |
83 |
unsigned blocksize; |
63 |
unsigned nprefix; |
84 |
unsigned nprefix; |
64 |
|
85 |
|
65 |
memset( &dfx, 0, sizeof dfx ); |
86 |
dfx = xtrycalloc (1, sizeof *dfx); |
|
|
87 |
if (!dfx) |
88 |
return gpg_error_from_syserror (); |
89 |
dfx->refcount = 1; |
90 |
|
66 |
if ( opt.verbose && !dek->algo_info_printed ) |
91 |
if ( opt.verbose && !dek->algo_info_printed ) |
67 |
{ |
92 |
{ |
68 |
const char *s = gcry_cipher_algo_name (dek->algo); |
93 |
const char *s = gcry_cipher_algo_name (dek->algo); |
Lines 77-96
Link Here
|
77 |
goto leave; |
102 |
goto leave; |
78 |
blocksize = gcry_cipher_get_algo_blklen (dek->algo); |
103 |
blocksize = gcry_cipher_get_algo_blklen (dek->algo); |
79 |
if ( !blocksize || blocksize > 16 ) |
104 |
if ( !blocksize || blocksize > 16 ) |
80 |
log_fatal("unsupported blocksize %u\n", blocksize ); |
105 |
log_fatal ("unsupported blocksize %u\n", blocksize ); |
81 |
nprefix = blocksize; |
106 |
nprefix = blocksize; |
82 |
if ( ed->len && ed->len < (nprefix+2) ) |
107 |
if ( ed->len && ed->len < (nprefix+2) ) |
83 |
BUG(); |
108 |
BUG(); |
84 |
|
109 |
|
85 |
if ( ed->mdc_method ) |
110 |
if ( ed->mdc_method ) |
86 |
{ |
111 |
{ |
87 |
if (gcry_md_open (&dfx.mdc_hash, ed->mdc_method, 0 )) |
112 |
if (gcry_md_open (&dfx->mdc_hash, ed->mdc_method, 0 )) |
88 |
BUG (); |
113 |
BUG (); |
89 |
if ( DBG_HASHING ) |
114 |
if ( DBG_HASHING ) |
90 |
gcry_md_start_debug (dfx.mdc_hash, "checkmdc"); |
115 |
gcry_md_start_debug (dfx->mdc_hash, "checkmdc"); |
91 |
} |
116 |
} |
92 |
|
117 |
|
93 |
rc = gcry_cipher_open (&dfx.cipher_hd, dek->algo, |
118 |
rc = gcry_cipher_open (&dfx->cipher_hd, dek->algo, |
94 |
GCRY_CIPHER_MODE_CFB, |
119 |
GCRY_CIPHER_MODE_CFB, |
95 |
(GCRY_CIPHER_SECURE |
120 |
(GCRY_CIPHER_SECURE |
96 |
| ((ed->mdc_method || dek->algo >= 100)? |
121 |
| ((ed->mdc_method || dek->algo >= 100)? |
Lines 104-110
Link Here
|
104 |
|
129 |
|
105 |
|
130 |
|
106 |
/* log_hexdump( "thekey", dek->key, dek->keylen );*/ |
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 |
if ( gpg_err_code (rc) == GPG_ERR_WEAK_KEY ) |
133 |
if ( gpg_err_code (rc) == GPG_ERR_WEAK_KEY ) |
109 |
{ |
134 |
{ |
110 |
log_info(_("WARNING: message was encrypted with" |
135 |
log_info(_("WARNING: message was encrypted with" |
Lines 123-129
Link Here
|
123 |
goto leave; |
148 |
goto leave; |
124 |
} |
149 |
} |
125 |
|
150 |
|
126 |
gcry_cipher_setiv (dfx.cipher_hd, NULL, 0); |
151 |
gcry_cipher_setiv (dfx->cipher_hd, NULL, 0); |
127 |
|
152 |
|
128 |
if ( ed->len ) |
153 |
if ( ed->len ) |
129 |
{ |
154 |
{ |
Lines 144-151
Link Here
|
144 |
temp[i] = c; |
169 |
temp[i] = c; |
145 |
} |
170 |
} |
146 |
|
171 |
|
147 |
gcry_cipher_decrypt (dfx.cipher_hd, temp, nprefix+2, NULL, 0); |
172 |
gcry_cipher_decrypt (dfx->cipher_hd, temp, nprefix+2, NULL, 0); |
148 |
gcry_cipher_sync (dfx.cipher_hd); |
173 |
gcry_cipher_sync (dfx->cipher_hd); |
149 |
p = temp; |
174 |
p = temp; |
150 |
/* log_hexdump( "prefix", temp, nprefix+2 ); */ |
175 |
/* log_hexdump( "prefix", temp, nprefix+2 ); */ |
151 |
if (dek->symmetric |
176 |
if (dek->symmetric |
Lines 155-171
Link Here
|
155 |
goto leave; |
180 |
goto leave; |
156 |
} |
181 |
} |
157 |
|
182 |
|
158 |
if ( dfx.mdc_hash ) |
183 |
if ( dfx->mdc_hash ) |
159 |
gcry_md_write (dfx.mdc_hash, temp, nprefix+2); |
184 |
gcry_md_write (dfx->mdc_hash, temp, nprefix+2); |
160 |
|
185 |
|
|
|
186 |
dfx->refcount++; |
161 |
if ( ed->mdc_method ) |
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 ); |
163 |
else |
189 |
else |
164 |
iobuf_push_filter( ed->buf, decode_filter, &dfx ); |
190 |
iobuf_push_filter ( ed->buf, decode_filter, dfx ); |
165 |
|
191 |
|
166 |
proc_packets ( procctx, ed->buf ); |
192 |
proc_packets ( procctx, ed->buf ); |
167 |
ed->buf = NULL; |
193 |
ed->buf = NULL; |
168 |
if ( ed->mdc_method && dfx.eof_seen == 2 ) |
194 |
if ( ed->mdc_method && dfx->eof_seen == 2 ) |
169 |
rc = gpg_error (GPG_ERR_INV_PACKET); |
195 |
rc = gpg_error (GPG_ERR_INV_PACKET); |
170 |
else if ( ed->mdc_method ) |
196 |
else if ( ed->mdc_method ) |
171 |
{ |
197 |
{ |
Lines 184-209
Link Here
|
184 |
bytes are appended. */ |
210 |
bytes are appended. */ |
185 |
int datalen = gcry_md_get_algo_dlen (ed->mdc_method); |
211 |
int datalen = gcry_md_get_algo_dlen (ed->mdc_method); |
186 |
|
212 |
|
187 |
gcry_cipher_decrypt (dfx.cipher_hd, dfx.defer, 22, NULL, 0); |
213 |
assert (dfx->cipher_hd); |
188 |
gcry_md_write (dfx.mdc_hash, dfx.defer, 2); |
214 |
assert (dfx->mdc_hash); |
189 |
gcry_md_final (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); |
190 |
|
218 |
|
191 |
if (dfx.defer[0] != '\xd3' || dfx.defer[1] != '\x14' ) |
219 |
if (dfx->defer[0] != '\xd3' || dfx->defer[1] != '\x14' ) |
192 |
{ |
220 |
{ |
193 |
log_error("mdc_packet with invalid encoding\n"); |
221 |
log_error("mdc_packet with invalid encoding\n"); |
194 |
rc = gpg_error (GPG_ERR_INV_PACKET); |
222 |
rc = gpg_error (GPG_ERR_INV_PACKET); |
195 |
} |
223 |
} |
196 |
else if (datalen != 20 |
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 |
rc = gpg_error (GPG_ERR_BAD_SIGNATURE); |
227 |
rc = gpg_error (GPG_ERR_BAD_SIGNATURE); |
199 |
/* log_printhex("MDC message:", dfx.defer, 22); */ |
228 |
/* log_printhex("MDC message:", dfx->defer, 22); */ |
200 |
/* log_printhex("MDC calc:", gcry_md_read (dfx.mdc_hash,0), datalen); */ |
229 |
/* log_printhex("MDC calc:", gcry_md_read (dfx->mdc_hash,0), datalen); */ |
201 |
} |
230 |
} |
202 |
|
231 |
|
203 |
|
232 |
|
204 |
leave: |
233 |
leave: |
205 |
gcry_cipher_close (dfx.cipher_hd); |
234 |
release_dfx_context (dfx); |
206 |
gcry_md_close (dfx.mdc_hash); |
|
|
207 |
return rc; |
235 |
return rc; |
208 |
} |
236 |
} |
209 |
|
237 |
|
Lines 214-220
Link Here
|
214 |
mdc_decode_filter (void *opaque, int control, IOBUF a, |
242 |
mdc_decode_filter (void *opaque, int control, IOBUF a, |
215 |
byte *buf, size_t *ret_len) |
243 |
byte *buf, size_t *ret_len) |
216 |
{ |
244 |
{ |
217 |
decode_filter_ctx_t *dfx = opaque; |
245 |
decode_filter_ctx_t dfx = opaque; |
218 |
size_t n, size = *ret_len; |
246 |
size_t n, size = *ret_len; |
219 |
int rc = 0; |
247 |
int rc = 0; |
220 |
int c; |
248 |
int c; |
Lines 226-236
Link Here
|
226 |
} |
254 |
} |
227 |
else if( control == IOBUFCTRL_UNDERFLOW ) |
255 |
else if( control == IOBUFCTRL_UNDERFLOW ) |
228 |
{ |
256 |
{ |
229 |
assert(a); |
257 |
assert (a); |
230 |
assert( size > 44 ); |
258 |
assert ( size > 44 ); |
231 |
|
259 |
|
232 |
/* Get at least 22 bytes and put it somewhere ahead in the buffer. */ |
260 |
/* Get at least 22 bytes and put it somewhere ahead in the buffer. */ |
233 |
for(n=22; n < 44 ; n++ ) |
261 |
for (n=22; n < 44 ; n++ ) |
234 |
{ |
262 |
{ |
235 |
if( (c = iobuf_get(a)) == -1 ) |
263 |
if( (c = iobuf_get(a)) == -1 ) |
236 |
break; |
264 |
break; |
Lines 279-286
Link Here
|
279 |
|
307 |
|
280 |
if ( n ) |
308 |
if ( n ) |
281 |
{ |
309 |
{ |
282 |
gcry_cipher_decrypt (dfx->cipher_hd, buf, n, NULL, 0); |
310 |
if ( dfx->cipher_hd ) |
283 |
gcry_md_write (dfx->mdc_hash, buf, n); |
311 |
gcry_cipher_decrypt (dfx->cipher_hd, buf, n, NULL, 0); |
|
|
312 |
if ( dfx->mdc_hash ) |
313 |
gcry_md_write (dfx->mdc_hash, buf, n); |
284 |
} |
314 |
} |
285 |
else |
315 |
else |
286 |
{ |
316 |
{ |
Lines 289-294
Link Here
|
289 |
} |
319 |
} |
290 |
*ret_len = n; |
320 |
*ret_len = n; |
291 |
} |
321 |
} |
|
|
322 |
else if ( control == IOBUFCTRL_FREE ) |
323 |
{ |
324 |
release_dfx_context (dfx); |
325 |
} |
292 |
else if ( control == IOBUFCTRL_DESC ) |
326 |
else if ( control == IOBUFCTRL_DESC ) |
293 |
{ |
327 |
{ |
294 |
*(char**)buf = "mdc_decode_filter"; |
328 |
*(char**)buf = "mdc_decode_filter"; |
Lines 300-306
Link Here
|
300 |
static int |
334 |
static int |
301 |
decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len) |
335 |
decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len) |
302 |
{ |
336 |
{ |
303 |
decode_filter_ctx_t *fc = opaque; |
337 |
decode_filter_ctx_t fc = opaque; |
304 |
size_t n, size = *ret_len; |
338 |
size_t n, size = *ret_len; |
305 |
int rc = 0; |
339 |
int rc = 0; |
306 |
|
340 |
|
Lines 311-321
Link Here
|
311 |
if ( n == -1 ) |
345 |
if ( n == -1 ) |
312 |
n = 0; |
346 |
n = 0; |
313 |
if ( n ) |
347 |
if ( n ) |
314 |
gcry_cipher_decrypt (fc->cipher_hd, buf, n, NULL, 0); |
348 |
{ |
|
|
349 |
if (fc->cipher_hd) |
350 |
gcry_cipher_decrypt (fc->cipher_hd, buf, n, NULL, 0); |
351 |
} |
315 |
else |
352 |
else |
316 |
rc = -1; /* EOF */ |
353 |
rc = -1; /* EOF */ |
317 |
*ret_len = n; |
354 |
*ret_len = n; |
318 |
} |
355 |
} |
|
|
356 |
else if ( control == IOBUFCTRL_FREE ) |
357 |
{ |
358 |
release_dfx_context (fc); |
359 |
} |
319 |
else if ( control == IOBUFCTRL_DESC ) |
360 |
else if ( control == IOBUFCTRL_DESC ) |
320 |
{ |
361 |
{ |
321 |
*(char**)buf = "decode_filter"; |
362 |
*(char**)buf = "decode_filter"; |