~ubuntu-dev/ubuntu/lucid/mutt/lucid-201002110857

« back to all changes in this revision

Viewing changes to crypt-gpgme.c

  • Committer: Bazaar Package Importer
  • Author(s): Bhavani Shankar
  • Date: 2009-06-07 17:30:03 UTC
  • mto: (16.2.1 experimental) (2.3.1 squeeze)
  • mto: This revision was merged to the branch mainline in revision 21.
  • Revision ID: james.westby@ubuntu.com-20090607173003-rg37ui3h2bbv7wl0
Tags: upstream-1.5.19
ImportĀ upstreamĀ versionĀ 1.5.19

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* crypt-gpgme.c - GPGME based crypto operations
2
 
 * Copyright (C) 1996,1997 Michael R. Elkins <me@cs.hmc.edu>
 
2
 * Copyright (C) 1996-7,2007 Michael R. Elkins <me@cs.hmc.edu>
3
3
 * Copyright (C) 1998,1999,2000 Thomas Roessler <roessler@does-not-exist.org>
4
4
 * Copyright (C) 2001  Thomas Roessler <roessler@does-not-exist.org>
5
5
 *                     Oliver Ehli <elmy@acm.org>
82
82
#define CRYPT_KV_STRONGID 8
83
83
#define CRYPT_KV_MATCH (CRYPT_KV_ADDR|CRYPT_KV_STRING)
84
84
 
 
85
/* static local variables */
 
86
static int GpgmeLocaleSet = 0;
 
87
 
85
88
/*
86
89
 * Type definitions.
87
90
 */
339
342
  gpgme_error_t err;
340
343
  gpgme_ctx_t ctx;
341
344
 
 
345
  if (!GpgmeLocaleSet)
 
346
  {
 
347
    gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL));
 
348
#ifdef ENABLE_NLS
 
349
    gpgme_set_locale (NULL, LC_MESSAGES, setlocale (LC_MESSAGES, NULL));
 
350
#endif
 
351
 
 
352
    GpgmeLocaleSet = 1;
 
353
  }
 
354
 
342
355
  err = gpgme_new (&ctx);
343
356
  if (err)
344
357
    {
756
769
   which must have been allocated by the caller with size BUFLEN.
757
770
   Returns 0 on success or -1 in case of an error.  The return string
758
771
   is truncted to BUFLEN - 1. */
759
 
static int get_micalg (gpgme_ctx_t ctx, char *buf, size_t buflen)
 
772
static int get_micalg (gpgme_ctx_t ctx, int use_smime, char *buf, size_t buflen)
760
773
{
761
774
  gpgme_sign_result_t result = NULL;
762
775
  const char *algorithm_name = NULL;
771
784
    algorithm_name = gpgme_hash_algo_name (result->signatures->hash_algo);
772
785
    if (algorithm_name)
773
786
    {
774
 
      /* convert GPGME raw hash name to RFC 3156 format */
775
 
      snprintf (buf, buflen, "pgp-%s", algorithm_name);
776
 
      ascii_strlower (buf + 4);
 
787
      if (use_smime)
 
788
      {
 
789
        /* convert GPGME raw hash name to RFC 2633 format */
 
790
        snprintf (buf, buflen, "%s", algorithm_name);
 
791
        ascii_strlower (buf);
 
792
      } else {
 
793
        /* convert GPGME raw hash name to RFC 3156 format */
 
794
        snprintf (buf, buflen, "pgp-%s", algorithm_name);
 
795
        ascii_strlower (buf + 4);
 
796
      }
777
797
    }
778
798
  }
779
799
 
873
893
                      &t->parameter);
874
894
  /* Get the micalg from gpgme.  Old gpgme versions don't support this
875
895
     for S/MIME so we assume sha-1 in this case. */
876
 
  if (!get_micalg (ctx, buf, sizeof buf))
 
896
  if (!get_micalg (ctx, use_smime, buf, sizeof buf))
877
897
    mutt_set_parameter ("micalg", buf, &t->parameter);
878
898
  else if (use_smime)
879
 
    mutt_set_parameter ("micalg", "pgp-sha1", &t->parameter);
 
899
    mutt_set_parameter ("micalg", "sha1", &t->parameter);
880
900
  gpgme_release (ctx);
881
901
 
882
902
  t->parts = a;
1245
1265
    state_attach_puts (txt, s);
1246
1266
}
1247
1267
 
 
1268
static void print_smime_keyinfo (const char* msg, gpgme_signature_t sig,
 
1269
                                 gpgme_key_t key, STATE *s)
 
