diff options
Diffstat (limited to 'src/util/gnunet-crypto-tvg.c')
-rw-r--r-- | src/util/gnunet-crypto-tvg.c | 874 |
1 files changed, 798 insertions, 76 deletions
diff --git a/src/util/gnunet-crypto-tvg.c b/src/util/gnunet-crypto-tvg.c index c3fead62e..8949f427c 100644 --- a/src/util/gnunet-crypto-tvg.c +++ b/src/util/gnunet-crypto-tvg.c | |||
@@ -22,11 +22,36 @@ | |||
22 | * @file util/gnunet-crypto-tgv.c | 22 | * @file util/gnunet-crypto-tgv.c |
23 | * @brief Generate test vectors for cryptographic operations. | 23 | * @brief Generate test vectors for cryptographic operations. |
24 | * @author Florian Dold | 24 | * @author Florian Dold |
25 | * | ||
26 | * Note that this program shouldn't depend on code in src/json/, | ||
27 | * so we're using raw jansson and no GNUnet JSON helpers. | ||
28 | * | ||
29 | * Test vectors have the following format (TypeScript pseudo code): | ||
30 | * | ||
31 | * interface TestVectorFile { | ||
32 | * encoding: "base32crockford"; | ||
33 | * producer?: string; | ||
34 | * vectors: TestVector[]; | ||
35 | * } | ||
36 | * | ||
37 | * enum Operation { | ||
38 | * Hash("hash"), | ||
39 | * ... | ||
40 | * } | ||
41 | * | ||
42 | * interface TestVector { | ||
43 | * operation: Operation; | ||
44 | * // Inputs for the operation | ||
45 | * [ k: string]: string | number; | ||
46 | * }; | ||
47 | * | ||
48 | * | ||
25 | */ | 49 | */ |
26 | #include "platform.h" | 50 | #include "platform.h" |
27 | #include "gnunet_util_lib.h" | 51 | #include "gnunet_util_lib.h" |
28 | #include "gnunet_signatures.h" | 52 | #include "gnunet_signatures.h" |
29 | #include "gnunet_testing_lib.h" | 53 | #include "gnunet_testing_lib.h" |
54 | #include <jansson.h> | ||
30 | #include <gcrypt.h> | 55 | #include <gcrypt.h> |
31 | 56 | ||
32 | GNUNET_NETWORK_STRUCT_BEGIN | 57 | GNUNET_NETWORK_STRUCT_BEGIN |
@@ -46,46 +71,660 @@ GNUNET_NETWORK_STRUCT_END | |||
46 | 71 | ||
47 | 72 | ||
48 | /** | 73 | /** |
49 | * Print data base32-crockford with a preceding label. | 74 | * Should we verify or output test vectors? |
75 | */ | ||
76 | static int verify_flag = GNUNET_NO; | ||
77 | |||
78 | |||
79 | /** | ||
80 | * Global exit code. | ||
81 | */ | ||
82 | static int global_ret = 0; | ||
83 | |||
84 | |||
85 | /** | ||
86 | * Create a fresh test vector for a given operation label. | ||
87 | * | ||
88 | * @param vecs array of vectors to append the new vector to | ||
89 | * @param vecname label for the operation of the vector | ||
90 | * @returns the fresh test vector | ||
91 | */ | ||
92 | static json_t * | ||
93 | vec_for (json_t *vecs, const char *vecname) | ||
94 | { | ||
95 | json_t *t = json_object (); | ||
96 | |||
97 | json_object_set_new (t, | ||
98 | "operation", | ||
99 | json_string (vecname)); | ||
100 | json_array_append_new (vecs, t); | ||
101 | return t; | ||
102 | } | ||
103 | |||
104 | |||
105 | /** | ||
106 | * Add a base32crockford encoded value | ||
107 | * to a test vector. | ||
50 | * | 108 | * |
51 | * @param label label to print | 109 | * @param vec test vector to add to |
52 | * @param data data to print | 110 | * @param label label for the value |
111 | * @param data data to add | ||
53 | * @param size size of data | 112 | * @param size size of data |
54 | */ | 113 | */ |
55 | static void | 114 | static void |
56 | display_data (char *label, void *data, size_t size) | 115 | d2j (json_t *vec, |
116 | const char *label, | ||
117 | const void *data, | ||
118 | size_t size) | ||
57 | { | 119 | { |
58 | char *enc = GNUNET_STRINGS_data_to_string_alloc (data, size); | 120 | char *buf; |
59 | printf ("%s %s\n", label, enc); | 121 | json_t *json; |
60 | GNUNET_free (enc); | ||
61 | } | ||
62 | 122 | ||
123 | buf = GNUNET_STRINGS_data_to_string_alloc (data, size); | ||
124 | json = json_string (buf); | ||
125 | GNUNET_free (buf); | ||
126 | GNUNET_break (NULL != json); | ||
127 | |||
128 | json_object_set_new (vec, label, json); | ||
129 | } | ||
63 | 130 | ||
64 | /** | 131 | /** |
65 | * Main function that will be run. | 132 | * Add a number to a test vector. |
66 | * | 133 | * |
67 | * @param cls closure | 134 | * @param vec test vector to add to |
68 | * @param args remaining command-line arguments | 135 | * @param label label for the value |
69 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) | 136 | * @param data data to add |
70 | * @param cfg configuration | 137 | * @param size size of data |
71 | */ | 138 | */ |
72 | static void | 139 | static void |
73 | run (void *cls, | 140 | uint2j (json_t *vec, |
74 | char *const *args, | 141 | const char *label, |
75 | const char *cfgfile, | 142 | unsigned int num) |
76 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 143 | { |
144 | json_t *json = json_integer (num); | ||
145 | |||
146 | json_object_set_new (vec, label, json); | ||
147 | } | ||
148 | |||
149 | |||
150 | static int | ||
151 | expect_data_fixed (json_t *vec, | ||
152 | const char *name, | ||
153 | void *data, | ||
154 | size_t expect_len) | ||
155 | { | ||
156 | const char *s = json_string_value (json_object_get (vec, name)); | ||
157 | |||
158 | if (NULL == s) | ||
159 | return GNUNET_NO; | ||
160 | |||
161 | if (GNUNET_OK != GNUNET_STRINGS_string_to_data (s, | ||
162 | strlen (s), | ||
163 | data, | ||
164 | expect_len)) | ||
165 | return GNUNET_NO; | ||
166 | return GNUNET_OK; | ||
167 | } | ||
168 | |||
169 | static int | ||
170 | expect_data_dynamic (json_t *vec, | ||
171 | const char *name, | ||
172 | void **data, | ||
173 | size_t *ret_len) | ||
174 | { | ||
175 | const char *s = json_string_value (json_object_get (vec, name)); | ||
176 | size_t len; | ||
177 | |||
178 | if (NULL == s) | ||
179 | return GNUNET_NO; | ||
180 | |||
181 | len = (strlen (s) * 5) / 8; | ||
182 | if (NULL != ret_len) | ||
183 | *ret_len = len; | ||
184 | *data = GNUNET_malloc (len); | ||
185 | |||
186 | if (GNUNET_OK != GNUNET_STRINGS_string_to_data (s, strlen (s), *data, len)) | ||
187 | return GNUNET_NO; | ||
188 | return GNUNET_OK; | ||
189 | } | ||
190 | |||
191 | |||
192 | /** | ||
193 | * Check a single vector. | ||
194 | * | ||
195 | * @param operation operator of the vector | ||
196 | * @param vec the vector, a JSON object. | ||
197 | * | ||
198 | * @returns GNUNET_OK if the vector is okay | ||
199 | */ | ||
200 | static int | ||
201 | checkvec (const char *operation, | ||
202 | json_t *vec) | ||
203 | { | ||
204 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
205 | "checking %s\n", operation); | ||
206 | |||
207 | if (0 == strcmp (operation, "hash")) | ||
208 | { | ||
209 | void *data; | ||
210 | size_t data_len; | ||
211 | struct GNUNET_HashCode hash_out; | ||
212 | struct GNUNET_HashCode hc; | ||
213 | |||
214 | if (GNUNET_OK != expect_data_dynamic (vec, | ||
215 | "input", | ||
216 | &data, | ||
217 | &data_len)) | ||
218 | { | ||
219 | GNUNET_break (0); | ||
220 | return GNUNET_SYSERR; | ||
221 | } | ||
222 | if (GNUNET_OK != expect_data_fixed (vec, | ||
223 | "output", | ||
224 | &hash_out, | ||
225 | sizeof (hash_out))) | ||
226 | { | ||
227 | GNUNET_break (0); | ||
228 | return GNUNET_NO; | ||
229 | } | ||
230 | |||
231 | GNUNET_CRYPTO_hash (data, data_len, &hc); | ||
232 | |||
233 | if (0 != GNUNET_memcmp (&hc, &hash_out)) | ||
234 | { | ||
235 | GNUNET_break (0); | ||
236 | return GNUNET_NO; | ||
237 | } | ||
238 | } | ||
239 | else if (0 == strcmp (operation, "ecc_ecdh")) | ||
240 | { | ||
241 | struct GNUNET_CRYPTO_EcdhePrivateKey priv1; | ||
242 | struct GNUNET_CRYPTO_EcdhePublicKey pub1; | ||
243 | struct GNUNET_CRYPTO_EcdhePrivateKey priv2; | ||
244 | struct GNUNET_HashCode skm; | ||
245 | struct GNUNET_HashCode skm_comp; | ||
246 | |||
247 | if (GNUNET_OK != expect_data_fixed (vec, | ||
248 | "priv1", | ||
249 | &priv1, | ||
250 | sizeof (priv1))) | ||
251 | { | ||
252 | GNUNET_break (0); | ||
253 | return GNUNET_NO; | ||
254 | } | ||
255 | if (GNUNET_OK != expect_data_fixed (vec, | ||
256 | "priv2", | ||
257 | &priv2, | ||
258 | sizeof (priv2))) | ||
259 | { | ||
260 | GNUNET_break (0); | ||
261 | return GNUNET_NO; | ||
262 | } | ||
263 | if (GNUNET_OK != expect_data_fixed (vec, | ||
264 | "pub1", | ||
265 | &pub1, | ||
266 | sizeof (pub1))) | ||
267 | { | ||
268 | GNUNET_break (0); | ||
269 | return GNUNET_NO; | ||
270 | } | ||
271 | if (GNUNET_OK != expect_data_fixed (vec, | ||
272 | "skm", | ||
273 | &skm, | ||
274 | sizeof (skm))) | ||
275 | { | ||
276 | GNUNET_break (0); | ||
277 | return GNUNET_NO; | ||
278 | } | ||
279 | GNUNET_assert (GNUNET_OK == | ||
280 | GNUNET_CRYPTO_ecc_ecdh (&priv2, | ||
281 | &pub1, | ||
282 | &skm_comp)); | ||
283 | if (0 != GNUNET_memcmp (&skm, &skm_comp)) | ||
284 | { | ||
285 | GNUNET_break (0); | ||
286 | return GNUNET_NO; | ||
287 | } | ||
288 | } | ||
289 | else if (0 == strcmp (operation, "eddsa_key_derivation")) | ||
290 | { | ||
291 | struct GNUNET_CRYPTO_EddsaPrivateKey priv; | ||
292 | struct GNUNET_CRYPTO_EddsaPublicKey pub; | ||
293 | struct GNUNET_CRYPTO_EddsaPublicKey pub_comp; | ||
294 | |||
295 | if (GNUNET_OK != expect_data_fixed (vec, | ||
296 | "priv", | ||
297 | &priv, | ||
298 | sizeof (priv))) | ||
299 | { | ||
300 | GNUNET_break (0); | ||
301 | return GNUNET_NO; | ||
302 | } | ||
303 | |||
304 | if (GNUNET_OK != expect_data_fixed (vec, | ||
305 | "pub", | ||
306 | &pub, | ||
307 | sizeof (pub))) | ||
308 | { | ||
309 | GNUNET_break (0); | ||
310 | return GNUNET_NO; | ||
311 | } | ||
312 | |||
313 | GNUNET_CRYPTO_eddsa_key_get_public (&priv, | ||
314 | &pub_comp); | ||
315 | if (0 != GNUNET_memcmp (&pub, &pub_comp)) | ||
316 | { | ||
317 | GNUNET_break (0); | ||
318 | return GNUNET_NO; | ||
319 | } | ||
320 | |||
321 | } | ||
322 | else if (0 == strcmp (operation, "eddsa_signing")) | ||
323 | { | ||
324 | struct GNUNET_CRYPTO_EddsaPrivateKey priv; | ||
325 | struct GNUNET_CRYPTO_EddsaPublicKey pub; | ||
326 | struct TestSignatureDataPS data = { 0 }; | ||
327 | struct GNUNET_CRYPTO_EddsaSignature sig; | ||
328 | struct GNUNET_CRYPTO_EddsaSignature sig_comp; | ||
329 | |||
330 | if (GNUNET_OK != expect_data_fixed (vec, | ||
331 | "priv", | ||
332 | &priv, | ||
333 | sizeof (priv))) | ||
334 | { | ||
335 | GNUNET_break (0); | ||
336 | return GNUNET_NO; | ||
337 | } | ||
338 | |||
339 | if (GNUNET_OK != expect_data_fixed (vec, | ||
340 | "pub", | ||
341 | &pub, | ||
342 | sizeof (pub))) | ||
343 | { | ||
344 | GNUNET_break (0); | ||
345 | return GNUNET_NO; | ||
346 | } | ||
347 | |||
348 | if (GNUNET_OK != expect_data_fixed (vec, | ||
349 | "data", | ||
350 | &data, | ||
351 | sizeof (data))) | ||
352 | { | ||
353 | GNUNET_break (0); | ||
354 | return GNUNET_NO; | ||
355 | } | ||
356 | |||
357 | if (GNUNET_OK != expect_data_fixed (vec, | ||
358 | "sig", | ||
359 | &sig, | ||
360 | sizeof (sig))) | ||
361 | { | ||
362 | GNUNET_break (0); | ||
363 | return GNUNET_NO; | ||
364 | } | ||
365 | |||
366 | GNUNET_CRYPTO_eddsa_sign (&priv, | ||
367 | &data, | ||
368 | &sig_comp); | ||
369 | GNUNET_assert (GNUNET_OK == | ||
370 | GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_TEST, | ||
371 | &data, | ||
372 | &sig, | ||
373 | &pub)); | ||
374 | if (0 != GNUNET_memcmp (&sig, &sig_comp)) | ||
375 | { | ||
376 | GNUNET_break (0); | ||
377 | return GNUNET_NO; | ||
378 | } | ||
379 | } | ||
380 | else if (0 == strcmp (operation, "kdf")) | ||
381 | { | ||
382 | size_t out_len; | ||
383 | void *out; | ||
384 | size_t out_len_comp; | ||
385 | void *out_comp; | ||
386 | void *ikm; | ||
387 | size_t ikm_len; | ||
388 | void *salt; | ||
389 | size_t salt_len; | ||
390 | void *ctx; | ||
391 | size_t ctx_len; | ||
392 | |||
393 | if (GNUNET_OK != expect_data_dynamic (vec, | ||
394 | "out", | ||
395 | &out, | ||
396 | &out_len)) | ||
397 | { | ||
398 | GNUNET_break (0); | ||
399 | return GNUNET_SYSERR; | ||
400 | } | ||
401 | |||
402 | out_len_comp = out_len; | ||
403 | out_comp = GNUNET_malloc (out_len_comp); | ||
404 | |||
405 | if (GNUNET_OK != expect_data_dynamic (vec, | ||
406 | "ikm", | ||
407 | &ikm, | ||
408 | &ikm_len)) | ||
409 | { | ||
410 | GNUNET_break (0); | ||
411 | return GNUNET_SYSERR; | ||
412 | } | ||
413 | |||
414 | if (GNUNET_OK != expect_data_dynamic (vec, | ||
415 | "salt", | ||
416 | &salt, | ||
417 | &salt_len)) | ||
418 | { | ||
419 | GNUNET_break (0); | ||
420 | return GNUNET_SYSERR; | ||
421 | } | ||
422 | |||
423 | if (GNUNET_OK != expect_data_dynamic (vec, | ||
424 | "ctx", | ||
425 | &ctx, | ||
426 | &ctx_len)) | ||
427 | { | ||
428 | GNUNET_break (0); | ||
429 | return GNUNET_SYSERR; | ||
430 | } | ||
431 | |||
432 | GNUNET_assert (GNUNET_OK == | ||
433 | GNUNET_CRYPTO_kdf (out_comp, | ||
434 | out_len_comp, | ||
435 | salt, | ||
436 | salt_len, | ||
437 | ikm, | ||
438 | ikm_len, | ||
439 | ctx, | ||
440 | ctx_len, | ||
441 | NULL)); | ||
442 | |||
443 | if (0 != memcmp (out, out_comp, out_len)) | ||
444 | { | ||
445 | GNUNET_break (0); | ||
446 | return GNUNET_NO; | ||
447 | } | ||
448 | |||
449 | } | ||
450 | else if (0 == strcmp (operation, "eddsa_ecdh")) | ||
451 | { | ||
452 | struct GNUNET_CRYPTO_EcdhePrivateKey priv_ecdhe; | ||
453 | struct GNUNET_CRYPTO_EcdhePublicKey pub_ecdhe; | ||
454 | struct GNUNET_CRYPTO_EddsaPrivateKey priv_eddsa; | ||
455 | struct GNUNET_CRYPTO_EddsaPublicKey pub_eddsa; | ||
456 | struct GNUNET_HashCode key_material; | ||
457 | struct GNUNET_HashCode key_material_comp; | ||
458 | |||
459 | if (GNUNET_OK != expect_data_fixed (vec, | ||
460 | "priv_ecdhe", | ||
461 | &priv_ecdhe, | ||
462 | sizeof (priv_ecdhe))) | ||
463 | { | ||
464 | GNUNET_break (0); | ||
465 | return GNUNET_NO; | ||
466 | } | ||
467 | |||
468 | if (GNUNET_OK != expect_data_fixed (vec, | ||
469 | "pub_ecdhe", | ||
470 | &pub_ecdhe, | ||
471 | sizeof (pub_ecdhe))) | ||
472 | { | ||
473 | GNUNET_break (0); | ||
474 | return GNUNET_NO; | ||
475 | } | ||
476 | |||
477 | if (GNUNET_OK != expect_data_fixed (vec, | ||
478 | "priv_eddsa", | ||
479 | &priv_eddsa, | ||
480 | sizeof (priv_eddsa))) | ||
481 | { | ||
482 | GNUNET_break (0); | ||
483 | return GNUNET_NO; | ||
484 | } | ||
485 | |||
486 | if (GNUNET_OK != expect_data_fixed (vec, | ||
487 | "pub_eddsa", | ||
488 | &pub_eddsa, | ||
489 | sizeof (pub_eddsa))) | ||
490 | { | ||
491 | GNUNET_break (0); | ||
492 | return GNUNET_NO; | ||
493 | } | ||
494 | |||
495 | if (GNUNET_OK != expect_data_fixed (vec, | ||
496 | "key_material", | ||
497 | &key_material, | ||
498 | sizeof (key_material))) | ||
499 | { | ||
500 | GNUNET_break (0); | ||
501 | return GNUNET_NO; | ||
502 | } | ||
503 | |||
504 | GNUNET_CRYPTO_ecdh_eddsa (&priv_ecdhe, &pub_eddsa, &key_material_comp); | ||
505 | |||
506 | if (0 != GNUNET_memcmp (&key_material, &key_material_comp)) | ||
507 | { | ||
508 | GNUNET_break (0); | ||
509 | return GNUNET_NO; | ||
510 | } | ||
511 | } | ||
512 | else if (0 == strcmp (operation, "rsa_blind_signing")) | ||
513 | { | ||
514 | struct GNUNET_CRYPTO_RsaPrivateKey *skey; | ||
515 | struct GNUNET_CRYPTO_RsaPublicKey *pkey; | ||
516 | struct GNUNET_HashCode message_hash; | ||
517 | struct GNUNET_CRYPTO_RsaBlindingKeySecret bks; | ||
518 | struct GNUNET_CRYPTO_RsaSignature *blinded_sig; | ||
519 | struct GNUNET_CRYPTO_RsaSignature *sig; | ||
520 | void *blinded_data; | ||
521 | size_t blinded_len; | ||
522 | void *blinded_data_comp; | ||
523 | size_t blinded_len_comp; | ||
524 | void *public_enc_data; | ||
525 | size_t public_enc_len; | ||
526 | void *secret_enc_data; | ||
527 | size_t secret_enc_len; | ||
528 | void *sig_enc_data; | ||
529 | size_t sig_enc_length; | ||
530 | void *sig_enc_data_comp; | ||
531 | size_t sig_enc_length_comp; | ||
532 | |||
533 | if (GNUNET_OK != expect_data_fixed (vec, | ||
534 | "message_hash", | ||
535 | &message_hash, | ||
536 | sizeof (message_hash))) | ||
537 | { | ||
538 | GNUNET_break (0); | ||
539 | return GNUNET_SYSERR; | ||
540 | } | ||
541 | |||
542 | if (GNUNET_OK != expect_data_fixed (vec, | ||
543 | "blinding_key_secret", | ||
544 | &bks, | ||
545 | sizeof (bks))) | ||
546 | { | ||
547 | GNUNET_break (0); | ||
548 | return GNUNET_SYSERR; | ||
549 | } | ||
550 | |||
551 | if (GNUNET_OK != expect_data_dynamic (vec, | ||
552 | "blinded_message", | ||
553 | &blinded_data, | ||
554 | &blinded_len)) | ||
555 | { | ||
556 | GNUNET_break (0); | ||
557 | return GNUNET_SYSERR; | ||
558 | } | ||
559 | |||
560 | if (GNUNET_OK != expect_data_dynamic (vec, | ||
561 | "rsa_public_key", | ||
562 | &public_enc_data, | ||
563 | &public_enc_len)) | ||
564 | { | ||
565 | GNUNET_break (0); | ||
566 | return GNUNET_SYSERR; | ||
567 | } | ||
568 | |||
569 | if (GNUNET_OK != expect_data_dynamic (vec, | ||
570 | "rsa_private_key", | ||
571 | &secret_enc_data, | ||
572 | &secret_enc_len)) | ||
573 | { | ||
574 | GNUNET_break (0); | ||
575 | return GNUNET_SYSERR; | ||
576 | } | ||
577 | |||
578 | if (GNUNET_OK != expect_data_dynamic (vec, | ||
579 | "sig", | ||
580 | &sig_enc_data, | ||
581 | &sig_enc_length)) | ||
582 | { | ||
583 | GNUNET_break (0); | ||
584 | return GNUNET_SYSERR; | ||
585 | } | ||
586 | |||
587 | pkey = GNUNET_CRYPTO_rsa_public_key_decode (public_enc_data, | ||
588 | public_enc_len); | ||
589 | GNUNET_assert (NULL != pkey); | ||
590 | skey = GNUNET_CRYPTO_rsa_private_key_decode (secret_enc_data, | ||
591 | secret_enc_len); | ||
592 | GNUNET_assert (NULL != skey); | ||
593 | |||
594 | GNUNET_assert (GNUNET_YES == | ||
595 | GNUNET_CRYPTO_rsa_blind (&message_hash, | ||
596 | &bks, | ||
597 | pkey, | ||
598 | &blinded_data_comp, | ||
599 | &blinded_len_comp)); | ||
600 | if ( (blinded_len != blinded_len_comp) || (0 != memcmp (blinded_data, | ||
601 | blinded_data_comp, | ||
602 | blinded_len)) ) | ||
603 | { | ||
604 | GNUNET_break (0); | ||
605 | return GNUNET_NO; | ||
606 | } | ||
607 | blinded_sig = GNUNET_CRYPTO_rsa_sign_blinded (skey, blinded_data, | ||
608 | blinded_len); | ||
609 | sig = GNUNET_CRYPTO_rsa_unblind (blinded_sig, &bks, pkey); | ||
610 | GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_rsa_verify (&message_hash, sig, | ||
611 | pkey)); | ||
612 | public_enc_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey, | ||
613 | &public_enc_data); | ||
614 | sig_enc_length_comp = GNUNET_CRYPTO_rsa_signature_encode (sig, &sig_enc_data_comp); | ||
615 | |||
616 | if ( (sig_enc_length != sig_enc_length_comp) || | ||
617 | (0 != memcmp (sig_enc_data, sig_enc_data_comp, sig_enc_length) )) | ||
618 | { | ||
619 | GNUNET_break (0); | ||
620 | return GNUNET_NO; | ||
621 | } | ||
622 | } | ||
623 | else | ||
624 | { | ||
625 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
626 | "unsupported operation '%s'\n", operation); | ||
627 | } | ||
628 | |||
629 | return GNUNET_OK; | ||
630 | } | ||
631 | |||
632 | /** | ||
633 | * Check test vectors from stdin. | ||
634 | * | ||
635 | * @returns global exit code | ||
636 | */ | ||
637 | static int | ||
638 | check_vectors () | ||
639 | { | ||
640 | json_error_t err; | ||
641 | json_t *vecfile = json_loadf (stdin, 0, &err); | ||
642 | const char *encoding; | ||
643 | json_t *vectors; | ||
644 | |||
645 | if (NULL == vecfile) | ||
646 | { | ||
647 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "unable to parse JSON\n"); | ||
648 | return 1; | ||
649 | } | ||
650 | encoding = json_string_value (json_object_get (vecfile, | ||
651 | "encoding")); | ||
652 | if ( (NULL == encoding) || (0 != strcmp (encoding, "base32crockford")) ) | ||
653 | { | ||
654 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "unsupported or missing encoding\n"); | ||
655 | json_decref (vecfile); | ||
656 | return 1; | ||
657 | } | ||
658 | vectors = json_object_get (vecfile, "vectors"); | ||
659 | if (!json_is_array (vectors)) | ||
660 | { | ||
661 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bad vectors\n"); | ||
662 | json_decref (vecfile); | ||
663 | return 1; | ||
664 | } | ||
665 | { | ||
666 | /* array is a JSON array */ | ||
667 | size_t index; | ||
668 | json_t *value; | ||
669 | int ret; | ||
670 | |||
671 | json_array_foreach (vectors, index, value) { | ||
672 | const char *op = json_string_value (json_object_get (value, | ||
673 | "operation")); | ||
674 | |||
675 | if (NULL == op) | ||
676 | { | ||
677 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
678 | "missing operation\n"); | ||
679 | ret = GNUNET_SYSERR; | ||
680 | break; | ||
681 | } | ||
682 | ret = checkvec (op, value); | ||
683 | if (GNUNET_OK != ret) | ||
684 | { | ||
685 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
686 | "bad vector %u\n", | ||
687 | (unsigned int) index); | ||
688 | break; | ||
689 | } | ||
690 | } | ||
691 | return (ret == GNUNET_OK) ? 0 : 1; | ||
692 | } | ||
693 | } | ||
694 | |||
695 | /** | ||
696 | * Output test vectors. | ||
697 | * | ||
698 | * @returns global exit code | ||
699 | */ | ||
700 | static int | ||
701 | output_vectors () | ||
77 | { | 702 | { |
703 | json_t *vecfile = json_object (); | ||
704 | json_t *vecs = json_array (); | ||
705 | |||
706 | json_object_set_new (vecfile, | ||
707 | "encoding", | ||
708 | json_string ("base32crockford")); | ||
709 | json_object_set_new (vecfile, | ||
710 | "producer", | ||
711 | json_string ("GNUnet " PACKAGE_VERSION " " VCS_VERSION)); | ||
712 | json_object_set_new (vecfile, | ||
713 | "vectors", | ||
714 | vecs); | ||
715 | |||
78 | { | 716 | { |
717 | json_t *vec = vec_for (vecs, "hash"); | ||
79 | struct GNUNET_HashCode hc; | 718 | struct GNUNET_HashCode hc; |
80 | char *str = "Hello, GNUnet"; | 719 | char *str = "Hello, GNUnet"; |
81 | 720 | ||
82 | GNUNET_CRYPTO_hash (str, strlen (str), &hc); | 721 | GNUNET_CRYPTO_hash (str, strlen (str), &hc); |
83 | 722 | ||
84 | printf ("hash code:\n"); | 723 | d2j (vec, "input", str, strlen (str)); |
85 | display_data (" input", str, strlen (str)); | 724 | d2j (vec, "output", &hc, sizeof (struct GNUNET_HashCode)); |
86 | display_data (" output", &hc, sizeof (struct GNUNET_HashCode)); | ||
87 | } | 725 | } |
88 | { | 726 | { |
727 | json_t *vec = vec_for (vecs, "ecc_ecdh"); | ||
89 | struct GNUNET_CRYPTO_EcdhePrivateKey priv1; | 728 | struct GNUNET_CRYPTO_EcdhePrivateKey priv1; |
90 | struct GNUNET_CRYPTO_EcdhePublicKey pub1; | 729 | struct GNUNET_CRYPTO_EcdhePublicKey pub1; |
91 | struct GNUNET_CRYPTO_EcdhePrivateKey priv2; | 730 | struct GNUNET_CRYPTO_EcdhePrivateKey priv2; |
@@ -100,22 +739,26 @@ run (void *cls, | |||
100 | &pub1, | 739 | &pub1, |
101 | &skm)); | 740 | &skm)); |
102 | 741 | ||
103 | printf ("ecdhe key:\n"); | 742 | d2j (vec, |
104 | display_data (" priv1", | 743 | "priv1", |
105 | &priv1, | 744 | &priv1, |
106 | sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey)); | 745 | sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey)); |
107 | display_data (" pub1", | 746 | d2j (vec, |
108 | &pub1, | 747 | "pub1", |
109 | sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); | 748 | &pub1, |
110 | display_data (" priv2", | 749 | sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); |
111 | &priv2, | 750 | d2j (vec, |
112 | sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey)); | 751 | "priv2", |
113 | display_data (" skm", | 752 | &priv2, |
114 | &skm, | 753 | sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey)); |
115 | sizeof (struct GNUNET_HashCode)); | 754 | d2j (vec, |
755 | "skm", | ||
756 | &skm, | ||
757 | sizeof (struct GNUNET_HashCode)); | ||
116 | } | 758 | } |
117 | 759 | ||
118 | { | 760 | { |
761 | json_t *vec = vec_for (vecs, "eddsa_key_derivation"); | ||
119 | struct GNUNET_CRYPTO_EddsaPrivateKey priv; | 762 | struct GNUNET_CRYPTO_EddsaPrivateKey priv; |
120 | struct GNUNET_CRYPTO_EddsaPublicKey pub; | 763 | struct GNUNET_CRYPTO_EddsaPublicKey pub; |
121 | 764 | ||
@@ -123,15 +766,17 @@ run (void *cls, | |||
123 | GNUNET_CRYPTO_eddsa_key_get_public (&priv, | 766 | GNUNET_CRYPTO_eddsa_key_get_public (&priv, |
124 | &pub); | 767 | &pub); |
125 | 768 | ||
126 | printf ("eddsa key:\n"); | 769 | d2j (vec, |
127 | display_data (" priv", | 770 | "priv", |
128 | &priv, | 771 | &priv, |
129 | sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)); | 772 | sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)); |
130 | display_data (" pub", | 773 | d2j (vec, |
131 | &pub, | 774 | "pub", |
132 | sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)); | 775 | &pub, |
776 | sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)); | ||
133 | } | 777 | } |
134 | { | 778 | { |
779 | json_t *vec = vec_for (vecs, "eddsa_signing"); | ||
135 | struct GNUNET_CRYPTO_EddsaPrivateKey priv; | 780 | struct GNUNET_CRYPTO_EddsaPrivateKey priv; |
136 | struct GNUNET_CRYPTO_EddsaPublicKey pub; | 781 | struct GNUNET_CRYPTO_EddsaPublicKey pub; |
137 | struct GNUNET_CRYPTO_EddsaSignature sig; | 782 | struct GNUNET_CRYPTO_EddsaSignature sig; |
@@ -151,22 +796,26 @@ run (void *cls, | |||
151 | &sig, | 796 | &sig, |
152 | &pub)); | 797 | &pub)); |
153 | 798 | ||
154 | printf ("eddsa sig:\n"); | 799 | d2j (vec, |
155 | display_data (" priv", | 800 | "priv", |
156 | &priv, | 801 | &priv, |
157 | sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)); | 802 | sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)); |
158 | display_data (" pub", | 803 | d2j (vec, |
159 | &pub, | 804 | "pub", |
160 | sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)); | 805 | &pub, |
161 | display_data (" data", | 806 | sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)); |
162 | &data, | 807 | d2j (vec, |
163 | sizeof (struct TestSignatureDataPS)); | 808 | "data", |
164 | display_data (" sig", | 809 | &data, |
165 | &sig, | 810 | sizeof (struct TestSignatureDataPS)); |
166 | sizeof (struct GNUNET_CRYPTO_EddsaSignature)); | 811 | d2j (vec, |
812 | "sig", | ||
813 | &sig, | ||
814 | sizeof (struct GNUNET_CRYPTO_EddsaSignature)); | ||
167 | } | 815 | } |
168 | 816 | ||
169 | { | 817 | { |
818 | json_t *vec = vec_for (vecs, "kdf"); | ||
170 | size_t out_len = 64; | 819 | size_t out_len = 64; |
171 | char out[out_len]; | 820 | char out[out_len]; |
172 | char *ikm = "I'm the secret input key material"; | 821 | char *ikm = "I'm the secret input key material"; |
@@ -184,14 +833,28 @@ run (void *cls, | |||
184 | strlen (ctx), | 833 | strlen (ctx), |
185 | NULL)); | 834 | NULL)); |
186 | 835 | ||
187 | printf ("kdf:\n"); | 836 | d2j (vec, |
188 | display_data (" salt", salt, strlen (salt)); | 837 | "salt", |
189 | display_data (" ikm", ikm, strlen (ikm)); | 838 | salt, |
190 | display_data (" ctx", ctx, strlen (ctx)); | 839 | strlen (salt)); |
191 | printf (" out_len %u\n", (unsigned int) out_len); | 840 | d2j (vec, |
192 | display_data (" out", out, out_len); | 841 | "ikm", |
842 | ikm, | ||
843 | strlen (ikm)); | ||
844 | d2j (vec, | ||
845 | "ctx", | ||
846 | ctx, | ||
847 | strlen (ctx)); | ||
848 | uint2j (vec, | ||
849 | "out_len", | ||
850 | (unsigned int) out_len); | ||
851 | d2j (vec, | ||
852 | "out", | ||
853 | out, | ||
854 | out_len); | ||
193 | } | 855 | } |
194 | { | 856 | { |
857 | json_t *vec = vec_for (vecs, "eddsa_ecdh"); | ||
195 | struct GNUNET_CRYPTO_EcdhePrivateKey priv_ecdhe; | 858 | struct GNUNET_CRYPTO_EcdhePrivateKey priv_ecdhe; |
196 | struct GNUNET_CRYPTO_EcdhePublicKey pub_ecdhe; | 859 | struct GNUNET_CRYPTO_EcdhePublicKey pub_ecdhe; |
197 | struct GNUNET_CRYPTO_EddsaPrivateKey priv_eddsa; | 860 | struct GNUNET_CRYPTO_EddsaPrivateKey priv_eddsa; |
@@ -204,25 +867,26 @@ run (void *cls, | |||
204 | GNUNET_CRYPTO_eddsa_key_get_public (&priv_eddsa, &pub_eddsa); | 867 | GNUNET_CRYPTO_eddsa_key_get_public (&priv_eddsa, &pub_eddsa); |
205 | GNUNET_CRYPTO_ecdh_eddsa (&priv_ecdhe, &pub_eddsa, &key_material); | 868 | GNUNET_CRYPTO_ecdh_eddsa (&priv_ecdhe, &pub_eddsa, &key_material); |
206 | 869 | ||
207 | printf ("eddsa_ecdh:\n"); | 870 | d2j (vec, "priv_ecdhe", |
208 | display_data (" priv_ecdhe", | ||
209 | &priv_ecdhe, | 871 | &priv_ecdhe, |
210 | sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey)); | 872 | sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey)); |
211 | display_data (" pub_ecdhe", | 873 | d2j (vec, "pub_ecdhe", |
212 | &pub_ecdhe, | 874 | &pub_ecdhe, |
213 | sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); | 875 | sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); |
214 | display_data (" priv_eddsa", | 876 | d2j (vec, "priv_eddsa", |
215 | &priv_eddsa, | 877 | &priv_eddsa, |
216 | sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)); | 878 | sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)); |
217 | display_data (" pub_eddsa", | 879 | d2j (vec, "pub_eddsa", |
218 | &pub_eddsa, | 880 | &pub_eddsa, |
219 | sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)); | 881 | sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)); |
220 | display_data (" key_material", | 882 | d2j (vec, "key_material", |
221 | &key_material, | 883 | &key_material, |
222 | sizeof (struct GNUNET_HashCode)); | 884 | sizeof (struct GNUNET_HashCode)); |
223 | } | 885 | } |
224 | 886 | ||
225 | { | 887 | { |
888 | json_t *vec = vec_for (vecs, "rsa_blind_signing"); | ||
889 | |||
226 | struct GNUNET_CRYPTO_RsaPrivateKey *skey; | 890 | struct GNUNET_CRYPTO_RsaPrivateKey *skey; |
227 | struct GNUNET_CRYPTO_RsaPublicKey *pkey; | 891 | struct GNUNET_CRYPTO_RsaPublicKey *pkey; |
228 | struct GNUNET_HashCode message_hash; | 892 | struct GNUNET_HashCode message_hash; |
@@ -233,10 +897,13 @@ run (void *cls, | |||
233 | size_t blinded_len; | 897 | size_t blinded_len; |
234 | void *public_enc_data; | 898 | void *public_enc_data; |
235 | size_t public_enc_len; | 899 | size_t public_enc_len; |
900 | void *secret_enc_data; | ||
901 | size_t secret_enc_len; | ||
236 | void *blinded_sig_enc_data; | 902 | void *blinded_sig_enc_data; |
237 | size_t blinded_sig_enc_length; | 903 | size_t blinded_sig_enc_length; |
238 | void *sig_enc_data; | 904 | void *sig_enc_data; |
239 | size_t sig_enc_length; | 905 | size_t sig_enc_length; |
906 | |||
240 | skey = GNUNET_CRYPTO_rsa_private_key_create (2048); | 907 | skey = GNUNET_CRYPTO_rsa_private_key_create (2048); |
241 | pkey = GNUNET_CRYPTO_rsa_private_key_get_public (skey); | 908 | pkey = GNUNET_CRYPTO_rsa_private_key_get_public (skey); |
242 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, | 909 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, |
@@ -259,25 +926,75 @@ run (void *cls, | |||
259 | pkey)); | 926 | pkey)); |
260 | public_enc_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey, | 927 | public_enc_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey, |
261 | &public_enc_data); | 928 | &public_enc_data); |
929 | secret_enc_len = GNUNET_CRYPTO_rsa_private_key_encode (skey, | ||
930 | &secret_enc_data); | ||
262 | blinded_sig_enc_length = GNUNET_CRYPTO_rsa_signature_encode (blinded_sig, | 931 | blinded_sig_enc_length = GNUNET_CRYPTO_rsa_signature_encode (blinded_sig, |
263 | & | 932 | & |
264 | blinded_sig_enc_data); | 933 | blinded_sig_enc_data); |
265 | sig_enc_length = GNUNET_CRYPTO_rsa_signature_encode (sig, &sig_enc_data); | 934 | sig_enc_length = GNUNET_CRYPTO_rsa_signature_encode (sig, &sig_enc_data); |
266 | printf ("blind signing:\n"); | 935 | d2j (vec, |
267 | display_data (" message_hash", &message_hash, sizeof (struct | 936 | "message_hash", |
268 | GNUNET_HashCode)); | 937 | &message_hash, |
269 | display_data (" rsa_public_key", public_enc_data, public_enc_len); | 938 | sizeof (struct GNUNET_HashCode)); |
270 | display_data (" blinding_key_secret", &bks, sizeof (struct | 939 | d2j (vec, |
271 | GNUNET_CRYPTO_RsaBlindingKeySecret)); | 940 | "rsa_public_key", |
272 | display_data (" blinded_message", blinded_data, blinded_len); | 941 | public_enc_data, |
273 | display_data (" blinded_sig", blinded_sig_enc_data, | 942 | public_enc_len); |
274 | blinded_sig_enc_length); | 943 | d2j (vec, |
275 | display_data (" sig", sig_enc_data, sig_enc_length); | 944 | "rsa_private_key", |
945 | secret_enc_data, | ||
946 | secret_enc_len); | ||
947 | d2j (vec, | ||
948 | "blinding_key_secret", | ||
949 | &bks, | ||
950 | sizeof (struct GNUNET_CRYPTO_RsaBlindingKeySecret)); | ||
951 | d2j (vec, | ||
952 | "blinded_message", | ||
953 | blinded_data, | ||
954 | blinded_len); | ||
955 | d2j (vec, | ||
956 | "blinded_sig", | ||
957 | blinded_sig_enc_data, | ||
958 | blinded_sig_enc_length); | ||
959 | d2j (vec, | ||
960 | "sig", | ||
961 | sig_enc_data, | ||
962 | sig_enc_length); | ||
276 | GNUNET_CRYPTO_rsa_private_key_free (skey); | 963 | GNUNET_CRYPTO_rsa_private_key_free (skey); |
277 | GNUNET_CRYPTO_rsa_public_key_free (pkey); | 964 | GNUNET_CRYPTO_rsa_public_key_free (pkey); |
278 | GNUNET_CRYPTO_rsa_signature_free (sig); | 965 | GNUNET_CRYPTO_rsa_signature_free (sig); |
279 | GNUNET_CRYPTO_rsa_signature_free (blinded_sig); | 966 | GNUNET_CRYPTO_rsa_signature_free (blinded_sig); |
967 | GNUNET_free (public_enc_data); | ||
968 | GNUNET_free (blinded_data); | ||
969 | GNUNET_free (sig_enc_data); | ||
970 | GNUNET_free (blinded_sig_enc_data); | ||
280 | } | 971 | } |
972 | |||
973 | json_dumpf (vecfile, stdout, JSON_INDENT (2)); | ||
974 | json_decref (vecfile); | ||
975 | printf ("\n"); | ||
976 | |||
977 | return 0; | ||
978 | } | ||
979 | |||
980 | /** | ||
981 | * Main function that will be run. | ||
982 | * | ||
983 | * @param cls closure | ||
984 | * @param args remaining command-line arguments | ||
985 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) | ||
986 | * @param cfg configuration | ||
987 | */ | ||
988 | static void | ||
989 | run (void *cls, | ||
990 | char *const *args, | ||
991 | const char *cfgfile, | ||
992 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
993 | { | ||
994 | if (GNUNET_YES == verify_flag) | ||
995 | global_ret = check_vectors (); | ||
996 | else | ||
997 | global_ret = output_vectors (); | ||
281 | } | 998 | } |
282 | 999 | ||
283 | 1000 | ||
@@ -293,6 +1010,11 @@ main (int argc, | |||
293 | char *const *argv) | 1010 | char *const *argv) |
294 | { | 1011 | { |
295 | const struct GNUNET_GETOPT_CommandLineOption options[] = { | 1012 | const struct GNUNET_GETOPT_CommandLineOption options[] = { |
1013 | GNUNET_GETOPT_option_flag ('V', | ||
1014 | "verify", | ||
1015 | gettext_noop ( | ||
1016 | "verify a test vector from stdin"), | ||
1017 | &verify_flag), | ||
296 | GNUNET_GETOPT_OPTION_END | 1018 | GNUNET_GETOPT_OPTION_END |
297 | }; | 1019 | }; |
298 | 1020 | ||
@@ -307,7 +1029,7 @@ main (int argc, | |||
307 | options, | 1029 | options, |
308 | &run, NULL)) | 1030 | &run, NULL)) |
309 | return 1; | 1031 | return 1; |
310 | return 0; | 1032 | return global_ret; |
311 | } | 1033 | } |
312 | 1034 | ||
313 | 1035 | ||