1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

Backported some stuff from trunk

This commit is contained in:
Werner Koch 2009-12-03 19:39:39 +00:00
parent 1356693b0d
commit ae7b03d427
13 changed files with 390 additions and 58 deletions

4
NEWS
View File

@ -1,12 +1,14 @@
Noteworthy changes in version 2.0.14
-------------------------------------------------
* The default for --inlucde-cert is now to include all certificates
* The default for --include-cert is now to include all certificates
in the chain except for the root certificate.
* Numerical values may now be used as an alternative to the
debug-level keywords.
* The GPGSM --audit-log feature is now more complete.
Noteworthy changes in version 2.0.13 (2009-09-04)
-------------------------------------------------

View File

@ -1,3 +1,12 @@
2009-12-03 Werner Koch <wk@g10code.com>
From trunk:
* 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-09-03 Werner Koch <wk@g10code.com>
Update from libestream:

View File

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

View File

@ -62,6 +62,12 @@ typedef enum
operations the Dirmngr is not required and thus no such event
will be logged. */
AUDIT_GPG_READY, /* err */
/* Indicates whether the Gpg engine is available. */
AUDIT_GPGSM_READY, /* err */
/* Indicates whether the Gpgsm engine is available. */
AUDIT_GOT_DATA,
/* Data to be processed has been seen. */
@ -72,15 +78,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. */
@ -109,7 +127,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:
@ -121,6 +139,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. */
@ -158,7 +194,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. */

View File

@ -3,6 +3,8 @@
* gpg.c (set_debug): Allow for numerical debug levels. Print
active debug flags.
* gpg.c (gpgconf_list): Add key "default_pubkey_algo".
2009-09-28 Werner Koch <wk@g10code.com>
* trustdb.c (get_validity_info): Take care of a NULL PK. Fixes

View File

@ -1613,6 +1613,11 @@ gpgconf_list (const char *configfile)
printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT);
printf ("group:%lu:\n", GC_OPT_FLAG_NONE);
/* The next one is an info only item and should match what
keygen:ask_keysize actually implements. */
printf ("default_pubkey_algo:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT,
"RSA-2048");
xfree (configfile_esc);
}

View File

