summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2009-12-02 19:33:59 +0100
committerWerner Koch <wk@gnupg.org>2009-12-02 19:33:59 +0100
commit9e834047519bbaffd54bc20590a4625e9622883e (patch)
treef8da97c151867fa9350ccfa058b8fcdae03a2183 /common
parent2009-11-27 Marcus Brinkmann <marcus@g10code.de> (diff)
downloadgnupg2-9e834047519bbaffd54bc20590a4625e9622883e.tar.xz
gnupg2-9e834047519bbaffd54bc20590a4625e9622883e.zip
More stuff for the audit-log.
Diffstat (limited to 'common')
-rw-r--r--common/ChangeLog8
-rw-r--r--common/audit.c214
-rw-r--r--common/audit.h45
3 files changed, 239 insertions, 28 deletions
diff --git a/common/ChangeLog b/common/ChangeLog
index a519f3850..60157680d 100644
--- a/common/ChangeLog
+++ b/common/ChangeLog
@@ -1,3 +1,11 @@
+2009-12-02 Werner Koch <wk@g10code.com>
+
+ * audit.c (proc_type_decrypt, proc_type_sign): Implemented.
+ (proc_type_verify): Print hash algo infos.
+ * audit.h (AUDIT_DATA_CIPHER_ALGO, AUDIT_BAD_DATA_CIPHER_ALSO)
+ (AUDIT_NEW_RECP, AUDIT_DECRYPTION_RESULT, AUDIT_RECP_RESULT)
+ (AUDIT_ATTR_HASH_ALGO, AUDIT_SIGNED_BY, AUDIT_SIGNING_DONE):
+
2009-11-05 Marcus Brinkmann <marcus@g10code.de>
* asshelp.c (start_new_gpg_agent): Update use of
diff --git a/common/audit.c b/common/audit.c
index 436f0d25d..02a0a2b22 100644
--- a/common/audit.c
+++ b/common/audit.c
@@ -1,5 +1,5 @@
/* audit.c - GnuPG's audit subsystem
- * Copyright (C) 2007 Free Software Foundation, Inc.
+ * Copyright (C) 2007, 2009 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -42,7 +42,7 @@ struct log_item_s
{
audit_event_t event; /* The event. */
gpg_error_t err; /* The logged error code. */
- int intvalue; /* A logged interger value. */
+ int intvalue; /* A logged integer value. */
char *string; /* A malloced string or NULL. */
ksba_cert_t cert; /* A certifciate or NULL. */
int have_err:1;
@@ -483,6 +483,14 @@ writeout_li (audit_ctx_t ctx, const char *oktext, const char *format, ...)
oktext = _("|audit-log-result|Not enabled");
else if (!strcmp (oktext, "error"))
oktext = _("|audit-log-result|Error");
+ else if (!strcmp (oktext, "not-used"))
+ oktext = _("|audit-log-result|Not used");
+ else if (!strcmp (oktext, "okay"))
+ oktext = _("|audit-log-result|Okay");
+ else if (!strcmp (oktext, "skipped"))
+ oktext = _("|audit-log-result|Skipped");
+ else if (!strcmp (oktext, "some"))
+ oktext = _("|audit-log-result|Some");
else
s = "";
@@ -806,16 +814,72 @@ proc_type_encrypt (audit_ctx_t ctx)
static void
proc_type_sign (audit_ctx_t ctx)
{
- log_item_t item;
+ log_item_t item, loopitem;
+ int signer, idx;
+ const char *result;
+ ksba_cert_t cert;
+ char *name;
+ int lastalgo;
- item = NULL;
+ item = find_log_item (ctx, AUDIT_SIGNING_DONE, 0);
writeout_li (ctx, item?"Yes":"No", "%s", _("Data signing succeeded"));
enter_li (ctx);
item = find_log_item (ctx, AUDIT_GOT_DATA, 0);
writeout_li (ctx, item? "Yes":"No", "%s", _("Data available"));
+ /* Write remarks with the data hash algorithms. We use a very
+ simple scheme to avoid some duplicates. */
+ loopitem = NULL;
+ lastalgo = 0;
+ while ((loopitem = find_next_log_item
+ (ctx, loopitem, AUDIT_DATA_HASH_ALGO, AUDIT_NEW_SIG)))
+ {
+ if (loopitem->intvalue && loopitem->intvalue != lastalgo)
+ writeout_rem (ctx, _("data hash algorithm: %s"),
+ gcry_md_algo_name (loopitem->intvalue));
+ lastalgo = loopitem->intvalue;
+ }
+ /* Loop over all signer. */
+ loopitem = NULL;
+ signer = 0;
+ while ((loopitem=find_next_log_item (ctx, loopitem, AUDIT_NEW_SIG, 0)))
+ {
+ signer++;
+
+ item = find_next_log_item (ctx, loopitem, AUDIT_SIGNED_BY, AUDIT_NEW_SIG);
+ if (!item)
+ result = "error";
+ else if (!item->err)
+ result = "okay";
+ else if (gpg_err_code (item->err) == GPG_ERR_CANCELED)
+ result = "skipped";
+ else
+ result = gpg_strerror (item->err);
+ cert = item? item->cert : NULL;
+
+ writeout_li (ctx, result, _("Signer %d"), signer);
+ item = find_next_log_item (ctx, loopitem,
+ AUDIT_ATTR_HASH_ALGO, AUDIT_NEW_SIG);
+ if (item)
+ writeout_rem (ctx, _("attr hash algorithm: %s"),
+ gcry_md_algo_name (item->intvalue));
+
+ if (cert)
+ {
+ name = get_cert_name (cert);
+ writeout_rem (ctx, "%s", name);
+ xfree (name);
+ enter_li (ctx);
+ for (idx=0; (name = get_cert_subject (cert, idx)); idx++)
+ {
+ writeout_rem (ctx, "%s", name);
+ xfree (name);
+ }
+ leave_li (ctx);
+ }
+ }
leave_li (ctx);
}
@@ -826,16 +890,87 @@ proc_type_sign (audit_ctx_t ctx)
static void
proc_type_decrypt (audit_ctx_t ctx)
{
- log_item_t item;
+ log_item_t loopitem, item;
+ int algo, recpno;
+ char *name;
+ char numbuf[35];
+ int idx;
- item = NULL;
- writeout_li (ctx, item?"Yes":"No", "%s", _("Data decryption succeeded"));
+ item = find_log_item (ctx, AUDIT_DECRYPTION_RESULT, 0);
+ writeout_li (ctx, item && !item->err?"Yes":"No",
+ "%s", _("Data decryption succeeded"));
enter_li (ctx);
item = find_log_item (ctx, AUDIT_GOT_DATA, 0);
writeout_li (ctx, item? "Yes":"No", "%s", _("Data available"));
+ item = find_log_item (ctx, AUDIT_DATA_CIPHER_ALGO, 0);
+ algo = item? item->intvalue : 0;
+ writeout_li (ctx, algo?"Yes":"No", "%s", _("Encryption algorithm supported"));
+ if (algo)
+ writeout_rem (ctx, _("algorithm: %s"), gcry_cipher_algo_name (algo));
+
+ item = find_log_item (ctx, AUDIT_BAD_DATA_CIPHER_ALGO, 0);
+ if (item && item->string)
+ {
+ algo = gcry_cipher_map_name (item->string);
+ if (algo)
+ writeout_rem (ctx, _("algorithm: %s"), gcry_cipher_algo_name (algo));
+ else if (item->string && !strcmp (item->string, "1.2.840.113549.3.2"))
+ writeout_rem (ctx, _("unsupported algorithm: %s"), "RC2");
+ else if (item->string)
+ writeout_rem (ctx, _("unsupported algorithm: %s"), item->string);
+ else
+ writeout_rem (ctx, _("seems to be not encrypted"));
+ }
+
+
+ for (recpno = 0, item = NULL;
+ (item = find_next_log_item (ctx, item, AUDIT_NEW_RECP, 0)); recpno++)
+ ;
+ snprintf (numbuf, sizeof numbuf, "%d", recpno);
+ writeout_li (ctx, numbuf, "%s", _("Number of recipients"));
+
+ /* Loop over all recipients. */
+ loopitem = NULL;
+ while ((loopitem = find_next_log_item (ctx, loopitem, AUDIT_NEW_RECP, 0)))
+ {
+ const char *result;
+
+ recpno = loopitem->have_intvalue? loopitem->intvalue : -1;
+
+ item = find_next_log_item (ctx, loopitem,
+ AUDIT_RECP_RESULT, AUDIT_NEW_RECP);
+ if (!item)
+ result = "not-used";
+ else if (!item->err)
+ result = "okay";
+ else if (gpg_err_code (item->err) == GPG_ERR_CANCELED)
+ result = "skipped";
+ else
+ result = gpg_strerror (item->err);
+
+ item = find_next_log_item (ctx, loopitem,
+ AUDIT_RECP_NAME, AUDIT_NEW_RECP);
+ writeout_li (ctx, result, _("Recipient %d"), recpno);
+ if (item && item->string)
+ writeout_rem (ctx, "%s", item->string);
+
+ /* If we have a certificate write out more infos. */
+ item = find_next_log_item (ctx, loopitem,
+ AUDIT_SAVE_CERT, AUDIT_NEW_RECP);
+ if (item && item->cert)
+ {
+ enter_li (ctx);
+ for (idx=0; (name = get_cert_subject (item->cert, idx)); idx++)
+ {
+ writeout_rem (ctx, "%s", name);
+ xfree (name);
+ }
+ leave_li (ctx);
+ }
+ }
leave_li (ctx);
}
@@ -847,11 +982,12 @@ static void
proc_type_verify (audit_ctx_t ctx)
{
log_item_t loopitem, item;
- int signo, count, idx;
+ int signo, count, idx, n_good, n_bad;
char numbuf[35];
+ const char *result;
/* If there is at least one signature status we claim that the
- verifciation succeeded. This does not mean that the data has
+ verification succeeded. This does not mean that the data has
verified okay. */
item = find_log_item (ctx, AUDIT_SIG_STATUS, 0);
writeout_li (ctx, item?"Yes":"No", "%s", _("Data verification succeeded"));
@@ -867,17 +1003,41 @@ proc_type_verify (audit_ctx_t ctx)
if (!item)
goto leave;
- item = find_log_item (ctx, AUDIT_DATA_HASH_ALGO, AUDIT_NEW_SIG);
- writeout_li (ctx, item?"Yes":"No", "%s", _("Parsing signature succeeded"));
- if (!item)
+ /* Print info about the used data hashing algorithms. */
+ for (idx=0, n_good=n_bad=0; idx < ctx->logused; idx++)
{
- item = find_log_item (ctx, AUDIT_BAD_DATA_HASH_ALGO, AUDIT_NEW_SIG);
- if (item)
- writeout_rem (ctx, _("Bad hash algorithm: %s"),
- item->string? item->string:"?");
-
- goto leave;
+ item = ctx->log + idx;
+ if (item->event == AUDIT_NEW_SIG)
+ break;
+ else if (item->event == AUDIT_DATA_HASH_ALGO)
+ n_good++;
+ else if (item->event == AUDIT_BAD_DATA_HASH_ALGO)
+ n_bad++;
}
+ item = find_log_item (ctx, AUDIT_DATA_HASHING, AUDIT_NEW_SIG);
+ if (!item || item->err || !n_good)
+ result = "No";
+ else if (n_good && !n_bad)
+ result = "Yes";
+ else
+ result = "Some";
+ writeout_li (ctx, result, "%s", _("Parsing data succeeded"));
+ if (n_good || n_bad)
+ {
+ for (idx=0; idx < ctx->logused; idx++)
+ {
+ item = ctx->log + idx;
+ if (item->event == AUDIT_NEW_SIG)
+ break;
+ else if (item->event == AUDIT_DATA_HASH_ALGO)
+ writeout_rem (ctx, _("data hash algorithm: %s"),
+ gcry_md_algo_name (item->intvalue));
+ else if (item->event == AUDIT_BAD_DATA_HASH_ALGO)
+ writeout_rem (ctx, _("bad data hash algorithm: %s"),
+ item->string? item->string:"?");
+ }
+ }
+
/* Loop over all signatures. */
loopitem = find_log_item (ctx, AUDIT_NEW_SIG, 0);
@@ -893,6 +1053,18 @@ proc_type_verify (audit_ctx_t ctx)
AUDIT_SIG_NAME, AUDIT_NEW_SIG);
if (item)
writeout_rem (ctx, "%s", item->string);
+
+ item = find_next_log_item (ctx, loopitem,
+ AUDIT_DATA_HASH_ALGO, AUDIT_NEW_SIG);
+ if (item)
+ writeout_rem (ctx, _("data hash algorithm: %s"),
+ gcry_md_algo_name (item->intvalue));
+ item = find_next_log_item (ctx, loopitem,
+ AUDIT_ATTR_HASH_ALGO, AUDIT_NEW_SIG);
+ if (item)
+ writeout_rem (ctx, _("attr hash algorithm: %s"),
+ gcry_md_algo_name (item->intvalue));
+
enter_li (ctx);
/* List the certificate chain. */
@@ -1006,11 +1178,7 @@ audit_print_result (audit_ctx_t ctx, estream_t out, int use_html)
/* We use an environment variable to include some debug info in the
log. */
if ((s = getenv ("gnupg_debug_audit")))
- {
- show_raw = 1;
- if (!strcmp (s, "html"))
- use_html = 1;
- }
+ show_raw = 1;
assert (!ctx->outstream);
ctx->outstream = out;
diff --git a/common/audit.h b/common/audit.h
index 5f5aff419..28d1edbd1 100644
--- a/common/audit.h
+++ b/common/audit.h
@@ -81,15 +81,27 @@ typedef enum
/* A certifciate only signature has been detected. */
AUDIT_DATA_HASH_ALGO, /* int */
- /* The hash algo given as argument is used for this signature.
- This event will be repeated for all hash algorithms used with
- the data. */
+ /* The hash algo given as argument is used for the data. This
+ event will be repeated for all hash algorithms used with the
+ data. */
+
+ AUDIT_ATTR_HASH_ALGO, /* int */
+ /* The hash algo given as argument is used to hash the message
+ digest and other signed attributes of this signature. */
+
+ AUDIT_DATA_CIPHER_ALGO, /* int */
+ /* The cipher algo given as argument is used for this data. */
AUDIT_BAD_DATA_HASH_ALGO, /* string */
/* The hash algo as specified by the signature can't be used.
STRING is the description of this algorithm which usually is an
OID string. STRING may be NULL. */
+ AUDIT_BAD_DATA_CIPHER_ALGO, /* string */
+ /* The symmetric cipher algorithm is not supported. STRING is the
+ description of this algorithm which usually is an OID string.
+ STRING may be NULL. */
+
AUDIT_DATA_HASHING, /* ok_err */
/* Logs the result of the data hashing. */
@@ -118,7 +130,7 @@ typedef enum
certificate used for verification. An example for STRING when
using CMS is: "#1234/CN=Prostetnic Vogon Jeltz". */
- AUDIT_SIG_STATUS, /* string */
+ AUDIT_SIG_STATUS, /* string */
/* The signature status of the current signer. This is the last
audit information for one signature. STRING gives the status:
@@ -130,6 +142,24 @@ typedef enum
"good" - good signature
*/
+ AUDIT_NEW_RECP, /* int */
+ /* A new recipient has been seen during decryption. The argument
+ is the recipient number as used internally by the program. */
+
+ AUDIT_RECP_NAME, /* string */
+ /* The name of a recipient. This is the name or other identification
+ data as known from the decryption and not the name from the
+ certificate used for decryption. An example for STRING when
+ using CMS is: "#1234/CN=Prostetnic Vogon Jeltz". */
+
+ AUDIT_RECP_RESULT, /* ok_err */
+ /* The status of the session key decryption. This is only written
+ for recipients tried. */
+
+ AUDIT_DECRYPTION_RESULT, /* ok_err */
+ /* The status of the entire decryption. The decryption was
+ successful if the error code is 0. */
+
AUDIT_VALIDATE_CHAIN,
/* Start the validation of a certificate chain. */
@@ -167,7 +197,12 @@ typedef enum
AUDIT_ENCRYPTION_DONE,
/* Encryption succeeded. */
-
+ AUDIT_SIGNED_BY, /* cert, err */
+ /* Records the certificate used for signed and whether the signure
+ could be created (if err==0). */
+
+ AUDIT_SIGNING_DONE,
+ /* Signing succeeded. */
AUDIT_LAST_EVENT /* Marker for parsing this list. */