aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2018-03-23 10:27:59 +0000
committerWerner Koch <[email protected]>2018-03-23 10:27:59 +0000
commitd83482a1d768fc5afd3aa4836f2fefe5c549d02e (patch)
tree8040c1f5203ca96ec097715dfbc133958c53a9d2
parentjson: Add a new function to cJSON. (diff)
downloadgpgme-d83482a1d768fc5afd3aa4836f2fefe5c549d02e.tar.gz
gpgme-d83482a1d768fc5afd3aa4836f2fefe5c549d02e.zip
json: Finish op:encrypt.
* src/gpgme-json.c (add_base64_to_object): New. (data_from_base64_string): New. (op_encrypt): Employ them. (process_request): Print unformated json. -- Signed-off-by: Werner Koch <[email protected]>
-rw-r--r--src/gpgme-json.c183
1 files changed, 171 insertions, 12 deletions
diff --git a/src/gpgme-json.c b/src/gpgme-json.c
index 75f1a095..6ba79e5a 100644
--- a/src/gpgme-json.c
+++ b/src/gpgme-json.c
@@ -64,6 +64,7 @@ static int opt_interactive;
*/
#define xtrymalloc(a) gpgrt_malloc ((a))
+#define xtrystrdup(a) gpgrt_strdup ((a))
#define xmalloc(a) ({ \
void *_r = gpgrt_malloc ((a)); \
if (!_r) \
@@ -140,6 +141,87 @@ xjson_AddBoolToObject (cjson_t object, const char *name, int abool)
return ;
}
+/* This is similar to cJSON_AddStringToObject but takes a gpgme DATA
+ * object and adds it under NAME as a base 64 encoded string to
+ * OBJECT. Ownership of DATA is transferred to this function. */
+static gpg_error_t
+add_base64_to_object (cjson_t object, const char *name, gpgme_data_t data)
+{
+ gpg_err_code_t err;
+ estream_t fp = NULL;
+ gpgrt_b64state_t state = NULL;
+ cjson_t j_str = NULL;
+ void *buffer = NULL;
+ size_t buflen;
+
+ fp = es_fopenmem (0, "rwb");
+ if (!fp)
+ {
+ err = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+ state = gpgrt_b64enc_start (fp, "");
+ if (!state)
+ {
+ err = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+
+ gpgme_data_write (data, "", 1); /* Make sure we have a string. */
+ buffer = gpgme_data_release_and_get_mem (data, &buflen);
+ data = NULL;
+ if (!buffer)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+
+ err = gpgrt_b64enc_write (state, buffer, buflen);
+ if (err)
+ goto leave;
+ xfree (buffer);
+ buffer = NULL;
+
+ err = gpgrt_b64enc_finish (state);
+ state = NULL;
+ if (err)
+ return err;
+
+ es_fputc (0, fp);
+ if (es_fclose_snatch (fp, &buffer, NULL))
+ {
+ fp = NULL;
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ fp = NULL;
+
+ j_str = cJSON_CreateStringConvey (buffer);
+ if (!j_str)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ buffer = NULL;
+
+ if (!cJSON_AddItemToObject (object, name, j_str))
+ {
+ err = gpg_error_from_syserror ();
+ cJSON_Delete (j_str);
+ j_str = NULL;
+ goto leave;
+ }
+ j_str = NULL;
+
+ leave:
+ xfree (buffer);
+ cJSON_Delete (j_str);
+ gpgrt_b64enc_finish (state);
+ es_fclose (fp);
+ gpgme_data_release (data);
+ return err;
+}
+
/* Create a JSON error object. If JSON is not NULL the error message
* is appended to that object. An existing "type" item will be replaced. */
@@ -386,6 +468,72 @@ release_context (gpgme_ctx_t ctx)
}
+
+/* Given a Base-64 encoded string object in JSON return a gpgme data
+ * object at R_DATA. */
+static gpg_error_t
+data_from_base64_string (gpgme_data_t *r_data, cjson_t json)
+{
+#if GPGRT_VERSION_NUMBER < 0x011d00 /* 1.29 */
+ *r_data = NULL;
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+#else
+ gpg_error_t err;
+ size_t len;
+ char *buf = NULL;
+ gpgrt_b64state_t state = NULL;
+ gpgme_data_t data = NULL;
+
+ *r_data = NULL;
+
+ /* A quick check on the JSON. */
+ if (!cjson_is_string (json))
+ {
+ err = gpg_error (GPG_ERR_INV_VALUE);
+ goto leave;
+ }
+
+ state = gpgrt_b64dec_start (NULL);
+ if (!state)
+ {
+ err = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+
+ /* Fixme: Data duplication - we should see how to snatch the memory
+ * from the json object. */
+ len = strlen (json->valuestring);
+ buf = xtrystrdup (json->valuestring);
+ if (!buf)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+
+ err = gpgrt_b64dec_proc (state, buf, len, &len);
+ if (err)
+ goto leave;
+
+ err = gpgrt_b64dec_finish (state);
+ state = NULL;
+ if (err)
+ goto leave;
+
+ err = gpgme_data_new_from_mem (&data, buf, len, 1);
+ if (err)
+ goto leave;
+ *r_data = data;
+ data = NULL;
+
+ leave:
+ xfree (data);
+ xfree (buf);
+ gpgrt_b64dec_finish (state);
+ return err;
+#endif
+}
+
+
/*
* Implementaion of the commands.
@@ -487,16 +635,23 @@ op_encrypt (cjson_t request, cjson_t result)
}
if (opt_base64)
{
- err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
- goto leave;
+ err = data_from_base64_string (&input, j_input);
+ if (err)
+ {
+ error_object (result, "Error decoding Base-64 encoded 'data': %s",
+ gpg_strerror (err));
+ goto leave;
+ }
}
- err = gpgme_data_new_from_mem (&input, j_input->valuestring,
- strlen (j_input->valuestring), 0);
- if (err)
+ else
{
- error_object (result, "Error creating input data object: %s",
- gpg_strerror (err));
- goto leave;
+ err = gpgme_data_new_from_mem (&input, j_input->valuestring,
+ strlen (j_input->valuestring), 0);
+ if (err)
+ {
+ error_object (result, "Error getting 'data': %s", gpg_strerror (err));
+ goto leave;
+ }
}
/* Create an output data object. */
@@ -541,9 +696,10 @@ op_encrypt (cjson_t request, cjson_t result)
}
else
{
- error_object (result, "Binary output is not yet supported");
- err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
- goto leave;
+ err = add_base64_to_object (result, "data", output);
+ output = NULL;
+ if (err)
+ goto leave;
}
leave:
@@ -685,7 +841,10 @@ process_request (const char *request)
leave:
cJSON_Delete (json);
json = NULL;
- res = cJSON_Print (response);
+ if (opt_interactive)
+ res = cJSON_Print (response);
+ else
+ res = cJSON_PrintUnformatted (response);
if (!res)
log_error ("Printing JSON data failed\n");
cJSON_Delete (response);