1270
{
 
1271
  size_t msglen;
 
1272
  gpgme_user_id_t uids = NULL;
 
1273
  int i, aka = 0;
 
1274
 
 
1275
  state_attach_puts (msg, s);
 
1276
  state_attach_puts (" ", s);
 
1277
  for (uids = key->uids; uids; uids = uids->next)
 
1278
  {
 
1279
    if (uids->revoked)
 
1280
      continue;
 
1281
    if (aka)
 
1282
    {
 
1283
      msglen = mutt_strlen (msg) - 4;
 
1284
      for (i = 0; i < msglen; i++)
 
1285
        state_attach_puts(" ", s);
 
1286
      state_attach_puts(_("aka: "), s);
 
1287
    }
 
1288
    state_attach_puts (uids->uid, s);
 
1289
    state_attach_puts ("\n", s);
 
1290
    
 
1291
    aka = 1;
 
1292
  }
 
1293
 
 
1294
  msglen = mutt_strlen (msg) - 8;
 
1295
  for (i = 0; i < msglen; i++)
 
1296
    state_attach_puts(" ", s);
 
1297
  state_attach_puts (_("created: "), s);
 
1298
  print_time (sig->timestamp, s);
 
1299
  state_attach_puts ("\n", s);  
 
1300
}
 
1301
 
1248
1302
/* Show information about one signature.  This fucntion is called with
1249
1303
   the context CTX of a sucessful verification operation and the
1250
1304
   enumerator IDX which should start at 0 and incremete for each
1254
1308
   2 for a signature with a warning or -1 for no more signature.  */
1255
1309
static int show_one_sig_status (gpgme_ctx_t ctx, int idx, STATE *s)
1256
1310
{
1257
 
  time_t created;
1258
1311
  const char *fpr, *uid;
1259
1312
  gpgme_key_t key = NULL;
1260
1313
  int i, anybad = 0, anywarn = 0;
1261
1314
  unsigned int sum;
1262
 
  gpgme_user_id_t uids = NULL;
1263
1315
  gpgme_verify_result_t result;
1264
1316
  gpgme_signature_t sig;
1265
1317
  gpgme_error_t err = GPG_ERR_NO_ERROR;
1283
1335
          signature_key = NULL;
1284
1336
        }
1285
1337
      
1286
 
      created = sig->timestamp;
1287
1338
      fpr = sig->fpr;
1288
1339
      sum = sig->summary;
1289
1340
 
1308
1359
        ; /* No state information so no way to print anything. */
1309
1360
      else if (err)
1310
1361
        {
1311
 
          state_attach_puts (_("Error getting key information: "), s);
1312
 
         state_attach_puts ( gpg_strerror (err), s );
1313
 
          state_attach_puts ("\n", s);
1314
 
         anybad = 1;
 
1362
          state_attach_puts (_("Error getting key information: "), s);
 
1363
          state_attach_puts ( gpg_strerror (err), s );
 
1364
          state_attach_puts ("\n", s);
 
1365
          anybad = 1;
1315
1366
        }
1316
1367
      else if ((sum & GPGME_SIGSUM_GREEN))
1317
 
        {
1318
 
          state_attach_puts (_("Good signature from: "), s);
1319
 
          state_attach_puts (uid, s);
1320
 
          state_attach_puts ("\n", s);
1321
 
          for (i = 1, uids = key->uids; uids; i++, uids = uids->next)
1322
 
            {
1323
 
              if (i == 1)
1324
 
                /* Skip primary UID.  */
1325
 
                continue;
1326
 
              if (uids->revoked)
1327
 
                continue;
1328
 
              state_attach_puts (_("                aka: "), s);
1329
 
              state_attach_puts (uids->uid, s);
1330
 
              state_attach_puts ("\n", s);
1331
 
            }
1332
 
          state_attach_puts (_("            created: "), s);
1333
 
          print_time (created, s);
1334
 
          state_attach_puts ("\n", s);
1335
 
          if (show_sig_summary (sum, ctx, key, idx, s, sig))
1336
 
            anywarn = 1;
1337
 
          show_one_sig_validity (ctx, idx, s);
1338
 
        }
 
1368
      {
 
1369
        print_smime_keyinfo (_("Good signature from:"), sig, key, s);
 
1370
        if (show_sig_summary (sum, ctx, key, idx, s, sig))
 
1371
          anywarn = 1;
 
1372
        show_one_sig_validity (ctx, idx, s);
 
1373
      }
1339
1374
      else if ((sum & GPGME_SIGSUM_RED))
