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