diff options
Diffstat (limited to 'src/identity')
-rw-r--r-- | src/identity/Makefile.am | 5 | ||||
-rw-r--r-- | src/identity/gnunet-identity.c | 209 | ||||
-rw-r--r-- | src/identity/test_identity.conf | 3 | ||||
-rwxr-xr-x | src/identity/test_identity_messages.sh | 34 |
4 files changed, 247 insertions, 4 deletions
diff --git a/src/identity/Makefile.am b/src/identity/Makefile.am index 59ace6c41..e535c208a 100644 --- a/src/identity/Makefile.am +++ b/src/identity/Makefile.am | |||
@@ -71,9 +71,12 @@ check_PROGRAMS = \ | |||
71 | test_identity \ | 71 | test_identity \ |
72 | test_identity_defaults | 72 | test_identity_defaults |
73 | 73 | ||
74 | check_SCRIPTS = \ | ||
75 | test_identity_messages.sh | ||
76 | |||
74 | if ENABLE_TEST_RUN | 77 | if ENABLE_TEST_RUN |
75 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; | 78 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; |
76 | TESTS = $(check_PROGRAMS) | 79 | TESTS = $(check_PROGRAMS) $(check_SCRIPTS) |
77 | endif | 80 | endif |
78 | 81 | ||
79 | 82 | ||
diff --git a/src/identity/gnunet-identity.c b/src/identity/gnunet-identity.c index d8dc936d3..97dc2ce7e 100644 --- a/src/identity/gnunet-identity.c +++ b/src/identity/gnunet-identity.c | |||
@@ -71,6 +71,16 @@ static int quiet; | |||
71 | static int type_eddsa; | 71 | static int type_eddsa; |
72 | 72 | ||
73 | /** | 73 | /** |
74 | * -W option | ||
75 | */ | ||
76 | static char *write_msg; | ||
77 | |||
78 | /** | ||
79 | * -R option | ||
80 | */ | ||
81 | static char *read_msg; | ||
82 | |||
83 | /** | ||
74 | * -C option | 84 | * -C option |
75 | */ | 85 | */ |
76 | static char *create_ego; | 86 | static char *create_ego; |
@@ -86,6 +96,11 @@ static char *delete_ego; | |||
86 | static char *privkey_ego; | 96 | static char *privkey_ego; |
87 | 97 | ||
88 | /** | 98 | /** |
99 | * -k option | ||
100 | */ | ||
101 | static char *pubkey_msg; | ||
102 | |||
103 | /** | ||
89 | * -s option. | 104 | * -s option. |
90 | */ | 105 | */ |
91 | static char *set_ego; | 106 | static char *set_ego; |
@@ -164,6 +179,8 @@ test_finished (void) | |||
164 | (NULL == delete_op) && | 179 | (NULL == delete_op) && |
165 | (NULL == set_op) && | 180 | (NULL == set_op) && |
166 | (NULL == set_subsystem) && | 181 | (NULL == set_subsystem) && |
182 | (NULL == write_msg) && | ||
183 | (NULL == read_msg) && | ||
167 | (! list) && | 184 | (! list) && |
168 | (! monitor)) | 185 | (! monitor)) |
169 | { | 186 | { |
@@ -260,6 +277,135 @@ set_done (void *cls, const char *emsg) | |||
260 | 277 | ||
261 | 278 | ||
262 | /** | 279 | /** |
280 | * Encrypt a message given with -W, encrypted using public key of | ||
281 | * an identity given with -k. | ||
282 | */ | ||
283 | static void | ||
284 | write_encrypted_message (void) | ||
285 | { | ||
286 | struct GNUNET_IDENTITY_PublicKey recipient; | ||
287 | if (GNUNET_IDENTITY_public_key_from_string (pubkey_msg, &recipient) != | ||
288 | GNUNET_SYSERR) | ||
289 | { | ||
290 | struct GNUNET_CRYPTO_EcdhePublicKey message_key; | ||
291 | size_t msg_len = strlen (write_msg); | ||
292 | ssize_t res = GNUNET_IDENTITY_encrypt (write_msg, | ||
293 | msg_len, | ||
294 | &recipient, | ||
295 | &message_key, | ||
296 | write_msg); | ||
297 | if (-1 != res) | ||
298 | { | ||
299 | char *keystr; | ||
300 | char *serialized_msg; | ||
301 | keystr = GNUNET_STRINGS_data_to_string_alloc (&message_key, | ||
302 | sizeof(struct | ||
303 | GNUNET_CRYPTO_EcdhePublicKey)); | ||
304 | serialized_msg = GNUNET_STRINGS_data_to_string_alloc (write_msg, | ||
305 | msg_len); | ||
306 | fprintf (stdout, | ||
307 | "%s.%s\n", | ||
308 | keystr, serialized_msg); | ||
309 | GNUNET_free (keystr); | ||
310 | GNUNET_free (serialized_msg); | ||
311 | } | ||
312 | else | ||
313 | { | ||
314 | fprintf (stderr, "Error during encryption.\n"); | ||
315 | global_ret = 1; | ||
316 | } | ||
317 | } | ||
318 | else | ||
319 | { | ||
320 | fprintf (stderr, "Invalid recipient public key.\n"); | ||
321 | global_ret = 1; | ||
322 | } | ||
323 | } | ||
324 | |||
325 | |||
326 | /** | ||
327 | * Decrypt a message given with -R, encrypted using public key of @c ego | ||
328 | * and ephemeral key given with -k. | ||
329 | * | ||
330 | * @param ego ego whose private key is used for decryption | ||
331 | */ | ||
332 | static void | ||
333 | read_encrypted_message (struct GNUNET_IDENTITY_Ego *ego) | ||
334 | { | ||
335 | // message contains ECDHE key and ciphertext divided by ".", so split up first | ||
336 | char delim[2] = "."; | ||
337 | char *key_msg = strtok (read_msg, delim); | ||
338 | char *cipher; | ||
339 | if (NULL == key_msg) | ||
340 | { | ||
341 | fprintf (stderr, "Invalid message format.\n"); | ||
342 | global_ret = 1; | ||
343 | return; | ||
344 | } | ||
345 | cipher = strtok (NULL, delim); | ||
346 | if (NULL == cipher) | ||
347 | { | ||
348 | fprintf (stderr, "Invalid message format, text missing.\n"); | ||
349 | global_ret = 1; | ||
350 | return; | ||
351 | } | ||
352 | |||
353 | if (NULL != strtok (NULL, delim)) | ||
354 | { | ||
355 | fprintf (stderr, | ||
356 | "Invalid message format, expecting only key and cipher components.\n"); | ||
357 | global_ret = 1; | ||
358 | return; | ||
359 | } | ||
360 | |||
361 | struct GNUNET_CRYPTO_EcdhePublicKey message_key; | ||
362 | if (GNUNET_OK == GNUNET_STRINGS_string_to_data (key_msg, strlen ( | ||
363 | key_msg), | ||
364 | &message_key, | ||
365 | sizeof(message_key))) | ||
366 | { | ||
367 | char *deserialized_msg; | ||
368 | size_t msg_len; | ||
369 | if (GNUNET_OK == GNUNET_STRINGS_string_to_data_alloc (cipher, strlen ( | ||
370 | cipher), | ||
371 | (void **) & | ||
372 | deserialized_msg, | ||
373 | &msg_len)) | ||
374 | { | ||
375 | ssize_t res = GNUNET_IDENTITY_decrypt (deserialized_msg, | ||
376 | msg_len, | ||
377 | GNUNET_IDENTITY_ego_get_private_key ( | ||
378 | ego), | ||
379 | &message_key, | ||
380 | deserialized_msg); | ||
381 | if (-1 != res) | ||
382 | { | ||
383 | fprintf (stdout, | ||
384 | "%s\n", | ||
385 | deserialized_msg); | ||
386 | } | ||
387 | else | ||
388 | { | ||
389 | fprintf (stderr, "Failed to decrypt message.\n"); | ||
390 | global_ret = 1; | ||
391 | } | ||
392 | GNUNET_free (deserialized_msg); | ||
393 | } | ||
394 | else | ||
395 | { | ||
396 | fprintf (stderr, "Invalid message format.\n"); | ||
397 | global_ret = 1; | ||
398 | } | ||
399 | } | ||
400 | else | ||
401 | { | ||
402 | fprintf (stderr, "Invalid message ephemeral key.\n"); | ||
403 | global_ret = 1; | ||
404 | } | ||
405 | } | ||
406 | |||
407 | |||
408 | /** | ||
263 | * If listing is enabled, prints information about the egos. | 409 | * If listing is enabled, prints information about the egos. |
264 | * | 410 | * |
265 | * This function is initially called for all egos and then again | 411 | * This function is initially called for all egos and then again |
@@ -330,13 +476,25 @@ print_ego (void *cls, | |||
330 | GNUNET_free (set_ego); | 476 | GNUNET_free (set_ego); |
331 | set_ego = NULL; | 477 | set_ego = NULL; |
332 | } | 478 | } |
479 | if ( (NULL == ego) && | ||
480 | (NULL != set_ego) && | ||
481 | (NULL != read_msg) ) | ||
482 | { | ||
483 | fprintf (stderr, | ||
484 | "Ego `%s' is not known, cannot decrypt message.\n", | ||
485 | set_ego); | ||
486 | GNUNET_free (read_msg); | ||
487 | read_msg = NULL; | ||
488 | GNUNET_free (set_ego); | ||
489 | set_ego = NULL; | ||
490 | } | ||
333 | if ((NULL == ego) && (! monitor)) | 491 | if ((NULL == ego) && (! monitor)) |
334 | { | 492 | { |
335 | list = 0; | 493 | list = 0; |
336 | test_finished (); | 494 | test_finished (); |
337 | return; | 495 | return; |
338 | } | 496 | } |
339 | if (! (list | monitor)) | 497 | if (! (list | monitor) && (NULL == read_msg)) |
340 | return; | 498 | return; |
341 | if ( (NULL == ego) || | 499 | if ( (NULL == ego) || |
342 | (NULL == identifier) ) | 500 | (NULL == identifier) ) |
@@ -349,7 +507,14 @@ print_ego (void *cls, | |||
349 | s = GNUNET_IDENTITY_public_key_to_string (&pk); | 507 | s = GNUNET_IDENTITY_public_key_to_string (&pk); |
350 | privs = GNUNET_IDENTITY_private_key_to_string ( | 508 | privs = GNUNET_IDENTITY_private_key_to_string ( |
351 | GNUNET_IDENTITY_ego_get_private_key (ego)); | 509 | GNUNET_IDENTITY_ego_get_private_key (ego)); |
352 | if ((monitor) || (NULL != identifier)) | 510 | if ((NULL != read_msg) && (NULL != set_ego)) |
511 | { | ||
512 | // due to the check above, set_ego and the identifier are equal | ||
513 | read_encrypted_message (ego); | ||
514 | GNUNET_free (read_msg); | ||
515 | read_msg = NULL; | ||
516 | } | ||
517 | else if ((monitor) || (NULL != identifier)) | ||
353 | { | 518 | { |
354 | if (quiet) | 519 | if (quiet) |
355 | { | 520 | { |
@@ -397,6 +562,19 @@ run (void *cls, | |||
397 | fprintf (stderr, "Option -s requires option -e to be specified as well.\n"); | 562 | fprintf (stderr, "Option -s requires option -e to be specified as well.\n"); |
398 | return; | 563 | return; |
399 | } | 564 | } |
565 | |||
566 | if ((NULL != read_msg) && (NULL == set_ego)) | ||
567 | { | ||
568 | fprintf (stderr, | ||
569 | "Option -R requires options -e to be specified as well.\n"); | ||
570 | return; | ||
571 | } | ||
572 | |||
573 | if ((NULL != write_msg) && (NULL == pubkey_msg)) | ||
574 | { | ||
575 | fprintf (stderr, "Option -W requires option -k to be specified as well.\n"); | ||
576 | return; | ||
577 | } | ||
400 | sh = GNUNET_IDENTITY_connect (cfg, | 578 | sh = GNUNET_IDENTITY_connect (cfg, |
401 | (monitor | list) || | 579 | (monitor | list) || |
402 | (NULL != set_ego) || | 580 | (NULL != set_ego) || |
@@ -404,6 +582,13 @@ run (void *cls, | |||
404 | ? &print_ego | 582 | ? &print_ego |
405 | : NULL, | 583 | : NULL, |
406 | NULL); | 584 | NULL); |
585 | if (NULL != write_msg) | ||
586 | { | ||
587 | write_encrypted_message (); | ||
588 | GNUNET_free (write_msg); | ||
589 | write_msg = NULL; | ||
590 | } | ||
591 | // read message is handled in ego callback (print_ego) | ||
407 | if (NULL != delete_ego) | 592 | if (NULL != delete_ego) |
408 | delete_op = | 593 | delete_op = |
409 | GNUNET_IDENTITY_delete (sh, | 594 | GNUNET_IDENTITY_delete (sh, |
@@ -471,6 +656,18 @@ main (int argc, char *const *argv) | |||
471 | gettext_noop ( | 656 | gettext_noop ( |
472 | "set the private key for the identity to PRIVATE_KEY (use together with -C)"), | 657 | "set the private key for the identity to PRIVATE_KEY (use together with -C)"), |
473 | &privkey_ego), | 658 | &privkey_ego), |
659 | GNUNET_GETOPT_option_string ('R', | ||
660 | "read", | ||
661 | "MESSAGE", | ||
662 | gettext_noop ( | ||
663 | "Read and decrypt message encrypted for the given ego (use together with -e EGO)"), | ||
664 | &read_msg), | ||
665 | GNUNET_GETOPT_option_string ('W', | ||
666 | "write", | ||
667 | "MESSAGE", | ||
668 | gettext_noop ( | ||
669 | "Encrypt and write message for recipient identity PULBIC_KEY, (use together with -k RECIPIENT_PUBLIC_KEY)"), | ||
670 | &write_msg), | ||
474 | GNUNET_GETOPT_option_flag ('X', | 671 | GNUNET_GETOPT_option_flag ('X', |
475 | "eddsa", | 672 | "eddsa", |
476 | gettext_noop ( | 673 | gettext_noop ( |
@@ -489,8 +686,14 @@ main (int argc, char *const *argv) | |||
489 | "ego", | 686 | "ego", |
490 | "NAME", | 687 | "NAME", |
491 | gettext_noop ( | 688 | gettext_noop ( |
492 | "set default identity to NAME for a subsystem SUBSYSTEM (use together with -s) or restrict results to NAME (use together with -d)"), | 689 | "set default identity to NAME for a subsystem SUBSYSTEM (use together with -s), restrict results to NAME (use together with -d) or read and decrypt a message for NAME (use together with -R)"), |
493 | &set_ego), | 690 | &set_ego), |
691 | GNUNET_GETOPT_option_string ('k', | ||
692 | "key", | ||
693 | "PUBLIC_KEY", | ||
694 | gettext_noop ( | ||
695 | "The public key of the recipient (with -W)"), | ||
696 | &pubkey_msg), | ||
494 | GNUNET_GETOPT_option_flag ('m', | 697 | GNUNET_GETOPT_option_flag ('m', |
495 | "monitor", | 698 | "monitor", |
496 | gettext_noop ("run in monitor mode egos"), | 699 | gettext_noop ("run in monitor mode egos"), |
diff --git a/src/identity/test_identity.conf b/src/identity/test_identity.conf index 9c433da77..14b915732 100644 --- a/src/identity/test_identity.conf +++ b/src/identity/test_identity.conf | |||
@@ -1,3 +1,6 @@ | |||
1 | [PATHS] | ||
2 | GNUNET_TEST_HOME = $GNUNET_TMP/test-identity-service/ | ||
3 | |||
1 | [arm] | 4 | [arm] |
2 | PORT = 12000 | 5 | PORT = 12000 |
3 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-p1-service-arm.sock | 6 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-p1-service-arm.sock |
diff --git a/src/identity/test_identity_messages.sh b/src/identity/test_identity_messages.sh new file mode 100755 index 000000000..250c6a6f1 --- /dev/null +++ b/src/identity/test_identity_messages.sh | |||
@@ -0,0 +1,34 @@ | |||
1 | #!/bin/bash | ||
2 | trap "gnunet-arm -e -c test_identity.conf" SIGINT | ||
3 | |||
4 | LOCATION=$(which gnunet-config) | ||
5 | if [ -z $LOCATION ] | ||
6 | then | ||
7 | LOCATION="gnunet-config" | ||
8 | fi | ||
9 | $LOCATION --version 1> /dev/null | ||
10 | if test $? != 0 | ||
11 | then | ||
12 | echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX" | ||
13 | exit 77 | ||
14 | fi | ||
15 | |||
16 | rm -rf `gnunet-config -c test_identity.conf -s PATHS -o GNUNET_HOME -f` | ||
17 | |||
18 | which timeout >/dev/null 2>&1 && DO_TIMEOUT="timeout 30" | ||
19 | |||
20 | TEST_MSG="This is a test message. 123" | ||
21 | gnunet-arm -s -c test_identity.conf | ||
22 | gnunet-identity -C recipientego -c test_identity.conf | ||
23 | RECIPIENT_KEY=$(gnunet-identity -d -e recipientego -q -c test_identity.conf) | ||
24 | MSG_ENC=$(gnunet-identity -W "$TEST_MSG" -k $RECIPIENT_KEY -c test_identity.conf) | ||
25 | MSG_DEC=$(gnunet-identity -R "$MSG_ENC" -e recipientego -c test_identity.conf) | ||
26 | |||
27 | if test "$TEST_MSG" != "$MSG_DEC" | ||
28 | then | ||
29 | echo "Failed - $TEST_MSG != $MSG_DEC" | ||
30 | exit 1 | ||
31 | fi | ||
32 | |||
33 | gnunet-identity -D recipientego -c test_identity.conf | ||
34 | gnunet-arm -e -c test_identity.conf | ||