chiark / gitweb /
dirmngr: Drop useless housekeeping.
[gnupg2.git] / common / sexputil.c
1 /* sexputil.c - Utility functions for S-expressions.
2  * Copyright (C) 2005, 2007, 2009 Free Software Foundation, Inc.
3  * Copyright (C) 2013 Werner Koch
4  *
5  * This file is part of GnuPG.
6  *
7  * This file is free software; you can redistribute it and/or modify
8  * it under the terms of either
9  *
10  *   - the GNU Lesser General Public License as published by the Free
11  *     Software Foundation; either version 3 of the License, or (at
12  *     your option) any later version.
13  *
14  * or
15  *
16  *   - the GNU General Public License as published by the Free
17  *     Software Foundation; either version 2 of the License, or (at
18  *     your option) any later version.
19  *
20  * or both in parallel, as here.
21  *
22  * This file is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, see <https://www.gnu.org/licenses/>.
29  */
30
31 /* This file implements a few utility functions useful when working
32    with canonical encrypted S-expresions (i.e. not the S-exprssion
33    objects from libgcrypt).  */
34
35 #include <config.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <unistd.h>
40 #include <errno.h>
41 #ifdef HAVE_LOCALE_H
42 #include <locale.h>
43 #endif
44
45 #include "util.h"
46 #include "tlv.h"
47 #include "sexp-parse.h"
48 #include "openpgpdefs.h"  /* for pubkey_algo_t */
49
50
51 /* Return a malloced string with the S-expression CANON in advanced
52    format.  Returns NULL on error.  */
53 static char *
54 sexp_to_string (gcry_sexp_t sexp)
55 {
56   size_t n;
57   char *result;
58
59   if (!sexp)
60     return NULL;
61   n = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);
62   if (!n)
63     return NULL;
64   result = xtrymalloc (n);
65   if (!result)
66     return NULL;
67   n = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, result, n);
68   if (!n)
69     BUG ();
70
71   return result;
72 }
73
74
75 /* Return a malloced string with the S-expression CANON in advanced
76    format.  Returns NULL on error.  */
77 char *
78 canon_sexp_to_string (const unsigned char *canon, size_t canonlen)
79 {
80   size_t n;
81   gcry_sexp_t sexp;
82   char *result;
83
84   n = gcry_sexp_canon_len (canon, canonlen, NULL, NULL);
85   if (!n)
86     return NULL;
87   if (gcry_sexp_sscan (&sexp, NULL, canon, n))
88     return NULL;
89   result = sexp_to_string (sexp);
90   gcry_sexp_release (sexp);
91   return result;
92 }
93
94
95 /* Print the canonical encoded S-expression in SEXP in advanced
96    format.  SEXPLEN may be passed as 0 is SEXP is known to be valid.
97    With TEXT of NULL print just the raw S-expression, with TEXT just
98    an empty string, print a trailing linefeed, otherwise print an
99    entire debug line. */
100 void
101 log_printcanon (const char *text, const unsigned char *sexp, size_t sexplen)
102 {
103   if (text && *text)
104     log_debug ("%s ", text);
105   if (sexp)
106     {
107       char *buf = canon_sexp_to_string (sexp, sexplen);
108       log_printf ("%s", buf? buf : "[invalid S-expression]");
109       xfree (buf);
110     }
111   if (text)
112     log_printf ("\n");
113 }
114
115
116 /* Print the gcryp S-expression in SEXP in advanced format.  With TEXT
117    of NULL print just the raw S-expression, with TEXT just an empty
118    string, print a trailing linefeed, otherwise print an entire debug
119    line. */
120 void
121 log_printsexp (const char *text, gcry_sexp_t sexp)
122 {
123   if (text && *text)
124     log_debug ("%s ", text);
125   if (sexp)
126     {
127       char *buf = sexp_to_string (sexp);
128       log_printf ("%s", buf? buf : "[invalid S-expression]");
129       xfree (buf);
130     }
131   if (text)
132     log_printf ("\n");
133 }
134
135
136 /* Helper function to create a canonical encoded S-expression from a
137    Libgcrypt S-expression object.  The function returns 0 on success
138    and the malloced canonical S-expression is stored at R_BUFFER and
139    the allocated length at R_BUFLEN.  On error an error code is
140    returned and (NULL, 0) stored at R_BUFFER and R_BUFLEN.  If the
141    allocated buffer length is not required, NULL by be used for
142    R_BUFLEN.  */
143 gpg_error_t
144 make_canon_sexp (gcry_sexp_t sexp, unsigned char **r_buffer, size_t *r_buflen)
145 {
146   size_t len;
147   unsigned char *buf;
148
149   *r_buffer = NULL;
150   if (r_buflen)
151     *r_buflen = 0;;
152
153   len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, NULL, 0);
154   if (!len)
155     return gpg_error (GPG_ERR_BUG);
156   buf = xtrymalloc (len);
157   if (!buf)
158     return gpg_error_from_syserror ();
159   len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, buf, len);
160   if (!len)
161     return gpg_error (GPG_ERR_BUG);
162
163   *r_buffer = buf;
164   if (r_buflen)
165     *r_buflen = len;
166
167   return 0;
168 }
169
170
171 /* Same as make_canon_sexp but pad the buffer to multiple of 64
172    bits.  If SECURE is set, secure memory will be allocated.  */
173 gpg_error_t
174 make_canon_sexp_pad (gcry_sexp_t sexp, int secure,
175                      unsigned char **r_buffer, size_t *r_buflen)
176 {
177   size_t len;
178   unsigned char *buf;
179
180   *r_buffer = NULL;
181   if (r_buflen)
182     *r_buflen = 0;;
183
184   len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, NULL, 0);
185   if (!len)
186     return gpg_error (GPG_ERR_BUG);
187   len += (8 - len % 8) % 8;
188   buf = secure? xtrycalloc_secure (1, len) : xtrycalloc (1, len);
189   if (!buf)
190     return gpg_error_from_syserror ();
191   if (!gcry_sexp_sprint (sexp, GCRYSEXP_FMT_CANON, buf, len))
192     return gpg_error (GPG_ERR_BUG);
193
194   *r_buffer = buf;
195   if (r_buflen)
196     *r_buflen = len;
197
198   return 0;
199 }
200
201 /* Return the so called "keygrip" which is the SHA-1 hash of the
202    public key parameters expressed in a way depended on the algorithm.
203
204    KEY is expected to be an canonical encoded S-expression with a
205    public or private key. KEYLEN is the length of that buffer.
206
207    GRIP must be at least 20 bytes long.  On success 0 is returned, on
208    error an error code. */
209 gpg_error_t
210 keygrip_from_canon_sexp (const unsigned char *key, size_t keylen,
211                          unsigned char *grip)
212 {
213   gpg_error_t err;
214   gcry_sexp_t sexp;
215
216   if (!grip)
217     return gpg_error (GPG_ERR_INV_VALUE);
218   err = gcry_sexp_sscan (&sexp, NULL, (const char *)key, keylen);
219   if (err)
220     return err;
221   if (!gcry_pk_get_keygrip (sexp, grip))
222     err = gpg_error (GPG_ERR_INTERNAL);
223   gcry_sexp_release (sexp);
224   return err;
225 }
226
227
228 /* Compare two simple S-expressions like "(3:foo)".  Returns 0 if they
229    are identical or !0 if they are not.  Note that this function can't
230    be used for sorting. */
231 int
232 cmp_simple_canon_sexp (const unsigned char *a_orig,
233                        const unsigned char *b_orig)
234 {
235   const char *a = (const char *)a_orig;
236   const char *b = (const char *)b_orig;
237   unsigned long n1, n2;
238   char *endp;
239
240   if (!a && !b)
241     return 0; /* Both are NULL, they are identical. */
242   if (!a || !b)
243     return 1; /* One is NULL, they are not identical. */
244   if (*a != '(' || *b != '(')
245     log_bug ("invalid S-exp in cmp_simple_canon_sexp\n");
246
247   a++;
248   n1 = strtoul (a, &endp, 10);
249   a = endp;
250   b++;
251   n2 = strtoul (b, &endp, 10);
252   b = endp;
253
254   if (*a != ':' || *b != ':' )
255     log_bug ("invalid S-exp in cmp_simple_canon_sexp\n");
256   if (n1 != n2)
257     return 1; /* Not the same. */
258
259   for (a++, b++; n1; n1--, a++, b++)
260     if (*a != *b)
261       return 1; /* Not the same. */
262   return 0;
263 }
264
265
266 /* Create a simple S-expression from the hex string at LINE.  Returns
267    a newly allocated buffer with that canonical encoded S-expression
268    or NULL in case of an error.  On return the number of characters
269    scanned in LINE will be stored at NSCANNED.  This fucntions stops
270    converting at the first character not representing a hexdigit. Odd
271    numbers of hex digits are allowed; a leading zero is then
272    assumed. If no characters have been found, NULL is returned.*/
273 unsigned char *
274 make_simple_sexp_from_hexstr (const char *line, size_t *nscanned)
275 {
276   size_t n, len;
277   const char *s;
278   unsigned char *buf;
279   unsigned char *p;
280   char numbuf[50], *numbufp;
281   size_t numbuflen;
282
283   for (n=0, s=line; hexdigitp (s); s++, n++)
284     ;
285   if (nscanned)
286     *nscanned = n;
287   if (!n)
288     return NULL;
289   len = ((n+1) & ~0x01)/2;
290   numbufp = smklen (numbuf, sizeof numbuf, len, &numbuflen);
291   buf = xtrymalloc (1 + numbuflen + len + 1 + 1);
292   if (!buf)
293     return NULL;
294   buf[0] = '(';
295   p = (unsigned char *)stpcpy ((char *)buf+1, numbufp);
296   s = line;
297   if ((n&1))
298     {
299       *p++ = xtoi_1 (s);
300       s++;
301       n--;
302     }
303   for (; n > 1; n -=2, s += 2)
304     *p++ = xtoi_2 (s);
305   *p++ = ')';
306   *p = 0; /* (Not really neaded.) */
307
308   return buf;
309 }
310
311
312 /* Return the hash algorithm from a KSBA sig-val. SIGVAL is a
313    canonical encoded S-expression.  Return 0 if the hash algorithm is
314    not encoded in SIG-VAL or it is not supported by libgcrypt.  */
315 int
316 hash_algo_from_sigval (const unsigned char *sigval)
317 {
318   const unsigned char *s = sigval;
319   size_t n;
320   int depth;
321   char buffer[50];
322
323   if (!s || *s != '(')
324     return 0; /* Invalid S-expression.  */
325   s++;
326   n = snext (&s);
327   if (!n)
328     return 0; /* Invalid S-expression.  */
329   if (!smatch (&s, n, "sig-val"))
330     return 0; /* Not a sig-val.  */
331   if (*s != '(')
332     return 0; /* Invalid S-expression.  */
333   s++;
334   /* Skip over the algo+parameter list.  */
335   depth = 1;
336   if (sskip (&s, &depth) || depth)
337     return 0; /* Invalid S-expression.  */
338   if (*s != '(')
339     return 0; /* No further list.  */
340   /* Check whether this is (hash ALGO).  */
341   s++;
342   n = snext (&s);
343   if (!n)
344     return 0; /* Invalid S-expression.  */
345   if (!smatch (&s, n, "hash"))
346     return 0; /* Not a "hash" keyword.  */
347   n = snext (&s);
348   if (!n || n+1 >= sizeof (buffer))
349     return 0; /* Algorithm string is missing or too long.  */
350   memcpy (buffer, s, n);
351   buffer[n] = 0;
352
353   return gcry_md_map_name (buffer);
354 }
355
356
357 /* Create a public key S-expression for an RSA public key from the
358    modulus M with length MLEN and the public exponent E with length
359    ELEN.  Returns a newly allocated buffer of NULL in case of a memory
360    allocation problem.  If R_LEN is not NULL, the length of the
361    canonical S-expression is stored there. */
362 unsigned char *
363 make_canon_sexp_from_rsa_pk (const void *m_arg, size_t mlen,
364                              const void *e_arg, size_t elen,
365                              size_t *r_len)
366 {
367   const unsigned char *m = m_arg;
368   const unsigned char *e = e_arg;
369   int m_extra = 0;
370   int e_extra = 0;
371   char mlen_str[35];
372   char elen_str[35];
373   unsigned char *keybuf, *p;
374   const char part1[] = "(10:public-key(3:rsa(1:n";
375   const char part2[] = ")(1:e";
376   const char part3[] = ")))";
377
378   /* Remove leading zeroes.  */
379   for (; mlen && !*m; mlen--, m++)
380     ;
381   for (; elen && !*e; elen--, e++)
382     ;
383
384   /* Insert a leading zero if the number would be zero or interpreted
385      as negative.  */
386   if (!mlen || (m[0] & 0x80))
387     m_extra = 1;
388   if (!elen || (e[0] & 0x80))
389     e_extra = 1;
390
391   /* Build the S-expression.  */
392   snprintf (mlen_str, sizeof mlen_str, "%u:", (unsigned int)mlen+m_extra);
393   snprintf (elen_str, sizeof elen_str, "%u:", (unsigned int)elen+e_extra);
394
395   keybuf = xtrymalloc (strlen (part1) + strlen (mlen_str) + mlen + m_extra
396                        + strlen (part2) + strlen (elen_str) + elen + e_extra
397                        + strlen (part3) + 1);
398   if (!keybuf)
399     return NULL;
400
401   p = stpcpy (keybuf, part1);
402   p = stpcpy (p, mlen_str);
403   if (m_extra)
404     *p++ = 0;
405   memcpy (p, m, mlen);
406   p += mlen;
407   p = stpcpy (p, part2);
408   p = stpcpy (p, elen_str);
409   if (e_extra)
410     *p++ = 0;
411   memcpy (p, e, elen);
412   p += elen;
413   p = stpcpy (p, part3);
414
415   if (r_len)
416     *r_len = p - keybuf;
417
418   return keybuf;
419 }
420
421
422 /* Return the parameters of a public RSA key expressed as an
423    canonical encoded S-expression.  */
424 gpg_error_t
425 get_rsa_pk_from_canon_sexp (const unsigned char *keydata, size_t keydatalen,
426                             unsigned char const **r_n, size_t *r_nlen,
427                             unsigned char const **r_e, size_t *r_elen)
428 {
429   gpg_error_t err;
430   const unsigned char *buf, *tok;
431   size_t buflen, toklen;
432   int depth, last_depth1, last_depth2;
433   const unsigned char *rsa_n = NULL;
434   const unsigned char *rsa_e = NULL;
435   size_t rsa_n_len, rsa_e_len;
436
437   *r_n = NULL;
438   *r_nlen = 0;
439   *r_e = NULL;
440   *r_elen = 0;
441
442   buf = keydata;
443   buflen = keydatalen;
444   depth = 0;
445   if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
446     return err;
447   if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
448     return err;
449   if (!tok || toklen != 10 || memcmp ("public-key", tok, toklen))
450     return gpg_error (GPG_ERR_BAD_PUBKEY);
451   if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
452     return err;
453   if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
454     return err;
455   if (!tok || toklen != 3 || memcmp ("rsa", tok, toklen))
456     return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
457
458   last_depth1 = depth;
459   while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))
460          && depth && depth >= last_depth1)
461     {
462       if (tok)
463         return gpg_error (GPG_ERR_UNKNOWN_SEXP);
464       if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
465         return err;
466       if (tok && toklen == 1)
467         {
468           const unsigned char **mpi;
469           size_t *mpi_len;
470
471           switch (*tok)
472             {
473             case 'n': mpi = &rsa_n; mpi_len = &rsa_n_len; break;
474             case 'e': mpi = &rsa_e; mpi_len = &rsa_e_len; break;
475             default:  mpi = NULL;   mpi_len = NULL; break;
476             }
477           if (mpi && *mpi)
478             return gpg_error (GPG_ERR_DUP_VALUE);
479
480           if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
481             return err;
482           if (tok && mpi)
483             {
484               /* Strip off leading zero bytes and save. */
485               for (;toklen && !*tok; toklen--, tok++)
486                 ;
487               *mpi = tok;
488               *mpi_len = toklen;
489             }
490         }
491
492       /* Skip to the end of the list. */
493       last_depth2 = depth;
494       while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))
495              && depth && depth >= last_depth2)
496         ;
497       if (err)
498         return err;
499     }
500
501   if (err)
502     return err;
503
504   if (!rsa_n || !rsa_n_len || !rsa_e || !rsa_e_len)
505     return gpg_error (GPG_ERR_BAD_PUBKEY);
506
507   *r_n = rsa_n;
508   *r_nlen = rsa_n_len;
509   *r_e = rsa_e;
510   *r_elen = rsa_e_len;
511   return 0;
512 }
513
514
515 /* Return the algo of a public RSA expressed as an canonical encoded
516    S-expression.  The return value is a statically allocated
517    string.  On error that string is set to NULL. */
518 gpg_error_t
519 get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen,
520                              const char **r_algo)
521 {
522   gpg_error_t err;
523   const unsigned char *buf, *tok;
524   size_t buflen, toklen;
525   int depth;
526
527   *r_algo = NULL;
528
529   buf = keydata;
530   buflen = keydatalen;
531   depth = 0;
532   if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
533     return err;
534   if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
535     return err;
536   if (!tok || toklen != 10 || memcmp ("public-key", tok, toklen))
537     return gpg_error (GPG_ERR_BAD_PUBKEY);
538   if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
539     return err;
540   if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
541     return err;
542   if (!tok)
543     return gpg_error (GPG_ERR_BAD_PUBKEY);
544
545   if (toklen == 3 && !memcmp ("rsa", tok, toklen))
546     *r_algo = "rsa";
547   else if (toklen == 3 && !memcmp ("dsa", tok, toklen))
548     *r_algo = "dsa";
549   else if (toklen == 3 && !memcmp ("elg", tok, toklen))
550     *r_algo = "elg";
551   else if (toklen == 5 && !memcmp ("ecdsa", tok, toklen))
552     *r_algo = "ecdsa";
553   else if (toklen == 5 && !memcmp ("eddsa", tok, toklen))
554     *r_algo = "eddsa";
555   else
556     return gpg_error (GPG_ERR_PUBKEY_ALGO);
557
558   return 0;
559 }
560
561
562 /* Return the algo of a public KEY of SEXP. */
563 int
564 get_pk_algo_from_key (gcry_sexp_t key)
565 {
566   gcry_sexp_t list;
567   const char *s;
568   size_t n;
569   char algoname[6];
570   int algo = 0;
571
572   list = gcry_sexp_nth (key, 1);
573   if (!list)
574     goto out;
575   s = gcry_sexp_nth_data (list, 0, &n);
576   if (!s)
577     goto out;
578   if (n >= sizeof (algoname))
579     goto out;
580   memcpy (algoname, s, n);
581   algoname[n] = 0;
582
583   algo = gcry_pk_map_name (algoname);
584   if (algo == GCRY_PK_ECC)
585     {
586       gcry_sexp_t l1 = gcry_sexp_find_token (list, "flags", 0);
587       int i;
588
589       for (i = l1 ? gcry_sexp_length (l1)-1 : 0; i > 0; i--)
590         {
591           s = gcry_sexp_nth_data (l1, i, &n);
592           if (!s)
593             continue; /* Not a data element. */
594
595           if (n == 5 && !memcmp (s, "eddsa", 5))
596             {
597               algo = GCRY_PK_EDDSA;
598               break;
599             }
600         }
601       gcry_sexp_release (l1);
602     }
603
604  out:
605   gcry_sexp_release (list);
606
607   return algo;
608 }