GNUnet 0.27.0
 
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 identifier,
42 sizeof (*identifier));
43
44 identifier->code.group_bit = 1;
45 identifier->code.level_bits = 0x7F & level;
46}
47
48
51 const struct GNUNET_MESSENGER_EpochGroup *previous,
53{
54 const struct GNUNET_CRYPTO_SymmetricSessionKey *previous_key;
55
56 GNUNET_assert ((group) && (previous) && (key));
57
58 previous_key = get_epoch_group_key (previous);
59
60 if (! previous_key)
61 return GNUNET_SYSERR;
62
64 key, sizeof (*key),
67 previous_key,
68 sizeof (*previous_key),
71 return GNUNET_SYSERR;
72 else
73 return GNUNET_OK;
74}
75
76
81 uint32_t level,
83{
84 struct GNUNET_MESSENGER_EpochGroup *group;
85 const struct GNUNET_MESSENGER_EpochGroup *previous;
86
88
90
91 if (! group)
92 return NULL;
93
95
96 if ((GNUNET_YES == valid) && (previous) &&
97 (GNUNET_YES != previous->valid))
98 previous = NULL;
99
100 if (identifier)
102 sizeof (group->identifier));
103 else
104 random_epoch_group_identifier (level, &(group->identifier));
105
107
109
110 group->epoch = epoch;
112 group->shared_key = NULL;
113 group->query = NULL;
114
115 group->valid = GNUNET_YES;
116 group->stored = GNUNET_NO;
117
118 if (previous)
119 {
121
122 if (GNUNET_OK == derive_epoch_group_key (group,
123 previous,
124 &key))
125 {
127 group->valid = previous->valid;
128 }
129 }
130
131 return group;
132}
133
134
135void
137{
138 GNUNET_assert (group);
139
140 if (group->membership)
142
143 if (group->shared_key)
144 GNUNET_free (group->shared_key);
145
146 if (group->query)
148
149 GNUNET_free (group);
150}
151
152
153uint32_t
155{
156 GNUNET_assert (group);
157
158 return group->identifier.code.level_bits;
159}
160
161
162uint32_t
164{
165 GNUNET_assert (group);
166
167 return 0x1 << get_epoch_group_level (group);
168}
169
170
171uint32_t
173 group)
174{
175 GNUNET_assert (group);
176
178}
179
180
183{
184 GNUNET_assert (group);
185
187}
188
189
192{
193 GNUNET_assert (group);
194
195 return is_epoch_membership_member (group->membership, NULL);
196}
197
198
199void
201 const struct GNUNET_CRYPTO_SymmetricSessionKey *shared_key,
202 enum GNUNET_GenericReturnValue write_record)
203{
204 GNUNET_assert (group);
205
206 if ((GNUNET_NO == write_record) && (shared_key))
207 group->stored = GNUNET_YES;
208
209 if (group->shared_key)
210 return;
211
213
214 if (! group->shared_key)
215 return;
216
217 if (shared_key)
218 GNUNET_memcpy (group->shared_key, shared_key,
219 sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey));
220 else
222
223 update_epoch_group (group->epoch, group);
224
225 if (GNUNET_YES != group->stored)
227}
228
229
232{
233 GNUNET_assert (group);
234
235 return group->shared_key;
236}
237
238
241 ,
242 const struct GNUNET_MESSENGER_EpochGroup *
243 previous)
244{
245 const struct GNUNET_CRYPTO_SymmetricSessionKey *shared_key;
247
248 GNUNET_assert ((group) && (previous));
249
250 shared_key = get_epoch_group_key (group);
251
252 if (! shared_key)
253 return GNUNET_SYSERR;
254
255 if (GNUNET_OK != derive_epoch_group_key (group, previous, &key))
256 return GNUNET_SYSERR;
257
258 if (0 == GNUNET_memcmp (shared_key, &key))
259 return GNUNET_YES;
260 else
261 return GNUNET_NO;
262}
263
264
267 const struct GNUNET_HashCode *hash,
268 const struct GNUNET_MESSENGER_Message *message,
269 struct GNUNET_MESSENGER_Contact *contact,
271{
273
274 GNUNET_assert ((group) && (hash) && (message) && (contact));
275
276 if (GNUNET_YES != is_epoch_member (group->epoch, contact))
277 return GNUNET_SYSERR;
278
280 hash,
281 message,
282 contact,
283 sent);
284
285 if (GNUNET_YES != result)
286 return result;
287
288 update_epoch_group (group->epoch, group);
289 return GNUNET_YES;
290}
291
292
293static uint32_t
301
302
305 const struct GNUNET_MESSENGER_Contact *contact)
306{
307 GNUNET_assert ((group) && (contact));
308
309 return is_epoch_membership_member (group->membership, contact);
310}
311
312
318
321 const struct GNUNET_MESSENGER_Contact *member)
322{
324
325 GNUNET_assert ((cls) && (member));
326
327 check = cls;
328
329 if (GNUNET_YES == is_epoch_group_member (check->group, member))
330 return GNUNET_YES;
331
332 check->result = GNUNET_NO;
333 return GNUNET_NO;
334}
335
336
339 const struct GNUNET_MESSENGER_EpochGroup *other)
340{
342
343 GNUNET_assert ((group) && (other));
344
345 if (group == other)
346 return GNUNET_YES;
347
349 return GNUNET_NO;
350
352 return GNUNET_NO;
353
354 check.group = other;
355 check.result = GNUNET_YES;
356
359 &check);
360
361 return check.result;
362}
363
364
367 struct GNUNET_HashCode *hash,
368 enum GNUNET_GenericReturnValue other)
369{
370 GNUNET_assert ((group) && (hash));
371
373}
374
375
376void
378 const struct GNUNET_MESSENGER_Contact *contact)
379{
380 const struct GNUNET_MESSENGER_Message *message;
381 struct GNUNET_MESSENGER_EpochGroup *previous;
382 struct GNUNET_MESSENGER_Epoch *epoch;
383
384 GNUNET_assert (group);
385
386 if (GNUNET_NO == group->valid)
387 return;
388
389 if ((contact) && (GNUNET_YES != is_epoch_member (group->epoch, contact)))
390 return;
391
392 group->valid = GNUNET_NO;
394
395 message = get_room_message (group->epoch->room, &(group->epoch->hash));
396
397 if (! message)
398 goto skip_traversal;
399
400 switch (message->header.kind)
401 {
403 epoch = get_room_epoch (
404 group->epoch->room, &(message->body.join.epoch), GNUNET_NO);
405
406 if (epoch)
407 previous = get_epoch_group (
408 epoch, &(group->identifier), GNUNET_SYSERR);
409 else
410 previous = NULL;
411 break;
413 epoch = get_room_epoch (
414 group->epoch->room, &(message->body.leave.epoch), GNUNET_NO);
415
416 if (epoch)
417 previous = get_epoch_group (
418 epoch, &(group->identifier), GNUNET_SYSERR);
419 else
420 previous = NULL;
421 break;
423 epoch = get_room_epoch (
424 group->epoch->room, &(message->body.merge.epochs[0]), GNUNET_NO);
425
426 if (epoch)
427 {
428 previous = get_epoch_group (
429 epoch, &(group->identifier), GNUNET_SYSERR);
430
431 if ((previous) &&
432 (GNUNET_YES != is_epoch_group_key_derived_from (previous, group)))
433 previous = NULL;
434 }
435 else
436 previous = NULL;
437
438 if (! previous)
439 {
440 epoch = get_room_epoch (
441 group->epoch->room, &(message->body.merge.epochs[1]), GNUNET_NO);
442
443 if (epoch)
444 previous = get_epoch_group (
445 epoch, &(group->identifier), GNUNET_SYSERR);
446 }
447 break;
448 default:
449 previous = NULL;
450 break;
451 }
452
453 if ((previous) &&
454 (GNUNET_YES != is_epoch_group_key_derived_from (previous, group)))
455 previous = NULL;
456
457 if (previous)
458 invalidate_epoch_group (previous, contact);
459
460skip_traversal:
461 if (group->epoch->main_group != group)
462 return;
463
465 group->epoch, NULL, GNUNET_YES);
466}
467
468
471{
472 GNUNET_assert (group);
473
474 if (get_epoch_proposal_group (group->epoch) == group)
475 return GNUNET_YES;
476 else
477 return GNUNET_NO;
478}
479
480
486
489 const struct GNUNET_MESSENGER_Contact *member)
490{
491 struct GNUNET_MESSENGER_CheckEpoch *check;
492 uint32_t i;
493
494 GNUNET_assert ((cls) && (member));
495
496 check = cls;
497
498 for (i = 0; i < check->epoch->members_count; i++)
499 if (member == check->epoch->members[i])
500 return GNUNET_YES;
501
502 check->result = GNUNET_NO;
503 return GNUNET_NO;
504}
505
506
509 const struct GNUNET_MESSENGER_Epoch *epoch)
510{
511 struct GNUNET_MESSENGER_CheckEpoch check;
512
513 GNUNET_assert ((group) && (epoch));
514
516 return GNUNET_NO;
517
518 if (GNUNET_YES != group->valid)
519 return GNUNET_NO;
520
521 if (group->epoch == epoch)
522 return GNUNET_YES;
523
524 if (0 == epoch->members_count)
525 return GNUNET_NO;
526
527 check.epoch = epoch;
528 check.result = GNUNET_YES;
529
532 &check);
533
534 return check.result;
535}
536
537
543
546 const struct GNUNET_MESSENGER_Contact *
547 member)
548{
550
551 GNUNET_assert ((cls) && (member));
552
553 check = cls;
554
556 return GNUNET_YES;
557
558 check->result = GNUNET_YES;
559 return GNUNET_NO;
560}
561
562
565 group,
566 const struct
569{
571
572 GNUNET_assert ((group) && (announcement));
573
575 return GNUNET_YES;
576
578 check.result = GNUNET_NO;
579
582 &check);
583
584 return check.result;
585}
586
587
588double
590 group)
591{
592 const struct GNUNET_MESSENGER_EpochGroup *target;
593 uint32_t members_count;
594 uint32_t announced;
595 uint32_t position;
596
597 GNUNET_assert (group);
598
599 if (GNUNET_NO == is_epoch_group_completed (group))
600 target = get_epoch_previous_group (group->epoch, &(group->identifier));
601 else
602 target = NULL;
603
604 if (! target)
605 target = group;
606
607 members_count = get_epoch_group_members_count (target);
608 announced = get_epoch_group_members_count (group);
609
610 if (members_count <= announced)
611 return 0.0;
612
613 position = get_epoch_group_member_position (target);
614
615 if (position > announced)
616 position -= announced;
617 else
618 position = 0;
619
620 return (0.0 + position) / (members_count - announced);
621}
622
623
626{
628 const struct GNUNET_CRYPTO_EcdhePrivateKey *private_key;
630 struct GNUNET_MESSENGER_Message *message;
631
632 GNUNET_assert (group);
633
634 key = get_epoch_group_key (group);
635
636 if (! key)
637 return GNUNET_SYSERR;
638
641
643 return GNUNET_NO;
644
647
648 private_key = get_epoch_private_key (group->epoch,
649 timeout);
650
651 if (! private_key)
652 return GNUNET_SYSERR;
653
655
656 message = create_message_announcement (&(group->identifier),
657 private_key,
658 key,
659 timeout);
660
661 if (! message)
662 return GNUNET_SYSERR;
663
664 send_epoch_message (group->epoch, message);
665
668
669 return GNUNET_OK;
670}
671
672
675 const struct GNUNET_HashCode *event)
676{
677 struct GNUNET_MESSENGER_Room *room;
679 const struct GNUNET_MESSENGER_Message *group_message;
680 const struct GNUNET_MESSENGER_Message *announcement_message;
681 const struct GNUNET_CRYPTO_EcdhePublicKey *public_key;
682 struct GNUNET_MESSENGER_Message *message;
683
684 GNUNET_assert ((group) && (event));
685
686 room = group->epoch->room;
687 key = get_epoch_group_key (group);
688
689 if (! key)
690 return GNUNET_SYSERR;
691
692 if (GNUNET_YES != is_room_message_sent (room, event))
693 return GNUNET_SYSERR;
694
695 group_message = get_room_message (room, event);
696
697 if ((! group_message) ||
698 (GNUNET_MESSENGER_KIND_GROUP != group_message->header.kind))
699 return GNUNET_SYSERR;
700
701 announcement_message = get_room_message (room, &(group_message->body.group.
702 partner));
703
704 if ((! announcement_message) ||
705 (GNUNET_MESSENGER_KIND_ANNOUNCEMENT != announcement_message->header.kind))
706 return GNUNET_SYSERR;
707
708 public_key = &(announcement_message->body.announcement.key);
709 message = create_message_access (event,
710 public_key,
711 key);
712
713 if (! message)
714 return GNUNET_SYSERR;
715
716 send_epoch_message (group->epoch, message);
717 return GNUNET_OK;
718}
719
720
723{
725 struct GNUNET_MESSENGER_Message *message;
726
727 GNUNET_assert (group);
728
729 key = get_epoch_group_key (group);
730
731 if (! key)
732 return GNUNET_SYSERR;
733
734 message = create_message_revolution (&(group->identifier),
735 key);
736
737 if (! message)
738 return GNUNET_SYSERR;
739
740 send_epoch_message (group->epoch, message);
741 return GNUNET_OK;
742}
743
744
747 const struct GNUNET_HashCode *initiator_event,
748 const struct GNUNET_HashCode *partner_event,
750{
751 struct GNUNET_MESSENGER_Room *room;
752 const struct GNUNET_MESSENGER_Message *announcement_message;
753 const union GNUNET_MESSENGER_EpochIdentifier *initiator_identifier;
754 const union GNUNET_MESSENGER_EpochIdentifier *partner_identifier;
755 struct GNUNET_MESSENGER_Message *message;
756
757 GNUNET_assert ((group) && (initiator_event) && (partner_event));
758
759 if (0 == GNUNET_CRYPTO_hash_cmp (initiator_event, partner_event))
760 return GNUNET_SYSERR;
761
762 room = group->epoch->room;
763
764 if (GNUNET_YES != is_room_message_sent (room, initiator_event))
765 return GNUNET_SYSERR;
766
767 announcement_message = get_room_message (room, initiator_event);
768
769 if ((! announcement_message) ||
770 (GNUNET_MESSENGER_KIND_ANNOUNCEMENT != announcement_message->header.kind))
771 return GNUNET_SYSERR;
772
773 initiator_identifier = &(announcement_message->body.announcement.identifier);
774
775 if (group->identifier.code.level_bits != initiator_identifier->code.level_bits
776 + 1)
777 return GNUNET_SYSERR;
778
779 announcement_message = get_room_message (room, partner_event);
780
781 if ((! announcement_message) ||
782 (GNUNET_MESSENGER_KIND_ANNOUNCEMENT != announcement_message->header.kind))
783 return GNUNET_SYSERR;
784
785 partner_identifier = &(announcement_message->body.announcement.identifier);
786
787 if (initiator_identifier->code.level_bits != partner_identifier->code.
788 level_bits)
789 return GNUNET_SYSERR;
790
791 if (((initiator_identifier->code.group_bit) || (partner_identifier->code.
792 group_bit)) &&
793 (0 == GNUNET_memcmp (initiator_identifier->code.bits, partner_identifier->
794 code.bits)))
795 return GNUNET_SYSERR;
796
797 if (get_room_sender (room, initiator_event) == get_room_sender (room,
798 partner_event)
799 )
800 return GNUNET_SYSERR;
801
802 message = create_message_group (&(group->identifier),
803 initiator_event,
804 partner_event,
805 timeout);
806
807 if (! message)
808 return GNUNET_SYSERR;
809
810 send_epoch_message (group->epoch, message);
811 return GNUNET_OK;
812}
813
814
817 const struct GNUNET_HashCode *event)
818{
819 struct GNUNET_MESSENGER_Room *room;
821 const struct GNUNET_MESSENGER_Message *group_message;
822 const struct GNUNET_HashCode *announcement_event;
823 const struct GNUNET_MESSENGER_Message *announcement_message;
824 const union GNUNET_MESSENGER_EpochIdentifier *identifier;
825 const struct GNUNET_MESSENGER_EpochGroup *target_group;
826 const struct GNUNET_CRYPTO_SymmetricSessionKey *group_key;
827 struct GNUNET_MESSENGER_Message *message;
828
829 GNUNET_assert ((group) && (event));
830
831 room = group->epoch->room;
832 key = get_epoch_group_key (group);
833
834 if (! key)
835 return GNUNET_SYSERR;
836
837 group_message = get_room_message (room, event);
838
839 if ((! group_message) ||
840 (GNUNET_MESSENGER_KIND_GROUP != group_message->header.kind))
841 return GNUNET_SYSERR;
842
843 if (0 != GNUNET_memcmp (&(group->identifier), &(group_message->body.group.
844 identifier)))
845 return GNUNET_SYSERR;
846
847 if (GNUNET_YES == is_room_message_sent (room, event))
848 announcement_event = &(group_message->body.group.initiator);
849 else
850 announcement_event = &(group_message->body.group.partner);
851
852 if (GNUNET_YES != is_room_message_sent (room, announcement_event))
853 return GNUNET_SYSERR;
854
855 announcement_message = get_room_message (room, announcement_event);
856
857 if ((! announcement_message) ||
858 (GNUNET_MESSENGER_KIND_ANNOUNCEMENT != announcement_message->header.kind))
859 return GNUNET_SYSERR;
860
861 identifier = &(announcement_message->body.announcement.identifier);
862
863 if (! identifier->code.group_bit)
864 return GNUNET_SYSERR;
865
866 if (0 == GNUNET_memcmp (&(group->identifier), identifier))
867 return GNUNET_SYSERR;
868
869 target_group = get_epoch_group (group->epoch,
870 identifier,
871 GNUNET_YES);
872
873 if (! target_group)
874 return GNUNET_SYSERR;
875
876 if (get_epoch_group_level (target_group) + 1 != get_epoch_group_level (group))
877 return GNUNET_SYSERR;
878
879 group_key = get_epoch_group_key (target_group);
880
881 if (! group_key)
882 return GNUNET_SYSERR;
883
884 message = create_message_authorization (identifier,
885 event,
886 group_key,
887 key);
888
889 if (! message)
890 return GNUNET_SYSERR;
891
892 send_epoch_message (group->epoch, message);
893 return GNUNET_OK;
894}
895
896
897void
899 const struct GNUNET_MESSENGER_Message *message,
900 const struct GNUNET_HashCode *hash,
901 struct GNUNET_MESSENGER_Contact *sender,
903{
904 struct GNUNET_HashCode proposal_hash;
906 enum GNUNET_GenericReturnValue is_proposal;
908
909 GNUNET_assert ((group) && (message) && (hash) && (sender));
910
911 if (GNUNET_YES == is_epoch_group_proposal (group))
912 {
913 GNUNET_memcpy (&(proposal_hash), &(group->epoch->proposal_hash), sizeof (
914 proposal_hash));
915 memset (&(group->epoch->proposal_hash), 0, sizeof (group->epoch->
916 proposal_hash));
917
918 is_proposal = GNUNET_YES;
919
921 }
922 else
923 is_proposal = GNUNET_NO;
924
925 key = get_epoch_group_key (group);
926
927 if (key)
928 {
929 if (GNUNET_OK != verify_message_by_key (message, key))
930 return;
931
932 if ((GNUNET_YES == is_epoch_group_completed (group)) &&
933 (GNUNET_YES != is_epoch_group_member (group, sender)))
934 {
936 return;
937 }
938 }
939
940 if (GNUNET_YES != confirm_epoch_group_member (group, hash, message, sender,
941 sent))
942 return;
943
944 {
945 const struct GNUNET_MESSENGER_EpochGroup *proposal_group;
946
947 proposal_group = get_epoch_proposal_group (group->epoch);
948
949 if ((proposal_group) && (group->epoch->main_group) &&
950 (get_epoch_group_level (proposal_group) <= get_epoch_group_level (
951 group->epoch->main_group)))
953 }
954
955 if ((key) && (GNUNET_YES == is_proposal) &&
957 {
958 send_epoch_group_authorization (group, &proposal_hash);
960 }
961
963
964 delay_room_action (group->epoch->room, hash, timeout);
965}
966
967
968void
970 group,
971 const struct GNUNET_MESSENGER_Message *
972 message,
973 const struct GNUNET_HashCode *hash,
974 struct GNUNET_MESSENGER_Contact *sender,
976{
977 GNUNET_assert ((group) && (message) && (hash) && (sender));
978
979 if (GNUNET_YES == is_room_public (group->epoch->room))
980 return;
981
982 if ((GNUNET_YES == sent) && (GNUNET_YES == group->valid) &&
985}
986
987
988void
990 const struct GNUNET_MESSENGER_Message *message,
991 const struct GNUNET_HashCode *hash)
992{
993 const struct GNUNET_CRYPTO_EcdhePrivateKey *private_key;
994 struct GNUNET_CRYPTO_HpkePrivateKey private_hpke;
995 struct GNUNET_CRYPTO_SymmetricSessionKey shared_key;
996
997 GNUNET_assert ((group) && (message) && (hash));
998
999 private_key = get_epoch_private_key (group->epoch,
1001
1002 if (! private_key)
1003 {
1005 "Private key for decrypting shared key is missing!\n");
1006 return;
1007 }
1008
1009 GNUNET_memcpy (&private_hpke.ecdhe_key,
1010 private_key,
1011 sizeof *private_key);
1012 if (GNUNET_NO == extract_access_message_key (message,
1013 &private_hpke,
1014 &shared_key
1015 ))
1016 return;
1017
1018 set_epoch_group_key (group, &shared_key, GNUNET_YES);
1019
1020 if ((group->epoch->main_group) && (group != group->epoch->main_group) &&
1022 main_group)))
1023 return;
1024
1026
1027 send_epoch_group_authorization (group, &(message->body.access.event));
1029}
1030
1031
1032static void
1034 enum GNUNET_ErrorCode ec)
1035{
1036 struct GNUNET_MESSENGER_EpochGroup *group;
1037
1038 GNUNET_assert (cls);
1039
1040 group = cls;
1041
1042 if (GNUNET_EC_NONE != ec)
1044 "Error writing group key record: %d\n", (int) ec);
1045
1046 group->query = NULL;
1047}
1048
1049
1050void
1052 enum GNUNET_GenericReturnValue deleted)
1053{
1054 const struct GNUNET_MESSENGER_Handle *handle;
1055 const struct GNUNET_HashCode *hash;
1056 const struct GNUNET_ShortHashCode *identifier;
1057 const struct GNUNET_CRYPTO_SymmetricSessionKey *shared_key;
1058
1059 GNUNET_assert ((group) && (group->epoch));
1060
1061 handle = get_room_handle (group->epoch->room);
1062
1063 if (! handle)
1064 return;
1065
1066 hash = &(group->epoch->hash);
1067 identifier = &(group->identifier.hash);
1068
1069 if (GNUNET_YES == deleted)
1070 {
1071 shared_key = NULL;
1072 }
1073 else
1074 {
1075 shared_key = group->shared_key;
1076
1077 if (! shared_key)
1078 return;
1079 }
1080
1082 handle, group->epoch->room,
1083 hash, identifier, shared_key,
1084 GNUNET_YES == group->valid?
1088 group,
1089 &(group->query));
1090}
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_symmetric_create_session_key(struct GNUNET_CRYPTO_SymmetricSessionKey *key)
Create a new random session key.
void GNUNET_CRYPTO_random_block(enum GNUNET_CRYPTO_Quality mode, void *buffer, size_t length)
Fill block with a random values.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
#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.
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.
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)
static enum GNUNET_GenericReturnValue derive_epoch_group_key(const struct GNUNET_MESSENGER_EpochGroup *group, const struct GNUNET_MESSENGER_EpochGroup *previous, struct GNUNET_CRYPTO_SymmetricSessionKey *key)
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 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...
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 set_epoch_group_key(struct GNUNET_MESSENGER_EpochGroup *group, const struct GNUNET_CRYPTO_SymmetricSessionKey *shared_key, enum GNUNET_GenericReturnValue write_record)
Sets the secret key of a given epoch group to a shared 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.
const struct GNUNET_CRYPTO_SymmetricSessionKey * get_epoch_group_key(const struct GNUNET_MESSENGER_EpochGroup *group)
Returns the secret key of a given epoch group or NULL.
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_SymmetricSessionKey *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_SymmetricSessionKey *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_SymmetricSessionKey *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_SymmetricSessionKey *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_revolution(const union GNUNET_MESSENGER_EpochIdentifier *identifier, const struct GNUNET_CRYPTO_SymmetricSessionKey *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_authorization(const union GNUNET_MESSENGER_EpochIdentifier *identifier, const struct GNUNET_HashCode *event, const struct GNUNET_CRYPTO_SymmetricSessionKey *group_key, const struct GNUNET_CRYPTO_SymmetricSessionKey *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_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_SymmetricSessionKey *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_CRYPTO_SymmetricSessionKey * shared_key
struct GNUNET_NAMESTORE_QueueEntry * query
struct GNUNET_MESSENGER_Epoch * epoch
struct GNUNET_MESSENGER_EpochMembership * membership
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