diff options
author | defanor <defanor@uberspace.net> | 2021-02-07 22:13:35 +0300 |
---|---|---|
committer | defanor <defanor@uberspace.net> | 2021-02-07 22:13:35 +0300 |
commit | 81a85c55ef1159ac4baee59dddcd33a47099e678 (patch) | |
tree | d352af4691c8c61be3a7e545e0109b0486f216a7 | |
parent | bfc932724364aa776d11395f77090764f5148042 (diff) |
Add rexmpp_openpgp_set_signers function
Now there are can_sign/can_encrypt checks, and this should be more
suitable for future sign-only and encrypt-only functions.
-rw-r--r-- | src/rexmpp_openpgp.c | 54 |
1 files changed, 37 insertions, 17 deletions
diff --git a/src/rexmpp_openpgp.c b/src/rexmpp_openpgp.c index cb8b4d7..d4a1332 100644 --- a/src/rexmpp_openpgp.c +++ b/src/rexmpp_openpgp.c @@ -650,10 +650,14 @@ void rexmpp_openpgp_add_keys (rexmpp_t *s, } err = gpgme_get_key(s->pgp_ctx, fingerprint, &(*keys)[*nkeys], 0); if (gpg_err_code(err) == GPG_ERR_NO_ERROR) { - *nkeys = *nkeys + 1; - if (*nkeys == *allocated) { - *allocated = *allocated * 2; - *keys = realloc(*keys, sizeof(gpgme_key_t *) * *allocated); + if ((*keys)[*nkeys]->can_encrypt) { + *nkeys = *nkeys + 1; + if (*nkeys == *allocated) { + *allocated = *allocated * 2; + *keys = realloc(*keys, sizeof(gpgme_key_t *) * *allocated); + } + } else { + gpgme_key_unref((*keys)[*nkeys]); } (*keys)[*nkeys] = NULL; } else if (gpg_err_code(err) == GPG_ERR_EOF) { @@ -667,6 +671,33 @@ void rexmpp_openpgp_add_keys (rexmpp_t *s, } } +void rexmpp_openpgp_set_signers (rexmpp_t *s) { + gpgme_error_t err; + xmlNodePtr metadata; + gpgme_key_t sec_key; + gpgme_signers_clear(s->pgp_ctx); + for (metadata = rexmpp_published_fingerprints(s, s->initial_jid.bare); + metadata != NULL; + metadata = xmlNextElementSibling(metadata)) { + char *fingerprint = xmlGetProp(metadata, "v4-fingerprint"); + if (fingerprint == NULL) { + rexmpp_log(s, LOG_WARNING, "No fingerprint found in pubkey-metadata"); + continue; + } + err = gpgme_get_key(s->pgp_ctx, fingerprint, &sec_key, 1); + if (gpg_err_code(err) == GPG_ERR_NO_ERROR) { + if (sec_key->can_sign) { + gpgme_signers_add(s->pgp_ctx, sec_key); + } + gpgme_key_unref(sec_key); + } else if (gpg_err_code(err) != GPG_ERR_EOF) { + rexmpp_log(s, LOG_ERR, "Failed to read key %s: %s", + fingerprint, gpgme_strerror(err)); + } + free(fingerprint); + } +} + char *rexmpp_openpgp_encrypt_sign (rexmpp_t *s, xmlNodePtr payload, const char **recipients) @@ -698,19 +729,8 @@ char *rexmpp_openpgp_encrypt_sign (rexmpp_t *s, /* Add own keys for encryption and signing. */ rexmpp_openpgp_add_keys(s, s->initial_jid.bare, &keys, &nkeys, &allocated); - gpgme_signers_clear(s->pgp_ctx); - for (i = 0; i < nkeys; i++) { - /* Check that the key can be used to sign data, and that we have - the secret key. */ - if (keys[i]->can_sign) { - gpgme_key_t sec_key; - err = gpgme_get_key(s->pgp_ctx, keys[i]->subkeys->fpr, &sec_key, 1); - gpgme_key_unref(sec_key); - if (gpg_err_code(err) == GPG_ERR_NO_ERROR) { - gpgme_signers_add(s->pgp_ctx, keys[i]); - } - } - } + rexmpp_openpgp_set_signers(s); + /* Add recipients' keys for encryption. */ for (i = 0; recipients[i] != NULL; i++) { rexmpp_openpgp_add_keys(s, recipients[i], &keys, &nkeys, &allocated); |