/external/libgcrypt/tests/tsexp.c

http://get-a-robot-vpnc.googlecode.com/ · C · 456 lines · 376 code · 55 blank · 25 comment · 56 complexity · da0f57fbf55ed1bb77d476ccd2c76a28 MD5 · raw file

  1. /* tsexp.c - S-expression regression tests
  2. * Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
  3. *
  4. * This file is part of Libgcrypt.
  5. *
  6. * Libgcrypt is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU Lesser General Public License as
  8. * published by the Free Software Foundation; either version 2.1 of
  9. * the License, or (at your option) any later version.
  10. *
  11. * Libgcrypt 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 Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  19. */
  20. #ifdef HAVE_CONFIG_H
  21. #include <config.h>
  22. #endif
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <stdarg.h>
  27. #include "../src/gcrypt.h"
  28. #define PGMNAME "tsexp"
  29. static int verbose;
  30. static int error_count;
  31. static void
  32. info (const char *format, ...)
  33. {
  34. va_list arg_ptr;
  35. if (verbose)
  36. {
  37. va_start( arg_ptr, format ) ;
  38. vfprintf (stderr, format, arg_ptr );
  39. va_end(arg_ptr);
  40. }
  41. }
  42. static void
  43. fail ( const char *format, ... )
  44. {
  45. va_list arg_ptr ;
  46. fputs (PGMNAME ": ", stderr);
  47. va_start( arg_ptr, format ) ;
  48. vfprintf (stderr, format, arg_ptr );
  49. va_end(arg_ptr);
  50. error_count++;
  51. }
  52. /* fixme: we need better tests */
  53. static void
  54. basic (void)
  55. {
  56. int pass;
  57. gcry_sexp_t sexp;
  58. int idx;
  59. char *secure_buffer;
  60. size_t secure_buffer_len;
  61. const char *string;
  62. static struct {
  63. const char *token;
  64. const char *parm;
  65. } values[] = {
  66. { "public-key", NULL },
  67. { "dsa", NULL },
  68. { "dsa", "p" },
  69. { "dsa", "y" },
  70. { "dsa", "q" },
  71. { "dsa", "g" },
  72. { NULL }
  73. };
  74. info ("doing some pretty pointless tests\n");
  75. secure_buffer_len = 99;
  76. secure_buffer = gcry_xmalloc_secure (secure_buffer_len);
  77. memset (secure_buffer, 'G', secure_buffer_len);
  78. for (pass=0;;pass++)
  79. {
  80. switch (pass)
  81. {
  82. case 0:
  83. string = ("(public-key (dsa (p #41424344#) (y this_is_y) "
  84. "(q #61626364656667#) (g %m)))");
  85. if ( gcry_sexp_build (&sexp, NULL, string,
  86. gcry_mpi_set_ui (NULL, 42)) )
  87. {
  88. fail (" scanning `%s' failed\n", string);
  89. return;
  90. }
  91. break;
  92. case 1:
  93. string = ("(public-key (dsa (p #41424344#) (y this_is_y) "
  94. "(q %b) (g %m)))");
  95. if ( gcry_sexp_build (&sexp, NULL, string,
  96. 15, "foo\0\x01\0x02789012345",
  97. gcry_mpi_set_ui (NULL, 42)) )
  98. {
  99. fail (" scanning `%s' failed\n", string);
  100. return;
  101. }
  102. break;
  103. case 2:
  104. string = ("(public-key (dsa (p #41424344#) (y silly_y_value) "
  105. "(q %b) (g %m)))");
  106. if ( gcry_sexp_build (&sexp, NULL, string,
  107. secure_buffer_len, secure_buffer,
  108. gcry_mpi_set_ui (NULL, 17)) )
  109. {
  110. fail (" scanning `%s' failed\n", string);
  111. return;
  112. }
  113. if (!gcry_is_secure (sexp))
  114. fail ("gcry_sexp_build did not switch to secure memory\n");
  115. break;
  116. case 3:
  117. {
  118. gcry_sexp_t help_sexp;
  119. if (gcry_sexp_new (&help_sexp,
  120. "(foobar-parms (xp #1234#)(xq #03#))", 0, 1))
  121. {
  122. fail (" scanning fixed string failed\n");
  123. return;
  124. }
  125. string = ("(public-key (dsa (p #41424344#) (parm %S) "
  126. "(y dummy)(q %b) (g %m)))");
  127. if ( gcry_sexp_build (&sexp, NULL, string, help_sexp,
  128. secure_buffer_len, secure_buffer,
  129. gcry_mpi_set_ui (NULL, 17)) )
  130. {
  131. fail (" scanning `%s' failed\n", string);
  132. return;
  133. }
  134. gcry_sexp_release (help_sexp);
  135. }
  136. break;
  137. default:
  138. return; /* Ready. */
  139. }
  140. /* now find something */
  141. for (idx=0; values[idx].token; idx++)
  142. {
  143. const char *token = values[idx].token;
  144. const char *parm = values[idx].parm;
  145. gcry_sexp_t s1, s2;
  146. gcry_mpi_t a;
  147. const char *p;
  148. size_t n;
  149. s1 = gcry_sexp_find_token (sexp, token, strlen(token) );
  150. if (!s1)
  151. {
  152. fail ("didn't found `%s'\n", token);
  153. continue;
  154. }
  155. p = gcry_sexp_nth_data (s1, 0, &n);
  156. if (!p)
  157. {
  158. fail ("no car for `%s'\n", token);
  159. continue;
  160. }
  161. info ("car=`%.*s'\n", (int)n, p);
  162. s2 = gcry_sexp_cdr (s1);
  163. if (!s2)
  164. {
  165. fail ("no cdr for `%s'\n", token);
  166. continue;
  167. }
  168. p = gcry_sexp_nth_data (s2, 0, &n);
  169. if (p)
  170. {
  171. fail ("data at car of `%s'\n", token);
  172. continue;
  173. }
  174. if (parm)
  175. {
  176. s2 = gcry_sexp_find_token (s1, parm, strlen (parm));
  177. if (!s2)
  178. {
  179. fail ("didn't found `%s'\n", parm);
  180. continue;
  181. }
  182. p = gcry_sexp_nth_data (s2, 0, &n);
  183. if (!p)
  184. {
  185. fail("no car for `%s'\n", parm );
  186. continue;
  187. }
  188. info ("car=`%.*s'\n", (int)n, p);
  189. p = gcry_sexp_nth_data (s2, 1, &n);
  190. if (!p)
  191. {
  192. fail("no cdr for `%s'\n", parm );
  193. continue;
  194. }
  195. info ("cdr=`%.*s'\n", (int)n, p);
  196. a = gcry_sexp_nth_mpi (s2, 0, GCRYMPI_FMT_USG);
  197. if (!a)
  198. {
  199. fail("failed to cdr the mpi for `%s'\n", parm);
  200. continue;
  201. }
  202. }
  203. }
  204. gcry_sexp_release (sexp);
  205. sexp = NULL;
  206. }
  207. gcry_free (secure_buffer);
  208. }
  209. static void
  210. canon_len (void)
  211. {
  212. static struct {
  213. size_t textlen; /* length of the buffer */
  214. size_t expected;/* expected length or 0 on error and then ... */
  215. size_t erroff; /* ... and at this offset */
  216. gcry_error_t errcode; /* ... with this error code */
  217. const char *text;
  218. } values[] = {
  219. { 14, 13, 0, GPG_ERR_NO_ERROR, "(9:abcdefghi) " },
  220. { 16, 15, 0, GPG_ERR_NO_ERROR, "(10:abcdefghix)" },
  221. { 14, 0,14, GPG_ERR_SEXP_STRING_TOO_LONG, "(10:abcdefghi)" },
  222. { 15, 0, 1, GPG_ERR_SEXP_ZERO_PREFIX, "(010:abcdefghi)" },
  223. { 2, 0, 0, GPG_ERR_SEXP_NOT_CANONICAL, "1:"},
  224. { 4, 0, 4, GPG_ERR_SEXP_STRING_TOO_LONG, "(1:)"},
  225. { 5, 5, 0, GPG_ERR_NO_ERROR, "(1:x)"},
  226. { 2, 2, 0, GPG_ERR_NO_ERROR, "()"},
  227. { 4, 2, 0, GPG_ERR_NO_ERROR, "()()"},
  228. { 4, 4, 0, GPG_ERR_NO_ERROR, "(())"},
  229. { 3, 0, 3, GPG_ERR_SEXP_STRING_TOO_LONG, "(()"},
  230. { 3, 0, 1, GPG_ERR_SEXP_BAD_CHARACTER, "( )"},
  231. { 9, 9, 0, GPG_ERR_NO_ERROR, "(3:abc())"},
  232. { 10, 0, 6, GPG_ERR_SEXP_BAD_CHARACTER, "(3:abc ())"},
  233. /* fixme: we need much more cases */
  234. { 0 },
  235. };
  236. int idx;
  237. gcry_error_t errcode;
  238. size_t n, erroff;
  239. info ("checking canoncial length test function\n");
  240. for (idx=0; values[idx].text; idx++)
  241. {
  242. n = gcry_sexp_canon_len ((const unsigned char*)values[idx].text,
  243. values[idx].textlen,
  244. &erroff, &errcode);
  245. if (n && n == values[idx].expected)
  246. ; /* success */
  247. else if (!n && !values[idx].expected)
  248. { /* we expected an error - check that this is the right one */
  249. if (values[idx].erroff != erroff)
  250. fail ("canonical length test %d - wrong error offset %u\n",
  251. idx, (unsigned int)erroff);
  252. if (gcry_err_code (errcode) != values[idx].errcode)
  253. fail ("canonical length test %d - wrong error code %d\n",
  254. idx, errcode);
  255. }
  256. else
  257. fail ("canonical length test %d failed - n=%u, off=%u, err=%d\n",
  258. idx, (unsigned int)n, (unsigned int)erroff, errcode);
  259. }
  260. }
  261. static void
  262. back_and_forth_one (int testno, const char *buffer, size_t length)
  263. {
  264. gcry_error_t rc;
  265. gcry_sexp_t se, se1;
  266. size_t n, n1;
  267. char *p1;
  268. rc = gcry_sexp_new (&se, buffer, length, 1);
  269. if (rc)
  270. {
  271. fail ("baf %d: gcry_sexp_new failed: %s\n", testno, gpg_strerror (rc));
  272. return;
  273. }
  274. n1 = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, NULL, 0);
  275. if (!n1)
  276. {
  277. fail ("baf %d: get required length for canon failed\n", testno);
  278. return;
  279. }
  280. p1 = gcry_xmalloc (n1);
  281. n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1, n1);
  282. if (n1 != n+1) /* sprints adds an extra 0 but dies not return it */
  283. {
  284. fail ("baf %d: length mismatch for canon\n", testno);
  285. return;
  286. }
  287. rc = gcry_sexp_create (&se1, p1, n, 0, gcry_free);
  288. if (rc)
  289. {
  290. fail ("baf %d: gcry_sexp_create failed: %s\n",
  291. testno, gpg_strerror (rc));
  292. return;
  293. }
  294. gcry_sexp_release (se1);
  295. /* Again but with memory checking. */
  296. p1 = gcry_xmalloc (n1+2);
  297. *p1 = '\x55';
  298. p1[n1+1] = '\xaa';
  299. n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1+1, n1);
  300. if (n1 != n+1) /* sprints adds an extra 0 but does not return it */
  301. {
  302. fail ("baf %d: length mismatch for canon\n", testno);
  303. return;
  304. }
  305. if (*p1 != '\x55' || p1[n1+1] != '\xaa')
  306. fail ("baf %d: memory corrupted (1)\n", testno);
  307. rc = gcry_sexp_create (&se1, p1+1, n, 0, NULL);
  308. if (rc)
  309. {
  310. fail ("baf %d: gcry_sexp_create failed: %s\n",
  311. testno, gpg_strerror (rc));
  312. return;
  313. }
  314. if (*p1 != '\x55' || p1[n1+1] != '\xaa')
  315. fail ("baf %d: memory corrupted (2)\n", testno);
  316. gcry_sexp_release (se1);
  317. if (*p1 != '\x55' || p1[n1+1] != '\xaa')
  318. fail ("baf %d: memory corrupted (3)\n", testno);
  319. gcry_free (p1);
  320. /* FIXME: we need a lot more tests */
  321. gcry_sexp_release (se);
  322. }
  323. static void
  324. back_and_forth (void)
  325. {
  326. static struct { const char *buf; int len; } tests[] = {
  327. { "(7:g34:fgh1::2:())", 0 },
  328. { "(7:g34:fgh1::2:())", 18 },
  329. {
  330. "(protected-private-key \n"
  331. " (rsa \n"
  332. " (n #00BE8A536204687149A48FF9F1715FF3530AD9A836D62102BF4065E5CF5953236DB94F1DF2FF4D525CD4CE7966DDC3C839968E8BAC2948934DF047CC65287CD79F6C23C93E55D7F9231E3942BD496DE383469977635A51ADF4AF747DB958CA02E9940DFC1DC0FC7FC755E7EB6618FEE6DA54B8A06E0CBF9D9257443F9992261435#)\n"
  333. " (e #010001#)\n"
  334. " (protected openpgp-s2k3-sha1-aes-cbc \n"
  335. " (\n"
  336. " (sha1 #C2A5673BD3882405# \"96\")\n"
  337. " #8D08AAF6A9209ED69D71EB7E64D78715#)\n"
  338. " #F7B0B535F8F8E22F4F3DA031224070303F82F9207D42952F1ACF21A4AB1C50304EBB25527992C7B265A9E9FF702826FB88759BDD55E4759E9FCA6C879538C9D043A9C60A326CB6681090BAA731289BD880A7D5774D9999F026E5E7963BFC8C0BDC9F061393CB734B4F259725C0A0A0B15BA39C39146EF6A1B3DC4DF30A22EBE09FD05AE6CB0C8C6532951A925F354F4E26A51964F5BBA50081690C421C8385C4074E9BAB9297D081B857756607EAE652415275A741C89E815558A50AC638EDC5F5030210B4395E3E1A40FF38DCCCB333A19EA88EFE7E4D51B54128C6DF27395646836679AC21B1B25C1DA6F0A7CE9F9BE078EFC7934FA9AE202CBB0AA06C20DFAF9A66FAB7E9073FBE96B9A7F25C3BA45EC3EECA65796AEE313BA148DE5314F30345B452B50B17C4D841A7F27397126E8C10BD0CE3B50A82C0425AAEE7798031671407B681F52916256F78CAF92A477AC27BCBE26DAFD1BCE386A853E2A036F8314BB2E8E5BB1F196434232EFB0288331C2AB16DBC5457CC295EB966CAC5CE73D5DA5D566E469F0EFA82F9A12B8693E0#)\n"
  339. " )\n"
  340. " )\n", 0 },
  341. { NULL, 0 }
  342. };
  343. int idx;
  344. for (idx=0; tests[idx].buf; idx++)
  345. back_and_forth_one (idx, tests[idx].buf, tests[idx].len);
  346. }
  347. static void
  348. check_sscan (void)
  349. {
  350. static struct {
  351. const char *text;
  352. gcry_error_t expected_err;
  353. } values[] = {
  354. /* Bug reported by Olivier L'Heureux 2003-10-07 */
  355. { "(7:sig-val(3:dsa"
  356. "(1:r20:\x7e\xff\xd5\xba\xc9\xc9\xa4\x9b\xd4\x26\x8b\x64"
  357. "\x06\x7a\xcf\x42\x7b\x6c\x51\xfb)"
  358. "(1:s21:\x01\x8c\x6c\x6f\x37\x1a\x8d\xfd\x5a\xb3\x2a\x3d"
  359. "\xc5\xae\x23\xed\x32\x62\x30\x62\x3e)))",
  360. GPG_ERR_NO_ERROR },
  361. { "(7:sig-val(3:dsa"
  362. "(1:r20:\x7e\xff\xd5\xba\xc9\xc9\xa4\x9b\xd4\x26\x8b\x64"
  363. "\x06\x7a\xcf\x42\x7b\x6c\x51\xfb)"
  364. "(1:s21:\x01\x8c\x6c\x6f\x37\x1a\x8d\xfd\x5a\xb3\x2a\x3d"
  365. "\xc5\xae\x23\xed\x32\x62\x30\x62\x3e))",
  366. GPG_ERR_SEXP_UNMATCHED_PAREN },
  367. { "(7:sig-val(3:dsa"
  368. "(1:r20:\x7e\xff\xd5\xba\xc9\xc9\xa4\x9b\xd4\x26\x8b\x64"
  369. "\x06\x7a\xcf\x42\x7b\x6c\x51\xfb)"
  370. "(1:s21:\x01\x8c\x6c\x6f\x37\x1a\x8d\xfd\x5a\xb3\x2a\x3d"
  371. "\xc5\xae\x23\xed\x32\x62\x30\x62\x3e))))",
  372. GPG_ERR_SEXP_UNMATCHED_PAREN },
  373. { NULL, 0 }
  374. };
  375. int idx;
  376. gcry_error_t err;
  377. gcry_sexp_t s;
  378. info ("checking gcry_sexp_sscan\n");
  379. for (idx=0; values[idx].text; idx++)
  380. {
  381. err = gcry_sexp_sscan (&s, NULL,
  382. values[idx].text,
  383. strlen (values[idx].text));
  384. if (gpg_err_code (err) != values[idx].expected_err)
  385. fail ("gcry_sexp_sscan test %d failed: %s\n", idx, gpg_strerror (err));
  386. gcry_sexp_release (s);
  387. }
  388. }
  389. int
  390. main (int argc, char **argv)
  391. {
  392. if (argc > 1 && !strcmp (argv[1], "--verbose"))
  393. verbose = 1;
  394. gcry_control (GCRYCTL_DISABLE_SECMEM_WARN);
  395. gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
  396. basic ();
  397. canon_len ();
  398. back_and_forth ();
  399. check_sscan ();
  400. return error_count? 1:0;
  401. }