7c6cb6af58acfe2fba72f4e117707160a973d228
[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.  Not 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 LIBNE.  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 so called "keygrip" which is the SHA-1 hash of the
296    public key parameters expressed in a way depended on the algorithm.
297
298    KEY is expected to be an canonical encoded S-expression with a
299    public or private key. KEYLEN is the length of that buffer.
300
301    GRIP must be at least 20 bytes long.  On success 0 is returned, on
302    error an error code. */
303 gpg_error_t
304 get_rsa_pk_from_canon_sexp (const unsigned char *keydata, size_t keydatalen,
305                             unsigned char const **r_n, size_t *r_nlen,
306                             unsigned char const **r_e, size_t *r_elen)
307 {
308   gpg_error_t err;
309   const unsigned char *buf, *tok;
310   size_t buflen, toklen;
311   int depth, last_depth1, last_depth2;
312   const unsigned char *rsa_n = NULL;
313   const unsigned char *rsa_e = NULL;
314   size_t rsa_n_len, rsa_e_len;
315
316   *r_n = NULL;
317   *r_nlen = 0;
318   *r_e = NULL;
319   *r_elen = 0;
320
321   buf = keydata;
322   buflen = keydatalen;
323   depth = 0;
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 != 10 || memcmp ("public-key", tok, toklen))
329     return gpg_error (GPG_ERR_BAD_PUBKEY);
330   if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
331     return err;
332   if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
333     return err;
334   if (!tok || toklen != 3 || memcmp ("rsa", tok, toklen))
335     return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
336
337   last_depth1 = depth;
338   while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))
339          && depth && depth >= last_depth1)
340     {
341       if (tok)
342         return gpg_error (GPG_ERR_UNKNOWN_SEXP);
343       if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
344         return err;
345       if (tok && toklen == 1)
346         {
347           const unsigned char **mpi;
348           size_t *mpi_len;
349
350           switch (*tok)
351             {
352             case 'n': mpi = &rsa_n; mpi_len = &rsa_n_len; break; 
353             case 'e': mpi = &rsa_e; mpi_len = &rsa_e_len; break; 
354             default:  mpi = NULL;   mpi_len = NULL; break;
355             }
356           if (mpi && *mpi)
357             return gpg_error (GPG_ERR_DUP_VALUE);
358
359           if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
360             return err;
361           if (tok && mpi)
362             {
363               /* Strip off leading zero bytes and save. */
364               for (;toklen && !*tok; toklen--, tok++)
365                 ;
366               *mpi = tok;
367               *mpi_len = toklen;
368             }
369         }
370
371       /* Skip to the end of the list. */
372       last_depth2 = depth;
373       while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))
374              && depth && depth >= last_depth2)
375         ;
376       if (err)
377         return err;
378     }
379
380   if (!rsa_n || !rsa_n_len || !rsa_e || !rsa_e_len)
381     return gpg_error (GPG_ERR_BAD_PUBKEY);
382
383   *r_n = rsa_n;
384   *r_nlen = rsa_n_len;
385   *r_e = rsa_e;
386   *r_elen = rsa_e_len;
387   return 0;
388 }