GNUnet 0.22.2
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_created,
217 enum GNUNET_ErrorCode ec)
218{
220
221 *op = NULL;
222 if (NULL == pk_created)
223 {
224 fprintf (stderr,
225 _ ("Failed to create ego: %s\n"),
227 global_ret = ec;
228 }
229 else if (verbose)
230 {
232 char *pubs;
233
234 GNUNET_CRYPTO_key_get_public (pk_created, &pub);
236 if (private_keys)
237 {
238 char *privs;
239
240 privs = GNUNET_CRYPTO_private_key_to_string (pk_created);
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 struct GNUNET_CRYPTO_EcdhePublicKey hpke_key = {0};
263 size_t msg_len = strlen (write_msg) + 1;
264 size_t ct_len = strlen (write_msg) + 1
266 unsigned char ct[ct_len];
269 {
271 GNUNET_CRYPTO_hpke_pk_to_x25519 (&recipient, &hpke_key));
273 NULL, 0, // FIXME provide?
274 NULL, 0,
275 (uint8_t*) write_msg,
276 msg_len,
277 ct, NULL))
278 {
279 char *serialized_msg;
280 serialized_msg = GNUNET_STRINGS_data_to_string_alloc (ct, ct_len);
281 fprintf (stdout,
282 "%s\n",
283 serialized_msg);
284 GNUNET_free (serialized_msg);
285 }
286 else
287 {
288 fprintf (stderr, "Error during encryption.\n");
289 global_ret = 1;
290 }
291 }
292 else
293 {
294 fprintf (stderr, "Invalid recipient public key.\n");
295 global_ret = 1;
296 }
297}
298
299
306static void
308{
309 struct GNUNET_CRYPTO_EcdhePrivateKey hpke_key;
310 char *deserialized_msg;
311 size_t msg_len;
313 strlen (read_msg),
314 (void **) &
315 deserialized_msg,
316 &msg_len))
317 {
321 &hpke_key));
323 NULL, 0,
324 NULL, 0,
325 (uint8_t*)
326 deserialized_msg,
327 msg_len,
328 (uint8_t*)
329 deserialized_msg,
330 NULL))
331 {
332 deserialized_msg[msg_len - 1] = '\0';
333 fprintf (stdout,
334 "%s\n",
335 deserialized_msg);
336 }
337 else
338 {
339 fprintf (stderr, "Failed to decrypt message.\n");
340 global_ret = 1;
341 }
342 GNUNET_free (deserialized_msg);
343 }
344 else
345 {
346 fprintf (stderr, "Invalid message format.\n");
347 global_ret = 1;
348 }
349}
350
351
384static void
385print_ego (void *cls,
386 struct GNUNET_IDENTITY_Ego *ego,
387 void **ctx,
388 const char *identifier)
389{
390 struct GNUNET_CRYPTO_PublicKey pk_tmp;
391 char *s;
392 char *privs;
393
394 if ( (NULL == ego) &&
395 (NULL != set_ego) &&
396 (NULL != read_msg) )
397 {
398 fprintf (stderr,
399 "Ego `%s' is not known, cannot decrypt message.\n",
400 set_ego);
402 read_msg = NULL;
404 set_ego = NULL;
405 }
406 if ((NULL == ego) && (! monitor))
407 {
408 list = 0;
409 test_finished ();
410 return;
411 }
412 if (! (list | monitor) && (NULL == read_msg))
413 return;
414 if ( (NULL == ego) ||
415 (NULL == identifier) )
416 return;
417 if ( (NULL != set_ego) &&
418 (0 != strcmp (identifier,
419 set_ego)) )
420 return;
425 if ((NULL != read_msg) && (NULL != set_ego))
426 {
427 // due to the check above, set_ego and the identifier are equal
430 read_msg = NULL;
431 }
432 else if ((monitor) || (NULL != identifier))
433 {
434 if (quiet)
435 {
436 if (private_keys)
437 fprintf (stdout, "%s - %s\n", s, privs);
438 else
439 fprintf (stdout, "%s\n", s);
440 }
441 else
442 {
443 if (private_keys)
444 fprintf (stdout, "%s - %s - %s - %s\n",
445 identifier, s, privs,
446 (ntohl (pk_tmp.type) == GNUNET_PUBLIC_KEY_TYPE_ECDSA) ?
447 "ECDSA" : "EdDSA");
448 else
449 fprintf (stdout, "%s - %s - %s\n",
450 identifier, s,
451 (ntohl (pk_tmp.type) == GNUNET_PUBLIC_KEY_TYPE_ECDSA) ?
452 "ECDSA" : "EdDSA");
453
454 }
455 }
456 GNUNET_free (privs);
457 GNUNET_free (s);
458}
459
460
469static void
470run (void *cls,
471 char *const *args,
472 const char *cfgfile,
473 const struct GNUNET_CONFIGURATION_Handle *cfg)
474{
475 if ((NULL != read_msg) && (NULL == set_ego))
476 {
477 fprintf (stderr,
478 "Option -R requires options -e to be specified as well.\n");
479 return;
480 }
481
482 if ((NULL != write_msg) && (NULL == pubkey_msg))
483 {
484 fprintf (stderr, "Option -W requires option -k to be specified as well.\n");
485 return;
486 }
488 (monitor | list) ||
489 (NULL != set_ego)
490 ? &print_ego
491 : NULL,
492 NULL);
493 if (NULL != write_msg)
494 {
497 write_msg = NULL;
498 }
499 // read message is handled in ego callback (print_ego)
500 if (NULL != delete_ego)
501 delete_op =
505 &delete_op);
506 if (NULL != create_ego)
507 {
508 if (NULL != privkey_ego)
509 {
511 strlen (privkey_ego),
512 &pk,
513 sizeof(struct
515 create_op =
518 &pk,
519 0, // Ignored
521 &create_op);
522 }
523 else
524 create_op =
527 NULL,
528 (type_eddsa) ?
532 &create_op);
533 }
535 NULL);
536 test_finished ();
537}
538
539
547int
548main (int argc, char *const *argv)
549{
552 "create",
553 "NAME",
554 gettext_noop ("create ego NAME"),
555 &create_ego),
557 "delete",
558 "NAME",
559 gettext_noop ("delete ego NAME "),
560 &delete_ego),
562 "privkey",
563 "PRIVATE_KEY",
565 "set the private key for the identity to PRIVATE_KEY (use together with -C)"),
566 &privkey_ego),
568 "read",
569 "MESSAGE",
571 "Read and decrypt message encrypted for the given ego (use together with -e EGO)"),
572 &read_msg),
574 "write",
575 "MESSAGE",
577 "Encrypt and write message for recipient identity PULBIC_KEY, (use together with -k RECIPIENT_PUBLIC_KEY)"),
578 &write_msg),
580 "eddsa",
582 "generate an EdDSA identity. (use together with -C) EXPERIMENTAL"),
583 &type_eddsa),
585 "display",
586 gettext_noop ("display all egos"),
587 &list),
589 "quiet",
590 gettext_noop ("reduce output"),
591 &quiet),
593 'e',
594 "ego",
595 "NAME",
597 "restrict results to NAME (use together with -d) or read and decrypt a message for NAME (use together with -R)"),
598 &set_ego),
600 "key",
601 "PUBLIC_KEY",
603 "The public key of the recipient (with -W)"),
604 &pubkey_msg),
606 "monitor",
607 gettext_noop ("run in monitor mode egos"),
608 &monitor),
610 "private-keys",
611 gettext_noop ("display private keys as well"),
612 &private_keys),
615 };
616 int res;
617
618 global_ret = TIMEOUT_STATUS_CODE; /* timeout */
620 argc,
621 argv,
622 "gnunet-identity",
623 gettext_noop ("Maintain egos"),
624 options,
625 &run,
626 NULL);
627
628 if (GNUNET_OK != res)
629 return 3;
630 return global_ret;
631}
632
633
634/* 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:74
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:143
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:108
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_created, 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
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_open_oneshot(const struct GNUNET_CRYPTO_EcdhePrivateKey *skR, const uint8_t *info, size_t info_len, const uint8_t *aad, size_t aad_len, const uint8_t *ct, size_t ct_len, uint8_t *pt, unsigned long long *pt_len)
RFC9180 HPKE encryption.
Definition: crypto_hpke.c:958
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_seal_oneshot(const struct GNUNET_CRYPTO_EcdhePublicKey *pkR, const uint8_t *info, size_t info_len, const uint8_t *aad, size_t aad_len, const uint8_t *pt, size_t pt_len, uint8_t *ct, unsigned long long *ct_len)
RFC9180 HPKE encryption.
Definition: crypto_hpke.c:929
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:379
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:430
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:389
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_sk_to_x25519(const struct GNUNET_CRYPTO_PrivateKey *sk, struct GNUNET_CRYPTO_EcdhePrivateKey *x25519)
Convert a GNUnet identity key to a key sutiable for HPKE (X25519)
Definition: crypto_hpke.c:1013
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hpke_pk_to_x25519(const struct GNUNET_CRYPTO_PublicKey *pk, struct GNUNET_CRYPTO_EcdhePublicKey *x25519)
Convert a GNUnet identity key to a key sutiable for HPKE (X25519)
Definition: crypto_hpke.c:989
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:399
#define GNUNET_CRYPTO_HPKE_SEAL_ONESHOT_OVERHEAD_BYTES
@ GNUNET_PUBLIC_KEY_TYPE_EDDSA
EDDSA identity.
@ GNUNET_PUBLIC_KEY_TYPE_ECDSA
The identity type.
@ GNUNET_OK
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_free(ptr)
Wrapper around free.
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_gnunet(void)
Return default project data used by 'libgnunetutil' for GNUnet.
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(const struct GNUNET_OS_ProjectData *pd, 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:407
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:567
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:1339
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:878
char * GNUNET_STRINGS_data_to_string_alloc(const void *buf, size_t size)
Return the base32crockford encoding of the given buffer.
Definition: strings.c:787
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:812
#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).
Private ECC key encoded for transmission.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
A private key for an identity as per LSD0001.
An identity key as per LSD0001.
uint32_t type
Type of public key.
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