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  }
215  else
216  {
217  printf ("(%d) %s.%s <- %s\n", i,
218  iss_key, dc[i].issuer_attribute,
219  sub_key);
220  }
221  GNUNET_free (iss_key);
222  GNUNET_free (sub_key);
223  }
224  printf ("\nCredentials:\n");
225  for (i = 0; i < c_count; i++)
226  {
229  printf ("%s.%s <- %s\n",
230  iss_key, cred[i].issuer_attribute,
231  sub_key);
232  GNUNET_free (iss_key);
233  GNUNET_free (sub_key);
234  }
235  printf ("Successful.\n");
236  }
237 
238 
240 }
241 
249 static void
250 identity_cb (void *cls,
251  const struct GNUNET_IDENTITY_Ego *ego)
252 {
253  const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
254  struct GNUNET_CREDENTIAL_Credential *crd;
255  struct GNUNET_TIME_Absolute etime_abs;
256  struct GNUNET_TIME_Relative etime_rel;
257  char *res;
258 
259  el = NULL;
260  if (NULL == ego)
261  {
262  if (NULL != ego_name)
263  {
264  fprintf (stderr,
265  _ ("Ego `%s' not known to identity service\n"),
266  ego_name);
267  }
269  return;
270  }
271 
272  if (GNUNET_YES == collect)
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;
303  }
305  &etime_rel))
306  {
307  etime_abs = GNUNET_TIME_relative_to_absolute (etime_rel);
308  }
310  &etime_abs))
311  {
312  fprintf (stderr,
313  "%s is not a valid ttl!\n",
314  expiration);
316  return;
317  }
318 
319 
320  privkey = GNUNET_IDENTITY_ego_get_private_key (ego);
322  ego_name = NULL;
323  crd = GNUNET_CREDENTIAL_credential_issue (privkey,
324  &subject_pkey,
325  issuer_attr,
326  &etime_abs);
327 
329  GNUNET_free (crd);
330  printf ("%s\n", res);
332 }
333 
334 
335 
336 
345 static void
346 run (void *cls,
347  char *const *args,
348  const char *cfgfile,
349  const struct GNUNET_CONFIGURATION_Handle *c)
350 {
351  cfg = c;
352 
353 
355  &do_timeout, NULL);
357 
358  if (GNUNET_YES == collect)
359  {
360  if (NULL == issuer_key)
361  {
362  fprintf (stderr,
363  _ ("Issuer public key not well-formed\n"));
365  return;
366  }
367 
368  credential = GNUNET_CREDENTIAL_connect (cfg);
369 
370  if (NULL == credential)
371  {
372  fprintf (stderr,
373  _ ("Failed to connect to CREDENTIAL\n"));
375  return;
376  }
377  if (NULL == issuer_attr)
378  {
379  fprintf (stderr,
380  _ ("You must provide issuer the attribute\n"));
382  return;
383  }
384 
385  if (NULL == ego_name)
386  {
387  fprintf (stderr,
388  _ ("ego required\n"));
390  return;
391  }
392  el = GNUNET_IDENTITY_ego_lookup (cfg,
393  ego_name,
394  &identity_cb,
395  (void *) cfg);
396  return;
397  }
398 
399  if (NULL == subject_key)
400  {
401  fprintf (stderr,
402  _ ("Subject public key needed\n"));
404  return;
405  }
406  if (GNUNET_OK !=
408  strlen (subject_key),
409  &subject_pkey))
410  {
411  fprintf (stderr,
412  _ ("Subject public key `%s' is not well-formed\n"),
413  subject_key);
415  return;
416  }
417  if (GNUNET_YES == verify)
418  {
419  if (NULL == issuer_key)
420  {
421  fprintf (stderr,
422  _ ("Issuer public key not well-formed\n"));
424  return;
425  }
426  if (GNUNET_OK !=
428  strlen (issuer_key),
429  &issuer_pkey))
430  {
431  fprintf (stderr,
432  _ ("Issuer public key `%s' is not well-formed\n"),
433  issuer_key);
435  return;
436  }
437  credential = GNUNET_CREDENTIAL_connect (cfg);
438 
439  if (NULL == credential)
440  {
441  fprintf (stderr,
442  _ ("Failed to connect to CREDENTIAL\n"));
444  return;
445  }
446  if ((NULL == issuer_attr) ||(NULL == subject_credential) )
447  {
448  fprintf (stderr,
449  _ ("You must provide issuer and subject attributes\n"));
451  return;
452  }
453 
454  // Subject credentials are comma separated
455  char *tmp = GNUNET_strdup (subject_credential);
456  char *tok = strtok (tmp, ",");
457  if (NULL == tok)
458  {
459  fprintf (stderr,
460  "Invalid subject credentials\n");
461  GNUNET_free (tmp);
463  return;
464  }
465  int count = 1;
466  int i;
467  while (NULL != (tok = strtok (NULL, ",")))
468  count++;
469  struct GNUNET_CREDENTIAL_Credential credentials[count];
470  struct GNUNET_CREDENTIAL_Credential *cred;
471  GNUNET_free (tmp);
473  tok = strtok (tmp, ",");
474  for (i = 0; i < count; i++)
475  {
477  GNUNET_memcpy (&credentials[i],
478  cred,
479  sizeof(struct GNUNET_CREDENTIAL_Credential));
480  credentials[i].issuer_attribute = GNUNET_strdup (cred->issuer_attribute);
481  tok = strtok (NULL, ",");
482  GNUNET_free (cred);
483  }
484 
485  verify_request = GNUNET_CREDENTIAL_verify (credential,
486  &issuer_pkey,
487  issuer_attr, // TODO argument
488  &subject_pkey,
489  count,
490  credentials,
492  NULL);
493  for (i = 0; i < count; i++)
494  {
495  GNUNET_free ((char*) credentials[i].issuer_attribute);
496  }
497  GNUNET_free (tmp);
498  }
499  else if (GNUNET_YES == create_cred)
500  {
501  if (NULL == ego_name)
502  {
503  fprintf (stderr,
504  _ ("Issuer ego required\n"));
506  return;
507  }
508  el = GNUNET_IDENTITY_ego_lookup (cfg,
509  ego_name,
510  &identity_cb,
511  (void *) cfg);
512  return;
513  }
514  else
515  {
516  fprintf (stderr,
517  _ (
518  "Please specify name to lookup, subject key and issuer key!\n"));
520  }
521  return;
522 }
523 
524 
532 int
533 main (int argc, char *const *argv)
534 {
535  struct GNUNET_GETOPT_CommandLineOption options[] = {
537  "issue",
538  gettext_noop ("create credential"),
539  &create_cred),
541  "verify",
542  gettext_noop (
543  "verify credential against attribute"),
544  &verify),
546  "subject",
547  "PKEY",
548  gettext_noop (
549  "The public key of the subject to lookup the credential for"),
550  &subject_key),
552  "credential",
553  "CRED",
554  gettext_noop (
555  "The name of the credential presented by the subject"),
558  "issuer",
559  "PKEY",
560  gettext_noop (
561  "The public key of the authority to verify the credential against"),
562  &issuer_key),
564  "ego",
565  "EGO",
566  gettext_noop ("The ego to use"),
567  &ego_name),
569  "attribute",
570  "ATTR",
571  gettext_noop (
572  "The issuer attribute to verify against or to issue"),
573  &issuer_attr),
575  "ttl",
576  "EXP",
577  gettext_noop (
578  "The time to live for the credential"),
579  &expiration),
581  "collect",
582  gettext_noop ("collect credentials"),
583  &collect),
585  };
586  int ret;
587 
589  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
590  return 2;
591 
592  GNUNET_log_setup ("gnunet-credential", "WARNING", NULL);
593  ret =
594  (GNUNET_OK ==
595  GNUNET_PROGRAM_run (argc, argv, "gnunet-credential",
596  _ ("GNUnet credential resolver tool"),
597  options,
598  &run, NULL)) ? 0 : 1;
599  GNUNET_free ((void*) argv);
600  return ret;
601 }
602 
603 /* 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:1300
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:1440
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:246
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:351
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:555
API to serialize and deserialize delegation chains and credentials.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
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:402
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:75
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:526
static int ret
Final status code.
Definition: gnunet-arm.c:94
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:181
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:1253
Handle for an ego.
Definition: identity.h:245
static int verify
Verify mode.
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:332
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:466
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:368
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:77
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:966