Translate the oktext (yes/no).
[gnupg.git] / common / sexputil.c
blob4907a9355c077f4559866324777b2ab53c2ed9dc
1 /* sexputil.c - Utility functions for S-expressions.
2 * Copyright (C) 2005, 2007 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 /* This file implements a few utility functions useful when working
21 with canonical encrypted S-expresions (i.e. not the S-exprssion
22 objects from libgcrypt). */
24 #include <config.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <errno.h>
30 #ifdef HAVE_LOCALE_H
31 #include <locale.h>
32 #endif
34 #include "util.h"
35 #include "sexp-parse.h"
37 /* Return the so called "keygrip" which is the SHA-1 hash of the
38 public key parameters expressed in a way depended on the algorithm.
40 KEY is expected to be an canonical encoded S-expression with a
41 public or private key. KEYLEN is the length of that buffer.
43 GRIP must be at least 20 bytes long. On success 0 is returned, on
44 error an error code. */
45 gpg_error_t
46 keygrip_from_canon_sexp (const unsigned char *key, size_t keylen,
47 unsigned char *grip)
49 gpg_error_t err;
50 gcry_sexp_t sexp;
52 if (!grip)
53 return gpg_error (GPG_ERR_INV_VALUE);
54 err = gcry_sexp_sscan (&sexp, NULL, (const char *)key, keylen);
55 if (err)
56 return err;
57 if (!gcry_pk_get_keygrip (sexp, grip))
58 err = gpg_error (GPG_ERR_INTERNAL);
59 gcry_sexp_release (sexp);
60 return err;
64 /* Compare two simple S-expressions like "(3:foo)". Returns 0 if they
65 are identical or !0 if they are not. Not that this function can't
66 be used for sorting. */
67 int
68 cmp_simple_canon_sexp (const unsigned char *a_orig,
69 const unsigned char *b_orig)
71 const char *a = (const char *)a_orig;
72 const char *b = (const char *)b_orig;
73 unsigned long n1, n2;
74 char *endp;
76 if (!a && !b)
77 return 0; /* Both are NULL, they are identical. */
78 if (!a || !b)
79 return 1; /* One is NULL, they are not identical. */
80 if (*a != '(' || *b != '(')
81 log_bug ("invalid S-exp in cmp_simple_canon_sexp\n");
83 a++;
84 n1 = strtoul (a, &endp, 10);
85 a = endp;
86 b++;
87 n2 = strtoul (b, &endp, 10);
88 b = endp;
90 if (*a != ':' || *b != ':' )
91 log_bug ("invalid S-exp in cmp_simple_canon_sexp\n");
92 if (n1 != n2)
93 return 1; /* Not the same. */
95 for (a++, b++; n1; n1--, a++, b++)
96 if (*a != *b)
97 return 1; /* Not the same. */
98 return 0;
102 /* Create a simple S-expression from the hex string at LIBNE. Returns
103 a newly allocated buffer with that canonical encoded S-expression
104 or NULL in case of an error. On return the number of characters
105 scanned in LINE will be stored at NSCANNED. This fucntions stops
106 converting at the first character not representing a hexdigit. Odd
107 numbers of hex digits are allowed; a leading zero is then
108 assumed. If no characters have been found, NULL is returned.*/
109 unsigned char *
110 make_simple_sexp_from_hexstr (const char *line, size_t *nscanned)
112 size_t n, len;
113 const char *s;
114 unsigned char *buf;
115 unsigned char *p;
116 char numbuf[50], *numbufp;
117 size_t numbuflen;
119 for (n=0, s=line; hexdigitp (s); s++, n++)
121 if (nscanned)
122 *nscanned = n;
123 if (!n)
124 return NULL;
125 len = ((n+1) & ~0x01)/2;
126 numbufp = smklen (numbuf, sizeof numbuf, len, &numbuflen);
127 buf = xtrymalloc (1 + numbuflen + len + 1 + 1);
128 if (!buf)
129 return NULL;
130 buf[0] = '(';
131 p = (unsigned char *)stpcpy ((char *)buf+1, numbufp);
132 s = line;
133 if ((n&1))
135 *p++ = xtoi_1 (s);
136 s++;
137 n--;
139 for (; n > 1; n -=2, s += 2)
140 *p++ = xtoi_2 (s);
141 *p++ = ')';
142 *p = 0; /* (Not really neaded.) */
144 return buf;
148 /* Return the hash algorithm from a KSBA sig-val. SIGVAL is a
149 canonical encoded S-expression. Return 0 if the hash algorithm is
150 not encoded in SIG-VAL or it is not supported by libgcrypt. */
152 hash_algo_from_sigval (const unsigned char *sigval)
154 const unsigned char *s = sigval;
155 size_t n;
156 int depth;
157 char buffer[50];
159 if (!s || *s != '(')
160 return 0; /* Invalid S-expression. */
161 s++;
162 n = snext (&s);
163 if (!n)
164 return 0; /* Invalid S-expression. */
165 if (!smatch (&s, n, "sig-val"))
166 return 0; /* Not a sig-val. */
167 if (*s != '(')
168 return 0; /* Invalid S-expression. */
169 s++;
170 /* Skip over the algo+parameter list. */
171 depth = 1;
172 if (sskip (&s, &depth) || depth)
173 return 0; /* Invalid S-expression. */
174 if (*s != '(')
175 return 0; /* No futher list. */
176 /* Check whether this is (hash ALGO). */
177 s++;
178 n = snext (&s);
179 if (!n)
180 return 0; /* Invalid S-expression. */
181 if (!smatch (&s, n, "hash"))
182 return 0; /* Not a "hash" keyword. */
183 n = snext (&s);
184 if (!n || n+1 >= sizeof (buffer))
185 return 0; /* Algorithm string is missing or too long. */
186 memcpy (buffer, s, n);
187 buffer[n] = 0;
189 return gcry_md_map_name (buffer);