Пример #1
0
/* Return a GPGME key object matching PATTERN.  If no key matches or
   the match is ambiguous, return NULL. */
gpgme_key_t 
op_get_one_key (char *pattern)
{
  gpgme_error_t err;
  gpgme_ctx_t ctx;
  gpgme_key_t k, k2;

  err = gpgme_new (&ctx);
  if (err)
    return NULL; /* Error. */
  err = gpgme_op_keylist_start (ctx, pattern, 0);
  if (!err)
    {
      err = gpgme_op_keylist_next (ctx, &k);
      if (!err && !gpgme_op_keylist_next (ctx, &k2))
        {
          /* More than one matching key available.  Return an error
             instead. */
          gpgme_key_release (k);
          gpgme_key_release (k2);
          k = k2 = NULL;
        }
    }
  gpgme_op_keylist_end (ctx);
  gpgme_release (ctx);
  return k;
}
Пример #2
0
static void
cleanup (FILE *f1, GFile *f2, GFileOutputStream *ostream, gchar *buf, gpgme_key_t *sk, gpgme_ctx_t *ctx)
{
    if (f1 != NULL) {
        fclose (f1);
    }

    if (f2 != NULL) {
        g_object_unref (f2);
    }

    if (ostream != NULL) {
        g_output_stream_close (G_OUTPUT_STREAM (ostream), NULL, NULL);
        g_object_unref (ostream);
    }

    if (buf != NULL) {
        g_free (buf);
    }

    if (sk != NULL) {
        gpgme_key_release (*sk);
    }

    if (ctx != NULL) {
        gpgme_release (*ctx);
    }

}
Пример #3
0
GSList *
get_available_keys ()
{
    init_gpgme ();

    gpgme_ctx_t ctx;
    gpgme_key_t key;

    gpgme_error_t  err = gpgme_new (&ctx);
    if (err) {
        g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (err), gpgme_strerror (err));
        return GPGME_ERROR;
    }

    err = gpgme_op_keylist_start (ctx, NULL, 1);
    if (err) {
        g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (err), gpgme_strerror (err));
        gpgme_release (ctx);
        return GPGME_ERROR;
    }

    GSList *list = NULL;
    KeyInfo *key_info;

    while (1) {
        err = gpgme_op_keylist_next (ctx, &key);
        if (err) {
            break;
        }
        key_info = g_new0 (KeyInfo, 1);
        key_info->key_id = g_strdup (key->subkeys->keyid);
        if (key->uids && key->uids->name) {
            key_info->name = g_strdup (key->uids->name);
        } else {
            key_info->name = g_strdup ("none");
        }
        if (key->uids && key->uids->email) {
            key_info->email = g_strdup (key->uids->email);
        } else {
            key_info->email = g_strdup ("none");
        }
        key_info->key_fpr = g_strdup (key->subkeys->fpr);

        gssize bytes_to_copy = sizeof (KeyInfo) + g_utf8_strlen (key_info->name, -1) + g_utf8_strlen (key_info->email, -1) +
                g_utf8_strlen (key_info->key_id, -1) + g_utf8_strlen (key_info->key_fpr, -1) + 4;

        list = g_slist_append (list, g_memdup (key_info, bytes_to_copy));

        g_free (key_info);

        gpgme_key_release (key);
    }

    gpgme_release (ctx);

    return list;
}
Пример #4
0
/* Release an array of GPGME keys. */
static void 
release_key_array (gpgme_key_t *keys)
{
  int i;

  if (keys)
    {
      for (i = 0; keys[i]; i++) 
	gpgme_key_release (keys[i]);
      xfree (keys);
    }
}
Пример #5
0
/* ------------------
 * preferences dialog function
 * ------------------ */
