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 <wk@gnupg.org>
This commit is contained in:
Werner Koch 2018-04-17 13:48:56 +02:00
parent 3589da0500
commit 01435da498
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
7 changed files with 123 additions and 11 deletions

1
NEWS
View File

@ -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.

View File

@ -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

View File

@ -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";
}

View File

@ -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:

View File

@ -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;

View File

@ -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 --*/

View File

@ -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)
{