1340
 
        {
1341
 
          state_attach_puts (_("*BAD* signature claimed to be from: "), s);
1342
 
          state_attach_puts (uid, s);
1343
 
          state_attach_puts ("\n", s);
1344
 
          show_sig_summary (sum, ctx, key, idx, s, sig);
1345
 
        }
 
1375
      {
 
1376
        print_smime_keyinfo (_("*BAD* signature from:"), sig, key, s);
 
1377
        show_sig_summary (sum, ctx, key, idx, s, sig);
 
1378
      }
1346
1379
      else if (!anybad && key && (key->protocol == GPGME_PROTOCOL_OpenPGP))
1347
 
        { /* We can't decide (yellow) but this is a PGP key with a good
1348
 
             signature, so we display what a PGP user expects: The name,
1349
 
             fingerprint and the key validity (which is neither fully or
1350
 
             ultimate). */
1351
 
          state_attach_puts (_("Good signature from: "), s);
1352
 
          state_attach_puts (uid, s);
1353
 
          state_attach_puts ("\n", s);
1354
 
          state_attach_puts (_("            created: "), s);
1355
 
          print_time (created, s);
1356
 
          state_attach_puts ("\n", s);
1357
 
          show_one_sig_validity (ctx, idx, s);
1358
 
          show_fingerprint (key,s);
1359
 
          if (show_sig_summary (sum, ctx, key, idx, s, sig))
1360
 
            anywarn = 1;
1361
 
        }
 
1380
      { /* We can't decide (yellow) but this is a PGP key with a good
 
1381
           signature, so we display what a PGP user expects: The name,
 
1382
           fingerprint and the key validity (which is neither fully or
 
1383
           ultimate). */
 
1384
        print_smime_keyinfo (_("Good signature from:"), sig, key, s);
 
1385
        show_one_sig_validity (ctx, idx, s);
 
1386
        show_fingerprint (key,s);
 
1387
        if (show_sig_summary (sum, ctx, key, idx, s, sig))
 
1388
          anywarn = 1;
 
1389
      }
1362
1390
      else /* can't decide (yellow) */
1363
 
        {
1364
 
          state_attach_puts (_("Error checking signature"), s);
1365
 
          state_attach_puts ("\n", s);
1366
 
          show_sig_summary (sum, ctx, key, idx, s, sig);
1367
 
        }
 
1391
      {
 
1392
        print_smime_keyinfo (_("Problem signature from:"), sig, key, s);
 
1393
        state_attach_puts (_("               expires: "), s);
 
1394
        print_time (sig->exp_timestamp, s);
 
1395
        state_attach_puts ("\n", s);
 
1396
        show_sig_summary (sum, ctx, key, idx, s, sig);
 
1397
        anywarn = 1;
 
1398
      }
1368
1399
 
1369
1400
      if (key != signature_key)
1370
1401
        gpgme_key_release (key);
1820
1851
  return *cur? 0:-1;
1821
1852
}
1822
1853
 
 
1854
static int pgp_gpgme_extract_keys (gpgme_data_t keydata, FILE** fp, int dryrun)
 