@ -1765,6 +1765,8 @@ ask_algo (int addmode, int *r_subkey_algo, unsigned int *r_usage)
static unsigned
ask_keysize (int algo, unsigned int primary_keysize)
{
/* NOTE: If you change the default key size/algo, remember to change
it also in gpg.c:gpgconf_list. */
unsigned int nbits, min, def=2048, max=4096;
int for_subkey = !!primary_keysize;
int autocomp = 0;

View File

@ -1,3 +1,18 @@
2009-12-03 Werner Koch <wk@g10code.com>
From trunk:
* verify.c (gpgsm_verify): Add audit info on hash algorithms.
* sign.c (gpgsm_sign): Add audit log calls.
(hash_data): Return an error indicator.
* decrypt.c (gpgsm_decrypt): Add audit log calls.
* gpgsm.c: New option --html-audit-log.
* certreqgen.c (proc_parameters): Change fallback key length to
2048.
* gpgsm.c (main) <aGpgConfList>: Add key "default_pubkey_algo".
2009-12-03 Werner Koch <wk@g10code.com>
* gpgsm.c (set_debug): Allow for numerical debug levels. Print

View File

@ -61,7 +61,7 @@ The format of the native parameter file is follows:
This is a required parameter. For now the only supported
algorithm is "rsa".
Key-Length: <length-in-bits>
Length of the key in bits. Default is 1024.
Length of the key in bits. Default is 2048.
Key-Grip: hexstring
This is optional and used to generate a request for an already
existing key. Key-Length will be ignored when given,
@ -83,7 +83,7 @@ Here is an example:
$ cat >foo <<EOF
%echo Generating a standard key
Key-Type: RSA
Key-Length: 1024
Key-Length: 2048
Name-DN: CN=test cert 1,OU=Aegypten Project,O=g10 Code GmbH,L=Düsseldorf,C=DE
Name-Email: joe@foo.bar
# Do a commit here, so that we can later print "done" :-)
@ -477,7 +477,7 @@ proc_parameters (ctrl_t ctrl,
/* Check the keylength. */
if (!get_parameter (para, pKEYLENGTH, 0))
nbits = 1024;
nbits = 2048;
else
nbits = get_parameter_uint (para, pKEYLENGTH);
if ((nbits < 1024 || nbits > 4096) && !cardkeyid)

View File

@ -253,6 +253,8 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp)
memset (&dfparm, 0, sizeof dfparm);
audit_set_type (ctrl->audit, AUDIT_TYPE_DECRYPT);
kh = keydb_new (0);
if (!kh)
{
@ -296,6 +298,8 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp)
goto leave;
}
audit_log (ctrl->audit, AUDIT_SETUP_READY);
/* Parser loop. */
do
{
@ -313,6 +317,8 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp)
const char *algoid;
int any_key = 0;
audit_log (ctrl->audit, AUDIT_GOT_DATA);
algoid = ksba_cms_get_content_oid (cms, 2/* encryption algo*/);
algo = gcry_cipher_map_name (algoid);
mode = gcry_cipher_mode_from_oid (algoid);
@ -330,6 +336,7 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp)
sprintf (numbuf, "%d", rc);
gpgsm_status2 (ctrl, STATUS_ERROR, "decrypt.algorithm",
numbuf, algoid?algoid:"?", NULL);
audit_log_s (ctrl->audit, AUDIT_BAD_DATA_CIPHER_ALGO, algoid);
}
/* If it seems that this is not an encrypted message we
@ -339,6 +346,8 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp)
goto leave;
}
audit_log_i (ctrl->audit, AUDIT_DATA_CIPHER_ALGO, algo);
dfparm.algo = algo;
dfparm.mode = mode;
dfparm.blklen = gcry_cipher_get_algo_blklen (algo);
@ -369,6 +378,7 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp)
rc = ksba_cms_get_issuer_serial (cms, recp, &issuer, &serial);
if (rc == -1 && recp)
break; /* no more recipients */
audit_log_i (ctrl->audit, AUDIT_NEW_RECP, recp);
if (rc)
log_error ("recp %d - error getting info: %s\n",
recp, gpg_strerror (rc));
@ -382,6 +392,13 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp)
gpgsm_dump_serial (serial);
log_printf ("\n");
if (ctrl->audit)
{
char *tmpstr = gpgsm_format_sn_issuer (serial, issuer);
audit_log_s (ctrl->audit, AUDIT_RECP_NAME, tmpstr);
xfree (tmpstr);
}
keydb_search_reset (kh);
rc = keydb_search_issuer_sn (kh, issuer, serial);
if (rc)
@ -415,6 +432,8 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp)
kidbuf, "0", "0", NULL);
}
/* Put the certificate into the audit log. */
audit_log_cert (ctrl->audit, AUDIT_SAVE_CERT, cert, 0);
/* Just in case there is a problem with the own
certificate we print this message - should never
@ -462,10 +481,41 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp)
decrypt_filter,
&dfparm);
}
audit_log_ok (ctrl->audit, AUDIT_RECP_RESULT, rc);
}
xfree (hexkeygrip);
xfree (desc);
}
/* If we write an audit log add the unused recipients to the
log as well. */
if (ctrl->audit && any_key)
{
for (;; recp++)
{
char *issuer;
ksba_sexp_t serial;
int tmp_rc;
tmp_rc = ksba_cms_get_issuer_serial (cms, recp,
&issuer, &serial);
if (tmp_rc == -1)
break; /* no more recipients */
audit_log_i (ctrl->audit, AUDIT_NEW_RECP, recp);
if (tmp_rc)
log_error ("recp %d - error getting info: %s\n",
recp, gpg_strerror (rc));
else
{
char *tmpstr = gpgsm_format_sn_issuer (serial, issuer);
audit_log_s (ctrl->audit, AUDIT_RECP_NAME, tmpstr);
xfree (tmpstr);
xfree (issuer);
xfree (serial);
}
}
}
if (!any_key)
{
rc = gpg_error (GPG_ERR_NO_SECKEY);
@ -488,7 +538,7 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp)
dfparm.lastblock,
dfparm.blklen - npadding);
if (rc)
goto leave;
goto leave;
for (i=dfparm.blklen - npadding; i < dfparm.blklen; i++)
{
@ -515,6 +565,7 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp)
leave:
audit_log_ok (ctrl->audit, AUDIT_DECRYPTION_RESULT, rc);
if (rc)
{
gpgsm_status (ctrl, STATUS_DECRYPTION_FAILED, NULL);

View File

@ -99,6 +99,7 @@ enum cmd_and_opt_values {
oLogFile,
oNoLogFile,
oAuditLog,
oHtmlAuditLog,
oEnableSpecialFilenames,
@ -286,6 +287,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_s (oAuditLog, "audit-log",
N_("|FILE|write an audit log to FILE")),
ARGPARSE_s_s (oHtmlAuditLog, "html-audit-log", ""),
ARGPARSE_s_n (oDryRun, "dry-run", N_("do not make any changes")),
ARGPARSE_s_n (oBatch, "batch", N_("batch mode: never ask")),
ARGPARSE_s_n (oAnswerYes, "yes", N_("assume yes on most questions")),
@ -863,6 +865,7 @@ main ( int argc, char **argv)
int default_keyring = 1;
char *logfile = NULL;
char *auditlog = NULL;
char *htmlauditlog = NULL;
int greeting = 0;
int nogreeting = 0;
int debug_wait = 0;
@ -878,6 +881,7 @@ main ( int argc, char **argv)
int do_not_setup_keys = 0;
int recp_required = 0;
estream_t auditfp = NULL;
estream_t htmlauditfp = NULL;
/*mtrace();*/
@ -1194,6 +1198,7 @@ main ( int argc, char **argv)
case oNoLogFile: logfile = NULL; break;
case oAuditLog: auditlog = pargs.r.ret_str; break;
case oHtmlAuditLog: htmlauditlog = pargs.r.ret_str; break;
case oBatch:
opt.batch = 1;
@ -1422,11 +1427,6 @@ main ( int argc, char **argv)
}
# endif
if (auditlog)
log_info ("NOTE: The audit log feature (--audit-log) is "
"WORK IN PRORESS and not ready for use!\n");
if (may_coredump && !opt.quiet)
log_info (_("WARNING: program may create a core file!\n"));
@ -1558,7 +1558,7 @@ main ( int argc, char **argv)
/* Prepare the audit log feature for certain commands. */
if (auditlog)
if (auditlog || htmlauditlog)
{
switch (cmd)
{
@ -1568,7 +1568,10 @@ main ( int argc, char **argv)
case aVerify:
audit_release (ctrl.audit);
ctrl.audit = audit_new ();
auditfp = open_es_fwrite (auditlog);
if (auditlog)
auditfp = open_es_fwrite (auditlog);
if (htmlauditlog)
htmlauditfp = open_es_fwrite (htmlauditlog);
break;
default:
break;
@ -1645,6 +1648,10 @@ main ( int argc, char **argv)
printf ("encrypt-to:%lu:\n", GC_OPT_FLAG_DEFAULT);
printf ("keyserver:%lu:\n", GC_OPT_FLAG_NONE);
/* The next one is an info only item and should match what
proc_parameters actually implements. */
printf ("default_pubkey_algo:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT,
"RSA-2048");
}
break;
case aGPGConfTest:
@ -1920,12 +1927,16 @@ main ( int argc, char **argv)
}
/* Print the audit result if needed. */
if (auditlog && auditfp)
if ((auditlog && auditfp) || (htmlauditlog && htmlauditfp))
{
audit_print_result (ctrl.audit, auditfp, 0);
if (auditlog && auditfp)
audit_print_result (ctrl.audit, auditfp, 0);
if (htmlauditlog && htmlauditfp)
audit_print_result (ctrl.audit, htmlauditfp, 1);
audit_release (ctrl.audit);
ctrl.audit = NULL;
es_fclose (auditfp);
es_fclose (htmlauditfp);
}
/* cleanup */

View File

@ -34,18 +34,20 @@
#include "i18n.h"
static void
/* Hash the data and return if something was hashed. Return -1 on error. */
static int
hash_data (int fd, gcry_md_hd_t md)
{
FILE *fp;
char buffer[4096];
int nread;
int rc = 0;
fp = fdopen ( dup (fd), "rb");
if (!fp)
{
log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno));
return;
return -1;
}
do
@ -55,8 +57,12 @@ hash_data (int fd, gcry_md_hd_t md)
}
while (nread);
if (ferror (fp))
{
log_error ("read error on fd %d: %s\n", fd, strerror (errno));
rc = -1;
}
fclose (fp);
return rc;
}
static int
@ -321,6 +327,8 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
certlist_t cl;
int release_signerlist = 0;
audit_set_type (ctrl->audit, AUDIT_TYPE_SIGN);
kh = keydb_new (0);
if (!kh)
{
@ -539,8 +547,11 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
goto leave;
}
gcry_md_enable (data_md, algo);
audit_log_i (ctrl->audit, AUDIT_DATA_HASH_ALGO, algo);
}
audit_log (ctrl->audit, AUDIT_SETUP_READY);
if (detached)
{ /* We hash the data right now so that we can store the message
digest. ksba_cms_build() takes this as an flag that detached
@ -548,7 +559,8 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
unsigned char *digest;
size_t digest_len;
hash_data (data_fd, data_md);
if (!hash_data (data_fd, data_md))
audit_log (ctrl->audit, AUDIT_GOT_DATA);
for (cl=signerlist,signer=0; cl; cl = cl->next, signer++)
{
digest = gcry_md_read (data_md, cl->hash_algo);
@ -623,6 +635,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
rc = hash_and_copy_data (data_fd, data_md, writer);
if (rc)
goto leave;
audit_log (ctrl->audit, AUDIT_GOT_DATA);
for (cl=signerlist,signer=0; cl; cl = cl->next, signer++)
{
digest = gcry_md_read (data_md, cl->hash_algo);
@ -663,13 +676,18 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
unsigned char *sigval = NULL;
char *buf, *fpr;
audit_log_i (ctrl->audit, AUDIT_NEW_SIG, signer);
if (signer)
gcry_md_reset (md);
{
certlist_t cl_tmp;
for (cl_tmp=signerlist; cl_tmp; cl_tmp = cl_tmp->next)
gcry_md_enable (md, cl_tmp->hash_algo);
{
gcry_md_enable (md, cl_tmp->hash_algo);
audit_log_i (ctrl->audit, AUDIT_ATTR_HASH_ALGO,
cl_tmp->hash_algo);
}
}
rc = ksba_cms_hash_signed_attrs (cms, signer);
@ -685,6 +703,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
md, cl->hash_algo, &sigval);
if (rc)
{
audit_log_cert (ctrl->audit, AUDIT_SIGNED_BY, cl->cert, rc);
gcry_md_close (md);
goto leave;
}
@ -693,6 +712,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
xfree (sigval);
if (err)
{
audit_log_cert (ctrl->audit, AUDIT_SIGNED_BY, cl->cert, err);
log_error ("failed to store the signature: %s\n",
gpg_strerror (err));
rc = err;
@ -708,28 +728,29 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
gcry_md_close (md);
goto leave;
}
rc = 0;
{
int pkalgo = gpgsm_get_key_algo_info (cl->cert, NULL);
rc = asprintf (&buf, "%c %d %d 00 %s %s",
detached? 'D':'S',
pkalgo,
cl->hash_algo,
signed_at,
fpr);
buf = xtryasprintf ("%c %d %d 00 %s %s",
detached? 'D':'S',
pkalgo,
cl->hash_algo,
signed_at,
fpr);
if (!buf)
rc = gpg_error_from_syserror ();
}
xfree (fpr);
if (rc < 0)
if (rc)
{
rc = gpg_error (GPG_ERR_ENOMEM);
gcry_md_close (md);
goto leave;
}
rc = 0;
gpgsm_status (ctrl, STATUS_SIG_CREATED, buf);
free (buf); /* yes, we must use the regular free() here */
xfree (buf);
audit_log_cert (ctrl->audit, AUDIT_SIGNED_BY, cl->cert, 0);
}
gcry_md_close (md);
}
}
while (stopreason != KSBA_SR_READY);
@ -741,6 +762,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
goto leave;
}
audit_log (ctrl->audit, AUDIT_SIGNING_DONE);
log_info ("signature created\n");

View File

@ -216,6 +216,8 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
log_debug ("enabling extra hash algorithm %d\n",
opt.extra_digest_algo);
gcry_md_enable (data_md, opt.extra_digest_algo);
audit_log_i (ctrl->audit, AUDIT_DATA_HASH_ALGO,
opt.extra_digest_algo);
}
if (is_detached)
{
@ -236,7 +238,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
}
else if (stopreason == KSBA_SR_END_DATA)
{ /* The data bas been hashed */
audit_log_ok (ctrl->audit, AUDIT_DATA_HASHING, 0);
}
}
while (stopreason != KSBA_SR_READY);
@ -452,6 +454,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
log_printf (_(" using certificate ID 0x%08lX\n"),
gpgsm_get_short_fingerprint (cert, NULL));
audit_log_i (ctrl->audit, AUDIT_DATA_HASH_ALGO, algo);
if (msgdigest)
{ /* Signed attributes are available. */
@ -484,6 +487,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
goto next_signer;
}
audit_log_i (ctrl->audit, AUDIT_ATTR_HASH_ALGO, sigval_hash_algo);
rc = gcry_md_open (&md, sigval_hash_algo, 0);
if (rc)
{