diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/gpgme-json.c | 211 | 
1 files changed, 211 insertions, 0 deletions
| diff --git a/src/gpgme-json.c b/src/gpgme-json.c index 990f4a33..4f8e0afe 100644 --- a/src/gpgme-json.c +++ b/src/gpgme-json.c @@ -147,6 +147,16 @@ xjson_CreateObject (void)    return json;  } +/* Call cJSON_CreateArray but terminate in case of an error.  */ +static cjson_t +xjson_CreateArray (void) +{ +  cjson_t json = cJSON_CreateArray (); +  if (!json) +    xoutofcore ("cJSON_CreateArray"); +  return json; +} +  /* Wrapper around cJSON_AddStringToObject which returns an gpg-error   * code instead of the NULL or the new object.  */ @@ -590,6 +600,187 @@ data_from_base64_string (gpgme_data_t *r_data, cjson_t json)  } +/* Helper for summary formatting */ +static void +add_summary_to_object (cjson_t result, gpgme_sigsum_t summary) +{ +  cjson_t response = xjson_CreateArray (); +  if ( (summary & GPGME_SIGSUM_VALID      )) +    cJSON_AddItemToArray (response, +        cJSON_CreateString ("valid")); +  if ( (summary & GPGME_SIGSUM_GREEN      )) +    cJSON_AddItemToArray (response, +        cJSON_CreateString ("green")); +  if ( (summary & GPGME_SIGSUM_RED        )) +    cJSON_AddItemToArray (response, +        cJSON_CreateString ("red")); +  if ( (summary & GPGME_SIGSUM_KEY_REVOKED)) +    cJSON_AddItemToArray (response, +        cJSON_CreateString ("revoked")); +  if ( (summary & GPGME_SIGSUM_KEY_EXPIRED)) +    cJSON_AddItemToArray (response, +        cJSON_CreateString ("key-expired")); +  if ( (summary & GPGME_SIGSUM_SIG_EXPIRED)) +    cJSON_AddItemToArray (response, +        cJSON_CreateString ("sig-expired")); +  if ( (summary & GPGME_SIGSUM_KEY_MISSING)) +    cJSON_AddItemToArray (response, +        cJSON_CreateString ("key-missing")); +  if ( (summary & GPGME_SIGSUM_CRL_MISSING)) +    cJSON_AddItemToArray (response, +        cJSON_CreateString ("crl-missing")); +  if ( (summary & GPGME_SIGSUM_CRL_TOO_OLD)) +    cJSON_AddItemToArray (response, +        cJSON_CreateString ("crl-too-old")); +  if ( (summary & GPGME_SIGSUM_BAD_POLICY )) +    cJSON_AddItemToArray (response, +        cJSON_CreateString ("bad-policy")); +  if ( (summary & GPGME_SIGSUM_SYS_ERROR  )) +    cJSON_AddItemToArray (response, +        cJSON_CreateString ("sys-error")); + +  cJSON_AddItemToObject (result, "summary", response); +} + + +/* Helper for summary formatting */ +static const char * +validity_to_string (gpgme_validity_t val) +{ +  switch (val) +    { +    case GPGME_VALIDITY_UNDEFINED:return "undefined"; +    case GPGME_VALIDITY_NEVER:    return "never"; +    case GPGME_VALIDITY_MARGINAL: return "marginal"; +    case GPGME_VALIDITY_FULL:     return "full"; +    case GPGME_VALIDITY_ULTIMATE: return "ultimate"; +    case GPGME_VALIDITY_UNKNOWN: +    default:                      return "unknown"; +    } +} + + +/* Add a single signature to a result */ +static gpg_error_t +add_signature_to_object (cjson_t result, gpgme_signature_t sig) +{ +  gpg_error_t err = 0; + +  if (!cJSON_AddStringToObject (result, "status", gpgme_strerror (sig->status))) +    { +      err = gpg_error_from_syserror (); +      goto leave; +    } + +  if (!cJSON_AddNumberToObject (result, "code", sig->status)) +    { +      err = gpg_error_from_syserror (); +      goto leave; +    } + +  add_summary_to_object (result, sig->summary); + +  if (!cJSON_AddStringToObject (result, "fingerprint", sig->fpr)) +    { +      err = gpg_error_from_syserror (); +      goto leave; +    } + +  if (!cJSON_AddNumberToObject (result, "created", sig->timestamp)) +    { +      err = gpg_error_from_syserror (); +      goto leave; +    } + +  if (!cJSON_AddNumberToObject (result, "expired", sig->exp_timestamp)) +    { +      err = gpg_error_from_syserror (); +      goto leave; +    } + +  if (!cJSON_AddStringToObject (result, "validity", +                                validity_to_string (sig->validity))) +    { +      err = gpg_error_from_syserror (); +      goto leave; +    } + +leave: +  return err; +} + + +/* Add multiple signatures as an array to a result */ +static gpg_error_t +add_signatures_to_object (cjson_t result, gpgme_signature_t signatures) +{ +  cjson_t response = xJSON_CreateArray (); +  gpg_error_t err = 0; +  gpgme_signature_t sig; + +  for (sig = signatures; sig; sig = sig->next) +    { +      cjson_t sig_obj = xjson_CreateObject (); +      err = add_signature_to_object (sig_obj, sig); +      if (err) +        { +          cJSON_Delete (sig_obj); +          sig_obj = NULL; +          goto leave; +        } + +      cJSON_AddItemToArray (response, sig_obj); +    } + +  if (!cJSON_AddItemToObject (result, "signatures", response)) +    { +      err = gpg_error_from_syserror (); +      cJSON_Delete (response); +      response = NULL; +      return err; +    } +  response = NULL; + +leave: +  if (err && response) +    { +      cJSON_Delete (response); +      response = NULL; +    } +  return err; +} + + +/* Add an array of signature informations under the name "name". */ +static gpg_error_t +add_signatures_object (cjson_t result, const char *name, +                           gpgme_verify_result_t verify_result) +{ +  cjson_t response = xjson_CreateObject (); +  gpg_error_t err = 0; + +  err = add_signatures_to_object (response, verify_result->signatures); + +  if (err) +    { +      goto leave; +    } + +  if (!cJSON_AddItemToObject (result, name, response)) +    { +      err = gpg_error_from_syserror (); +      goto leave; +    } + leave: +  if (err) +    { +      cJSON_Delete (response); +      response = NULL; +    } +  return err; +} + +  /*   * Implementation of the commands. @@ -884,6 +1075,7 @@ op_decrypt (cjson_t request, cjson_t result)    gpgme_data_t input = NULL;    gpgme_data_t output = NULL;    gpgme_decrypt_result_t decrypt_result; +  gpgme_verify_result_t verify_result;    if ((err = get_protocol (request, &protocol)))      goto leave; @@ -955,6 +1147,24 @@ op_decrypt (cjson_t request, cjson_t result)    err = make_data_object (result, output, chunksize, "plaintext", -1);    output = NULL; +  if (err) +    { +      error_object (result, "Plaintext output failed: %s", gpg_strerror (err)); +      goto leave; +    } + +  verify_result = gpgme_op_verify_result (ctx); +  if (verify_result && verify_result->signatures) +    { +      err = add_signatures_object (result, "info", verify_result); +    } + +  if (err) +    { +      error_object (result, "Info output failed: %s", gpg_strerror (err)); +      goto leave; +    } +   leave:    release_context (ctx);    gpgme_data_release (input); @@ -1058,6 +1268,7 @@ static const char hlp_help[] =    "returned.  To list all operations it is allowed to leave out \"op\" in\n"    "help mode.  Supported values for \"op\" are:\n\n"    "  encrypt     Encrypt data.\n" +  "  decrypt     Decrypt data.\n"    "  getmore     Retrieve remaining data.\n"    "  help        Help overview.";  static gpg_error_t | 