1855
{
 
1856
  /* there's no side-effect free way to view key data in GPGME,
 
1857
   * so we import the key into a temporary keyring */
 
1858
  char tmpdir[_POSIX_PATH_MAX];
 
1859
  char tmpfile[_POSIX_PATH_MAX];
 
1860
  gpgme_ctx_t tmpctx;
 
1861
  gpgme_error_t err;
 
1862
  gpgme_engine_info_t engineinfo;
 
1863
  gpgme_key_t key;
 
1864
  gpgme_user_id_t uid;
 
1865
  gpgme_subkey_t subkey;
 
1866
  const char* shortid;
 
1867
  int len;
 
1868
  char date[STRING];
 
1869
  int more;
 
1870
  int rc = -1;
 
1871
 
 
1872
  if ((err = gpgme_new (&tmpctx)) != GPG_ERR_NO_ERROR)
 
1873
  {
 
1874
    dprint (1, (debugfile, "Error creating GPGME context\n"));
 
1875
    return rc;
 
1876
  }
 
1877
  
 
1878
  if (dryrun)
 
1879
  {
 
1880
    snprintf (tmpdir, sizeof(tmpdir), "%s/mutt-gpgme-XXXXXX", Tempdir);
 
1881
    if (!mkdtemp (tmpdir))
 
1882
    {
 
1883
      dprint (1, (debugfile, "Error creating temporary GPGME home\n"));
 
1884
      goto err_ctx;
 
1885
    }
 
1886
 
 
1887
    engineinfo = gpgme_ctx_get_engine_info (tmpctx);
 
1888
    while (engineinfo && engineinfo->protocol != GPGME_PROTOCOL_OpenPGP)
 
1889
      engineinfo = engineinfo->next;
 
1890
    if (!engineinfo)
 
1891
    {
 
1892
      dprint (1, (debugfile, "Error finding GPGME PGP engine\n"));
 
1893
      goto err_tmpdir;
 
1894
    }
 
1895
 
 
1896
    err = gpgme_ctx_set_engine_info (tmpctx, GPGME_PROTOCOL_OpenPGP,
 
1897
                                     engineinfo->file_name, tmpdir);
 
1898
    if (err != GPG_ERR_NO_ERROR)
 
1899
    {
 
1900
      dprint (1, (debugfile, "Error setting GPGME context home\n"));
 
1901
      goto err_tmpdir;
 
1902
    }
 
1903
  }
 
1904
 
 
1905
  if ((err = gpgme_op_import (tmpctx, keydata)) != GPG_ERR_NO_ERROR)
 
1906
  {
 
1907
    dprint (1, (debugfile, "Error importing key\n"));
 
1908
    goto err_tmpdir;
 
1909
  }
 
1910
 
 
1911
  mutt_mktemp (tmpfile);
 
1912
  *fp = safe_fopen (tmpfile, "w+");
 
1913
  if (!*fp)
 
1914
  {
 
1915
    mutt_perror (tmpfile);
 
1916
    goto err_tmpdir;
 
1917
  }
 
1918
  unlink (tmpfile);
 
1919
 
 
1920
  err = gpgme_op_keylist_start (tmpctx, NULL, 0);
 
1921
  while (!err)
 
1922
  {
 
1923
    if ((err = gpgme_op_keylist_next (tmpctx, &key)))
 
1924
      break;
 
1925
    uid = key->uids;
 
1926
    subkey = key->subkeys;
 
1927
    more = 0;
 
1928
    while (subkey)
 
1929
    {
 
1930
      shortid = subkey->keyid;
 
1931
      len = mutt_strlen (subkey->keyid);
 
1932
      if (len > 8)
 
1933
        shortid += len - 8;
 
1934
      strftime (date, sizeof (date), "%Y-%m-%d", localtime (&subkey->timestamp));
 
1935
 
 
1936
      if (!more)
 
1937
        fprintf (*fp, "%s %5.5s %d/%8s %s %s\n", more ? "sub" : "pub",
 
1938
                 gpgme_pubkey_algo_name (subkey->pubkey_algo), subkey->length,
 
1939
                 shortid, date, uid->uid);
 
1940
      else
 
1941
        fprintf (*fp, "%s %5.5s %d/%8s %s\n", more ? "sub" : "pub",
 
1942
                 gpgme_pubkey_algo_name (subkey->pubkey_algo), subkey->length,
 
1943
                 shortid, date);      
 
1944
      subkey = subkey->next;
 
1945
      more = 1;
 
1946
    }
 
1947
    gpgme_key_release (key);
 
1948
  }
 
1949
  if (gpg_err_code (err) != GPG_ERR_EOF)
 
1950
  {
 
1951
    dprint (1, (debugfile, "Error listing keys\n"));
 
1952
    goto err_fp;
 
1953
  }
 
1954
 
 
1955
  rc = 0;
 
1956
 
 
1957
err_fp:
 
1958
  if (rc)
 
1959
  {
 
1960
    fclose (*fp);
 
1961
    *fp = NULL;
 
1962
  }
 
1963
err_tmpdir:
 
1964
  if (dryrun)
 
1965
    mutt_rmtree (tmpdir);
 
1966
err_ctx:
 
1967
  gpgme_release (tmpctx);
 
1968
 
 
1969
  return rc;
 
1970
}
1823
1971
 
1824
1972
/* 
1825
1973
 * Implementation of `pgp_check_traditional'.
1903
2051
  return rv;
1904
2052
}
1905
2053
 
 
2054
/* TODO: looks like this won't work and we'll have to fully parse the
 
2055
 * message file. GPGME makes life hard yet again. */
 
2056
void pgp_gpgme_invoke_import (const char *fname)
 
