Poems for AllowSetForegroundWindow (W32)
[gnupg.git] / common / sexputil.c
index fe0870c..4907a93 100644 (file)
@@ -1,11 +1,11 @@
-/* sexputil.c - Utility fnctions for S-expressions.
- * Copyright (C) 2005 Free Software Foundation, Inc.
+/* sexputil.c - Utility functions for S-expressions.
+ * Copyright (C) 2005, 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 2 of the License, or
+ * 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,
@@ -14,9 +14,7 @@
  * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 /* This file implements a few utility functions useful when working
@@ -34,7 +32,7 @@
 #endif
 
 #include "util.h"
-
+#include "sexp-parse.h"
 
 /* Return the so called "keygrip" which is the SHA-1 hash of the
    public key parameters expressed in a way depended on the algorithm.
@@ -42,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)
@@ -115,7 +113,8 @@ make_simple_sexp_from_hexstr (const char *line, size_t *nscanned)
   const char *s;
   unsigned char *buf;
   unsigned char *p;
-  char numbuf[50];
+  char numbuf[50], *numbufp;
+  size_t numbuflen;
 
   for (n=0, s=line; hexdigitp (s); s++, n++)
     ;
@@ -124,11 +123,12 @@ make_simple_sexp_from_hexstr (const char *line, size_t *nscanned)
   if (!n)
     return NULL;
   len = ((n+1) & ~0x01)/2; 
-  sprintf (numbuf, "(%u:", (unsigned int)len);
-  buf = xtrymalloc (strlen (numbuf) + len + 1 + 1);
+  numbufp = smklen (numbuf, sizeof numbuf, len, &numbuflen);
+  buf = xtrymalloc (1 + numbuflen + len + 1 + 1);
   if (!buf)
     return NULL;
-  p = (unsigned char *)stpcpy ((char *)buf, numbuf);
+  buf[0] = '(';
+  p = (unsigned char *)stpcpy ((char *)buf+1, numbufp);
   s = line;
   if ((n&1))
     {
@@ -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);
+}
+