static gpgme_key_t get_key_from_name(gpgme_ctx_t ctx, const gchar * name, gboolean secret, gboolean accept_all, GtkWindow * parent, GError ** error) { GList *keys = NULL; gpgme_key_t key; gpgme_error_t err; gboolean found_bad; time_t now = time(NULL); /* let gpgme list keys */ if ((err = gpgme_op_keylist_start(ctx, name, secret)) != GPG_ERR_NO_ERROR) { gchar *msg = g_strdup_printf(_("could not list keys for \"%s\""), name); g_set_error_from_gpgme(error, err, msg); g_free(msg); return NULL; } found_bad = FALSE; while ((err = gpgme_op_keylist_next(ctx, &key)) == GPG_ERR_NO_ERROR) { /* check if this key and the relevant subkey are usable */ if (KEY_IS_OK(key)) { gpgme_subkey_t subkey = key->subkeys; while (subkey && ((secret && !subkey->can_sign) || (!secret && !subkey->can_encrypt))) subkey = subkey->next; if (subkey && KEY_IS_OK(subkey) && (subkey->expires == 0 || subkey->expires > now)) keys = g_list_append(keys, key); else found_bad = TRUE; } else found_bad = TRUE; } if (gpg_err_code(err) != GPG_ERR_EOF) { gchar *msg = g_strdup_printf(_("could not list keys for \"%s\""), name); g_set_error_from_gpgme(error, err, msg); g_free(msg); gpgme_op_keylist_end(ctx); g_list_foreach(keys, (GFunc) gpgme_key_unref, NULL); g_list_free(keys); return NULL; } gpgme_op_keylist_end(ctx); if (!keys) { if (error) { if (strchr(name, '@')) { if (found_bad) g_set_error(error, GPGME_ERROR_QUARK, GPG_ERR_KEY_SELECTION, _ ("%s: a key for %s is present, but it is expired, disabled, revoked or invalid"), "gmime-gpgme", name); else g_set_error(error, GPGME_ERROR_QUARK, GPG_ERR_KEY_SELECTION, _("%s: could not find a key for %s"), "gmime-gpgme", name); } else { if (found_bad) g_set_error(error, GPGME_ERROR_QUARK, GPG_ERR_KEY_SELECTION, _ ("%s: a key with id %s is present, but it is expired, disabled, revoked or invalid"), "gmime-gpgme", name); else g_set_error(error, GPGME_ERROR_QUARK, GPG_ERR_KEY_SELECTION, _("%s: could not find a key with id %s"), "gmime-gpgme", name); } } return NULL; } /* let the user select a key from the list if there is more than one */ if (g_list_length(keys) > 1) { if (select_key_cb) key = select_key_cb(name, secret, keys, gpgme_get_protocol(ctx), parent); else { if (error) g_set_error(error, GPGME_ERROR_QUARK, GPG_ERR_KEY_SELECTION, _("%s: multiple keys for %s"), "gmime-gpgme", name); key = NULL; } if (key) gpgme_key_ref(key); g_list_foreach(keys, (GFunc) gpgme_key_unref, NULL); } else key = (gpgme_key_t) keys->data; g_list_free(keys); /* OpenPGP: ask the user if a low-validity key should be trusted for * encryption */ // FIXME - shouldn't we do the same for S/MIME? if (key && !secret && !accept_all && gpgme_get_protocol(ctx) == GPGME_PROTOCOL_OpenPGP) { gpgme_user_id_t uid = key->uids; gchar *upcase_name = g_ascii_strup(name, -1); gboolean found = FALSE; while (!found && uid) { /* check the email field which may or may not be present */ if (uid->email && !g_ascii_strcasecmp(uid->email, name)) found = TRUE; else { /* no email or no match, check the uid */ gchar *upcase_uid = g_ascii_strup(uid->uid, -1); if (strstr(upcase_uid, upcase_name)) found = TRUE; else uid = uid->next; g_free(upcase_uid); } } g_free(upcase_name); /* ask the user if a low-validity key shall be used */ if (uid && uid->validity < GPGME_VALIDITY_FULL) { if (!accept_low_trust_cb || !accept_low_trust_cb(name, uid, parent)) { gpgme_key_unref(key); key = NULL; if (error) g_set_error(error, GPGME_ERROR_QUARK, GPG_ERR_KEY_SELECTION, _("%s: insufficient validity for uid %s"), "gmime-gpgme", name); } } } return key; }
static gpgme_key_t pkcs7_get_key_by_name (Pkcs7Ctx *pkcs7, const char *name, gboolean secret, GError **err) { time_t now = time (NULL); gpgme_key_t key = NULL; gpgme_subkey_t subkey; gboolean bad = FALSE; gpgme_error_t error; int errval = 0; if ((error = gpgme_op_keylist_start (pkcs7->ctx, name, secret)) != GPG_ERR_NO_ERROR) { if (secret) g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not list secret keys for \"%s\""), name); else g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not list keys for \"%s\""), name); return NULL; } while ((error = gpgme_op_keylist_next (pkcs7->ctx, &key)) == GPG_ERR_NO_ERROR) { /* check if this key and the relevant subkey are usable */ if (KEY_IS_OK (key)) { subkey = key->subkeys; while (subkey && ((secret && !subkey->can_sign) || (!secret && !subkey->can_encrypt))) subkey = subkey->next; if (subkey && KEY_IS_OK (subkey) && (subkey->expires == 0 || subkey->expires > now)) break; if (subkey->expired) errval = GPG_ERR_KEY_EXPIRED; else errval = GPG_ERR_BAD_KEY; } else { if (key->expired) errval = GPG_ERR_KEY_EXPIRED; else errval = GPG_ERR_BAD_KEY; } gpgme_key_unref (key); bad = TRUE; key = NULL; } gpgme_op_keylist_end (pkcs7->ctx); if (error != GPG_ERR_NO_ERROR && error != GPG_ERR_EOF) { if (secret) g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not list secret keys for \"%s\""), name); else g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not list keys for \"%s\""), name); return NULL; } if (!key) { if (strchr (name, '@')) { if (bad) g_set_error (err, GMIME_GPGME_ERROR, errval, _("A key for %s is present, but it is expired, disabled, revoked or invalid"), name); else g_set_error (err, GMIME_GPGME_ERROR, GPG_ERR_NOT_FOUND, _("Could not find a key for %s"), name); } else { if (bad) g_set_error (err, GMIME_GPGME_ERROR, errval, _("A key with id %s is present, but it is expired, disabled, revoked or invalid"), name); else g_set_error (err, GMIME_GPGME_ERROR, GPG_ERR_NOT_FOUND, _("Could not find a key with id %s"), name); } return NULL; } return key; }