GNUnet  0.20.0
gnunet-identity.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2013, 2018, 2019 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  */
28 #include "platform.h"
29 #include "gnunet_util_lib.h"
31 
32 
36 #define TIMEOUT_STATUS_CODE 40
37 
41 static struct GNUNET_IDENTITY_Handle *sh;
42 
46 static int list;
47 
51 static int monitor;
52 
56 static int private_keys;
57 
61 static unsigned int verbose;
62 
66 static int quiet;
67 
71 static int type_eddsa;
72 
76 static char *write_msg;
77 
81 static char *read_msg;
82 
86 static char *create_ego;
87 
91 static char *delete_ego;
92 
96 static char *privkey_ego;
97 
101 static char *pubkey_msg;
102 
106 static char *set_ego;
107 
112 
117 
122 
127 
131 static int global_ret;
132 
133 
139 static void
140 shutdown_task (void *cls)
141 {
142  if (NULL != set_op)
143  {
145  set_op = NULL;
146  }
147  if (NULL != create_op)
148  {
150  create_op = NULL;
151  }
152  if (NULL != delete_op)
153  {
155  delete_op = NULL;
156  }
157  if (NULL != set_ego)
158  {
160  set_ego = NULL;
161  }
163  sh = NULL;
164 }
165 
166 
170 static void
172 {
173  if ( (NULL == create_op) &&
174  (NULL == delete_op) &&
175  (NULL == set_op) &&
176  (NULL == write_msg) &&
177  (NULL == read_msg) &&
178  (! list) &&
179  (! monitor))
180  {
182  global_ret = 0;
184  }
185 }
186 
187 
194 static void
195 delete_finished (void *cls,
196  enum GNUNET_ErrorCode ec)
197 {
198  struct GNUNET_IDENTITY_Operation **op = cls;
199 
200  *op = NULL;
201  if (GNUNET_EC_NONE != ec)
202  fprintf (stderr, "%s\n", GNUNET_ErrorCode_get_hint (ec));
203  test_finished ();
204 }
205 
206 
214 static void
216  const struct GNUNET_IDENTITY_PrivateKey *pk,
217  enum GNUNET_ErrorCode ec)
218 {
219  struct GNUNET_IDENTITY_Operation **op = cls;
220 
221  *op = NULL;
222  if (NULL == pk)
223  {
224  fprintf (stderr,
225  _ ("Failed to create ego: %s\n"),
227  global_ret = 1;
228  }
229  else if (verbose)
230  {
232  char *pubs;
233 
236  if (private_keys)
237  {
238  char *privs;
239 
241  fprintf (stdout, "%s - %s\n", pubs, privs);
242  GNUNET_free (privs);
243  }
244  else
245  {
246  fprintf (stdout, "%s\n", pubs);
247  }
248  GNUNET_free (pubs);
249  }
250  test_finished ();
251 }
252 
253 
258 static void
260 {
261  struct GNUNET_IDENTITY_PublicKey recipient;
262  size_t ct_len = strlen (write_msg) + 1
264  unsigned char ct[ct_len];
267  {
268  size_t msg_len = strlen (write_msg) + 1;
270  msg_len,
271  &recipient,
272  ct, ct_len))
273  {
274  char *serialized_msg;
275  serialized_msg = GNUNET_STRINGS_data_to_string_alloc (ct, ct_len);
276  fprintf (stdout,
277  "%s\n",
278  serialized_msg);
279  GNUNET_free (serialized_msg);
280  }
281  else
282  {
283  fprintf (stderr, "Error during encryption.\n");
284  global_ret = 1;
285  }
286  }
287  else
288  {
289  fprintf (stderr, "Invalid recipient public key.\n");
290  global_ret = 1;
291  }
292 }
293 
294 
301 static void
303 {
304  char *deserialized_msg;
305  size_t msg_len;
307  read_msg),
308  (void **) &
309  deserialized_msg,
310  &msg_len))
311  {
312  if (GNUNET_OK == GNUNET_IDENTITY_decrypt (deserialized_msg,
313  msg_len,
315  ego),
316  deserialized_msg, msg_len))
317  {
318  deserialized_msg[msg_len - 1] = '\0';
319  fprintf (stdout,
320  "%s\n",
321  deserialized_msg);
322  }
323  else
324  {
325  fprintf (stderr, "Failed to decrypt message.\n");
326  global_ret = 1;
327  }
328  GNUNET_free (deserialized_msg);
329  }
330  else
331  {
332  fprintf (stderr, "Invalid message format.\n");
333  global_ret = 1;
334  }
335 }
336 
337 
370 static void
371 print_ego (void *cls,
372  struct GNUNET_IDENTITY_Ego *ego,
373  void **ctx,
374  const char *identifier)
375 {
377  char *s;
378  char *privs;
379 
380  if ( (NULL == ego) &&
381  (NULL != set_ego) &&
382  (NULL != read_msg) )
383  {
384  fprintf (stderr,
385  "Ego `%s' is not known, cannot decrypt message.\n",
386  set_ego);
388  read_msg = NULL;
390  set_ego = NULL;
391  }
392  if ((NULL == ego) && (! monitor))
393  {
394  list = 0;
395  test_finished ();
396  return;
397  }
398  if (! (list | monitor) && (NULL == read_msg))
399  return;
400  if ( (NULL == ego) ||
401  (NULL == identifier) )
402  return;
403  if ( (NULL != set_ego) &&
404  (0 != strcmp (identifier,
405  set_ego)) )
406  return;
411  if ((NULL != read_msg) && (NULL != set_ego))
412  {
413  // due to the check above, set_ego and the identifier are equal
416  read_msg = NULL;
417  }
418  else if ((monitor) || (NULL != identifier))
419  {
420  if (quiet)
421  {
422  if (private_keys)
423  fprintf (stdout, "%s - %s\n", s, privs);
424  else
425  fprintf (stdout, "%s\n", s);
426  }
427  else
428  {
429  if (private_keys)
430  fprintf (stdout, "%s - %s - %s - %s\n",
431  identifier, s, privs,
432  (ntohl (pk.type) == GNUNET_IDENTITY_TYPE_ECDSA) ?
433  "ECDSA" : "EdDSA");
434  else
435  fprintf (stdout, "%s - %s - %s\n",
436  identifier, s,
437  (ntohl (pk.type) == GNUNET_IDENTITY_TYPE_ECDSA) ?
438  "ECDSA" : "EdDSA");
439 
440  }
441  }
442  GNUNET_free (privs);
443  GNUNET_free (s);
444 }
445 
446 
455 static void
456 run (void *cls,
457  char *const *args,
458  const char *cfgfile,
459  const struct GNUNET_CONFIGURATION_Handle *cfg)
460 {
461  if ((NULL != read_msg) && (NULL == set_ego))
462  {
463  fprintf (stderr,
464  "Option -R requires options -e to be specified as well.\n");
465  return;
466  }
467 
468  if ((NULL != write_msg) && (NULL == pubkey_msg))
469  {
470  fprintf (stderr, "Option -W requires option -k to be specified as well.\n");
471  return;
472  }
474  (monitor | list) ||
475  (NULL != set_ego)
476  ? &print_ego
477  : NULL,
478  NULL);
479  if (NULL != write_msg)
480  {
483  write_msg = NULL;
484  }
485  // read message is handled in ego callback (print_ego)
486  if (NULL != delete_ego)
487  delete_op =
489  delete_ego,
491  &delete_op);
492  if (NULL != create_ego)
493  {
494  if (NULL != privkey_ego)
495  {
497  strlen (privkey_ego),
498  &pk,
499  sizeof(struct
501  create_op =
503  create_ego,
504  &pk,
505  0, // Ignored
507  &create_op);
508  }
509  else
510  create_op =
512  create_ego,
513  NULL,
514  (type_eddsa) ?
518  &create_op);
519  }
521  NULL);
522  test_finished ();
523 }
524 
525 
533 int
534 main (int argc, char *const *argv)
535 {
538  "create",
539  "NAME",
540  gettext_noop ("create ego NAME"),
541  &create_ego),
543  "delete",
544  "NAME",
545  gettext_noop ("delete ego NAME "),
546  &delete_ego),
548  "privkey",
549  "PRIVATE_KEY",
550  gettext_noop (
551  "set the private key for the identity to PRIVATE_KEY (use together with -C)"),
552  &privkey_ego),
554  "read",
555  "MESSAGE",
556  gettext_noop (
557  "Read and decrypt message encrypted for the given ego (use together with -e EGO)"),
558  &read_msg),
560  "write",
561  "MESSAGE",
562  gettext_noop (
563  "Encrypt and write message for recipient identity PULBIC_KEY, (use together with -k RECIPIENT_PUBLIC_KEY)"),
564  &write_msg),
566  "eddsa",
567  gettext_noop (
568  "generate an EdDSA identity. (use together with -C) EXPERIMENTAL"),
569  &type_eddsa),
571  "display",
572  gettext_noop ("display all egos"),
573  &list),
575  "quiet",
576  gettext_noop ("reduce output"),
577  &quiet),
579  'e',
580  "ego",
581  "NAME",
582  gettext_noop (
583  "restrict results to NAME (use together with -d) or read and decrypt a message for NAME (use together with -R)"),
584  &set_ego),
586  "key",
587  "PUBLIC_KEY",
588  gettext_noop (
589  "The public key of the recipient (with -W)"),
590  &pubkey_msg),
592  "monitor",
593  gettext_noop ("run in monitor mode egos"),
594  &monitor),
596  "private-keys",
597  gettext_noop ("display private keys as well"),
598  &private_keys),
601  };
602  int res;
603 
604  if (GNUNET_OK !=
605  GNUNET_STRINGS_get_utf8_args (argc, argv,
606  &argc, &argv))
607  return 4;
608  global_ret = TIMEOUT_STATUS_CODE; /* timeout */
609  res = GNUNET_PROGRAM_run (argc,
610  argv,
611  "gnunet-identity",
612  gettext_noop ("Maintain egos"),
613  options,
614  &run,
615  NULL);
616  GNUNET_free_nz ((void *) argv);
617 
618  if (GNUNET_OK != res)
619  return 3;
620  return global_ret;
621 }
622 
623 
624 /* end of gnunet-identity.c */
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
const char * GNUNET_ErrorCode_get_hint(enum GNUNET_ErrorCode ec)
Returns a hint for a given error code.
GNUNET_ErrorCode
Taler error codes.
@ GNUNET_EC_NONE
No error (success).
#define gettext_noop(String)
Definition: gettext.h:70
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
static int res
#define TIMEOUT_STATUS_CODE
Return value from main on timeout.
static void create_finished(void *cls, const struct GNUNET_IDENTITY_PrivateKey *pk, enum GNUNET_ErrorCode ec)
Creation operation finished.
static unsigned int verbose
Was "verbose" specified?
static void write_encrypted_message(void)
Encrypt a message given with -W, encrypted using public key of an identity given with -k.
struct GNUNET_IDENTITY_PrivateKey pk
Private key from command line option, or NULL.
static struct GNUNET_IDENTITY_Operation * set_op
Operation handle for set operation.
static char * privkey_ego
-P option
static struct GNUNET_IDENTITY_Operation * create_op
Handle for create operation.
static int global_ret
Value to return from main().
static int monitor
Was "monitor" specified?
static int list
Was "list" specified?
static int quiet
Was "quiet" specified?
static struct GNUNET_IDENTITY_Handle * sh
Handle to IDENTITY service.
static char * read_msg
-R option
static void shutdown_task(void *cls)
Task run on shutdown.
static void print_ego(void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, const char *identifier)
If listing is enabled, prints information about the egos.
static void read_encrypted_message(struct GNUNET_IDENTITY_Ego *ego)
Decrypt a message given with -R, encrypted using public key of ego and ephemeral key given with -k.
static int private_keys
Was "private" specified?
static char * delete_ego
-D option
static void test_finished(void)
Test if we are finished yet.
static struct GNUNET_IDENTITY_Operation * delete_op
Handle for delete operation.
static char * create_ego
-C option
static char * pubkey_msg
-k option
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
Main function that will be run by the scheduler.
int main(int argc, char *const *argv)
The main function.
static int type_eddsa
Was "eddsa" specified?
static void delete_finished(void *cls, enum GNUNET_ErrorCode ec)
Deletion operation finished.
static char * set_ego
-s option.
static char * write_msg
-W option
static struct GNUNET_CRYPTO_EddsaPublicKey pub
Definition: gnunet-scrypt.c:47
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
Identity service; implements identity management for GNUnet.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_verbose(unsigned int *level)
Define the '-V' verbosity option.
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.
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.
const struct GNUNET_IDENTITY_PrivateKey * GNUNET_IDENTITY_ego_get_private_key(const struct GNUNET_IDENTITY_Ego *ego)
Obtain the ECC key associated with a ego.
Definition: identity_api.c:560
enum GNUNET_GenericReturnValue GNUNET_IDENTITY_public_key_from_string(const char *str, struct GNUNET_IDENTITY_PublicKey *key)
Parses a (Base32) string representation of the public key.
enum GNUNET_GenericReturnValue GNUNET_IDENTITY_key_get_public(const struct GNUNET_IDENTITY_PrivateKey *privkey, struct GNUNET_IDENTITY_PublicKey *key)
Retrieves the public key representation of a private key.
Definition: identity_api.c:179
enum GNUNET_GenericReturnValue GNUNET_IDENTITY_decrypt(const void *ct_buf, size_t ct_size, const struct GNUNET_IDENTITY_PrivateKey *priv, void *pt, size_t pt_size)
Decrypt a given block with GNUNET_IDENTITY_PrivateKey and a given GNUNET_CRYPTO_EcdhePublicKey using ...
enum GNUNET_GenericReturnValue GNUNET_IDENTITY_encrypt(const void *pt, size_t pt_size, const struct GNUNET_IDENTITY_PublicKey *pub, void *ct_buf, size_t ct_size)
Encrypt a block with GNUNET_IDENTITY_PublicKey and derives a GNUNET_CRYPTO_EcdhePublicKey which is re...
char * GNUNET_IDENTITY_private_key_to_string(const struct GNUNET_IDENTITY_PrivateKey *key)
Creates a (Base32) string representation of the private key.
struct GNUNET_IDENTITY_Operation * GNUNET_IDENTITY_create(struct GNUNET_IDENTITY_Handle *h, const char *name, const struct GNUNET_IDENTITY_PrivateKey *privkey, enum GNUNET_IDENTITY_KeyType ktype, GNUNET_IDENTITY_CreateContinuation cont, void *cont_cls)
Create a new ego with the given name.
Definition: identity_api.c:586
#define GNUNET_IDENTITY_ENCRYPT_OVERHEAD_BYTES
void GNUNET_IDENTITY_ego_get_public_key(struct GNUNET_IDENTITY_Ego *ego, struct GNUNET_IDENTITY_PublicKey *pk)
Get the identifier (public key) of an ego.
Definition: identity_api.c:573
char * GNUNET_IDENTITY_public_key_to_string(const struct GNUNET_IDENTITY_PublicKey *key)
Creates a (Base32) string representation of the public key.
void GNUNET_IDENTITY_cancel(struct GNUNET_IDENTITY_Operation *op)
Cancel an identity operation.
Definition: identity_api.c:740
struct GNUNET_IDENTITY_Handle * GNUNET_IDENTITY_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_IDENTITY_Callback cb, void *cb_cls)
Connect to the identity service.
Definition: identity_api.c:531
void GNUNET_IDENTITY_disconnect(struct GNUNET_IDENTITY_Handle *h)
Disconnect from identity service.
Definition: identity_api.c:757
struct GNUNET_IDENTITY_Operation * GNUNET_IDENTITY_delete(struct GNUNET_IDENTITY_Handle *h, const char *name, GNUNET_IDENTITY_Continuation cb, void *cb_cls)
Delete an existing identity.
Definition: identity_api.c:699
@ GNUNET_IDENTITY_TYPE_ECDSA
The identity type.
@ GNUNET_IDENTITY_TYPE_EDDSA
EDDSA identity.
@ GNUNET_OK
@ GNUNET_SYSERR
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_free_nz(ptr)
Wrapper around free.
enum GNUNET_GenericReturnValue 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,...
Definition: program.c:400
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:562
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,...
Definition: scheduler.c:1334
enum GNUNET_GenericReturnValue GNUNET_STRINGS_string_to_data_alloc(const char *enc, size_t enclen, void **out, size_t *out_size)
Convert CrockfordBase32 encoding back to data.
Definition: strings.c:854
char * GNUNET_STRINGS_data_to_string_alloc(const void *buf, size_t size)
Return the base32crockford encoding of the given buffer.
Definition: strings.c:763
enum GNUNET_GenericReturnValue GNUNET_STRINGS_string_to_data(const char *enc, size_t enclen, void *out, size_t out_size)
Convert CrockfordBase32 encoding back to data.
Definition: strings.c:788
enum GNUNET_GenericReturnValue GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1222
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
Definition of a command line option.
Handle for an ego.
Definition: identity.h:37
Handle for the service.
Definition: identity_api.c:97
Handle for an operation with the identity service.
Definition: identity_api.c:41
void * cls
Closure for cont or cb.
Definition: identity_api.c:89
A private key for an identity as per LSD0001.
uint32_t type
Type of public key.
An identity key as per LSD0001.