W32CE fix.
[gnupg.git] / common / sexputil.c
1 /* sexputil.c - Utility functions for S-expressions.
2  * Copyright (C) 2005, 2007, 2009 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
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.
10  *
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.
15  *
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/>.
18  */
19
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).  */
23
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
33
34 #include "util.h"
35 #include "tlv.h"
36 #include "sexp-parse.h"
37
38
39 /* Helper function to create a a canonical encoded S-expression from a
40    Libgcrypt S-expression object.  The function returns 0 on success
41    and the malloced canonical S-expression is stored at R_BUFFER and
42    the allocated length at R_BUFLEN.  On error an error code is
43    returned and (NULL, 0) stored at R_BUFFER and R_BUFLEN.  If the
44    allocated buffer length is not required, NULL by be used for
45    R_BUFLEN.  */
46 gpg_error_t
47 make_canon_sexp (gcry_sexp_t sexp, unsigned char **r_buffer, size_t *r_buflen)
48 {
49   size_t len;
50   unsigned char *buf;
51
52   *r_buffer = NULL;
53   if (r_buflen)
54     *r_buflen = 0;;
55   
56   len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, NULL, 0);
57   if (!len)
58     return gpg_error (GPG_ERR_BUG);
59   buf = xtrymalloc (len);
60   if (!buf)
61     return gpg_error_from_syserror ();
62   len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, buf, len);
63   if (!len)
64     return gpg_error (GPG_ERR_BUG);
65
66   *r_buffer = buf;
67   if (r_buflen)
68     *r_buflen = len;
69
70   return 0;
71 }
72
73
74 /* Return the so called "keygrip" which is the SHA-1 hash of the
75    public key parameters expressed in a way depended on the algorithm.
76
77    KEY is expected to be an canonical encoded S-expression with a
78    public or private key. KEYLEN is the length of that buffer.
79
80    GRIP must be at least 20 bytes long.  On success 0 is returned, on
81    error an error code. */
82 gpg_error_t
83 keygrip_from_canon_sexp (const unsigned char *key, size_t keylen,
84                          unsigned char *grip)
85 {
86   gpg_error_t err;
87   gcry_sexp_t sexp;
88
89   if (!grip)
90     return gpg_error (GPG_ERR_INV_VALUE);
91   err = gcry_sexp_sscan (&sexp, NULL, (const char *)key, keylen);
92   if (err)
93     return err;
94   if (!gcry_pk_get_keygrip (sexp, grip))
95     err = gpg_error (GPG_ERR_INTERNAL);
96   gcry_sexp_release (sexp);
97   return err;
98 }
99
100
101 /* Compare two simple S-expressions like "(3:foo)".  Returns 0 if they
102    are identical or !0 if they are not.  Note that this function can't
103    be used for sorting. */
104 int
105 cmp_simple_canon_sexp (const unsigned char *a_orig,
106                        const unsigned char *b_orig)
107 {
108   const char *a = (const char *)a_orig;
109   const char *b = (const char *)b_orig;
110   unsigned long n1, n2;
111   char *endp;
112
113   if (!a && !b)
114     return 0; /* Both are NULL, they are identical. */
115   if (!a || !b)
116     return 1; /* One is NULL, they are not identical. */
117   if (*a != '(' || *b != '(')
118     log_bug ("invalid S-exp in cmp_simple_canon_sexp\n");
119
120   a++;
121   n1 = strtoul (a, &endp, 10);
122   a = endp;
123   b++;
124   n2 = strtoul (b, &endp, 10);
125   b = endp;
126
127   if (*a != ':' || *b != ':' )
128     log_bug ("invalid S-exp in cmp_simple_canon_sexp\n");
129   if (n1 != n2)
130     return 1; /* Not the same. */
131
132   for (a++, b++; n1; n1--, a++, b++)
133     if (*a != *b)
134       return 1; /* Not the same. */
135   return 0;
136 }
137
138
139 /* Create a simple S-expression from the hex string at LINE.  Returns
140    a newly allocated buffer with that canonical encoded S-expression
141    or NULL in case of an error.  On return the number of characters
142    scanned in LINE will be stored at NSCANNED.  This fucntions stops
143    converting at the first character not representing a hexdigit. Odd
144    numbers of hex digits are allowed; a leading zero is then
145    assumed. If no characters have been found, NULL is returned.*/
146 unsigned char *
147 make_simple_sexp_from_hexstr (const char *line, size_t *nscanned)
148 {
149   size_t n, len;
150   const char *s;
151   unsigned char *buf;
152   unsigned char *p;
153   char numbuf[50], *numbufp;
154   size_t numbuflen;
155
156   for (n=0, s=line; hexdigitp (s); s++, n++)
157     ;
158   if (nscanned)
159     *nscanned = n;
160   if (!n)
161     return NULL;
162   len = ((n+1) & ~0x01)/2; 
163   numbufp = smklen (numbuf, sizeof numbuf, len, &numbuflen);
164   buf = xtrymalloc (1 + numbuflen + len + 1 + 1);
165   if (!buf)
166     return NULL;
167   buf[0] = '(';
168   p = (unsigned char *)stpcpy ((char *)buf+1, numbufp);
169   s = line;
170   if ((n&1))
171     {
172       *p++ = xtoi_1 (s);
173       s++;
174       n--;
175     }
176   for (; n > 1; n -=2, s += 2)
177     *p++ = xtoi_2 (s);
178   *p++ = ')';
179   *p = 0; /* (Not really neaded.) */
180
181   return buf;
182 }
183
184
185 /* Return the hash algorithm from a KSBA sig-val. SIGVAL is a
186    canonical encoded S-expression.  Return 0 if the hash algorithm is
187    not encoded in SIG-VAL or it is not supported by libgcrypt.  */
188 int
189 hash_algo_from_sigval (const unsigned char *sigval)
190 {
191   const unsigned char *s = sigval;
192   size_t n;
193   int depth;
194   char buffer[50];
195
196   if (!s || *s != '(')
197     return 0; /* Invalid S-expression.  */
198   s++;
199   n = snext (&s);
200   if (!n)
201     return 0; /* Invalid S-expression.  */
202   if (!smatch (&s, n, "sig-val"))
203     return 0; /* Not a sig-val.  */
204   if (*s != '(')
205     return 0; /* Invalid S-expression.  */
206   s++;
207   /* Skip over the algo+parameter list.  */
208   depth = 1;
209   if (sskip (&s, &depth) || depth)
210     return 0; /* Invalid S-expression.  */
211   if (*s != '(')
212     return 0; /* No futher list.  */
213   /* Check whether this is (hash ALGO).  */
214   s++;
215   n = snext (&s);
216   if (!n)
217     return 0; /* Invalid S-expression.  */
218   if (!smatch (&s, n, "hash"))
219     return 0; /* Not a "hash" keyword.  */
220   n = snext (&s);
221   if (!n || n+1 >= sizeof (buffer))
222     return 0; /* Algorithm string is missing or too long.  */
223   memcpy (buffer, s, n);
224   buffer[n] = 0;
225   
226   return gcry_md_map_name (buffer);
227 }
228
229
230 /* Create a public key S-expression for an RSA public key from the
231    modulus M with length MLEN and the public exponent E with length
232    ELEN.  Returns a newly allocated buffer of NULL in case of a memory
233    allocation problem.  If R_LEN is not NULL, the length of the
234    canonical S-expression is stored there. */
235 unsigned char *
236 make_canon_sexp_from_rsa_pk (const void *m_arg, size_t mlen,
237                              const void *e_arg, size_t elen,
238                              size_t *r_len)
239 {
240   const unsigned char *m = m_arg;
241   const unsigned char *e = e_arg;
242   int m_extra = 0;
243   int e_extra = 0;
244   char mlen_str[35];
245   char elen_str[35];
246   unsigned char *keybuf, *p;
247   const char const part1[] = "(10:public-key(3:rsa(1:n";
248   const char const part2[] = ")(1:e";
249   const char const part3[] = ")))";
250
251   /* Remove leading zeroes.  */
252   for (; mlen && !*m; mlen--, m++)
253     ;
254   for (; elen && !*e; elen--, e++)
255     ;
256       
257   /* Insert a leading zero if the number would be zero or interpreted
258      as negative.  */
259   if (!mlen || (m[0] & 0x80))
260     m_extra = 1;
261   if (!elen || (e[0] & 0x80))
262     e_extra = 1;
263
264   /* Build the S-expression.  */
265   snprintf (mlen_str, sizeof mlen_str, "%u:", (unsigned int)mlen+m_extra);
266   snprintf (elen_str, sizeof elen_str, "%u:", (unsigned int)elen+e_extra);
267
268   keybuf = xtrymalloc (strlen (part1) + strlen (mlen_str) + mlen + m_extra
269                        + strlen (part2) + strlen (elen_str) + elen + e_extra
270                        + strlen (part3) + 1);
271   if (!keybuf)
272     return NULL;
273   
274   p = stpcpy (keybuf, part1);
275   p = stpcpy (p, mlen_str);
276   if (m_extra)
277     *p++ = 0;
278   memcpy (p, m, mlen);
279   p += mlen;
280   p = stpcpy (p, part2);
281   p = stpcpy (p, elen_str);
282   if (e_extra)
283     *p++ = 0;
284   memcpy (p, e, elen);
285   p += elen;
286   p = stpcpy (p, part3);
287  
288   if (r_len)
289     *r_len = p - keybuf;
290
291   return keybuf;
292 }
293
294
295 /* Return the parameters of a public RSA key expressed as an
296    canonical encoded S-expression.  */
297 gpg_error_t
298 get_rsa_pk_from_canon_sexp (const unsigned char *keydata, size_t keydatalen,
299                             unsigned char const **r_n, size_t *r_nlen,
300                             unsigned char const **r_e, size_t *r_elen)
301 {
302   gpg_error_t err;
303   const unsigned char *buf, *tok;
304   size_t buflen, toklen;
305   int depth, last_depth1, last_depth2;
306   const unsigned char *rsa_n = NULL;
307   const unsigned char *rsa_e = NULL;
308   size_t rsa_n_len, rsa_e_len;
309
310   *r_n = NULL;
311   *r_nlen = 0;
312   *r_e = NULL;
313   *r_elen = 0;
314
315   buf = keydata;
316   buflen = keydatalen;
317   depth = 0;
318   if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
319     return err;
320   if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
321     return err;
322   if (!tok || toklen != 10 || memcmp ("public-key", tok, toklen))
323     return gpg_error (GPG_ERR_BAD_PUBKEY);
324   if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
325     return err;
326   if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
327     return err;
328   if (!tok || toklen != 3 || memcmp ("rsa", tok, toklen))
329     return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
330
331   last_depth1 = depth;
332   while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))
333          && depth && depth >= last_depth1)
334     {
335       if (tok)
336         return gpg_error (GPG_ERR_UNKNOWN_SEXP);
337       if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
338         return err;
339       if (tok && toklen == 1)
340         {
341           const unsigned char **mpi;
342           size_t *mpi_len;
343
344           switch (*tok)
345             {
346             case 'n': mpi = &rsa_n; mpi_len = &rsa_n_len; break; 
347             case 'e': mpi = &rsa_e; mpi_len = &rsa_e_len; break; 
348             default:  mpi = NULL;   mpi_len = NULL; break;
349             }
350           if (mpi && *mpi)
351             return gpg_error (GPG_ERR_DUP_VALUE);
352
353           if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
354             return err;
355           if (tok && mpi)
356             {
357               /* Strip off leading zero bytes and save. */
358               for (;toklen && !*tok; toklen--, tok++)
359                 ;
360               *mpi = tok;
361               *mpi_len = toklen;
362             }
363         }
364
365       /* Skip to the end of the list. */
366       last_depth2 = depth;
367       while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))
368              && depth && depth >= last_depth2)
369         ;
370       if (err)
371         return err;
372     }
373
374   if (err)
375     return err;
376
377   if (!rsa_n || !rsa_n_len || !rsa_e || !rsa_e_len)
378     return gpg_error (GPG_ERR_BAD_PUBKEY);
379
380   *r_n = rsa_n;
381   *r_nlen = rsa_n_len;
382   *r_e = rsa_e;
383   *r_elen = rsa_e_len;
384   return 0;
385 }
386
387
388 /* Return the algo of a public RSA expressed as an canonical encoded
389    S-expression.  On error the algo is set to 0. */
390 gpg_error_t
391 get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen,
392                              int *r_algo)
393 {
394   gpg_error_t err;
395   const unsigned char *buf, *tok;
396   size_t buflen, toklen;
397   int depth;
398     
399   *r_algo = 0;
400
401   buf = keydata;
402   buflen = keydatalen;
403   depth = 0;
404   if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
405     return err;
406   if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
407     return err;
408   if (!tok || toklen != 10 || memcmp ("public-key", tok, toklen))
409     return gpg_error (GPG_ERR_BAD_PUBKEY);
410   if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
411     return err;
412   if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
413     return err;
414   if (!tok)
415     return gpg_error (GPG_ERR_BAD_PUBKEY);
416
417   if (toklen == 3 && !memcmp ("rsa", tok, toklen))
418     *r_algo = GCRY_PK_RSA;
419   else if (toklen == 3 && !memcmp ("dsa", tok, toklen))
420     *r_algo = GCRY_PK_DSA;
421   else if (toklen == 3 && !memcmp ("elg", tok, toklen))
422     *r_algo = GCRY_PK_ELG;
423   else if (toklen == 5 && !memcmp ("ecdsa", tok, toklen))
424     *r_algo = GCRY_PK_ECDSA;
425   else
426     return  gpg_error (GPG_ERR_PUBKEY_ALGO);
427
428   return 0;
429 }