aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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
4 files changed, 114 insertions, 11 deletions
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 --*/