summaryrefslogtreecommitdiffstats
path: root/common/sexputil.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/sexputil.c')
-rw-r--r--common/sexputil.c52
1 files changed, 49 insertions, 3 deletions
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);
+}
+