aboutsummaryrefslogtreecommitdiff
path: root/src/messenger/messenger_api_message.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/messenger/messenger_api_message.c')
-rw-r--r--src/messenger/messenger_api_message.c423
1 files changed, 346 insertions, 77 deletions
diff --git a/src/messenger/messenger_api_message.c b/src/messenger/messenger_api_message.c
index fdab60eef..d88859186 100644
--- a/src/messenger/messenger_api_message.c
+++ b/src/messenger/messenger_api_message.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2020 GNUnet e.V. 3 Copyright (C) 2020--2021 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 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 6 under the terms of the GNU Affero General Public License as published
@@ -69,6 +69,8 @@ create_message (enum GNUNET_MESSENGER_MessageKind kind)
69struct GNUNET_MESSENGER_Message* 69struct GNUNET_MESSENGER_Message*
70copy_message (const struct GNUNET_MESSENGER_Message *message) 70copy_message (const struct GNUNET_MESSENGER_Message *message)
71{ 71{
72 GNUNET_assert(message);
73
72 struct GNUNET_MESSENGER_Message *copy = GNUNET_new(struct GNUNET_MESSENGER_Message); 74 struct GNUNET_MESSENGER_Message *copy = GNUNET_new(struct GNUNET_MESSENGER_Message);
73 75
74 GNUNET_memcpy(copy, message, sizeof(struct GNUNET_MESSENGER_Message)); 76 GNUNET_memcpy(copy, message, sizeof(struct GNUNET_MESSENGER_Message));
@@ -125,11 +127,28 @@ destroy_message_body (enum GNUNET_MESSENGER_MessageKind kind, struct GNUNET_MESS
125void 127void
126destroy_message (struct GNUNET_MESSENGER_Message *message) 128destroy_message (struct GNUNET_MESSENGER_Message *message)
127{ 129{
130 GNUNET_assert(message);
131
128 destroy_message_body (message->header.kind, &(message->body)); 132 destroy_message_body (message->header.kind, &(message->body));
129 133
130 GNUNET_free(message); 134 GNUNET_free(message);
131} 135}
132 136
137int
138is_message_session_bound (const struct GNUNET_MESSENGER_Message *message)
139{
140 GNUNET_assert(message);
141
142 if ((GNUNET_MESSENGER_KIND_JOIN == message->header.kind) ||
143 (GNUNET_MESSENGER_KIND_LEAVE == message->header.kind) ||
144 (GNUNET_MESSENGER_KIND_NAME == message->header.kind) ||
145 (GNUNET_MESSENGER_KIND_KEY == message->header.kind) ||
146 (GNUNET_MESSENGER_KIND_ID == message->header.kind))
147 return GNUNET_YES;
148 else
149 return GNUNET_NO;
150}
151
133static void 152static void
134fold_short_message (const struct GNUNET_MESSENGER_Message *message, struct GNUNET_MESSENGER_ShortMessage *shortened) 153fold_short_message (const struct GNUNET_MESSENGER_Message *message, struct GNUNET_MESSENGER_ShortMessage *shortened)
135{ 154{
@@ -158,18 +177,7 @@ get_message_body_kind_size (enum GNUNET_MESSENGER_MessageKind kind)
158 switch (kind) 177 switch (kind)
159 { 178 {
160 case GNUNET_MESSENGER_KIND_INFO: 179 case GNUNET_MESSENGER_KIND_INFO:
161 length += member_size(struct GNUNET_MESSENGER_Message, body.info.host_key); 180 length += member_size(struct GNUNET_MESSENGER_Message, body.info.messenger_version);
162 length += member_size(struct GNUNET_MESSENGER_Message, body.info.unique_id);
163 break;
164 case GNUNET_MESSENGER_KIND_JOIN:
165 length += member_size(struct GNUNET_MESSENGER_Message, body.join.key);
166 break;
167 case GNUNET_MESSENGER_KIND_LEAVE:
168 break;
169 case GNUNET_MESSENGER_KIND_NAME:
170 break;
171 case GNUNET_MESSENGER_KIND_KEY:
172 length += member_size(struct GNUNET_MESSENGER_Message, body.key.key);
173 break; 181 break;
174 case GNUNET_MESSENGER_KIND_PEER: 182 case GNUNET_MESSENGER_KIND_PEER:
175 length += member_size(struct GNUNET_MESSENGER_Message, body.peer.peer); 183 length += member_size(struct GNUNET_MESSENGER_Message, body.peer.peer);
@@ -195,7 +203,7 @@ get_message_body_kind_size (enum GNUNET_MESSENGER_MessageKind kind)
195 case GNUNET_MESSENGER_KIND_FILE: 203 case GNUNET_MESSENGER_KIND_FILE:
196 length += member_size(struct GNUNET_MESSENGER_Message, body.file.key); 204 length += member_size(struct GNUNET_MESSENGER_Message, body.file.key);
197 length += member_size(struct GNUNET_MESSENGER_Message, body.file.hash); 205 length += member_size(struct GNUNET_MESSENGER_Message, body.file.hash);
198 length += NAME_MAX; 206 length += member_size(struct GNUNET_MESSENGER_Message, body.file.name);
199 break; 207 break;
200 case GNUNET_MESSENGER_KIND_PRIVATE: 208 case GNUNET_MESSENGER_KIND_PRIVATE:
201 length += member_size(struct GNUNET_MESSENGER_Message, body.private.key); 209 length += member_size(struct GNUNET_MESSENGER_Message, body.private.key);
@@ -207,16 +215,17 @@ get_message_body_kind_size (enum GNUNET_MESSENGER_MessageKind kind)
207 return length; 215 return length;
208} 216}
209 217
218typedef uint32_t kind_t;
219
210uint16_t 220uint16_t
211get_message_kind_size (enum GNUNET_MESSENGER_MessageKind kind) 221get_message_kind_size (enum GNUNET_MESSENGER_MessageKind kind)
212{ 222{
213 uint16_t length = 0; 223 uint16_t length = 0;
214 224
215 length += member_size(struct GNUNET_MESSENGER_Message, header.signature);
216 length += member_size(struct GNUNET_MESSENGER_Message, header.timestamp); 225 length += member_size(struct GNUNET_MESSENGER_Message, header.timestamp);
217 length += member_size(struct GNUNET_MESSENGER_Message, header.sender_id); 226 length += member_size(struct GNUNET_MESSENGER_Message, header.sender_id);
218 length += member_size(struct GNUNET_MESSENGER_Message, header.previous); 227 length += member_size(struct GNUNET_MESSENGER_Message, header.previous);
219 length += member_size(struct GNUNET_MESSENGER_Message, header.kind); 228 length += sizeof(kind_t);
220 229
221 return length + get_message_body_kind_size (kind); 230 return length + get_message_body_kind_size (kind);
222} 231}
@@ -228,8 +237,17 @@ get_message_body_size (enum GNUNET_MESSENGER_MessageKind kind, const struct GNUN
228 237
229 switch (kind) 238 switch (kind)
230 { 239 {
240 case GNUNET_MESSENGER_KIND_INFO:
241 length += GNUNET_IDENTITY_key_get_length(&(body->info.host_key));
242 break;
243 case GNUNET_MESSENGER_KIND_JOIN:
244 length += GNUNET_IDENTITY_key_get_length(&(body->join.key));
245 break;
231 case GNUNET_MESSENGER_KIND_NAME: 246 case GNUNET_MESSENGER_KIND_NAME:
232 length += (body->name.name? strlen (body->name.name) : 0); 247 length += (body->name.name ? strlen (body->name.name) : 0);
248 break;
249 case GNUNET_MESSENGER_KIND_KEY:
250 length += GNUNET_IDENTITY_key_get_length(&(body->key.key));
233 break; 251 break;
234 case GNUNET_MESSENGER_KIND_TEXT: 252 case GNUNET_MESSENGER_KIND_TEXT:
235 length += strlen (body->text.text); 253 length += strlen (body->text.text);
@@ -248,19 +266,76 @@ get_message_body_size (enum GNUNET_MESSENGER_MessageKind kind, const struct GNUN
248} 266}
249 267
250uint16_t 268uint16_t
251get_message_size (const struct GNUNET_MESSENGER_Message *message) 269get_message_size (const struct GNUNET_MESSENGER_Message *message,
270 int include_signature)
252{ 271{
253 return get_message_kind_size (message->header.kind) + get_message_body_size (message->header.kind, &(message->body)); 272 GNUNET_assert(message);
273
274 uint16_t length = 0;
275
276 if (GNUNET_YES == include_signature)
277 length += GNUNET_IDENTITY_signature_get_length(&(message->header.signature));
278
279 length += get_message_kind_size (message->header.kind);
280 length += get_message_body_size (message->header.kind, &(message->body));
281
282 return length;
254} 283}
255 284
256static uint16_t 285static uint16_t
257get_short_message_size (const struct GNUNET_MESSENGER_ShortMessage *message) 286get_short_message_size (const struct GNUNET_MESSENGER_ShortMessage *message, int include_body)
258{ 287{
288 const uint16_t minimum_size = sizeof(struct GNUNET_HashCode) + sizeof(kind_t);
289
259 if (message) 290 if (message)
260 return sizeof(message->kind) + get_message_body_kind_size (message->kind) 291 return minimum_size + get_message_body_kind_size (message->kind)
261 + get_message_body_size (message->kind, &(message->body)); 292 + (include_body == GNUNET_YES? get_message_body_size (message->kind, &(message->body)) : 0);
262 else 293 else
263 return sizeof(message->kind); 294 return minimum_size;
295}
296
297static uint16_t
298calc_usual_padding ()
299{
300 uint16_t padding = 0;
301 uint16_t kind_size;
302
303 for (int i = 0; i <= GNUNET_MESSENGER_KIND_MAX; i++) {
304 kind_size = get_message_kind_size ((enum GNUNET_MESSENGER_MessageKind) i);
305
306 if (kind_size > padding)
307 padding = kind_size;
308 }
309
310 return padding + GNUNET_MESSENGER_PADDING_MIN;
311}
312
313#define max(x, y) (x > y? x : y)
314
315static uint16_t
316calc_padded_length (uint16_t length)
317{
318 static uint16_t usual_padding = 0;
319
320 if (!usual_padding)
321 usual_padding = calc_usual_padding();
322
323 const uint16_t padded_length = max(
324 length + GNUNET_MESSENGER_PADDING_MIN,
325 usual_padding
326 );
327
328 if (padded_length <= GNUNET_MESSENGER_PADDING_LEVEL0)
329 return GNUNET_MESSENGER_PADDING_LEVEL0;
330
331 if (padded_length <= GNUNET_MESSENGER_PADDING_LEVEL1)
332 return GNUNET_MESSENGER_PADDING_LEVEL1;
333
334 if (padded_length <= GNUNET_MESSENGER_PADDING_LEVEL2)
335 return GNUNET_MESSENGER_PADDING_LEVEL2;
336
337 return GNUNET_MESSENGER_MAX_MESSAGE_SIZE;
338
264} 339}
265 340
266#define min(x, y) (x < y? x : y) 341#define min(x, y) (x < y? x : y)
@@ -272,7 +347,27 @@ get_short_message_size (const struct GNUNET_MESSENGER_ShortMessage *message)
272 347
273#define encode_step(dst, offset, src) do { \ 348#define encode_step(dst, offset, src) do { \
274 encode_step_ext(dst, offset, src, sizeof(*src)); \ 349 encode_step_ext(dst, offset, src, sizeof(*src)); \
275} while(0) 350} while (0)
351
352#define encode_step_key(dst, offset, src, length) do { \
353 ssize_t result = GNUNET_IDENTITY_write_key_to_buffer( \
354 src, dst + offset, length - offset \
355 ); \
356 if (result < 0) \
357 GNUNET_break (0); \
358 else \
359 offset += result; \
360} while (0)
361
362#define encode_step_signature(dst, offset, src, length) do { \
363 ssize_t result = GNUNET_IDENTITY_write_signature_to_buffer( \
364 src, dst + offset, length - offset \
365 ); \
366 if (result < 0) \
367 GNUNET_break (0); \
368 else \
369 offset += result; \
370} while (0)
276 371
277static void 372static void
278encode_message_body (enum GNUNET_MESSENGER_MessageKind kind, const struct GNUNET_MESSENGER_MessageBody *body, 373encode_message_body (enum GNUNET_MESSENGER_MessageKind kind, const struct GNUNET_MESSENGER_MessageBody *body,
@@ -281,20 +376,18 @@ encode_message_body (enum GNUNET_MESSENGER_MessageKind kind, const struct GNUNET
281 switch (kind) 376 switch (kind)
282 { 377 {
283 case GNUNET_MESSENGER_KIND_INFO: 378 case GNUNET_MESSENGER_KIND_INFO:
284 encode_step(buffer, offset, &(body->info.host_key)); 379 encode_step_key(buffer, offset, &(body->info.host_key), length);
285 encode_step(buffer, offset, &(body->info.unique_id)); 380 encode_step(buffer, offset, &(body->info.messenger_version));
286 break; 381 break;
287 case GNUNET_MESSENGER_KIND_JOIN: 382 case GNUNET_MESSENGER_KIND_JOIN:
288 encode_step(buffer, offset, &(body->join.key)); 383 encode_step_key(buffer, offset, &(body->join.key), length);
289 break;
290 case GNUNET_MESSENGER_KIND_LEAVE:
291 break; 384 break;
292 case GNUNET_MESSENGER_KIND_NAME: 385 case GNUNET_MESSENGER_KIND_NAME:
293 if (body->name.name) 386 if (body->name.name)
294 encode_step_ext(buffer, offset, body->name.name, min(length - offset, strlen(body->name.name))); 387 encode_step_ext(buffer, offset, body->name.name, min(length - offset, strlen(body->name.name)));
295 break; 388 break;
296 case GNUNET_MESSENGER_KIND_KEY: 389 case GNUNET_MESSENGER_KIND_KEY:
297 encode_step(buffer, offset, &(body->key.key)); 390 encode_step_key(buffer, offset, &(body->key.key), length);
298 break; 391 break;
299 case GNUNET_MESSENGER_KIND_PEER: 392 case GNUNET_MESSENGER_KIND_PEER:
300 encode_step(buffer, offset, &(body->peer.peer)); 393 encode_step(buffer, offset, &(body->peer.peer));
@@ -321,7 +414,7 @@ encode_message_body (enum GNUNET_MESSENGER_MessageKind kind, const struct GNUNET
321 case GNUNET_MESSENGER_KIND_FILE: 414 case GNUNET_MESSENGER_KIND_FILE:
322 encode_step(buffer, offset, &(body->file.key)); 415 encode_step(buffer, offset, &(body->file.key));
323 encode_step(buffer, offset, &(body->file.hash)); 416 encode_step(buffer, offset, &(body->file.hash));
324 encode_step_ext(buffer, offset, body->file.name, NAME_MAX); 417 encode_step_ext(buffer, offset, body->file.name, sizeof(body->file.name));
325 encode_step_ext(buffer, offset, body->file.uri, min(length - offset, strlen(body->file.uri))); 418 encode_step_ext(buffer, offset, body->file.uri, min(length - offset, strlen(body->file.uri)));
326 break; 419 break;
327 case GNUNET_MESSENGER_KIND_PRIVATE: 420 case GNUNET_MESSENGER_KIND_PRIVATE:
@@ -331,18 +424,40 @@ encode_message_body (enum GNUNET_MESSENGER_MessageKind kind, const struct GNUNET
331 default: 424 default:
332 break; 425 break;
333 } 426 }
427
428 if (offset >= length)
429 return;
430
431 const uint16_t padding = length - offset;
432 const uint16_t used_padding = sizeof(padding) + sizeof(char);
433
434 GNUNET_assert(padding >= used_padding);
435
436 buffer[offset++] = '\0';
437
438 if (padding > used_padding)
439 GNUNET_CRYPTO_random_block(GNUNET_CRYPTO_QUALITY_WEAK, buffer + offset, padding - used_padding);
440
441 GNUNET_memcpy(buffer + length - sizeof(padding), &padding, sizeof(padding));
334} 442}
335 443
336void 444void
337encode_message (const struct GNUNET_MESSENGER_Message *message, uint16_t length, char *buffer) 445encode_message (const struct GNUNET_MESSENGER_Message *message, uint16_t length, char *buffer,
446 int include_signature)
338{ 447{
448 GNUNET_assert((message) && (buffer));
449
339 uint16_t offset = 0; 450 uint16_t offset = 0;
340 451
341 encode_step(buffer, offset, &(message->header.signature)); 452 if (GNUNET_YES == include_signature)
453 encode_step_signature(buffer, offset, &(message->header.signature), length);
454
455 const kind_t kind = (kind_t) message->header.kind;
456
342 encode_step(buffer, offset, &(message->header.timestamp)); 457 encode_step(buffer, offset, &(message->header.timestamp));
343 encode_step(buffer, offset, &(message->header.sender_id)); 458 encode_step(buffer, offset, &(message->header.sender_id));
344 encode_step(buffer, offset, &(message->header.previous)); 459 encode_step(buffer, offset, &(message->header.previous));
345 encode_step(buffer, offset, &(message->header.kind)); 460 encode_step(buffer, offset, &kind);
346 461
347 encode_message_body (message->header.kind, &(message->body), length, buffer, offset); 462 encode_message_body (message->header.kind, &(message->body), length, buffer, offset);
348} 463}
@@ -350,11 +465,22 @@ encode_message (const struct GNUNET_MESSENGER_Message *message, uint16_t length,
350static void 465static void
351encode_short_message (const struct GNUNET_MESSENGER_ShortMessage *message, uint16_t length, char *buffer) 466encode_short_message (const struct GNUNET_MESSENGER_ShortMessage *message, uint16_t length, char *buffer)
352{ 467{
353 uint16_t offset = 0; 468 struct GNUNET_HashCode hash;
469 uint16_t offset = sizeof(hash);
354 470
355 encode_step(buffer, offset, &(message->kind)); 471 const kind_t kind = (kind_t) message->kind;
472
473 encode_step(buffer, offset, &kind);
356 474
357 encode_message_body (message->kind, &(message->body), length, buffer, offset); 475 encode_message_body (message->kind, &(message->body), length, buffer, offset);
476
477 GNUNET_CRYPTO_hash(
478 buffer + sizeof(hash),
479 length - sizeof(hash),
480 &hash
481 );
482
483 GNUNET_memcpy(buffer, &hash, sizeof(hash));
358} 484}
359 485
360#define decode_step_ext(src, offset, dst, size) do { \ 486#define decode_step_ext(src, offset, dst, size) do { \
@@ -372,29 +498,51 @@ encode_short_message (const struct GNUNET_MESSENGER_ShortMessage *message, uint1
372 decode_step_ext(src, offset, dst, size); \ 498 decode_step_ext(src, offset, dst, size); \
373} while (0) 499} while (0)
374 500
375static void 501#define decode_step_key(src, offset, dst, length) do { \
502 ssize_t result = GNUNET_IDENTITY_read_key_from_buffer( \
503 dst, src + offset, length - offset \
504 ); \
505 if (result < 0) \
506 GNUNET_break(0); \
507 else \
508 offset += result; \
509} while (0)
510
511static uint16_t
376decode_message_body (enum GNUNET_MESSENGER_MessageKind *kind, struct GNUNET_MESSENGER_MessageBody *body, 512decode_message_body (enum GNUNET_MESSENGER_MessageKind *kind, struct GNUNET_MESSENGER_MessageBody *body,
377 uint16_t length, const char *buffer, uint16_t offset) 513 uint16_t length, const char *buffer, uint16_t offset)
378{ 514{
515 uint16_t padding = 0;
516
517 GNUNET_memcpy(&padding, buffer + length - sizeof(padding), sizeof(padding));
518
519 if (padding > length - offset)
520 padding = 0;
521
522 const uint16_t end_zero = length - padding;
523
524 if ((padding) && (buffer[end_zero] != '\0'))
525 padding = 0;
526
527 length -= padding;
528
379 switch (*kind) 529 switch (*kind)
380 { 530 {
381 case GNUNET_MESSENGER_KIND_INFO: 531 case GNUNET_MESSENGER_KIND_INFO: {
382 decode_step(buffer, offset, &(body->info.host_key)); 532 decode_step_key(buffer, offset, &(body->info.host_key), length);
383 decode_step(buffer, offset, &(body->info.unique_id)); 533 decode_step(buffer, offset, &(body->info.messenger_version));
384 break; 534 break;
385 case GNUNET_MESSENGER_KIND_JOIN: 535 } case GNUNET_MESSENGER_KIND_JOIN: {
386 decode_step(buffer, offset, &(body->join.key)); 536 decode_step_key(buffer, offset, &(body->join.key), length);
387 break;
388 case GNUNET_MESSENGER_KIND_LEAVE:
389 break; 537 break;
390 case GNUNET_MESSENGER_KIND_NAME: 538 } case GNUNET_MESSENGER_KIND_NAME:
391 if (length - offset > 0) 539 if (length - offset > 0)
392 decode_step_malloc(buffer, offset, body->name.name, length - offset, 1); 540 decode_step_malloc(buffer, offset, body->name.name, length - offset, 1);
393 else 541 else
394 body->name.name = NULL; 542 body->name.name = NULL;
395 break; 543 break;
396 case GNUNET_MESSENGER_KIND_KEY: 544 case GNUNET_MESSENGER_KIND_KEY:
397 decode_step(buffer, offset, &(body->key.key)); 545 decode_step_key(buffer, offset, &(body->key.key), length);
398 break; 546 break;
399 case GNUNET_MESSENGER_KIND_PEER: 547 case GNUNET_MESSENGER_KIND_PEER:
400 decode_step(buffer, offset, &(body->peer.peer)); 548 decode_step(buffer, offset, &(body->peer.peer));
@@ -421,7 +569,7 @@ decode_message_body (enum GNUNET_MESSENGER_MessageKind *kind, struct GNUNET_MESS
421 case GNUNET_MESSENGER_KIND_FILE: 569 case GNUNET_MESSENGER_KIND_FILE:
422 decode_step(buffer, offset, &(body->file.key)); 570 decode_step(buffer, offset, &(body->file.key));
423 decode_step(buffer, offset, &(body->file.hash)); 571 decode_step(buffer, offset, &(body->file.hash));
424 decode_step_ext(buffer, offset, body->file.name, NAME_MAX); 572 decode_step_ext(buffer, offset, body->file.name, sizeof(body->file.name));
425 decode_step_malloc(buffer, offset, body->file.uri, length - offset, 1); 573 decode_step_malloc(buffer, offset, body->file.uri, length - offset, 1);
426 break; 574 break;
427 case GNUNET_MESSENGER_KIND_PRIVATE: 575 case GNUNET_MESSENGER_KIND_PRIVATE:
@@ -434,26 +582,51 @@ decode_message_body (enum GNUNET_MESSENGER_MessageKind *kind, struct GNUNET_MESS
434 *kind = GNUNET_MESSENGER_KIND_UNKNOWN; 582 *kind = GNUNET_MESSENGER_KIND_UNKNOWN;
435 break; 583 break;
436 } 584 }
585
586 return padding;
437} 587}
438 588
439int 589int
440decode_message (struct GNUNET_MESSENGER_Message *message, uint16_t length, const char *buffer) 590decode_message (struct GNUNET_MESSENGER_Message *message, uint16_t length, const char *buffer,
591 int include_signature, uint16_t *padding)
441{ 592{
593 GNUNET_assert((message) && (buffer));
594
442 uint16_t offset = 0; 595 uint16_t offset = 0;
443 596
444 if (length < get_message_kind_size (GNUNET_MESSENGER_KIND_UNKNOWN)) 597 if (GNUNET_YES == include_signature)
598 {
599 ssize_t result = GNUNET_IDENTITY_read_signature_from_buffer(
600 &(message->header.signature), buffer, length - offset
601 );
602
603 if (result < 0)
604 return GNUNET_NO;
605 else
606 offset += result;
607 }
608
609 const uint16_t count = length - offset;
610
611 if (count < get_message_kind_size (GNUNET_MESSENGER_KIND_UNKNOWN))
445 return GNUNET_NO; 612 return GNUNET_NO;
446 613
447 decode_step(buffer, offset, &(message->header.signature)); 614 kind_t kind;
615
448 decode_step(buffer, offset, &(message->header.timestamp)); 616 decode_step(buffer, offset, &(message->header.timestamp));
449 decode_step(buffer, offset, &(message->header.sender_id)); 617 decode_step(buffer, offset, &(message->header.sender_id));
450 decode_step(buffer, offset, &(message->header.previous)); 618 decode_step(buffer, offset, &(message->header.previous));
451 decode_step(buffer, offset, &(message->header.kind)); 619 decode_step(buffer, offset, &kind);
452 620
453 if (length < get_message_kind_size (message->header.kind)) 621 message->header.kind = (enum GNUNET_MESSENGER_MessageKind) kind;
622
623 if (count < get_message_kind_size (message->header.kind))
454 return GNUNET_NO; 624 return GNUNET_NO;
455 625
456 decode_message_body (&(message->header.kind), &(message->body), length, buffer, offset); 626 const uint16_t result = decode_message_body (&(message->header.kind), &(message->body), length, buffer, offset);
627
628 if (padding)
629 *padding = result;
457 630
458 return GNUNET_YES; 631 return GNUNET_YES;
459} 632}
@@ -461,47 +634,80 @@ decode_message (struct GNUNET_MESSENGER_Message *message, uint16_t length, const
461static int 634static int
462decode_short_message (struct GNUNET_MESSENGER_ShortMessage *message, uint16_t length, const char *buffer) 635decode_short_message (struct GNUNET_MESSENGER_ShortMessage *message, uint16_t length, const char *buffer)
463{ 636{
464 uint16_t offset = 0; 637 struct GNUNET_HashCode expected, hash;
638 uint16_t offset = sizeof(hash);
639
640 if (length < get_short_message_size (NULL, GNUNET_NO))
641 return GNUNET_NO;
642
643 GNUNET_memcpy(&hash, buffer, sizeof(hash));
644
645 GNUNET_CRYPTO_hash(
646 buffer + sizeof(hash),
647 length - sizeof(hash),
648 &expected
649 );
465 650
466 if (length < get_short_message_size (NULL)) 651 if (0 != GNUNET_CRYPTO_hash_cmp(&hash, &expected))
467 return GNUNET_NO; 652 return GNUNET_NO;
468 653
469 decode_step(buffer, offset, &(message->kind)); 654 kind_t kind;
470 655
471 if (length < get_short_message_size (message)) 656 decode_step(buffer, offset, &kind);
657
658 message->kind = (enum GNUNET_MESSENGER_MessageKind) kind;
659
660 if (length < get_short_message_size (message, GNUNET_NO))
472 return GNUNET_NO; 661 return GNUNET_NO;
473 662
474 decode_message_body (&(message->kind), &(message->body), length, buffer, offset); 663 decode_message_body (&(message->kind), &(message->body), length, buffer, offset);
475 664
665 if (GNUNET_MESSENGER_KIND_UNKNOWN == message->kind)
666 return GNUNET_NO;
667
476 return GNUNET_YES; 668 return GNUNET_YES;
477} 669}
478 670
479void 671void
480hash_message (uint16_t length, const char *buffer, struct GNUNET_HashCode *hash) 672hash_message (const struct GNUNET_MESSENGER_Message *message, uint16_t length, const char *buffer,
673 struct GNUNET_HashCode *hash)
481{ 674{
482 GNUNET_CRYPTO_hash (buffer + sizeof(struct GNUNET_CRYPTO_EcdsaSignature), 675 GNUNET_assert((message) && (buffer) && (hash));
483 length - sizeof(struct GNUNET_CRYPTO_EcdsaSignature), hash); 676
677 const ssize_t offset = GNUNET_IDENTITY_signature_get_length(
678 &(message->header.signature)
679 );
680
681 GNUNET_CRYPTO_hash (buffer + offset, length - offset, hash);
484} 682}
485 683
486void 684void
487sign_message (struct GNUNET_MESSENGER_Message *message, uint16_t length, char *buffer, 685sign_message (struct GNUNET_MESSENGER_Message *message, uint16_t length, char *buffer,
488 const struct GNUNET_HashCode *hash, const struct GNUNET_MESSENGER_Ego *ego) 686 const struct GNUNET_HashCode *hash, const struct GNUNET_MESSENGER_Ego *ego)
489{ 687{
688 GNUNET_assert((message) && (buffer) && (hash) && (ego));
689
490 struct GNUNET_MESSENGER_MessageSignature signature; 690 struct GNUNET_MESSENGER_MessageSignature signature;
491 691
492 signature.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE); 692 signature.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE);
493 signature.purpose.size = htonl (sizeof(signature)); 693 signature.purpose.size = htonl (sizeof(signature));
494 694
495 GNUNET_memcpy(&(signature.hash), hash, sizeof(struct GNUNET_HashCode)); 695 GNUNET_memcpy(&(signature.hash), hash, sizeof(struct GNUNET_HashCode));
496
497 GNUNET_IDENTITY_sign(&(ego->priv), &signature, &(message->header.signature)); 696 GNUNET_IDENTITY_sign(&(ego->priv), &signature, &(message->header.signature));
498 GNUNET_memcpy(buffer, &(message->header.signature), sizeof(struct GNUNET_CRYPTO_EcdsaSignature)); 697
698 uint16_t offset = 0;
699 encode_step_signature(buffer, offset, &(message->header.signature), length);
499} 700}
500 701
501int 702int
502verify_message (const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash, 703verify_message (const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash,
503 const struct GNUNET_IDENTITY_PublicKey *key) 704 const struct GNUNET_IDENTITY_PublicKey *key)
504{ 705{
706 GNUNET_assert((message) && (hash) && (key));
707
708 if (ntohl (key->type) != ntohl (message->header.signature.type))
709 return GNUNET_SYSERR;
710
505 struct GNUNET_MESSENGER_MessageSignature signature; 711 struct GNUNET_MESSENGER_MessageSignature signature;
506 712
507 signature.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE); 713 signature.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE);
@@ -516,26 +722,32 @@ verify_message (const struct GNUNET_MESSENGER_Message *message, const struct GNU
516int 722int
517encrypt_message (struct GNUNET_MESSENGER_Message *message, const struct GNUNET_IDENTITY_PublicKey *key) 723encrypt_message (struct GNUNET_MESSENGER_Message *message, const struct GNUNET_IDENTITY_PublicKey *key)
518{ 724{
725 GNUNET_assert((message) && (key));
726
519 struct GNUNET_MESSENGER_ShortMessage shortened; 727 struct GNUNET_MESSENGER_ShortMessage shortened;
520 728
521 fold_short_message (message, &shortened); 729 fold_short_message (message, &shortened);
522 730
523 const uint16_t length = get_short_message_size (&shortened); 731 const uint16_t length = get_short_message_size (&shortened, GNUNET_YES);
732 const uint16_t padded_length = calc_padded_length(length);
524 733
525 message->header.kind = GNUNET_MESSENGER_KIND_PRIVATE; 734 message->header.kind = GNUNET_MESSENGER_KIND_PRIVATE;
526 message->body.private.data = GNUNET_malloc(length); 735 message->body.private.data = GNUNET_malloc(padded_length);
736 message->body.private.length = padded_length;
527 737
528 encode_short_message (&shortened, length, message->body.private.data); 738 encode_short_message (&shortened, padded_length, message->body.private.data);
529 739
530 if (GNUNET_IDENTITY_encrypt (message->body.private.data, length, key, &(message->body.private.key), 740 if (padded_length == GNUNET_IDENTITY_encrypt (message->body.private.data, padded_length, key,
531 message->body.private.data) 741 &(message->body.private.key),
532 == length) 742 message->body.private.data))
533 { 743 {
534 destroy_message_body (shortened.kind, &(shortened.body)); 744 destroy_message_body (shortened.kind, &(shortened.body));
535 return GNUNET_YES; 745 return GNUNET_YES;
536 } 746 }
537 else 747 else
538 { 748 {
749 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Encrypting message failed!\n");
750
539 unfold_short_message (&shortened, message); 751 unfold_short_message (&shortened, message);
540 return GNUNET_NO; 752 return GNUNET_NO;
541 } 753 }
@@ -544,18 +756,28 @@ encrypt_message (struct GNUNET_MESSENGER_Message *message, const struct GNUNET_I
544int 756int
545decrypt_message (struct GNUNET_MESSENGER_Message *message, const struct GNUNET_IDENTITY_PrivateKey *key) 757decrypt_message (struct GNUNET_MESSENGER_Message *message, const struct GNUNET_IDENTITY_PrivateKey *key)
546{ 758{
547 if (message->body.private.length != GNUNET_IDENTITY_decrypt (message->body.private.data, 759 GNUNET_assert((message) && (key));
548 message->body.private.length, key, 760
549 &(message->body.private.key), 761 if (message->body.private.length != GNUNET_IDENTITY_decrypt (message->body.private.data, message->body.private.length,
762 key, &(message->body.private.key),
550 message->body.private.data)) 763 message->body.private.data))
764 {
765 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Decrypting message failed!\n");
766
551 return GNUNET_NO; 767 return GNUNET_NO;
768 }
552 769
553 struct GNUNET_MESSENGER_ShortMessage shortened; 770 struct GNUNET_MESSENGER_ShortMessage shortened;
554 771
555 if (GNUNET_YES != decode_short_message (&shortened, message->body.private.length, message->body.private.data)) 772 if (GNUNET_YES != decode_short_message (&shortened, message->body.private.length, message->body.private.data))
773 {
774 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Decoding decrypted message failed!\n");
775
556 return GNUNET_NO; 776 return GNUNET_NO;
777 }
557 778
558 unfold_short_message (&shortened, message); 779 unfold_short_message (&shortened, message);
780
559 return GNUNET_YES; 781 return GNUNET_YES;
560} 782}
561 783
@@ -563,18 +785,25 @@ struct GNUNET_MQ_Envelope*
563pack_message (struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash, 785pack_message (struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *hash,
564 const struct GNUNET_MESSENGER_Ego *ego, int mode) 786 const struct GNUNET_MESSENGER_Ego *ego, int mode)
565{ 787{
566 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Packing message: %u\n", message->header.kind); 788 GNUNET_assert(message);
789
790 if (ego)
791 message->header.signature.type = ego->priv.type;
792
793 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Packing message kind=%u and sender: %s\n",
794 message->header.kind, GNUNET_sh2s(&(message->header.sender_id)));
567 795
568 struct GNUNET_MessageHeader *header; 796 struct GNUNET_MessageHeader *header;
569 797
570 uint16_t length = get_message_size (message); 798 const uint16_t length = get_message_size (message, GNUNET_YES);
799 const uint16_t padded_length = calc_padded_length(length);
571 800
572 struct GNUNET_MQ_Envelope *env; 801 struct GNUNET_MQ_Envelope *env;
573 char *buffer; 802 char *buffer;
574 803
575 if (GNUNET_MESSENGER_PACK_MODE_ENVELOPE == mode) 804 if (GNUNET_MESSENGER_PACK_MODE_ENVELOPE == mode)
576 { 805 {
577 env = GNUNET_MQ_msg_extra(header, length, GNUNET_MESSAGE_TYPE_CADET_CLI); 806 env = GNUNET_MQ_msg_extra(header, padded_length, GNUNET_MESSAGE_TYPE_CADET_CLI);
578 807
579 buffer = (char*) &(header[1]); 808 buffer = (char*) &(header[1]);
580 } 809 }
@@ -582,14 +811,14 @@ pack_message (struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *
582 { 811 {
583 env = NULL; 812 env = NULL;
584 813
585 buffer = GNUNET_malloc(length); 814 buffer = GNUNET_malloc(padded_length);
586 } 815 }
587 816
588 encode_message (message, length, buffer); 817 encode_message (message, padded_length, buffer, GNUNET_YES);
589 818
590 if (hash) 819 if (hash)
591 { 820 {
592 hash_message (length, buffer, hash); 821 hash_message (message, length, buffer, hash);
593 822
594 if (ego) 823 if (ego)
595 sign_message (message, length, buffer, hash, ego); 824 sign_message (message, length, buffer, hash, ego);
@@ -600,3 +829,43 @@ pack_message (struct GNUNET_MESSENGER_Message *message, struct GNUNET_HashCode *
600 829
601 return env; 830 return env;
602} 831}
832
833int
834filter_message_sending (const struct GNUNET_MESSENGER_Message *message)
835{
836 switch (message->header.kind)
837 {
838 case GNUNET_MESSENGER_KIND_INFO:
839 return GNUNET_SYSERR; // Reserved for connection handling only!
840 case GNUNET_MESSENGER_KIND_JOIN:
841 return GNUNET_NO; // Use #GNUNET_MESSENGER_enter_room(...) instead!
842 case GNUNET_MESSENGER_KIND_LEAVE:
843 return GNUNET_NO; // Use #GNUNET_MESSENGER_close_room(...) instead!
844 case GNUNET_MESSENGER_KIND_NAME:
845 return GNUNET_YES;
846 case GNUNET_MESSENGER_KIND_KEY:
847 return GNUNET_NO; // Use #GNUNET_MESSENGER_update(...) instead!
848 case GNUNET_MESSENGER_KIND_PEER:
849 return GNUNET_NO; // Use #GNUNET_MESSENGER_open_room(...) instead!
850 case GNUNET_MESSENGER_KIND_ID:
851 return GNUNET_SYSERR; // Reserved for member id handling only!
852 case GNUNET_MESSENGER_KIND_MISS:
853 return GNUNET_SYSERR; // Reserved for connection handling only!
854 case GNUNET_MESSENGER_KIND_MERGE:
855 return GNUNET_YES;
856 case GNUNET_MESSENGER_KIND_REQUEST:
857 return GNUNET_YES;
858 case GNUNET_MESSENGER_KIND_INVITE:
859 return GNUNET_YES;
860 case GNUNET_MESSENGER_KIND_TEXT:
861 return GNUNET_YES;
862 case GNUNET_MESSENGER_KIND_FILE:
863 return GNUNET_YES;
864 case GNUNET_MESSENGER_KIND_PRIVATE:
865 return GNUNET_NO; // Use #GNUNET_MESSENGER_send_message(...) with a contact instead!
866 case GNUNET_MESSENGER_KIND_DELETE:
867 return GNUNET_YES;
868 default:
869 return GNUNET_SYSERR;
870 }
871}