~ubuntu-branches/ubuntu/trusty/gnupg2/trusty-proposed

« back to all changes in this revision

Viewing changes to g10/mainproc.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2013-10-07 15:38:03 UTC
  • mfrom: (18.1.4 saucy)
  • Revision ID: package-import@ubuntu.com-20131007153803-9z5dpnkp34igz6ax
Tags: 2.0.20-1ubuntu3
* SECURITY UPDATE: incorrect no-usage-permitted flag handling
  - debian/patches/CVE-2013-4351.patch: correctly handle empty key flags
    in g10/getkey.c, g10/keygen.c, include/cipher.h.
  - CVE-2013-4351
* SECURITY UPDATE: denial of service via infinite recursion
  - debian/patches/CVE-2013-4402.patch: set limits on number of filters
    and nested packets in common/iobuf.c, g10/mainproc.c.
  - CVE-2013-4402

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
#include "pka.h"
43
43
 
44
44
 
 
45
/* Put an upper limit on nested packets.  The 32 is an arbitrary
 
46
   value, a much lower should actually be sufficient.  */
 
47
#define MAX_NESTING_DEPTH 32
 
48
 
 
49
 
45
50
struct kidlist_item {
46
51
    struct kidlist_item *next;
47
52
    u32 kid[2];
86
91
  DEK *dek;
87
92
  int last_was_session_key;
88
93
  KBNODE list;      /* The current list of packets. */
89
 
  int have_data;
90
94
  IOBUF iobuf;      /* Used to get the filename etc. */
91
95
  int trustletter;  /* Temporary usage in list_node. */
92
96
  ulong symkeys;
93
97
  struct kidlist_item *pkenc_list; /* List of encryption packets. */
94
 
  int any_sig_seen;  /* Set to true if a signature packet has been seen. */
 
98
  struct {
 
99
    unsigned int sig_seen:1;      /* Set to true if a signature packet
 
100
                                     has been seen. */
 
101
    unsigned int data:1;          /* Any data packet seen */
 
102
    unsigned int uncompress_failed:1;
 
103
  } any;
95
104
};
96
105
 
97
106
 
120
129
    }
121
130
    c->pkenc_list = NULL;
122
131
    c->list = NULL;
123
 
    c->have_data = 0;
 
132
    c->any.data = 0;
 
133
    c->any.uncompress_failed = 0;
124
134
    c->last_was_session_key = 0;
125
135
    xfree(c->dek); c->dek = NULL;
