~ubuntu-branches/ubuntu/hardy/gnupg2/hardy-security

« back to all changes in this revision

Viewing changes to g10/encr-data.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Bienia, Michael Bienia, Kees Cook
  • Date: 2006-12-07 00:28:23 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20061207002823-0i7ittrpmsm1nv0i
Tags: 2.0.1-0ubuntu1
[ Michael Bienia ]
* New upstream version.
* Remaining changes:
  - Remove libpcsclite-dev, libopensc2-dev build dependencies (they are in
    universe).
* g10/encr-data.c: remotely controllable function pointer (CVE-2006-6235)
* debian/control: add libcurl3-gnutls-dev to build-depends 
  (Closes Ubuntu: #62864)

[ Kees Cook ]
* debian/rules: include doc/ files as done with gnupg

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
static int decode_filter ( void *opaque, int control, IOBUF a,
40
40
                                        byte *buf, size_t *ret_len);
41
41
 
42
 
typedef struct 
 
42
typedef struct decode_filter_context_s
43
43
{
44
44
  gcry_cipher_hd_t cipher_hd;
45
45
  gcry_md_hd_t mdc_hash;
46
46
  char defer[22];
47
47
  int  defer_filled;
48
48
  int  eof_seen;
49
 
} decode_filter_ctx_t;
 
49
  int  refcount;
 
50
} *decode_filter_ctx_t;
 
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
 
50
71
 
51
72
 
52
73
/****************
62
83
  unsigned blocksize;
63
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
91
  if ( opt.verbose && !dek->algo_info_printed )
67
92
    {
68
93
      const char *s = gcry_cipher_algo_name (dek->algo);
77
102
    goto leave;
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) )
83
108
    BUG();
84
109
 
85
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
113
        BUG ();
89
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
119
                         GCRY_CIPHER_MODE_CFB,
95
120
                         (GCRY_CIPHER_SECURE
96
121
                          | ((ed->mdc_method || dek->algo >= 100)?
104
129
 
105
130
 
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 )
109
134
    {
110
135
      log_info(_("WARNING: message was encrypted with"
123
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
153
  if ( ed->len )
129
154
    {
144
169
          temp[i] = c;
145
170
    }
146
171
  
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);
149
174
  p = temp;
150
175
  /* log_hexdump( "prefix", temp, nprefix+2 ); */
151
176
  if (dek->symmetric
155
180
      goto leave;
156
181
    }
157
182
  
158
 
  if ( dfx.mdc_hash )
159
 
    gcry_md_write (dfx.mdc_hash, temp, nprefix+2);
160
 
  
 
183
  if ( dfx->mdc_hash )
 
184
    gcry_md_write (dfx->mdc_hash, temp, nprefix+2);
 
185
 
 
186
  dfx->refcount++;
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 );
163
189
  else
164
 
    iobuf_push_filter( ed->buf, decode_filter, &dfx );
 
190
    iobuf_push_filter ( ed->buf, decode_filter, dfx );
165
191
 
166
192
  proc_packets ( procctx, ed->buf );
167
193
  ed->buf = NULL;
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 )
171
197
    { 
184
210
         bytes are appended.  */
185
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);
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);
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
221
          log_error("mdc_packet with invalid encoding\n");
194
222
          rc = gpg_error (GPG_ERR_INV_PACKET);
195
223
        }
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); */
201
230
    }
202
231
  
203
232
  
204
233
 leave:
205
 
  gcry_cipher_close (dfx.cipher_hd);
206
 
  gcry_md_close (dfx.mdc_hash);
 
234
  release_dfx_context (dfx);
207
235
  return rc;
208
236
}
209
237
 
214
242
mdc_decode_filter (void *opaque, int control, IOBUF a,
215
243
                   byte *buf, size_t *ret_len)
216
244
{
217
 
  decode_filter_ctx_t *dfx = opaque;
 
245
  decode_filter_ctx_t dfx = opaque;
218
246
  size_t n, size = *ret_len;
219
247
  int rc = 0;
220
248
  int c;
226
254
    }
227
255
  else if( control == IOBUFCTRL_UNDERFLOW )
228
256
    {
229
 
      assert(a);
230
 
      assert( size > 44 );
 
257
      assert (a);
 
258
      assert ( size > 44 );
231
259
      
232
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
263
          if( (c = iobuf_get(a)) == -1 )
236
264
            break;
279
307
 
280
308
      if ( n )
281
309
        {
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);
 
312
          if ( dfx->mdc_hash )
 
313
            gcry_md_write (dfx->mdc_hash, buf, n);
284
314
        }
285
315
      else
286
316
        {
289
319
        }
290
320
      *ret_len = n;
291
321
    }
 
322
  else if ( control == IOBUFCTRL_FREE ) 
 
323
    {
 
324
      release_dfx_context (dfx);
 
325
    }
292
326
  else if ( control == IOBUFCTRL_DESC ) 
293
327
    {
294
328
      *(char**)buf = "mdc_decode_filter";
300
334
static int
301
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
338
  size_t n, size = *ret_len;
305
339
  int rc = 0;
306
340
  
311
345
      if ( n == -1 )
312
346
        n = 0;
313
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
352
      else
316
353
        rc = -1; /* EOF */
317
354
      *ret_len = n;
318
355
    }
 
356
  else if ( control == IOBUFCTRL_FREE ) 
 
357
    {
 
358
      release_dfx_context (fc);
 
359
    }
319
360
  else if ( control == IOBUFCTRL_DESC )
320
361
    {
321
362
      *(char**)buf = "decode_filter";