Line data Source code
1 : /* t-sexp.c - S-expression regression tests
2 : * Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
3 : * Copyright (C) 2014 g10 Code GmbH
4 : *
5 : * This file is part of Libgcrypt.
6 : *
7 : * Libgcrypt is free software; you can redistribute it and/or modify
8 : * it under the terms of the GNU Lesser General Public License as
9 : * published by the Free Software Foundation; either version 2.1 of
10 : * the License, or (at your option) any later version.
11 : *
12 : * Libgcrypt is distributed in the hope that it will be useful,
13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : * GNU Lesser General Public License for more details.
16 : *
17 : * You should have received a copy of the GNU Lesser General Public
18 : * License along with this program; if not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #ifdef HAVE_CONFIG_H
22 : #include <config.h>
23 : #endif
24 : #include <stdio.h>
25 : #include <stdlib.h>
26 : #include <string.h>
27 : #include <stdarg.h>
28 : #include <assert.h>
29 : #include "../src/gcrypt-int.h"
30 :
31 : #define PGMNAME "t-sexp"
32 : #include "t-common.h"
33 :
34 :
35 : /* Convert STRING consisting of hex characters into its binary
36 : representation and return it as an allocated buffer. The valid
37 : length of the buffer is returned at R_LENGTH. The string is
38 : delimited by end of string. The function returns NULL on
39 : error. */
40 : static void *
41 8 : hex2buffer (const char *string, size_t *r_length)
42 : {
43 : const char *s;
44 : unsigned char *buffer;
45 : size_t length;
46 :
47 8 : buffer = xmalloc (strlen(string)/2+1);
48 8 : length = 0;
49 266 : for (s=string; *s; s +=2 )
50 : {
51 258 : if (!hexdigitp (s) || !hexdigitp (s+1))
52 0 : return NULL; /* Invalid hex digits. */
53 258 : ((unsigned char*)buffer)[length++] = xtoi_2 (s);
54 : }
55 8 : *r_length = length;
56 8 : return buffer;
57 : }
58 :
59 :
60 : static gcry_mpi_t
61 55 : hex2mpi (const char *string)
62 : {
63 : gpg_error_t err;
64 : gcry_mpi_t val;
65 :
66 55 : err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL);
67 55 : if (err)
68 0 : die ("hex2mpi '%s' failed: %s\n", string, gpg_strerror (err));
69 55 : return val;
70 : }
71 :
72 : static gcry_mpi_t
73 5 : hex2mpiopa (const char *string)
74 : {
75 : char *buffer;
76 : size_t buflen;
77 : gcry_mpi_t val;
78 :
79 5 : buffer = hex2buffer (string, &buflen);
80 5 : if (!buffer)
81 0 : die ("hex2mpiopa '%s' failed: parser error\n", string);
82 5 : val = gcry_mpi_set_opaque (NULL, buffer, buflen*8);
83 5 : if (!buffer)
84 0 : die ("hex2mpiopa '%s' failed: set_opaque error\n", string);
85 5 : return val;
86 : }
87 :
88 :
89 : /* Compare A to B, where B is given as a hex string. */
90 : static int
91 60 : cmp_mpihex (gcry_mpi_t a, const char *b)
92 : {
93 : gcry_mpi_t bval;
94 : int res;
95 :
96 60 : if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
97 5 : bval = hex2mpiopa (b);
98 : else
99 55 : bval = hex2mpi (b);
100 60 : res = gcry_mpi_cmp (a, bval);
101 60 : gcry_mpi_release (bval);
102 60 : return res;
103 : }
104 :
105 : /* Compare A to B, where A is a buffer and B a hex string. */
106 : static int
107 3 : cmp_bufhex (const void *a, size_t alen, const char *b)
108 : {
109 : void *bbuf;
110 : size_t blen;
111 : int res;
112 :
113 3 : if (!a && !b)
114 0 : return 0;
115 3 : if (a && !b)
116 0 : return 1;
117 3 : if (!a && b)
118 0 : return -1;
119 :
120 3 : bbuf = hex2buffer (b, &blen);
121 3 : if (!bbuf)
122 0 : die ("cmp_bufhex: error converting hex string\n");
123 3 : if (alen != blen)
124 0 : return alen < blen? -1 : 1;
125 3 : res = memcmp (a, bbuf, alen);
126 3 : xfree (bbuf);
127 3 : return res;
128 : }
129 :
130 :
131 :
132 : /* fixme: we need better tests */
133 : static void
134 1 : basic (void)
135 : {
136 : int pass;
137 : gcry_sexp_t sexp;
138 : int idx;
139 : char *secure_buffer;
140 : size_t secure_buffer_len;
141 : const char *string;
142 : static struct {
143 : const char *token;
144 : const char *parm;
145 : } values[] = {
146 : { "public-key", NULL },
147 : { "dsa", NULL },
148 : { "dsa", "p" },
149 : { "dsa", "y" },
150 : { "dsa", "q" },
151 : { "dsa", "g" },
152 : { NULL }
153 : };
154 :
155 1 : info ("doing some pretty pointless tests\n");
156 :
157 1 : secure_buffer_len = 99;
158 1 : secure_buffer = gcry_xmalloc_secure (secure_buffer_len);
159 1 : memset (secure_buffer, 'G', secure_buffer_len);
160 :
161 5 : for (pass=0;;pass++)
162 : {
163 : gcry_mpi_t m;
164 :
165 5 : switch (pass)
166 : {
167 : case 0:
168 1 : string = ("(public-key (dsa (p #41424344#) (y this_is_y) "
169 : "(q #61626364656667#) (g %m)))");
170 :
171 1 : m = gcry_mpi_set_ui (NULL, 42);
172 1 : if ( gcry_sexp_build (&sexp, NULL, string, m ) )
173 : {
174 0 : gcry_mpi_release (m);
175 0 : fail (" scanning `%s' failed\n", string);
176 0 : return;
177 : }
178 1 : gcry_mpi_release (m);
179 1 : break;
180 :
181 : case 1:
182 1 : string = ("(public-key (dsa (p #41424344#) (y this_is_y) "
183 : "(q %b) (g %m)))");
184 :
185 1 : m = gcry_mpi_set_ui (NULL, 42);
186 1 : if ( gcry_sexp_build (&sexp, NULL, string,
187 : 15, "foo\0\x01\0x02789012345", m) )
188 : {
189 0 : gcry_mpi_release (m);
190 0 : fail (" scanning `%s' failed\n", string);
191 0 : return;
192 : }
193 1 : gcry_mpi_release (m);
194 1 : break;
195 :
196 : case 2:
197 1 : string = ("(public-key (dsa (p #41424344#) (y silly_y_value) "
198 : "(q %b) (g %m)))");
199 :
200 1 : m = gcry_mpi_set_ui (NULL, 17);
201 1 : if ( gcry_sexp_build (&sexp, NULL, string,
202 : secure_buffer_len, secure_buffer, m) )
203 : {
204 0 : gcry_mpi_release (m);
205 0 : fail (" scanning `%s' failed\n", string);
206 0 : return;
207 : }
208 1 : gcry_mpi_release (m);
209 1 : if (!gcry_is_secure (sexp))
210 0 : fail ("gcry_sexp_build did not switch to secure memory\n");
211 1 : break;
212 :
213 : case 3:
214 : {
215 : gcry_sexp_t help_sexp;
216 :
217 1 : if (gcry_sexp_new (&help_sexp,
218 : "(foobar-parms (xp #1234#)(xq #03#))", 0, 1))
219 : {
220 0 : fail (" scanning fixed string failed\n");
221 0 : return;
222 : }
223 :
224 1 : string = ("(public-key (dsa (p #41424344#) (parm %S) "
225 : "(y dummy)(q %b) (g %m)))");
226 1 : m = gcry_mpi_set_ui (NULL, 17);
227 1 : if ( gcry_sexp_build (&sexp, NULL, string, help_sexp,
228 : secure_buffer_len, secure_buffer, m) )
229 : {
230 0 : gcry_mpi_release (m);
231 0 : fail (" scanning `%s' failed\n", string);
232 0 : return;
233 : }
234 1 : gcry_mpi_release (m);
235 1 : gcry_sexp_release (help_sexp);
236 : }
237 1 : break;
238 :
239 :
240 : default:
241 1 : return; /* Ready. */
242 : }
243 :
244 :
245 : /* now find something */
246 28 : for (idx=0; values[idx].token; idx++)
247 : {
248 24 : const char *token = values[idx].token;
249 24 : const char *parm = values[idx].parm;
250 : gcry_sexp_t s1, s2;
251 : gcry_mpi_t a;
252 : const char *p;
253 : size_t n;
254 :
255 24 : s1 = gcry_sexp_find_token (sexp, token, strlen(token) );
256 24 : if (!s1)
257 : {
258 0 : fail ("didn't found `%s'\n", token);
259 0 : continue;
260 : }
261 :
262 24 : p = gcry_sexp_nth_data (s1, 0, &n);
263 24 : if (!p)
264 : {
265 0 : gcry_sexp_release (s1);
266 0 : fail ("no car for `%s'\n", token);
267 0 : continue;
268 : }
269 : /* info ("car=`%.*s'\n", (int)n, p); */
270 :
271 24 : s2 = gcry_sexp_cdr (s1);
272 24 : if (!s2)
273 : {
274 0 : gcry_sexp_release (s1);
275 0 : fail ("no cdr for `%s'\n", token);
276 0 : continue;
277 : }
278 :
279 24 : p = gcry_sexp_nth_data (s2, 0, &n);
280 24 : gcry_sexp_release (s2);
281 24 : if (p)
282 : {
283 0 : gcry_sexp_release (s1);
284 0 : fail ("data at car of `%s'\n", token);
285 0 : continue;
286 : }
287 :
288 24 : if (parm)
289 : {
290 16 : s2 = gcry_sexp_find_token (s1, parm, strlen (parm));
291 16 : gcry_sexp_release (s1);
292 16 : if (!s2)
293 : {
294 0 : fail ("didn't found `%s'\n", parm);
295 0 : continue;
296 : }
297 16 : p = gcry_sexp_nth_data (s2, 0, &n);
298 16 : if (!p)
299 : {
300 0 : gcry_sexp_release (s2);
301 0 : fail("no car for `%s'\n", parm );
302 0 : continue;
303 : }
304 : /* info ("car=`%.*s'\n", (int)n, p); */
305 16 : p = gcry_sexp_nth_data (s2, 1, &n);
306 16 : if (!p)
307 : {
308 0 : gcry_sexp_release (s2);
309 0 : fail("no cdr for `%s'\n", parm );
310 0 : continue;
311 : }
312 : /* info ("cdr=`%.*s'\n", (int)n, p); */
313 :
314 16 : a = gcry_sexp_nth_mpi (s2, 0, GCRYMPI_FMT_USG);
315 16 : gcry_sexp_release (s2);
316 16 : if (!a)
317 : {
318 0 : fail("failed to cdr the mpi for `%s'\n", parm);
319 0 : continue;
320 : }
321 16 : gcry_mpi_release (a);
322 : }
323 : else
324 8 : gcry_sexp_release (s1);
325 : }
326 :
327 4 : gcry_sexp_release (sexp);
328 4 : sexp = NULL;
329 4 : }
330 : gcry_free (secure_buffer);
331 : }
332 :
333 :
334 : static void
335 1 : canon_len (void)
336 : {
337 : static struct {
338 : size_t textlen; /* length of the buffer */
339 : size_t expected;/* expected length or 0 on error and then ... */
340 : size_t erroff; /* ... and at this offset */
341 : gcry_error_t errcode; /* ... with this error code */
342 : const char *text;
343 : } values[] = {
344 : { 14, 13, 0, GPG_ERR_NO_ERROR, "(9:abcdefghi) " },
345 : { 16, 15, 0, GPG_ERR_NO_ERROR, "(10:abcdefghix)" },
346 : { 14, 0,14, GPG_ERR_SEXP_STRING_TOO_LONG, "(10:abcdefghi)" },
347 : { 15, 0, 1, GPG_ERR_SEXP_ZERO_PREFIX, "(010:abcdefghi)" },
348 : { 2, 0, 0, GPG_ERR_SEXP_NOT_CANONICAL, "1:"},
349 : { 4, 0, 4, GPG_ERR_SEXP_STRING_TOO_LONG, "(1:)"},
350 : { 5, 5, 0, GPG_ERR_NO_ERROR, "(1:x)"},
351 : { 2, 2, 0, GPG_ERR_NO_ERROR, "()"},
352 : { 4, 2, 0, GPG_ERR_NO_ERROR, "()()"},
353 : { 4, 4, 0, GPG_ERR_NO_ERROR, "(())"},
354 : { 3, 0, 3, GPG_ERR_SEXP_STRING_TOO_LONG, "(()"},
355 : { 3, 0, 1, GPG_ERR_SEXP_BAD_CHARACTER, "( )"},
356 : { 9, 9, 0, GPG_ERR_NO_ERROR, "(3:abc())"},
357 : { 10, 0, 6, GPG_ERR_SEXP_BAD_CHARACTER, "(3:abc ())"},
358 : /* fixme: we need much more cases */
359 : { 0 },
360 : };
361 : int idx;
362 : gcry_error_t errcode;
363 : size_t n, erroff;
364 :
365 1 : info ("checking canoncial length test function\n");
366 15 : for (idx=0; values[idx].text; idx++)
367 : {
368 14 : n = gcry_sexp_canon_len ((const unsigned char*)values[idx].text,
369 : values[idx].textlen,
370 : &erroff, &errcode);
371 :
372 14 : if (n && n == values[idx].expected)
373 : ; /* success */
374 7 : else if (!n && !values[idx].expected)
375 : { /* we expected an error - check that this is the right one */
376 7 : if (values[idx].erroff != erroff)
377 0 : fail ("canonical length test %d - wrong error offset %u\n",
378 : idx, (unsigned int)erroff);
379 14 : if (gcry_err_code (errcode) != values[idx].errcode)
380 0 : fail ("canonical length test %d - wrong error code %d\n",
381 : idx, errcode);
382 : }
383 : else
384 0 : fail ("canonical length test %d failed - n=%u, off=%u, err=%d\n",
385 : idx, (unsigned int)n, (unsigned int)erroff, errcode);
386 : }
387 1 : }
388 :
389 :
390 : /* Compare SE to the canonical formatted expression in
391 : * (CANON,CANONLEN). This is done by a converting SE to canonical
392 : * format and doing a byte compare. Returns 0 if they match. */
393 : static int
394 10 : compare_to_canon (gcry_sexp_t se, const unsigned char *canon, size_t canonlen)
395 : {
396 : size_t n, n1;
397 : char *p1;
398 :
399 10 : n1 = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, NULL, 0);
400 10 : if (!n1)
401 : {
402 0 : fail ("get required length in compare_to_canon failed\n");
403 0 : return -1;
404 : }
405 10 : p1 = gcry_xmalloc (n1);
406 10 : n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1, n1);
407 10 : if (n1 != n+1)
408 : {
409 0 : fail ("length mismatch in compare_to_canon detected\n");
410 0 : xfree (p1);
411 0 : return -1;
412 : }
413 10 : if (n1 != canonlen || memcmp (p1, canon, canonlen))
414 : {
415 0 : xfree (p1);
416 0 : return -1;
417 : }
418 10 : xfree (p1);
419 10 : return 0;
420 : }
421 :
422 :
423 : static void
424 10 : back_and_forth_one (int testno, const char *buffer, size_t length)
425 : {
426 : gcry_error_t rc;
427 : gcry_sexp_t se, se1;
428 : unsigned char *canon;
429 : size_t canonlen; /* Including the hidden nul suffix. */
430 : size_t n, n1;
431 : char *p1;
432 :
433 10 : rc = gcry_sexp_new (&se, buffer, length, 1);
434 10 : if (rc)
435 : {
436 0 : fail ("baf %d: gcry_sexp_new failed: %s\n", testno, gpg_strerror (rc));
437 0 : return;
438 : }
439 10 : n1 = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, NULL, 0);
440 10 : if (!n1)
441 : {
442 0 : fail ("baf %d: get required length for canon failed\n", testno);
443 0 : return;
444 : }
445 10 : p1 = gcry_xmalloc (n1);
446 10 : n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1, n1);
447 10 : if (n1 != n+1) /* sprints adds an extra 0 but does not return it. */
448 : {
449 0 : fail ("baf %d: length mismatch for canon\n", testno);
450 0 : return;
451 : }
452 10 : canonlen = n1;
453 10 : canon = gcry_malloc (canonlen);
454 10 : memcpy (canon, p1, canonlen);
455 10 : rc = gcry_sexp_create (&se1, p1, n, 0, gcry_free);
456 10 : if (rc)
457 : {
458 0 : fail ("baf %d: gcry_sexp_create failed: %s\n",
459 : testno, gpg_strerror (rc));
460 0 : return;
461 : }
462 10 : gcry_sexp_release (se1);
463 :
464 : /* Again but with memory checking. */
465 10 : p1 = gcry_xmalloc (n1+2);
466 10 : *p1 = '\x55';
467 10 : p1[n1+1] = '\xaa';
468 10 : n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1+1, n1);
469 10 : if (n1 != n+1) /* sprints adds an extra 0 but does not return it */
470 : {
471 0 : fail ("baf %d: length mismatch for canon\n", testno);
472 0 : return;
473 : }
474 10 : if (*p1 != '\x55' || p1[n1+1] != '\xaa')
475 0 : fail ("baf %d: memory corrupted (1)\n", testno);
476 10 : rc = gcry_sexp_create (&se1, p1+1, n, 0, NULL);
477 10 : if (rc)
478 : {
479 0 : fail ("baf %d: gcry_sexp_create failed: %s\n",
480 : testno, gpg_strerror (rc));
481 0 : return;
482 : }
483 10 : if (*p1 != '\x55' || p1[n1+1] != '\xaa')
484 0 : fail ("baf %d: memory corrupted (2)\n", testno);
485 10 : gcry_sexp_release (se1);
486 10 : if (*p1 != '\x55' || p1[n1+1] != '\xaa')
487 0 : fail ("baf %d: memory corrupted (3)\n", testno);
488 10 : gcry_free (p1);
489 :
490 : /* Check converting to advanced format. */
491 10 : n1 = gcry_sexp_sprint (se, GCRYSEXP_FMT_ADVANCED, NULL, 0);
492 10 : if (!n1)
493 : {
494 0 : fail ("baf %d: get required length for advanced failed\n", testno);
495 0 : return;
496 : }
497 10 : p1 = gcry_xmalloc (n1);
498 10 : n = gcry_sexp_sprint (se, GCRYSEXP_FMT_ADVANCED, p1, n1);
499 10 : if (n1 != n+1) /* sprints adds an extra 0 but does not return it */
500 : {
501 0 : fail ("baf %d: length mismatch for advanced\n", testno);
502 0 : return;
503 : }
504 10 : rc = gcry_sexp_create (&se1, p1, n, 0, gcry_free);
505 10 : if (rc)
506 : {
507 0 : fail ("baf %d: gcry_sexp_create failed: %s\n",
508 : testno, gpg_strerror (rc));
509 0 : return;
510 : }
511 10 : if (compare_to_canon (se1, canon, canonlen))
512 : {
513 0 : fail ("baf %d: converting to advanced failed: %s\n",
514 : testno, gpg_strerror (rc));
515 0 : return;
516 : }
517 10 : gcry_sexp_release (se1);
518 :
519 :
520 : /* FIXME: we need a lot more tests */
521 :
522 10 : gcry_sexp_release (se);
523 10 : xfree (canon);
524 : }
525 :
526 :
527 :
528 : static void
529 1 : back_and_forth (void)
530 : {
531 : static struct { const char *buf; int len; } tests[] = {
532 : { "(7:g34:fgh1::2:())", 0 },
533 : { "(7:g34:fgh1::2:())", 18 },
534 : {
535 : "(protected-private-key \n"
536 : " (rsa \n"
537 : " (n #00BE8A536204687149A48FF9F1715FF3530AD9A836D62102BF4065E5CF5953236DB94F1DF2FF4D525CD4CE7966DDC3C839968E8BAC2948934DF047CC65287CD79F6C23C93E55D7F9231E3942BD496DE383469977635A51ADF4AF747DB958CA02E9940DFC1DC0FC7FC755E7EB6618FEE6DA54B8A06E0CBF9D9257443F9992261435#)\n"
538 : " (e #010001#)\n"
539 : " (protected openpgp-s2k3-sha1-aes-cbc \n"
540 : " (\n"
541 : " (sha1 #C2A5673BD3882405# \"96\")\n"
542 : " #8D08AAF6A9209ED69D71EB7E64D78715#)\n"
543 : " #F7B0B535F8F8E22F4F3DA031224070303F82F9207D42952F1ACF21A4AB1C50304EBB25527992C7B265A9E9FF702826FB88759BDD55E4759E9FCA6C879538C9D043A9C60A326CB6681090BAA731289BD880A7D5774D9999F026E5E7963BFC8C0BDC9F061393CB734B4F259725C0A0A0B15BA39C39146EF6A1B3DC4DF30A22EBE09FD05AE6CB0C8C6532951A925F354F4E26A51964F5BBA50081690C421C8385C4074E9BAB9297D081B857756607EAE652415275A741C89E815558A50AC638EDC5F5030210B4395E3E1A40FF38DCCCB333A19EA88EFE7E4D51B54128C6DF27395646836679AC21B1B25C1DA6F0A7CE9F9BE078EFC7934FA9AE202CBB0AA06C20DFAF9A66FAB7E9073FBE96B9A7F25C3BA45EC3EECA65796AEE313BA148DE5314F30345B452B50B17C4D841A7F27397126E8C10BD0CE3B50A82C0425AAEE7798031671407B681F52916256F78CAF92A477AC27BCBE26DAFD1BCE386A853E2A036F8314BB2E8E5BB1F196434232EFB0288331C2AB16DBC5457CC295EB966CAC5CE73D5DA5D566E469F0EFA82F9A12B8693E0#)\n"
544 : " )\n"
545 : " )\n", 0 },
546 : { "((sha1 #8B98CBF4A9823CA7# \"2097\") #3B6FC9#)", 0 },
547 : { "((4:sha18:\x8B\x98\xCB\xF4\xA9\x82\x3C\xA7""4:2097)3:\x3B\x6F\xC9)", 0},
548 : { "((4:sha18:\x8B\x98\xCB\x22\xA9\x82\x3C\xA7""4:2097)3:\x3B\x6F\xC9)", 0},
549 : { "((sha1 #64652267686970C9# \"2097\") #3B6FC9#)", 0 },
550 : { "((4:sha18:\x64\x65\x22\x67\x68\xc3\xa4\x71""4:2097)3:\x3B\x6F\xC9)", 0},
551 : { "((sha1 \"defghäq\" \"2097\") #3B6FC9#)", 0 },
552 : { "((sha1 \"de\\\"ghäq\" \"2097\") #3B6FC9#)", 0 },
553 : { NULL, 0 }
554 : };
555 : int idx;
556 :
557 11 : for (idx=0; tests[idx].buf; idx++)
558 10 : back_and_forth_one (idx, tests[idx].buf, tests[idx].len);
559 1 : }
560 :
561 :
562 : static void
563 1 : check_sscan (void)
564 : {
565 : static struct {
566 : const char *text;
567 : gcry_error_t expected_err;
568 : } values[] = {
569 : /* Bug reported by Olivier L'Heureux 2003-10-07 */
570 : { "(7:sig-val(3:dsa"
571 : "(1:r20:\x7e\xff\xd5\xba\xc9\xc9\xa4\x9b\xd4\x26\x8b\x64"
572 : "\x06\x7a\xcf\x42\x7b\x6c\x51\xfb)"
573 : "(1:s21:\x01\x8c\x6c\x6f\x37\x1a\x8d\xfd\x5a\xb3\x2a\x3d"
574 : "\xc5\xae\x23\xed\x32\x62\x30\x62\x3e)))",
575 : GPG_ERR_NO_ERROR },
576 : { "(7:sig-val(3:dsa"
577 : "(1:r20:\x7e\xff\xd5\xba\xc9\xc9\xa4\x9b\xd4\x26\x8b\x64"
578 : "\x06\x7a\xcf\x42\x7b\x6c\x51\xfb)"
579 : "(1:s21:\x01\x8c\x6c\x6f\x37\x1a\x8d\xfd\x5a\xb3\x2a\x3d"
580 : "\xc5\xae\x23\xed\x32\x62\x30\x62\x3e))",
581 : GPG_ERR_SEXP_UNMATCHED_PAREN },
582 : { "(7:sig-val(3:dsa"
583 : "(1:r20:\x7e\xff\xd5\xba\xc9\xc9\xa4\x9b\xd4\x26\x8b\x64"
584 : "\x06\x7a\xcf\x42\x7b\x6c\x51\xfb)"
585 : "(1:s21:\x01\x8c\x6c\x6f\x37\x1a\x8d\xfd\x5a\xb3\x2a\x3d"
586 : "\xc5\xae\x23\xed\x32\x62\x30\x62\x3e))))",
587 : GPG_ERR_SEXP_UNMATCHED_PAREN },
588 : { NULL, 0 }
589 : };
590 : int idx;
591 : gcry_error_t err;
592 : gcry_sexp_t s;
593 :
594 1 : info ("checking gcry_sexp_sscan\n");
595 4 : for (idx=0; values[idx].text; idx++)
596 : {
597 3 : err = gcry_sexp_sscan (&s, NULL,
598 : values[idx].text,
599 : strlen (values[idx].text));
600 3 : if (gpg_err_code (err) != values[idx].expected_err)
601 0 : fail ("gcry_sexp_sscan test %d failed: %s\n", idx, gpg_strerror (err));
602 3 : gcry_sexp_release (s);
603 : }
604 1 : }
605 :
606 :
607 : static void
608 1 : check_extract_param (void)
609 : {
610 : /* This sample data is a real key but with some parameters of the
611 : public key modified. */
612 : static char sample1[] =
613 : "(key-data"
614 : " (public-key"
615 : " (ecc"
616 : " (curve Ed25519)"
617 : " (p #6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED#)"
618 : " (a #EF#)"
619 : " (b #C2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6#)"
620 : " (g #14"
621 : " 216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
622 : " 6666666666666666666666666666666666666666666666666666666666666658#)"
623 : " (n #0000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED#)"
624 : " (q #20B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62#)"
625 : "))"
626 : " (private-key"
627 : " (ecc"
628 : " (curve Ed25519)"
629 : " (p #7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED#)"
630 : " (a #FF#)"
631 : " (b #D2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6#)"
632 : " (g #04"
633 : " 216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
634 : " 6666666666666666666666666666666666666666666666666666666666666658#)"
635 : " (n #1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED#)"
636 : " (q #30B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62#)"
637 : " (d #56BEA284A22F443A7AEA8CEFA24DA5055CDF1D490C94D8C568FE0802C9169276#)"
638 : ")))";
639 :
640 : static char sample1_p[] =
641 : "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED";
642 : static char sample1_px[] =
643 : "6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED";
644 : static char sample1_a[] = "FF";
645 : static char sample1_ax[] = "EF";
646 : static char sample1_b[] =
647 : "D2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6";
648 : static char sample1_bx[] =
649 : "C2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6";
650 : static char sample1_g[] =
651 : "04"
652 : "216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
653 : "6666666666666666666666666666666666666666666666666666666666666658";
654 : static char sample1_gx[] =
655 : "14"
656 : "216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
657 : "6666666666666666666666666666666666666666666666666666666666666658";
658 : static char sample1_n[] =
659 : "1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED";
660 : static char sample1_nx[] =
661 : "0000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED";
662 : static char sample1_q[] =
663 : "30B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62";
664 : static char sample1_qx[] =
665 : "20B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62";
666 : static char sample1_d[] =
667 : "56BEA284A22F443A7AEA8CEFA24DA5055CDF1D490C94D8C568FE0802C9169276";
668 :
669 : static struct {
670 : const char *sexp_str;
671 : const char *path;
672 : const char *list;
673 : int nparam;
674 : gpg_err_code_t expected_err;
675 : const char *exp_p;
676 : const char *exp_a;
677 : const char *exp_b;
678 : const char *exp_g;
679 : const char *exp_n;
680 : const char *exp_q;
681 : const char *exp_d;
682 : } tests[] = {
683 : {
684 : sample1,
685 : NULL,
686 : "pabgnqd", 6,
687 : GPG_ERR_MISSING_VALUE,
688 : },
689 : {
690 : sample1,
691 : NULL,
692 : "pabgnq", 7,
693 : GPG_ERR_INV_ARG
694 : },
695 : {
696 : sample1,
697 : NULL,
698 : "pab'gnq", 7,
699 : GPG_ERR_SYNTAX
700 : },
701 : {
702 : sample1,
703 : NULL,
704 : "pab''gnq", 7,
705 : GPG_ERR_SYNTAX
706 : },
707 : {
708 : sample1,
709 : NULL,
710 : "pabgnqd", 7,
711 : 0,
712 : sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
713 : sample1_qx, sample1_d
714 : },
715 : {
716 : sample1,
717 : NULL,
718 : " pab\tg nq\nd ", 7,
719 : 0,
720 : sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
721 : sample1_qx, sample1_d
722 : },
723 : {
724 : sample1,
725 : NULL,
726 : "abg", 3,
727 : 0,
728 : sample1_ax, sample1_bx, sample1_gx
729 : },
730 : {
731 : sample1,
732 : NULL,
733 : "ab'g'", 3,
734 : 0,
735 : sample1_ax, sample1_bx, sample1_gx
736 : },
737 : {
738 : sample1,
739 : NULL,
740 : "x?abg", 4,
741 : 0,
742 : NULL, sample1_ax, sample1_bx, sample1_gx
743 : },
744 : {
745 : sample1,
746 : NULL,
747 : "p?abg", 4,
748 : GPG_ERR_USER_1,
749 : NULL, sample1_ax, sample1_bx, sample1_gx
750 : },
751 : {
752 : sample1,
753 : NULL,
754 : "pax?gnqd", 7,
755 : 0,
756 : sample1_px, sample1_ax, NULL, sample1_gx, sample1_nx,
757 : sample1_qx, sample1_d
758 : },
759 : {
760 : sample1,
761 : "public-key",
762 : "pabgnqd", 7,
763 : GPG_ERR_NO_OBJ, /* d is not in public key. */
764 : sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
765 : sample1_qx, sample1_d
766 : },
767 : {
768 : sample1,
769 : "private-key",
770 : "pabgnqd", 7,
771 : 0,
772 : sample1_p, sample1_a, sample1_b, sample1_g, sample1_n,
773 : sample1_q, sample1_d
774 : },
775 : {
776 : sample1,
777 : "public-key!ecc",
778 : "pabgnq", 6,
779 : 0,
780 : sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
781 : sample1_qx
782 : },
783 : {
784 : sample1,
785 : "public-key!ecc!foo",
786 : "pabgnq", 6,
787 : GPG_ERR_NOT_FOUND
788 : },
789 : {
790 : sample1,
791 : "public-key!!ecc",
792 : "pabgnq", 6,
793 : GPG_ERR_NOT_FOUND
794 : },
795 : {
796 : sample1,
797 : "private-key",
798 : "pa/bgnqd", 7,
799 : 0,
800 : sample1_p, sample1_a, sample1_b, sample1_g, sample1_n,
801 : sample1_q, sample1_d
802 : },
803 : {
804 : sample1,
805 : "private-key",
806 : "p-a+bgnqd", 7,
807 : 0,
808 : sample1_p, "-01", sample1_b, sample1_g, sample1_n,
809 : sample1_q, sample1_d
810 : },
811 : {NULL}
812 : };
813 : int idx, i;
814 : const char *paramstr;
815 : int paramidx;
816 : gpg_error_t err;
817 : gcry_sexp_t sxp;
818 : gcry_mpi_t mpis[7];
819 : gcry_buffer_t ioarray[7];
820 : char iobuffer[200];
821 :
822 1 : info ("checking gcry_sexp_extract_param\n");
823 19 : for (idx=0; tests[idx].sexp_str; idx++)
824 : {
825 18 : err = gcry_sexp_new (&sxp, tests[idx].sexp_str, 0, 1);
826 18 : if (err)
827 0 : die ("converting string to sexp failed: %s", gpg_strerror (err));
828 :
829 18 : memset (mpis, 0, sizeof mpis);
830 18 : switch (tests[idx].nparam)
831 : {
832 : case 0:
833 0 : err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
834 : NULL);
835 0 : break;
836 : case 1:
837 0 : err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
838 : mpis+0, NULL);
839 0 : break;
840 : case 2:
841 0 : err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
842 : mpis+0, mpis+1, NULL);
843 0 : break;
844 : case 3:
845 2 : err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
846 : mpis+0, mpis+1, mpis+2, NULL);
847 2 : break;
848 : case 4:
849 2 : err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
850 : mpis+0, mpis+1, mpis+2, mpis+3, NULL);
851 2 : break;
852 : case 5:
853 0 : err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
854 : mpis+0, mpis+1, mpis+2, mpis+3, mpis+4,
855 : NULL);
856 0 : break;
857 : case 6:
858 4 : err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
859 : mpis+0, mpis+1, mpis+2, mpis+3, mpis+4,
860 : mpis+5, NULL);
861 4 : break;
862 : case 7:
863 10 : err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
864 : mpis+0, mpis+1, mpis+2, mpis+3, mpis+4,
865 : mpis+5, mpis+6, NULL);
866 10 : break;
867 : default:
868 0 : die ("test %d: internal error", idx);
869 : }
870 :
871 18 : if (tests[idx].expected_err
872 8 : && tests[idx].expected_err != GPG_ERR_USER_1)
873 : {
874 14 : if (tests[idx].expected_err != gpg_err_code (err))
875 0 : fail ("gcry_sexp_extract_param test %d failed: "
876 : "expected error '%s' - got '%s'", idx,
877 0 : gpg_strerror (tests[idx].expected_err),gpg_strerror (err));
878 :
879 : }
880 11 : else if (err)
881 : {
882 0 : fail ("gcry_sexp_extract_param test %d failed: %s",
883 : idx, gpg_strerror (err));
884 : }
885 : else /* No error - check the extracted values. */
886 : {
887 88 : for (paramidx=0; paramidx < DIM (mpis); paramidx++)
888 : {
889 77 : switch (paramidx)
890 : {
891 11 : case 0: paramstr = tests[idx].exp_p; break;
892 11 : case 1: paramstr = tests[idx].exp_a; break;
893 11 : case 2: paramstr = tests[idx].exp_b; break;
894 11 : case 3: paramstr = tests[idx].exp_g; break;
895 11 : case 4: paramstr = tests[idx].exp_n; break;
896 11 : case 5: paramstr = tests[idx].exp_q; break;
897 11 : case 6: paramstr = tests[idx].exp_d; break;
898 : default:
899 0 : die ("test %d: internal error: bad param %d",
900 : idx, paramidx);
901 : }
902 :
903 77 : if (tests[idx].expected_err == GPG_ERR_USER_1
904 7 : && mpis[paramidx] && !paramstr && paramidx == 0)
905 : ; /* Okay Special case error for param 0. */
906 76 : else if (!mpis[paramidx] && !paramstr)
907 : ; /* Okay. */
908 59 : else if (!mpis[paramidx] && paramstr)
909 0 : fail ("test %d: value for param %d expected but not returned",
910 : idx, paramidx);
911 59 : else if (mpis[paramidx] && !paramstr)
912 0 : fail ("test %d: value for param %d not expected",
913 : idx, paramidx);
914 59 : else if (cmp_mpihex (mpis[paramidx], paramstr))
915 : {
916 0 : fail ("test %d: param %d mismatch", idx, paramidx);
917 0 : gcry_log_debug ("expected: %s\n", paramstr);
918 0 : gcry_log_debugmpi (" got", mpis[paramidx]);
919 : }
920 59 : else if (tests[idx].expected_err && paramidx == 0)
921 0 : fail ("test %d: param %d: expected error '%s' - got 'Success'",
922 0 : idx, paramidx, gpg_strerror (tests[idx].expected_err));
923 : }
924 :
925 : }
926 :
927 144 : for (i=0; i < DIM (mpis); i++)
928 126 : gcry_mpi_release (mpis[i]);
929 18 : gcry_sexp_release (sxp);
930 : }
931 :
932 1 : info ("checking gcry_sexp_extract_param/desc\n");
933 :
934 1 : memset (ioarray, 0, sizeof ioarray);
935 :
936 1 : err = gcry_sexp_new (&sxp, sample1, 0, 1);
937 1 : if (err)
938 0 : die ("converting string to sexp failed: %s", gpg_strerror (err));
939 :
940 1 : ioarray[1].size = sizeof iobuffer;
941 1 : ioarray[1].data = iobuffer;
942 1 : ioarray[1].off = 0;
943 1 : ioarray[2].size = sizeof iobuffer;
944 1 : ioarray[2].data = iobuffer;
945 1 : ioarray[2].off = 50;
946 1 : assert (ioarray[2].off < sizeof iobuffer);
947 1 : err = gcry_sexp_extract_param (sxp, "key-data!private-key", "&pab",
948 : ioarray+0, ioarray+1, ioarray+2, NULL);
949 1 : if (err)
950 0 : fail ("gcry_sexp_extract_param with desc failed: %s", gpg_strerror (err));
951 : else
952 : {
953 1 : if (!ioarray[0].data)
954 0 : fail ("gcry_sexp_extract_param/desc failed: no P");
955 1 : else if (ioarray[0].size != 32)
956 0 : fail ("gcry_sexp_extract_param/desc failed: P has wrong size");
957 1 : else if (ioarray[0].len != 32)
958 0 : fail ("gcry_sexp_extract_param/desc failed: P has wrong length");
959 1 : else if (ioarray[0].off)
960 0 : fail ("gcry_sexp_extract_param/desc failed: P has OFF set");
961 1 : else if (cmp_bufhex (ioarray[0].data, ioarray[0].len, sample1_p))
962 : {
963 0 : fail ("gcry_sexp_extract_param/desc failed: P mismatch");
964 0 : gcry_log_debug ("expected: %s\n", sample1_p);
965 0 : gcry_log_debughex (" got", ioarray[0].data, ioarray[0].len);
966 : }
967 :
968 1 : if (!ioarray[1].data)
969 0 : fail ("gcry_sexp_extract_param/desc failed: A buffer lost");
970 1 : else if (ioarray[1].size != sizeof iobuffer)
971 0 : fail ("gcry_sexp_extract_param/desc failed: A size changed");
972 1 : else if (ioarray[1].off != 0)
973 0 : fail ("gcry_sexp_extract_param/desc failed: A off changed");
974 1 : else if (ioarray[1].len != 1)
975 0 : fail ("gcry_sexp_extract_param/desc failed: A has wrong length");
976 1 : else if (cmp_bufhex ((char *)ioarray[1].data + ioarray[1].off,
977 : ioarray[1].len, sample1_a))
978 : {
979 0 : fail ("gcry_sexp_extract_param/desc failed: A mismatch");
980 0 : gcry_log_debug ("expected: %s\n", sample1_a);
981 0 : gcry_log_debughex (" got",
982 0 : (char *)ioarray[1].data + ioarray[1].off,
983 : ioarray[1].len);
984 : }
985 :
986 1 : if (!ioarray[2].data)
987 0 : fail ("gcry_sexp_extract_param/desc failed: B buffer lost");
988 1 : else if (ioarray[2].size != sizeof iobuffer)
989 0 : fail ("gcry_sexp_extract_param/desc failed: B size changed");
990 1 : else if (ioarray[2].off != 50)
991 0 : fail ("gcry_sexp_extract_param/desc failed: B off changed");
992 1 : else if (ioarray[2].len != 32)
993 0 : fail ("gcry_sexp_extract_param/desc failed: B has wrong length");
994 1 : else if (cmp_bufhex ((char *)ioarray[2].data + ioarray[2].off,
995 : ioarray[2].len, sample1_b))
996 : {
997 0 : fail ("gcry_sexp_extract_param/desc failed: B mismatch");
998 0 : gcry_log_debug ("expected: %s\n", sample1_b);
999 0 : gcry_log_debughex (" got",
1000 0 : (char *)ioarray[2].data + ioarray[2].off,
1001 : ioarray[2].len);
1002 : }
1003 :
1004 1 : xfree (ioarray[0].data);
1005 : }
1006 :
1007 1 : gcry_sexp_release (sxp);
1008 :
1009 1 : info ("checking gcry_sexp_extract_param long name\n");
1010 :
1011 1 : memset (ioarray, 0, sizeof ioarray);
1012 1 : memset (mpis, 0, sizeof mpis);
1013 :
1014 1 : err = gcry_sexp_new (&sxp, sample1, 0, 1);
1015 1 : if (err)
1016 0 : die ("converting string to sexp failed: %s", gpg_strerror (err));
1017 :
1018 1 : err = gcry_sexp_extract_param (sxp, "key-data!private-key",
1019 : "&'curve'+p",
1020 : ioarray+0, mpis+0, NULL);
1021 1 : if (err)
1022 0 : fail ("gcry_sexp_extract_param long name failed: %s", gpg_strerror (err));
1023 :
1024 1 : if (!ioarray[0].data)
1025 0 : fail ("gcry_sexp_extract_param long name failed: no curve");
1026 1 : else if (ioarray[0].size != 7)
1027 0 : fail ("gcry_sexp_extract_param long name failed: curve has wrong size");
1028 1 : else if (ioarray[0].len != 7)
1029 0 : fail ("gcry_sexp_extract_param long name failed: curve has wrong length");
1030 1 : else if (ioarray[0].off)
1031 0 : fail ("gcry_sexp_extract_param long name failed: curve has OFF set");
1032 1 : else if (strncmp (ioarray[0].data, "Ed25519", 7))
1033 : {
1034 0 : fail ("gcry_sexp_extract_param long name failed: curve mismatch");
1035 0 : gcry_log_debug ("expected: %s\n", "Ed25519");
1036 0 : gcry_log_debug (" got: %.*s\n",
1037 0 : (int)ioarray[0].len, (char*)ioarray[0].data);
1038 : }
1039 :
1040 1 : if (!mpis[0])
1041 0 : fail ("gcry_sexp_extract_param long name failed: p not returned");
1042 1 : else if (cmp_mpihex (mpis[0], sample1_p))
1043 : {
1044 0 : fail ("gcry_sexp_extract_param long name failed: p mismatch");
1045 0 : gcry_log_debug ("expected: %s\n", sample1_p);
1046 0 : gcry_log_debugmpi (" got", mpis[0]);
1047 : }
1048 :
1049 1 : gcry_free (ioarray[0].data);
1050 1 : gcry_mpi_release (mpis[0]);
1051 :
1052 1 : gcry_sexp_release (sxp);
1053 :
1054 1 : }
1055 :
1056 :
1057 : /* A test based on bug 1594. */
1058 : static void
1059 1 : bug_1594 (void)
1060 : {
1061 : static char thing[] =
1062 : "(signature"
1063 : " (public-key"
1064 : " (rsa"
1065 : " (n #00A53A6B3A50BE571F805BD98ECE1FCE4CE291C3D4D3E971740E1EE6D447F526"
1066 : " 6AC8973DDC82F0ADD234CC82E0A0A3F48B81ACC8B038DB8ACC3E78DC2ED2642F"
1067 : " 6BA353FCA60F47C2801DEB477B37FB8B2F5508AA1C6D922780DB142DEA19B812"
1068 : " C4E64F1138AD3BD61C58DB2D2591BE0BF36A1AC588AA45763BCDFF581050ABA8"
1069 : " CA47BD9723ADD6A308AE28471EDD2B16D03C941D4F2B7E019C43AF8972880633"
1070 : " 54E97B7E19F1677D84B69A26B184A77B719DD72C48E0EE36107046F786566A9D"
1071 : " 13BAD724D6D78F24700FC22FC000E1B2A8C1B08ED62008395B0764CD9B55E80D"
1072 : " A0A2B61C698DC27EA98E68BB576ACFC2B91B4D7283E7D960948D049D6E3C4CB1"
1073 : " F489B460A120A4BB6C04A843FD3A67454136DE61CF68A927871EFFA9141BD372"
1074 : " A748593C703E0301F039A9E674C50301BFC385BABE5B154250E7D57B82DB31F1"
1075 : " E1AC696F870DCD8FE8DEC75608B988FCA3B484F1FD7755BF452F99597269AF02"
1076 : " E8AF87D0F93DB427291659183D077254C835BFB6DDFD87CD0B5E0738682FCD34"
1077 : " 923F22551F73944E6CBE3ED6879B4414676B5DA0F30ED21DFA12BD2230C3C5D2"
1078 : " EA116A3EFEB4AEC21C58E63FAFA549A63190F01859445E9B80F427B80FD4C884"
1079 : " 2AD41FE760A3E9DEDFB56CEBE8EA783838B2B392CACDDC760CCE212E388AFBC1"
1080 : " 95DC6D0ED87E9091F82A82CE372738C8DE8ABD76ACD06AC8B80AA0597162DF59"
1081 : " 67#)"
1082 : " (e #010001#))))";
1083 : gcry_sexp_t sig, pubkey, n, n_val;
1084 :
1085 1 : info ("checking fix for bug 1594\n");
1086 :
1087 1 : if (gcry_sexp_new (&sig, thing, 0, 1))
1088 0 : die ("scanning fixed string failed\n");
1089 1 : pubkey = gcry_sexp_find_token (sig, "public-key", 0);
1090 1 : gcry_sexp_release (sig);
1091 1 : if (!pubkey)
1092 : {
1093 0 : fail ("'public-key' token not found");
1094 0 : return;
1095 : }
1096 1 : n = gcry_sexp_find_token (pubkey, "n", 0);
1097 1 : if (!n)
1098 : {
1099 0 : fail ("'n' token not found");
1100 0 : gcry_sexp_release (pubkey);
1101 0 : return;
1102 : }
1103 1 : n_val = gcry_sexp_nth (n, 1);
1104 : /* Bug 1594 would require the following test:
1105 : * if (n_val)
1106 : * fail ("extracting 1-th of 'n' list did not fail");
1107 : * However, we meanwhile modified the S-expression functions to
1108 : * behave like Scheme to allow the access of any element of a list.
1109 : */
1110 1 : if (!n_val)
1111 0 : fail ("extracting 1-th of 'n' list failed");
1112 : /*gcry_log_debugsxp ("1-th", n_val); => "(#00A5...#)" */
1113 1 : gcry_sexp_release (n_val);
1114 1 : n_val = gcry_sexp_nth (n, 2);
1115 1 : if (n_val)
1116 0 : fail ("extracting 2-th of 'n' list did not fail");
1117 1 : n_val = gcry_sexp_nth (n, 0);
1118 1 : if (!n_val)
1119 0 : fail ("extracting 0-th of 'n' list failed");
1120 : /*gcry_log_debugsxp ("0-th", n_val); => "(n)" */
1121 1 : if (gcry_sexp_nth (n_val, 1))
1122 0 : fail ("extracting 1-th of car of 'n' list did not fail");
1123 1 : gcry_sexp_release (n_val);
1124 1 : gcry_sexp_release (n);
1125 1 : gcry_sexp_release (pubkey);
1126 : }
1127 :
1128 :
1129 : int
1130 1 : main (int argc, char **argv)
1131 : {
1132 1 : int last_argc = -1;
1133 :
1134 1 : if (argc)
1135 : {
1136 1 : argc--; argv++;
1137 : }
1138 2 : while (argc && last_argc != argc )
1139 : {
1140 0 : last_argc = argc;
1141 0 : if (!strcmp (*argv, "--"))
1142 : {
1143 0 : argc--; argv++;
1144 0 : break;
1145 : }
1146 0 : else if (!strcmp (*argv, "--help"))
1147 : {
1148 0 : puts (
1149 : "usage: " PGMNAME " [options]\n"
1150 : "\n"
1151 : "Options:\n"
1152 : " --verbose Show what is going on\n"
1153 : " --debug Flyswatter\n"
1154 : );
1155 0 : exit (0);
1156 : }
1157 0 : else if (!strcmp (*argv, "--verbose"))
1158 : {
1159 0 : verbose = 1;
1160 0 : argc--; argv++;
1161 : }
1162 0 : else if (!strcmp (*argv, "--debug"))
1163 : {
1164 0 : verbose = debug = 1;
1165 0 : argc--; argv++;
1166 : }
1167 0 : else if (!strncmp (*argv, "--", 2))
1168 0 : die ("unknown option '%s'", *argv);
1169 : }
1170 :
1171 1 : if (debug)
1172 0 : gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
1173 1 : gcry_control (GCRYCTL_DISABLE_SECMEM_WARN);
1174 1 : gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
1175 1 : if (!gcry_check_version (GCRYPT_VERSION))
1176 0 : die ("version mismatch");
1177 : /* #include "../src/gcrypt-int.h" indicates that internal interfaces
1178 : may be used; thus better do an exact version check. */
1179 1 : if (strcmp (gcry_check_version (NULL), GCRYPT_VERSION))
1180 0 : die ("exact version match failed");
1181 1 : gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
1182 1 : gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
1183 :
1184 1 : basic ();
1185 1 : canon_len ();
1186 1 : back_and_forth ();
1187 1 : check_sscan ();
1188 1 : check_extract_param ();
1189 1 : bug_1594 ();
1190 :
1191 1 : return errorcount? 1:0;
1192 : }
|