2057
{
 
2058
  gpgme_data_t keydata;
 
2059
  gpgme_error_t err;
 
2060
  FILE* in;
 
2061
  FILE* out;
 
2062
  long outlen;
 
2063
 
 
2064
  if (!(in = safe_fopen (fname, "r")))
 
2065
    return;
 
2066
  if ((err = gpgme_data_new_from_stream (&keydata, in)) != GPG_ERR_NO_ERROR)
 
2067
  {
 
2068
    dprint (1, (debugfile, "error converting key file into data object\n"));
 
2069
    return;
 
2070
  }
 
2071
  fclose (in);
 
2072
 
 
2073
  if (!pgp_gpgme_extract_keys (keydata, &out, 0))
 
2074
  {
 
2075
    /* display import results */
 
2076
    outlen = ftell (out);
 
2077
    fseek (out, 0, SEEK_SET);
 
2078
    mutt_copy_bytes (out, stdout, outlen);
 
2079
    fclose (out);
 
2080
  }
 
2081
  else
 
2082
    printf (_("Error extracting key data!\n"));
 
2083
}
 
2084
 
1906
2085
 
1907
2086
/* 
1908
2087
 * Implementation of `application_handler'.
2026
2205
              clearsign = 1;
2027
2206
              needpass = 0;
2028
2207
            }
2029
 
          else if (!option (OPTDONTHANDLEPGPKEYS) &&
2030
 
                   !mutt_strcmp ("PUBLIC KEY BLOCK-----\n", buf + 15))
2031
 
            {
2032
 
              needpass = 0;
2033
 
              pgp_keyblock =1;
2034
 
            } 
 
2208
          else if (!mutt_strcmp ("PUBLIC KEY BLOCK-----\n", buf + 15))
 
2209
          {
 
2210
            needpass = 0;
 
2211
            pgp_keyblock = 1;
 
2212
          } 
2035
2213
          else
2036
2214
            {
2037
2215
              /* XXX - we may wish to recode here */
2047
2225
          /* Copy PGP material to an data container */
2048
2226
          armored_data = file_to_data_object (s->fpin, m->offset, m->length);
2049
2227
          /* Invoke PGP if needed */
2050
 
          if (!clearsign || (s->flags & M_VERIFY))
 
2228
          if (pgp_keyblock)
 
2229
          {
 
2230
            pgp_gpgme_extract_keys (armored_data, &pgpout, 1);
 
2231
          }
 
2232
          else if (!clearsign || (s->flags & M_VERIFY))
2051
2233
            {
2052
2234
              unsigned int sig_stat = 0;
2053
2235
              gpgme_data_t plaintext;
2089
2271
                  char *tmpfname;
2090
2272
 
2091
2273
                  {
2092
 
                    /* Check wether signatures have been verified.  */
 
2274
                    /* Check whether signatures have been verified.  */
2093
2275
                    gpgme_verify_result_t verify_result;
2094
2276
 
2095
2277
                    verify_result = gpgme_op_verify_result (ctx);
2192
2374
              safe_fclose (&pgpout);
2193
2375
            }
2194
2376
        }
 
2377
#if 0
2195
2378
      else
2196
 
        {
2197
 
          /* XXX - we may wish to recode here */
2198
 
          if (s->prefix)
2199
 
            state_puts (s->prefix, s);
2200
 
          state_puts (buf, s);
2201
 
        }
 
2379
      {
 
2380
        /* why would we want to display this at all? */
 
2381
        /* XXX - we may wish to recode here */
 
2382
        if (s->prefix)
 
2383
          state_puts (s->prefix, s);
 
2384
        state_puts (buf, s);
 
2385
      }
 
2386
#endif
2202
2387
    }
2203
2388
 
2204
2389
  m->goodsig = (maybe_goodsig && have_any_sigs);
2207
2392
    {
2208
2393
      state_attach_puts (_("[-- Error: could not find beginning"
2209
2394
                           " of PGP message! --]\n\n"), s);
2210
 
      return -1;
 
2395
      return 1;
2211
2396
    }
2212
2397
  dprint (2, (debugfile, "Leaving pgp_application_pgp handler\n"));
2213
2398
 
3647
3832
  mutt_make_help (buf, sizeof (buf), _("Help"), menu_to_use, OP_HELP);
3648
3833
  strcat (helpstr, buf);        /* __STRCAT_CHECKED__ */
3649
3834
 
3650
 
  menu = mutt_new_menu ();
 
3835
  menu = mutt_new_menu (menu_to_use);
3651
3836
  menu->max = i;
3652
3837
  menu->make_entry = crypt_entry;
3653
 
  menu->menu = menu_to_use;
3654
3838
  menu->help = helpstr;
3655
3839
  menu->data = key_table;
3656
3840