aboutsummaryrefslogtreecommitdiffstats
path: root/src/gpgme-json.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2018-04-17 06:33:44 +0000
committerWerner Koch <[email protected]>2018-04-17 06:45:00 +0000
commita1f76b3b54b75a150fe272b804d85ffd40a507a6 (patch)
tree3f0dd57d543391fc300206bcfebb5e9eb9bb10fd /src/gpgme-json.c
parentcore: Tweak STATUS_FAILURE handling. (diff)
downloadgpgme-a1f76b3b54b75a150fe272b804d85ffd40a507a6.tar.gz
gpgme-a1f76b3b54b75a150fe272b804d85ffd40a507a6.zip
core: Add extended versions of the encrypt functions.
* src/gpgme.h.in (gpgme_op_encrypt_ext_start) New. (gpgme_op_encrypt_ext): New. (gpgme_op_encrypt_sign_ext_start): New. (gpgme_op_encrypt_sign_ext): New. * src/libgpgme.vers, tests/run-encrypt.c: Add them. * src/encrypt.c (encrypt_start): Add arg recpstring. (gpgme_op_encrypt): Factor code out to ... (gpgme_op_encrypt_ext): new function with new arg recpstring. (gpgme_op_encrypt_start): Factor code out to ... (gpgme_op_encrypt_ext_start): new function with new arg recpstring. * src/encrypt-sign.c (encrypt_sign_start): Add arg recpstring. (gpgme_op_encrypt_sign): Factor code out to ... (gpgme_op_encrypt_sign_ext): new function with new arg recpstring. (gpgme_op_encrypt_sign_start): Factor code out to ... (gpgme_op_encrypt_sign_ext_start): new function with new arg recpstring. * src/engine-backend.h (struct engine_ops): Change fields encrypt and encrypt_sign. * src/engine.c (_gpgme_engine_op_encrypt): Add arg recpstring and pass to engine. (_gpgme_engine_op_encrypt_sign): Ditto. * src/engine-gpg.c (append_args_from_recipients_string): New. (gpg_encrypt): Add arg recpstring and call new function as needed. (gpg_encrypt_sign): Ditto. * src/engine-gpgsm.c (set_recipients_from_string): New. (gpgsm_encrypt): Add arg recpstring and call new function as needed. * src/engine-uiserver.c (set_recipients_from_string): New. (uiserver_encrypt): Add arg recpstring and call new function as needed. * tests/run-encrypt.c (xstrdup): New. (main): Add option --keystring. * src/gpgme-json.c (get_keys): Simplify. (op_encrypt): Modify to make use of the extended encrypt function. -- This new feature can be used to avoid the need for a key lookup and thus several extra calls to the backend. Note that run-test uses a semicolon as delimiter because that make testing the feature on the command line much easier. Signed-off-by: Werner Koch <[email protected]>
Diffstat (limited to 'src/gpgme-json.c')
-rw-r--r--src/gpgme-json.c74
1 files changed, 36 insertions, 38 deletions
diff --git a/src/gpgme-json.c b/src/gpgme-json.c
index b54d9a8a..4b1cd5b8 100644
--- a/src/gpgme-json.c
+++ b/src/gpgme-json.c
@@ -354,18 +354,19 @@ get_protocol (cjson_t json, gpgme_protocol_t *r_protocol)
}
-/* Extract the keys from the KEYS array in the JSON object. CTX is a
- * GPGME context object. On success an array with the keys is stored
- * at R_KEYS. In failure an error code is returned. */
+/* Extract the keys from the "keys" array in the JSON object. On
+ * success a string with the keys identifiers is stored at R_KEYS.
+ * The keys in that string are LF delimited. On failure an error code
+ * is returned. */
static gpg_error_t
-get_keys (gpgme_ctx_t ctx, cjson_t json, gpgme_key_t **r_keys)
+get_keys (cjson_t json, char **r_keystring)
{
- gpg_error_t err;
cjson_t j_keys, j_item;
int i, nkeys;
- gpgme_key_t *keys;
+ char *p;
+ size_t length;
- *r_keys = NULL;
+ *r_keystring = NULL;
j_keys = cJSON_GetObjectItem (json, "keys");
if (!j_keys)
@@ -373,8 +374,15 @@ get_keys (gpgme_ctx_t ctx, cjson_t json, gpgme_key_t **r_keys)
if (!cjson_is_array (j_keys) && !cjson_is_string (j_keys))
return gpg_error (GPG_ERR_INV_VALUE);
+ /* Fixme: We should better use a membuf like thing. */
+ length = 1; /* For the EOS. */
if (cjson_is_string (j_keys))
- nkeys = 1;
+ {
+ nkeys = 1;
+ length += strlen (j_keys->valuestring);
+ if (strchr (j_keys->valuestring, '\n'))
+ return gpg_error (GPG_ERR_INV_USER_ID);
+ }
else
{
nkeys = cJSON_GetArraySize (j_keys);
@@ -385,43 +393,37 @@ get_keys (gpgme_ctx_t ctx, cjson_t json, gpgme_key_t **r_keys)
j_item = cJSON_GetArrayItem (j_keys, i);
if (!j_item || !cjson_is_string (j_item))
return gpg_error (GPG_ERR_INV_VALUE);
+ if (i)
+ length++; /* Space for delimiter. */
+ length += strlen (j_item->valuestring);
+ if (strchr (j_item->valuestring, '\n'))
+ return gpg_error (GPG_ERR_INV_USER_ID);
}
}
- /* Now allocate an array to store the gpgme key objects. */
- keys = xcalloc (nkeys + 1, sizeof *keys);
+ p = *r_keystring = xtrymalloc (length);
+ if (!p)
+ return gpg_error_from_syserror ();
if (cjson_is_string (j_keys))
{
- err = gpgme_get_key (ctx, j_keys->valuestring, &keys[0], 0);
- if (err)
- goto leave;
+ strcpy (p, j_keys->valuestring);
}
else
{
for (i=0; i < nkeys; i++)
{
j_item = cJSON_GetArrayItem (j_keys, i);
- err = gpgme_get_key (ctx, j_item->valuestring, &keys[i], 0);
- if (err)
- goto leave;
+ if (i)
+ *p++ = '\n'; /* Add delimiter. */
+ p = stpcpy (p, j_item->valuestring);
}
}
- err = 0;
- *r_keys = keys;
- keys = NULL;
-
- leave:
- if (keys)
- {
- for (i=0; keys[i]; i++)
- gpgme_key_unref (keys[i]);
- xfree (keys);
- }
- return err;
+ return 0;
}
+
/*
* GPGME support functions.
@@ -582,11 +584,11 @@ op_encrypt (cjson_t request, cjson_t result)
gpgme_ctx_t ctx = NULL;
gpgme_protocol_t protocol;
int opt_base64;
- gpgme_key_t *keys = NULL;
+ char *keystring = NULL;
cjson_t j_input;
gpgme_data_t input = NULL;
gpgme_data_t output = NULL;
- int abool, i;
+ int abool;
gpgme_encrypt_flags_t encrypt_flags = 0;
if ((err = get_protocol (request, &protocol)))
@@ -622,7 +624,7 @@ op_encrypt (cjson_t request, cjson_t result)
/* Get the keys. */
- err = get_keys (ctx, request, &keys);
+ err = get_keys (request, &keystring);
if (err)
{
/* Provide a custom error response. */
@@ -674,7 +676,8 @@ op_encrypt (cjson_t request, cjson_t result)
}
/* Encrypt. */
- err = gpgme_op_encrypt (ctx, keys, encrypt_flags, input, output);
+ err = gpgme_op_encrypt_ext (ctx, NULL, keystring, encrypt_flags,
+ input, output);
/* encrypt_result = gpgme_op_encrypt_result (ctx); */
if (err)
{
@@ -713,12 +716,7 @@ op_encrypt (cjson_t request, cjson_t result)
}
leave:
- if (keys)
- {
- for (i=0; keys[i]; i++)
- gpgme_key_unref (keys[i]);
- xfree (keys);
- }
+ xfree (keystring);
release_context (ctx);
gpgme_data_release (input);
return err;