GNUnet debian-0.24.3-23-g589b01d60
messenger_api_epoch_group.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2024--2025 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 sizeof (*key),
65 &(group->epoch->hash),
66 sizeof (group->epoch->hash),
67 previous_key,
68 sizeof (*previous_key),
69 &(group->identifier),
70 sizeof (group->identifier),
71 NULL))
72 return GNUNET_SYSERR;
73 else
74 return GNUNET_OK;
75}
76
77
82 uint32_t level,
84{
85 struct GNUNET_MESSENGER_EpochGroup *group;
86 const struct GNUNET_MESSENGER_EpochGroup *previous;
87
89
91
92 if (! group)
93 return NULL;
94
96
97 if ((GNUNET_YES == valid) && (previous) &&
98 (GNUNET_YES != previous->valid))
99 previous = NULL;
100
101 if (identifier)
103 sizeof (group->identifier));
104 else
105 random_epoch_group_identifier (level, &(group->identifier));
106
108
110
111 group->epoch = epoch;
113 group->shared_key = NULL;
114 group->query = NULL;
115
116 group->valid = GNUNET_YES;
117 group->stored = GNUNET_NO;
118
119 if (previous)
120 {
122
123 if (GNUNET_OK == derive_epoch_group_key (group,
124 previous,
125 &key))
126 {
128 group->valid = previous->valid;
129 }
130 }
131
132 return group;
133}
134
135
136void
138{
139 GNUNET_assert (group);
140
141 if (group->membership)
143
144 if (group->shared_key)
145 GNUNET_free (group->shared_key);
146
147 if (group->query)
149
150 GNUNET_free (group);
151}
152
153
154uint32_t
156{
157 GNUNET_assert (group);
158
159 return group->identifier.code.level_bits;
160}
161
162
163uint32_t
165{
166 GNUNET_assert (group);
167
168 return 0x1 << get_epoch_group_level (group);
169}
170
171
172uint32_t
174 group)
175{
176 GNUNET_assert (group);
177
179}
180
181
184{
185 GNUNET_assert (group);
186
188}
189
190
193{
194 GNUNET_assert (group);
195
196 return is_epoch_membership_member (group->membership, NULL);
197}
198
199
200void
202 const struct GNUNET_CRYPTO_SymmetricSessionKey *shared_key,
203 enum GNUNET_GenericReturnValue write_record)
204{
205 GNUNET_assert (group);
206
207 if ((GNUNET_NO == write_record) && (shared_key))
208 group->stored = GNUNET_YES;
209
210 if (group->shared_key)
211 return;
212
214
215 if (! group->shared_key)
216 return;
217
218 if (shared_key)
219 GNUNET_memcpy (group->shared_key, shared_key,
220 sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey));
221 else
223
224 update_epoch_group (group->epoch, group);
225
226 if (GNUNET_YES != group->stored)
228}
229
230
233{
234 GNUNET_assert (group);
235
236 return group->shared_key;
237}
238
239
242 ,
243 const struct GNUNET_MESSENGER_EpochGroup *
244 previous)
245{
246 const struct GNUNET_CRYPTO_SymmetricSessionKey *shared_key;
248
249 GNUNET_assert ((group) && (previous));
250
251 shared_key = get_epoch_group_key (group);
252
253 if (! shared_key)
254 return GNUNET_SYSERR;
255
256 if (GNUNET_OK != derive_epoch_group_key (group, previous, &key))
257 return GNUNET_SYSERR;
258
259 if (0 == GNUNET_memcmp (shared_key, &key))
260 return GNUNET_YES;
261 else
262 return GNUNET_NO;
263}
264
265
268 const struct GNUNET_HashCode *hash,
269 const struct GNUNET_MESSENGER_Message *message,
270 struct GNUNET_MESSENGER_Contact *contact,
272{
274
275 GNUNET_assert ((group) && (hash) && (message) && (contact));
276
277 if (GNUNET_YES != is_epoch_member (group->epoch, contact))
278 return GNUNET_SYSERR;
279
281 hash,
282 message,
283 contact,
284 sent);
285
286 if (GNUNET_YES != result)
287 return result;
288
289 update_epoch_group (group->epoch, group);
290 return GNUNET_YES;
291}
292
293
294static uint32_t
296 group)
297{
298 GNUNET_assert (group);
299
301}
302
303
306 const struct GNUNET_MESSENGER_Contact *contact)
307{
308 GNUNET_assert ((group) && (contact));
309
310 return is_epoch_membership_member (group->membership, contact);
311}
312
313
315{
318};
319
322 const struct GNUNET_MESSENGER_Contact *member)
323{
325
326 GNUNET_assert ((cls) && (member));
327
328 check = cls;
329
330 if (GNUNET_YES == is_epoch_group_member (check->group, member))
331 return GNUNET_YES;
332
333 check->result = GNUNET_NO;
334 return GNUNET_NO;
335}
336
337
340 const struct GNUNET_MESSENGER_EpochGroup *other)
341{
343
344 GNUNET_assert ((group) && (other));
345
346 if (group == other)
347 return GNUNET_YES;
348
350 return GNUNET_NO;
351
353 return GNUNET_NO;
354
355 check.group = other;
356 check.result = GNUNET_YES;
357
360 &check);
361
362 return check.result;
363}
364
365
368 struct GNUNET_HashCode *hash,
369 enum GNUNET_GenericReturnValue other)
370{
371 GNUNET_assert ((group) && (hash));
372
374}
375
376
377void
379 const struct GNUNET_MESSENGER_Contact *contact)
380{
381 const struct GNUNET_MESSENGER_Message *message;
382 struct GNUNET_MESSENGER_EpochGroup *previous;
383 struct GNUNET_MESSENGER_Epoch *epoch;
384
385 GNUNET_assert (group);
386
387 if (GNUNET_NO == group->valid)
388 return;
389
390 if ((contact) && (GNUNET_YES != is_epoch_member (group->epoch, contact)))
391 return;
392
393 group->valid = GNUNET_NO;
395
396 message = get_room_message (group->epoch->room, &(group->epoch->hash));
397
398 if (! message)
399 goto skip_traversal;
400
401 switch (message->header.kind)
402 {
404 epoch = get_room_epoch (
405 group->epoch->room, &(message->body.join.epoch), GNUNET_NO);
406
407 if (epoch)
408 previous = get_epoch_group (
409 epoch, &(group->identifier), GNUNET_SYSERR);
410 else
411 previous = NULL;
412 break;
414 epoch = get_room_epoch (
415 group->epoch->room, &(message->body.leave.epoch), GNUNET_NO);
416
417 if (epoch)
418 previous = get_epoch_group (
419 epoch, &(group->identifier), GNUNET_SYSERR);
420 else
421 previous = NULL;
422 break;
424 epoch = get_room_epoch (
425 group->epoch->room, &(message->body.merge.epochs[0]), GNUNET_NO);
426
427 if (epoch)
428 {
429 previous = get_epoch_group (
430 epoch, &(group->identifier), GNUNET_SYSERR);
431
432 if ((previous) &&
433 (GNUNET_YES != is_epoch_group_key_derived_from (previous, group)))
434 previous = NULL;
435 }
436 else
437 previous = NULL;
438
439 if (! previous)
440 {
441 epoch = get_room_epoch (
442 group->epoch->room, &(message->body.merge.epochs[1]), GNUNET_NO);
443
444 if (epoch)
445 previous = get_epoch_group (
446 epoch, &(group->identifier), GNUNET_SYSERR);
447 }
448 break;
449 default:
450 previous = NULL;
451 break;
452 }
453
454 if ((previous) &&
455 (GNUNET_YES != is_epoch_group_key_derived_from (previous, group)))
456 previous = NULL;
457
458 if (previous)
459 invalidate_epoch_group (previous, contact);
460
461skip_traversal:
462 if (group->epoch->main_group != group)
463 return;
464
466 group->epoch, NULL, GNUNET_YES);
467}
468
469
472{
473 GNUNET_assert (group);
474
475 if (get_epoch_proposal_group (group->epoch) == group)
476 return GNUNET_YES;
477 else
478 return GNUNET_NO;
479}
480
481
483{
486};
487
490 const struct GNUNET_MESSENGER_Contact *member)
491{
492 struct GNUNET_MESSENGER_CheckEpoch *check;
493 uint32_t i;
494
495 GNUNET_assert ((cls) && (member));
496
497 check = cls;
498
499 for (i = 0; i < check->epoch->members_count; i++)
500 if (member == check->epoch->members[i])
501 return GNUNET_YES;
502
503 check->result = GNUNET_NO;
504 return GNUNET_NO;
505}
506
507
510 const struct GNUNET_MESSENGER_Epoch *epoch)
511{
512 struct GNUNET_MESSENGER_CheckEpoch check;
513
514 GNUNET_assert ((group) && (epoch));
515
517 return GNUNET_NO;
518
519 if (GNUNET_YES != group->valid)
520 return GNUNET_NO;
521
522 if (group->epoch == epoch)
523 return GNUNET_YES;
524
525 if (0 == epoch->members_count)
526 return GNUNET_NO;
527
528 check.epoch = epoch;
529 check.result = GNUNET_YES;
530
533 &check);
534
535 return check.result;
536}
537
538
540{
543};
544
547 const struct GNUNET_MESSENGER_Contact *
548 member)
549{
551
552 GNUNET_assert ((cls) && (member));
553
554 check = cls;
555
557 return GNUNET_YES;
558
559 check->result = GNUNET_YES;
560 return GNUNET_NO;
561}
562
563
566 group,
567 const struct
570{
572
573 GNUNET_assert ((group) && (announcement));
574
576 return GNUNET_YES;
577
579 check.result = GNUNET_NO;
580
583 &check);
584
585 return check.result;
586}
587
588
589double
591 group)
592{
593 const struct GNUNET_MESSENGER_EpochGroup *target;
594 uint32_t members_count;
595 uint32_t announced;
596 uint32_t position;
597
598 GNUNET_assert (group);
599
600 if (GNUNET_NO == is_epoch_group_completed (group))
601 target = get_epoch_previous_group (group->epoch, &(group->identifier));
602 else
603 target = NULL;
604
605 if (! target)
606 target = group;
607
608 members_count = get_epoch_group_members_count (target);
609 announced = get_epoch_group_members_count (group);
610
611 if (members_count <= announced)
612 return 0.0;
613
614 position = get_epoch_group_member_position (target);
615
616 if (position > announced)
617 position -= announced;
618 else
619 position = 0;
620
621 return (0.0 + position) / (members_count - announced);
622}
623
624
627{
629 const struct GNUNET_CRYPTO_EcdhePrivateKey *private_key;
631 struct GNUNET_MESSENGER_Message *message;
632
633 GNUNET_assert (group);
634
635 key = get_epoch_group_key (group);
636
637 if (! key)
638 return GNUNET_SYSERR;
639
642
644 return GNUNET_NO;
645
648
649 private_key = get_epoch_private_key (group->epoch,
650 timeout);
651
652 if (! private_key)
653 return GNUNET_SYSERR;
654
656
657 message = create_message_announcement (&(group->identifier),
658 private_key,
659 key,
660 timeout);
661
662 if (! message)
663 return GNUNET_SYSERR;
664
665 send_epoch_message (group->epoch, message);
666
669
670 return GNUNET_OK;
671}
672
673
676 const struct GNUNET_HashCode *event)
677{
678 struct GNUNET_MESSENGER_Room *room;
680 const struct GNUNET_MESSENGER_Message *group_message;
681 const struct GNUNET_MESSENGER_Message *announcement_message;
682 const struct GNUNET_CRYPTO_EcdhePublicKey *public_key;
683 struct GNUNET_MESSENGER_Message *message;
684
685 GNUNET_assert ((group) && (event));
686
687 room = group->epoch->room;
688 key = get_epoch_group_key (group);
689
690 if (! key)
691 return GNUNET_SYSERR;
692
693 if (GNUNET_YES != is_room_message_sent (room, event))
694 return GNUNET_SYSERR;
695
696 group_message = get_room_message (room, event);
697
698 if ((! group_message) ||
699 (GNUNET_MESSENGER_KIND_GROUP != group_message->header.kind))
700 return GNUNET_SYSERR;
701
702 announcement_message = get_room_message (room, &(group_message->body.group.
703 partner));
704
705 if ((! announcement_message) ||
706 (GNUNET_MESSENGER_KIND_ANNOUNCEMENT != announcement_message->header.kind))
707 return GNUNET_SYSERR;
708
709 public_key = &(announcement_message->body.announcement.key);
710 message = create_message_access (event,
711 public_key,
712 key);
713
714 if (! message)
715 return GNUNET_SYSERR;
716
717 send_epoch_message (group->epoch, message);
718 return GNUNET_OK;
719}
720
721
724{
726 struct GNUNET_MESSENGER_Message *message;
727
728 GNUNET_assert (group);
729
730 key = get_epoch_group_key (group);
731
732 if (! key)
733 return GNUNET_SYSERR;
734
735 message = create_message_revolution (&(group->identifier),
736 key);
737
738 if (! message)
739 return GNUNET_SYSERR;
740
741 send_epoch_message (group->epoch, message);
742 return GNUNET_OK;
743}
744
745
748 const struct GNUNET_HashCode *initiator_event,
749 const struct GNUNET_HashCode *partner_event,
751{
752 struct GNUNET_MESSENGER_Room *room;
753 const struct GNUNET_MESSENGER_Message *announcement_message;
754 const union GNUNET_MESSENGER_EpochIdentifier *initiator_identifier;
755 const union GNUNET_MESSENGER_EpochIdentifier *partner_identifier;
756 struct GNUNET_MESSENGER_Message *message;
757
758 GNUNET_assert ((group) && (initiator_event) && (partner_event));
759
760 if (0 == GNUNET_CRYPTO_hash_cmp (initiator_event, partner_event))
761 return GNUNET_SYSERR;
762
763 room = group->epoch->room;
764
765 if (GNUNET_YES != is_room_message_sent (room, initiator_event))
766 return GNUNET_SYSERR;
767
768 announcement_message = get_room_message (room, initiator_event);
769
770 if ((! announcement_message) ||
771 (GNUNET_MESSENGER_KIND_ANNOUNCEMENT != announcement_message->header.kind))
772 return GNUNET_SYSERR;
773
774 initiator_identifier = &(announcement_message->body.announcement.identifier);
775
776 if (group->identifier.code.level_bits != initiator_identifier->code.level_bits
777 + 1)
778 return GNUNET_SYSERR;
779
780 announcement_message = get_room_message (room, partner_event);
781
782 if ((! announcement_message) ||
783 (GNUNET_MESSENGER_KIND_ANNOUNCEMENT != announcement_message->header.kind))
784 return GNUNET_SYSERR;
785
786 partner_identifier = &(announcement_message->body.announcement.identifier);
787
788 if (initiator_identifier->code.level_bits != partner_identifier->code.
789 level_bits)
790 return GNUNET_SYSERR;
791
792 if (((initiator_identifier->code.group_bit) || (partner_identifier->code.
793 group_bit)) &&
794 (0 == GNUNET_memcmp (initiator_identifier->code.bits, partner_identifier->
795 code.bits)))
796 return GNUNET_SYSERR;
797
798 if (get_room_sender (room, initiator_event) == get_room_sender (room,
799 partner_event)
800 )
801 return GNUNET_SYSERR;
802
803 message = create_message_group (&(group->identifier),
804 initiator_event,
805 partner_event,
806 timeout);
807
808 if (! message)
809 return GNUNET_SYSERR;
810
811 send_epoch_message (group->epoch, message);
812 return GNUNET_OK;
813}
814
815
818 const struct GNUNET_HashCode *event)
819{
820 struct GNUNET_MESSENGER_Room *room;
822 const struct GNUNET_MESSENGER_Message *group_message;
823 const struct GNUNET_HashCode *announcement_event;
824 const struct GNUNET_MESSENGER_Message *announcement_message;
825 const union GNUNET_MESSENGER_EpochIdentifier *identifier;
826 const struct GNUNET_MESSENGER_EpochGroup *target_group;
827 const struct GNUNET_CRYPTO_SymmetricSessionKey *group_key;
828 struct GNUNET_MESSENGER_Message *message;
829
830 GNUNET_assert ((group) && (event));
831
832 room = group->epoch->room;
833 key = get_epoch_group_key (group);
834
835 if (! key)
836 return GNUNET_SYSERR;
837
838 group_message = get_room_message (room, event);
839
840 if ((! group_message) ||
841 (GNUNET_MESSENGER_KIND_GROUP != group_message->header.kind))
842 return GNUNET_SYSERR;
843
844 if (0 != GNUNET_memcmp (&(group->identifier), &(group_message->body.group.
845 identifier)))
846 return GNUNET_SYSERR;
847
848 if (GNUNET_YES == is_room_message_sent (room, event))
849 announcement_event = &(group_message->body.group.initiator);
850 else
851 announcement_event = &(group_message->body.group.partner);
852
853 if (GNUNET_YES != is_room_message_sent (room, announcement_event))
854 return GNUNET_SYSERR;
855
856 announcement_message = get_room_message (room, announcement_event);
857
858 if ((! announcement_message) ||
859 (GNUNET_MESSENGER_KIND_ANNOUNCEMENT != announcement_message->header.kind))
860 return GNUNET_SYSERR;
861
862 identifier = &(announcement_message->body.announcement.identifier);
863
864 if (! identifier->code.group_bit)
865 return GNUNET_SYSERR;
866
867 if (0 == GNUNET_memcmp (&(group->identifier), identifier))
868 return GNUNET_SYSERR;
869
870 target_group = get_epoch_group (group->epoch,
871 identifier,
872 GNUNET_YES);
873
874 if (! target_group)
875 return GNUNET_SYSERR;
876
877 if (get_epoch_group_level (target_group) + 1 != get_epoch_group_level (group))
878 return GNUNET_SYSERR;
879
880 group_key = get_epoch_group_key (target_group);
881
882 if (! group_key)
883 return GNUNET_SYSERR;
884
885 message = create_message_authorization (identifier,
886 event,
887 group_key,
888 key);
889
890 if (! message)
891 return GNUNET_SYSERR;
892
893 send_epoch_message (group->epoch, message);
894 return GNUNET_OK;
895}
896
897
898void
900 const struct GNUNET_MESSENGER_Message *message,
901 const struct GNUNET_HashCode *hash,
902 struct GNUNET_MESSENGER_Contact *sender,
904{
905 struct GNUNET_HashCode proposal_hash;
907 enum GNUNET_GenericReturnValue is_proposal;
909
910 GNUNET_assert ((group) && (message) && (hash) && (sender));
911
912 if (GNUNET_YES == is_epoch_group_proposal (group))
913 {
914 GNUNET_memcpy (&(proposal_hash), &(group->epoch->proposal_hash), sizeof (
915 proposal_hash));
916 memset (&(group->epoch->proposal_hash), 0, sizeof (group->epoch->
917 proposal_hash));
918
919 is_proposal = GNUNET_YES;
920
922 }
923 else
924 is_proposal = GNUNET_NO;
925
926 key = get_epoch_group_key (group);
927
928 if (key)
929 {
930 if (GNUNET_OK != verify_message_by_key (message, key))
931 return;
932
933 if ((GNUNET_YES == is_epoch_group_completed (group)) &&
934 (GNUNET_YES != is_epoch_group_member (group, sender)))
935 {
937 return;
938 }
939 }
940
941 if (GNUNET_YES != confirm_epoch_group_member (group, hash, message, sender,
942 sent))
943 return;
944
945 {
946 const struct GNUNET_MESSENGER_EpochGroup *proposal_group;
947
948 proposal_group = get_epoch_proposal_group (group->epoch);
949
950 if ((proposal_group) && (group->epoch->main_group) &&
951 (get_epoch_group_level (proposal_group) <= get_epoch_group_level (
952 group->epoch->main_group)))
954 }
955
956 if ((key) && (GNUNET_YES == is_proposal) &&
958 {
959 send_epoch_group_authorization (group, &proposal_hash);
961 }
962
964
965 delay_room_action (group->epoch->room, hash, timeout);
966}
967
968
969void
971 group,
972 const struct GNUNET_MESSENGER_Message *
973 message,
974 const struct GNUNET_HashCode *hash,
975 struct GNUNET_MESSENGER_Contact *sender,
977{
978 GNUNET_assert ((group) && (message) && (hash) && (sender));
979
980 if (GNUNET_YES == is_room_public (group->epoch->room))
981 return;
982
983 if ((GNUNET_YES == sent) && (GNUNET_YES == group->valid) &&
986}
987
988
989void
991 const struct GNUNET_MESSENGER_Message *message,
992 const struct GNUNET_HashCode *hash)
993{
994 const struct GNUNET_CRYPTO_EcdhePrivateKey *private_key;
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 if (GNUNET_NO == extract_access_message_key (message, private_key, &shared_key
1010 ))
1011 return;
1012
1013 set_epoch_group_key (group, &shared_key, GNUNET_YES);
1014
1015 if ((group->epoch->main_group) && (group != group->epoch->main_group) &&
1017 main_group)))
1018 return;
1019
1021
1022 send_epoch_group_authorization (group, &(message->body.access.event));
1024}
1025
1026
1027static void
1029 enum GNUNET_ErrorCode ec)
1030{
1031 struct GNUNET_MESSENGER_EpochGroup *group;
1032
1033 GNUNET_assert (cls);
1034
1035 group = cls;
1036
1037 if (GNUNET_EC_NONE != ec)
1039 "Error writing group key record: %d\n", (int) ec);
1040
1041 group->query = NULL;
1042}
1043
1044
1045void
1047 enum GNUNET_GenericReturnValue deleted)
1048{
1049 const struct GNUNET_MESSENGER_Handle *handle;
1050 const struct GNUNET_HashCode *key;
1051 const struct GNUNET_HashCode *hash;
1052 const struct GNUNET_ShortHashCode *identifier;
1053 const struct GNUNET_CRYPTO_SymmetricSessionKey *shared_key;
1054
1055 GNUNET_assert ((group) && (group->epoch));
1056
1057 handle = get_room_handle (group->epoch->room);
1058
1059 if (! handle)
1060 return;
1061
1062 key = get_room_key (group->epoch->room);
1063 hash = &(group->epoch->hash);
1064 identifier = &(group->identifier.hash);
1065
1066 if (GNUNET_YES == deleted)
1067 {
1068 shared_key = NULL;
1069 }
1070 else
1071 {
1072 shared_key = group->shared_key;
1073
1074 if (! shared_key)
1075 return;
1076 }
1077
1079 handle, key, hash, identifier, shared_key,
1080 GNUNET_YES == group->valid?
1084 group,
1085 &(group->query));
1086}
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.
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).
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.
Definition: crypto_hash.c:218
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_kdf(void *result, size_t out_len, const void *xts, size_t xts_len, const void *skm, size_t skm_len,...)
Derive key.
Definition: crypto_kdf.c:62
#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_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:664
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 wether ...
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 positon of the client inside a given epoch group in relation to its list of...
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_HashCode *key, 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 identified by its key in an epoch with cer...
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.
enum GNUNET_GenericReturnValue extract_access_message_key(const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_CRYPTO_EcdhePrivateKey *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...
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 ...
const struct GNUNET_HashCode * get_room_key(const struct GNUNET_MESSENGER_Room *room)
Return a the hash representation of a given room.
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 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