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