chiark / gitweb /
Import gnupg2_2.1.17.orig.tar.bz2
[gnupg2.git] / common / name-value.c
1 /* name-value.c - Parser and writer for a name-value format.
2  *      Copyright (C) 2016 g10 Code GmbH
3  *
4  * This file is part of GnuPG.
5  *
6  * This file is free software; you can redistribute it and/or modify
7  * it under the terms of either
8  *
9  *   - the GNU Lesser General Public License as published by the Free
10  *     Software Foundation; either version 3 of the License, or (at
11  *     your option) any later version.
12  *
13  * or
14  *
15  *   - the GNU General Public License as published by the Free
16  *     Software Foundation; either version 2 of the License, or (at
17  *     your option) any later version.
18  *
19  * or both in parallel, as here.
20  *
21  * GnuPG is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, see <https://www.gnu.org/licenses/>.
28  */
29
30 /*
31  * This module aso provides features for the extended private key
32  * format of gpg-agent.
33  */
34
35 #include <config.h>
36 #include <assert.h>
37 #include <gcrypt.h>
38 #include <gpg-error.h>
39 #include <string.h>
40
41 #include "mischelp.h"
42 #include "strlist.h"
43 #include "util.h"
44 #include "name-value.h"
45
46 struct name_value_container
47 {
48   struct name_value_entry *first;
49   struct name_value_entry *last;
50   unsigned int private_key_mode:1;
51 };
52
53
54 struct name_value_entry
55 {
56   struct name_value_entry *prev;
57   struct name_value_entry *next;
58
59   /* The name.  Comments and blank lines have NAME set to NULL.  */
60   char *name;
61
62   /* The value as stored in the file.  We store it when when we parse
63      a file so that we can reproduce it.  */
64   strlist_t raw_value;
65
66   /* The decoded value.  */
67   char *value;
68 };
69
70
71 /* Helper */
72 static inline gpg_error_t
73 my_error_from_syserror (void)
74 {
75   return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
76 }
77
78
79 static inline gpg_error_t
80 my_error (gpg_err_code_t ec)
81 {
82   return gpg_err_make (default_errsource, ec);
83 }
84
85
86 \f
87
88 /* Allocation and deallocation.  */
89
90 /* Allocate a private key container structure.  */
91 nvc_t
92 nvc_new (void)
93 {
94   return xtrycalloc (1, sizeof (struct name_value_container));
95 }
96
97
98 /* Allocate a private key container structure for use with private keys.  */
99 nvc_t
100 nvc_new_private_key (void)
101 {
102   nvc_t nvc = nvc_new ();
103   if (nvc)
104     nvc->private_key_mode = 1;
105   return nvc;
106 }
107
108
109 static void
110 nve_release (nve_t entry, int private_key_mode)
111 {
112   if (entry == NULL)
113     return;
114
115   xfree (entry->name);
116   if (entry->value && private_key_mode)
117     wipememory (entry->value, strlen (entry->value));
118   xfree (entry->value);
119   if (private_key_mode)
120     free_strlist_wipe (entry->raw_value);
121   else
122     free_strlist (entry->raw_value);
123   xfree (entry);
124 }
125
126
127 /* Release a private key container structure.  */
128 void
129 nvc_release (nvc_t pk)
130 {
131   nve_t e, next;
132
133   if (pk == NULL)
134     return;
135
136   for (e = pk->first; e; e = next)
137     {
138       next = e->next;
139       nve_release (e, pk->private_key_mode);
140     }
141
142   xfree (pk);
143 }
144
145 \f
146
147 /* Dealing with names and values.  */
148
149 /* Check whether the given name is valid.  Valid names start with a
150    letter, end with a colon, and contain only alphanumeric characters
151    and the hyphen.  */
152 static int
153 valid_name (const char *name)
154 {
155   size_t i, len = strlen (name);
156
157   if (! alphap (name) || len == 0 || name[len - 1] != ':')
158     return 0;
159
160   for (i = 1; i < len - 1; i++)
161     if (! alnump (&name[i]) && name[i] != '-')
162       return 0;
163
164   return 1;
165 }
166
167
168 /* Makes sure that ENTRY has a RAW_VALUE.  */
169 static gpg_error_t
170 assert_raw_value (nve_t entry)
171 {
172   gpg_error_t err = 0;
173   size_t len, offset;
174 #define LINELEN 70
175   char buf[LINELEN+3];
176
177   if (entry->raw_value)
178     return 0;
179
180   len = strlen (entry->value);
181   offset = 0;
182   while (len)
183     {
184       size_t amount, linelen = LINELEN;
185
186       /* On the first line we need to subtract space for the name.  */
187       if (entry->raw_value == NULL && strlen (entry->name) < linelen)
188         linelen -= strlen (entry->name);
189
190       /* See if the rest of the value fits in this line.  */
191       if (len <= linelen)
192         amount = len;
193       else
194         {
195           size_t i;
196
197           /* Find a suitable space to break on.  */
198           for (i = linelen - 1; linelen - i < 30 && linelen - i > offset; i--)
199             if (ascii_isspace (entry->value[i]))
200               break;
201
202           if (ascii_isspace (entry->value[i]))
203             {
204               /* Found one.  */
205               amount = i;
206             }
207           else
208             {
209               /* Just induce a hard break.  */
210               amount = linelen;
211             }
212         }
213
214       snprintf (buf, sizeof buf, " %.*s\n", (int) amount,
215                 &entry->value[offset]);
216       if (append_to_strlist_try (&entry->raw_value, buf) == NULL)
217         {
218           err = my_error_from_syserror ();
219           goto leave;
220         }
221
222       offset += amount;
223       len -= amount;
224     }
225
226  leave:
227   if (err)
228     {
229       free_strlist_wipe (entry->raw_value);
230       entry->raw_value = NULL;
231     }
232
233   return err;
234 #undef LINELEN
235 }
236
237
238 /* Computes the length of the value encoded as continuation.  If
239    *SWALLOW_WS is set, all whitespace at the beginning of S is
240    swallowed.  If START is given, a pointer to the beginning of the
241    value is stored there.  */
242 static size_t
243 continuation_length (const char *s, int *swallow_ws, const char **start)
244 {
245   size_t len;
246
247   if (*swallow_ws)
248     {
249       /* The previous line was a blank line and we inserted a newline.
250          Swallow all whitespace at the beginning of this line.  */
251       while (ascii_isspace (*s))
252         s++;
253     }
254   else
255     {
256       /* Iff a continuation starts with more than one space, it
257          encodes a space.  */
258       if (ascii_isspace (*s))
259         s++;
260     }
261
262   /* Strip whitespace at the end.  */
263   len = strlen (s);
264   while (len > 0 && ascii_isspace (s[len-1]))
265     len--;
266
267   if (len == 0)
268     {
269       /* Blank lines encode newlines.  */
270       len = 1;
271       s = "\n";
272       *swallow_ws = 1;
273     }
274   else
275     *swallow_ws = 0;
276
277   if (start)
278     *start = s;
279
280   return len;
281 }
282
283
284 /* Makes sure that ENTRY has a VALUE.  */
285 static gpg_error_t
286 assert_value (nve_t entry)
287 {
288   size_t len;
289   int swallow_ws;
290   strlist_t s;
291   char *p;
292
293   if (entry->value)
294     return 0;
295
296   len = 0;
297   swallow_ws = 0;
298   for (s = entry->raw_value; s; s = s->next)
299     len += continuation_length (s->d, &swallow_ws, NULL);
300
301   /* Add one for the terminating zero.  */
302   len += 1;
303
304   entry->value = p = xtrymalloc (len);
305   if (entry->value == NULL)
306     return my_error_from_syserror ();
307
308   swallow_ws = 0;
309   for (s = entry->raw_value; s; s = s->next)
310     {
311       const char *start;
312       size_t l = continuation_length (s->d, &swallow_ws, &start);
313
314       memcpy (p, start, l);
315       p += l;
316     }
317
318   *p++ = 0;
319   assert (p - entry->value == len);
320
321   return 0;
322 }
323
324
325 /* Get the name.  */
326 char *
327 nve_name (nve_t pke)
328 {
329   return pke->name;
330 }
331
332
333 /* Get the value.  */
334 char *
335 nve_value (nve_t pke)
336 {
337   if (assert_value (pke))
338     return NULL;
339   return pke->value;
340 }
341
342 \f
343
344 /* Adding and modifying values.  */
345
346 /* Add (NAME, VALUE, RAW_VALUE) to PK.  NAME may be NULL for comments
347    and blank lines.  At least one of VALUE and RAW_VALUE must be
348    given.  If PRESERVE_ORDER is not given, entries with the same name
349    are grouped.  NAME, VALUE and RAW_VALUE is consumed.  */
350 static gpg_error_t
351 _nvc_add (nvc_t pk, char *name, char *value, strlist_t raw_value,
352           int preserve_order)
353 {
354   gpg_error_t err = 0;
355   nve_t e;
356
357   assert (value || raw_value);
358
359   if (name && ! valid_name (name))
360     {
361       err = my_error (GPG_ERR_INV_NAME);
362       goto leave;
363     }
364
365   if (name
366       && pk->private_key_mode
367       && !ascii_strcasecmp (name, "Key:")
368       && nvc_lookup (pk, "Key:"))
369     {
370       err = my_error (GPG_ERR_INV_NAME);
371       goto leave;
372     }
373
374   e = xtrycalloc (1, sizeof *e);
375   if (e == NULL)
376     {
377       err = my_error_from_syserror ();
378       goto leave;
379     }
380
381   e->name = name;
382   e->value = value;
383   e->raw_value = raw_value;
384
385   if (pk->first)
386     {
387       nve_t last;
388
389       if (preserve_order || name == NULL)
390         last = pk->last;
391       else
392         {
393           /* See if there is already an entry with NAME.  */
394           last = nvc_lookup (pk, name);
395
396           /* If so, find the last in that block.  */
397           if (last)
398             {
399               while (last->next)
400                 {
401                   nve_t next = last->next;
402
403                   if (next->name && ascii_strcasecmp (next->name, name) == 0)
404                     last = next;
405                   else
406                     break;
407                 }
408             }
409           else /* Otherwise, just find the last entry.  */
410             last = pk->last;
411         }
412
413       if (last->next)
414         {
415           e->prev = last;
416           e->next = last->next;
417           last->next = e;
418           e->next->prev = e;
419         }
420       else
421         {
422           e->prev = last;
423           last->next = e;
424           pk->last = e;
425         }
426     }
427   else
428     pk->first = pk->last = e;
429
430  leave:
431   if (err)
432     {
433       xfree (name);
434       if (value)
435         wipememory (value, strlen (value));
436       xfree (value);
437       free_strlist_wipe (raw_value);
438     }
439
440   return err;
441 }
442
443
444 /* Add (NAME, VALUE) to PK.  If an entry with NAME already exists, it
445    is not updated but the new entry is appended.  */
446 gpg_error_t
447 nvc_add (nvc_t pk, const char *name, const char *value)
448 {
449   char *k, *v;
450
451   k = xtrystrdup (name);
452   if (k == NULL)
453     return my_error_from_syserror ();
454
455   v = xtrystrdup (value);
456   if (v == NULL)
457     {
458       xfree (k);
459       return my_error_from_syserror ();
460     }
461
462   return _nvc_add (pk, k, v, NULL, 0);
463 }
464
465
466 /* Add (NAME, VALUE) to PK.  If an entry with NAME already exists, it
467    is updated with VALUE.  If multiple entries with NAME exist, the
468    first entry is updated.  */
469 gpg_error_t
470 nvc_set (nvc_t pk, const char *name, const char *value)
471 {
472   nve_t e;
473
474   if (! valid_name (name))
475     return GPG_ERR_INV_NAME;
476
477   e = nvc_lookup (pk, name);
478   if (e)
479     {
480       char *v;
481
482       v = xtrystrdup (value);
483       if (v == NULL)
484         return my_error_from_syserror ();
485
486       free_strlist_wipe (e->raw_value);
487       e->raw_value = NULL;
488       if (e->value)
489         wipememory (e->value, strlen (e->value));
490       xfree (e->value);
491       e->value = v;
492
493       return 0;
494     }
495   else
496     return nvc_add (pk, name, value);
497 }
498
499
500 /* Delete the given entry from PK.  */
501 void
502 nvc_delete (nvc_t pk, nve_t entry)
503 {
504   if (entry->prev)
505     entry->prev->next = entry->next;
506   else
507     pk->first = entry->next;
508
509   if (entry->next)
510     entry->next->prev = entry->prev;
511   else
512     pk->last = entry->prev;
513
514   nve_release (entry, pk->private_key_mode);
515 }
516
517 \f
518
519 /* Lookup and iteration.  */
520
521 /* Get the first non-comment entry.  */
522 nve_t
523 nvc_first (nvc_t pk)
524 {
525   nve_t entry;
526   for (entry = pk->first; entry; entry = entry->next)
527     if (entry->name)
528       return entry;
529   return NULL;
530 }
531
532
533 /* Get the first entry with the given name.  */
534 nve_t
535 nvc_lookup (nvc_t pk, const char *name)
536 {
537   nve_t entry;
538   for (entry = pk->first; entry; entry = entry->next)
539     if (entry->name && ascii_strcasecmp (entry->name, name) == 0)
540       return entry;
541   return NULL;
542 }
543
544
545 /* Get the next non-comment entry.  */
546 nve_t
547 nve_next (nve_t entry)
548 {
549   for (entry = entry->next; entry; entry = entry->next)
550     if (entry->name)
551       return entry;
552   return NULL;
553 }
554
555
556 /* Get the next entry with the given name.  */
557 nve_t
558 nve_next_value (nve_t entry, const char *name)
559 {
560   for (entry = entry->next; entry; entry = entry->next)
561     if (entry->name && ascii_strcasecmp (entry->name, name) == 0)
562       return entry;
563   return NULL;
564 }
565
566 \f
567
568 /* Private key handling.  */
569
570 /* Get the private key.  */
571 gpg_error_t
572 nvc_get_private_key (nvc_t pk, gcry_sexp_t *retsexp)
573 {
574   gpg_error_t err;
575   nve_t e;
576
577   e = pk->private_key_mode? nvc_lookup (pk, "Key:") : NULL;
578   if (e == NULL)
579     return my_error (GPG_ERR_MISSING_KEY);
580
581   err = assert_value (e);
582   if (err)
583     return err;
584
585   return gcry_sexp_sscan (retsexp, NULL, e->value, strlen (e->value));
586 }
587
588
589 /* Set the private key.  */
590 gpg_error_t
591 nvc_set_private_key (nvc_t pk, gcry_sexp_t sexp)
592 {
593   gpg_error_t err;
594   char *raw, *clean, *p;
595   size_t len, i;
596
597   if (!pk->private_key_mode)
598     return my_error (GPG_ERR_MISSING_KEY);
599
600   len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);
601
602   raw = xtrymalloc (len);
603   if (raw == NULL)
604     return my_error_from_syserror ();
605
606   clean = xtrymalloc (len);
607   if (clean == NULL)
608     {
609       xfree (raw);
610       return my_error_from_syserror ();
611     }
612
613   gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, raw, len);
614
615   /* Strip any whitespace at the end.  */
616   i = strlen (raw) - 1;
617   while (i && ascii_isspace (raw[i]))
618     {
619       raw[i] = 0;
620       i--;
621     }
622
623   /* Replace any newlines with spaces, remove superfluous whitespace.  */
624   len = strlen (raw);
625   for (p = clean, i = 0; i < len; i++)
626     {
627       char c = raw[i];
628
629       /* Collapse contiguous and superfluous spaces.  */
630       if (ascii_isspace (c) && i > 0
631           && (ascii_isspace (raw[i-1]) || raw[i-1] == '(' || raw[i-1] == ')'))
632         continue;
633
634       if (c == '\n')
635         c = ' ';
636
637       *p++ = c;
638     }
639   *p = 0;
640
641   err = nvc_set (pk, "Key:", clean);
642   xfree (raw);
643   xfree (clean);
644   return err;
645 }
646
647 \f
648
649 /* Parsing and serialization.  */
650
651 static gpg_error_t
652 do_nvc_parse (nvc_t *result, int *errlinep, estream_t stream,
653               int for_private_key)
654 {
655   gpg_error_t err = 0;
656   gpgrt_ssize_t len;
657   char *buf = NULL;
658   size_t buf_len = 0;
659   char *name = NULL;
660   strlist_t raw_value = NULL;
661
662   *result = for_private_key? nvc_new_private_key () : nvc_new ();
663   if (*result == NULL)
664     return my_error_from_syserror ();
665
666   if (errlinep)
667     *errlinep = 0;
668   while ((len = es_read_line (stream, &buf, &buf_len, NULL)) > 0)
669     {
670       char *p;
671       if (errlinep)
672         *errlinep += 1;
673
674       /* Skip any whitespace.  */
675       for (p = buf; *p && ascii_isspace (*p); p++)
676         /* Do nothing.  */;
677
678       if (name && (spacep (buf) || *p == 0))
679         {
680           /* A continuation.  */
681           if (append_to_strlist_try (&raw_value, buf) == NULL)
682             {
683               err = my_error_from_syserror ();
684               goto leave;
685             }
686           continue;
687         }
688
689       /* No continuation.  Add the current entry if any.  */
690       if (raw_value)
691         {
692           err = _nvc_add (*result, name, NULL, raw_value, 1);
693           if (err)
694             goto leave;
695         }
696
697       /* And prepare for the next one.  */
698       name = NULL;
699       raw_value = NULL;
700
701       if (*p != 0 && *p != '#')
702         {
703           char *colon, *value, tmp;
704
705           colon = strchr (buf, ':');
706           if (colon == NULL)
707             {
708               err = my_error (GPG_ERR_INV_VALUE);
709               goto leave;
710             }
711
712           value = colon + 1;
713           tmp = *value;
714           *value = 0;
715           name = xtrystrdup (p);
716           *value = tmp;
717
718           if (name == NULL)
719             {
720               err = my_error_from_syserror ();
721               goto leave;
722             }
723
724           if (append_to_strlist_try (&raw_value, value) == NULL)
725             {
726               err = my_error_from_syserror ();
727               goto leave;
728             }
729           continue;
730         }
731
732       if (append_to_strlist_try (&raw_value, buf) == NULL)
733         {
734           err = my_error_from_syserror ();
735           goto leave;
736         }
737     }
738   if (len < 0)
739     {
740       err = gpg_error_from_syserror ();
741       goto leave;
742     }
743
744   /* Add the final entry.  */
745   if (raw_value)
746     err = _nvc_add (*result, name, NULL, raw_value, 1);
747
748  leave:
749   gpgrt_free (buf);
750   if (err)
751     {
752       nvc_release (*result);
753       *result = NULL;
754     }
755
756   return err;
757 }
758
759
760 /* Parse STREAM and return a newly allocated name value container
761    structure in RESULT.  If ERRLINEP is given, the line number the
762    parser was last considering is stored there.  */
763 gpg_error_t
764 nvc_parse (nvc_t *result, int *errlinep, estream_t stream)
765 {
766   return do_nvc_parse (result, errlinep, stream, 0);
767 }
768
769
770 /* Parse STREAM and return a newly allocated name value container
771    structure in RESULT - assuming the extended private key format.  If
772    ERRLINEP is given, the line number the parser was last considering
773    is stored there.  */
774 gpg_error_t
775 nvc_parse_private_key (nvc_t *result, int *errlinep, estream_t stream)
776 {
777   return do_nvc_parse (result, errlinep, stream, 1);
778 }
779
780
781 /* Write a representation of PK to STREAM.  */
782 gpg_error_t
783 nvc_write (nvc_t pk, estream_t stream)
784 {
785   gpg_error_t err;
786   nve_t entry;
787   strlist_t s;
788
789   for (entry = pk->first; entry; entry = entry->next)
790     {
791       if (entry->name)
792         es_fputs (entry->name, stream);
793
794       err = assert_raw_value (entry);
795       if (err)
796         return err;
797
798       for (s = entry->raw_value; s; s = s->next)
799         es_fputs (s->d, stream);
800
801       if (es_ferror (stream))
802         return my_error_from_syserror ();
803     }
804
805   return 0;
806 }