126
136
}
198
208
{
199
209
    KBNODE node;
200
210
 
201
 
    c->any_sig_seen = 1;
 
211
    c->any.sig_seen = 1;
202
212
    if( pkt->pkttype == PKT_SIGNATURE && !c->list ) {
203
213
        /* This is the first signature for the following datafile.
204
214
         * GPG does not write such packets; instead it always uses
764
774
    return proc_encryption_packets( info, a );
765
775
}
766
776
 
767
 
static void
 
777
static int
768
778
proc_compressed( CTX c, PACKET *pkt )
769
779
{
770
 
    PKT_compressed *zd = pkt->pkt.compressed;
771
 
    int rc;
772
 
 
773
 
    /*printf("zip: compressed data packet\n");*/
774
 
    if (c->sigs_only)
775
 
        rc = handle_compressed( c, zd, proc_compressed_cb, c );
776
 
    else if( c->encrypt_only )
777
 
        rc = handle_compressed( c, zd, proc_encrypt_cb, c );
778
 
    else
779
 
        rc = handle_compressed( c, zd, NULL, NULL );
780
 
    if( rc )
781
 
        log_error("uncompressing failed: %s\n", g10_errstr(rc));
782
 
    free_packet(pkt);
783
 
    c->last_was_session_key = 0;
 
780
  PKT_compressed *zd = pkt->pkt.compressed;
 
781
  int rc;
 
782
 
 
783
  /*printf("zip: compressed data packet\n");*/
 
784
  if (c->sigs_only)
 
785
    rc = handle_compressed (c, zd, proc_compressed_cb, c);
 
786
  else if (c->encrypt_only)
 
787
    rc = handle_compressed (c, zd, proc_encrypt_cb, c);
 
788
  else
 
789
    rc = handle_compressed (c, zd, NULL, NULL);
 
790
 
 
791
  if (gpg_err_code (rc) == GPG_ERR_BAD_DATA)
 
792
    {
 
793
      if  (!c->any.uncompress_failed)
 
794
        {
 
795
          CTX cc;
 
796
 
 
797
          for (cc=c; cc; cc = cc->anchor)
 
798
            cc->any.uncompress_failed = 1;
 
799
          log_error ("uncompressing failed: %s\n", g10_errstr(rc));
 
800
        }
 
801
      }
 
802
  else if (rc)
 
803
    log_error("uncompressing failed: %s\n", g10_errstr(rc));
 
804
 
 
805
  free_packet (pkt);
 
806
  c->last_was_session_key = 0;
 
807
  return rc;
784
808
}
785
809
 
786
810
/****************
1197
1221
       Using log_error is required because verify_files does not check
1198
1222
       error codes for each file but we want to terminate the process
1199
1223
       with an error. */
1200
 
    if (!rc && !c->any_sig_seen)
 
1224
    if (!rc && !c->any.sig_seen)
1201
1225
      {
1202
1226
        write_status_text (STATUS_NODATA, "4");
1203
1227
        log_error (_("no signature found\n"));
1207
1231
    /* Propagate the signature seen flag upward. Do this only on
1208
1232
       success so that we won't issue the nodata status several
1209
1233
       times. */
1210
 
    if (!rc && c->anchor && c->any_sig_seen)
1211
 
      c->anchor->any_sig_seen = 1;
 
1234
    if (!rc && c->anchor && c->any.sig_seen)
 
1235
      c->anchor->any.sig_seen = 1;
1212
1236
 
1213
1237
    xfree( c );
1214
1238
    return rc;
1234
1258
     Using log_error is required because verify_files does not check
1235
1259
     error codes for each file but we want to terminate the process
1236
1260
     with an error. */
1237
 
  if (!rc && !c->any_sig_seen)
 
1261
  if (!rc && !c->any.sig_seen)
1238
1262
    {
1239
1263
      write_status_text (STATUS_NODATA, "4");
1240
1264
      log_error (_("no signature found\n"));
1243
1267
 
1244
1268
  /* Propagate the signature seen flag upward. Do this only on success
1245
1269
     so that we won't issue the nodata status several times. */
1246
 
  if (!rc && c->anchor && c->any_sig_seen)
1247
 
    c->anchor->any_sig_seen = 1;
 
1270
  if (!rc && c->anchor && c->any.sig_seen)
 
1271
    c->anchor->any.sig_seen = 1;
1248
1272
 
1249
1273
  xfree ( c );
1250
1274
  return rc;
1265
1289
}
1266
1290
 
1267
1291
 
1268
 
int
 
1292
static int
 
1293
check_nesting (CTX c)
 
1294
{
 
1295
  int level;
 
1296
 
 
1297
  for (level=0; c; c = c->anchor)
 
1298
    level++;
 
1299
 
 
1300
  if (level > MAX_NESTING_DEPTH)
 
1301
    {
 
1302
      log_error ("input data with too deeply nested packets\n");
 
1303
      write_status_text (STATUS_UNEXPECTED, "1");
 
1304
      return GPG_ERR_BAD_DATA;
 
1305
    }
 
1306
  return 0;
 
1307
}
 
1308
 
 
1309
 
 
1310
static int
1269
1311
do_proc_packets( CTX c, IOBUF a )
1270
1312
{
1271
 
    PACKET *pkt = xmalloc( sizeof *pkt );
1272
 
    int rc=0;
1273
 
    int any_data=0;
 
1313
    PACKET *pkt;
 
1314
    int rc = 0;
 
1315
    int any_data = 0;
1274
1316
    int newpkt;
1275
1317
 
 
1318
    rc = check_nesting (c);
 
1319
    if (rc)
 
1320
      return rc;
 
1321
 
 
1322
    pkt = xmalloc( sizeof *pkt );
1276
1323
    c->iobuf = a;
1277
1324
    init_packet(pkt);
1278
1325
    while( (rc=parse_packet(a, pkt)) != -1 ) {
1293
1340
              case PKT_SYMKEY_ENC:  proc_symkey_enc( c, pkt ); break;
1294
1341
              case PKT_ENCRYPTED:
1295
1342
              case PKT_ENCRYPTED_MDC: proc_encrypted( c, pkt ); break;
1296
 
              case PKT_COMPRESSED:  proc_compressed( c, pkt ); break;
 
1343
              case PKT_COMPRESSED:  rc = proc_compressed( c, pkt ); break;
1297
1344
              default: newpkt = 0; break;
1298
1345
            }
1299
1346
        }
1311
1358
                goto leave;
1312
1359
              case PKT_SIGNATURE:   newpkt = add_signature( c, pkt ); break;
1313
1360
              case PKT_PLAINTEXT:   proc_plaintext( c, pkt ); break;
1314
 
              case PKT_COMPRESSED:  proc_compressed( c, pkt ); break;
 
1361
              case PKT_COMPRESSED:  rc = proc_compressed( c, pkt ); break;
1315
1362
              case PKT_ONEPASS_SIG: newpkt = add_onepass_sig( c, pkt ); break;
1316
1363
              case PKT_GPG_CONTROL: newpkt = add_gpg_control(c, pkt); break;
1317
1364
              default: newpkt = 0; break;
1331
1378
              case PKT_ENCRYPTED:
1332
1379
              case PKT_ENCRYPTED_MDC: proc_encrypted( c, pkt ); break;
1333
1380
              case PKT_PLAINTEXT:   proc_plaintext( c, pkt ); break;
1334
 
              case PKT_COMPRESSED:  proc_compressed( c, pkt ); break;
 
1381
              case PKT_COMPRESSED:  rc = proc_compressed( c, pkt ); break;
1335
1382
              case PKT_ONEPASS_SIG: newpkt = add_onepass_sig( c, pkt ); break;
1336
1383
              case PKT_GPG_CONTROL: newpkt = add_gpg_control(c, pkt); break;
1337
1384
              default: newpkt = 0; break;
1356
1403
              case PKT_ENCRYPTED:
1357
1404
              case PKT_ENCRYPTED_MDC: proc_encrypted( c, pkt ); break;
1358
1405
              case PKT_PLAINTEXT:   proc_plaintext( c, pkt ); break;
1359
 
              case PKT_COMPRESSED:  proc_compressed( c, pkt ); break;
 
1406
              case PKT_COMPRESSED:  rc = proc_compressed( c, pkt ); break;
1360
1407
              case PKT_ONEPASS_SIG: newpkt = add_onepass_sig( c, pkt ); break;
1361
1408
              case PKT_GPG_CONTROL: newpkt = add_gpg_control(c, pkt); break;
1362
1409
              case PKT_RING_TRUST:  newpkt = add_ring_trust( c, pkt ); break;
1363
1410
              default: newpkt = 0; break;
1364
1411
            }
1365
1412
        }
 
