summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS3
-rw-r--r--common/ChangeLog9
-rw-r--r--common/Makefile.am4
-rw-r--r--common/sexp-parse.h2
-rw-r--r--common/sexputil.c52
-rw-r--r--common/t-sexputil.c82
-rw-r--r--common/util.h1
-rw-r--r--doc/ChangeLog11
-rw-r--r--doc/debugging.texi5
-rw-r--r--doc/examples/trustlist.txt11
-rw-r--r--doc/gpg.texi12
-rw-r--r--doc/gpgsm.texi13
-rw-r--r--doc/qualified.txt29
-rw-r--r--doc/specify-user-id.texi2
-rw-r--r--sm/ChangeLog7
-rw-r--r--sm/gpgsm.c13
-rw-r--r--sm/gpgsm.h3
-rw-r--r--sm/sign.c4
-rw-r--r--sm/verify.c38
19 files changed, 276 insertions, 25 deletions
diff --git a/NEWS b/NEWS
index d5130d7fc..28a31a93f 100644
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,9 @@ Noteworthy changes in version 2.0.8
* Creating DSA2 keys is now possible.
+ * New option --extra-digest-algo for gpgsm to allow verification of
+ broken signatures.
+
Noteworthy changes in version 2.0.7 (2007-09-10)
------------------------------------------------
diff --git a/common/ChangeLog b/common/ChangeLog
index b6b12f95b..b42bf9f4f 100644
--- a/common/ChangeLog
+++ b/common/ChangeLog
@@ -1,3 +1,9 @@
+2007-12-13 Werner Koch <wk@g10code.com>
+
+ * sexputil.c (hash_algo_from_sigval): New.
+ * t-sexputil.c: New.
+ * Makefile.am (module_tests): Add it.
+
2007-12-11 Werner Koch <wk@g10code.com>
* asshelp.c (send_pinentry_environment): Allow using of old
@@ -1126,7 +1132,8 @@
(atoi_1,atoi_2,atoi_4,xtoi_1,xtoi_2): New.
- Copyright 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright 2001, 2002, 2003, 2004, 2005, 2006,
+ 2007 Free Software Foundation, Inc.
This file is free software; as a special exception the author gives
unlimited permission to copy and/or distribute it, with or without
diff --git a/common/Makefile.am b/common/Makefile.am
index 11404af02..e9c532521 100644
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -107,7 +107,7 @@ status-codes.h: Makefile mkstrtable.awk exstatus.awk status.h
#
# Module tests
#
-module_tests = t-convert t-gettime t-sysutils
+module_tests = t-convert t-gettime t-sysutils t-sexputil
module_maint_tests = t-helpfile
t_common_ldadd = libcommon.a ../jnlib/libjnlib.a ../gl/libgnu.a \
@@ -117,5 +117,5 @@ t_convert_LDADD = $(t_common_ldadd)
t_gettime_LDADD = $(t_common_ldadd)
t_sysutils_LDADD = $(t_common_ldadd)
t_helpfile_LDADD = $(t_common_ldadd)
-
+t_sexputil_LDADD = $(t_common_ldadd)
diff --git a/common/sexp-parse.h b/common/sexp-parse.h
index d2675fbdb..b3213a6fe 100644
--- a/common/sexp-parse.h
+++ b/common/sexp-parse.h
@@ -44,7 +44,7 @@ snext (unsigned char const **buf)
lists and may be passed as a positive number to skip over the
remainder of an S-Expression if the current position is somewhere
in an S-Expression. The function may return an error code if it
- encounters an impossible conditions */
+ encounters an impossible condition. */
static inline gpg_error_t
sskip (unsigned char const **buf, int *depth)
{
diff --git a/common/sexputil.c b/common/sexputil.c
index c7f718660..4907a9355 100644
--- a/common/sexputil.c
+++ b/common/sexputil.c
@@ -1,5 +1,5 @@
/* sexputil.c - Utility functions for S-expressions.
- * Copyright (C) 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2005, 2007 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -40,8 +40,8 @@
KEY is expected to be an canonical encoded S-expression with a
public or private key. KEYLEN is the length of that buffer.
- GRIP must be at least 20 bytes long On success 0 is return, on
- error an aerror code. */
+ GRIP must be at least 20 bytes long. On success 0 is returned, on
+ error an error code. */
gpg_error_t
keygrip_from_canon_sexp (const unsigned char *key, size_t keylen,
unsigned char *grip)
@@ -143,3 +143,49 @@ make_simple_sexp_from_hexstr (const char *line, size_t *nscanned)
return buf;
}
+
+
+/* Return the hash algorithm from a KSBA sig-val. SIGVAL is a
+ canonical encoded S-expression. Return 0 if the hash algorithm is
+ not encoded in SIG-VAL or it is not supported by libgcrypt. */
+int
+hash_algo_from_sigval (const unsigned char *sigval)
+{
+ const unsigned char *s = sigval;
+ size_t n;
+ int depth;
+ char buffer[50];
+
+ if (!s || *s != '(')
+ return 0; /* Invalid S-expression. */
+ s++;
+ n = snext (&s);
+ if (!n)
+ return 0; /* Invalid S-expression. */
+ if (!smatch (&s, n, "sig-val"))
+ return 0; /* Not a sig-val. */
+ if (*s != '(')
+ return 0; /* Invalid S-expression. */
+ s++;
+ /* Skip over the algo+parameter list. */
+ depth = 1;
+ if (sskip (&s, &depth) || depth)
+ return 0; /* Invalid S-expression. */
+ if (*s != '(')
+ return 0; /* No futher list. */
+ /* Check whether this is (hash ALGO). */
+ s++;
+ n = snext (&s);
+ if (!n)
+ return 0; /* Invalid S-expression. */
+ if (!smatch (&s, n, "hash"))
+ return 0; /* Not a "hash" keyword. */
+ n = snext (&s);
+ if (!n || n+1 >= sizeof (buffer))
+ return 0; /* Algorithm string is missing or too long. */
+ memcpy (buffer, s, n);
+ buffer[n] = 0;
+
+ return gcry_md_map_name (buffer);
+}
+
diff --git a/common/t-sexputil.c b/common/t-sexputil.c
new file mode 100644
index 000000000..097dc9878
--- /dev/null
+++ b/common/t-sexputil.c
@@ -0,0 +1,82 @@
+/* t-sexputil.c - Module test for sexputil.c
+ * Copyright (C) 2007 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "util.h"
+
+#define pass() do { ; } while(0)
+#define fail(a) do { fprintf (stderr, "%s:%d: test %d failed\n",\
+ __FILE__,__LINE__, (a)); \
+ exit (1); \
+ } while(0)
+
+
+static void
+test_hash_algo_from_sigval (void)
+{
+ int algo;
+ /* A real world example. */
+ unsigned char example1_rsa_sha1[] =
+ ("\x28\x37\x3A\x73\x69\x67\x2D\x76\x61\x6C\x28\x33\x3A\x72\x73\x61"
+ "\x28\x31\x3A\x73\x31\x32\x38\x3A\x17\xD2\xE9\x5F\xB4\x24\xD4\x1E"
+ "\x8C\xEE\x94\xDA\x41\x42\x1F\x26\x5E\xF4\x6D\xEC\x5B\xBD\x5B\x89"
+ "\x7A\x69\x11\x43\xE9\xD2\x23\x21\x25\x64\xA6\xB0\x56\xEF\xB4\xE9"
+ "\x06\xB2\x44\xF6\x80\x1E\xFF\x41\x23\xEB\xC9\xFA\xFD\x09\xBF\x9C"
+ "\x8E\xCF\x7F\xC3\x7F\x3A\x40\x48\x89\xDC\xBA\xB7\xDB\x9E\xF1\xBA"
+ "\x7C\x08\xEA\x74\x1D\x49\xE7\x65\xEF\x67\x79\xBC\x23\xD9\x49\xCD"
+ "\x05\x99\xD3\xD8\xB7\x7B\xC7\x0E\xF2\xB3\x01\x48\x0F\xC8\xEB\x05"
+ "\x7B\xFB\x61\xCC\x41\x04\x74\x6D\x33\x84\xB1\xE6\x6A\xD8\x0F\xBC"
+ "\x27\xAC\x43\x45\xFA\x04\xD1\x22\x29\x29\x28\x34\x3A\x68\x61\x73"
+ "\x68\x34\x3A\x73\x68\x61\x31\x29\x29");
+ /* The same but without the hash algo. */
+ unsigned char example1_rsa[] =
+ ("\x28\x37\x3A\x73\x69\x67\x2D\x76\x61\x6C\x28\x33\x3A\x72\x73\x61"
+ "\x28\x31\x3A\x73\x31\x32\x38\x3A\x17\xD2\xE9\x5F\xB4\x24\xD4\x1E"
+ "\x8C\xEE\x94\xDA\x41\x42\x1F\x26\x5E\xF4\x6D\xEC\x5B\xBD\x5B\x89"
+ "\x7A\x69\x11\x43\xE9\xD2\x23\x21\x25\x64\xA6\xB0\x56\xEF\xB4\xE9"
+ "\x06\xB2\x44\xF6\x80\x1E\xFF\x41\x23\xEB\xC9\xFA\xFD\x09\xBF\x9C"
+ "\x8E\xCF\x7F\xC3\x7F\x3A\x40\x48\x89\xDC\xBA\xB7\xDB\x9E\xF1\xBA"
+ "\x7C\x08\xEA\x74\x1D\x49\xE7\x65\xEF\x67\x79\xBC\x23\xD9\x49\xCD"
+ "\x05\x99\xD3\xD8\xB7\x7B\xC7\x0E\xF2\xB3\x01\x48\x0F\xC8\xEB\x05"
+ "\x7B\xFB\x61\xCC\x41\x04\x74\x6D\x33\x84\xB1\xE6\x6A\xD8\x0F\xBC"
+ "\x27\xAC\x43\x45\xFA\x04\xD1\x22\x29\x29\x29");
+
+ algo = hash_algo_from_sigval (example1_rsa_sha1);
+ if (algo != GCRY_MD_SHA1)
+ fail (0);
+ algo = hash_algo_from_sigval (example1_rsa);
+ if (algo)
+ fail (0);
+}
+
+
+
+
+int
+main (int argc, char **argv)
+{
+
+ test_hash_algo_from_sigval ();
+
+ return 0;
+}
+
diff --git a/common/util.h b/common/util.h
index e9d0ffbec..53a56a336 100644
--- a/common/util.h
+++ b/common/util.h
@@ -164,6 +164,7 @@ gpg_error_t keygrip_from_canon_sexp (const unsigned char *key, size_t keylen,
int cmp_simple_canon_sexp (const unsigned char *a, const unsigned char *b);
unsigned char *make_simple_sexp_from_hexstr (const char *line,
size_t *nscanned);
+int hash_algo_from_sigval (const unsigned char *sigval);
/*-- convert.c --*/
int hex2bin (const char *string, void *buffer, size_t length);
diff --git a/doc/ChangeLog b/doc/ChangeLog
index 63415c4da..b01d3b179 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,14 @@
+2007-12-13 Werner Koch <wk@g10code.com>
+
+ * qualified.txt: Add 2 root certs from S-Trust for 2008-2012.
+ * examples/trustlist.txt: Ditto.
+
+ * gpgsm.texi (Esoteric Options): Document --extra-digest-algo.
+
+2007-12-12 Werner Koch <wk@g10code.com>
+
+ * gpg.texi: Typo fixes. From Christer Andersson.
+
2007-12-04 Werner Koch <wk@g10code.com>
* help.txt: New online help file.
diff --git a/doc/debugging.texi b/doc/debugging.texi
index fb27b2710..242d601cb 100644
--- a/doc/debugging.texi
+++ b/doc/debugging.texi
@@ -182,7 +182,12 @@ such a certificate. You may use the @code{relax} flag in
fingerprint and this flag may only be added manually to
@file{trustlist.txt}.
+@item Error message: ``digest algorithm N has not been enabled''
+The signature is broken. You may try the option
+@option{--extra-digest-algo SHA256} to workaround the problem. The
+number N is the internal algorighm indentifier; for example 8 refers to
+SHA-256.
@end itemize
diff --git a/doc/examples/trustlist.txt b/doc/examples/trustlist.txt
index 1fcae4106..fa80ed4fc 100644
--- a/doc/examples/trustlist.txt
+++ b/doc/examples/trustlist.txt
@@ -38,6 +38,17 @@ DB:45:3D:1B:B0:1A:F3:23:10:6B:DE:D0:09:61:57:AA:F4:25:E0:5B S
# Issuer: /CN=11R-CA 1:PN/O=Bundesnetzagentur/C=DE
A0:8B:DF:3B:AA:EE:3F:9D:64:6C:47:81:23:21:D4:A6:18:81:67:1D S
+# S/N: 00B3963E0E6C2D65125853E970665402E5
+# Issuer: /CN=S-TRUST Qualified Root CA 2008-001:PN
+# /O=Deutscher Sparkassen Verlag GmbH/L=Stuttgart/C=DE
+C9:2F:E6:50:DB:32:59:E0:CE:65:55:F3:8C:76:E0:B8:A8:FE:A3:CA S
+
+# S/N: 00C4216083F35C54F67B09A80C3C55FE7D
+# Issuer: /CN=S-TRUST Qualified Root CA 2008-002:PN
+# /O=Deutscher Sparkassen Verlag GmbH/L=Stuttgart/C=DE
+D5:C7:50:F2:FE:4E:EE:D7:C7:B1:E4:13:7B:FB:54:84:3A:7D:97:9B S
+
+
#Serial number: 00
# Issuer: /CN=CA Cert Signing Authority/OU=http:\x2f\x2fwww.
# cacert.org/O=Root CA/EMail=support@cacert.org
diff --git a/doc/gpg.texi b/doc/gpg.texi
index f7b7df856..cc048b1db 100644
--- a/doc/gpg.texi
+++ b/doc/gpg.texi
@@ -113,7 +113,7 @@ Developer information:
@node GPG Commands
@section Commands
-Commands are not distinguished from options execpt for the fact that
+Commands are not distinguished from options except for the fact that
only one command is allowed.
@command{@gpgname} may be run with no commands, in which case it will
@@ -876,7 +876,7 @@ encountered, you can explicitly stop parsing by using the special option
@node GPG Configuration Options
@subsection How to change the configuration
-These options are used to change the configuraton and are usually found
+These options are used to change the configuration and are usually found
in the option file.
@table @gnupgtabopt
@@ -2456,13 +2456,13 @@ listed. @option{--list-config} is only usable with
@item --gpgconf-list
@opindex gpgconf-list
-This command is simliar to @option{--list-config} but in general only
+This command is similar to @option{--list-config} but in general only
internally used by the @command{gpgconf} tool.
@item --gpgconf-test
@opindex gpgconf-test
This is more or less dummy action. However it parses the configuration
-file and returns with failure if the configuraion file would prevent
+file and returns with failure if the configuration file would prevent
@command{gpg} from startup. Thus it may be used to run a syntax check
on the configuration file.
@@ -2560,7 +2560,7 @@ For existing users the a small
helper script is provided to create these files (@pxref{addgnupghome}).
@end ifclear
-For internal purposes @command{@gpgname} creates and maintaines a few other
+For internal purposes @command{@gpgname} creates and maintains a few other
files; They all live in in the current home directory (@pxref{option
--homedir}). Only the @command{@gpgname} may modify these files.
@@ -2686,7 +2686,7 @@ user for the filename.
@include specify-user-id.texi
@end ifset
-@mansect return vaue
+@mansect return value
@chapheading RETURN VALUE
The program returns 0 if everything was fine, 1 if at least
diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi
index e5ae1688c..12f882e09 100644
--- a/doc/gpgsm.texi
+++ b/doc/gpgsm.texi
@@ -569,6 +569,19 @@ encryption. For convenience the strings @code{3DES}, @code{AES} and
@table @gnupgtabopt
+@item --extra-digest-algo @var{name}
+@opindex extra-digest-algo
+Sometimes signatures are broken in that they announce a different digest
+algorithm than actually used. @command{gpgsm} uses a one-pass data
+processing model and thus needs to rely on the announcde digest
+algorithms to properly hash the data. As a workaround this option may
+be used to tell gpg to also hash the data using the algorithm
+@var{name}; this slows processing down a little bit but allows to verify
+such broken signatures. If @command{gpgsm} prints an error like
+``digest algo 8 has not been enabled'' you may want to try this option,
+with @samp{SHA256} for @var{name}.
+
+
@item --faked-system-time @var{epoch}
@opindex faked-system-time
This option is only useful for testing; it sets the system time back or
diff --git a/doc/qualified.txt b/doc/qualified.txt
index f6a54d66e..ddd77972b 100644
--- a/doc/qualified.txt
+++ b/doc/qualified.txt
@@ -180,6 +180,35 @@ E0:BF:1B:91:91:6B:88:E4:F1:15:92:22:CE:37:23:96:B1:4A:2E:5C de
7A:3C:1B:60:2E:BD:A4:A1:E0:EB:AD:7A:BA:4F:D1:43:69:A9:39:FC de
+# ID: 0xA8FEA3CA
+# S/N: 00B3963E0E6C2D65125853E970665402E5
+# Issuer: /CN=S-TRUST Qualified Root CA 2008-001:PN
+# /O=Deutscher Sparkassen Verlag GmbH/L=Stuttgart/C=DE
+# Subject: /CN=S-TRUST Qualified Root CA 2008-001:PN
+# /O=Deutscher Sparkassen Verlag GmbH/L=Stuttgart/C=DE
+# validity: 2008-01-01 00:00:00 through 2012-12-30 23:59:59
+# key type: 2048 bit RSA
+# key usage: certSign crlSign
+# chain length: 1
+#[checked: 2007-12-13 via received ZIP file with qualified signature from
+# /CN=Dr. Matthias Stehle/O=Deutscher Sparkassenverlag
+# /C=DE/SerialNumber=DSV0000000008/SN=Stehle/GN=Matthias Georg]
+C9:2F:E6:50:DB:32:59:E0:CE:65:55:F3:8C:76:E0:B8:A8:FE:A3:CA
+
+# ID: 0x3A7D979B
+# S/N: 00C4216083F35C54F67B09A80C3C55FE7D
+# Issuer: /CN=S-TRUST Qualified Root CA 2008-002:PN
+# /O=Deutscher Sparkassen Verlag GmbH/L=Stuttgart/C=DE
+# Subject: /CN=S-TRUST Qualified Root CA 2008-002:PN
+# /O=Deutscher Sparkassen Verlag GmbH/L=Stuttgart/C=DE
+# validity: 2008-01-01 00:00:00 through 2012-12-30 23:59:59
+# key type: 2048 bit RSA
+# key usage: certSign crlSign
+# chain length: 1
+#[checked: 2007-12-13 via received ZIP file with qualified signature from
+# /CN=Dr. Matthias Stehle/O=Deutscher Sparkassenverlag
+# /C=DE/SerialNumber=DSV0000000008/SN=Stehle/GN=Matthias Georg"]
+D5:C7:50:F2:FE:4E:EE:D7:C7:B1:E4:13:7B:FB:54:84:3A:7D:97:9B
#*******************************************
diff --git a/doc/specify-user-id.texi b/doc/specify-user-id.texi
index 0929a10f8..7d23ed86f 100644
--- a/doc/specify-user-id.texi
+++ b/doc/specify-user-id.texi
@@ -121,7 +121,7 @@ This should return the Root cert of the issuer. See note above.
@item By exact match on serial number and issuer's DN.
-This is indicated by a hash mark, followed by the hexadecmal
+This is indicated by a hash mark, followed by the hexadecimal
representation of the serial number, then followed by a slash and the
RFC-2253 encoded DN of the issuer. See note above.
diff --git a/sm/ChangeLog b/sm/ChangeLog
index 49ed50669..032f02897 100644
--- a/sm/ChangeLog
+++ b/sm/ChangeLog
@@ -1,3 +1,10 @@
+2007-12-13 Werner Koch <wk@g10code.com>
+
+ * gpgsm.c (main): Add option --extra-digest-algo.
+ * gpgsm.h (struct): Add EXTRA_DIGEST_ALGO.
+ * verify.c (gpgsm_verify): Use it. Use the hash algorithm from
+ the signature value.
+
2007-12-11 Werner Koch <wk@g10code.com>
* certchain.c (do_validate_chain): Log AUDIT_ROOT_TRUSTED.
diff --git a/sm/gpgsm.c b/sm/gpgsm.c
index 93474b37a..71f8e2cc1 100644
--- a/sm/gpgsm.c
+++ b/sm/gpgsm.c
@@ -174,6 +174,7 @@ enum cmd_and_opt_values {
oOpenPGP,
oCipherAlgo,
oDigestAlgo,
+ oExtraDigestAlgo,
oCompressAlgo,
oCommandFD,
oNoVerbose,
@@ -388,6 +389,7 @@ static ARGPARSE_OPTS opts[] = {
{ oCipherAlgo, "cipher-algo", 2 , N_("|NAME|use cipher algorithm NAME")},
{ oDigestAlgo, "digest-algo", 2 ,
N_("|NAME|use message digest algorithm NAME")},
+ { oExtraDigestAlgo, "extra-digest-algo", 2 , "@" },
#if 0
{ oCompressAlgo, "compress-algo", 1 , N_("|N|use compress algorithm N")},
#endif
@@ -842,6 +844,7 @@ main ( int argc, char **argv)
int use_random_seed = 1;
int with_fpr = 0;
char *def_digest_string = NULL;
+ char *extra_digest_algo = NULL;
enum cmd_and_opt_values cmd = 0;
struct server_control_s ctrl;
certlist_t recplist = NULL;
@@ -1298,6 +1301,10 @@ main ( int argc, char **argv)
}
break;
+ case oExtraDigestAlgo:
+ extra_digest_algo = pargs.r.ret_str;
+ break;
+
case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
case oNoRandomSeedFile: use_random_seed = 0; break;
@@ -1441,6 +1448,12 @@ main ( int argc, char **argv)
if (our_md_test_algo(opt.def_digest_algo) )
log_error (_("selected digest algorithm is invalid\n"));
}
+ if (extra_digest_algo)
+ {
+ opt.extra_digest_algo = gcry_md_map_name (extra_digest_algo);
+ if (our_md_test_algo (opt.extra_digest_algo) )
+ log_error (_("selected digest algorithm is invalid\n"));
+ }
}
if (log_get_errorcount(0))
diff --git a/sm/gpgsm.h b/sm/gpgsm.h
index 5232ce427..8b03995e8 100644
--- a/sm/gpgsm.h
+++ b/sm/gpgsm.h
@@ -92,6 +92,9 @@ struct
char *local_user; /* NULL or argument to -u */
+ int extra_digest_algo; /* A digest algorithm also used for
+ verification of signatures. */
+
int always_trust; /* Trust the given keys even if there is no
valid certification chain */
int skip_verify; /* do not check signatures on data */
diff --git a/sm/sign.c b/sm/sign.c
index d617e7239..d8e8451bf 100644
--- a/sm/sign.c
+++ b/sm/sign.c
@@ -491,7 +491,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
unsigned char *digest;
size_t digest_len;
/* Fixme do this for all signers and get the algo to use from
- the signer's certificate - does not make mich sense, but we
+ the signer's certificate - does not make much sense, but we
should do this consistent as we have already done it above. */
algo = GCRY_MD_SHA1;
hash_data (data_fd, data_md);
@@ -530,7 +530,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
}
/* We need to write at least a minimal list of our capabilities to
- try to convince some MUAs to use 3DEs and not the crippled
+ try to convince some MUAs to use 3DES and not the crippled
RC2. Our list is:
aes128-CBC
diff --git a/sm/verify.c b/sm/verify.c
index 2a455a5ce..1071d9086 100644
--- a/sm/verify.c
+++ b/sm/verify.c
@@ -203,10 +203,20 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
}
else
{
+ if (DBG_X509)
+ log_debug ("enabling hash algorithm %d (%s)\n",
+ algo, algoid? algoid:"");
gcry_md_enable (data_md, algo);
audit_log_i (ctrl->audit, AUDIT_DATA_HASH_ALGO, algo);
}
}
+ if (opt.extra_digest_algo)
+ {
+ if (DBG_X509)
+ log_debug ("enabling extra hash algorithm %d\n",
+ opt.extra_digest_algo);
+ gcry_md_enable (data_md, opt.extra_digest_algo);
+ }
if (is_detached)
{
if (data_fd == -1)
@@ -271,6 +281,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
char *msgdigest = NULL;
size_t msgdigestlen;
char *ctattr;
+ int sigval_hash_algo;
int info_pkalgo;
unsigned int verifyflags;
@@ -331,7 +342,8 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
&algo, &is_enabled)
|| !is_enabled)
{
- log_error ("digest algo %d has not been enabled\n", algo);
+ log_error ("digest algo %d (%s) has not been enabled\n",
+ algo, algoid?algoid:"");
audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "unsupported");
goto next_signer;
}
@@ -389,8 +401,16 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
goto next_signer;
}
+ sigval_hash_algo = hash_algo_from_sigval (sigval);
if (DBG_X509)
- log_debug ("signer %d - signature available", signer);
+ {
+ log_debug ("signer %d - signature available (sigval hash=%d)",
+ signer, sigval_hash_algo);
+/* log_printhex ("sigval ", sigval, */
+/* gcry_sexp_canon_len (sigval, 0, NULL, NULL)); */
+ }
+ if (!sigval_hash_algo)
+ sigval_hash_algo = algo; /* Fallback used e.g. with old libksba. */
/* Find the certificate of the signer */
keydb_search_reset (kh);
@@ -438,8 +458,8 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
gcry_md_hd_t md;
unsigned char *s;
- /* check that the message digest in the signed attributes
- matches the one we calculated on the data */
+ /* Check that the message digest in the signed attributes
+ matches the one we calculated on the data. */
s = gcry_md_read (data_md, algo);
if ( !s || !msgdigestlen
|| gcry_md_get_algo_dlen (algo) != msgdigestlen
@@ -456,7 +476,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
goto next_signer;
}
- rc = gcry_md_open (&md, algo, 0);
+ rc = gcry_md_open (&md, sigval_hash_algo, 0);
if (rc)
{
log_error ("md_open failed: %s\n", gpg_strerror (rc));
@@ -476,14 +496,14 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "error");
goto next_signer;
}
- rc = gpgsm_check_cms_signature (cert, sigval, md, algo,
- &info_pkalgo);
+ rc = gpgsm_check_cms_signature (cert, sigval, md,
+ sigval_hash_algo, &info_pkalgo);
gcry_md_close (md);
}
else
{
- rc = gpgsm_check_cms_signature (cert, sigval, data_md, algo,
- &info_pkalgo);
+ rc = gpgsm_check_cms_signature (cert, sigval, data_md,
+ algo, &info_pkalgo);
}
if (rc)