1 /* name-value.c - Parser and writer for a name-value format.
2 * Copyright (C) 2016 g10 Code GmbH
4 * This file is part of GnuPG.
6 * This file is free software; you can redistribute it and/or modify
7 * it under the terms of either
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.
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.
19 * or both in parallel, as here.
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.
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/>.
31 * This module aso provides features for the extended private key
32 * format of gpg-agent.
38 #include <gpg-error.h>
44 #include "name-value.h"
46 struct name_value_container
48 struct name_value_entry *first;
49 struct name_value_entry *last;
50 unsigned int private_key_mode:1;
54 struct name_value_entry
56 struct name_value_entry *prev;
57 struct name_value_entry *next;
59 /* The name. Comments and blank lines have NAME set to NULL. */
62 /* The value as stored in the file. We store it when when we parse
63 a file so that we can reproduce it. */
66 /* The decoded value. */
72 static inline gpg_error_t
73 my_error_from_syserror (void)
75 return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
79 static inline gpg_error_t
80 my_error (gpg_err_code_t ec)
82 return gpg_err_make (default_errsource, ec);
88 /* Allocation and deallocation. */
90 /* Allocate a private key container structure. */
94 return xtrycalloc (1, sizeof (struct name_value_container));
98 /* Allocate a private key container structure for use with private keys. */
100 nvc_new_private_key (void)
102 nvc_t nvc = nvc_new ();
104 nvc->private_key_mode = 1;
110 nve_release (nve_t entry, int private_key_mode)
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);
122 free_strlist (entry->raw_value);
127 /* Release a private key container structure. */
129 nvc_release (nvc_t pk)
136 for (e = pk->first; e; e = next)
139 nve_release (e, pk->private_key_mode);
147 /* Dealing with names and values. */
149 /* Check whether the given name is valid. Valid names start with a
150 letter, end with a colon, and contain only alphanumeric characters
153 valid_name (const char *name)
155 size_t i, len = strlen (name);
157 if (! alphap (name) || len == 0 || name[len - 1] != ':')
160 for (i = 1; i < len - 1; i++)
161 if (! alnump (&name[i]) && name[i] != '-')
168 /* Makes sure that ENTRY has a RAW_VALUE. */
170 assert_raw_value (nve_t entry)
177 if (entry->raw_value)
180 len = strlen (entry->value);
184 size_t amount, linelen = LINELEN;
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);
190 /* See if the rest of the value fits in this line. */
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]))
202 if (ascii_isspace (entry->value[i]))
209 /* Just induce a hard break. */
214 snprintf (buf, sizeof buf, " %.*s\n", (int) amount,
215 &entry->value[offset]);
216 if (append_to_strlist_try (&entry->raw_value, buf) == NULL)
218 err = my_error_from_syserror ();
229 free_strlist_wipe (entry->raw_value);
230 entry->raw_value = NULL;
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. */
243 continuation_length (const char *s, int *swallow_ws, const char **start)
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))
256 /* Iff a continuation starts with more than one space, it
258 if (ascii_isspace (*s))
262 /* Strip whitespace at the end. */
264 while (len > 0 && ascii_isspace (s[len-1]))
269 /* Blank lines encode newlines. */
284 /* Makes sure that ENTRY has a VALUE. */
286 assert_value (nve_t entry)
298 for (s = entry->raw_value; s; s = s->next)
299 len += continuation_length (s->d, &swallow_ws, NULL);
301 /* Add one for the terminating zero. */
304 entry->value = p = xtrymalloc (len);
305 if (entry->value == NULL)
306 return my_error_from_syserror ();
309 for (s = entry->raw_value; s; s = s->next)
312 size_t l = continuation_length (s->d, &swallow_ws, &start);
314 memcpy (p, start, l);
319 assert (p - entry->value == len);
335 nve_value (nve_t pke)
337 if (assert_value (pke))
344 /* Adding and modifying values. */
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. */
351 _nvc_add (nvc_t pk, char *name, char *value, strlist_t raw_value,
357 assert (value || raw_value);
359 if (name && ! valid_name (name))
361 err = my_error (GPG_ERR_INV_NAME);
366 && pk->private_key_mode
367 && !ascii_strcasecmp (name, "Key:")
368 && nvc_lookup (pk, "Key:"))
370 err = my_error (GPG_ERR_INV_NAME);
374 e = xtrycalloc (1, sizeof *e);
377 err = my_error_from_syserror ();
383 e->raw_value = raw_value;
389 if (preserve_order || name == NULL)
393 /* See if there is already an entry with NAME. */
394 last = nvc_lookup (pk, name);
396 /* If so, find the last in that block. */
401 nve_t next = last->next;
403 if (next->name && ascii_strcasecmp (next->name, name) == 0)
409 else /* Otherwise, just find the last entry. */
416 e->next = last->next;
428 pk->first = pk->last = e;
435 wipememory (value, strlen (value));
437 free_strlist_wipe (raw_value);
444 /* Add (NAME, VALUE) to PK. If an entry with NAME already exists, it
445 is not updated but the new entry is appended. */
447 nvc_add (nvc_t pk, const char *name, const char *value)
451 k = xtrystrdup (name);
453 return my_error_from_syserror ();
455 v = xtrystrdup (value);
459 return my_error_from_syserror ();
462 return _nvc_add (pk, k, v, NULL, 0);
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. */
470 nvc_set (nvc_t pk, const char *name, const char *value)
474 if (! valid_name (name))
475 return GPG_ERR_INV_NAME;
477 e = nvc_lookup (pk, name);
482 v = xtrystrdup (value);
484 return my_error_from_syserror ();
486 free_strlist_wipe (e->raw_value);
489 wipememory (e->value, strlen (e->value));
496 return nvc_add (pk, name, value);
500 /* Delete the given entry from PK. */
502 nvc_delete (nvc_t pk, nve_t entry)
505 entry->prev->next = entry->next;
507 pk->first = entry->next;
510 entry->next->prev = entry->prev;
512 pk->last = entry->prev;
514 nve_release (entry, pk->private_key_mode);
519 /* Lookup and iteration. */
521 /* Get the first non-comment entry. */
526 for (entry = pk->first; entry; entry = entry->next)
533 /* Get the first entry with the given name. */
535 nvc_lookup (nvc_t pk, const char *name)
538 for (entry = pk->first; entry; entry = entry->next)
539 if (entry->name && ascii_strcasecmp (entry->name, name) == 0)
545 /* Get the next non-comment entry. */
547 nve_next (nve_t entry)
549 for (entry = entry->next; entry; entry = entry->next)
556 /* Get the next entry with the given name. */
558 nve_next_value (nve_t entry, const char *name)
560 for (entry = entry->next; entry; entry = entry->next)
561 if (entry->name && ascii_strcasecmp (entry->name, name) == 0)
568 /* Private key handling. */
570 /* Get the private key. */
572 nvc_get_private_key (nvc_t pk, gcry_sexp_t *retsexp)
577 e = pk->private_key_mode? nvc_lookup (pk, "Key:") : NULL;
579 return my_error (GPG_ERR_MISSING_KEY);
581 err = assert_value (e);
585 return gcry_sexp_sscan (retsexp, NULL, e->value, strlen (e->value));
589 /* Set the private key. */
591 nvc_set_private_key (nvc_t pk, gcry_sexp_t sexp)
594 char *raw, *clean, *p;
597 if (!pk->private_key_mode)
598 return my_error (GPG_ERR_MISSING_KEY);
600 len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);
602 raw = xtrymalloc (len);
604 return my_error_from_syserror ();
606 clean = xtrymalloc (len);
610 return my_error_from_syserror ();
613 gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, raw, len);
615 /* Strip any whitespace at the end. */
616 i = strlen (raw) - 1;
617 while (i && ascii_isspace (raw[i]))
623 /* Replace any newlines with spaces, remove superfluous whitespace. */
625 for (p = clean, i = 0; i < len; i++)
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] == ')'))
641 err = nvc_set (pk, "Key:", clean);
649 /* Parsing and serialization. */
652 do_nvc_parse (nvc_t *result, int *errlinep, estream_t stream,
660 strlist_t raw_value = NULL;
662 *result = for_private_key? nvc_new_private_key () : nvc_new ();
664 return my_error_from_syserror ();
668 while ((len = es_read_line (stream, &buf, &buf_len, NULL)) > 0)
674 /* Skip any whitespace. */
675 for (p = buf; *p && ascii_isspace (*p); p++)
678 if (name && (spacep (buf) || *p == 0))
680 /* A continuation. */
681 if (append_to_strlist_try (&raw_value, buf) == NULL)
683 err = my_error_from_syserror ();
689 /* No continuation. Add the current entry if any. */
692 err = _nvc_add (*result, name, NULL, raw_value, 1);
697 /* And prepare for the next one. */
701 if (*p != 0 && *p != '#')
703 char *colon, *value, tmp;
705 colon = strchr (buf, ':');
708 err = my_error (GPG_ERR_INV_VALUE);
715 name = xtrystrdup (p);
720 err = my_error_from_syserror ();
724 if (append_to_strlist_try (&raw_value, value) == NULL)
726 err = my_error_from_syserror ();
732 if (append_to_strlist_try (&raw_value, buf) == NULL)
734 err = my_error_from_syserror ();
740 err = gpg_error_from_syserror ();
744 /* Add the final entry. */
746 err = _nvc_add (*result, name, NULL, raw_value, 1);
752 nvc_release (*result);
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. */
764 nvc_parse (nvc_t *result, int *errlinep, estream_t stream)
766 return do_nvc_parse (result, errlinep, stream, 0);
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
775 nvc_parse_private_key (nvc_t *result, int *errlinep, estream_t stream)
777 return do_nvc_parse (result, errlinep, stream, 1);
781 /* Write a representation of PK to STREAM. */
783 nvc_write (nvc_t pk, estream_t stream)
789 for (entry = pk->first; entry; entry = entry->next)
792 es_fputs (entry->name, stream);
794 err = assert_raw_value (entry);
798 for (s = entry->raw_value; s; s = s->next)
799 es_fputs (s->d, stream);
801 if (es_ferror (stream))
802 return my_error_from_syserror ();