summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2018-04-17 13:48:56 +0200
committerWerner Koch <wk@gnupg.org>2018-04-17 13:48:56 +0200
commit01435da498af9f7538d7ee810392d7eaa407957e (patch)
tree8a9515130220ecdf058c85fcf9ce24e88618872c
parent3589da0500f1c80717e658d103a0cb2751d27b49 (diff)
downloadgpgme-01435da498af9f7538d7ee810392d7eaa407957e.tar.gz
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>
-rw-r--r--NEWS1
-rw-r--r--doc/gpgme.texi7
-rw-r--r--src/conversion.c46
-rw-r--r--src/decrypt.c70
-rw-r--r--src/gpgme.h.in4
-rw-r--r--src/util.h5
-rw-r--r--tests/run-decrypt.c1
7 files changed, 123 insertions, 11 deletions
diff --git a/NEWS b/NEWS
index 162212cf..92a96732 100644
--- a/NEWS
+++ b/NEWS
@@ -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;
diff --git a/src/util.h b/src/util.h
index b4043ed1..da929eb4 100644
--- a/src/util.h
+++ b/src/util.h
@@ -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)
{