[svn] GnuPG - r3934 - branches/GNUPG-1-9-BRANCH/sm
svn author wk
cvs at cvs.gnupg.org
Sun Nov 13 20:07:08 CET 2005
Author: wk
Date: 2005-11-13 20:07:06 +0100 (Sun, 13 Nov 2005)
New Revision: 3934
Added:
branches/GNUPG-1-9-BRANCH/sm/qualified.c
Modified:
branches/GNUPG-1-9-BRANCH/sm/ChangeLog
branches/GNUPG-1-9-BRANCH/sm/Makefile.am
branches/GNUPG-1-9-BRANCH/sm/call-agent.c
branches/GNUPG-1-9-BRANCH/sm/call-dirmngr.c
branches/GNUPG-1-9-BRANCH/sm/certchain.c
branches/GNUPG-1-9-BRANCH/sm/certcheck.c
branches/GNUPG-1-9-BRANCH/sm/certdump.c
branches/GNUPG-1-9-BRANCH/sm/gpgsm.h
branches/GNUPG-1-9-BRANCH/sm/keylist.c
branches/GNUPG-1-9-BRANCH/sm/sign.c
branches/GNUPG-1-9-BRANCH/sm/verify.c
Log:
Added qualified signature features.
Modified: branches/GNUPG-1-9-BRANCH/sm/ChangeLog
===================================================================
--- branches/GNUPG-1-9-BRANCH/sm/ChangeLog 2005-11-13 19:05:00 UTC (rev 3933)
+++ branches/GNUPG-1-9-BRANCH/sm/ChangeLog 2005-11-13 19:07:06 UTC (rev 3934)
@@ -1,3 +1,29 @@
+2005-11-13 Werner Koch <wk at g10code.com>
+
+ * call-agent.c (gpgsm_agent_get_confirmation): New.
+
+ * keylist.c (list_cert_std): Print qualified status.
+ * qualified.c: New.
+ * certchain.c (gpgsm_validate_chain): Check for qualified
+ certificates.
+
+ * certchain.c (gpgsm_basic_cert_check): Release keydb handle when
+ no-chain-validation is used.
+
+2005-11-11 Werner Koch <wk at g10code.com>
+
+ * keylist.c (print_capabilities): Print is_qualified status.
+
+2005-10-28 Werner Koch <wk at g10code.com>
+
+ * certdump.c (pretty_print_sexp): New.
+ (gpgsm_print_name2): Use it here. This allows proper printing of
+ DNS names as used with server certificates.
+
+2005-10-10 Werner Koch <wk at g10code.com>
+
+ * keylist.c: Add pkaAdress OID as reference.
+
2005-10-08 Marcus Brinkmann <marcus at g10code.de>
* Makefile.am (gpgsm_LDADD): Add ../gl/libgnu.a after
@@ -3,4 +29,11 @@
../common/libcommon.a.
+2005-09-13 Werner Koch <wk at g10code.com>
+
+ * verify.c (gpgsm_verify): Print a note if the unknown algorithm
+ is MD2.
+ * sign.c (gpgsm_sign): Ditto.
+ * certcheck.c (gpgsm_check_cert_sig): Ditto.
+
2005-09-08 Werner Koch <wk at g10code.com>
Modified: branches/GNUPG-1-9-BRANCH/sm/Makefile.am
===================================================================
--- branches/GNUPG-1-9-BRANCH/sm/Makefile.am 2005-11-13 19:05:00 UTC (rev 3933)
+++ branches/GNUPG-1-9-BRANCH/sm/Makefile.am 2005-11-13 19:07:06 UTC (rev 3934)
@@ -49,7 +49,8 @@
import.c \
export.c \
delete.c \
- certreqgen.c
+ certreqgen.c \
+ qualified.c
gpgsm_LDADD = ../jnlib/libjnlib.a ../kbx/libkeybox.a \
Modified: branches/GNUPG-1-9-BRANCH/sm/call-agent.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/sm/call-agent.c 2005-11-13 19:05:00 UTC (rev 3933)
+++ branches/GNUPG-1-9-BRANCH/sm/call-agent.c 2005-11-13 19:07:06 UTC (rev 3934)
@@ -693,3 +693,24 @@
return map_assuan_err (rc);
}
+
+
+/* Ask the agent to pop up a confirmation dialog with the text DESC
+ and an okay and cancel button. */
+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);
+ if (rc)
+ return rc;
+
+ snprintf (line, DIM(line)-1, "GET_CONFIRMATION %s", desc);
+ line[DIM(line)-1] = 0;
+
+ rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
+ return map_assuan_err (rc);
+}
Modified: branches/GNUPG-1-9-BRANCH/sm/call-dirmngr.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/sm/call-dirmngr.c 2005-11-13 19:05:00 UTC (rev 3933)
+++ branches/GNUPG-1-9-BRANCH/sm/call-dirmngr.c 2005-11-13 19:07:06 UTC (rev 3934)
@@ -276,7 +276,7 @@
{
size_t n;
- /* Send a certificate where a sourceKeyidentifier is included. */
+ /* Send a certificate where a sourceKeyIdentifier is included. */
line += 12;
while (*line == ' ')
line++;
Modified: branches/GNUPG-1-9-BRANCH/sm/certchain.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/sm/certchain.c 2005-11-13 19:05:00 UTC (rev 3933)
+++ branches/GNUPG-1-9-BRANCH/sm/certchain.c 2005-11-13 19:07:06 UTC (rev 3934)
@@ -643,6 +643,9 @@
int any_no_crl = 0;
int any_crl_too_old = 0;
int any_no_policy_match = 0;
+ int is_qualified = -1; /* Indicates whether the certificate stems
+ from a qualified root certificate.
+ -1 = unknown, 0 = no, 1 = yes. */
int lm = listmode;
gnupg_get_isotime (current_time);
@@ -771,6 +774,53 @@
if (rc)
goto leave;
+
+ /* Set the flag for qualified signatures. This flag is
+ deduced from a list of root certificates allowed for
+ qualified signatures. */
+ if (is_qualified == -1)
+ {
+ gpg_error_t err;
+ size_t buflen;
+ char buf[1];
+
+ if (!ksba_cert_get_user_data (cert, "is_qualified",
+ &buf, sizeof (buf),
+ &buflen) && buflen)
+ {
+ /* We already checked this for this certificate,
+ thus we simply take it from the user data. */
+ is_qualified = !!*buf;
+ }
+ else
+ {
+ /* Need to consult the list of root certificates for
+ qualified signatures. */
+ err = gpgsm_is_in_qualified_list (ctrl, subject_cert);
+ if (!err)
+ is_qualified = 1;
+ else if ( gpg_err_code (err) == GPG_ERR_NOT_FOUND)
+ is_qualified = 0;
+ else
+ log_error ("checking the list of qualified "
+ "root certificates failed: %s\n",
+ gpg_strerror (err));
+ if ( is_qualified != -1 )
+ {
+ /* Cache the result but don't care toomuch about
+ an error. */
+ buf[0] = !!is_qualified;
+ err = ksba_cert_set_user_data (subject_cert,
+ "is_qualified", buf, 1);
+ if (err)
+ log_error ("set_user_data(is_qualified) failed: %s\n",
+ gpg_strerror (err));
+ }
+ }
+ }
+
+
+ /* Check whether we really trust this root certificate. */
rc = gpgsm_agent_istrusted (ctrl, subject_cert);
if (!rc)
;
@@ -968,7 +1018,7 @@
keydb_search_reset (kh);
subject_cert = issuer_cert;
issuer_cert = NULL;
- }
+ } /* End chain traversal. */
if (!listmode)
{
@@ -996,6 +1046,27 @@
}
leave:
+ if (is_qualified != -1)
+ {
+ /* We figured something about the qualified signature capability
+ of the certificate under question. Store the result as user
+ data in the certificate object. We do this even if the
+ validation itself failed. */
+ /* Fixme: We should set this flag for all certificates in the
+ chain for optimizing reasons. */
+ char buf[1];
+ gpg_error_t err;
+
+ buf[0] = !!is_qualified;
+ err = ksba_cert_set_user_data (cert, "is_qualified", buf, 1);
+ if (err)
+ {
+ log_error ("set_user_data(is_qualified) failed: %s\n",
+ gpg_strerror (err));
+ if (!rc)
+ rc = err;
+ }
+ }
if (r_exptime)
gnupg_copy_time (r_exptime, exptime);
xfree (issuer);
@@ -1017,7 +1088,7 @@
int rc = 0;
char *issuer = NULL;
char *subject = NULL;
- KEYDB_HANDLE kh = keydb_new (0);
+ KEYDB_HANDLE kh;
ksba_cert_t issuer_cert = NULL;
if (opt.no_chain_validation)
@@ -1026,6 +1097,7 @@
return 0;
}
+ kh = keydb_new (0);
if (!kh)
{
log_error (_("failed to allocated keyDB handle\n"));
Modified: branches/GNUPG-1-9-BRANCH/sm/certcheck.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/sm/certcheck.c 2005-11-13 19:05:00 UTC (rev 3933)
+++ branches/GNUPG-1-9-BRANCH/sm/certcheck.c 2005-11-13 19:07:06 UTC (rev 3934)
@@ -168,6 +168,10 @@
if (!algo)
{
log_error ("unknown hash algorithm `%s'\n", algoid? algoid:"?");
+ if (algoid
+ && ( !strcmp (algoid, "1.2.840.113549.1.1.2")
+ ||!strcmp (algoid, "1.2.840.113549.2.2")))
+ log_info (_("(this is the MD2 algorithm)\n"));
return gpg_error (GPG_ERR_GENERAL);
}
rc = gcry_md_open (&md, algo, 0);
Modified: branches/GNUPG-1-9-BRANCH/sm/certdump.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/sm/certdump.c 2005-11-13 19:05:00 UTC (rev 3933)
+++ branches/GNUPG-1-9-BRANCH/sm/certdump.c 2005-11-13 19:07:06 UTC (rev 3934)
@@ -484,7 +484,52 @@
}
+/* Print the S-Expression in BUF, which has a valid length of BUFLEN,
+ as a human readable string in one line to FP. */
+static void
+pretty_print_sexp (FILE *fp, const unsigned char *buf, size_t buflen)
+{
+ size_t len;
+ gcry_sexp_t sexp;
+ char *result, *p;
+ if ( gcry_sexp_sscan (&sexp, NULL, (const char*)buf, buflen) )
+ {
+ fputs (_("[Error - invalid encoding]"), fp);
+ return;
+ }
+ len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+ assert (len);
+ result = xtrymalloc (len);
+ if (!result)
+ {
+ fputs (_("[Error - out of core]"), fp);
+ gcry_sexp_release (sexp);
+ return;
+ }
+ len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, result, len);
+ assert (len);
+ for (p = result; len; len--, p++)
+ {
+ if (*p == '\n')
+ {
+ if (len > 1) /* Avoid printing the trailing LF. */
+ fputs ("\\n", fp);
+ }
+ else if (*p == '\r')
+ fputs ("\\r", fp);
+ else if (*p == '\v')
+ fputs ("\\v", fp);
+ else if (*p == '\t')
+ fputs ("\\t", fp);
+ else
+ putc (*p, fp);
+ }
+ xfree (result);
+ gcry_sexp_release (sexp);
+}
+
+
void
gpgsm_print_name2 (FILE *fp, const char *name, int translate)
{
@@ -507,7 +552,9 @@
}
}
else if (*s == '(')
- fputs (_("[Error - unknown encoding]"), fp);
+ {
+ pretty_print_sexp (fp, s, gcry_sexp_canon_len (s, 0, NULL, NULL));
+ }
else if (!((*s >= '0' && *s < '9')
|| (*s >= 'A' && *s <= 'Z')
|| (*s >= 'a' && *s <= 'z')))
@@ -576,7 +623,7 @@
/* Format NAME which is expected to be in rfc2253 format into a better
human readable format. Caller must free the returned string. NULL
is returned in case of an error. With TRANSLATE set to true the
- name will be translated to the native encodig. Note that NAME is
+ name will be translated to the native encoding. Note that NAME is
internally always UTF-8 encoded. */
char *
gpgsm_format_name2 (const char *name, int translate)
@@ -658,7 +705,7 @@
#ifdef ENABLE_NLS
- /* The Assuan agent protol requires us to transmit utf-8 strings */
+ /* 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)
Modified: branches/GNUPG-1-9-BRANCH/sm/gpgsm.h
===================================================================
--- branches/GNUPG-1-9-BRANCH/sm/gpgsm.h 2005-11-13 19:05:00 UTC (rev 3933)
+++ branches/GNUPG-1-9-BRANCH/sm/gpgsm.h 2005-11-13 19:07:06 UTC (rev 3934)
@@ -288,6 +288,10 @@
/*-- certreqgen.c --*/
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);
+
/*-- call-agent.c --*/
int gpgsm_agent_pksign (ctrl_t ctrl, const char *keygrip, const char *desc,
unsigned char *digest,
@@ -306,6 +310,7 @@
int gpgsm_agent_marktrusted (ctrl_t ctrl, ksba_cert_t cert);
int gpgsm_agent_learn (ctrl_t ctrl);
int gpgsm_agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc);
+gpg_error_t gpgsm_agent_get_confirmation (ctrl_t ctrl, const char *desc);
/*-- call-dirmngr.c --*/
int gpgsm_dirmngr_isvalid (ctrl_t ctrl,
Modified: branches/GNUPG-1-9-BRANCH/sm/keylist.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/sm/keylist.c 2005-11-13 19:05:00 UTC (rev 3933)
+++ branches/GNUPG-1-9-BRANCH/sm/keylist.c 2005-11-13 19:07:06 UTC (rev 3934)
@@ -66,6 +66,9 @@
{ "1.3.6.1.5.5.7.3.11", "sbgpCertAAServerAuth" },
{ "1.3.6.1.5.5.7.3.13", "eapOverPPP" },
{ "1.3.6.1.5.5.7.3.14", "wlanSSID" },
+
+ { "2.16.840.1.113730.4.1", "serverGatedCrypto.ns" }, /* Netscape. */
+ { "1.3.6.1.4.1.311.10.3.3", "serverGatedCrypto.ms"}, /* Microsoft. */
{ NULL, NULL }
};
@@ -160,6 +163,9 @@
{ "2.16.840.1.113730.1.12", "netscape-ssl-server-name" },
{ "2.16.840.1.113730.1.13", "netscape-comment" },
+ /* GnuPG extensions */
+ { "1.3.6.1.4.1.11591.2.1.1", "pkaAddress" },
+
{ NULL }
};
@@ -207,7 +213,22 @@
{
gpg_error_t err;
unsigned int use;
+ size_t buflen;
+ char buffer[1];
+ err = ksba_cert_get_user_data (cert, "is_qualified",
+ &buffer, sizeof (buffer), &buflen);
+ if (!err && buflen)
+ {
+ if (*buffer)
+ putc ('q', fp);
+ }
+ else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
+ ; /* Don't know - will not get marked as 'q' */
+ else
+ log_debug ("get_user_data(is_qualified) failed: %s\n",
+ gpg_strerror (err));
+
err = ksba_cert_get_key_usage (cert, &use);
if (gpg_err_code (err) == GPG_ERR_NO_DATA)
{
@@ -1032,9 +1053,28 @@
fprintf (fp, " fingerprint: %s\n", dn?dn:"error");
xfree (dn);
+
+
if (with_validation)
{
+ gpg_error_t tmperr;
+ size_t buflen;
+ char buffer[1];
+
err = gpgsm_validate_chain (ctrl, cert, NULL, 1, fp, 0);
+ tmperr = ksba_cert_get_user_data (cert, "is_qualified",
+ &buffer, sizeof (buffer), &buflen);
+ if (!tmperr && buflen)
+ {
+ if (*buffer)
+ fputs (" [qualified]\n", fp);
+ }
+ else if (gpg_err_code (tmperr) == GPG_ERR_NOT_FOUND)
+ ; /* Don't know - will not get marked as 'q' */
+ else
+ log_debug ("get_user_data(is_qualified) failed: %s\n",
+ gpg_strerror (tmperr));
+
if (!err)
fprintf (fp, " [certificate is good]\n");
else
Added: branches/GNUPG-1-9-BRANCH/sm/qualified.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/sm/qualified.c 2005-11-13 19:05:00 UTC (rev 3933)
+++ branches/GNUPG-1-9-BRANCH/sm/qualified.c 2005-11-13 19:07:06 UTC (rev 3934)
@@ -0,0 +1,264 @@
+/* qualified.c - Routines related to qualified signatures
+ * Copyright (C) 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <errno.h>
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
+#ifdef HAVE_LANGINFO_CODESET
+#include <langinfo.h>
+#endif
+
+#include "gpgsm.h"
+#include "i18n.h"
+#include <ksba.h>
+
+
+/* We open the file only once and keep the open file pointer as well
+ as the name of the file here. Note that, a listname not equal to
+ NULL indicates that this module has been intialized and if the
+ LISTFP is also NULL, no list of qualified signatures exists. */
+static char *listname;
+static FILE *listfp;
+
+
+/* Read the trustlist and return entry by entry. KEY must point to a
+ buffer of at least 41 characters. COUNTRY shall be a buffer of at
+ least 3 characters to receive the country code of that qualified
+ signature (i.e. "de" for German and "be" for Belgium).
+
+ Reading a valid entry returns 0, EOF is indicated by GPG_ERR_EOF
+ and any other error condition is indicated by the appropriate error
+ code. */
+static gpg_error_t
+read_list (char *key, char *country, int *lnr)
+{
+ gpg_error_t err;
+ int c, i, j;
+ char *p, line[256];
+
+ *key = 0;
+ *country = 0;
+
+ if (!listname)
+ {
+ listname = make_filename (GNUPG_DATADIR, "qualified.txt", NULL);
+ listfp = fopen (listname, "r");
+ if (!listfp && errno != ENOENT)
+ {
+ err = gpg_error_from_errno (errno);
+ log_error (_("can't open `%s': %s\n"), listname, gpg_strerror (err));
+ return err;
+ }
+ }
+
+ if (!listfp)
+ return gpg_error (GPG_ERR_EOF);
+
+ do
+ {
+ if (!fgets (line, DIM(line)-1, listfp) )
+ {
+ if (feof (listfp))
+ return gpg_error (GPG_ERR_EOF);
+ return gpg_error_from_errno (errno);
+ }
+
+ if (!*line || line[strlen(line)-1] != '\n')
+ {
+ /* Eat until end of line. */
+ while ( (c=getc (listfp)) != EOF && c != '\n')
+ ;
+ return gpg_error (*line? GPG_ERR_LINE_TOO_LONG
+ : GPG_ERR_INCOMPLETE_LINE);
+ }
+ ++*lnr;
+
+ /* Allow for empty lines and spaces */
+ for (p=line; spacep (p); p++)
+ ;
+ }
+ while (!*p || *p == '\n' || *p == '#');
+
+ for (i=j=0; (p[i] == ':' || hexdigitp (p+i)) && j < 40; i++)
+ if ( p[i] != ':' )
+ key[j++] = p[i] >= 'a'? (p[i] & 0xdf): p[i];
+ key[j] = 0;
+ if (j != 40 || !(spacep (p+i) || p[i] == '\n'))
+ {
+ log_error (_("invalid formatted fingerprint in `%s', line %d\n"),
+ listname, *lnr);
+ return gpg_error (GPG_ERR_BAD_DATA);
+ }
+ assert (p[i]);
+ i++;
+ while (spacep (p+i))
+ i++;
+ if ( p[i] >= 'a' && p[i] <= 'z'
+ && p[i+1] >= 'a' && p[i+1] <= 'z'
+ && (spacep (p+i+2) || p[i+2] == '\n'))
+ {
+ country[0] = p[i];
+ country[1] = p[i+1];
+ country[2] = 0;
+ }
+ else
+ {
+ log_error (_("invalid country code in `%s', line %d\n"), listname, *lnr);
+ return gpg_error (GPG_ERR_BAD_DATA);
+ }
+
+ return 0;
+}
+
+
+
+
+/* Check whether the certificate CERT is included in the list of
+ qualified certificates. This list is similar to the "trustlist.txt"
+ as maintained by gpg-agent and includes fingerprints of root
+ certificates to be used for qualified (legally binding like
+ handwritten) signatures. We keep this list system wide and not
+ per user because it is not a decision of the user.
+
+ Returns: 0 if the certificate is included. GPG_ERR_NOT_FOUND if it
+ is not in the liost or any other error (e.g. if no list of
+ qualified signatures is available. */
+gpg_error_t
+gpgsm_is_in_qualified_list (ctrl_t ctrl, ksba_cert_t cert)
+{
+ gpg_error_t err;
+ char *fpr;
+ char key[41];
+ char country[2];
+ int lnr = 0;
+
+ fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
+ if (!fpr)
+ return gpg_error (GPG_ERR_GENERAL);
+
+ if (listfp)
+ rewind (listfp);
+ while (!(err = read_list (key, country, &lnr)))
+ {
+ if (!strcmp (key, fpr))
+ break;
+ }
+ if (gpg_err_code (err) == GPG_ERR_EOF)
+ err = gpg_error (GPG_ERR_NOT_FOUND);
+
+ xfree (fpr);
+ return err;
+}
+
+
+/* We know that CERT is a qualified certificate. Ask the user for
+ consent to actually create a signature using this certificate.
+ Returns: 0 for yes, GPG_ERR_CANCEL for no or any otehr error
+ code. */
+gpg_error_t
+gpgsm_qualified_consent (ctrl_t ctrl, ksba_cert_t cert)
+{
+ gpg_error_t err;
+ char *name, *subject, *buffer, *p;
+ const char *s;
+ char *orig_codeset = NULL;
+
+ 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"
+ "This will create a qualified signature by law "
+ "equated to a handwritten signature.\n\n"
+ "Are you really sure that you want to do this?"),
+ 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);
+ return err;
+}
Modified: branches/GNUPG-1-9-BRANCH/sm/sign.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/sm/sign.c 2005-11-13 19:05:00 UTC (rev 3933)
+++ branches/GNUPG-1-9-BRANCH/sm/sign.c 2005-11-13 19:07:06 UTC (rev 3934)
@@ -426,6 +426,35 @@
goto leave;
}
}
+
+
+ /* Check whether one of the certificates is qualified. Note that we
+ already validated the certificate and thus the user data stored
+ flag must be available. */
+ for (cl=signerlist; cl; cl = cl->next)
+ {
+ size_t buflen;
+ char buffer[1];
+
+ err = ksba_cert_get_user_data (cl->cert, "is_qualified",
+ &buffer, sizeof (buffer), &buflen);
+ if (err || !buflen)
+ {
+ log_error (_("checking for qualified certificate failed: %s\n"),
+ gpg_strerror (err));
+ rc = err;
+ goto leave;
+ }
+ if (*buffer)
+ {
+ err = gpgsm_qualified_consent (ctrl, cl->cert);
+ if (err)
+ {
+ rc = err;
+ goto leave;
+ }
+ }
+ }
/* Prepare hashing (actually we are figuring out what we have set above)*/
rc = gcry_md_open (&data_md, 0, 0);
@@ -443,6 +472,10 @@
if (!algo)
{
log_error ("unknown hash algorithm `%s'\n", algoid? algoid:"?");
+ if (algoid
+ && ( !strcmp (algoid, "1.2.840.113549.1.1.2")
+ ||!strcmp (algoid, "1.2.840.113549.2.2")))
+ log_info (_("(this is the MD2 algorithm)\n"));
rc = gpg_error (GPG_ERR_BUG);
goto leave;
}
Modified: branches/GNUPG-1-9-BRANCH/sm/verify.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/sm/verify.c 2005-11-13 19:05:00 UTC (rev 3933)
+++ branches/GNUPG-1-9-BRANCH/sm/verify.c 2005-11-13 19:07:06 UTC (rev 3934)
@@ -179,8 +179,14 @@
{
algo = gcry_md_map_name (algoid);
if (!algo)
- log_error ("unknown hash algorithm `%s'\n",
- algoid? algoid:"?");
+ {
+ log_error ("unknown hash algorithm `%s'\n",
+ algoid? algoid:"?");
+ if (algoid
+ && ( !strcmp (algoid, "1.2.840.113549.1.1.2")
+ ||!strcmp (algoid, "1.2.840.113549.2.2")))
+ log_info (_("(this is the MD2 algorithm)\n"));
+ }
else
gcry_md_enable (data_md, algo);
}
More information about the Gnupg-commits
mailing list