summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2007-12-13 16:45:40 +0100
committerWerner Koch <wk@gnupg.org>2007-12-13 16:45:40 +0100
commit9d66580cff83d5b6cb6dc52ecc2fcfbfe1e94315 (patch)
tree7373ba64496d9695d194ed16c54abee7f5f887ba /common
parentAllow type 20 keys only with option --rfc2440. (diff)
downloadgnupg2-9d66580cff83d5b6cb6dc52ecc2fcfbfe1e94315.tar.xz
gnupg2-9d66580cff83d5b6cb6dc52ecc2fcfbfe1e94315.zip
Allow verification of some broken S-TRUST generated signatures.
Diffstat (limited to 'common')
-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
6 files changed, 143 insertions, 7 deletions
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);