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  {
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  }
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 
322  ego_name = NULL;
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  }
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  }
509  ego_name,
510  &identity_cb,
511  (void *)cfg);
512  return;
513  }
514  else
515  {
516  fprintf(stderr,
517  _("Please specify name to lookup, subject key and issuer key!\n"));
519  }
520  return;
521 }
522 
523 
531 int
532 main(int argc, char *const *argv)
533 {
534  struct GNUNET_GETOPT_CommandLineOption options[] = {
536  "issue",
537  gettext_noop("create credential"),
538  &create_cred),
540  "verify",
541  gettext_noop("verify credential against attribute"),
542  &verify),
544  "subject",
545  "PKEY",
546  gettext_noop("The public key of the subject to lookup the credential for"),
547  &subject_key),
549  "credential",
550  "CRED",
551  gettext_noop("The name of the credential presented by the subject"),
554  "issuer",
555  "PKEY",
556  gettext_noop("The public key of the authority to verify the credential against"),
557  &issuer_key),
559  "ego",
560  "EGO",
561  gettext_noop("The ego to use"),
562  &ego_name),
564  "attribute",
565  "ATTR",
566  gettext_noop("The issuer attribute to verify against or to issue"),
567  &issuer_attr),
569  "ttl",
570  "EXP",
571  gettext_noop("The time to live for the credential"),
572  &expiration),
574  "collect",
575  gettext_noop("collect credentials"),
576  &collect),
578  };
579  int ret;
580 
582  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args(argc, argv, &argc, &argv))
583  return 2;
584 
585  GNUNET_log_setup("gnunet-credential", "WARNING", NULL);
586  ret =
587  (GNUNET_OK ==
588  GNUNET_PROGRAM_run(argc, argv, "gnunet-credential",
589  _("GNUnet credential resolver tool"),
590  options,
591  &run, NULL)) ? 0 : 1;
592  GNUNET_free((void*)argv);
593  return ret;
594 }
595 
596 /* 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:1284
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:1439
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:350
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:553
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:401
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:517
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: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:1237
Handle for an ego.
Definition: identity.h:237
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: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:83
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:131
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:367
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:956