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 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
my_error_from_syserror(void)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
my_error(gpg_err_code_t ec)80 my_error (gpg_err_code_t ec)
81 {
82   return gpg_err_make (default_errsource, ec);
83 }
84 
85 
86 
87 
88 /* Allocation and deallocation.  */
89 
90 /* Allocate a private key container structure.  */
91 nvc_t
nvc_new(void)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
nvc_new_private_key(void)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
nve_release(nve_t entry,int private_key_mode)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
nvc_release(nvc_t pk)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 
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
valid_name(const char * name)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
assert_raw_value(nve_t entry)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; i--)
199 	    if (ascii_isspace (entry->value[offset+i]))
200 	      break;
201 
202 	  if (ascii_isspace (entry->value[offset+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
continuation_length(const char * s,int * swallow_ws,const char ** start)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
assert_value(nve_t entry)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 *
nve_name(nve_t pke)327 nve_name (nve_t pke)
328 {
329   return pke->name;
330 }
331 
332 
333 /* Get the value.  */
334 char *
nve_value(nve_t pke)335 nve_value (nve_t pke)
336 {
337   if (assert_value (pke))
338     return NULL;
339   return pke->value;
340 }
341 
342 
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
_nvc_add(nvc_t pk,char * name,char * value,strlist_t raw_value,int preserve_order)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
nvc_add(nvc_t pk,const char * name,const char * value)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
nvc_set(nvc_t pk,const char * name,const char * value)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
nvc_delete(nvc_t pk,nve_t entry)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 
518 /* Delete the entries with NAME from PK.  */
519 void
nvc_delete_named(nvc_t pk,const char * name)520 nvc_delete_named (nvc_t pk, const char *name)
521 {
522   nve_t e;
523 
524   if (!valid_name (name))
525     return;
526 
527   while ((e = nvc_lookup (pk, name)))
528     nvc_delete (pk, e);
529 }
530 
531 
532 
533 
534 /* Lookup and iteration.  */
535 
536 /* Get the first non-comment entry.  */
537 nve_t
nvc_first(nvc_t pk)538 nvc_first (nvc_t pk)
539 {
540   nve_t entry;
541   for (entry = pk->first; entry; entry = entry->next)
542     if (entry->name)
543       return entry;
544   return NULL;
545 }
546 
547 
548 /* Get the first entry with the given name.  */
549 nve_t
nvc_lookup(nvc_t pk,const char * name)550 nvc_lookup (nvc_t pk, const char *name)
551 {
552   nve_t entry;
553   for (entry = pk->first; entry; entry = entry->next)
554     if (entry->name && ascii_strcasecmp (entry->name, name) == 0)
555       return entry;
556   return NULL;
557 }
558 
559 
560 /* Get the next non-comment entry.  */
561 nve_t
nve_next(nve_t entry)562 nve_next (nve_t entry)
563 {
564   for (entry = entry->next; entry; entry = entry->next)
565     if (entry->name)
566       return entry;
567   return NULL;
568 }
569 
570 
571 /* Get the next entry with the given name.  */
572 nve_t
nve_next_value(nve_t entry,const char * name)573 nve_next_value (nve_t entry, const char *name)
574 {
575   for (entry = entry->next; entry; entry = entry->next)
576     if (entry->name && ascii_strcasecmp (entry->name, name) == 0)
577       return entry;
578   return NULL;
579 }
580 
581 
582 /* Return the string for the first entry in NVC with NAME.  If an
583  * entry with NAME is missing in NVC or its value is the empty string
584  * NULL is returned.  Note that the The returned string is a pointer
585  * into NVC.  */
586 const char *
nvc_get_string(nvc_t nvc,const char * name)587 nvc_get_string (nvc_t nvc, const char *name)
588 {
589   nve_t item;
590 
591   if (!nvc)
592     return NULL;
593   item = nvc_lookup (nvc, name);
594   if (!item)
595     return NULL;
596   return nve_value (item);
597 }
598 
599 
600 
601 
602 /* Private key handling.  */
603 
604 /* Get the private key.  */
605 gpg_error_t
nvc_get_private_key(nvc_t pk,gcry_sexp_t * retsexp)606 nvc_get_private_key (nvc_t pk, gcry_sexp_t *retsexp)
607 {
608   gpg_error_t err;
609   nve_t e;
610 
611   e = pk->private_key_mode? nvc_lookup (pk, "Key:") : NULL;
612   if (e == NULL)
613     return my_error (GPG_ERR_MISSING_KEY);
614 
615   err = assert_value (e);
616   if (err)
617     return err;
618 
619   return gcry_sexp_sscan (retsexp, NULL, e->value, strlen (e->value));
620 }
621 
622 
623 /* Set the private key.  */
624 gpg_error_t
nvc_set_private_key(nvc_t pk,gcry_sexp_t sexp)625 nvc_set_private_key (nvc_t pk, gcry_sexp_t sexp)
626 {
627   gpg_error_t err;
628   char *raw, *clean, *p;
629   size_t len, i;
630 
631   if (!pk->private_key_mode)
632     return my_error (GPG_ERR_MISSING_KEY);
633 
634   len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);
635 
636   raw = xtrymalloc (len);
637   if (raw == NULL)
638     return my_error_from_syserror ();
639 
640   clean = xtrymalloc (len);
641   if (clean == NULL)
642     {
643       xfree (raw);
644       return my_error_from_syserror ();
645     }
646 
647   gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, raw, len);
648 
649   /* Strip any whitespace at the end.  */
650   i = strlen (raw) - 1;
651   while (i && ascii_isspace (raw[i]))
652     {
653       raw[i] = 0;
654       i--;
655     }
656 
657   /* Replace any newlines with spaces, remove superfluous whitespace.  */
658   len = strlen (raw);
659   for (p = clean, i = 0; i < len; i++)
660     {
661       char c = raw[i];
662 
663       /* Collapse contiguous and superfluous spaces.  */
664       if (ascii_isspace (c) && i > 0
665 	  && (ascii_isspace (raw[i-1]) || raw[i-1] == '(' || raw[i-1] == ')'))
666 	continue;
667 
668       if (c == '\n')
669 	c = ' ';
670 
671       *p++ = c;
672     }
673   *p = 0;
674 
675   err = nvc_set (pk, "Key:", clean);
676   xfree (raw);
677   xfree (clean);
678   return err;
679 }
680 
681 
682 
683 /* Parsing and serialization.  */
684 
685 static gpg_error_t
do_nvc_parse(nvc_t * result,int * errlinep,estream_t stream,int for_private_key)686 do_nvc_parse (nvc_t *result, int *errlinep, estream_t stream,
687               int for_private_key)
688 {
689   gpg_error_t err = 0;
690   gpgrt_ssize_t len;
691   char *buf = NULL;
692   size_t buf_len = 0;
693   char *name = NULL;
694   strlist_t raw_value = NULL;
695 
696   *result = for_private_key? nvc_new_private_key () : nvc_new ();
697   if (*result == NULL)
698     return my_error_from_syserror ();
699 
700   if (errlinep)
701     *errlinep = 0;
702   while ((len = es_read_line (stream, &buf, &buf_len, NULL)) > 0)
703     {
704       char *p;
705       if (errlinep)
706 	*errlinep += 1;
707 
708       /* Skip any whitespace.  */
709       for (p = buf; *p && ascii_isspace (*p); p++)
710 	/* Do nothing.  */;
711 
712       if (name && (spacep (buf) || *p == 0))
713 	{
714 	  /* A continuation.  */
715 	  if (append_to_strlist_try (&raw_value, buf) == NULL)
716 	    {
717 	      err = my_error_from_syserror ();
718 	      goto leave;
719 	    }
720 	  continue;
721 	}
722 
723       /* No continuation.  Add the current entry if any.  */
724       if (raw_value)
725 	{
726 	  err = _nvc_add (*result, name, NULL, raw_value, 1);
727           name = NULL;
728 	  if (err)
729 	    goto leave;
730 	}
731 
732       /* And prepare for the next one.  */
733       name = NULL;
734       raw_value = NULL;
735 
736       if (*p != 0 && *p != '#')
737 	{
738 	  char *colon, *value, tmp;
739 
740 	  colon = strchr (buf, ':');
741 	  if (colon == NULL)
742 	    {
743 	      err = my_error (GPG_ERR_INV_VALUE);
744 	      goto leave;
745 	    }
746 
747 	  value = colon + 1;
748 	  tmp = *value;
749 	  *value = 0;
750 	  name = xtrystrdup (p);
751 	  *value = tmp;
752 
753 	  if (name == NULL)
754 	    {
755 	      err = my_error_from_syserror ();
756 	      goto leave;
757 	    }
758 
759 	  if (append_to_strlist_try (&raw_value, value) == NULL)
760 	    {
761 	      err = my_error_from_syserror ();
762 	      goto leave;
763 	    }
764 	  continue;
765 	}
766 
767       if (append_to_strlist_try (&raw_value, buf) == NULL)
768 	{
769 	  err = my_error_from_syserror ();
770 	  goto leave;
771 	}
772     }
773   if (len < 0)
774     {
775       err = gpg_error_from_syserror ();
776       goto leave;
777     }
778 
779   /* Add the final entry.  */
780   if (raw_value)
781     {
782       err = _nvc_add (*result, name, NULL, raw_value, 1);
783       name = NULL;
784     }
785 
786  leave:
787   xfree (name);
788   gpgrt_free (buf);
789   if (err)
790     {
791       nvc_release (*result);
792       *result = NULL;
793     }
794 
795   return err;
796 }
797 
798 
799 /* Parse STREAM and return a newly allocated name value container
800    structure in RESULT.  If ERRLINEP is given, the line number the
801    parser was last considering is stored there.  */
802 gpg_error_t
nvc_parse(nvc_t * result,int * errlinep,estream_t stream)803 nvc_parse (nvc_t *result, int *errlinep, estream_t stream)
804 {
805   return do_nvc_parse (result, errlinep, stream, 0);
806 }
807 
808 
809 /* Parse STREAM and return a newly allocated name value container
810    structure in RESULT - assuming the extended private key format.  If
811    ERRLINEP is given, the line number the parser was last considering
812    is stored there.  */
813 gpg_error_t
nvc_parse_private_key(nvc_t * result,int * errlinep,estream_t stream)814 nvc_parse_private_key (nvc_t *result, int *errlinep, estream_t stream)
815 {
816   return do_nvc_parse (result, errlinep, stream, 1);
817 }
818 
819 
820 /* Helper fpr nvc_write.  */
821 static gpg_error_t
write_one_entry(nve_t entry,estream_t stream)822 write_one_entry (nve_t entry, estream_t stream)
823 {
824   gpg_error_t err;
825   strlist_t sl;
826 
827   if (entry->name)
828     es_fputs (entry->name, stream);
829 
830   err = assert_raw_value (entry);
831   if (err)
832     return err;
833 
834   for (sl = entry->raw_value; sl; sl = sl->next)
835     es_fputs (sl->d, stream);
836 
837   if (es_ferror (stream))
838     return my_error_from_syserror ();
839 
840   return 0;
841 }
842 
843 
844 /* Write a representation of PK to STREAM.  */
845 gpg_error_t
nvc_write(nvc_t pk,estream_t stream)846 nvc_write (nvc_t pk, estream_t stream)
847 {
848   gpg_error_t err = 0;
849   nve_t entry;
850   nve_t keyentry = NULL;
851 
852   for (entry = pk->first; entry; entry = entry->next)
853     {
854       if (pk->private_key_mode
855           && entry->name && !ascii_strcasecmp (entry->name, "Key:"))
856         {
857           if (!keyentry)
858             keyentry = entry;
859           continue;
860         }
861 
862       err = write_one_entry (entry, stream);
863       if (err)
864 	return err;
865     }
866 
867   /* In private key mode we write the Key always last.  */
868   if (keyentry)
869     err = write_one_entry (keyentry, stream);
870 
871   return err;
872 }
873