json: Deduplicate input handling code

* gpgme-json.c (get_string_data): New.
(op_verify, op_sign, op_decrypt, op_encrypt): Use it.

--
This handles the common base64 decoding and creation of the
gpgme_data object.
This commit is contained in:
Andre Heinecke 2018-05-25 09:46:30 +02:00
parent 321005c12f
commit a46c27b321
No known key found for this signature in database
GPG Key ID: 2978E9D40CBABA5C

View File

@ -844,6 +844,58 @@ add_ei_to_object (cjson_t result, gpgme_engine_info_t info)
return gpg_error_from_syserror (); return gpg_error_from_syserror ();
return 0; return 0;
} }
/* Create a gpgme_data from json string data named "name"
* in the request. Takes the base64 option into account.
*
* Adds an error to the "result" on error. */
static gpg_error_t
get_string_data (cjson_t request, cjson_t result, const char *name,
gpgme_data_t *r_data)
{
gpgme_error_t err;
int opt_base64;
cjson_t j_data;
if ((err = get_boolean_flag (request, "base64", 0, &opt_base64)))
return err;
/* Get the data. Note that INPUT is a shallow data object with the
* storage hold in REQUEST. */
j_data = cJSON_GetObjectItem (request, name);
if (!j_data)
{
return gpg_error (GPG_ERR_NO_DATA);
}
if (!cjson_is_string (j_data))
{
return gpg_error (GPG_ERR_INV_VALUE);
}
if (opt_base64)
{
err = data_from_base64_string (r_data, j_data);
if (err)
{
gpg_error_object (result, err,
"Error decoding Base-64 encoded '%s': %s",
name, gpg_strerror (err));
return err;
}
}
else
{
err = gpgme_data_new_from_mem (r_data, j_data->valuestring,
strlen (j_data->valuestring), 0);
if (err)
{
gpg_error_object (result, err, "Error getting '%s': %s",
name, gpg_strerror (err));
return err;
}
}
return 0;
}
/* /*
* Implementation of the commands. * Implementation of the commands.
@ -977,10 +1029,8 @@ op_encrypt (cjson_t request, cjson_t result)
gpgme_ctx_t ctx = NULL; gpgme_ctx_t ctx = NULL;
gpgme_protocol_t protocol; gpgme_protocol_t protocol;
size_t chunksize; size_t chunksize;
int opt_base64;
int opt_mime; int opt_mime;
char *keystring = NULL; char *keystring = NULL;
cjson_t j_input;
gpgme_data_t input = NULL; gpgme_data_t input = NULL;
gpgme_data_t output = NULL; gpgme_data_t output = NULL;
int abool; int abool;
@ -992,8 +1042,6 @@ op_encrypt (cjson_t request, cjson_t result)
if ((err = get_chunksize (request, &chunksize))) if ((err = get_chunksize (request, &chunksize)))
goto leave; goto leave;
if ((err = get_boolean_flag (request, "base64", 0, &opt_base64)))
goto leave;
if ((err = get_boolean_flag (request, "mime", 0, &opt_mime))) if ((err = get_boolean_flag (request, "mime", 0, &opt_mime)))
goto leave; goto leave;
@ -1036,40 +1084,9 @@ op_encrypt (cjson_t request, cjson_t result)
goto leave; goto leave;
} }
/* Get the data. Note that INPUT is a shallow data object with the if ((err = get_string_data (request, result, "data", &input)))
* storage hold in REQUEST. */
j_input = cJSON_GetObjectItem (request, "data");
if (!j_input)
{
err = gpg_error (GPG_ERR_NO_DATA);
goto leave; goto leave;
}
if (!cjson_is_string (j_input))
{
err = gpg_error (GPG_ERR_INV_VALUE);
goto leave;
}
if (opt_base64)
{
err = data_from_base64_string (&input, j_input);
if (err)
{
gpg_error_object (result, err, "Error decoding Base-64 encoded "
"'data': %s", gpg_strerror (err));
goto leave;
}
}
else
{
err = gpgme_data_new_from_mem (&input, j_input->valuestring,
strlen (j_input->valuestring), 0);
if (err)
{
gpg_error_object (result, err, "Error getting 'data': %s",
gpg_strerror (err));
goto leave;
}
}
if (opt_mime) if (opt_mime)
gpgme_data_set_encoding (input, GPGME_DATA_ENCODING_MIME); gpgme_data_set_encoding (input, GPGME_DATA_ENCODING_MIME);
@ -1136,8 +1153,6 @@ op_decrypt (cjson_t request, cjson_t result)
gpgme_ctx_t ctx = NULL; gpgme_ctx_t ctx = NULL;
gpgme_protocol_t protocol; gpgme_protocol_t protocol;
size_t chunksize; size_t chunksize;
int opt_base64;
cjson_t j_input;
gpgme_data_t input = NULL; gpgme_data_t input = NULL;
gpgme_data_t output = NULL; gpgme_data_t output = NULL;
gpgme_decrypt_result_t decrypt_result; gpgme_decrypt_result_t decrypt_result;
@ -1149,45 +1164,9 @@ op_decrypt (cjson_t request, cjson_t result)
if ((err = get_chunksize (request, &chunksize))) if ((err = get_chunksize (request, &chunksize)))
goto leave; goto leave;
if ((err = get_boolean_flag (request, "base64", 0, &opt_base64))) if ((err = get_string_data (request, result, "data", &input)))
goto leave; goto leave;
/* Get the data. Note that INPUT is a shallow data object with the
* storage hold in REQUEST. */
j_input = cJSON_GetObjectItem (request, "data");
if (!j_input)
{
err = gpg_error (GPG_ERR_NO_DATA);
goto leave;
}
if (!cjson_is_string (j_input))
{
err = gpg_error (GPG_ERR_INV_VALUE);
goto leave;
}
if (opt_base64)
{
err = data_from_base64_string (&input, j_input);
if (err)
{
gpg_error_object (result, err,
"Error decoding Base-64 encoded 'data': %s",
gpg_strerror (err));
goto leave;
}
}
else
{
err = gpgme_data_new_from_mem (&input, j_input->valuestring,
strlen (j_input->valuestring), 0);
if (err)
{
gpg_error_object (result, err, "Error getting 'data': %s",
gpg_strerror (err));
goto leave;
}
}
/* Create an output data object. */ /* Create an output data object. */
err = gpgme_data_new (&output); err = gpgme_data_new (&output);
if (err) if (err)
@ -1279,9 +1258,7 @@ op_sign (cjson_t request, cjson_t result)
gpgme_ctx_t ctx = NULL; gpgme_ctx_t ctx = NULL;
gpgme_protocol_t protocol; gpgme_protocol_t protocol;
size_t chunksize; size_t chunksize;
int opt_base64;
char *keystring = NULL; char *keystring = NULL;
cjson_t j_input;
gpgme_data_t input = NULL; gpgme_data_t input = NULL;
gpgme_data_t output = NULL; gpgme_data_t output = NULL;
int abool; int abool;
@ -1296,9 +1273,6 @@ op_sign (cjson_t request, cjson_t result)
if ((err = get_chunksize (request, &chunksize))) if ((err = get_chunksize (request, &chunksize)))
goto leave; goto leave;
if ((err = get_boolean_flag (request, "base64", 0, &opt_base64)))
goto leave;
if ((err = get_boolean_flag (request, "armor", 0, &abool))) if ((err = get_boolean_flag (request, "armor", 0, &abool)))
goto leave; goto leave;
gpgme_set_armor (ctx, abool); gpgme_set_armor (ctx, abool);
@ -1356,41 +1330,8 @@ op_sign (cjson_t request, cjson_t result)
gpgme_key_unref (key); gpgme_key_unref (key);
} }
/* Get the data. Note that INPUT is a shallow data object with the if ((err = get_string_data (request, result, "data", &input)))
* storage hold in REQUEST. */
j_input = cJSON_GetObjectItem (request, "data");
if (!j_input)
{
err = gpg_error (GPG_ERR_NO_DATA);
goto leave; goto leave;
}
if (!cjson_is_string (j_input))
{
err = gpg_error (GPG_ERR_INV_VALUE);
goto leave;
}
if (opt_base64)
{
err = data_from_base64_string (&input, j_input);
if (err)
{
gpg_error_object (result, err,
"Error decoding Base-64 encoded 'data': %s",
gpg_strerror (err));
goto leave;
}
}
else
{
err = gpgme_data_new_from_mem (&input, j_input->valuestring,
strlen (j_input->valuestring), 0);
if (err)
{
gpg_error_object (result, err, "Error getting 'data': %s",
gpg_strerror (err));
goto leave;
}
}
/* Create an output data object. */ /* Create an output data object. */
err = gpgme_data_new (&output); err = gpgme_data_new (&output);
@ -1415,7 +1356,7 @@ op_sign (cjson_t request, cjson_t result)
/* We need to base64 if armoring has not been requested. */ /* We need to base64 if armoring has not been requested. */
err = make_data_object (result, output, chunksize, err = make_data_object (result, output, chunksize,
"ciphertext", !gpgme_get_armor (ctx)); "signature", !gpgme_get_armor (ctx));
output = NULL; output = NULL;
leave: leave:
@ -1452,8 +1393,6 @@ op_verify (cjson_t request, cjson_t result)
gpgme_ctx_t ctx = NULL; gpgme_ctx_t ctx = NULL;
gpgme_protocol_t protocol; gpgme_protocol_t protocol;
size_t chunksize; size_t chunksize;
int opt_base64;
cjson_t j_input, j_signature;
gpgme_data_t input = NULL; gpgme_data_t input = NULL;
gpgme_data_t signature = NULL; gpgme_data_t signature = NULL;
gpgme_data_t output = NULL; gpgme_data_t output = NULL;
@ -1465,71 +1404,13 @@ op_verify (cjson_t request, cjson_t result)
if ((err = get_chunksize (request, &chunksize))) if ((err = get_chunksize (request, &chunksize)))
goto leave; goto leave;
if ((err = get_boolean_flag (request, "base64", 0, &opt_base64))) if ((err = get_string_data (request, result, "data", &input)))
goto leave; goto leave;
/* Get the data. Note that INPUT is a shallow data object with the err = get_string_data (request, result, "signature", &signature);
* storage hold in REQUEST. */ /* Signature data is optional otherwise we expect opaque or clearsigned. */
j_input = cJSON_GetObjectItem (request, "data"); if (err && err != gpg_error (GPG_ERR_NO_DATA))
if (!j_input)
{
err = gpg_error (GPG_ERR_NO_DATA);
goto leave; goto leave;
}
if (!cjson_is_string (j_input))
{
err = gpg_error (GPG_ERR_INV_VALUE);
goto leave;
}
if (opt_base64)
{
err = data_from_base64_string (&input, j_input);
if (err)
{
gpg_error_object (result, err, "Error decoding Base-64 encoded "
"'data': %s", gpg_strerror (err));
goto leave;
}
}
else
{
err = gpgme_data_new_from_mem (&input, j_input->valuestring,
strlen (j_input->valuestring), 0);
if (err)
{
gpg_error_object (result, err, "Error getting 'data': %s",
gpg_strerror (err));
goto leave;
}
}
/* Get the signature. */
j_signature = cJSON_GetObjectItem (request, "signature");
if (j_signature && cjson_is_string (j_signature))
{
if (opt_base64)
{
err = data_from_base64_string (&signature, j_signature);
if (err)
{
gpg_error_object (result, err, "Error decoding Base-64 encoded "
"'signature': %s", gpg_strerror (err));
goto leave;
}
}
else
{
err = gpgme_data_new_from_mem (&signature, j_signature->valuestring,
strlen (j_signature->valuestring),
0);
if (err)
{
gpg_error_object (result, err, "Error getting 'signature': %s",
gpg_strerror (err));
goto leave;
}
}
}
/* Create an output data object. */ /* Create an output data object. */
err = gpgme_data_new (&output); err = gpgme_data_new (&output);
@ -1540,9 +1421,6 @@ op_verify (cjson_t request, cjson_t result)
goto leave; goto leave;
} }
gpgme_data_rewind (input);
gpgme_data_rewind (signature);
/* Verify. */ /* Verify. */
if (signature) if (signature)
{ {