diff --git a/sm/ChangeLog b/sm/ChangeLog index 5c6c5eb42..88d9763c8 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,14 @@ +2005-11-23 Werner Koch + + * gpgsm.h: New member QUALSIG_APPROVAL. + * sign.c (gpgsm_sign): Print a warning if a certificate is not + qualified. + * qualified.c (gpgsm_qualified_consent): Include a note that this + is not approved software. + (gpgsm_not_qualified_warning): New. + * gpgsm.c (main): Prepared to print a note whether the software + has been approved. + 2005-11-13 Werner Koch * call-agent.c (gpgsm_agent_get_confirmation): New. diff --git a/sm/call-agent.c b/sm/call-agent.c index 03a3a2e3f..9942672ae 100644 --- a/sm/call-agent.c +++ b/sm/call-agent.c @@ -701,7 +701,6 @@ gpg_error_t gpgsm_agent_get_confirmation (ctrl_t ctrl, const char *desc) { int rc; - char *fpr; char line[ASSUAN_LINELENGTH]; rc = start_agent (ctrl); diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 0f9745a8c..7347bf575 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -1220,6 +1220,11 @@ main ( int argc, char **argv) if (may_coredump && !opt.quiet) log_info (_("WARNING: program may create a core file!\n")); +/* if (opt.qualsig_approval && !opt.quiet) */ +/* log_info (_("This software has offically been approved to " */ +/* "create and verify\n" */ +/* "qualified signatures according to German law.\n")); */ + if (logfile && cmd == aServer) { log_set_file (logfile); diff --git a/sm/gpgsm.h b/sm/gpgsm.h index 52eff359a..dc863f682 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -108,6 +108,13 @@ struct { char *fixed_passphrase; /* Passphrase used by regression tests. */ int auto_issuer_key_retrieve; /* try to retrieve a missing issuer key. */ + + int qualsig_approval; /* Set to true if this software has + officially been approved to create an + verify qualified signatures. This is a + runtime option in case we want to check + the integrity of the software at + runtime. */ } opt; @@ -291,6 +298,7 @@ int gpgsm_genkey (ctrl_t ctrl, int in_fd, FILE *out_fp); /*-- qualified.c --*/ gpg_error_t gpgsm_is_in_qualified_list (ctrl_t ctrl, ksba_cert_t cert); gpg_error_t gpgsm_qualified_consent (ctrl_t ctrl, ksba_cert_t cert); +gpg_error_t gpgsm_not_qualified_warning (ctrl_t ctrl, ksba_cert_t cert); /*-- call-agent.c --*/ int gpgsm_agent_pksign (ctrl_t ctrl, const char *keygrip, const char *desc, diff --git a/sm/qualified.c b/sm/qualified.c index c4bd00f96..4a2b6587f 100644 --- a/sm/qualified.c +++ b/sm/qualified.c @@ -216,9 +216,14 @@ gpgsm_qualified_consent (ctrl_t ctrl, ksba_cert_t cert) "certificate:\n" "\"%s\"\n" "This will create a qualified signature by law " - "equated to a handwritten signature.\n\n" + "equated to a handwritten signature.\n\n%s%s" "Are you really sure that you want to do this?"), - subject? subject:"?" + subject? subject:"?", + opt.qualsig_approval? + "": + "Note that this software is not officially approved " + "to create or verify such signatures.\n", + opt.qualsig_approval? "":"\n" ) < 0 ) err = gpg_error_from_errno (errno); else @@ -257,6 +262,96 @@ gpgsm_qualified_consent (ctrl_t ctrl, ksba_cert_t cert) free (name); + err = gpgsm_agent_get_confirmation (ctrl, buffer); + + xfree (buffer); + return err; +} + + +/* Popup a prompt to inform the user that the signature created is not + a qualified one. This is of course only doen if we know that we + have been approved. */ +gpg_error_t +gpgsm_not_qualified_warning (ctrl_t ctrl, ksba_cert_t cert) +{ + gpg_error_t err; + char *name, *subject, *buffer, *p; + const char *s; + char *orig_codeset = NULL; + + if (!opt.qualsig_approval) + return 0; + + name = ksba_cert_get_subject (cert, 0); + if (!name) + return gpg_error (GPG_ERR_GENERAL); + subject = gpgsm_format_name2 (name, 0); + ksba_free (name); name = NULL; + + +#ifdef ENABLE_NLS + /* The Assuan agent protocol requires us to transmit utf-8 strings */ + orig_codeset = bind_textdomain_codeset (PACKAGE_GT, NULL); +#ifdef HAVE_LANGINFO_CODESET + if (!orig_codeset) + orig_codeset = nl_langinfo (CODESET); +#endif + if (orig_codeset) + { /* We only switch when we are able to restore the codeset later. + Note that bind_textdomain_codeset does only return on memory + errors but not if a codeset is not available. Thus we don't + bother printing a diagnostic here. */ + orig_codeset = xstrdup (orig_codeset); + if (!bind_textdomain_codeset (PACKAGE_GT, "utf-8")) + orig_codeset = NULL; + } +#endif + + if (asprintf (&name, + _("You are about to create a signature using your " + "certificate:\n" + "\"%s\"\n" + "Note, that this certificate will NOT create a " + "qualified signature!"), + subject? subject:"?") < 0 ) + err = gpg_error_from_errno (errno); + else + err = 0; + +#ifdef ENABLE_NLS + if (orig_codeset) + bind_textdomain_codeset (PACKAGE_GT, orig_codeset); +#endif + xfree (orig_codeset); + xfree (subject); + + if (err) + return err; + + buffer = p = xtrymalloc (strlen (name) * 3 + 1); + if (!buffer) + { + err = gpg_error_from_errno (errno); + free (name); + return err; + } + for (s=name; *s; s++) + { + if (*s < ' ' || *s == '+') + { + sprintf (p, "%%%02X", *(unsigned char *)s); + p += 3; + } + else if (*s == ' ') + *p++ = '+'; + else + *p++ = *s; + } + *p = 0; + free (name); + + err = gpgsm_agent_get_confirmation (ctrl, buffer); xfree (buffer); diff --git a/sm/sign.c b/sm/sign.c index d9a332c9a..74bfe41aa 100644 --- a/sm/sign.c +++ b/sm/sign.c @@ -446,13 +446,13 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist, goto leave; } if (*buffer) + err = gpgsm_qualified_consent (ctrl, cl->cert); + else + err = gpgsm_not_qualified_warning (ctrl, cl->cert); + if (err) { - err = gpgsm_qualified_consent (ctrl, cl->cert); - if (err) - { - rc = err; - goto leave; - } + rc = err; + goto leave; } }