From f6a91145b60ce924daaee6b2d5b9449c6170d9f9 Mon Sep 17 00:00:00 2001 From: James Booth Date: Tue, 25 Aug 2015 00:21:49 +0100 Subject: Show public/private indicator when listing PGP keys --- src/pgp/gpg.c | 102 ++++++++++++++++++++++++++++++++++++++++++++-------------- src/pgp/gpg.h | 9 ++++-- 2 files changed, 85 insertions(+), 26 deletions(-) (limited to 'src/pgp') diff --git a/src/pgp/gpg.c b/src/pgp/gpg.c index 6edab8d1..9d594be4 100644 --- a/src/pgp/gpg.c +++ b/src/pgp/gpg.c @@ -215,11 +215,38 @@ p_gpg_addkey(const char * const jid, const char * const keyid) return TRUE; } -GSList * +static ProfPGPKey * +_p_gpg_key_new(void) +{ + ProfPGPKey *p_pgpkey = malloc(sizeof(ProfPGPKey)); + p_pgpkey->id = NULL; + p_pgpkey->name = NULL; + p_pgpkey->fp = NULL; + p_pgpkey->encrypt = FALSE; + p_pgpkey->sign = FALSE; + p_pgpkey->certify = FALSE; + p_pgpkey->authenticate = FALSE; + p_pgpkey->secret = FALSE; + + return p_pgpkey; +} + +static void +_p_gpg_free_key(ProfPGPKey *key) +{ + if (key) { + free(key->id); + free(key->name); + free(key->fp); + free(key); + } +} + +GHashTable * p_gpg_list_keys(void) { gpgme_error_t error; - GSList *result = NULL; + GHashTable *result = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)_p_gpg_free_key); gpgme_ctx_t ctx; error = gpgme_new(&ctx); @@ -231,25 +258,56 @@ p_gpg_list_keys(void) error = gpgme_op_keylist_start(ctx, NULL, 0); if (error == GPG_ERR_NO_ERROR) { + gpgme_key_t key; + error = gpgme_op_keylist_next(ctx, &key); while (!error) { - gpgme_key_t key; - error = gpgme_op_keylist_next(ctx, &key); + gpgme_subkey_t sub = key->subkeys; - if (error) { - break; + ProfPGPKey *p_pgpkey = _p_gpg_key_new(); + p_pgpkey->id = strdup(sub->keyid); + p_pgpkey->name = strdup(key->uids->uid); + p_pgpkey->fp = strdup(sub->fpr); + if (sub->can_encrypt) p_pgpkey->encrypt = TRUE; + if (sub->can_authenticate) p_pgpkey->authenticate = TRUE; + if (sub->can_certify) p_pgpkey->certify = TRUE; + if (sub->can_sign) p_pgpkey->sign = TRUE; + + sub = sub->next; + while (sub) { + if (sub->can_encrypt) p_pgpkey->encrypt = TRUE; + if (sub->can_authenticate) p_pgpkey->authenticate = TRUE; + if (sub->can_certify) p_pgpkey->certify = TRUE; + if (sub->can_sign) p_pgpkey->sign = TRUE; + + sub = sub->next; } - ProfPGPKey *p_pgpkey = malloc(sizeof(ProfPGPKey)); - p_pgpkey->id = strdup(key->subkeys->keyid); - p_pgpkey->name = strdup(key->uids->uid); - p_pgpkey->fp = strdup(key->subkeys->fpr); + g_hash_table_insert(result, strdup(p_pgpkey->name), p_pgpkey); - result = g_slist_append(result, p_pgpkey); + gpgme_key_unref(key); + error = gpgme_op_keylist_next(ctx, &key); + } + } + + error = gpgme_op_keylist_start(ctx, NULL, 1); + if (error == GPG_ERR_NO_ERROR) { + gpgme_key_t key; + error = gpgme_op_keylist_next(ctx, &key); + while (!error) { + gpgme_subkey_t sub = key->subkeys; + while (sub) { + if (sub->secret) { + ProfPGPKey *p_pgpkey = g_hash_table_lookup(result, key->uids->uid); + if (p_pgpkey) { + p_pgpkey->secret = TRUE; + } + } + sub = sub->next; + } gpgme_key_unref(key); + error = gpgme_op_keylist_next(ctx, &key); } - } else { - log_error("GPG: Could not list keys. %s %s", gpgme_strsource(error), gpgme_strerror(error)); } gpgme_release(ctx); @@ -257,6 +315,13 @@ p_gpg_list_keys(void) return result; } +void +p_gpg_free_keys(GHashTable *keys) +{ + g_hash_table_destroy(keys); +} + + GHashTable * p_gpg_fingerprints(void) { @@ -269,17 +334,6 @@ p_gpg_libver(void) return libversion; } -void -p_gpg_free_key(ProfPGPKey *key) -{ - if (key) { - free(key->id); - free(key->name); - free(key->fp); - free(key); - } -} - gboolean p_gpg_valid_key(const char * const keyid) { diff --git a/src/pgp/gpg.h b/src/pgp/gpg.h index 3bdae37e..f4c3f4a2 100644 --- a/src/pgp/gpg.h +++ b/src/pgp/gpg.h @@ -39,19 +39,24 @@ typedef struct pgp_key_t { char *id; char *name; char *fp; + gboolean encrypt; + gboolean sign; + gboolean certify; + gboolean authenticate; + gboolean secret; } ProfPGPKey; void p_gpg_init(void); void p_gpg_close(void); void p_gpg_on_connect(const char * const barejid); void p_gpg_on_disconnect(void); -GSList* p_gpg_list_keys(void); +GHashTable* p_gpg_list_keys(void); +void p_gpg_free_keys(GHashTable *keys); gboolean p_gpg_addkey(const char * const jid, const char * const keyid); GHashTable* p_gpg_fingerprints(void); gboolean p_gpg_valid_key(const char * const keyid); gboolean p_gpg_available(const char * const barejid); const char* p_gpg_libver(void); -void p_gpg_free_key(ProfPGPKey *key); char* p_gpg_sign(const char * const str, const char * const fp); void p_gpg_verify(const char * const barejid, const char *const sign); char* p_gpg_encrypt(const char * const barejid, const char * const message); -- cgit 1.4.1-2-gfad0