GNUnet  0.10.x
gnunet-credential.c
Go to the documentation of this file.
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 */
25 #include "platform.h"
26 #include <gnunet_util_lib.h>
28 #include <gnunet_gnsrecord_lib.h>
29 #include "credential_misc.h"
31 
35 static const struct GNUNET_CONFIGURATION_Handle *cfg;
36 
41 
46 
51 
56 
61 
65 static struct GNUNET_SCHEDULER_Task *tt;
66 
70 static char *subject_key;
71 
75 static char *subject_credential;
76 
80 static char *expiration;
81 
86 
91 
92 
96 static char *issuer_key;
97 
101 static char *ego_name;
102 
106 static char *issuer_attr;
107 
111 static int verify;
112 
116 static int create_cred;
117 
121 static int collect;
122 
128 static void
129 do_shutdown (void *cls)
130 {
131  if (NULL != verify_request)
132  {
133  GNUNET_CREDENTIAL_request_cancel (verify_request);
134  verify_request = NULL;
135  }
136  if (NULL != credential)
137  {
138  GNUNET_CREDENTIAL_disconnect (credential);
139  credential = NULL;
140  }
141  if (NULL != tt)
142  {
144  tt = NULL;
145  }
146 }
147 
148 
154 static void
155 do_timeout (void *cls)
156 {
157  tt = NULL;
159 }
160 
161 static void
163  unsigned int d_count,
165  unsigned int c_count,
166  struct GNUNET_CREDENTIAL_Credential *cred)
167 {
168  int i;
169  char* line;
170 
171  verify_request = NULL;
172  if (NULL != cred)
173  {
174  for (i=0;i<c_count;i++)
175  {
176  line = GNUNET_CREDENTIAL_credential_to_string (&cred[i]);
177  printf ("%s\n",
178  line);
179  GNUNET_free (line);
180  }
181  }
182 
183 
185 }
186 
187 
188 static void
190  unsigned int d_count,
192  unsigned int c_count,
193  struct GNUNET_CREDENTIAL_Credential *cred)
194 {
195  int i;
196  char* iss_key;
197  char* sub_key;
198 
199  verify_request = NULL;
200  if (NULL == cred)
201  printf ("Failed.\n");
202  else
203  {
204  printf("Delegation Chain:\n");
205  for (i=0;i<d_count;i++)
206  {
209  if (0 != dc[i].subject_attribute_len)
210  {
211  printf ("(%d) %s.%s <- %s.%s\n", i,
212  iss_key, dc[i].issuer_attribute,
213  sub_key, dc[i].subject_attribute);
214  } else {
215  printf ("(%d) %s.%s <- %s\n", i,
216  iss_key, dc[i].issuer_attribute,
217  sub_key);
218  }
219  GNUNET_free (iss_key);
220  GNUNET_free (sub_key);
221  }
222  printf("\nCredentials:\n");
223  for (i=0;i<c_count;i++)
224  {
227  printf ("%s.%s <- %s\n",
228  iss_key, cred[i].issuer_attribute,
229  sub_key);
230  GNUNET_free (iss_key);
231  GNUNET_free (sub_key);
232 
233  }
234  printf ("Successful.\n");
235  }
236 
237 
239 }
240 
248 static void
249 identity_cb (void *cls,
250  const struct GNUNET_IDENTITY_Ego *ego)
251 {
252  const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
253  struct GNUNET_CREDENTIAL_Credential *crd;
254  struct GNUNET_TIME_Absolute etime_abs;
255  struct GNUNET_TIME_Relative etime_rel;
256  char *res;
257 
258  el = NULL;
259  if (NULL == ego)
260  {
261  if (NULL != ego_name)
262  {
263  fprintf (stderr,
264  _("Ego `%s' not known to identity service\n"),
265  ego_name);
266  }
268  return;
269  }
270 
271  if (GNUNET_YES == collect)
272  {
273 
274  if (GNUNET_OK !=
276  strlen (issuer_key),
277  &issuer_pkey))
278  {
279  fprintf (stderr,
280  _("Issuer public key `%s' is not well-formed\n"),
281  issuer_key);
283  }
284  privkey = GNUNET_IDENTITY_ego_get_private_key (ego);
285 
286  collect_request = GNUNET_CREDENTIAL_collect(credential,
287  &issuer_pkey,
288  issuer_attr, //TODO argument
289  privkey,
291  NULL);
292  return;
293  }
294 
295  //Else issue
296 
297  if (NULL == expiration)
298  {
299  fprintf (stderr,
300  "Please specify a TTL\n");
302  return;
304  &etime_rel))
305  {
306  etime_abs = GNUNET_TIME_relative_to_absolute (etime_rel);
308  &etime_abs))
309  {
310  fprintf (stderr,
311  "%s is not a valid ttl!\n",
312  expiration);
314  return;
315  }
316 
317 
318  privkey = GNUNET_IDENTITY_ego_get_private_key (ego);
320  ego_name = NULL;
321  crd = GNUNET_CREDENTIAL_credential_issue (privkey,
322  &subject_pkey,
323  issuer_attr,
324  &etime_abs);
325 
327  GNUNET_free (crd);
328  printf ("%s\n", res);
330 }
331 
332 
333 
334 
343 static void
344 run (void *cls,
345  char *const *args,
346  const char *cfgfile,
347  const struct GNUNET_CONFIGURATION_Handle *c)
348 {
349 
350  cfg = c;
351 
352 
354  &do_timeout, NULL);
356 
357  if (GNUNET_YES == collect) {
358  if (NULL == issuer_key)
359  {
360  fprintf (stderr,
361  _("Issuer public key not well-formed\n"));
363  return;
364 
365  }
366 
367  credential = GNUNET_CREDENTIAL_connect (cfg);
368 
369  if (NULL == credential)
370  {
371  fprintf (stderr,
372  _("Failed to connect to CREDENTIAL\n"));
374  return;
375  }
376  if (NULL == issuer_attr)
377  {
378  fprintf (stderr,
379  _("You must provide issuer the attribute\n"));
381  return;
382  }
383 
384  if (NULL == ego_name)
385  {
386  fprintf (stderr,
387  _("ego required\n"));
389  return;
390 
391  }
392  el = GNUNET_IDENTITY_ego_lookup (cfg,
393  ego_name,
394  &identity_cb,
395  (void *) cfg);
396  return;
397 
398  }
399 
400  if (NULL == subject_key)
401  {
402  fprintf (stderr,
403  _("Subject public key needed\n"));
405  return;
406 
407  }
408  if (GNUNET_OK !=
410  strlen (subject_key),
411  &subject_pkey))
412  {
413  fprintf (stderr,
414  _("Subject public key `%s' is not well-formed\n"),
415  subject_key);
417  return;
418  }
419  if (GNUNET_YES == verify) {
420  if (NULL == issuer_key)
421  {
422  fprintf (stderr,
423  _("Issuer public key not well-formed\n"));
425  return;
426 
427  }
428  if (GNUNET_OK !=
430  strlen (issuer_key),
431  &issuer_pkey))
432  {
433  fprintf (stderr,
434  _("Issuer public key `%s' is not well-formed\n"),
435  issuer_key);
437  return;
438  }
439  credential = GNUNET_CREDENTIAL_connect (cfg);
440 
441  if (NULL == credential)
442  {
443  fprintf (stderr,
444  _("Failed to connect to CREDENTIAL\n"));
446  return;
447  }
448  if (NULL == issuer_attr || NULL == subject_credential)
449  {
450  fprintf (stderr,
451  _("You must provide issuer and subject attributes\n"));
453  return;
454  }
455 
456  //Subject credentials are comma separated
457  char *tmp = GNUNET_strdup (subject_credential);
458  char *tok = strtok (tmp, ",");
459  if (NULL == tok)
460  {
461  fprintf (stderr,
462  "Invalid subject credentials\n");
463  GNUNET_free (tmp);
465  return;
466  }
467  int count = 1;
468  int i;
469  while (NULL != (tok = strtok(NULL, ",")))
470  count++;
471  struct GNUNET_CREDENTIAL_Credential credentials[count];
472  struct GNUNET_CREDENTIAL_Credential *cred;
473  GNUNET_free (tmp);
475  tok = strtok (tmp, ",");
476  for (i=0;i<count;i++)
477  {
479  GNUNET_memcpy (&credentials[i],
480  cred,
481  sizeof (struct GNUNET_CREDENTIAL_Credential));
482  credentials[i].issuer_attribute = GNUNET_strdup (cred->issuer_attribute);
483  tok = strtok(NULL, ",");
484  GNUNET_free (cred);
485  }
486 
487  verify_request = GNUNET_CREDENTIAL_verify(credential,
488  &issuer_pkey,
489  issuer_attr, //TODO argument
490  &subject_pkey,
491  count,
492  credentials,
494  NULL);
495  for (i=0;i<count;i++)
496  {
497  GNUNET_free ((char*)credentials[i].issuer_attribute);
498  }
499  GNUNET_free (tmp);
500  } else if (GNUNET_YES == create_cred) {
501  if (NULL == ego_name)
502  {
503  fprintf (stderr,
504  _("Issuer ego required\n"));
506  return;
507 
508  }
509  el = GNUNET_IDENTITY_ego_lookup (cfg,
510  ego_name,
511  &identity_cb,
512  (void *) cfg);
513  return;
514  } else {
515  fprintf (stderr,
516  _("Please specify name to lookup, subject key and issuer key!\n"));
518  }
519  return;
520 }
521 
522 
530 int
531 main (int argc, char *const *argv)
532 {
533  struct GNUNET_GETOPT_CommandLineOption options[] = {
535  "issue",
536  gettext_noop ("create credential"),
537  &create_cred),
539  "verify",
540  gettext_noop ("verify credential against attribute"),
541  &verify),
543  "subject",
544  "PKEY",
545  gettext_noop ("The public key of the subject to lookup the credential for"),
546  &subject_key),
548  "credential",
549  "CRED",
550  gettext_noop ("The name of the credential presented by the subject"),
553  "issuer",
554  "PKEY",
555  gettext_noop ("The public key of the authority to verify the credential against"),
556  &issuer_key),
558  "ego",
559  "EGO",
560  gettext_noop ("The ego to use"),
561  &ego_name),
563  "attribute",
564  "ATTR",
565  gettext_noop ("The issuer attribute to verify against or to issue"),
566  &issuer_attr),
568  "ttl",
569  "EXP",
570  gettext_noop ("The time to live for the credential"),
571  &expiration),
573  "collect",
574  gettext_noop ("collect credentials"),
575  &collect),
577  };
578  int ret;
579 
581  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
582  return 2;
583 
584  GNUNET_log_setup ("gnunet-credential", "WARNING", NULL);
585  ret =
586  (GNUNET_OK ==
587  GNUNET_PROGRAM_run (argc, argv, "gnunet-credential",
588  _("GNUnet credential resolver tool"),
589  options,
590  &run, NULL)) ? 0 : 1;
591  GNUNET_free ((void*) argv);
592  return ret;
593 }
594 
595 /* end of gnunet-credential.c */
struct GNUNET_CRYPTO_EcdsaPublicKey issuer_pkey
Issuer key.
static void handle_collect_result(void *cls, unsigned int d_count, struct GNUNET_CREDENTIAL_Delegation *dc, unsigned int c_count, struct GNUNET_CREDENTIAL_Credential *cred)
static char * subject_credential
Subject credential string.
struct GNUNET_CREDENTIAL_Credential * GNUNET_CREDENTIAL_credential_from_string(const char *s)
static char * expiration
Credential TTL.
Handle for ego lookup.
static struct GNUNET_SCHEDULER_Task * tt
Task scheduled to handle timeout.
void GNUNET_CREDENTIAL_request_cancel(struct GNUNET_CREDENTIAL_Request *lr)
Cancel pending verify request.
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Main function that will be run.
static struct GNUNET_CREDENTIAL_Handle * credential
Handle to Credential service.
static struct GNUNET_IDENTITY_EgoLookup * el
EgoLookup.
static void handle_verify_result(void *cls, unsigned int d_count, struct GNUNET_CREDENTIAL_Delegation *dc, unsigned int c_count, struct GNUNET_CREDENTIAL_Credential *cred)
static int collect
Collect mode.
int main(int argc, char *const *argv)
The main function for gnunet-gns.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1293
static char * subject_key
Subject pubkey string.
int GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1521
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:245
int GNUNET_STRINGS_fancy_time_to_relative(const char *fancy_time, struct GNUNET_TIME_Relative *rtime)
Convert a given fancy human-readable time to our internal representation.
Definition: strings.c:353
const struct GNUNET_CRYPTO_EcdsaPrivateKey * GNUNET_IDENTITY_ego_get_private_key(const struct GNUNET_IDENTITY_Ego *ego)
Obtain the ECC key associated with a ego.
Definition: identity_api.c:556
API to serialize and deserialize delegation chains and credentials.
int GNUNET_STRINGS_fancy_time_to_absolute(const char *fancy_time, struct GNUNET_TIME_Absolute *atime)
Convert a given fancy human-readable time to our internal representation.
Definition: strings.c:408
static void identity_cb(void *cls, const struct GNUNET_IDENTITY_Ego *ego)
Callback invoked from identity service with ego information.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
static int create_cred
Issue mode.
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
Definition of a command line option.
Private ECC key encoded for transmission.
static struct GNUNET_CREDENTIAL_Request * collect_request
Handle to collect request.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:524
static int ret
Final status code.
Definition: gnunet-arm.c:89
struct GNUNET_CRYPTO_EcdsaPublicKey subject_pkey
Subject key.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
static struct GNUNET_TIME_Relative timeout
Desired timeout for the lookup (default is no timeout).
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_string(char shortName, const char *name, const char *argumentHelp, const char *description, char **str)
Allow user to specify a string.
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
void GNUNET_CREDENTIAL_disconnect(struct GNUNET_CREDENTIAL_Handle *handle)
Shutdown connection with the CREDENTIAL service.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1246
Handle for an ego.
Definition: identity.h:245
static int verify
Verify mode.
#define GNUNET_memcpy(dst, src, n)
static char * line
Desired phone line (string to be converted to a hash).
struct GNUNET_CREDENTIAL_Handle * GNUNET_CREDENTIAL_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the connection with the CREDENTIAL service.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
static void do_shutdown(void *cls)
Task run on shutdown.
Connection to the CREDENTIAL service.
static int res
struct GNUNET_CREDENTIAL_Request * GNUNET_CREDENTIAL_collect(struct GNUNET_CREDENTIAL_Handle *handle, const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key, const char *issuer_attribute, const struct GNUNET_CRYPTO_EcdsaPrivateKey *subject_key, GNUNET_CREDENTIAL_CredentialResultProcessor proc, void *proc_cls)
Performs attribute collection.
char * GNUNET_CRYPTO_ecdsa_public_key_to_string(const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Convert a public key to a string.
Definition: crypto_ecc.c:334
Handle to a verify request.
char * GNUNET_CREDENTIAL_credential_to_string(const struct GNUNET_CREDENTIAL_Credential *cred)
static char * ego_name
ego
static char * issuer_key
Issuer pubkey string.
const char * issuer_attribute
The attribute.
struct GNUNET_IDENTITY_EgoLookup * GNUNET_IDENTITY_ego_lookup(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *name, GNUNET_IDENTITY_EgoCallback cb, void *cb_cls)
Lookup an ego by name.
int GNUNET_CRYPTO_ecdsa_public_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Convert a string representing a public key to a public key.
Definition: crypto_ecc.c:468
configuration data
Definition: configuration.c:85
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_flag(char shortName, const char *name, const char *description, int *val)
Allow user to specify a flag (which internally means setting an integer to 1/GNUNET_YES/GNUNET_OK.
Credential helper functions.
Entry in list of pending tasks.
Definition: scheduler.c:134
struct GNUNET_CREDENTIAL_Credential * GNUNET_CREDENTIAL_credential_issue(const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, struct GNUNET_CRYPTO_EcdsaPublicKey *subject, const char *attribute, struct GNUNET_TIME_Absolute *expiration)
Issue an attribute to a subject.
int GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration, parse options).
Definition: program.c:361
static struct GNUNET_CREDENTIAL_Request * verify_request
Handle to verify request.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:80
int GNUNET_log_setup(const char *comp, const char *loglevel, const char *logfile)
Setup logging.
struct GNUNET_CREDENTIAL_Request * GNUNET_CREDENTIAL_verify(struct GNUNET_CREDENTIAL_Handle *handle, const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key, const char *issuer_attribute, const struct GNUNET_CRYPTO_EcdsaPublicKey *subject_key, uint32_t credential_count, const struct GNUNET_CREDENTIAL_Credential *credentials, GNUNET_CREDENTIAL_CredentialResultProcessor proc, void *proc_cls)
Performs attribute verification.
static char * issuer_attr
Issuer attribute.
static void do_timeout(void *cls)
Task run on timeout.
static struct GNUNET_FS_DownloadContext * dc
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
#define gettext_noop(String)
Definition: gettext.h:69
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965