static PurplePluginPrefFrame *
get_plugin_pref_frame(PurplePlugin *plugin) {
	PurplePluginPrefFrame *frame;
	PurplePluginPref *ppref;
	gpgme_error_t error;
	gpgme_ctx_t ctx;
	gpgme_key_t key;

	// create preferences frame
	frame = purple_plugin_pref_frame_new();
	
	// connect to gpgme
	gpgme_check_version (NULL);
	error = gpgme_new(&ctx);
	if (error)
	{
		purple_debug_error(PLUGIN_ID,"gpgme_new failed: %s %s\n",gpgme_strsource (error), gpgme_strerror (error));
		return NULL;
	}

	// create key chooser preference
	ppref = purple_plugin_pref_new_with_name_and_label(PREF_MY_KEY,"My key");
	purple_plugin_pref_set_type(ppref, PURPLE_PLUGIN_PREF_CHOICE);
	purple_plugin_pref_add_choice(ppref, "None", "");

	// list keys (secret keys)
	error = gpgme_op_keylist_start (ctx,NULL,1);
	if (error == GPG_ERR_NO_ERROR)
	{
		while (!error)
		{
			error = gpgme_op_keylist_next (ctx, &key);
			if (error) break;
			// add key to preference chooser
			//TODO: find something better for g_strdup, or some possibility to free memory after preferences dialog closed
			purple_plugin_pref_add_choice(ppref, g_strdup(key->uids->uid), g_strdup(key->subkeys->fpr));
			purple_debug_info(PLUGIN_ID,"Found secret key for: %s has fpr %s\n",key->uids->uid,key->subkeys->fpr);
			gpgme_key_release (key);
		}
	}else
	{
		purple_debug_error(PLUGIN_ID,"gpgme_op_keylist_start failed: %s %s\n",gpgme_strsource (error), gpgme_strerror (error));
	}
	// close gpgme connection
	gpgme_release (ctx);

	purple_plugin_pref_frame_add(frame, ppref);

	return frame;
}
Пример #6
0
int main(void)
{
   gpgme_ctx_t ctx;
   gpgme_error_t err;

   int setup_res = setup(&ctx);
   if(setup_res) return setup_res;

   /* Change mode to list sigs and */
   gpgme_keylist_mode_t mode = gpgme_get_keylist_mode(ctx);
   mode |= GPGME_KEYLIST_MODE_SIGS | GPGME_KEYLIST_MODE_SIG_NOTATIONS;
   err = gpgme_set_keylist_mode(ctx, mode);
   if (err != GPG_ERR_NO_ERROR) return 6;

   /* List all keys */
   /* (context, pattern, secret_only) */
   err = gpgme_op_keylist_start(ctx, NULL, 0);
   if (err != GPG_ERR_NO_ERROR) return 7;

   gpgme_key_t key;
   while ((err = gpgme_op_keylist_next(ctx, &key)) == GPG_ERR_NO_ERROR) {
      printf("Got a key\n");
      printf ("%s:", key->subkeys->keyid);
      if (key->uids && key->uids->name)
        printf (" %s", key->uids->name);
      if (key->uids && key->uids->email)
        printf (" <%s>", key->uids->email);
      if (key->uids && key->uids->signatures) {
        printf("First signature: %s\n", key->uids->signatures->keyid);
      }
      putchar ('\n');
      gpgme_key_release (key);
   }
   if (gpg_err_code(err) == GPG_ERR_EOF) {
      printf("%xu\n", err);
      printf("End of keylist.\n");
   } else {
      print_gpg_error(err);
      return 8;
   }

   /* free context */
   gpgme_release(ctx);

   return 0;
}
Пример #7
0
int get_next_key(char *buf, int buf_size) {
    gpgme_key_t key;
    int tmp_size = buf_size - 1;

    _cf_err = gpgme_op_keylist_next (_cf_ctx, &key);

    if(!_cf_err) {
        strcpy(buf,"");

        /* copy fingerprint and add ":" at the end */
        strncat(buf, key->subkeys->fpr, tmp_size);
        tmp_size -= strlen(key->subkeys->fpr) - 1; /* subtract 1 for the ":" character */
        strncat(buf, ":", tmp_size);

        /* Try to copy name */
        if (key->uids && key->uids->name) {
            strncat(buf, key->uids->name, tmp_size);
            tmp_size -= strlen(key->uids->name);
        }

        /* Try to copy email */
        if (key->uids && key->uids->email) {
            strncat(buf, " <", tmp_size);
            tmp_size -= 2;
            strncat(buf, key->uids->email, tmp_size);
            tmp_size -= strlen(key->uids->email);
            strncat(buf, ">", tmp_size);
            tmp_size -= 1;
        }

        gpgme_key_release (key);
        return 1;
    } else {
        gpgme_release(_cf_ctx);
        return 0;
    }
}
Пример #8
0
static void
destroy_key (gpointer data)
{
    gpgme_key_t key = data;
    gpgme_key_release (key);
}
Пример #9
0
gboolean sgpgme_setup_signers(gpgme_ctx_t ctx, PrefsAccount *account,
			      const gchar *from_addr)
{
	GPGAccountConfig *config;
	const gchar *signer_addr = account->address;

	gpgme_signers_clear(ctx);

	if (from_addr)
		signer_addr = from_addr;
	config = prefs_gpg_account_get_config(account);

	switch(config->sign_key) {
	case SIGN_KEY_DEFAULT:
		debug_print("using default gnupg key\n");
		break;
	case SIGN_KEY_BY_FROM:
		debug_print("using key for %s\n", signer_addr);
		break;
	case SIGN_KEY_CUSTOM:
		debug_print("using key for %s\n", config->sign_key_id);
		break;
	}

	if (config->sign_key != SIGN_KEY_DEFAULT) {
		const gchar *keyid;
		gpgme_key_t key, found_key;
		gpgme_error_t err;

		if (config->sign_key == SIGN_KEY_BY_FROM)
			keyid = signer_addr;
		else if (config->sign_key == SIGN_KEY_CUSTOM)
			keyid = config->sign_key_id;
		else
			goto bail;

                found_key = NULL;
		/* Look for any key, not just private ones, or GPGMe doesn't
		 * correctly set the revoked flag. */
		err = gpgme_op_keylist_start(ctx, keyid, 0);
		while ((err = gpgme_op_keylist_next(ctx, &key)) == 0) {
			if (key == NULL)
				continue;

			if (!key->can_sign)
				continue;

			if (key->protocol != gpgme_get_protocol(ctx)) {
				debug_print("skipping a key (wrong protocol %d)\n", key->protocol);
				gpgme_key_release(key);
				continue;
			}

			if (key->expired) {
				debug_print("skipping a key, expired");
				gpgme_key_release(key);
				continue;
			}
			if (key->revoked) {
				debug_print("skipping a key, revoked");
				gpgme_key_release(key);
				continue;
			}
			if (key->disabled) {
				debug_print("skipping a key, disabled");
				gpgme_key_release(key);
				continue;
			}

			if (found_key != NULL) {
				gpgme_key_release(key);
				gpgme_op_keylist_end(ctx);
				g_warning("ambiguous specification of secret key '%s'\n", keyid);
				privacy_set_error(_("Secret key specification is ambiguous"));
				goto bail;
			}

			found_key = key;
                }
		gpgme_op_keylist_end(ctx);

		if (found_key == NULL) {
			g_warning("setup_signers start: %s", gpgme_strerror(err));
			privacy_set_error(_("Secret key not found (%s)"), gpgme_strerror(err));
			goto bail;
                }

		err = gpgme_signers_add(ctx, found_key);
		debug_print("got key (proto %d (pgp %d, smime %d).\n",
			    found_key->protocol, GPGME_PROTOCOL_OpenPGP,
			    GPGME_PROTOCOL_CMS);
		gpgme_key_release(found_key);

		if (err) {
			g_warning("error adding secret key: %s\n",
				  gpgme_strerror(err));
			privacy_set_error(_("Error setting secret key: %s"),
					  gpgme_strerror(err));
			goto bail;
		}
        }

	prefs_gpg_account_free_config(config);

	return TRUE;
bail:
	prefs_gpg_account_free_config(config);
	return FALSE;
}
Пример #10
0
gboolean sgpgme_setup_signers(gpgme_ctx_t ctx, PrefsAccount *account,
			      const gchar *from_addr)
{
	GPGAccountConfig *config;
	const gchar *signer_addr = account->address;

	gpgme_signers_clear(ctx);

	if (from_addr)
		signer_addr = from_addr;
	config = prefs_gpg_account_get_config(account);

	switch(config->sign_key) {
	case SIGN_KEY_DEFAULT:
		debug_print("using default gnupg key\n");
		break;
	case SIGN_KEY_BY_FROM:
		debug_print("using key for %s\n", signer_addr);
		break;
	case SIGN_KEY_CUSTOM:
		debug_print("using key for %s\n", config->sign_key_id);
		break;
	}

	if (config->sign_key != SIGN_KEY_DEFAULT) {
		const gchar *keyid;
		gpgme_key_t key, key2;
		gpgme_error_t err;

		if (config->sign_key == SIGN_KEY_BY_FROM)
			keyid = signer_addr;
		else if (config->sign_key == SIGN_KEY_CUSTOM)
			keyid = config->sign_key_id;
		else
			goto bail;

		err = gpgme_op_keylist_start(ctx, keyid, 1);
		if (!err) {
			do {
				err = gpgme_op_keylist_next(ctx, &key);
				if (!err && key && key->protocol == gpgme_get_protocol(ctx) &&
				    !key->expired && !key->revoked && !key->disabled)
					break;
				if (!err && key && key->protocol != gpgme_get_protocol(ctx)) {
					debug_print("skipping a key (wrong protocol %d)\n", key->protocol);
					gpgme_key_release(key);
				}
				if (!err && key && (key->expired || key->revoked || key->disabled)) {
					
					debug_print("skipping a key");
					if (key->expired) 
						debug_print(" expired");
					if (key->revoked) 
						debug_print(" revoked");
					if (key->disabled) 
						debug_print(" disabled");
					debug_print("\n");
					gpgme_key_release(key);
				}
			} while (!err);
		}
		if (err) {
			g_warning("setup_signers start: %s", gpgme_strerror(err));
			privacy_set_error(_("Secret key not found (%s)"), gpgme_strerror(err));
			goto bail;
		}
		
		do {
			err = gpgme_op_keylist_next(ctx, &key2);
			if (!err && key2 && key2->protocol == gpgme_get_protocol(ctx) &&
			    !key2->expired && !key2->revoked && !key2->disabled)
				break;
			if (!err && key2 && key2->protocol != gpgme_get_protocol(ctx)) {
				debug_print("skipping a key (wrong protocol %d)\n", key2->protocol);
				gpgme_key_release(key2);
			}
			if (!err && key2 && (key2->expired || key2->revoked || key2->disabled)) {
					debug_print("skipping a key");
					if (key2->expired) 
						debug_print(" expired");
					if (key2->revoked) 
						debug_print(" revoked");
					if (key2->disabled) 
						debug_print(" disabled");
					debug_print("\n");
				gpgme_key_release(key2);
			}
		} while (!err);
		if (!err) {
			gpgme_key_release(key2);
			g_warning("ambiguous specification of secret key '%s'\n",
				keyid);
			privacy_set_error(_("Secret key specification is ambiguous"));
			goto bail;
		}
		
		gpgme_op_keylist_end(ctx);
		err = gpgme_signers_add(ctx, key);
		debug_print("got key (proto %d (pgp %d, smime %d).\n", key->protocol,
				GPGME_PROTOCOL_OpenPGP, GPGME_PROTOCOL_CMS);
		gpgme_key_release(key);
		
		if (err) {
			g_warning("error adding secret key: %s\n", gpgme_strerror(err));
			privacy_set_error(_("Error setting secret key: %s"), gpgme_strerror(err));
			goto bail;
		}
	}

	prefs_gpg_account_free_config(config);

	return TRUE;
bail:
	prefs_gpg_account_free_config(config);
	return FALSE;
}
Пример #11
0
/* Print a text with the attestation of the signature verification
   (which is in RES) to A.  FILENAME may also be used in the
   attestation. */
