1 /* t-name-value.c - Module test for name-value.c
2 * Copyright (C) 2016 g10 Code GmbH
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <https://www.gnu.org/licenses/>.
29 #include "name-value.h"
32 static int private_key_mode;
39 return nvc_new_private_key ();
46 test_getting_values (nvc_t pk)
50 e = nvc_lookup (pk, "Comment:");
53 /* Names are case-insensitive. */
54 e = nvc_lookup (pk, "comment:");
56 e = nvc_lookup (pk, "COMMENT:");
59 e = nvc_lookup (pk, "SomeOtherName:");
65 test_key_extraction (nvc_t pk)
72 err = nvc_get_private_key (pk, &key);
79 gcry_sexp_release (key);
83 err = nvc_get_private_key (pk, &key);
84 assert (gpg_err_code (err) == GPG_ERR_MISSING_KEY);
90 test_iteration (nvc_t pk)
96 for (e = nvc_first (pk); e; e = nve_next (e))
101 for (e = nvc_lookup (pk, "Comment:");
103 e = nve_next_value (e, "Comment:"))
110 test_whitespace (nvc_t pk)
114 e = nvc_lookup (pk, "One:");
116 assert (strcmp (nve_value (e), "WithoutWhitespace") == 0);
118 e = nvc_lookup (pk, "Two:");
120 assert (strcmp (nve_value (e), "With Whitespace") == 0);
122 e = nvc_lookup (pk, "Three:");
124 assert (strcmp (nve_value (e),
125 "Blank lines in continuations encode newlines.\n"
126 "Next paragraph.") == 0);
133 void (*test_func) (nvc_t);
137 "# This is a comment followed by an empty line\n"
142 "# This is a comment followed by two empty lines, Windows style\r\n"
148 "# Some name,value pairs\n"
149 "Comment: Some comment.\n"
150 "SomeOtherName: Some value.\n",
154 " # Whitespace is preserved as much as possible\r\n"
155 "Comment:Some comment.\n"
156 "SomeOtherName: Some value. \n",
160 "# Values may be continued in the next line as indicated by leading\n"
162 "Comment: Some rather long\n"
163 " comment that is continued in the next line.\n"
165 " Blank lines with or without whitespace are allowed within\n"
166 " continuations to allow paragraphs.\n"
167 "SomeOtherName: Some value.\n",
171 "# Names may be given multiple times forming an array of values\n"
172 "Comment: Some comment, element 0.\n"
173 "Comment: Some comment, element 1.\n"
174 "Comment: Some comment, element 2.\n"
175 "SomeOtherName: Some value.\n",
179 "# One whitespace at the beginning of a continuation is swallowed.\n"
184 "Three: Blank lines in continuations encode newlines.\n"
186 " Next paragraph.\n",
190 "Description: Key to sign all GnuPG released tarballs.\n"
191 " The key is actually stored on a smart card.\n"
193 "OpenSSH-cert: long base64 encoded string wrapped so that this\n"
194 " key file can be easily edited with a standard editor.\n"
195 "Key: (shadowed-private-key\n"
197 " (n #00AA1AD2A55FD8C8FDE9E1941772D9CC903FA43B268CB1B5A1BAFDC900\n"
198 " 2961D8AEA153424DC851EF13B83AC64FBE365C59DC1BD3E83017C90D4365B4\n"
199 " 83E02859FC13DB5842A00E969480DB96CE6F7D1C03600392B8E08EF0C01FC7\n"
200 " 19F9F9086B25AD39B4F1C2A2DF3E2BE317110CFFF21D4A11455508FE407997\n"
201 " 601260816C8422297C0637BB291C3A079B9CB38A92CE9E551F80AA0EBF4F0E\n"
202 " 72C3F250461E4D31F23A7087857FC8438324A013634563D34EFDDCBF2EA80D\n"
203 " F9662C9CCD4BEF2522D8BDFED24CEF78DC6B309317407EAC576D889F88ADA0\n"
204 " 8C4FFB480981FB68C5C6CA27503381D41018E6CDC52AAAE46B166BDC10637A\n"
205 " E186A02BA2497FDC5D1221#)\n"
208 " (#D2760001240102000005000011730000# OPENPGP.1)\n"
216 nvc_to_string (nvc_t pk)
223 sink = es_fopenmem (0, "rw");
226 err = nvc_write (pk, sink);
229 len = es_ftell (sink);
230 buf = xmalloc (len+1);
233 es_fseek (sink, 0, SEEK_SET);
234 es_read (sink, buf, len, NULL);
242 void dummy_free (void *p) { (void) p; }
243 void *dummy_realloc (void *p, size_t s) { (void) s; return p; }
252 for (i = 0; i < DIM (tests); i++)
258 len = strlen (tests[i].value);
259 source = es_mopen (tests[i].value, len, len,
260 0, dummy_realloc, dummy_free, "r");
263 if (private_key_mode)
264 err = nvc_parse_private_key (&pk, NULL, source);
266 err = nvc_parse (&pk, NULL, source);
272 err = nvc_write (pk, es_stderr);
276 buf = nvc_to_string (pk);
277 assert (memcmp (tests[i].value, buf, len) == 0);
282 if (tests[i].test_func)
283 tests[i].test_func (pk);
291 run_modification_tests (void)
301 nvc_set (pk, "Foo:", "Bar");
302 buf = nvc_to_string (pk);
303 assert (strcmp (buf, "Foo: Bar\n") == 0);
306 nvc_set (pk, "Foo:", "Baz");
307 buf = nvc_to_string (pk);
308 assert (strcmp (buf, "Foo: Baz\n") == 0);
311 nvc_set (pk, "Bar:", "Bazzel");
312 buf = nvc_to_string (pk);
313 assert (strcmp (buf, "Foo: Baz\nBar: Bazzel\n") == 0);
316 nvc_add (pk, "Foo:", "Bar");
317 buf = nvc_to_string (pk);
318 assert (strcmp (buf, "Foo: Baz\nFoo: Bar\nBar: Bazzel\n") == 0);
321 nvc_add (pk, "DontExistYet:", "Bar");
322 buf = nvc_to_string (pk);
323 assert (strcmp (buf, "Foo: Baz\nFoo: Bar\nBar: Bazzel\nDontExistYet: Bar\n")
327 nvc_delete (pk, nvc_lookup (pk, "DontExistYet:"));
328 buf = nvc_to_string (pk);
329 assert (strcmp (buf, "Foo: Baz\nFoo: Bar\nBar: Bazzel\n") == 0);
332 nvc_delete (pk, nve_next_value (nvc_lookup (pk, "Foo:"), "Foo:"));
333 buf = nvc_to_string (pk);
334 assert (strcmp (buf, "Foo: Baz\nBar: Bazzel\n") == 0);
337 nvc_delete (pk, nvc_lookup (pk, "Foo:"));
338 buf = nvc_to_string (pk);
339 assert (strcmp (buf, "Bar: Bazzel\n") == 0);
342 nvc_delete (pk, nvc_first (pk));
343 buf = nvc_to_string (pk);
344 assert (strcmp (buf, "") == 0);
347 nvc_set (pk, "Foo:", "A really long value spanning across multiple lines"
348 " that has to be wrapped at a convenient space.");
349 buf = nvc_to_string (pk);
350 assert (strcmp (buf, "Foo: A really long value spanning across multiple"
351 " lines that has to be\n wrapped at a convenient space.\n")
355 nvc_set (pk, "Foo:", "XA really long value spanning across multiple lines"
356 " that has to be wrapped at a convenient space.");
357 buf = nvc_to_string (pk);
358 assert (strcmp (buf, "Foo: XA really long value spanning across multiple"
359 " lines that has to\n be wrapped at a convenient space.\n")
363 nvc_set (pk, "Foo:", "XXXXA really long value spanning across multiple lines"
364 " that has to be wrapped at a convenient space.");
365 buf = nvc_to_string (pk);
366 assert (strcmp (buf, "Foo: XXXXA really long value spanning across multiple"
367 " lines that has\n to be wrapped at a convenient space.\n")
371 nvc_set (pk, "Foo:", "Areallylongvaluespanningacrossmultiplelines"
372 "thathastobewrappedataconvenientspacethatisnotthere.");
373 buf = nvc_to_string (pk);
374 assert (strcmp (buf, "Foo: Areallylongvaluespanningacrossmultiplelinesthat"
375 "hastobewrappedataco\n nvenientspacethatisnotthere.\n")
383 err = gcry_sexp_build (&key, NULL, "(hello world)");
387 if (private_key_mode)
389 err = nvc_set_private_key (pk, key);
392 buf = nvc_to_string (pk);
393 assert (strcmp (buf, "Key: (hello world)\n") == 0);
398 err = nvc_set_private_key (pk, key);
399 assert (gpg_err_code (err) == GPG_ERR_MISSING_KEY);
401 gcry_sexp_release (key);
407 convert (const char *fname)
417 source = es_fopen (fname, "rb");
421 if (fstat (es_fileno (source), &st))
425 buf = xtrymalloc (buflen+1);
428 if (es_fread (buf, buflen, 1, source) != 1)
431 err = gcry_sexp_sscan (&key, NULL, buf, buflen);
434 fprintf (stderr, "malformed s-expression in %s\n", fname);
441 err = nvc_set_private_key (pk, key);
444 err = nvc_write (pk, es_stdout);
456 parse (const char *fname)
465 source = es_fopen (fname, "rb");
472 if (private_key_mode)
473 err = nvc_parse_private_key (&pk_a, &line, source);
475 err = nvc_parse (&pk_a, &line, source);
478 fprintf (stderr, "failed to parse %s line %d: %s\n",
479 fname, line, gpg_strerror (err));
483 buf = nvc_to_string (pk_a);
486 pk_b = my_nvc_new ();
489 for (e = nvc_first (pk_a); e; e = nve_next (e))
491 gcry_sexp_t key = NULL;
493 if (private_key_mode && !strcasecmp (nve_name (e), "Key:"))
495 err = nvc_get_private_key (pk_a, &key);
502 err = nvc_set_private_key (pk_b, key);
507 err = nvc_add (pk_b, nve_name (e), nve_value (e));
512 buf = nvc_to_string (pk_b);
514 fprintf (stdout, "%s", buf);
523 "usage: t-private-keys [--verbose]"
524 " [--convert <private-key-file>"
525 " || --parse-key <extended-private-key-file>"
526 " || --parse <file> ]\n");
532 main (int argc, char **argv)
534 enum { TEST, CONVERT, PARSE, PARSEKEY } command = TEST;
538 if (argc && !strcmp (argv[0], "--verbose"))
544 if (argc && !strcmp (argv[0], "--convert"))
552 if (argc && !strcmp (argv[0], "--parse-key"))
560 if (argc && !strcmp (argv[0], "--parse"))
572 run_modification_tests ();
573 private_key_mode = 1;
575 run_modification_tests ();
583 private_key_mode = 1;