Sophie

Sophie

distrib > Mandriva > 2007.0 > x86_64 > by-pkgid > 77892816771d96cd2436f0b5e2750bb5 > files > 1

gnupg2-1.9.22-2.2mdv2007.0.src.rpm

--- gnupg-1.9.22/g10/encr-data.c.cve-2006-6235	2006-06-20 10:33:00.000000000 -0600
+++ gnupg-1.9.22/g10/encr-data.c	2006-12-05 11:37:13.000000000 -0700
@@ -46,8 +46,26 @@ typedef struct 
   char defer[20];
   int  defer_filled;
   int  eof_seen;
-} decode_filter_ctx_t;
+  int  refcount;
+} *decode_filter_ctx_t;
 
+/* Helper to release the decode context.  */
+static void
+release_dfx_context (decode_filter_ctx_t dfx)
+{
+  if (!dfx)
+    return;
+
+  assert (dfx->refcount);
+  if ( !--dfx->refcount )
+    {
+      cipher_close (dfx->cipher_hd);
+      dfx->cipher_hd = NULL;
+      md_close (dfx->mdc_hash);
+      dfx->mdc_hash = NULL;
+      xfree (dfx);
+    }
+}
 
 /****************
  * Decrypt the data, specified by ED with the key DEK.
@@ -62,7 +80,10 @@ decrypt_data( void *procctx, PKT_encrypt
     unsigned blocksize;
     unsigned nprefix;
 
-    memset( &dfx, 0, sizeof dfx );
+
+    dfx = xcalloc (1, sizeof *dfx);
+    dfx->refcount = 1;
+
     if( opt.verbose && !dek->algo_info_printed ) {
 	const char *s = gcry_cipher_algo_name (dek->algo);
 	if (s && *s)
@@ -76,19 +97,19 @@ decrypt_data( void *procctx, PKT_encrypt
 	goto leave;
     blocksize = gcry_cipher_get_algo_blklen (dek->algo);
     if( !blocksize || blocksize > 16 )
-	log_fatal("unsupported blocksize %u\n", blocksize );
+	log_fatal ("unsupported blocksize %u\n", blocksize );
     nprefix = blocksize;
     if( ed->len && ed->len < (nprefix+2) )
 	BUG();
 
     if( ed->mdc_method ) {
-        if (gcry_md_open (&dfx.mdc_hash, ed->mdc_method, 0 ))
+        if (gcry_md_open (&dfx->mdc_hash, ed->mdc_method, 0 ))
             BUG ();
 	if ( DBG_HASHING )
-	    gcry_md_start_debug (dfx.mdc_hash, "checkmdc");
+	    gcry_md_start_debug (dfx->mdc_hash, "checkmdc");
     }
 
-    rc = gcry_cipher_open (&dfx.cipher_hd, dek->algo,
+    rc = gcry_cipher_open (&dfx->cipher_hd, dek->algo,
                            GCRY_CIPHER_MODE_CFB,
                            (GCRY_CIPHER_SECURE
                             | ((ed->mdc_method || dek->algo >= 100)?
@@ -102,7 +123,7 @@ decrypt_data( void *procctx, PKT_encrypt
 
 
     /* log_hexdump( "thekey", dek->key, dek->keylen );*/
