summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordefanor <defanor@uberspace.net>2021-02-07 22:13:35 +0300
committerdefanor <defanor@uberspace.net>2021-02-07 22:13:35 +0300
commit81a85c55ef1159ac4baee59dddcd33a47099e678 (patch)
treed352af4691c8c61be3a7e545e0109b0486f216a7
parentbfc932724364aa776d11395f77090764f5148042 (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.c54
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);