1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /* unit-test-crypto.c: Test crypto stuff
3 
4    Copyright (C) 2007 Stefan Walter
5 
6    The Gnome Keyring Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Library General Public License as
8    published by the Free Software Foundation; either version 2 of the
9    License, or (at your option) any later version.
10 
11    The Gnome Keyring Library 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 GNU
14    Library General Public License for more details.
15 
16    You should have received a copy of the GNU Library General Public
17    License along with the Gnome Library; see the file COPYING.LIB.  If not,
18    see <http://www.gnu.org/licenses/>.
19 
20    Author: Stef Walter <stef@memberwebs.com>
21 */
22 
23 #include "config.h"
24 
25 #include "egg/egg-asn1x.h"
26 #include "egg/egg-asn1-defs.h"
27 #include "egg/egg-libgcrypt.h"
28 #include "egg/egg-secure-memory.h"
29 #include "egg/egg-symkey.h"
30 #include "egg/egg-testing.h"
31 
32 typedef struct _EggAsn1xDef ASN1_ARRAY_TYPE;
33 typedef struct _EggAsn1xDef asn1_static_node;
34 #include "test.asn.h"
35 
36 #include <gcrypt.h>
37 
38 #include <stdlib.h>
39 #include <stdio.h>
40 #include <string.h>
41 
42 EGG_SECURE_DEFINE_GLIB_GLOBALS ();
43 
44 static const struct {
45 	const gchar *password;
46 	int cipher_algo;
47 	int hash_algo;
48 	int iterations;
49 	const gchar *salt;
50 
51 	const gchar *result_simple;
52 	const gchar *result_pkcs12;
53 	const gchar *result_pbkdf2;
54 	const gchar *result_pbe;
55 } all_generation_tests[] = {
56 
57 	{ /* 24 byte output */
58 		"booo", GCRY_CIPHER_3DES, GCRY_MD_MD5, 1,
59 		"\x70\x4C\xFF\xD6\x2F\xBA\x03\xE9",
60 		"\x84\x12\xBB\x34\x94\x8C\x40\xAD\x97\x57\x96\x74\x5B\x6A\xFB\xF8\xD6\x61\x33\x51\xEA\x8C\xCF\xD8",
61 		NULL,
62 		NULL,
63 		NULL
64 	},
65 
66 	{ /* 5 byte output */
67 		"booo", GCRY_CIPHER_RFC2268_40, GCRY_MD_SHA1, 2048,
68 		"\x8A\x58\xC2\xE8\x7C\x1D\x80\x11",
69 		NULL,
70 		"\xD6\xA6\xF0\x76\x66",
71 		NULL,
72 		NULL
73 	},
74 
75 	{ /* Null Password, 5 byte output */
76 		NULL, GCRY_CIPHER_RFC2268_40, GCRY_MD_SHA1, 2000,
77 		"\x04\xE0\x1C\x3E\xF8\xF2\xE9\xFD",
78 		NULL,
79 		"\x98\x7F\x20\x97\x1E",
80 		NULL,
81 		NULL
82 	},
83 
84 	{ /* 24 byte output */
85 		"booo", GCRY_CIPHER_3DES, GCRY_MD_SHA1, 2048,
86 		"\xBD\xEE\x0B\xC6\xCF\x43\xAC\x25",
87 		NULL,
88 		"\x3F\x38\x1B\x0E\x87\xEB\x19\xBE\xD1\x39\xDC\x5B\xC2\xD2\xB3\x3C\x35\xA8\xB8\xF9\xEE\x66\x48\x94",
89 		"\x20\x25\x90\xD8\xD6\x98\x3E\x71\x10\x17\x1F\x51\x49\x87\x27\xCA\x97\x27\xD1\xC9\x72\xF8\x11\xBB",
90 		NULL
91 	},
92 
93 	{ /* Empty password, 24 byte output */
94 		"", GCRY_CIPHER_3DES, GCRY_MD_SHA1, 2048,
95 		"\xF7\xCF\xD9\xCF\x1F\xF3\xAD\xF6",
96 		NULL,
97 		NULL,
98 		"\x53\xE3\x35\x9E\x5D\xC1\x85\x1A\x71\x3A\x67\x4E\x80\x56\x13\xD6\x4E\x3E\x89\x43\xB7\x1D\x5F\x7F",
99 		NULL
100 	},
101 
102 	{ /* Empty password, 24 byte output */
103 		"", GCRY_CIPHER_3DES, GCRY_MD_SHA1, 2048,
104 		"\xD9\xB3\x2E\xC7\xBA\x1A\x8E\x15",
105 		NULL,
106 		"\x39\x70\x75\x7C\xF5\xE2\x13\x0B\x5D\xC2\x9D\x96\x8B\x71\xC7\xFC\x5B\x97\x1F\x79\x9F\x06\xFC\xA2",
107 		NULL,
108 		NULL
109 	},
110 
111 	{ /* 8 byte output */
112 		"booo", GCRY_CIPHER_DES, GCRY_MD_MD5, 2048,
113 		"\x93\x4C\x3D\x29\xA2\x42\xB0\xF5",
114 		NULL,
115 		NULL,
116 		NULL,
117 		"\x8C\x67\x19\x7F\xB9\x23\xE2\x8D"
118 	}
119 };
120 
121 #define N_GENERATION_TESTS (sizeof (all_generation_tests) / sizeof (all_generation_tests[0]))
122 
123 static void
test_generate_key_simple(void)124 test_generate_key_simple (void)
125 {
126 	int i;
127 	gboolean ret;
128 	guchar *key;
129 
130 	for (i = 0; i < N_GENERATION_TESTS; ++i) {
131 
132 		if (!all_generation_tests[i].result_simple)
133 			continue;
134 
135 		ret = egg_symkey_generate_simple (all_generation_tests[i].cipher_algo,
136 		                                  all_generation_tests[i].hash_algo,
137 		                                  all_generation_tests[i].password, -1,
138 		                                  (guchar*)all_generation_tests[i].salt, 8,
139 		                                  all_generation_tests[i].iterations,
140 		                                  &key, NULL);
141 		g_assert (ret && "key generation failed");
142 
143 		ret = (memcmp (key, all_generation_tests[i].result_simple,
144 		               gcry_cipher_get_algo_keylen (all_generation_tests[i].cipher_algo)) == 0);
145 
146 		g_assert (ret && "invalid simple key generated");
147 
148 		egg_secure_free (key);
149 	}
150 }
151 
152 static void
test_generate_key_pkcs12(void)153 test_generate_key_pkcs12 (void)
154 {
155 	int i;
156 	gboolean ret;
157 	guchar *key;
158 
159 	for (i = 0; i < N_GENERATION_TESTS; ++i) {
160 
161 		if (!all_generation_tests[i].result_pkcs12)
162 			continue;
163 
164 		ret = egg_symkey_generate_pkcs12 (all_generation_tests[i].cipher_algo,
165 		                                  all_generation_tests[i].hash_algo,
166 		                                  all_generation_tests[i].password, -1,
167 		                                  (guchar*)all_generation_tests[i].salt, 8,
168 		                                  all_generation_tests[i].iterations,
169 		                                  &key, NULL);
170 		g_assert ("failed to generate pkcs12 key" && ret);
171 
172 		ret = (memcmp (key, all_generation_tests[i].result_pkcs12,
173 			        gcry_cipher_get_algo_keylen (all_generation_tests[i].cipher_algo)) == 0);
174 
175 		g_assert ("invalid pkcs12 key generated" && ret);
176 
177 		egg_secure_free (key);
178 	}
179 }
180 
181 static void
test_generate_key_pbkdf2(void)182 test_generate_key_pbkdf2 (void)
183 {
184 	int i;
185 	gboolean ret;
186 	guchar *key;
187 
188 	for (i = 0; i < N_GENERATION_TESTS; ++i) {
189 
190 		if (!all_generation_tests[i].result_pbkdf2)
191 			continue;
192 
193 		ret = egg_symkey_generate_pbkdf2 (all_generation_tests[i].cipher_algo,
194 		                                  all_generation_tests[i].hash_algo,
195 		                                  all_generation_tests[i].password, -1,
196 		                                  (guchar*)all_generation_tests[i].salt, 8,
197 		                                  all_generation_tests[i].iterations,
198 		                                  &key, NULL);
199 		g_assert ("failed to generate pbkdf2 key" && ret);
200 
201 		ret = (memcmp (key, all_generation_tests[i].result_pbkdf2,
202 			        gcry_cipher_get_algo_keylen (all_generation_tests[i].cipher_algo)) == 0);
203 
204 		g_assert ("invalid pbkdf2 key generated" && ret);
205 
206 		egg_secure_free (key);
207 	}
208 }
209 
210 static void
test_generate_key_pbe(void)211 test_generate_key_pbe (void)
212 {
213 	int i;
214 	gboolean ret;
215 	guchar *key;
216 
217 	for (i = 0; i < N_GENERATION_TESTS; ++i) {
218 
219 		if (!all_generation_tests[i].result_pbe)
220 			continue;
221 
222 		ret = egg_symkey_generate_pbe (all_generation_tests[i].cipher_algo,
223 		                               all_generation_tests[i].hash_algo,
224 		                               all_generation_tests[i].password, -1,
225 		                               (guchar*)all_generation_tests[i].salt, 8,
226 		                               all_generation_tests[i].iterations,
227 		                               &key, NULL);
228 		g_assert ("failed to generate pbe key" && ret);
229 
230 		ret = (memcmp (key, all_generation_tests[i].result_pbe,
231 			        gcry_cipher_get_algo_keylen (all_generation_tests[i].cipher_algo)) == 0);
232 
233 		g_assert ("invalid pbe key generated" && ret);
234 
235 		egg_secure_free (key);
236 	}
237 }
238 
239 typedef struct {
240 	const gchar *name;
241 	const gchar *scheme;
242 
243 	/* Info to use with cipher */
244 	const gchar *password;
245 	const gchar *salt;
246 	gsize iterations;
247 
248 	/* DER representation of cipher */
249 	gsize n_der;
250 	const gchar *der;
251 
252 	/* Data to encrypt and test with */
253 	gsize n_text_length;
254 	const gchar *plain_text;
255 	const gchar *cipher_text;
256 } ReadCipher;
257 
258 static const ReadCipher cipher_tests[] = {
259 	{
260 		"pbe-sha1-des-cbc", "1.2.840.113549.1.5.10",
261 		"password", "saltsalt", 33,
262 		15, "\x30\x0D"
263 			"\x04\x08""saltsalt"
264 			"\x02\x01\x2A",
265 		8, "plaintex", "\x69\xe2\x88\x4c\x31\xcf\x0e\x2a"
266 	},
267 	{
268 		"pkcs12-pbe-3des-sha1", "1.2.840.113549.1.12.1.3",
269 		"password", "saltsalt", 33,
270 		15, "\x30\x0D"
271 			"\x04\x08""saltsalt"
272 			"\x02\x01\x2A",
273 		8, "plaintex", "\xcf\xfb\x49\x2e\x42\x75\x15\x56"
274 	},
275 	{
276 		"pkcs5-pbes2", "1.2.840.113549.1.5.13",
277 		"password", "salt", 33,
278 		48, "\x30\x2e"
279 			"\x30\x16"
280 				"\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x05\x0c"
281 				"\x30\x09"
282 					"\x04\x04\x73\x61\x6c\x74"
283 					"\x02\x01\x21"
284 			"\x30\x14"
285 				"\x06\x08\x2a\x86\x48\x86\xf7\x0d\x03\x07"
286 				"\x04\x08\x73\x61\x6c\x74\x73\x61\x6c\x74",
287 		8, "plaintex", "\x46\x1A\x3A\x39\xD0\xF5\x21\x5C"
288 	},
289 	{
290 		"pkcs5-pbes2-des-cbc", "1.2.840.113549.1.5.13",
291 		"password", "salt", 33,
292 		0x2d, "\x30\x2b"
293 			"\x30\x16"
294 				"\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x05\x0c"
295 				"\x30\x09"
296 					"\x04\x04\x73\x61\x6c\x74"
297 					"\x02\x01\x21"
298 			"\x30\x11"
299 				"\x06\x05\x2b\x0e\x03\x02\x07"
300 				"\x04\x08\x73\x61\x6c\x74\x73\x61\x6c\x74",
301 		8, "plaintex", "\xB7\x7B\x54\xBF\x29\x4D\x31\x7D"
302 	}
303 };
304 
305 typedef struct {
306 	const gchar *name;
307 	const gchar *scheme;
308 
309 	/* Info to use with cipher */
310 	const gchar *password;
311 
312 	/* DER representation of cipher */
313 	gsize n_der;
314 	const gchar *der;
315 } InvalidCipher;
316 
317 #if 0
318 #include "egg/egg-hex.h"
319 
320 static void
321 create_pkcs5_pbes2 (void)
322 {
323 	GNode *asn;
324 	GNode *param;
325 	GBytes *bytes;
326 	gconstpointer data;
327 	gsize size;
328 
329 	asn = egg_asn1x_create (pkix_asn1_tab, "pkcs-5-PBES2-params");
330 
331 	egg_asn1x_set_oid_as_string (egg_asn1x_node (asn, "keyDerivationFunc", "algorithm", NULL), "1.2.840.113549.1.5.12");
332 	param = egg_asn1x_create (pkix_asn1_tab, "pkcs-5-PBKDF2-params");
333 	egg_asn1x_set_integer_as_ulong (egg_asn1x_node (param, "iterationCount", NULL), 33);
334 #if 1
335 	egg_asn1x_set_choice (egg_asn1x_node (param, "salt", NULL), egg_asn1x_node (param, "salt", "specified", NULL));
336 	egg_asn1x_set_string_as_raw (egg_asn1x_node (param, "salt", "specified", NULL), (guchar *)"salt", 4, NULL);
337 #else
338 	egg_asn1x_set_choice (egg_asn1x_node (param, "salt", NULL), egg_asn1x_node (param, "salt", "otherSource", NULL)); */
339 	egg_asn1x_set_oid_as_string (egg_asn1x_node (param, "salt", "otherSource", "algorithm", NULL), "1.2.1"); */
340 #endif
341 	egg_asn1x_set_any_from (egg_asn1x_node (asn, "keyDerivationFunc", "parameters", NULL), param);
342 	egg_asn1x_destroy (param);
343 
344 	egg_asn1x_set_oid_as_string (egg_asn1x_node (asn, "encryptionScheme", "algorithm", NULL), "1.3.14.3.2.7");
345 	param = egg_asn1x_create (pkix_asn1_tab, "pkcs-5-des-EDE3-CBC-params");
346 	egg_asn1x_set_string_as_raw (param, (guchar *)"saltsalt", 8, NULL);
347 	egg_asn1x_set_any_from (egg_asn1x_node (asn, "encryptionScheme", "parameters", NULL), param);
348 	egg_asn1x_destroy (param);
349 
350 	bytes = egg_asn1x_encode (asn, NULL);
351 	egg_asn1x_assert (bytes != NULL, asn);
352 	egg_asn1x_destroy (asn);
353 
354 	data = g_bytes_get_data (bytes, &size);
355 	g_printerr ("%s: \\x%s\n", __FUNCTION__, egg_hex_encode_full (data, size, FALSE, "\\x", 1));
356 	g_bytes_unref (bytes);
357 }
358 #endif
359 
360 static void
test_read_cipher(gconstpointer data)361 test_read_cipher (gconstpointer data)
362 {
363 	const ReadCipher *test = data;
364 	gcry_cipher_hd_t cih;
365 	gcry_error_t gcry;
366 	GNode *asn;
367 	gboolean ret;
368 	GBytes *bytes;
369 	gpointer block;
370 
371 	bytes = g_bytes_new_static (test->der, test->n_der);
372 	asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestAny", bytes);
373 	g_assert (asn != NULL);
374 	g_bytes_unref (bytes);
375 
376 	ret = egg_symkey_read_cipher (g_quark_from_static_string (test->scheme),
377 	                              test->password, strlen (test->password),
378 	                              asn, &cih);
379 
380 	egg_asn1x_destroy (asn);
381 	g_assert (ret == TRUE);
382 
383 	block = g_memdup (test->plain_text, test->n_text_length);
384 	gcry = gcry_cipher_encrypt (cih, block, test->n_text_length, NULL, 0);
385 	g_assert_cmpint (gcry, ==, 0);
386 
387 	egg_assert_cmpmem (test->cipher_text, test->n_text_length, ==,
388 	                   block, test->n_text_length);
389 
390 	gcry_cipher_close (cih);
391 	g_free (block);
392 }
393 
394 static const InvalidCipher cipher_invalid[] = {
395 	{
396 		"pbe-bad-der", "1.2.840.113549.1.12.1.3",
397 		"password",
398 		/* Valid DER, but not pkcs-12-PbeParams */
399 		11, "\x30\x09\x04\x07""invalid"
400 	},
401 	{
402 		"pkcs5-pbe-bad-der", "1.2.840.113549.1.5.10",
403 		"password",
404 		/* Valid DER, but not pkcs-5-PBE-params */
405 		11, "\x30\x09\x04\x07""invalid"
406 	},
407 	{
408 		"pkcs5-pbes2-bad-der", "1.2.840.113549.1.5.13",
409 		"password",
410 		/* Valid DER, but not pkcs-5-PBES2-params */
411 		11, "\x30\x09\x04\x07""invalid"
412 	},
413 	{
414 		"pkcs5-pbes2-missing-key-parameters", "1.2.840.113549.1.5.13",
415 		"password",
416 		0x25, "\x30\x23"
417 			"\x30\x0b"
418 				"\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x05\x0c"
419 				/* Missing OPTIONAL parameters here */
420 			"\x30\x14"
421 				"\x06\x08\x2a\x86\x48\x86\xf7\x0d\x03\x07"
422 				"\x04\x08\x73\x61\x6c\x74\x73\x61\x6c\x74",
423 	},
424 	{
425 		"pkcs5-pbes2-missing-scheme-parameters", "1.2.840.113549.1.5.13",
426 		"password",
427 		0x26, "\x30\x24"
428 			"\x30\x16"
429 				"\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x05\x0c"
430 				"\x30\x09"
431 					"\x04\x04\x73\x61\x6c\x74"
432 					"\x02\x01\x21"
433 			"\x30\x0a"
434 				"\x06\x08\x2a\x86\x48\x86\xf7\x0d\x03\x07"
435 				/* Missing OPTIONAL parameters here */
436 	},
437 	{
438 		"pkcs5-pbes2-bad-key-derivation-algo", "1.2.840.113549.1.5.13",
439 		"password",
440 		48, "\x30\x2e"
441 			"\x30\x16" /* An unsupported keyDerivation algorithm oid */
442 				"\x06\x09\x2a\x86\x48\x86\xf7\x0c\x01\x04\x0b"
443 				"\x30\x09"
444 					"\x04\x04\x73\x61\x6c\x74"
445 					"\x02\x01\x21"
446 			"\x30\x14"
447 				"\x06\x08\x2a\x86\x48\x86\xf7\x0d\x03\x07"
448 				"\x04\x08\x73\x61\x6c\x74\x73\x61\x6c\x74",
449 	},
450 	{
451 		"pkcs5-pbes2-salt-not-specified", "1.2.840.113549.1.5.13",
452 		"password",
453 		0x30, "\x30\x2e"
454 			"\x30\x16"
455 				"\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x05\x0c"
456 				"\x30\x09"
457 					"\x30\x04"
458 						"\x06\x02\x2a\x01"
459 					"\x02\x01\x21"
460 			"\x30\x14"
461 				"\x06\x08\x2a\x86\x48\x86\xf7\x0d\x03\x07"
462 				"\x04\x08\x73\x61\x6c\x74\x73\x61\x6c\x74"
463 	},
464 	{
465 		"pkcs5-pbes2-unsupported-des-rc5-cbc", "1.2.840.113549.1.5.13",
466 		"password",
467 		0x30, "\x30\x2e"
468 			"\x30\x16"
469 				"\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x05\x0c"
470 				"\x30\x09"
471 					"\x04\x04\x73\x61\x6c\x74"
472 					"\x02\x01\x21"
473 			"\x30\x14"
474 				"\x06\x08\x2a\x86\x48\x86\xf7\x0d\x03\x09"
475 				"\x04\x08\x73\x61\x6c\x74\x73\x61\x6c\x74"
476 	}
477 };
478 
479 static void
test_read_cipher_invalid(gconstpointer data)480 test_read_cipher_invalid (gconstpointer data)
481 {
482 	const InvalidCipher *test = data;
483 	gcry_cipher_hd_t cih;
484 	GNode *asn;
485 	gboolean ret;
486 	GBytes *bytes;
487 
488 	bytes = g_bytes_new_static (test->der, test->n_der);
489 	asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestAny", bytes);
490 	g_assert (asn != NULL);
491 	g_bytes_unref (bytes);
492 
493 	ret = egg_symkey_read_cipher (g_quark_from_static_string (test->scheme),
494 	                              test->password, strlen (test->password),
495 	                              asn, &cih);
496 
497 	egg_asn1x_destroy (asn);
498 	g_assert (ret == FALSE);
499 }
500 
501 static void
test_read_cipher_unsupported_pbe(void)502 test_read_cipher_unsupported_pbe (void)
503 {
504 	gcry_cipher_hd_t cih;
505 	GNode *asn;
506 	gboolean ret;
507 	GBytes *bytes;
508 
509 	/*
510 	 * On many test systems RC2 is no longer supported by libgcrypt, but
511 	 * in case these tests are run elsewhere, double check.
512 	 */
513 	if (gcry_cipher_algo_info (GCRY_CIPHER_RFC2268_128, GCRYCTL_TEST_ALGO, NULL, 0) == 0)
514 		return;
515 
516 	bytes = g_bytes_new_static ("\x30\x09\x04\x07""invalid", 11);
517 	asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestAny", bytes);
518 	g_assert (asn != NULL);
519 	g_bytes_unref (bytes);
520 
521 	ret = egg_symkey_read_cipher (g_quark_from_static_string ("1.2.840.113549.1.12.1.5"),
522 	                              "blah", 4, asn, &cih);
523 
524 	g_assert (ret == FALSE);
525 
526 	egg_asn1x_destroy (asn);
527 }
528 
529 typedef struct {
530 	const gchar *name;
531 	const gchar *scheme;
532 	gsize digest_len;
533 
534 	/* Info to use with cipher */
535 	const gchar *password;
536 	const gchar *salt;
537 	gsize iterations;
538 
539 	/* DER representation of cipher */
540 	gsize n_der;
541 	const gchar *der;
542 
543 	/* Data to encrypt and test with */
544 	gsize n_plain_length;
545 	const gchar *plain_text;
546 	const gchar *digest;
547 } ReadMac;
548 
549 static const ReadMac mac_tests[] = {
550 	{
551 		"sha1", "1.3.14.3.2.26", 20,
552 		"password", "saltsalt", 33,
553 		31, "\x30\x1d"
554 			"\x30\x12"
555 				"\x30\x07"
556 					"\x06\x05\x2b\x0e\x03\x02\x1a"
557 				"\x04\x07""invalid"
558 			"\x04\x04""salt"
559 			"\x02\x01\x21",
560 		8, "plaintex", "\x8b\x96\x7f\xa2\xf4\x4f\x2d\x70\xcb\x59\x7e\x8f\xad\xf3\x92\x18\x70\x08\x5c\x57"
561 	}
562 };
563 
564 static void
test_read_mac(gconstpointer data)565 test_read_mac (gconstpointer data)
566 {
567 	const ReadMac *test = data;
568 	gcry_md_hd_t mdh;
569 	gpointer digest;
570 	gsize digest_len;
571 	GNode *asn;
572 	gboolean ret;
573 	GBytes *bytes;
574 
575 	bytes = g_bytes_new_static (test->der, test->n_der);
576 	asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestAny", bytes);
577 	g_assert (asn != NULL);
578 	g_bytes_unref (bytes);
579 
580 	ret = egg_symkey_read_mac (g_quark_from_static_string (test->scheme),
581 	                           test->password, strlen (test->password),
582 	                           asn, &mdh, &digest_len);
583 
584 	g_assert_cmpint (digest_len, ==, test->digest_len);
585 
586 	egg_asn1x_destroy (asn);
587 	g_assert (ret == TRUE);
588 
589 	gcry_md_write (mdh, test->plain_text, test->n_plain_length);
590 	digest = gcry_md_read (mdh, 0);
591 
592 	egg_assert_cmpmem (test->digest, digest_len, ==,
593 	                   digest, digest_len);
594 
595 	gcry_md_close (mdh);
596 }
597 
598 static void
test_read_mac_invalid(void)599 test_read_mac_invalid (void)
600 {
601 	gcry_md_hd_t mdh;
602 	gsize digest_len;
603 	GNode *asn;
604 	gboolean ret;
605 	GBytes *bytes;
606 
607 	bytes = g_bytes_new_static ("\x30\x09\x04\x07""invalid", 11);
608 	asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestAny", bytes);
609 	g_assert (asn != NULL);
610 	g_bytes_unref (bytes);
611 
612 	ret = egg_symkey_read_mac (g_quark_from_static_string ("1.3.14.3.2.26"),
613 	                           "blah", 4, asn, &mdh, &digest_len);
614 
615 	g_assert (ret == FALSE);
616 
617 	egg_asn1x_destroy (asn);
618 }
619 
620 static void
null_log_handler(const gchar * log_domain,GLogLevelFlags log_level,const gchar * message,gpointer user_data)621 null_log_handler (const gchar *log_domain, GLogLevelFlags log_level,
622                   const gchar *message, gpointer user_data)
623 {
624 
625 }
626 
627 int
main(int argc,char ** argv)628 main (int argc, char **argv)
629 {
630 	gchar *name;
631 	gint i;
632 
633 	g_test_init (&argc, &argv, NULL);
634 	egg_libgcrypt_initialize ();
635 
636 	/* Suppress these messages in tests */
637 	g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO,
638 	                   null_log_handler, NULL);
639 
640 	g_test_add_func ("/symkey/generate_key_simple", test_generate_key_simple);
641 	g_test_add_func ("/symkey/generate_key_pkcs12", test_generate_key_pkcs12);
642 	g_test_add_func ("/symkey/generate_key_pbkdf2", test_generate_key_pbkdf2);
643 	g_test_add_func ("/symkey/generate_key_pbe", test_generate_key_pbe);
644 
645 	for (i = 0; i < G_N_ELEMENTS (cipher_tests); i++) {
646 		name = g_strdup_printf ("/symkey/read-cipher/%s", cipher_tests[i].name);
647 		g_test_add_data_func (name, cipher_tests + i, test_read_cipher);
648 		g_free (name);
649 	}
650 
651 	for (i = 0; i < G_N_ELEMENTS (cipher_invalid); i++) {
652 		name = g_strdup_printf ("/symkey/read-cipher-invalid/%s", cipher_invalid[i].name);
653 		g_test_add_data_func (name, cipher_invalid + i, test_read_cipher_invalid);
654 		g_free (name);
655 	}
656 
657 	g_test_add_func ("/symkey/read-cipher-unsupported/pbe", test_read_cipher_unsupported_pbe);
658 
659 	for (i = 0; i < G_N_ELEMENTS (mac_tests); i++) {
660 		name = g_strdup_printf ("/symkey/read-mac/%s", mac_tests[i].name);
661 		g_test_add_data_func (name, mac_tests + i, test_read_mac);
662 		g_free (name);
663 	}
664 
665 	g_test_add_func ("/symkey/read-mac-invalid", test_read_mac_invalid);
666 
667 	return g_test_run ();
668 }
669