-    rc = gcry_cipher_setkey (dfx.cipher_hd, dek->key, dek->keylen);
+    rc = gcry_cipher_setkey (dfx->cipher_hd, dek->key, dek->keylen);
     if ( gpg_err_code (rc) == GPG_ERR_WEAK_KEY )
       {
 	log_info(_("WARNING: message was encrypted with"
@@ -120,7 +141,7 @@ decrypt_data( void *procctx, PKT_encrypt
         goto leave;
     }
 
-    gcry_cipher_setiv (dfx.cipher_hd, NULL, 0);
+    gcry_cipher_setiv (dfx->cipher_hd, NULL, 0);
 
     if( ed->len ) {
 	for(i=0; i < (nprefix+2) && ed->len; i++, ed->len-- ) {
@@ -138,8 +159,8 @@ decrypt_data( void *procctx, PKT_encrypt
 		temp[i] = c;
     }
 
-    gcry_cipher_decrypt (dfx.cipher_hd, temp, nprefix+2, NULL, 0);
-    gcry_cipher_sync (dfx.cipher_hd);
+    gcry_cipher_decrypt (dfx->cipher_hd, temp, nprefix+2, NULL, 0);
+    gcry_cipher_sync (dfx->cipher_hd);
     p = temp;
 /* log_hexdump( "prefix", temp, nprefix+2 ); */
     if(dek->symmetric
@@ -149,34 +170,34 @@ decrypt_data( void *procctx, PKT_encrypt
 	goto leave;
       }
 
-    if( dfx.mdc_hash )
-	gcry_md_write (dfx.mdc_hash, temp, nprefix+2);
+    if( dfx->mdc_hash )
+	gcry_md_write (dfx->mdc_hash, temp, nprefix+2);
 
+    dfx->refcount++;
     if( ed->mdc_method )
-	iobuf_push_filter( ed->buf, mdc_decode_filter, &dfx );
+	iobuf_push_filter( ed->buf, mdc_decode_filter, dfx );
     else
-	iobuf_push_filter( ed->buf, decode_filter, &dfx );
+	iobuf_push_filter( ed->buf, decode_filter, dfx );
 
     proc_packets( procctx, ed->buf );
     ed->buf = NULL;
-    if( ed->mdc_method && dfx.eof_seen == 2 )
+    if( ed->mdc_method && dfx->eof_seen == 2 )
 	rc = gpg_error (GPG_ERR_INV_PACKET);
     else if( ed->mdc_method ) { /* check the mdc */
 	int datalen = gcry_md_get_algo_dlen (ed->mdc_method);
 
-	gcry_cipher_decrypt (dfx.cipher_hd, dfx.defer, 20, NULL, 0);
-	gcry_md_final (dfx.mdc_hash);
+	gcry_cipher_decrypt (dfx->cipher_hd, dfx->defer, 20, NULL, 0);
+	gcry_md_final (dfx->mdc_hash);
 	if (datalen != 20
-	    || memcmp (gcry_md_read( dfx.mdc_hash, 0 ), dfx.defer, datalen) )
+	    || memcmp (gcry_md_read( dfx->mdc_hash, 0 ), dfx->defer, datalen) )
           rc = gpg_error (GPG_ERR_BAD_SIGNATURE);
-	/*log_hexdump("MDC calculated:", md_read( dfx.mdc_hash, 0), datalen);*/
-	/*log_hexdump("MDC message   :", dfx.defer, 20);*/
+	/*log_hexdump("MDC calculated:", md_read( dfx->mdc_hash, 0), datalen);*/
+	/*log_hexdump("MDC message   :", dfx->defer, 20);*/
     }
     
 
   leave:
-    gcry_cipher_close (dfx.cipher_hd);
-    gcry_md_close (dfx.mdc_hash);
+    release_dfx_context (dfx);
     return rc;
 }
 
@@ -187,7 +208,7 @@ static int
 mdc_decode_filter( void *opaque, int control, IOBUF a,
 					      byte *buf, size_t *ret_len)
 {
-    decode_filter_ctx_t *dfx = opaque;
+    decode_filter_ctx_t dfx = opaque;
     size_t n, size = *ret_len;
     int rc = 0;
     int c;
@@ -197,11 +218,11 @@ mdc_decode_filter( void *opaque, int con
 	rc = -1;
     }
     else if( control == IOBUFCTRL_UNDERFLOW ) {
-	assert(a);
-	assert( size > 40 );
+	assert (a);
+	assert ( size > 40 );
 
 	/* get at least 20 bytes and put it somewhere ahead in the buffer */
-	for(n=20; n < 40 ; n++ ) {
+	for (n=20; n < 40 ; n++ ) {
 	    if( (c = iobuf_get(a)) == -1 )
 		break;
 	    buf[n] = c;
@@ -242,8 +263,10 @@ mdc_decode_filter( void *opaque, int con
 	}
 
 	if( n ) {
-	    gcry_cipher_decrypt (dfx->cipher_hd, buf, n, NULL, 0);
-	    gcry_md_write (dfx->mdc_hash, buf, n);
+	    if ( dfx->cipher_hd )
+	      gcry_cipher_decrypt (dfx->cipher_hd, buf, n, NULL, 0);
+	    if ( dfx->mdc_hash )
+	      gcry_md_write (dfx->mdc_hash, buf, n);
 	}
 	else {
 	    assert( dfx->eof_seen );
@@ -251,6 +274,9 @@ mdc_decode_filter( void *opaque, int con
 	}
 	*ret_len = n;
     }
+    else if ( control == IOBUFCTRL_FREE ) {
+        release_dfx_context (dfx);
+    }
     else if( control == IOBUFCTRL_DESC ) {
 	*(char**)buf = "mdc_decode_filter";
     }
@@ -260,7 +286,7 @@ mdc_decode_filter( void *opaque, int con
 static int
 decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len)
 {
-    decode_filter_ctx_t *fc = opaque;
+    decode_filter_ctx_t fc = opaque;
     size_t n, size = *ret_len;
     int rc = 0;
 
@@ -269,14 +295,21 @@ decode_filter( void *opaque, int control
 	n = iobuf_read( a, buf, size );
 	if( n == -1 ) n = 0;
 	if( n )
-	    gcry_cipher_decrypt (fc->cipher_hd, buf, n, NULL, 0);
+	  {
+            if (fc->cipher_hd)
+              gcry_cipher_decrypt (fc->cipher_hd, buf, n, NULL, 0);
+	  }
 	else
 	    rc = -1; /* eof */
 	*ret_len = n;
     }
+    else if ( control == IOBUFCTRL_FREE )
+      {
+        release_dfx_context (fc);
+      }
     else if( control == IOBUFCTRL_DESC ) {
 	*(char**)buf = "decode_filter";
     }
     return rc;
 }
-
+