aboutsummaryrefslogtreecommitdiff
path: root/src/abd/gnunet-abd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/abd/gnunet-abd.c')
-rw-r--r--src/abd/gnunet-abd.c1070
1 files changed, 1070 insertions, 0 deletions
diff --git a/src/abd/gnunet-abd.c b/src/abd/gnunet-abd.c
new file mode 100644
index 000000000..23083ec68
--- /dev/null
+++ b/src/abd/gnunet-abd.c
@@ -0,0 +1,1070 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012-2013 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19*/
20/**
21 * @file gnunet-abd.c
22 * @brief command line tool to access command line Credential service
23 * @author Martin Schanzenbach
24 */
25#include "platform.h"
26#include <gnunet_util_lib.h>
27#include <gnunet_abd_service.h>
28#include <gnunet_gnsrecord_lib.h>
29#include <gnunet_namestore_service.h>
30#include "delegate_misc.h"
31#include "abd_serialization.h"
32
33/**
34 * Configuration we are using.
35 */
36static const struct GNUNET_CONFIGURATION_Handle *cfg;
37
38/**
39 * Handle to the namestore.
40 */
41static struct GNUNET_NAMESTORE_Handle *ns;
42
43/**
44 * Private key for the our zone.
45 */
46static struct GNUNET_CRYPTO_EcdsaPrivateKey zone_pkey;
47
48/**
49 * EgoLookup
50 */
51static struct GNUNET_IDENTITY_EgoLookup *el;
52
53/**
54 * Handle to Credential service.
55 */
56static struct GNUNET_ABD_Handle *abd;
57
58/**
59 * Desired timeout for the lookup (default is no timeout).
60 */
61static struct GNUNET_TIME_Relative timeout;
62
63/**
64 * Handle to verify request
65 */
66static struct GNUNET_ABD_Request *verify_request;
67
68/**
69 * Handle to collect request
70 */
71static struct GNUNET_ABD_Request *collect_request;
72
73/**
74 * Task scheduled to handle timeout.
75 */
76static struct GNUNET_SCHEDULER_Task *tt;
77
78/**
79 * Return value of the commandline.
80 */
81static int ret = 0;
82
83/**
84 * Subject pubkey string
85 */
86static char *subject;
87
88/**
89 * Subject delegate string
90 */
91static char *subject_delegate;
92
93/**
94 * Credential TTL
95 */
96static char *expiration;
97
98/**
99 * Subject key
100 */
101struct GNUNET_CRYPTO_EcdsaPublicKey subject_pkey;
102
103/**
104 * Issuer key
105 */
106struct GNUNET_CRYPTO_EcdsaPublicKey issuer_pkey;
107
108
109/**
110 * Issuer pubkey string
111 */
112static char *issuer_key;
113
114/**
115 * ego
116 */
117static char *ego_name;
118
119/**
120 * Issuer attribute
121 */
122static char *issuer_attr;
123
124/**
125 * Verify mode
126 */
127static int verify;
128
129/**
130 * Collect mode
131 */
132static int collect;
133
134/**
135 * Create mode
136 */
137static int create_is;
138
139/**
140 * Create mode
141 */
142static int create_ss;
143
144/**
145 * Create mode
146 */
147static int sign_ss;
148
149/**
150 * Signed issue credentials
151 */
152static char *import;
153
154/**
155 * Is record private
156 */
157static int is_private;
158
159/**
160 * Search direction: forward
161 */
162static int forward;
163
164/**
165 * Search direction: backward
166 */
167static int backward;
168
169/**
170 * API enum, filled and passed for collect/verify
171 */
172enum GNUNET_ABD_AlgoDirectionFlags direction = 0;
173
174/**
175 * Queue entry for the 'add' operation.
176 */
177static struct GNUNET_NAMESTORE_QueueEntry *add_qe;
178
179/**
180 * Value in binary format.
181 */
182static void *data;
183
184/**
185 * Number of bytes in #data.
186 */
187static size_t data_size;
188
189/**
190 * Type string converted to DNS type value.
191 */
192static uint32_t type;
193
194/**
195 * Type of the record to add/remove, NULL to remove all.
196 */
197static char *typestring;
198/**
199 * Expiration string converted to numeric value.
200 */
201static uint64_t etime;
202
203/**
204 * Is expiration time relative or absolute time?
205 */
206static int etime_is_rel = GNUNET_SYSERR;
207
208/**
209 * Fixed size of the public/private keys
210 */
211static const int key_length = 52;
212
213/**
214 * Record label for storing delegations
215 */
216static char *record_label;
217
218/**
219 * Task run on shutdown. Cleans up everything.
220 *
221 * @param cls unused
222 */
223static void
224do_shutdown (void *cls)
225{
226 if (NULL != verify_request)
227 {
228 GNUNET_ABD_request_cancel (verify_request);
229 verify_request = NULL;
230 }
231 if (NULL != abd)
232 {
233 GNUNET_ABD_disconnect (abd);
234 abd = NULL;
235 }
236 if (NULL != tt)
237 {
238 GNUNET_SCHEDULER_cancel (tt);
239 tt = NULL;
240 }
241 if (NULL != el)
242 {
243 GNUNET_IDENTITY_ego_lookup_cancel (el);
244 el = NULL;
245 }
246 if (NULL != add_qe)
247 {
248 GNUNET_NAMESTORE_cancel (add_qe);
249 add_qe = NULL;
250 }
251 if (NULL != ns)
252 {
253 GNUNET_NAMESTORE_disconnect (ns);
254 ns = NULL;
255 }
256}
257
258
259/**
260 * Task run on timeout. Triggers shutdown.
261 *
262 * @param cls unused
263 */
264static void
265do_timeout (void *cls)
266{
267 tt = NULL;
268 GNUNET_SCHEDULER_shutdown ();
269}
270
271static void
272handle_intermediate_result(void *cls,
273 struct GNUNET_ABD_Delegation *dd,
274 bool is_bw)
275{
276 char *prefix = "";
277 if(is_bw)
278 prefix = "Backward -";
279 else
280 prefix = "Forward -";
281
282 printf ("%s Intermediate result: %s.%s <- %s.%s\n",
283 prefix,
284 GNUNET_CRYPTO_ecdsa_public_key_to_string (&dd->issuer_key),
285 dd->issuer_attribute,
286 GNUNET_CRYPTO_ecdsa_public_key_to_string (&dd->subject_key),
287 dd->subject_attribute);
288}
289
290static void
291handle_collect_result (void *cls,
292 unsigned int d_count,
293 struct GNUNET_ABD_Delegation *dc,
294 unsigned int c_count,
295 struct GNUNET_ABD_Delegate *dele)
296{
297 int i;
298 char *line;
299
300 verify_request = NULL;
301 if (NULL != dele)
302 {
303 for (i = 0; i < c_count; i++)
304 {
305 line = GNUNET_ABD_delegate_to_string (&dele[i]);
306 printf ("%s\n", line);
307 GNUNET_free (line);
308 }
309 }
310 else
311 {
312 printf ("Received NULL\n");
313 }
314
315 GNUNET_SCHEDULER_shutdown ();
316}
317
318
319static void
320handle_verify_result (void *cls,
321 unsigned int d_count,
322 struct GNUNET_ABD_Delegation *dc,
323 unsigned int c_count,
324 struct GNUNET_ABD_Delegate *dele)
325{
326 int i;
327 char *iss_key;
328 char *sub_key;
329
330 verify_request = NULL;
331 if (NULL == dele)
332 ret = 1;
333 else
334 {
335 printf ("Delegation Chain:\n");
336 for (i = 0; i < d_count; i++)
337 {
338 iss_key = GNUNET_CRYPTO_ecdsa_public_key_to_string (&dc[i].issuer_key);
339 sub_key = GNUNET_CRYPTO_ecdsa_public_key_to_string (&dc[i].subject_key);
340
341 if (0 != dc[i].subject_attribute_len)
342 {
343 printf ("(%d) %s.%s <- %s.%s\n",
344 i,
345 iss_key,
346 dc[i].issuer_attribute,
347 sub_key,
348 dc[i].subject_attribute);
349 }
350 else
351 {
352 printf ("(%d) %s.%s <- %s\n",
353 i,
354 iss_key,
355 dc[i].issuer_attribute,
356 sub_key);
357 }
358 GNUNET_free (iss_key);
359 GNUNET_free (sub_key);
360 }
361 printf ("\nDelegate(s):\n");
362 for (i = 0; i < c_count; i++)
363 {
364 iss_key = GNUNET_CRYPTO_ecdsa_public_key_to_string (&dele[i].issuer_key);
365 sub_key = GNUNET_CRYPTO_ecdsa_public_key_to_string (&dele[i].subject_key);
366 printf ("%s.%s <- %s\n", iss_key, dele[i].issuer_attribute, sub_key);
367 GNUNET_free (iss_key);
368 GNUNET_free (sub_key);
369 }
370 printf ("Successful.\n");
371 }
372
373 GNUNET_SCHEDULER_shutdown ();
374}
375
376/**
377 * Callback invoked from identity service with ego information.
378 * An @a ego of NULL means the ego was not found.
379 *
380 * @param cls closure with the configuration
381 * @param ego an ego known to identity service, or NULL
382 */
383static void
384identity_cb (void *cls, const struct GNUNET_IDENTITY_Ego *ego)
385{
386 const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
387
388 el = NULL;
389 if (NULL == ego)
390 {
391 if (NULL != ego_name)
392 {
393 fprintf (stderr,
394 _ ("Ego `%s' not known to identity service\n"),
395 ego_name);
396 }
397 GNUNET_SCHEDULER_shutdown ();
398 return;
399 }
400
401 if (GNUNET_YES == collect)
402 {
403
404 if (GNUNET_OK !=
405 GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_key,
406 strlen (issuer_key),
407 &issuer_pkey))
408 {
409 fprintf (stderr,
410 _ ("Issuer public key `%s' is not well-formed\n"),
411 issuer_key);
412 GNUNET_SCHEDULER_shutdown ();
413 }
414 privkey = GNUNET_IDENTITY_ego_get_private_key (ego);
415
416 collect_request = GNUNET_ABD_collect (abd,
417 &issuer_pkey,
418 issuer_attr,
419 privkey,
420 direction,
421 &handle_collect_result,
422 NULL,
423 &handle_intermediate_result,
424 NULL);
425 return;
426 }
427 GNUNET_SCHEDULER_shutdown ();
428}
429
430/**
431 * Parse expiration time.
432 *
433 * @param expirationstring text to parse
434 * @param etime_is_rel[out] set to #GNUNET_YES if time is relative
435 * @param etime[out] set to expiration time (abs or rel)
436 * @return #GNUNET_OK on success
437 */
438static int
439parse_expiration (const char *expirationstring,
440 int *etime_is_rel,
441 uint64_t *etime)
442{
443 // copied from namestore/gnunet-namestore.c
444 struct GNUNET_TIME_Relative etime_rel;
445 struct GNUNET_TIME_Absolute etime_abs;
446
447 if (0 == strcmp (expirationstring, "never"))
448 {
449 *etime = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
450 *etime_is_rel = GNUNET_NO;
451 return GNUNET_OK;
452 }
453 if (GNUNET_OK ==
454 GNUNET_STRINGS_fancy_time_to_relative (expirationstring, &etime_rel))
455 {
456 *etime_is_rel = GNUNET_YES;
457 *etime = etime_rel.rel_value_us;
458 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
459 "Storing record with relative expiration time of %s\n",
460 GNUNET_STRINGS_relative_time_to_string (etime_rel, GNUNET_NO));
461 return GNUNET_OK;
462 }
463 if (GNUNET_OK ==
464 GNUNET_STRINGS_fancy_time_to_absolute (expirationstring, &etime_abs))
465 {
466 *etime_is_rel = GNUNET_NO;
467 *etime = etime_abs.abs_value_us;
468 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
469 "Storing record with absolute expiration time of %s\n",
470 GNUNET_STRINGS_absolute_time_to_string (etime_abs));
471 return GNUNET_OK;
472 }
473 return GNUNET_SYSERR;
474}
475
476/**
477 * Function called if lookup fails.
478 */
479static void
480error_cb (void *cls)
481{
482 fprintf (stderr, "Error occured during lookup, shutting down.\n");
483 GNUNET_SCHEDULER_shutdown ();
484 return;
485}
486static void
487add_continuation (void *cls, int32_t success, const char *emsg)
488{
489 struct GNUNET_NAMESTORE_QueueEntry **qe = cls;
490 *qe = NULL;
491
492 if(GNUNET_OK == success)
493 printf ("Adding successful.\n");
494 else
495 fprintf (stderr, "Error occured during adding, shutting down.\n");
496
497 GNUNET_SCHEDULER_shutdown ();
498}
499
500static void
501get_existing_record (void *cls,
502 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
503 const char *rec_name,
504 unsigned int rd_count,
505 const struct GNUNET_GNSRECORD_Data *rd)
506{
507 struct GNUNET_GNSRECORD_Data rdn[rd_count + 1];
508 struct GNUNET_GNSRECORD_Data *rde;
509
510 memset (rdn, 0, sizeof (struct GNUNET_GNSRECORD_Data));
511 GNUNET_memcpy (&rdn[1], rd, rd_count * sizeof (struct GNUNET_GNSRECORD_Data));
512 rde = &rdn[0];
513 rde->data = data;
514 rde->data_size = data_size;
515 rde->record_type = type;
516
517 // Set flags
518 if (GNUNET_YES == is_private)
519 rde->flags |= GNUNET_GNSRECORD_RF_PRIVATE;
520 rde->expiration_time = etime;
521 if (GNUNET_YES == etime_is_rel)
522 rde->flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
523 else if (GNUNET_NO != etime_is_rel)
524 rde->expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
525
526 GNUNET_assert (NULL != rec_name);
527 add_qe = GNUNET_NAMESTORE_records_store (ns,
528 &zone_pkey,
529 rec_name,
530 rd_count + 1,
531 rde,
532 &add_continuation,
533 &add_qe);
534
535 return;
536}
537
538static void
539store_cb (void *cls, const struct GNUNET_IDENTITY_Ego *ego)
540{
541 const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
542
543 el = NULL;
544
545 ns = GNUNET_NAMESTORE_connect (cfg);
546 if (NULL == ns)
547 {
548 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
549 _ ("Failed to connect to namestore\n"));
550 GNUNET_SCHEDULER_shutdown ();
551 return;
552 }
553
554 // Key handling
555 zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego);
556
557 if (GNUNET_GNSRECORD_TYPE_DELEGATE == type)
558 {
559 // Parse import
560 struct GNUNET_ABD_Delegate *cred;
561 cred = GNUNET_ABD_delegate_from_string (import);
562
563 // Get import subject public key string
564 char *subject_pubkey_str =
565 GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->subject_key);
566
567 // Get zone public key string
568 struct GNUNET_CRYPTO_EcdsaPublicKey zone_pubkey;
569 GNUNET_IDENTITY_ego_get_public_key (ego, &zone_pubkey);
570 char *zone_pubkey_str =
571 GNUNET_CRYPTO_ecdsa_public_key_to_string (&zone_pubkey);
572
573 // Check if the subject key in the signed import matches the zone's key it is issued to
574 if (strcmp (zone_pubkey_str, subject_pubkey_str) != 0)
575 {
576 fprintf (stderr,
577 "Import signed delegate does not match this ego's public key.\n");
578 GNUNET_SCHEDULER_shutdown ();
579 return;
580 }
581
582 // Expiration
583 etime = cred->expiration.abs_value_us;
584 etime_is_rel = GNUNET_NO;
585
586 // Prepare the data to be store in the record
587 data_size = GNUNET_ABD_delegate_serialize (cred, (char **) &data);
588 GNUNET_free (cred);
589 }
590 else
591 {
592 // For all other types e.g. GNUNET_GNSRECORD_TYPE_ATTRIBUTE
593 if (GNUNET_OK !=
594 GNUNET_GNSRECORD_string_to_value (type, subject, &data, &data_size))
595 {
596 fprintf (stderr,
597 "Value `%s' invalid for record type `%s'\n",
598 subject,
599 typestring);
600 GNUNET_SCHEDULER_shutdown ();
601 return;
602 }
603
604 // Take care of expiration
605 if (NULL == expiration)
606 {
607 fprintf (stderr, "Missing option -e for operation 'create'\n");
608 GNUNET_SCHEDULER_shutdown ();
609 return;
610 }
611 if (GNUNET_OK != parse_expiration (expiration, &etime_is_rel, &etime))
612 {
613 fprintf (stderr, "Invalid time format `%s'\n", expiration);
614 GNUNET_SCHEDULER_shutdown ();
615 return;
616 }
617 }
618
619 // Start lookup
620 add_qe = GNUNET_NAMESTORE_records_lookup (ns,
621 &zone_pkey,
622 record_label,
623 &error_cb,
624 NULL,
625 &get_existing_record,
626 NULL);
627 return;
628}
629
630static void
631sign_cb (void *cls, const struct GNUNET_IDENTITY_Ego *ego)
632{
633 const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
634 struct GNUNET_ABD_Delegate *dele;
635 struct GNUNET_TIME_Absolute etime_abs;
636 char *res;
637
638 el = NULL;
639
640 // work on expiration time
641 if (NULL == expiration)
642 {
643 fprintf (stderr, "Please specify a TTL\n");
644 GNUNET_SCHEDULER_shutdown ();
645 return;
646 }
647 else if (GNUNET_OK !=
648 GNUNET_STRINGS_fancy_time_to_absolute (expiration, &etime_abs))
649 {
650 fprintf (stderr,
651 "%s is not a valid ttl! Only absolute times are accepted!\n",
652 expiration);
653 GNUNET_SCHEDULER_shutdown ();
654 return;
655 }
656
657 // If contains a space - split it by the first space only - assume first entry is subject followed by attribute(s)
658 char *subject_pubkey_str;
659 char *subject_attr = NULL;
660 char *token;
661
662 // Subject Public Key
663 token = strtok (subject, " ");
664 if (key_length == strlen (token))
665 {
666 subject_pubkey_str = token;
667 }
668 else
669 {
670 fprintf (stderr, "Key error, wrong length: %ld!\n", strlen (token));
671 GNUNET_SCHEDULER_shutdown ();
672 return;
673 }
674 // Subject Attribute(s)
675 token = strtok (NULL, " ");
676 if (NULL != token)
677 {
678 subject_attr = token;
679 }
680
681 // work on keys
682 privkey = GNUNET_IDENTITY_ego_get_private_key (ego);
683
684 if (GNUNET_OK !=
685 GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_pubkey_str,
686 strlen (subject_pubkey_str),
687 &subject_pkey))
688 {
689 fprintf (stderr,
690 "Subject public key `%s' is not well-formed\n",
691 subject_pubkey_str);
692 GNUNET_SCHEDULER_shutdown ();
693 return;
694 }
695
696 // Sign delegate
697 dele = GNUNET_ABD_delegate_issue (privkey,
698 &subject_pkey,
699 issuer_attr,
700 subject_attr,
701 &etime_abs);
702 res = GNUNET_ABD_delegate_to_string (dele);
703 GNUNET_free (dele);
704 printf ("%s\n", res);
705
706 GNUNET_free_non_null (ego_name);
707 ego_name = NULL;
708
709 GNUNET_SCHEDULER_shutdown ();
710}
711
712/**
713 * Main function that will be run.
714 *
715 * @param cls closure
716 * @param args remaining command-line arguments
717 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
718 * @param c configuration
719 */
720static void
721run (void *cls,
722 char *const *args,
723 const char *cfgfile,
724 const struct GNUNET_CONFIGURATION_Handle *c)
725{
726 cfg = c;
727
728 tt = GNUNET_SCHEDULER_add_delayed (timeout, &do_timeout, NULL);
729 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
730
731 // Check relevant cmdline parameters
732 if (GNUNET_YES == create_is)
733 {
734 if (NULL == ego_name)
735 {
736 fprintf (stderr, "Missing option '-ego'\n");
737 GNUNET_SCHEDULER_shutdown ();
738 return;
739 }
740 if (NULL == issuer_attr)
741 {
742 fprintf (stderr, "Missing option '-attribute' for issuer attribute\n");
743 GNUNET_SCHEDULER_shutdown ();
744 return;
745 }
746 if (NULL == subject)
747 {
748 fprintf (stderr, "Missing option -subject for operation 'create'.'\n");
749 GNUNET_SCHEDULER_shutdown ();
750 return;
751 }
752
753 // Lookup ego, on success call store_cb and store as ATTRIBUTE type
754 type = GNUNET_GNSRECORD_TYPE_ATTRIBUTE;
755 record_label = issuer_attr;
756 el = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, &store_cb, (void *) cfg);
757 return;
758 }
759
760 if (GNUNET_YES == create_ss)
761 {
762
763 // check if signed parameter has been passed in cmd line call
764 if (NULL == import)
765 {
766 fprintf (stderr, "'import' required\n");
767 GNUNET_SCHEDULER_shutdown ();
768 return;
769 }
770
771 type = GNUNET_GNSRECORD_TYPE_DELEGATE;
772 record_label = GNUNET_GNS_EMPTY_LABEL_AT;
773 // Store subject side
774 el = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, &store_cb, (void *) cfg);
775
776 return;
777 }
778
779 if (GNUNET_YES == sign_ss)
780 {
781 if (NULL == ego_name)
782 {
783 fprintf (stderr, "ego required\n");
784 GNUNET_SCHEDULER_shutdown ();
785 return;
786 }
787 if (NULL == subject)
788 {
789 fprintf (stderr, "Subject public key needed\n");
790 GNUNET_SCHEDULER_shutdown ();
791 return;
792 }
793
794 // lookup ego and call function sign_cb on success
795 el = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, &sign_cb, (void *) cfg);
796 return;
797 }
798
799 if (GNUNET_NO == forward && GNUNET_NO == backward)
800 {
801 // set default: bidirectional
802 forward = GNUNET_YES;
803 backward = GNUNET_YES;
804 }
805 if (GNUNET_YES == forward)
806 direction |= GNUNET_ABD_FLAG_FORWARD;
807 if (GNUNET_YES == backward)
808 direction |= GNUNET_ABD_FLAG_BACKWARD;
809
810 if (GNUNET_YES == collect)
811 {
812 if (NULL == issuer_key)
813 {
814 fprintf (stderr, _ ("Issuer public key not well-formed\n"));
815 GNUNET_SCHEDULER_shutdown ();
816 return;
817 }
818
819 abd = GNUNET_ABD_connect (cfg);
820
821 if (NULL == abd)
822 {
823 fprintf (stderr, _ ("Failed to connect to ABD\n"));
824 GNUNET_SCHEDULER_shutdown ();
825 return;
826 }
827 if (NULL == issuer_attr)
828 {
829 fprintf (stderr, _ ("You must provide issuer the attribute\n"));
830 GNUNET_SCHEDULER_shutdown ();
831 return;
832 }
833
834 if (NULL == ego_name)
835 {
836 fprintf (stderr, _ ("ego required\n"));
837 GNUNET_SCHEDULER_shutdown ();
838 return;
839 }
840 el = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, &identity_cb, (void *) cfg);
841 return;
842 }
843
844 if (NULL == subject)
845 {
846 fprintf (stderr, _ ("Subject public key needed\n"));
847 GNUNET_SCHEDULER_shutdown ();
848 return;
849 }
850 if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_public_key_from_string (subject,
851 strlen (subject),
852 &subject_pkey))
853 {
854 fprintf (stderr,
855 _ ("Subject public key `%s' is not well-formed\n"),
856 subject);
857 GNUNET_SCHEDULER_shutdown ();
858 return;
859 }
860
861 if (GNUNET_YES == verify)
862 {
863 if (NULL == issuer_key)
864 {
865 fprintf (stderr, _ ("Issuer public key not well-formed\n"));
866 GNUNET_SCHEDULER_shutdown ();
867 return;
868 }
869 if (GNUNET_OK !=
870 GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_key,
871 strlen (issuer_key),
872 &issuer_pkey))
873 {
874 fprintf (stderr,
875 _ ("Issuer public key `%s' is not well-formed\n"),
876 issuer_key);
877 GNUNET_SCHEDULER_shutdown ();
878 return;
879 }
880 abd = GNUNET_ABD_connect (cfg);
881
882 if (NULL == abd)
883 {
884 fprintf (stderr, _ ("Failed to connect to ABD\n"));
885 GNUNET_SCHEDULER_shutdown ();
886 return;
887 }
888 if (NULL == issuer_attr || NULL == subject_delegate)
889 {
890 fprintf (stderr, _ ("You must provide issuer and subject attributes\n"));
891 GNUNET_SCHEDULER_shutdown ();
892 return;
893 }
894
895 //Subject credentials are comma separated
896 char *tmp = GNUNET_strdup (subject_delegate);
897 char *tok = strtok (tmp, ",");
898 if (NULL == tok)
899 {
900 fprintf (stderr, "Invalid subject credentials\n");
901 GNUNET_free (tmp);
902 GNUNET_SCHEDULER_shutdown ();
903 return;
904 }
905 int count = 1;
906 int i;
907 while (NULL != (tok = strtok (NULL, ",")))
908 count++;
909 struct GNUNET_ABD_Delegate delegates[count];
910 struct GNUNET_ABD_Delegate *dele;
911 GNUNET_free (tmp);
912 tmp = GNUNET_strdup (subject_delegate);
913 tok = strtok (tmp, ",");
914 for (i = 0; i < count; i++)
915 {
916 dele = GNUNET_ABD_delegate_from_string (tok);
917 GNUNET_memcpy (&delegates[i],
918 dele,
919 sizeof (struct GNUNET_ABD_Delegate));
920 delegates[i].issuer_attribute = GNUNET_strdup (dele->issuer_attribute);
921 tok = strtok (NULL, ",");
922 GNUNET_free (dele);
923 }
924
925 verify_request = GNUNET_ABD_verify (abd,
926 &issuer_pkey,
927 issuer_attr,
928 &subject_pkey,
929 count,
930 delegates,
931 direction,
932 &handle_verify_result,
933 NULL,
934 &handle_intermediate_result,
935 NULL);
936 for (i = 0; i < count; i++)
937 {
938 GNUNET_free ((char *) delegates[i].issuer_attribute);
939 }
940 GNUNET_free (tmp);
941 }
942 else
943 {
944 fprintf (stderr,
945 _ (
946 "Please specify name to lookup, subject key and issuer key!\n"));
947 GNUNET_SCHEDULER_shutdown ();
948 }
949 return;
950}
951
952
953/**
954 * The main function for gnunet-gns.
955 *
956 * @param argc number of arguments from the command line
957 * @param argv command line arguments
958 * @return 0 ok, 1 on error
959 */
960int
961main (int argc, char *const *argv)
962{
963 struct GNUNET_GETOPT_CommandLineOption options[] =
964 {GNUNET_GETOPT_option_flag ('V',
965 "verify",
966 gettext_noop (
967 "verify credential against attribute"),
968 &verify),
969 GNUNET_GETOPT_option_string (
970 's',
971 "subject",
972 "PKEY",
973 gettext_noop (
974 "The public key of the subject to lookup the"
975 "credential for, or for issuer side storage: subject and its attributes"),
976 &subject),
977 GNUNET_GETOPT_option_string (
978 'd',
979 "delegate",
980 "DELE",
981 gettext_noop ("The private, signed delegate presented by the subject"),
982 &subject_delegate),
983 GNUNET_GETOPT_option_string (
984 'i',
985 "issuer",
986 "PKEY",
987 gettext_noop (
988 "The public key of the authority to verify the credential against"),
989 &issuer_key),
990 GNUNET_GETOPT_option_string ('e',
991 "ego",
992 "EGO",
993 gettext_noop ("The ego/zone name to use"),
994 &ego_name),
995 GNUNET_GETOPT_option_string (
996 'a',
997 "attribute",
998 "ATTR",
999 gettext_noop ("The issuer attribute to verify against or to issue"),
1000 &issuer_attr),
1001 GNUNET_GETOPT_option_string ('T',
1002 "ttl",
1003 "EXP",
1004 gettext_noop (
1005 "The time to live for the credential."
1006 "e.g. 5m, 6h, \"1990-12-30 12:00:00\""),
1007 &expiration),
1008 GNUNET_GETOPT_option_flag ('g',
1009 "collect",
1010 gettext_noop ("collect credentials"),
1011 &collect),
1012 GNUNET_GETOPT_option_flag ('U',
1013 "createIssuerSide",
1014 gettext_noop (
1015 "Create and issue a credential issuer side."),
1016 &create_is),
1017 GNUNET_GETOPT_option_flag ('C',
1018 "createSubjectSide",
1019 gettext_noop (
1020 "Issue a credential subject side."),
1021 &create_ss),
1022 GNUNET_GETOPT_option_flag (
1023 'S',
1024 "signSubjectSide",
1025 gettext_noop ("Create, sign and return a credential subject side."),
1026 &sign_ss),
1027 GNUNET_GETOPT_option_string (
1028 'x',
1029 "import",
1030 "IMP",
1031 gettext_noop (
1032 "Import signed credentials that should be issued to a zone/ego"),
1033 &import),
1034 GNUNET_GETOPT_option_flag ('P',
1035 "private",
1036 gettext_noop ("Create private record entry."),
1037 &is_private),
1038 GNUNET_GETOPT_option_flag (
1039 'F',
1040 "forward",
1041 gettext_noop (
1042 "Indicates that the collect/verify process is done via forward search."),
1043 &forward),
1044 GNUNET_GETOPT_option_flag (
1045 'B',
1046 "backward",
1047 gettext_noop (
1048 "Indicates that the collect/verify process is done via forward search."),
1049 &backward),
1050 GNUNET_GETOPT_OPTION_END};
1051
1052
1053 timeout = GNUNET_TIME_UNIT_FOREVER_REL;
1054 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
1055 return 2;
1056
1057 GNUNET_log_setup ("gnunet-abd", "WARNING", NULL);
1058 if (GNUNET_OK != GNUNET_PROGRAM_run (argc,
1059 argv,
1060 "gnunet-abd",
1061 _ ("GNUnet abd resolver tool"),
1062 options,
1063 &run,
1064 NULL))
1065 ret = 1;
1066 GNUNET_free ((void *) argv);
1067 return ret;
1068}
1069
1070/* end of gnunet-abd.c */