GNUnet 0.28.0-dev.3-20-gf1136b0b8
 
Loading...
Searching...
No Matches
messenger_api_epoch_group.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2024--2026 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 */
27
28#include "messenger_api_epoch.h"
31#include "messenger_api_room.h"
32
33static void
36 identifier)
37{
38 GNUNET_assert (identifier);
39
41 sizeof (*identifier));
42
43 identifier->code.group_bit = 1;
44 identifier->code.level_bits = 0x7F & level;
45}
46
47
50 const struct GNUNET_MESSENGER_EpochGroup *previous,
52{
53 const struct GNUNET_CRYPTO_AeadSecretKey *previous_key;
54
55 GNUNET_assert ((group) && (previous) && (key));
56
57 previous_key = get_epoch_group_key (previous);
58
59 if (! previous_key)
60 return GNUNET_SYSERR;
61
63 key, sizeof (*key),
66 previous_key,
67 sizeof (*previous_key),
70 return GNUNET_SYSERR;
71 else
72 return GNUNET_OK;
73}
74
75
80 uint32_t level,
82{
83 struct GNUNET_MESSENGER_EpochGroup *group;
84 const struct GNUNET_MESSENGER_EpochGroup *previous;
85
87
89
90 if (! group)
91 return NULL;
92
94
95 if ((GNUNET_YES == valid) && (previous) &&
96 (GNUNET_YES != previous->valid))
97 previous = NULL;
98
99 if (identifier)
101 sizeof (group->identifier));
102 else
103 random_epoch_group_identifier (level, &(group->identifier));
104
106
108
109 group->epoch = epoch;
111 group->shared_key = NULL;
112 group->query = NULL;
113
114 group->valid = GNUNET_YES;
115 group->stored = GNUNET_NO;
116
117 if (previous)
118 {
120
121 if (GNUNET_OK == derive_epoch_group_key (group,
122 previous,
123 &key))
124 {
126 group->valid = previous->valid;
127 }
128 }
129
130 return group;
131}
132
133
134void
136{
137 GNUNET_assert (group);
138
139 if (group->membership)
141
142 if (group->shared_key)
143 GNUNET_free (group->shared_key);
144
145 if (group->query)
147
148 GNUNET_free (group);
149}
150
151
152uint32_t
154{
155 GNUNET_assert (group);
156
157 return group->identifier.code.level_bits;
158}
159
160
161uint32_t
163{
164 GNUNET_assert (group);
165
166 return 0x1 << get_epoch_group_level (group);
167}
168
169
170uint32_t
172 group)
173{
174 GNUNET_assert (group);
175
177}
178
179
182{
183 GNUNET_assert (group);
184
186}
187
188
191{
192 GNUNET_assert (group);
193
194 return is_epoch_membership_member (group->membership, NULL);
195}
196
197
198void
200 const struct GNUNET_CRYPTO_AeadSecretKey *shared_key,
201 enum GNUNET_GenericReturnValue write_record)
202{
203 GNUNET_assert (group);
204
205 if ((GNUNET_NO == write_record) && (shared_key))
206 group->stored = GNUNET_YES;
207
208 if (group->shared_key)
209 return;
210
212
213 if (! group->shared_key)
214 return;
215
216 if (shared_key)
217 GNUNET_memcpy (group->shared_key, shared_key,
218 sizeof (struct GNUNET_CRYPTO_AeadSecretKey));
219 else
221
222 update_epoch_group (group->epoch, group);
223
224 if (GNUNET_YES != group->stored)
226}
227
228
229const struct GNUNET_CRYPTO_AeadSecretKey*
231{
232 GNUNET_assert (group);
233
234 return group->shared_key;
235}
236
237
240 ,
241 const struct GNUNET_MESSENGER_EpochGroup *
242 previous)
243{
244 const struct GNUNET_CRYPTO_AeadSecretKey *shared_key;
246
247 GNUNET_assert ((group) && (previous));
248
249 shared_key = get_epoch_group_key (group);
250
251 if (! shared_key)
252 return GNUNET_SYSERR;
253
254 if (GNUNET_OK != derive_epoch_group_key (group, previous, &key))
255 return GNUNET_SYSERR;
256
257 if (0 == GNUNET_memcmp (shared_key, &key))
258 return GNUNET_YES;
259 else
260 return GNUNET_NO;
261}
262
263
266 const struct GNUNET_HashCode *hash,
267 const struct GNUNET_MESSENGER_Message *message,
268 struct GNUNET_MESSENGER_Contact *contact,
270{
272
273 GNUNET_assert ((group) && (hash) && (message) && (contact));
274
275 if (GNUNET_YES != is_epoch_member (group->epoch, contact))
276 return GNUNET_SYSERR;
277
279 hash,
280 message,
281 contact,
282 sent);
283
284 if (GNUNET_YES != result)
285 return result;
286
287 update_epoch_group (group->epoch, group);
288 return GNUNET_YES;
289}
290
291
292static uint32_t
300
301
304 const struct GNUNET_MESSENGER_Contact *contact)
305{
306 GNUNET_assert ((group) && (contact));
307
308 return is_epoch_membership_member (group->membership, contact);
309}
310
311
317
320 const struct GNUNET_MESSENGER_Contact *member)
321{
323
324 GNUNET_assert ((cls) && (member));
325
326 check = cls;
327
328 if (GNUNET_YES == is_epoch_group_member (check->group, member))
329 return GNUNET_YES;
330
331 check->result = GNUNET_NO;
332 return GNUNET_NO;
333}
334
335
338 const struct GNUNET_MESSENGER_EpochGroup *other)
339{
341
342 GNUNET_assert ((group) && (other));
343
344 if (group == other)
345 return GNUNET_YES;
346
348 return GNUNET_NO;
349
351 return GNUNET_NO;
352
353 check.group = other;
354 check.result = GNUNET_YES;
355
358 &check);
359
360 return check.result;
361}
362
363
366 struct GNUNET_HashCode *hash,
367 enum GNUNET_GenericReturnValue other)
368{
369 GNUNET_assert ((group) && (hash));
370
372}
373
374
375void
377 const struct GNUNET_MESSENGER_Contact *contact)
378{
379 const struct GNUNET_MESSENGER_Message *message;
380 struct GNUNET_MESSENGER_EpochGroup *previous;
381 struct GNUNET_MESSENGER_Epoch *epoch;
382
383 GNUNET_assert (group);
384
385 if (GNUNET_NO == group->valid)
386 return;
387
388 if ((contact) && (GNUNET_YES != is_epoch_member (group->epoch, contact)))
389 return;
390
391 group->valid = GNUNET_NO;
393
394 message = get_room_message (group->epoch->room, &(group->epoch->hash));
395
396 if (! message)
397 goto skip_traversal;
398
399 switch (message->header.kind)
400 {
402 epoch = get_room_epoch (
403 group->epoch->room, &(message->body.join.epoch), GNUNET_NO);
404
405 if (epoch)
406 previous = get_epoch_group (
407 epoch, &(group->identifier), GNUNET_SYSERR);
408 else
409 previous = NULL;
410 break;
412 epoch = get_room_epoch (
413 group->epoch->room, &(message->body.leave.epoch), GNUNET_NO);
414
415 if (epoch)
416 previous = get_epoch_group (
417 epoch, &(group->identifier), GNUNET_SYSERR);
418 else
419 previous = NULL;
420 break;
422 epoch = get_room_epoch (
423 group->epoch->room, &(message->body.merge.epochs[0]), GNUNET_NO);
424
425 if (epoch)
426 {
427 previous = get_epoch_group (
428 epoch, &(group->identifier), GNUNET_SYSERR);
429
430 if ((previous) &&
431 (GNUNET_YES != is_epoch_group_key_derived_from (previous, group)))
432 previous = NULL;
433 }
434 else
435 previous = NULL;
436
437 if (! previous)
438 {
439 epoch = get_room_epoch (
440 group->epoch->room, &(message->body.merge.epochs[1]), GNUNET_NO);
441
442 if (epoch)
443 previous = get_epoch_group (
444 epoch, &(group->identifier), GNUNET_SYSERR);
445 }
446 break;
447 default:
448 previous = NULL;
449 break;
450 }
451
452 if ((previous) &&
453 (GNUNET_YES != is_epoch_group_key_derived_from (previous, group)))
454 previous = NULL;
455
456 if (previous)
457 invalidate_epoch_group (previous, contact);
458
459skip_traversal:
460 if (group->epoch->main_group != group)
461 return;
462
464 group->epoch, NULL, GNUNET_YES);
465}
466
467
470{
471 GNUNET_assert (group);
472
473 if (get_epoch_proposal_group (group->epoch) == group)
474 return GNUNET_YES;
475 else
476 return GNUNET_NO;
477}
478
479
485
488 const struct GNUNET_MESSENGER_Contact *member)
489{
490 struct GNUNET_MESSENGER_CheckEpoch *check;
491 uint32_t i;
492
493 GNUNET_assert ((cls) && (member));
494
495 check = cls;
496
497 for (i = 0; i < check->epoch->members_count; i++)
498 if (member == check->epoch->members[i])
499 return GNUNET_YES;
500
501 check->result = GNUNET_NO;
502 return GNUNET_NO;
503}
504
505
508 const struct GNUNET_MESSENGER_Epoch *epoch)
509{
510 struct GNUNET_MESSENGER_CheckEpoch check;
511
512 GNUNET_assert ((group) && (epoch));
513
515 return GNUNET_NO;
516
517 if (GNUNET_YES != group->valid)
518 return GNUNET_NO;
519
520 if (group->epoch == epoch)
521 return GNUNET_YES;
522
523 if (0 == epoch->members_count)
524 return GNUNET_NO;
525
526 check.epoch = epoch;
527 check.result = GNUNET_YES;
528
531 &check);
532
533 return check.result;
534}
535
536
542
545 const struct GNUNET_MESSENGER_Contact *
546 member)
547{
549
550 GNUNET_assert ((cls) && (member));
551
552 check = cls;
553
555 return GNUNET_YES;
556
557 check->result = GNUNET_YES;
558 return GNUNET_NO;
559}
560
561
564 group,
565 const struct
568{
570
571 GNUNET_assert ((group) && (announcement));
572
574 return GNUNET_YES;
575
577 check.result = GNUNET_NO;
578
581 &check);
582
583 return check.result;
584}
585
586
587double
589 group)
590{
591 const struct GNUNET_MESSENGER_EpochGroup *target;
592 uint32_t members_count;
593 uint32_t announced;
594 uint32_t position;
595
596 GNUNET_assert (group);
597
598 if (GNUNET_NO == is_epoch_group_completed (group))
599 target = get_epoch_previous_group (group->epoch, &(group->identifier));
600 else
601 target = NULL;
602
603 if (! target)
604 target = group;
605
606 members_count = get_epoch_group_members_count (target);
607 announced = get_epoch_group_members_count (group);
608
609 if (members_count <= announced)
610 return 0.0;
611
612 position = get_epoch_group_member_position (target);
613
614 if (position > announced)
615 position -= announced;
616 else
617 position = 0;
618
619 return (0.0 + position) / (members_count - announced);
620}
621
622
625{
626 const struct GNUNET_CRYPTO_AeadSecretKey *key;
627 const struct GNUNET_CRYPTO_EcdhePrivateKey *private_key;
629 struct GNUNET_MESSENGER_Message *message;
630
631 GNUNET_assert (group);
632
633 key = get_epoch_group_key (group);
634
635 if (! key)
636 return GNUNET_SYSERR;
637
640
642 return GNUNET_NO;
643
646
647 private_key = get_epoch_private_key (group->epoch,
648 timeout);
649
650 if (! private_key)
651 return GNUNET_SYSERR;
652
654
655 message = create_message_announcement (&(group->identifier),
656 private_key,
657 key,
658 timeout);
659
660 if (! message)
661 return GNUNET_SYSERR;
662
663 send_epoch_message (group->epoch, message);
664
667
668 return GNUNET_OK;
669}
670
671
674 const struct GNUNET_HashCode *event)
675{
676 struct GNUNET_MESSENGER_Room *room;
677 const struct GNUNET_CRYPTO_AeadSecretKey *key;
678 const struct GNUNET_MESSENGER_Message *group_message;
679 const struct GNUNET_MESSENGER_Message *announcement_message;
680 const struct GNUNET_CRYPTO_EcdhePublicKey *public_key;
681 struct GNUNET_MESSENGER_Message *message;
682
683 GNUNET_assert ((group) && (event));
684
685 room = group->epoch->room;
686 key = get_epoch_group_key (group);
687
688 if (! key)
689 return GNUNET_SYSERR;
690
691 if (GNUNET_YES != is_room_message_sent (room, event))
692 return GNUNET_SYSERR;
693
694 group_message = get_room_message (room, event);
695
696 if ((! group_message) ||
697 (GNUNET_MESSENGER_KIND_GROUP != group_message->header.kind))
698 return GNUNET_SYSERR;
699
700 announcement_message = get_room_message (room, &(group_message->body.group.
701 partner));
702
703 if ((! announcement_message) ||
704 (GNUNET_MESSENGER_KIND_ANNOUNCEMENT != announcement_message->header.kind))
705 return GNUNET_SYSERR;
706
707 public_key = &(announcement_message->body.announcement.key);
708 message = create_message_access (event,
709 public_key,
710 key);
711
712 if (! message)
713 return GNUNET_SYSERR;
714
715 send_epoch_message (group->epoch, message);
716 return GNUNET_OK;
717}
718
719
722{
723 const struct GNUNET_CRYPTO_AeadSecretKey *key;
724 struct GNUNET_MESSENGER_Message *message;
725
726 GNUNET_assert (group);
727
728 key = get_epoch_group_key (group);
729
730 if (! key)
731 return GNUNET_SYSERR;
732
733 message = create_message_revolution (&(group->identifier),
734 key);
735
736 if (! message)
737 return GNUNET_SYSERR;
738
739 send_epoch_message (group->epoch, message);
740 return GNUNET_OK;
741}
742
743
746 const struct GNUNET_HashCode *initiator_event,
747 const struct GNUNET_HashCode *partner_event,
749{
750 struct GNUNET_MESSENGER_Room *room;
751 const struct GNUNET_MESSENGER_Message *announcement_message;
752 const union GNUNET_MESSENGER_EpochIdentifier *initiator_identifier;
753 const union GNUNET_MESSENGER_EpochIdentifier *partner_identifier;
754 struct GNUNET_MESSENGER_Message *message;
755
756 GNUNET_assert ((group) && (initiator_event) && (partner_event));
757
758 if (0 == GNUNET_CRYPTO_hash_cmp (initiator_event, partner_event))
759 return GNUNET_SYSERR;
760
761 room = group->epoch->room;
762
763 if (GNUNET_YES != is_room_message_sent (room, initiator_event))
764 return GNUNET_SYSERR;
765
766 announcement_message = get_room_message (room, initiator_event);
767
768 if ((! announcement_message) ||
769 (GNUNET_MESSENGER_KIND_ANNOUNCEMENT != announcement_message->header.kind))
770 return GNUNET_SYSERR;
771
772 initiator_identifier = &(announcement_message->body.announcement.identifier);
773
774 if (group->identifier.code.level_bits != initiator_identifier->code.level_bits
775 + 1)
776 return GNUNET_SYSERR;
777
778 announcement_message = get_room_message (room, partner_event);
779
780 if ((! announcement_message) ||
781 (GNUNET_MESSENGER_KIND_ANNOUNCEMENT != announcement_message->header.kind))
782 return GNUNET_SYSERR;
783
784 partner_identifier = &(announcement_message->body.announcement.identifier);
785
786 if (initiator_identifier->code.level_bits != partner_identifier->code.
787 level_bits)
788 return GNUNET_SYSERR;
789
790 if (((initiator_identifier->code.group_bit) || (partner_identifier->code.
791 group_bit)) &&
792 (0 == GNUNET_memcmp (initiator_identifier->code.bits, partner_identifier->
793 code.bits)))
794 return GNUNET_SYSERR;
795
796 if (get_room_sender (room, initiator_event) == get_room_sender (room,
797 partner_event)
798 )
799 return GNUNET_SYSERR;
800
801 message = create_message_group (&(group->identifier),
802 initiator_event,
803 partner_event,
804 timeout);
805
806 if (! message)
807 return GNUNET_SYSERR;
808
809 send_epoch_message (group->epoch, message);
810 return GNUNET_OK;
811}
812
813
816 const struct GNUNET_HashCode *event)
817{
818 struct GNUNET_MESSENGER_Room *room;
819 const struct GNUNET_CRYPTO_AeadSecretKey *key;
820 const struct GNUNET_MESSENGER_Message *group_message;
821 const struct GNUNET_HashCode *announcement_event;
822 const struct GNUNET_MESSENGER_Message *announcement_message;
823 const union GNUNET_MESSENGER_EpochIdentifier *identifier;
824 const struct GNUNET_MESSENGER_EpochGroup *target_group;
825 const struct GNUNET_CRYPTO_AeadSecretKey *group_key;
826 struct GNUNET_MESSENGER_Message *message;
827
828 GNUNET_assert ((group) && (event));
829
830 room = group->epoch->room;
831 key = get_epoch_group_key (group);
832
833 if (! key)
834 return GNUNET_SYSERR;
835
836 group_message = get_room_message (room, event);
837
838 if ((! group_message) ||
839 (GNUNET_MESSENGER_KIND_GROUP != group_message->header.kind))
840 return GNUNET_SYSERR;
841
842 if (0 != GNUNET_memcmp (&(group->identifier), &(group_message->body.group.
843 identifier)))
844 return GNUNET_SYSERR;
845
846 if (GNUNET_YES == is_room_message_sent (room, event))
847 announcement_event = &(group_message->body.group.initiator);
848 else
849 announcement_event = &(group_message->body.group.partner);
850
851 if (GNUNET_YES != is_room_message_sent (room, announcement_event))
852 return GNUNET_SYSERR;
853
854 announcement_message = get_room_message (room, announcement_event);
855
856 if ((! announcement_message) ||
857 (GNUNET_MESSENGER_KIND_ANNOUNCEMENT != announcement_message->header.kind))
858 return GNUNET_SYSERR;
859
860 identifier = &(announcement_message->body.announcement.identifier);
861
862 if (! identifier->code.group_bit)
863 return GNUNET_SYSERR;
864
865 if (0 == GNUNET_memcmp (&(group->identifier), identifier))
866 return GNUNET_SYSERR;
867
868 target_group = get_epoch_group (group->epoch,
869 identifier,
870 GNUNET_YES);
871
872 if (! target_group)
873 return GNUNET_SYSERR;
874
875 if (get_epoch_group_level (target_group) + 1 != get_epoch_group_level (group))
876 return GNUNET_SYSERR;
877
878 group_key = get_epoch_group_key (target_group);
879
880 if (! group_key)
881 return GNUNET_SYSERR;
882
883 message = create_message_authorization (identifier,
884 event,
885 group_key,
886 key);
887
888 if (! message)
889 return GNUNET_SYSERR;
890
891 send_epoch_message (group->epoch, message);
892 return GNUNET_OK;
893}
894
895
896void
898 const struct GNUNET_MESSENGER_Message *message,
899 const struct GNUNET_HashCode *hash,
900 struct GNUNET_MESSENGER_Contact *sender,
902{
903 struct GNUNET_HashCode proposal_hash;
904 const struct GNUNET_CRYPTO_AeadSecretKey *key;
905 enum GNUNET_GenericReturnValue is_proposal;
907
908 GNUNET_assert ((group) && (message) && (hash) && (sender));
909
910 if (GNUNET_YES == is_epoch_group_proposal (group))
911 {
912 GNUNET_memcpy (&(proposal_hash), &(group->epoch->proposal_hash), sizeof (
913 proposal_hash));
914 memset (&(group->epoch->proposal_hash), 0, sizeof (group->epoch->
915 proposal_hash));
916
917 is_proposal = GNUNET_YES;
918
920 }
921 else
922 is_proposal = GNUNET_NO;
923
924 key = get_epoch_group_key (group);
925
926 if (key)
927 {
928 if (GNUNET_OK != verify_message_by_key (message, key))
929 return;
930
931 if ((GNUNET_YES == is_epoch_group_completed (group)) &&
932 (GNUNET_YES != is_epoch_group_member (group, sender)))
933 {
935 return;
936 }
937 }
938
939 if (GNUNET_YES != confirm_epoch_group_member (group, hash, message, sender,
940 sent))
941 return;
942
943 {
944 const struct GNUNET_MESSENGER_EpochGroup *proposal_group;
945
946 proposal_group = get_epoch_proposal_group (group->epoch);
947
948 if ((proposal_group) && (group->epoch->main_group) &&
949 (get_epoch_group_level (proposal_group) <= get_epoch_group_level (
950 group->epoch->main_group)))
952 }
953
954 if ((key) && (GNUNET_YES == is_proposal) &&
956 {
957 send_epoch_group_authorization (group, &proposal_hash);
959 }
960
962
963 delay_room_action (group->epoch->room, hash, timeout);
964}
965
966
967void
969 group,
970 const struct GNUNET_MESSENGER_Message *
971 message,
972 const struct GNUNET_HashCode *hash,
973 struct GNUNET_MESSENGER_Contact *sender,
975{
976 GNUNET_assert ((group) && (message) && (hash) && (sender));
977
978 if (GNUNET_YES == is_room_public (group->epoch->room))
979 return;
980
981 if ((GNUNET_YES == sent) && (GNUNET_YES == group->valid) &&
984}
985
986
987void
989 const struct GNUNET_MESSENGER_Message *message,
990 const struct GNUNET_HashCode *hash)
991{
992 const struct GNUNET_CRYPTO_EcdhePrivateKey *private_key;
993 struct GNUNET_CRYPTO_HpkePrivateKey private_hpke;
994 struct GNUNET_CRYPTO_AeadSecretKey shared_key;
995
996 GNUNET_assert ((group) && (message) && (hash));
997
998 private_key = get_epoch_private_key (group->epoch,
1000
1001 if (! private_key)
1002 {
1004 "Private key for decrypting shared key is missing!\n");
1005 return;
1006 }
1007
1008 GNUNET_memcpy (&private_hpke.ecdhe_key,
1009 private_key,
1010 sizeof *private_key);
1011 if (GNUNET_NO == extract_access_message_key (message,
1012 &private_hpke,
1013 &shared_key
1014 ))
1015 return;
1016
1017 set_epoch_group_key (group, &shared_key, GNUNET_YES);
1018
1019 if ((group->epoch->main_group) && (group != group->epoch->main_group) &&
1021 main_group)))
1022 return;
1023
1025
1026 send_epoch_group_authorization (group, &(message->body.access.event));
1028}
1029
1030
1031static void
1033 enum GNUNET_ErrorCode ec)
1034{
1035 struct GNUNET_MESSENGER_EpochGroup *group;
1036
1037 GNUNET_assert (cls);
1038
1039 group = cls;
1040
1041 if (GNUNET_EC_NONE != ec)
1043 "Error writing group key record: %d\n", (int) ec);
1044
1045 group->query = NULL;
1046}
1047
1048
1049void
1051 enum GNUNET_GenericReturnValue deleted)
1052{
1053 const struct GNUNET_MESSENGER_Handle *handle;
1054 const struct GNUNET_HashCode *hash;
1055 const struct GNUNET_ShortHashCode *identifier;
1056 const struct GNUNET_CRYPTO_AeadSecretKey *shared_key;
1057
1058 GNUNET_assert ((group) && (group->epoch));
1059
1060 handle = get_room_handle (group->epoch->room);
1061
1062 if (! handle)
1063 return;
1064
1065 hash = &(group->epoch->hash);
1066 identifier = &(group->identifier.hash);
1067
1068 if (GNUNET_YES == deleted)
1069 {
1070 shared_key = NULL;
1071 }
1072 else
1073 {
1074 shared_key = group->shared_key;
1075
1076 if (! shared_key)
1077 return;
1078 }
1079
1081 handle, group->epoch->room,
1082 hash, identifier, shared_key,
1083 GNUNET_YES == group->valid?
1087 group,
1088 &(group->query));
1089}
static struct GNUNET_TIME_Relative timeout
User defined timestamp for completing operations.
Definition gnunet-arm.c:118
struct GNUNET_HashCode key
The key used in the DHT.
static int result
Global testing status.
struct GNUNET_REGEX_Announcement * announcement
static struct GNUNET_VPN_Handle * handle
Handle to vpn service.
Definition gnunet-vpn.c:35
GNUNET_ErrorCode
Taler error codes.
@ GNUNET_EC_NONE
No error (success).
void GNUNET_CRYPTO_random_block(void *buffer, size_t length)
Fill block with a random values.
#define GNUNET_CRYPTO_hkdf_gnunet(result, out_len, xts, xts_len, skm, skm_len,...)
A peculiar HKDF instantiation that tried to mimic Truncated NMAC.
int GNUNET_CRYPTO_hash_cmp(const struct GNUNET_HashCode *h1, const struct GNUNET_HashCode *h2)
Compare function for HashCodes, producing a total ordering of all hashcodes.
#define GNUNET_log(kind,...)
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_CRYPTO_kdf_arg_auto(d)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
void GNUNET_CRYPTO_aead_create_key(struct GNUNET_CRYPTO_AeadSecretKey *key)
Create a new AEAD key.
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
@ GNUNET_MESSENGER_KIND_ANNOUNCEMENT
The announcement kind.
@ GNUNET_MESSENGER_KIND_LEAVE
The leave kind.
@ GNUNET_MESSENGER_KIND_JOIN
The join kind.
@ GNUNET_MESSENGER_KIND_MERGE
The merge kind.
@ GNUNET_MESSENGER_KIND_GROUP
The group kind.
@ GNUNET_MESSENGER_FLAG_EPOCH_NONE
The none flag.
@ GNUNET_MESSENGER_FLAG_EPOCH_VALID
The valid flag.
void GNUNET_NAMESTORE_cancel(struct GNUNET_NAMESTORE_QueueEntry *qe)
Cancel a namestore operation.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_get_zero_(void)
Return relative time of 0ms.
Definition time.c:133
struct GNUNET_TIME_Relative GNUNET_TIME_relative_get_hour_(void)
Return relative time of 1 hour.
Definition time.c:187
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get_zero_(void)
Return absolute time of 0ms.
Definition time.c:142
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition time.c:406
bool GNUNET_TIME_relative_is_zero(struct GNUNET_TIME_Relative rel)
Test if rel is zero.
Definition time.c:660
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition time.c:486
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_add(struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Relative duration)
Add a given relative duration to the given start time.
Definition time.c:452
const struct GNUNET_TIME_Relative get_epoch_private_key_timeout(const struct GNUNET_MESSENGER_Epoch *epoch)
Returns the current relative timeout for the private key (ECDHE) of a given epoch that limits the usa...
void cancel_epoch_proposal_group(struct GNUNET_MESSENGER_Epoch *epoch)
Cancels the current proposal of a new group from a given epoch.
struct GNUNET_MESSENGER_EpochGroup * get_epoch_group(struct GNUNET_MESSENGER_Epoch *epoch, const union GNUNET_MESSENGER_EpochIdentifier *identifier, enum GNUNET_GenericReturnValue valid)
Returns the epoch group of a given epoch using a specific unique identifier or NULL.
const struct GNUNET_MESSENGER_EpochGroup * get_epoch_previous_group(struct GNUNET_MESSENGER_Epoch *epoch, const union GNUNET_MESSENGER_EpochIdentifier *identifier)
Returns the epoch group of a previous epoch from a given epoch using a specific group identifier.
enum GNUNET_GenericReturnValue is_epoch_member(const struct GNUNET_MESSENGER_Epoch *epoch, const struct GNUNET_MESSENGER_Contact *contact)
Returns whether a specific contact is member of a given epoch.
const struct GNUNET_CRYPTO_EcdhePrivateKey * get_epoch_private_key(struct GNUNET_MESSENGER_Epoch *epoch, const struct GNUNET_TIME_Relative timeout)
Returns the asymmetric private key (ECDHE) from a handle for a given epoch that can be used for HPKE ...
void propose_epoch_group(struct GNUNET_MESSENGER_Epoch *epoch, const struct GNUNET_TIME_Relative timeout)
Tries to propose a new group inside a given epoch that will automatically be formed by using the clie...
void send_epoch_message(const struct GNUNET_MESSENGER_Epoch *epoch, struct GNUNET_MESSENGER_Message *message)
Sends a created and allocated message in a room of a given epoch enforcing the message gets interpret...
const struct GNUNET_MESSENGER_EpochGroup * get_epoch_proposal_group(struct GNUNET_MESSENGER_Epoch *epoch)
Returns the current group of proposal for a given epoch.
void update_epoch_group(struct GNUNET_MESSENGER_Epoch *epoch, struct GNUNET_MESSENGER_EpochGroup *group)
Updates the main group of a given epoch, looking into replacing the current main group with a specifi...
enum GNUNET_GenericReturnValue is_epoch_announcement_member(const struct GNUNET_MESSENGER_EpochAnnouncement *announcement, const struct GNUNET_MESSENGER_Contact *contact)
Returns whether a specific contact is confirmed member of a given epoch announcement.
uint32_t get_epoch_announcement_members_count(const struct GNUNET_MESSENGER_EpochAnnouncement *announcement)
Returns the current amount of members of a given epoch announcement.
void write_epoch_group_record(struct GNUNET_MESSENGER_EpochGroup *group, enum GNUNET_GenericReturnValue deleted)
Writes/Deletes the GNS record of a given epoch group depending on a provided flag that states whether...
enum GNUNET_GenericReturnValue send_epoch_group_announcement(struct GNUNET_MESSENGER_EpochGroup *group)
Tries to send an announcement message by the client for a given epoch group using its secret key.
const struct GNUNET_CRYPTO_AeadSecretKey * get_epoch_group_key(const struct GNUNET_MESSENGER_EpochGroup *group)
Returns the secret key of a given epoch group or NULL.
static enum GNUNET_GenericReturnValue is_epoch_group_key_derived_from(const struct GNUNET_MESSENGER_EpochGroup *group, const struct GNUNET_MESSENGER_EpochGroup *previous)
enum GNUNET_GenericReturnValue is_epoch_group_announced(const struct GNUNET_MESSENGER_EpochGroup *group)
Returns whether the client has announced being part of a given epoch group owning its secret key.
enum GNUNET_GenericReturnValue is_epoch_group_compatible(const struct GNUNET_MESSENGER_EpochGroup *group, const struct GNUNET_MESSENGER_Epoch *epoch)
Returns whether a given epoch group is compatible with a specific epoch with its members.
enum GNUNET_GenericReturnValue it_check_epoch_group_member(void *cls, const struct GNUNET_MESSENGER_Contact *member)
static void random_epoch_group_identifier(uint32_t level, union GNUNET_MESSENGER_EpochIdentifier *identifier)
enum GNUNET_GenericReturnValue it_check_epoch_announcement_member(void *cls, const struct GNUNET_MESSENGER_Contact *member)
enum GNUNET_GenericReturnValue is_epoch_group_proposal(const struct GNUNET_MESSENGER_EpochGroup *group)
Returns whether a given epoch group is the current proposal of the client.
enum GNUNET_GenericReturnValue it_check_epoch_member(void *cls, const struct GNUNET_MESSENGER_Contact *member)
void handle_epoch_group_announcement_delay(struct GNUNET_MESSENGER_EpochGroup *group, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash, struct GNUNET_MESSENGER_Contact *sender, enum GNUNET_GenericReturnValue sent)
Handles an announcement message with hash from its sender inside a given epoch group as second stage ...
void invalidate_epoch_group(struct GNUNET_MESSENGER_EpochGroup *group, const struct GNUNET_MESSENGER_Contact *contact)
Invalidates a given epoch group by a specific contact.
uint32_t get_epoch_group_members_count(const struct GNUNET_MESSENGER_EpochGroup *group)
Returns the current amount of members of a given epoch group.
enum GNUNET_GenericReturnValue send_epoch_group_authorization(struct GNUNET_MESSENGER_EpochGroup *group, const struct GNUNET_HashCode *event)
Tries to send an authorization message by the client responding to a previous event in regards to a g...
enum GNUNET_GenericReturnValue is_epoch_group_subgroup_of(const struct GNUNET_MESSENGER_EpochGroup *group, const struct GNUNET_MESSENGER_EpochGroup *other)
Returns whether a given epoch group is subgroup of a specific other group.
static enum GNUNET_GenericReturnValue derive_epoch_group_key(const struct GNUNET_MESSENGER_EpochGroup *group, const struct GNUNET_MESSENGER_EpochGroup *previous, struct GNUNET_CRYPTO_AeadSecretKey *key)
static uint32_t get_epoch_group_member_position(const struct GNUNET_MESSENGER_EpochGroup *group)
enum GNUNET_GenericReturnValue send_epoch_group(struct GNUNET_MESSENGER_EpochGroup *group, const struct GNUNET_HashCode *initiator_event, const struct GNUNET_HashCode *partner_event, struct GNUNET_TIME_Relative timeout)
Tries to send a group message by the client for a given epoch group to propose it forming a group out...
uint32_t get_epoch_group_size(const struct GNUNET_MESSENGER_EpochGroup *group)
Returns the size of a given epoch group in terms of members.
struct GNUNET_MESSENGER_EpochGroup * create_epoch_group(struct GNUNET_MESSENGER_Epoch *epoch, const union GNUNET_MESSENGER_EpochIdentifier *identifier, uint32_t level, enum GNUNET_GenericReturnValue valid)
Creates and allocates a new epoch group for a given epoch using a specific group identifier or NULL a...
static void cont_write_epoch_group_record(void *cls, enum GNUNET_ErrorCode ec)
double get_epoch_group_position_factor(const struct GNUNET_MESSENGER_EpochGroup *group)
Returns a relative member position of the client inside a given epoch group in relation to its list o...
void destroy_epoch_group(struct GNUNET_MESSENGER_EpochGroup *group)
Destroys a given epoch group and frees its resources.
enum GNUNET_GenericReturnValue is_epoch_group_member(const struct GNUNET_MESSENGER_EpochGroup *group, const struct GNUNET_MESSENGER_Contact *contact)
Returns whether a specific contact is confirmed member of a given epoch group.
enum GNUNET_GenericReturnValue confirm_epoch_group_member(struct GNUNET_MESSENGER_EpochGroup *group, const struct GNUNET_HashCode *hash, const struct GNUNET_MESSENGER_Message *message, struct GNUNET_MESSENGER_Contact *contact, enum GNUNET_GenericReturnValue sent)
Confirms an announcement message with its hash to a given epoch group as confirmation for a specific ...
void handle_epoch_group_access(struct GNUNET_MESSENGER_EpochGroup *group, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash)
Handles an access message with hash from its sender inside a given epoch group.
enum GNUNET_GenericReturnValue is_epoch_group_completed(const struct GNUNET_MESSENGER_EpochGroup *group)
Returns whether a given epoch group is complete in terms of confirmed announcements from its members.
enum GNUNET_GenericReturnValue send_epoch_group_access(struct GNUNET_MESSENGER_EpochGroup *group, const struct GNUNET_HashCode *event)
Tries to send an access message by the client responding to a previous event in regards to a given ep...
void set_epoch_group_key(struct GNUNET_MESSENGER_EpochGroup *group, const struct GNUNET_CRYPTO_AeadSecretKey *shared_key, enum GNUNET_GenericReturnValue write_record)
Sets the secret key of a given epoch group to a shared key.
enum GNUNET_GenericReturnValue is_epoch_group_missing_announcement(const struct GNUNET_MESSENGER_EpochGroup *group, const struct GNUNET_MESSENGER_EpochAnnouncement *announcement)
Returns whether any member of a given epoch group is missing in a provided epoch announcement.
uint32_t get_epoch_group_level(const struct GNUNET_MESSENGER_EpochGroup *group)
Returns the group level of a given epoch group.
enum GNUNET_GenericReturnValue send_epoch_group_revolution(struct GNUNET_MESSENGER_EpochGroup *group)
Tries to send a revolution message by the client for a given epoch group using its secret key.
void handle_epoch_group_announcement(struct GNUNET_MESSENGER_EpochGroup *group, const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash, struct GNUNET_MESSENGER_Contact *sender, enum GNUNET_GenericReturnValue sent)
Handles an announcement message with hash from its sender inside a given epoch group as first stage.
enum GNUNET_GenericReturnValue get_epoch_group_member_hash(const struct GNUNET_MESSENGER_EpochGroup *group, struct GNUNET_HashCode *hash, enum GNUNET_GenericReturnValue other)
Provides an announcement hash of a member from a given epoch group.
enum GNUNET_GenericReturnValue is_epoch_membership_member(const struct GNUNET_MESSENGER_EpochMembership *membership, const struct GNUNET_MESSENGER_Contact *contact)
Returns whether a specific contact is announced member of a given epoch membership.
enum GNUNET_GenericReturnValue confirm_epoch_membership_announcment(struct GNUNET_MESSENGER_EpochMembership *membership, const struct GNUNET_HashCode *hash, const struct GNUNET_MESSENGER_Message *message, struct GNUNET_MESSENGER_Contact *contact, enum GNUNET_GenericReturnValue sent)
Adds an announcement message with its hash to a given epoch membership as confirmation for a specific...
int iterate_epoch_membership_members(const struct GNUNET_MESSENGER_EpochMembership *membership, GNUNET_MESSENGER_MembershipCallback callback, void *cls)
Iterate through all confirmed members of a given epoch membership and pass them through a provided ca...
enum GNUNET_GenericReturnValue is_epoch_membership_completed(const struct GNUNET_MESSENGER_EpochMembership *membership)
Returns whether a given epoch membership is complete, meaning that all of its intended members have p...
struct GNUNET_MESSENGER_EpochMembership * create_epoch_membership(uint32_t size)
Creates and allocates a new membership for subgroups of an epoch with specified size.
enum GNUNET_GenericReturnValue get_epoch_membership_member_hash(const struct GNUNET_MESSENGER_EpochMembership *membership, struct GNUNET_HashCode *hash, enum GNUNET_GenericReturnValue other)
Provides an announcement hash of a member from a given epoch membership.
uint32_t get_epoch_membership_member_position(const struct GNUNET_MESSENGER_EpochMembership *membership)
Returns the index position of the client inside a given epoch in relation to its list of members.
void destroy_epoch_membership(struct GNUNET_MESSENGER_EpochMembership *membership)
Destroys and frees resources of a given membership.
uint32_t get_epoch_membership_count(const struct GNUNET_MESSENGER_EpochMembership *membership)
Returns the current amount of individual members inside a given epoch membership.
enum GNUNET_GenericReturnValue store_handle_epoch_key(const struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_MESSENGER_Room *room, const struct GNUNET_HashCode *hash, const struct GNUNET_ShortHashCode *identifier, const struct GNUNET_CRYPTO_AeadSecretKey *shared_key, uint32_t flags, GNUNET_NAMESTORE_ContinuationWithStatus cont, void *cont_cls, struct GNUNET_NAMESTORE_QueueEntry **query)
Stores/deletes a shared_key for a given room from a handle in an epoch with certain hash using a spec...
enum GNUNET_GenericReturnValue extract_access_message_key(const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_CRYPTO_HpkePrivateKey *key, struct GNUNET_CRYPTO_AeadSecretKey *shared_key)
Extracts the shared epoch or group key from an access message using the private ephemeral key from an...
enum GNUNET_GenericReturnValue verify_message_by_key(const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_CRYPTO_AeadSecretKey *key)
Verifies the hmac of a given message body with a specific shared key.
#define GNUNET_MESSENGER_SALT_GROUP_KEY
struct GNUNET_MESSENGER_Message * create_message_announcement(const union GNUNET_MESSENGER_EpochIdentifier *identifier, const struct GNUNET_CRYPTO_EcdhePrivateKey *private_key, const struct GNUNET_CRYPTO_AeadSecretKey *shared_key, const struct GNUNET_TIME_Relative timeout)
Creates and allocates a new announcement message for an announcement of a given epoch or group under ...
struct GNUNET_MESSENGER_Message * create_message_authorization(const union GNUNET_MESSENGER_EpochIdentifier *identifier, const struct GNUNET_HashCode *event, const struct GNUNET_CRYPTO_AeadSecretKey *group_key, const struct GNUNET_CRYPTO_AeadSecretKey *shared_key)
Creates and allocates a new authorization message to grant access to the shared_key of a specific gro...
struct GNUNET_MESSENGER_Message * create_message_revolution(const union GNUNET_MESSENGER_EpochIdentifier *identifier, const struct GNUNET_CRYPTO_AeadSecretKey *shared_key)
Creates and allocates a new revolution message for an announced epoch or group selected by its identi...
struct GNUNET_MESSENGER_Message * create_message_group(const union GNUNET_MESSENGER_EpochIdentifier *identifier, const struct GNUNET_HashCode *initiator, const struct GNUNET_HashCode *partner, const struct GNUNET_TIME_Relative timeout)
Creates and allocates a new group message to propose a group formation between an initiator subgroup ...
struct GNUNET_MESSENGER_Message * create_message_access(const struct GNUNET_HashCode *event, const struct GNUNET_CRYPTO_EcdhePublicKey *public_key, const struct GNUNET_CRYPTO_AeadSecretKey *shared_key)
Creates and allocates a new access message to grant access to the shared_key of an announced epoch or...
struct GNUNET_MESSENGER_Contact * get_room_sender(const struct GNUNET_MESSENGER_Room *room, const struct GNUNET_HashCode *hash)
Returns a messages sender locally stored from a map for a given hash in a room.
enum GNUNET_GenericReturnValue is_room_message_sent(const struct GNUNET_MESSENGER_Room *room, const struct GNUNET_HashCode *hash)
Returns whether a message is sent by the handle of the given room itself or another client that is us...
const struct GNUNET_MESSENGER_Message * get_room_message(const struct GNUNET_MESSENGER_Room *room, const struct GNUNET_HashCode *hash)
Returns a message locally stored from a map for a given hash in a room.
struct GNUNET_MESSENGER_Epoch * get_room_epoch(struct GNUNET_MESSENGER_Room *room, const struct GNUNET_HashCode *hash, enum GNUNET_GenericReturnValue recent)
Returns the epoch in a given room from a specific epoch hash that represents the exact message the ep...
enum GNUNET_GenericReturnValue is_room_public(const struct GNUNET_MESSENGER_Room *room)
Returns whether a given room is public or using epoch keys to encrypt private traffic and sync those ...
struct GNUNET_MESSENGER_Handle * get_room_handle(struct GNUNET_MESSENGER_Room *room)
Returns the messenger handle of the room.
void delay_room_action(struct GNUNET_MESSENGER_Room *room, const struct GNUNET_HashCode *hash, const struct GNUNET_TIME_Relative delay)
Enqueues delayed handling of a message in a room under a given hash once a specific delay has timed o...
Private ECC key encoded for transmission.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
A public key used for decryption.
struct GNUNET_CRYPTO_EcdhePrivateKey ecdhe_key
An ECDHE/X25519 key.
A 512-bit hashcode.
const struct GNUNET_MESSENGER_EpochAnnouncement * announcement
const struct GNUNET_MESSENGER_EpochGroup * group
enum GNUNET_GenericReturnValue result
enum GNUNET_GenericReturnValue result
const struct GNUNET_MESSENGER_Epoch * epoch
enum GNUNET_GenericReturnValue valid
enum GNUNET_GenericReturnValue stored
struct GNUNET_NAMESTORE_QueueEntry * query
struct GNUNET_MESSENGER_Epoch * epoch
struct GNUNET_MESSENGER_EpochMembership * membership
struct GNUNET_CRYPTO_AeadSecretKey * shared_key
struct GNUNET_TIME_Absolute announcement_expiration
union GNUNET_MESSENGER_EpochIdentifier identifier
uint8_t bits[sizeof(struct GNUNET_ShortHashCode) - 1]
struct GNUNET_MESSENGER_Room * room
struct GNUNET_MESSENGER_EpochGroup * main_group
const struct GNUNET_MESSENGER_Contact ** members
struct GNUNET_HashCode proposal_hash
struct GNUNET_HashCode hash
struct GNUNET_HashCode event
The hash of the linked announcement or group message event.
union GNUNET_MESSENGER_EpochIdentifier identifier
The identifier of the announcement in an epoch.
struct GNUNET_CRYPTO_EcdhePublicKey key
The public key to appeal access.
struct GNUNET_MESSENGER_MessageAnnouncement announcement
struct GNUNET_MESSENGER_MessageGroup group
struct GNUNET_MESSENGER_MessageMerge merge
struct GNUNET_MESSENGER_MessageLeave leave
struct GNUNET_MESSENGER_MessageAccess access
struct GNUNET_MESSENGER_MessageJoin join
struct GNUNET_HashCode initiator
The hash of the initiator group announcement.
struct GNUNET_HashCode partner
The hash of the partner group announcement.
enum GNUNET_MESSENGER_MessageKind kind
The kind of the message.
struct GNUNET_HashCode epoch
The previous epoch the message was sent from.
struct GNUNET_HashCode epoch
The previous epoch the message was sent from.
struct GNUNET_HashCode epochs[2]
The previous epochs the message was sent from.
struct GNUNET_MESSENGER_MessageHeader header
Header.
struct GNUNET_MESSENGER_MessageBody body
Body.
A 256-bit hashcode.
Time for relative time used by GNUnet, in microseconds.
An epoch identifier unifies an epoch identifier code and its 256bit hash representation.
struct GNUNET_MESSENGER_EpochIdentifierCode code