static void
add_verify_attestation (gpgme_data_t a, gpgme_ctx_t ctx,
                        gpgme_verify_result_t res, const char *filename)
{
  time_t created;
  const char *fpr, *uid;
  gpgme_key_t key = NULL;
  int i, anybad = 0, anywarn = 0;
  unsigned int sum;
  gpgme_user_id_t uids = NULL;
  gpgme_signature_t sig;
  gpgme_error_t err;

  if (!gpgme_data_seek (a, 0, SEEK_CUR))
    {
      /* Nothing yet written to the stream.  Insert the current time. */
      at_puts (a, _("Verification started at: "));
      at_print_time (a, time (NULL));
      at_puts (a, "\n\n");
    }

  at_puts (a, _("Verification result for: "));
  at_puts (a, filename ? filename : _("[unnamed part]"));
  at_puts (a, "\n");
  if (res)
    {
      for (sig = res->signatures; sig; sig = sig->next)
        {
          created = sig->timestamp;
          fpr = sig->fpr;
          sum = sig->summary;

          if (gpg_err_code (sig->status) != GPG_ERR_NO_ERROR)
            anybad = 1;

          err = gpgme_get_key (ctx, fpr, &key, 0);
          uid = !err && key->uids && key->uids->uid ? key->uids->uid : "[?]";

          if ((sum & GPGME_SIGSUM_GREEN))
            {
              at_puts (a, _("Good signature from: "));
              at_puts (a, uid);
              at_puts (a, "\n");
              for (i = 1, uids = key->uids; uids; i++, uids = uids->next)
                {
                  if (uids->revoked)
                    continue;
                  at_puts (a, _("                aka: "));
                  at_puts (a, uids->uid);
                  at_puts (a, "\n");
                }
              at_puts (a, _("            created: "));
              at_print_time (a, created);
              at_puts (a, "\n");
              if (at_sig_summary (a, sum, sig, key))
                anywarn = 1;
              at_sig_validity (a, sig);
            }
          else if ((sum & GPGME_SIGSUM_RED))
            {
              at_puts (a, _("*BAD* signature claimed to be from: "));
              at_puts (a, uid);
              at_puts (a, "\n");
              at_sig_summary (a, sum, sig, key);
            }
          else if (!anybad && key && (key->protocol == GPGME_PROTOCOL_OpenPGP))
            { /* We can't decide (yellow) but this is a PGP key with a
                 good signature, so we display what a PGP user
                 expects: The name, fingerprint and the key validity
                 (which is neither fully or ultimate). */
              at_puts (a, _("Good signature from: "));
              at_puts (a, uid);
              at_puts (a, "\n");
              at_puts (a, _("            created: "));
              at_print_time (a, created);
              at_puts (a, "\n");
              at_sig_validity (a, sig);
              at_fingerprint (a, key);
              if (at_sig_summary (a, sum, sig, key))
                anywarn = 1;
            }
          else /* can't decide (yellow) */
            {
              at_puts (a, _("Error checking signature"));
              at_puts (a, "\n");
              at_sig_summary (a, sum, sig, key);
            }
          
          gpgme_key_release (key);
        }

      if (!anybad )
        {
          gpgme_sig_notation_t notation;
          
          for (sig = res->signatures; sig; sig = sig->next)
            {
              if (!sig->notations)
                continue;
              at_puts (a, _("*** Begin Notation (signature by: "));
              at_puts (a, sig->fpr);
              at_puts (a, ") ***\n");
              for (notation = sig->notations; notation;
                   notation = notation->next)
                {
                  if (notation->name)
                    {
                      at_puts (a, notation->name);
                      at_puts (a, "=");
                    }
                  if (notation->value)
                    {
                      at_puts (a, notation->value);
                      if (!(*notation->value
                            && (notation->value[strlen (notation->value)-1]
                                =='\n')))
                        at_puts (a, "\n");
                    }
                }
              at_puts (a, _("*** End Notation ***\n"));
            }
	}
    }
  at_puts (a, "\n");
}
Пример #12
0
/* Try to find a key for each item in array NAMES. Items not found are
   stored as malloced strings in the newly allocated array UNKNOWN.
   Found keys are stored in the newly allocated array KEYS.  Both
   arrays are terminated by a NULL entry.  Caller needs to release
   KEYS and UNKNOWN.

   Returns: 0 on success. However success may also be that one or all
   keys are unknown.
*/
int 
op_lookup_keys (char **names, gpgme_key_t **keys, char ***unknown)
{
  gpgme_error_t err;
  gpgme_ctx_t ctx;
  size_t n;
  int i, kpos, upos;
  gpgme_key_t k, k2;

  *keys = NULL;
  *unknown = NULL;

  err = gpgme_new (&ctx);
  if (err)
    return -1; /* Error. */

  for (n=0; names[n]; n++)
    ;

  *keys =  xcalloc (n+1, sizeof *keys);
  *unknown = xcalloc (n+1, sizeof *unknown);

  for (i=kpos=upos=0; names[i]; i++)
    {
      k = NULL;
      err = gpgme_op_keylist_start (ctx, names[i], 0);
      if (!err)
        {
          err = gpgme_op_keylist_next (ctx, &k);
          if (!err && !gpgme_op_keylist_next (ctx, &k2))
            {
              /* More than one matching key available.  Take this one
                 as unknown. */
              gpgme_key_release (k);
              gpgme_key_release (k2);
              k = k2 = NULL;
            }
        }
      gpgme_op_keylist_end (ctx);

      
      /* only useable keys will be added otherwise they will be stored
         in unknown (marked with their status). */
      if (k && !k->revoked && !k->disabled && !k->expired)
        (*keys)[kpos++] = k;
      else if (k)
	{
	  char *p, *fmt = "%s (%s)";
	  char *warn = k->revoked? "revoked" : k->expired? "expired" : "disabled";
	  
	  p = xcalloc (1, strlen (names[i]) + strlen (warn) + strlen (fmt) +1);
	  sprintf (p, fmt, names[i], warn);
	  (*unknown)[upos++] = p;
	  gpgme_key_release (k);
	}
      else if (!k)
        (*unknown)[upos++] = xstrdup (names[i]);
    }

  gpgme_release (ctx);
  return 0;
}
Пример #13
0
int main(void)
{
   gpgme_ctx_t ctx;
   gpgme_error_t err;

   int setup_res = setup(&ctx);
   if(setup_res) return setup_res;

   /* Change mode to extern */
   gpgme_keylist_mode_t mode = gpgme_get_keylist_mode(ctx);
   mode &= ~GPGME_KEYLIST_MODE_LOCAL;
   mode |= GPGME_KEYLIST_MODE_EXTERN;
   mode |= GPGME_KEYLIST_MODE_SIGS | GPGME_KEYLIST_MODE_SIG_NOTATIONS;
   err = gpgme_set_keylist_mode(ctx, mode);
   if (err != GPG_ERR_NO_ERROR) return 6;

   /* List all keys */
   /* (context, pattern, secret_only) */
   err = gpgme_op_keylist_start(ctx, "07E7871B", 0);
   if (err != GPG_ERR_NO_ERROR) return 7;

   gpgme_key_t key;
   size_t MAX_KEYS = 100;
   gpgme_key_t keyarray[MAX_KEYS+1]; // need a space for the NULL term
   size_t i = 0;

   while ((err = gpgme_op_keylist_next(ctx, &key)) == GPG_ERR_NO_ERROR) {
      printf("Got a key\n");
      printf ("%s:", key->subkeys->keyid);
      if (key->uids && key->uids->name)
        printf (" %s", key->uids->name);
      if (key->uids && key->uids->email)
        printf (" <%s>", key->uids->email);
      if (key->uids && key->uids->signatures) {
        printf("First signature: %s\n", key->uids->signatures->keyid);
      }
      putchar ('\n');
      if (i < MAX_KEYS) {
        keyarray[i++] = key;
      } else {
        printf("Too many keys, skipping a key\n");
      }
      //gpgme_key_release (key);
   }
   if (gpg_err_code(err) == GPG_ERR_EOF) {
      printf("%xu\n", err);
      printf("End of keylist.\n");
   } else {
      print_gpg_error(err);
      return 8;
   }

   // https://bugs.gnupg.org/gnupg/issue1670

   printf("Attempting to import %lu keys\n", i);
   err = gpgme_op_import_keys(ctx, keyarray);
   if (err != GPG_ERR_NO_ERROR) return 9;
   gpgme_import_result_t impres = gpgme_op_import_result(ctx);
   if (!impres) return 10;
   print_import_result(impres);

   /* free keys */
   for (i = 0; keyarray[i]; i++)
     gpgme_key_release(key);

   /* free context */
   gpgme_release(ctx);

   return 0;
}