1413
 
 
1414
        if (rc)
 
1415
          goto leave;
 
1416
 
1366
1417
        /* This is a very ugly construct and frankly, I don't remember why
1367
1418
         * I used it.  Adding the MDC check here is a hack.
1368
1419
         * The right solution is to initiate another context for encrypted
1372
1423
         * Hmmm: Rewrite this whole module here??
1373
1424
         */
1374
1425
        if( pkt->pkttype != PKT_SIGNATURE && pkt->pkttype != PKT_MDC )
1375
 
            c->have_data = pkt->pkttype == PKT_PLAINTEXT;
 
1426
            c->any.data = (pkt->pkttype == PKT_PLAINTEXT);
1376
1427
 
1377
1428
        if( newpkt == -1 )
1378
1429
            ;
2010
2061
    }
2011
2062
    else if( node->pkt->pkttype == PKT_ONEPASS_SIG ) {
2012
2063
        /* check all signatures */
2013
 
        if( !c->have_data ) {
 
2064
        if( !c->any.data ) {
2014
2065
            int use_textmode = 0;
2015
2066
 
2016
2067
            free_md_filter_context( &c->mfx );
2063
2114
             && node->pkt->pkt.gpg_control->control
2064
2115
                == CTRLPKT_CLEARSIGN_START ) {
2065
2116
        /* clear text signed message */
2066
 
        if( !c->have_data ) {
 
2117
        if( !c->any.data ) {
2067
2118
            log_error("cleartext signature without data\n" );
2068
2119
            return;
2069
2120
        }
2105
2156
        if( sig->sig_class != 0x00 && sig->sig_class != 0x01 )
2106
2157
            log_info(_("standalone signature of class 0x%02x\n"),
2107
2158
                                                    sig->sig_class);
2108
 
        else if( !c->have_data ) {
 
2159
        else if( !c->any.data ) {
2109
2160
            /* detached signature */
2110
2161
            free_md_filter_context( &c->mfx );
2111
2162
            if (gcry_md_open (&c->mfx.md, sig->digest_algo, 0))