GNUnet 0.21.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
42
46static int list;
47
51static int monitor;
52
56static int private_keys;
57
61static unsigned int verbose;
62
66static int quiet;
67
71static int type_eddsa;
72
76static char *write_msg;
77
81static char *read_msg;
82
86static char *create_ego;
87
91static char *delete_ego;
92
96static char *privkey_ego;
97
101static char *pubkey_msg;
102
106static char *set_ego;
107
112
117
122
127
131static int global_ret;
132
133
139static void
140shutdown_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
170static 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
194static void
196 enum GNUNET_ErrorCode ec)
197{
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
214static void
216 const struct GNUNET_CRYPTO_PrivateKey *pk,
217 enum GNUNET_ErrorCode ec)
218{
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
258static void
260{
261 struct GNUNET_CRYPTO_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
301static 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_CRYPTO_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
370static void
371print_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,
433 "ECDSA" : "EdDSA");
434 else
435 fprintf (stdout, "%s - %s - %s\n",
436 identifier, s,
438 "ECDSA" : "EdDSA");
439
440 }
441 }
442 GNUNET_free (privs);
443 GNUNET_free (s);
444}
445
446
455static void
456run (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 =
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 =
504 &pk,
505 0, // Ignored
507 &create_op);
508 }
509 else
510 create_op =
513 NULL,
514 (type_eddsa) ?
518 &create_op);
519 }
521 NULL);
522 test_finished ();
523}
524
525
533int
534main (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",
551 "set the private key for the identity to PRIVATE_KEY (use together with -C)"),
552 &privkey_ego),
554 "read",
555 "MESSAGE",
557 "Read and decrypt message encrypted for the given ego (use together with -e EGO)"),
558 &read_msg),
560 "write",
561 "MESSAGE",
563 "Encrypt and write message for recipient identity PULBIC_KEY, (use together with -k RECIPIENT_PUBLIC_KEY)"),
564 &write_msg),
566 "eddsa",
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",
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",
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 !=
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
#define gettext_noop(String)
Definition: gettext.h:70
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:109
static struct GNUNET_FS_Handle * ctx
#define TIMEOUT_STATUS_CODE
Return value from main on timeout.
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.
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 void create_finished(void *cls, const struct GNUNET_CRYPTO_PrivateKey *pk, enum GNUNET_ErrorCode ec)
Creation operation finished.
static int type_eddsa
Was "eddsa" specified?
static void delete_finished(void *cls, enum GNUNET_ErrorCode ec)
Deletion operation finished.
struct GNUNET_CRYPTO_PrivateKey pk
Private key from command line option, or NULL.
static char * set_ego
-s option.
static char * write_msg
-W option
static char * res
Currently read line or NULL on EOF.
static struct GNUNET_CRYPTO_EddsaPublicKey pub
Definition: gnunet-scrypt.c:47
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.
struct GNUNET_IDENTITY_Operation * GNUNET_IDENTITY_create(struct GNUNET_IDENTITY_Handle *id, const char *name, const struct GNUNET_CRYPTO_PrivateKey *privkey, enum GNUNET_CRYPTO_KeyType ktype, GNUNET_IDENTITY_CreateContinuation cont, void *cont_cls)
Create a new ego with the given name.
Definition: identity_api.c:561
const struct GNUNET_CRYPTO_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:517
struct GNUNET_IDENTITY_Operation * GNUNET_IDENTITY_delete(struct GNUNET_IDENTITY_Handle *id, const char *name, GNUNET_IDENTITY_Continuation cb, void *cb_cls)
Delete an existing ego.
Definition: identity_api.c:674
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:487
void GNUNET_IDENTITY_cancel(struct GNUNET_IDENTITY_Operation *op)
Cancel an identity operation.
Definition: identity_api.c:715
void GNUNET_IDENTITY_disconnect(struct GNUNET_IDENTITY_Handle *h)
Disconnect from identity service.
Definition: identity_api.c:732
void GNUNET_IDENTITY_ego_get_public_key(struct GNUNET_IDENTITY_Ego *ego, struct GNUNET_CRYPTO_PublicKey *pk)
Get the identifier (public key) of an ego.
Definition: identity_api.c:529
#define GNUNET_CRYPTO_ENCRYPT_OVERHEAD_BYTES
char * GNUNET_CRYPTO_public_key_to_string(const struct GNUNET_CRYPTO_PublicKey *key)
Creates a (Base32) string representation of the public key.
Definition: crypto_pkey.c:551
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_encrypt(const void *block, size_t size, const struct GNUNET_CRYPTO_PublicKey *pub, void *result, size_t result_size)
Encrypt a block with GNUNET_CRYPTO_PublicKey and derives a GNUNET_CRYPTO_EcdhePublicKey which is requ...
Definition: crypto_pkey.c:416
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_key_get_public(const struct GNUNET_CRYPTO_PrivateKey *privkey, struct GNUNET_CRYPTO_PublicKey *key)
Retrieves the public key representation of a private key.
Definition: crypto_pkey.c:602
char * GNUNET_CRYPTO_private_key_to_string(const struct GNUNET_CRYPTO_PrivateKey *key)
Creates a (Base32) string representation of the private key.
Definition: crypto_pkey.c:561
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_decrypt(const void *block, size_t size, const struct GNUNET_CRYPTO_PrivateKey *priv, void *result, size_t result_size)
Decrypt a given block with GNUNET_CRYPTO_PrivateKey and a given GNUNET_CRYPTO_EcdhePublicKey using ec...
Definition: crypto_pkey.c:467
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_public_key_from_string(const char *str, struct GNUNET_CRYPTO_PublicKey *key)
Parses a (Base32) string representation of the public key.
Definition: crypto_pkey.c:571
@ GNUNET_PUBLIC_KEY_TYPE_EDDSA
EDDSA identity.
@ GNUNET_PUBLIC_KEY_TYPE_ECDSA
The identity type.
@ 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:855
char * GNUNET_STRINGS_data_to_string_alloc(const void *buf, size_t size)
Return the base32crockford encoding of the given buffer.
Definition: strings.c:764
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:789
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:1230
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
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).
A private key for an identity as per LSD0001.
uint32_t type
Type of public key.
An identity key as per LSD0001.
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