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.c1100
1 files changed, 0 insertions, 1100 deletions
diff --git a/src/abd/gnunet-abd.c b/src/abd/gnunet-abd.c
deleted file mode 100644
index b1fb767e3..000000000
--- a/src/abd/gnunet-abd.c
+++ /dev/null
@@ -1,1100 +0,0 @@
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
271
272static void
273handle_intermediate_result (void *cls,
274 struct GNUNET_ABD_Delegation *dd,
275 bool is_bw)
276{
277 char *prefix = "";
278 if (is_bw)
279 prefix = "Backward -";
280 else
281 prefix = "Forward -";
282
283 printf ("%s Intermediate result: %s.%s <- %s.%s\n",
284 prefix,
285 GNUNET_CRYPTO_ecdsa_public_key_to_string (&dd->issuer_key),
286 dd->issuer_attribute,
287 GNUNET_CRYPTO_ecdsa_public_key_to_string (&dd->subject_key),
288 dd->subject_attribute);
289}
290
291
292static void
293handle_collect_result (void *cls,
294 unsigned int d_count,
295 struct GNUNET_ABD_Delegation *dc,
296 unsigned int c_count,
297 struct GNUNET_ABD_Delegate *dele)
298{
299 int i;
300 char *line;
301
302 verify_request = NULL;
303 if (NULL != dele)
304 {
305 for (i = 0; i < c_count; i++)
306 {
307 line = GNUNET_ABD_delegate_to_string (&dele[i]);
308 printf ("%s\n", line);
309 GNUNET_free (line);
310 }
311 }
312 else
313 {
314 printf ("Received NULL\n");
315 }
316
317 GNUNET_SCHEDULER_shutdown ();
318}
319
320
321static void
322handle_verify_result (void *cls,
323 unsigned int d_count,
324 struct GNUNET_ABD_Delegation *dc,
325 unsigned int c_count,
326 struct GNUNET_ABD_Delegate *dele)
327{
328 int i;
329 char *iss_key;
330 char *sub_key;
331
332 verify_request = NULL;
333 if (NULL == dele)
334 ret = 1;
335 else
336 {
337 printf ("Delegation Chain:\n");
338 for (i = 0; i < d_count; i++)
339 {
340 iss_key = GNUNET_CRYPTO_ecdsa_public_key_to_string (&dc[i].issuer_key);
341 sub_key = GNUNET_CRYPTO_ecdsa_public_key_to_string (&dc[i].subject_key);
342
343 if (0 != dc[i].subject_attribute_len)
344 {
345 printf ("(%d) %s.%s <- %s.%s\n",
346 i,
347 iss_key,
348 dc[i].issuer_attribute,
349 sub_key,
350 dc[i].subject_attribute);
351 }
352 else
353 {
354 printf ("(%d) %s.%s <- %s\n",
355 i,
356 iss_key,
357 dc[i].issuer_attribute,
358 sub_key);
359 }
360 GNUNET_free (iss_key);
361 GNUNET_free (sub_key);
362 }
363 printf ("\nDelegate(s):\n");
364 for (i = 0; i < c_count; i++)
365 {
366 iss_key = GNUNET_CRYPTO_ecdsa_public_key_to_string (&dele[i].issuer_key);
367 sub_key = GNUNET_CRYPTO_ecdsa_public_key_to_string (&dele[i].subject_key);
368 printf ("%s.%s <- %s\n", iss_key, dele[i].issuer_attribute, sub_key);
369 GNUNET_free (iss_key);
370 GNUNET_free (sub_key);
371 }
372 printf ("Successful.\n");
373 }
374
375 GNUNET_SCHEDULER_shutdown ();
376}
377
378
379/**
380 * Callback invoked from identity service with ego information.
381 * An @a ego of NULL means the ego was not found.
382 *
383 * @param cls closure with the configuration
384 * @param ego an ego known to identity service, or NULL
385 */
386static void
387identity_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego)
388{
389 const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
390
391 el = NULL;
392 if (NULL == ego)
393 {
394 if (NULL != ego_name)
395 {
396 fprintf (stderr,
397 _ ("Ego `%s' not known to identity service\n"),
398 ego_name);
399 }
400 GNUNET_SCHEDULER_shutdown ();
401 return;
402 }
403
404 if (GNUNET_YES == collect)
405 {
406
407 if (GNUNET_OK !=
408 GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_key,
409 strlen (issuer_key),
410 &issuer_pkey))
411 {
412 fprintf (stderr,
413 _ ("Issuer public key `%s' is not well-formed\n"),
414 issuer_key);
415 GNUNET_SCHEDULER_shutdown ();
416 }
417 privkey = GNUNET_IDENTITY_ego_get_private_key (ego);
418
419 collect_request = GNUNET_ABD_collect (abd,
420 &issuer_pkey,
421 issuer_attr,
422 privkey,
423 direction,
424 &handle_collect_result,
425 NULL,
426 &handle_intermediate_result,
427 NULL);
428 return;
429 }
430 GNUNET_SCHEDULER_shutdown ();
431}
432
433
434/**
435 * Parse expiration time.
436 *
437 * @param expirationstring text to parse
438 * @param etime_is_rel[out] set to #GNUNET_YES if time is relative
439 * @param etime[out] set to expiration time (abs or rel)
440 * @return #GNUNET_OK on success
441 */
442static int
443parse_expiration (const char *expirationstring,
444 int *etime_is_rel,
445 uint64_t *etime)
446{
447 // copied from namestore/gnunet-namestore.c
448 struct GNUNET_TIME_Relative etime_rel;
449 struct GNUNET_TIME_Absolute etime_abs;
450
451 if (0 == strcmp (expirationstring, "never"))
452 {
453 *etime = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
454 *etime_is_rel = GNUNET_NO;
455 return GNUNET_OK;
456 }
457 if (GNUNET_OK ==
458 GNUNET_STRINGS_fancy_time_to_relative (expirationstring, &etime_rel))
459 {
460 *etime_is_rel = GNUNET_YES;
461 *etime = etime_rel.rel_value_us;
462 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
463 "Storing record with relative expiration time of %s\n",
464 GNUNET_STRINGS_relative_time_to_string (etime_rel, GNUNET_NO));
465 return GNUNET_OK;
466 }
467 if (GNUNET_OK ==
468 GNUNET_STRINGS_fancy_time_to_absolute (expirationstring, &etime_abs))
469 {
470 *etime_is_rel = GNUNET_NO;
471 *etime = etime_abs.abs_value_us;
472 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
473 "Storing record with absolute expiration time of %s\n",
474 GNUNET_STRINGS_absolute_time_to_string (etime_abs));
475 return GNUNET_OK;
476 }
477 return GNUNET_SYSERR;
478}
479
480
481/**
482 * Function called if lookup fails.
483 */
484static void
485error_cb (void *cls)
486{
487 fprintf (stderr, "Error occurred during lookup, shutting down.\n");
488 GNUNET_SCHEDULER_shutdown ();
489 return;
490}
491
492
493static void
494add_continuation (void *cls, int32_t success, const char *emsg)
495{
496 struct GNUNET_NAMESTORE_QueueEntry **qe = cls;
497 *qe = NULL;
498
499 if (GNUNET_OK == success)
500 printf ("Adding successful.\n");
501 else
502 fprintf (stderr, "Error occurred during adding, shutting down.\n");
503
504 GNUNET_SCHEDULER_shutdown ();
505}
506
507
508static void
509get_existing_record (void *cls,
510 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
511 const char *rec_name,
512 unsigned int rd_count,
513 const struct GNUNET_GNSRECORD_Data *rd)
514{
515 struct GNUNET_GNSRECORD_Data *rde;
516 struct GNUNET_GNSRECORD_Data*rdn =
517 GNUNET_malloc (sizeof(*rdn) * (rd_count + 1));
518
519 memset (rdn, 0, sizeof (struct GNUNET_GNSRECORD_Data));
520 GNUNET_memcpy (&rdn[1], rd,
521 rd_count * sizeof (struct GNUNET_GNSRECORD_Data));
522 rde = &rdn[0];
523 rde->data = data;
524 rde->data_size = data_size;
525 rde->record_type = type;
526
527 // Set flags
528 if (GNUNET_YES == is_private)
529 rde->flags |= GNUNET_GNSRECORD_RF_PRIVATE;
530 rde->expiration_time = etime;
531 if (GNUNET_YES == etime_is_rel)
532 rde->flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
533 else if (GNUNET_NO != etime_is_rel)
534 rde->expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
535
536 GNUNET_assert (NULL != rec_name);
537 add_qe = GNUNET_NAMESTORE_records_store (ns,
538 &zone_pkey,
539 rec_name,
540 rd_count + 1,
541 rde,
542 &add_continuation,
543 &add_qe);
544 GNUNET_free (rdn);
545 return;
546}
547
548
549static void
550store_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego)
551{
552 const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
553
554 el = NULL;
555
556 ns = GNUNET_NAMESTORE_connect (cfg);
557 if (NULL == ns)
558 {
559 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
560 _ ("Failed to connect to namestore\n"));
561 GNUNET_SCHEDULER_shutdown ();
562 return;
563 }
564
565 // Key handling
566 zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego);
567
568 if (GNUNET_GNSRECORD_TYPE_DELEGATE == type)
569 {
570 // Parse import
571 struct GNUNET_ABD_Delegate *cred;
572 cred = GNUNET_ABD_delegate_from_string (import);
573
574 // Get import subject public key string
575 char *subject_pubkey_str =
576 GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->subject_key);
577
578 // Get zone public key string
579 struct GNUNET_CRYPTO_EcdsaPublicKey zone_pubkey;
580 GNUNET_IDENTITY_ego_get_public_key (ego, &zone_pubkey);
581 char *zone_pubkey_str =
582 GNUNET_CRYPTO_ecdsa_public_key_to_string (&zone_pubkey);
583
584 // Check if the subject key in the signed import matches the zone's key it is issued to
585 if (strcmp (zone_pubkey_str, subject_pubkey_str) != 0)
586 {
587 fprintf (stderr,
588 "Import signed delegate does not match this ego's public key.\n");
589 GNUNET_SCHEDULER_shutdown ();
590 return;
591 }
592
593 // Expiration
594 etime = cred->expiration.abs_value_us;
595 etime_is_rel = GNUNET_NO;
596
597 // Prepare the data to be store in the record
598 data_size = GNUNET_ABD_delegate_serialize (cred, (char **) &data);
599 GNUNET_free (cred);
600 }
601 else
602 {
603 // For all other types e.g. GNUNET_GNSRECORD_TYPE_ATTRIBUTE
604 if (GNUNET_OK !=
605 GNUNET_GNSRECORD_string_to_value (type, subject, &data, &data_size))
606 {
607 if (typestring == NULL)
608 {
609 fputs ("No value for unknown record type\n", stderr);
610 }
611 else if (subject == NULL)
612 {
613 fprintf (stderr,
614 "No value for record type`%s'\n",
615 typestring);
616 }
617 else
618 {
619 fprintf (stderr,
620 "Value `%s' invalid for record type `%s'\n",
621 subject,
622 typestring);
623 }
624 GNUNET_SCHEDULER_shutdown ();
625 return;
626 }
627
628 // Take care of expiration
629 if (NULL == expiration)
630 {
631 fprintf (stderr, "Missing option -e for operation 'create'\n");
632 GNUNET_SCHEDULER_shutdown ();
633 return;
634 }
635 if (GNUNET_OK != parse_expiration (expiration, &etime_is_rel, &etime))
636 {
637 fprintf (stderr, "Invalid time format `%s'\n", expiration);
638 GNUNET_SCHEDULER_shutdown ();
639 return;
640 }
641 }
642
643 // Start lookup
644 add_qe = GNUNET_NAMESTORE_records_lookup (ns,
645 &zone_pkey,
646 record_label,
647 &error_cb,
648 NULL,
649 &get_existing_record,
650 NULL);
651 return;
652}
653
654
655static void
656sign_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego)
657{
658 const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
659 struct GNUNET_ABD_Delegate *dele;
660 struct GNUNET_TIME_Absolute etime_abs;
661 char *res;
662
663 el = NULL;
664
665 // work on expiration time
666 if (NULL == expiration)
667 {
668 fprintf (stderr, "Please specify a TTL\n");
669 GNUNET_SCHEDULER_shutdown ();
670 return;
671 }
672 else if (GNUNET_OK !=
673 GNUNET_STRINGS_fancy_time_to_absolute (expiration, &etime_abs))
674 {
675 fprintf (stderr,
676 "%s is not a valid ttl! Only absolute times are accepted!\n",
677 expiration);
678 GNUNET_SCHEDULER_shutdown ();
679 return;
680 }
681
682 // If contains a space - split it by the first space only - assume first entry is subject followed by attribute(s)
683 char *subject_pubkey_str;
684 char *subject_attr = NULL;
685 char *token;
686
687 // Subject Public Key
688 token = strtok (subject, " ");
689 if (key_length == strlen (token))
690 {
691 subject_pubkey_str = token;
692 }
693 else
694 {
695 fprintf (stderr, "Key error, wrong length: %ld!\n", strlen (token));
696 GNUNET_SCHEDULER_shutdown ();
697 return;
698 }
699 // Subject Attribute(s)
700 token = strtok (NULL, " ");
701 if (NULL != token)
702 {
703 subject_attr = token;
704 }
705
706 // work on keys
707 privkey = GNUNET_IDENTITY_ego_get_private_key (ego);
708
709 if (GNUNET_OK !=
710 GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_pubkey_str,
711 strlen (subject_pubkey_str),
712 &subject_pkey))
713 {
714 fprintf (stderr,
715 "Subject public key `%s' is not well-formed\n",
716 subject_pubkey_str);
717 GNUNET_SCHEDULER_shutdown ();
718 return;
719 }
720
721 // Sign delegate
722 dele = GNUNET_ABD_delegate_issue (privkey,
723 &subject_pkey,
724 issuer_attr,
725 subject_attr,
726 &etime_abs);
727 res = GNUNET_ABD_delegate_to_string (dele);
728 GNUNET_free (dele);
729 printf ("%s\n", res);
730
731 GNUNET_free (ego_name);
732 ego_name = NULL;
733
734 GNUNET_SCHEDULER_shutdown ();
735}
736
737
738/**
739 * Main function that will be run.
740 *
741 * @param cls closure
742 * @param args remaining command-line arguments
743 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
744 * @param c configuration
745 */
746static void
747run (void *cls,
748 char *const *args,
749 const char *cfgfile,
750 const struct GNUNET_CONFIGURATION_Handle *c)
751{
752 cfg = c;
753
754 tt = GNUNET_SCHEDULER_add_delayed (timeout, &do_timeout, NULL);
755 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
756
757 // Check relevant cmdline parameters
758 if (GNUNET_YES == create_is)
759 {
760 if (NULL == ego_name)
761 {
762 fprintf (stderr, "Missing option '-ego'\n");
763 GNUNET_SCHEDULER_shutdown ();
764 return;
765 }
766 if (NULL == issuer_attr)
767 {
768 fprintf (stderr, "Missing option '-attribute' for issuer attribute\n");
769 GNUNET_SCHEDULER_shutdown ();
770 return;
771 }
772 if (NULL == subject)
773 {
774 fprintf (stderr, "Missing option -subject for operation 'create'.'\n");
775 GNUNET_SCHEDULER_shutdown ();
776 return;
777 }
778
779 // Lookup ego, on success call store_cb and store as ATTRIBUTE type
780 type = GNUNET_GNSRECORD_TYPE_ATTRIBUTE;
781 record_label = issuer_attr;
782 el = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, &store_cb, (void *) cfg);
783 return;
784 }
785
786 if (GNUNET_YES == create_ss)
787 {
788
789 // check if signed parameter has been passed in cmd line call
790 if (NULL == import)
791 {
792 fprintf (stderr, "'import' required\n");
793 GNUNET_SCHEDULER_shutdown ();
794 return;
795 }
796
797 type = GNUNET_GNSRECORD_TYPE_DELEGATE;
798 record_label = GNUNET_GNS_EMPTY_LABEL_AT;
799 // Store subject side
800 el = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, &store_cb, (void *) cfg);
801
802 return;
803 }
804
805 if (GNUNET_YES == sign_ss)
806 {
807 if (NULL == ego_name)
808 {
809 fprintf (stderr, "ego required\n");
810 GNUNET_SCHEDULER_shutdown ();
811 return;
812 }
813 if (NULL == subject)
814 {
815 fprintf (stderr, "Subject public key needed\n");
816 GNUNET_SCHEDULER_shutdown ();
817 return;
818 }
819
820 // lookup ego and call function sign_cb on success
821 el = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, &sign_cb, (void *) cfg);
822 return;
823 }
824
825 if ((GNUNET_NO == forward) && (GNUNET_NO == backward))
826 {
827 // set default: bidirectional
828 forward = GNUNET_YES;
829 backward = GNUNET_YES;
830 }
831 if (GNUNET_YES == forward)
832 direction |= GNUNET_ABD_FLAG_FORWARD;
833 if (GNUNET_YES == backward)
834 direction |= GNUNET_ABD_FLAG_BACKWARD;
835
836 if (GNUNET_YES == collect)
837 {
838 if (NULL == issuer_key)
839 {
840 fprintf (stderr, _ ("Issuer public key not well-formed\n"));
841 GNUNET_SCHEDULER_shutdown ();
842 return;
843 }
844
845 abd = GNUNET_ABD_connect (cfg);
846
847 if (NULL == abd)
848 {
849 fprintf (stderr, _ ("Failed to connect to ABD\n"));
850 GNUNET_SCHEDULER_shutdown ();
851 return;
852 }
853 if (NULL == issuer_attr)
854 {
855 fprintf (stderr, _ ("You must provide issuer the attribute\n"));
856 GNUNET_SCHEDULER_shutdown ();
857 return;
858 }
859
860 if (NULL == ego_name)
861 {
862 fprintf (stderr, _ ("ego required\n"));
863 GNUNET_SCHEDULER_shutdown ();
864 return;
865 }
866 el = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, &identity_cb, (void *) cfg);
867 return;
868 }
869
870 if (NULL == subject)
871 {
872 fprintf (stderr, _ ("Subject public key needed\n"));
873 GNUNET_SCHEDULER_shutdown ();
874 return;
875 }
876 if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_public_key_from_string (subject,
877 strlen (subject),
878 &subject_pkey))
879 {
880 fprintf (stderr,
881 _ ("Subject public key `%s' is not well-formed\n"),
882 subject);
883 GNUNET_SCHEDULER_shutdown ();
884 return;
885 }
886
887 if (GNUNET_YES == verify)
888 {
889 if (NULL == issuer_key)
890 {
891 fprintf (stderr, _ ("Issuer public key not well-formed\n"));
892 GNUNET_SCHEDULER_shutdown ();
893 return;
894 }
895 if (GNUNET_OK !=
896 GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_key,
897 strlen (issuer_key),
898 &issuer_pkey))
899 {
900 fprintf (stderr,
901 _ ("Issuer public key `%s' is not well-formed\n"),
902 issuer_key);
903 GNUNET_SCHEDULER_shutdown ();
904 return;
905 }
906 abd = GNUNET_ABD_connect (cfg);
907
908 if (NULL == abd)
909 {
910 fprintf (stderr, _ ("Failed to connect to ABD\n"));
911 GNUNET_SCHEDULER_shutdown ();
912 return;
913 }
914 if ((NULL == issuer_attr) || (NULL == subject_delegate))
915 {
916 fprintf (stderr, _ ("You must provide issuer and subject attributes\n"));
917 GNUNET_SCHEDULER_shutdown ();
918 return;
919 }
920
921 // Subject credentials are comma separated
922 char *tmp = GNUNET_strdup (subject_delegate);
923 char *tok = strtok (tmp, ",");
924 if (NULL == tok)
925 {
926 fprintf (stderr, "Invalid subject credentials\n");
927 GNUNET_free (tmp);
928 GNUNET_SCHEDULER_shutdown ();
929 return;
930 }
931 int count = 1;
932 int i;
933 while (NULL != (tok = strtok (NULL, ",")))
934 count++;
935 struct GNUNET_ABD_Delegate*delegates =
936 GNUNET_malloc (sizeof(*delegates) * count);
937 struct GNUNET_ABD_Delegate *dele;
938 GNUNET_free (tmp);
939 tmp = GNUNET_strdup (subject_delegate);
940 tok = strtok (tmp, ",");
941 for (i = 0; i < count; i++)
942 {
943 dele = GNUNET_ABD_delegate_from_string (tok);
944 GNUNET_memcpy (&delegates[i],
945 dele,
946 sizeof (struct GNUNET_ABD_Delegate));
947 delegates[i].issuer_attribute = GNUNET_strdup (dele->issuer_attribute);
948 tok = strtok (NULL, ",");
949 GNUNET_free (dele);
950 }
951
952 verify_request = GNUNET_ABD_verify (abd,
953 &issuer_pkey,
954 issuer_attr,
955 &subject_pkey,
956 count,
957 delegates,
958 direction,
959 &handle_verify_result,
960 NULL,
961 &handle_intermediate_result,
962 NULL);
963 for (i = 0; i < count; i++)
964 {
965 GNUNET_free_nz ((char *) delegates[i].issuer_attribute);
966 delegates[i].issuer_attribute = NULL;
967 }
968 GNUNET_free (tmp);
969 GNUNET_free (delegates);
970 }
971 else
972 {
973 fprintf (stderr,
974 _ (
975 "Please specify name to lookup, subject key and issuer key!\n"));
976 GNUNET_SCHEDULER_shutdown ();
977 }
978 return;
979}
980
981
982/**
983 * The main function for gnunet-gns.
984 *
985 * @param argc number of arguments from the command line
986 * @param argv command line arguments
987 * @return 0 ok, 1 on error
988 */
989int
990main (int argc, char *const *argv)
991{
992 struct GNUNET_GETOPT_CommandLineOption options[] =
993 {GNUNET_GETOPT_option_flag ('V',
994 "verify",
995 gettext_noop (
996 "verify credential against attribute"),
997 &verify),
998 GNUNET_GETOPT_option_string (
999 's',
1000 "subject",
1001 "PKEY",
1002 gettext_noop (
1003 "The public key of the subject to lookup the"
1004 "credential for, or for issuer side storage: subject and its attributes"),
1005 &subject),
1006 GNUNET_GETOPT_option_string (
1007 'd',
1008 "delegate",
1009 "DELE",
1010 gettext_noop ("The private, signed delegate presented by the subject"),
1011 &subject_delegate),
1012 GNUNET_GETOPT_option_string (
1013 'i',
1014 "issuer",
1015 "PKEY",
1016 gettext_noop (
1017 "The public key of the authority to verify the credential against"),
1018 &issuer_key),
1019 GNUNET_GETOPT_option_string ('e',
1020 "ego",
1021 "EGO",
1022 gettext_noop ("The ego/zone name to use"),
1023 &ego_name),
1024 GNUNET_GETOPT_option_string (
1025 'a',
1026 "attribute",
1027 "ATTR",
1028 gettext_noop ("The issuer attribute to verify against or to issue"),
1029 &issuer_attr),
1030 GNUNET_GETOPT_option_string ('T',
1031 "ttl",
1032 "EXP",
1033 gettext_noop (
1034 "The time to live for the credential."
1035 "e.g. 5m, 6h, \"1990-12-30 12:00:00\""),
1036 &expiration),
1037 GNUNET_GETOPT_option_flag ('g',
1038 "collect",
1039 gettext_noop ("collect credentials"),
1040 &collect),
1041 GNUNET_GETOPT_option_flag ('U',
1042 "createIssuerSide",
1043 gettext_noop (
1044 "Create and issue a credential issuer side."),
1045 &create_is),
1046 GNUNET_GETOPT_option_flag ('C',
1047 "createSubjectSide",
1048 gettext_noop (
1049 "Issue a credential subject side."),
1050 &create_ss),
1051 GNUNET_GETOPT_option_flag (
1052 'S',
1053 "signSubjectSide",
1054 gettext_noop ("Create, sign and return a credential subject side."),
1055 &sign_ss),
1056 GNUNET_GETOPT_option_string (
1057 'x',
1058 "import",
1059 "IMP",
1060 gettext_noop (
1061 "Import signed credentials that should be issued to a zone/ego"),
1062 &import),
1063 GNUNET_GETOPT_option_flag ('P',
1064 "private",
1065 gettext_noop ("Create private record entry."),
1066 &is_private),
1067 GNUNET_GETOPT_option_flag (
1068 'F',
1069 "forward",
1070 gettext_noop (
1071 "Indicates that the collect/verify process is done via forward search."),
1072 &forward),
1073 GNUNET_GETOPT_option_flag (
1074 'B',
1075 "backward",
1076 gettext_noop (
1077 "Indicates that the collect/verify process is done via forward search."),
1078 &backward),
1079 GNUNET_GETOPT_OPTION_END};
1080
1081
1082 timeout = GNUNET_TIME_UNIT_FOREVER_REL;
1083 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
1084 return 2;
1085
1086 GNUNET_log_setup ("gnunet-abd", "WARNING", NULL);
1087 if (GNUNET_OK != GNUNET_PROGRAM_run (argc,
1088 argv,
1089 "gnunet-abd",
1090 _ ("GNUnet abd resolver tool"),
1091 options,
1092 &run,
1093 NULL))
1094 ret = 1;
1095 GNUNET_free_nz ((void *) argv);
1096 return ret;
1097}
1098
1099
1100/* end of gnunet-abd.c */