diff options
| author | Werner Koch <[email protected]> | 2018-04-17 11:48:56 +0000 | 
|---|---|---|
| committer | Werner Koch <[email protected]> | 2018-04-17 11:48:56 +0000 | 
| commit | 01435da498af9f7538d7ee810392d7eaa407957e (patch) | |
| tree | 8a9515130220ecdf058c85fcf9ce24e88618872c | |
| parent | core: New keyword --file for OpenPGP recpstring. (diff) | |
| download | gpgme-01435da498af9f7538d7ee810392d7eaa407957e.tar.gz gpgme-01435da498af9f7538d7ee810392d7eaa407957e.zip | |
core: Extend decryption result with symkey_algo.
* src/gpgme.h.in (gpgme_op_decrypt_result_t): Add field 'symkey_algo'.
* src/decrypt.c (release_op_data): Free SYMKEY_ALGO.
(gpgme_op_decrypt_result): Make sure SYMKEY_ALGO is not NULL.
(parse_decryption_info): New.
(_gpgme_decrypt_status_handler): Parse DECRYPTION_INFO status.
* src/conversion.c (_gpgme_cipher_algo_name): New.
(_gpgme_cipher_mode_name): New.
* tests/run-decrypt.c (print_result): Print SYMKEY_ALGO
* src/util.h (_gpgme_map_gnupg_error): Remove obsolete prototype.
--
Signed-off-by: Werner Koch <[email protected]>
| -rw-r--r-- | NEWS | 1 | ||||
| -rw-r--r-- | doc/gpgme.texi | 7 | ||||
| -rw-r--r-- | src/conversion.c | 46 | ||||
| -rw-r--r-- | src/decrypt.c | 70 | ||||
| -rw-r--r-- | src/gpgme.h.in | 4 | ||||
| -rw-r--r-- | src/util.h | 5 | ||||
| -rw-r--r-- | tests/run-decrypt.c | 1 | 
7 files changed, 123 insertions, 11 deletions
| @@ -11,6 +11,7 @@ Noteworthy changes in version 1.10.1 (unreleased)   gpgme_op_encrypt_sign_ext_start  NEW.   GPGME_ENCRYPT_WANT_ADDRESS       NEW.   gpgme_import_result_t            EXTENDED: New field 'skipped_v3_keys'. + gpgme_decrypt_result_t           EXTENDED: New field 'symkey_algo'.   cpp: Key::locate                 NEW.   cpp: Data::toString              NEW.   cpp: ImportResult::numV3KeysSkipped  NEW. diff --git a/doc/gpgme.texi b/doc/gpgme.texi index f5efec67..5a09ea0a 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -5399,6 +5399,13 @@ You must not try to access this member of the struct unless  or @code{gpgme_get_ctx_flag (ctx, "export-session-key")} returns true  (non-empty string). +@item char *symkey_algo +@since{1.11.0} + +A string with the symmetric encryption algorithm and mode using the +format "<algo>.<mode>".  Note that old non-MDC encryption mode of +OpenPGP is given as "PGPCFB". +  @end table  @end deftp diff --git a/src/conversion.c b/src/conversion.c index 5b84f672..4bfd3d3e 100644 --- a/src/conversion.c +++ b/src/conversion.c @@ -575,3 +575,49 @@ _gpgme_map_pk_algo (int algo, gpgme_protocol_t protocol)    return algo;  } + + +/* Return a string with a cipher algorithm.  */ +const char * +_gpgme_cipher_algo_name (int algo, gpgme_protocol_t protocol) +{ +  if (protocol == GPGME_PROTOCOL_OPENPGP) +    { +      /* The algo is given according to OpenPGP specs.  */ +      switch (algo) +        { +        case 1:  return "IDEA"; +        case 2:	 return "3DES"; +        case 3:	 return "CAST5"; +        case 4:  return "BLOWFISH"; +        case 7:  return "AES"; +        case 8:  return "AES192"; +        case 9:  return "AES256"; +        case 10: return "TWOFISH"; +        case 11: return "CAMELLIA128"; +        case 12: return "CAMELLIA192"; +        case 13: return "CAMELLIA256"; +        } +    } + +  return "Unknown"; +} + + +/* Return a string with the cipher mode.  */ +const char * +_gpgme_cipher_mode_name (int algo, gpgme_protocol_t protocol) +{ +  if (protocol == GPGME_PROTOCOL_OPENPGP) +    { +      /* The algo is given according to OpenPGP specs.  */ +      switch (algo) +        { +        case 0:  return "CFB"; +        case 1:  return "EAX"; +        case 2:	 return "OCB"; +        } +    } + +  return "Unknown"; +} diff --git a/src/decrypt.c b/src/decrypt.c index 8c2cd4d7..e4de6e41 100644 --- a/src/decrypt.c +++ b/src/decrypt.c @@ -69,14 +69,10 @@ release_op_data (void *hook)    op_data_t opd = (op_data_t) hook;    gpgme_recipient_t recipient = opd->result.recipients; -  if (opd->result.unsupported_algorithm) -    free (opd->result.unsupported_algorithm); - -  if (opd->result.file_name) -    free (opd->result.file_name); - -  if (opd->result.session_key) -    free (opd->result.session_key); +  free (opd->result.unsupported_algorithm); +  free (opd->result.file_name); +  free (opd->result.session_key); +  free (opd->result.symkey_algo);    while (recipient)      { @@ -104,6 +100,17 @@ gpgme_op_decrypt_result (gpgme_ctx_t ctx)        return NULL;      } +  /* Make sure that SYMKEY_ALGO has a value.  */ +  if (!opd->result.symkey_algo) +    { +      opd->result.symkey_algo = strdup ("?.?"); +      if (!opd->result.symkey_algo) +        { +          TRACE_SUC0 ("result=(null)"); +          return NULL; +        } +    } +    if (_gpgme_debug_trace ())      {        gpgme_recipient_t rcp; @@ -263,6 +270,49 @@ parse_enc_to (char *args, gpgme_recipient_t *recp, gpgme_protocol_t protocol)  } +/* Parse the ARGS of a + *   DECRYPTION_INFO <mdc_method> <sym_algo> [<aead_algo>] + * status.  Returns 0 on success and updates the OPD. + */ +static gpgme_error_t +parse_decryption_info (char *args, op_data_t opd, gpgme_protocol_t protocol) +{ +  char *field[3]; +  int nfields; +  char *args2; +  int mdc, mode; +  const char *algostr, *modestr; + +  if (!args) +    return trace_gpg_error (GPG_ERR_INV_ENGINE); + +  args2 = strdup (args); /* Split modifies the input string. */ +  nfields = _gpgme_split_fields (args2, field, DIM (field)); +  if (nfields < 2) +    { +      free (args2); +      return trace_gpg_error (GPG_ERR_INV_ENGINE); /* Required arg missing.  */ +    } + +  mdc     = atoi (field[0]); +  algostr = _gpgme_cipher_algo_name (atoi (field[1]), protocol); +  mode    = nfields < 3? 0 : atoi (field[2]); +  modestr = _gpgme_cipher_mode_name (mode, protocol); + +  free (args2); + +  free (opd->result.symkey_algo); +  if (!mode && mdc != 2) +    opd->result.symkey_algo = _gpgme_strconcat (algostr, ".PGPCFB", NULL); +  else +    opd->result.symkey_algo = _gpgme_strconcat (algostr, ".", modestr, NULL); +  if (!opd->result.symkey_algo) +    return gpg_error_from_syserror (); + +  return 0; +} + +  gpgme_error_t  _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code,  			       char *args) @@ -303,7 +353,9 @@ _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code,        break;      case GPGME_STATUS_DECRYPTION_INFO: -      /* Fixme: Provide a way to return the used symmetric algorithm. */ +      err = parse_decryption_info (args, opd, ctx->protocol); +      if (err) +	return err;        break;      case GPGME_STATUS_DECRYPTION_OKAY: diff --git a/src/gpgme.h.in b/src/gpgme.h.in index 860e0931..202859c3 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -1368,6 +1368,10 @@ struct _gpgme_op_decrypt_result    /* A textual representation of the session key used to decrypt the     * message, if available */    char *session_key; + +   /* A string with the symmetric encryption algorithm and mode using +    * the format "<algo>.<mode>".  */ +  char *symkey_algo;  };  typedef struct _gpgme_op_decrypt_result *gpgme_decrypt_result_t; @@ -165,10 +165,11 @@ time_t _gpgme_parse_timestamp (const char *timestamp, char **endp);   * on error or missing timestamp.  */  unsigned long _gpgme_parse_timestamp_ul (const char *timestamp); -gpgme_error_t _gpgme_map_gnupg_error (char *err); -  int _gpgme_map_pk_algo (int algo, gpgme_protocol_t protocol); +const char *_gpgme_cipher_algo_name (int algo, gpgme_protocol_t protocol); +const char *_gpgme_cipher_mode_name (int algo, gpgme_protocol_t protocol); +  /*-- b64dec.c --*/ diff --git a/tests/run-decrypt.c b/tests/run-decrypt.c index a2e82a0e..8eb6ba09 100644 --- a/tests/run-decrypt.c +++ b/tests/run-decrypt.c @@ -59,6 +59,7 @@ print_result (gpgme_decrypt_result_t result)            nonnull(result->unsupported_algorithm));    if (result->session_key)      printf ("Session key: %s\n", result->session_key); +  printf ("Symmetric algorithm: %s\n", result->symkey_algo);    for (recp = result->recipients; recp && recp->next; recp = recp->next)      { | 
