diff options
author | Werner Koch <[email protected]> | 2009-12-02 18:33:59 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2009-12-02 18:33:59 +0000 |
commit | 9e834047519bbaffd54bc20590a4625e9622883e (patch) | |
tree | f8da97c151867fa9350ccfa058b8fcdae03a2183 /sm | |
parent | 2009-11-27 Marcus Brinkmann <[email protected]> (diff) | |
download | gnupg-9e834047519bbaffd54bc20590a4625e9622883e.tar.gz gnupg-9e834047519bbaffd54bc20590a4625e9622883e.zip |
More stuff for the audit-log.
Diffstat (limited to 'sm')
-rw-r--r-- | sm/ChangeLog | 13 | ||||
-rw-r--r-- | sm/decrypt.c | 53 | ||||
-rw-r--r-- | sm/gpgsm.c | 25 | ||||
-rw-r--r-- | sm/sign.c | 52 | ||||
-rw-r--r-- | sm/verify.c | 6 |
5 files changed, 123 insertions, 26 deletions
diff --git a/sm/ChangeLog b/sm/ChangeLog index 80235db78..167316330 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,16 @@ +2009-12-02 Werner Koch <[email protected]> + + * verify.c (gpgsm_verify): Add audit info on hash algorithms. + + * sign.c (gpgsm_sign): Add audit log calls. + (hash_data): Return an error indicator. + +2009-12-01 Werner Koch <[email protected]> + + * decrypt.c (gpgsm_decrypt): Add audit log calls. + + * gpgsm.c: New option --html-audit-log. + 2009-11-25 Marcus Brinkmann <[email protected]> * server.c (gpgsm_server): Use assuan_fd_t and assuan_fdopen on diff --git a/sm/decrypt.c b/sm/decrypt.c index 8fb9f2dfd..de025516f 100644 --- a/sm/decrypt.c +++ b/sm/decrypt.c @@ -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); diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 2d262b707..6e7cd8406 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -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")), @@ -851,6 +853,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; @@ -866,6 +869,7 @@ main ( int argc, char **argv) int do_not_setup_keys = 0; int recp_required = 0; estream_t auditfp = NULL; + estream_t htmlauditfp = NULL; struct assuan_malloc_hooks malloc_hooks; /*mtrace();*/ @@ -1182,6 +1186,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; @@ -1410,11 +1415,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")); @@ -1546,7 +1546,7 @@ main ( int argc, char **argv) /* Prepare the audit log feature for certain commands. */ - if (auditlog) + if (auditlog || htmlauditlog) { switch (cmd) { @@ -1556,7 +1556,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; @@ -1914,12 +1917,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 */ @@ -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"); diff --git a/sm/verify.c b/sm/verify.c index 77517c61f..c8663e3e6 100644 --- a/sm/verify.c +++ b/sm/verify.c @@ -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) { |