1 #include "test_common.h"
2
3 #include <stdlib.h>
4 #include <string.h>
5 #include <check.h>
6
7 #include "../src/signal_protocol.h"
8 #include "curve.h"
9 #include "uthash.h"
10
11 /*
12 * This is an implementation of Jenkin's "One-at-a-Time" hash.
13 *
14 * http://www.burtleburtle.net/bob/hash/doobs.html
15 *
16 * It is used to simplify using our new string recipient IDs
17 * as part of our keys without having to significantly modify the
18 * testing-only implementations of our data stores.
19 */
jenkins_hash(const char * key,size_t len)20 int64_t jenkins_hash(const char *key, size_t len)
21 {
22 uint64_t hash, i;
23 for(hash = i = 0; i < len; ++i) {
24 hash += key[i];
25 hash += (hash << 10);
26 hash ^= (hash >> 6);
27 }
28 hash += (hash << 3);
29 hash ^= (hash >> 11);
30 hash += (hash << 15);
31 return hash;
32 }
33
print_public_key(const char * prefix,ec_public_key * key)34 void print_public_key(const char *prefix, ec_public_key *key)
35 {
36 signal_buffer *buffer;
37 ec_public_key_serialize(&buffer, key);
38
39 fprintf(stderr, "%s ", prefix);
40 uint8_t *data = signal_buffer_data(buffer);
41 int len = signal_buffer_len(buffer);
42 int i;
43 for(i = 0; i < len; i++) {
44 if(i > 0 && (i % 40) == 0) {
45 fprintf(stderr, "\n");
46 }
47 fprintf(stderr, "%02X", data[i]);
48 }
49 fprintf(stderr, "\n");
50 signal_buffer_free(buffer);
51 }
52
print_buffer(const char * prefix,signal_buffer * buffer)53 void print_buffer(const char *prefix, signal_buffer *buffer)
54 {
55 fprintf(stderr, "%s ", prefix);
56 uint8_t *data = signal_buffer_data(buffer);
57 int len = signal_buffer_len(buffer);
58 int i;
59 for(i = 0; i < len; i++) {
60 if(i > 0 && (i % 40) == 0) {
61 fprintf(stderr, "\n");
62 }
63 fprintf(stderr, "%02X", data[i]);
64 }
65 fprintf(stderr, "\n");
66 }
67
shuffle_buffers(signal_buffer ** array,size_t n)68 void shuffle_buffers(signal_buffer **array, size_t n)
69 {
70 if (n > 1) {
71 size_t i;
72 for (i = 0; i < n - 1; i++) {
73 size_t j = i + rand() / (RAND_MAX / (n - i) + 1);
74 signal_buffer *t = array[j];
75 array[j] = array[i];
76 array[i] = t;
77 }
78 }
79 }
80
shuffle_ec_public_keys(ec_public_key ** array,size_t n)81 void shuffle_ec_public_keys(ec_public_key **array, size_t n)
82 {
83 if (n > 1) {
84 size_t i;
85 for (i = 0; i < n - 1; i++) {
86 size_t j = i + rand() / (RAND_MAX / (n - i) + 1);
87 ec_public_key *t = array[j];
88 array[j] = array[i];
89 array[i] = t;
90 }
91 }
92 }
93
create_test_ec_public_key(signal_context * context)94 ec_public_key *create_test_ec_public_key(signal_context *context)
95 {
96 int result = 0;
97 ec_key_pair *key_pair;
98 result = curve_generate_key_pair(context, &key_pair);
99 ck_assert_int_eq(result, 0);
100
101 ec_public_key *public_key = ec_key_pair_get_public(key_pair);
102 SIGNAL_REF(public_key);
103 SIGNAL_UNREF(key_pair);
104 return public_key;
105 }
106
create_test_ec_private_key(signal_context * context)107 ec_private_key *create_test_ec_private_key(signal_context *context)
108 {
109 int result = 0;
110 ec_key_pair *key_pair;
111 result = curve_generate_key_pair(context, &key_pair);
112 ck_assert_int_eq(result, 0);
113
114 ec_private_key *private_key = ec_key_pair_get_private(key_pair);
115 SIGNAL_REF(private_key);
116 SIGNAL_UNREF(key_pair);
117 return private_key;
118 }
119
test_log(int level,const char * message,size_t len,void * user_data)120 void test_log(int level, const char *message, size_t len, void *user_data)
121 {
122 switch(level) {
123 case SG_LOG_ERROR:
124 fprintf(stderr, "[ERROR] %s\n", message);
125 break;
126 case SG_LOG_WARNING:
127 fprintf(stderr, "[WARNING] %s\n", message);
128 break;
129 case SG_LOG_NOTICE:
130 fprintf(stderr, "[NOTICE] %s\n", message);
131 break;
132 case SG_LOG_INFO:
133 fprintf(stderr, "[INFO] %s\n", message);
134 break;
135 case SG_LOG_DEBUG:
136 fprintf(stderr, "[DEBUG] %s\n", message);
137 break;
138 default:
139 fprintf(stderr, "[%d] %s\n", level, message);
140 break;
141 }
142 }
143
setup_test_crypto_provider(signal_context * context)144 void setup_test_crypto_provider(signal_context *context)
145 {
146 signal_crypto_provider provider = {
147 .random_func = test_random_generator,
148 .hmac_sha256_init_func = test_hmac_sha256_init,
149 .hmac_sha256_update_func = test_hmac_sha256_update,
150 .hmac_sha256_final_func = test_hmac_sha256_final,
151 .hmac_sha256_cleanup_func = test_hmac_sha256_cleanup,
152 .sha512_digest_init_func = test_sha512_digest_init,
153 .sha512_digest_update_func = test_sha512_digest_update,
154 .sha512_digest_final_func = test_sha512_digest_final,
155 .sha512_digest_cleanup_func = test_sha512_digest_cleanup,
156 .encrypt_func = test_encrypt,
157 .decrypt_func = test_decrypt,
158 .user_data = 0
159 };
160
161 signal_context_set_crypto_provider(context, &provider);
162 }
163
164 /*------------------------------------------------------------------------*/
165
setup_test_store_context(signal_protocol_store_context ** context,signal_context * global_context)166 void setup_test_store_context(signal_protocol_store_context **context, signal_context *global_context)
167 {
168 int result = 0;
169
170 signal_protocol_store_context *store_context = 0;
171 result = signal_protocol_store_context_create(&store_context, global_context);
172 ck_assert_int_eq(result, 0);
173
174 setup_test_session_store(store_context);
175 setup_test_pre_key_store(store_context);
176 setup_test_signed_pre_key_store(store_context);
177 setup_test_identity_key_store(store_context, global_context);
178 setup_test_sender_key_store(store_context, global_context);
179
180 *context = store_context;
181 }
182
183 /*------------------------------------------------------------------------*/
184
185 typedef struct {
186 int64_t recipient_id;
187 int32_t device_id;
188 } test_session_store_session_key;
189
190 typedef struct {
191 test_session_store_session_key key;
192 signal_buffer *record;
193 UT_hash_handle hh;
194 } test_session_store_session;
195
196 typedef struct {
197 test_session_store_session *sessions;
198 } test_session_store_data;
199
test_session_store_load_session(signal_buffer ** record,signal_buffer ** user_record,const signal_protocol_address * address,void * user_data)200 int test_session_store_load_session(signal_buffer **record, signal_buffer **user_record, const signal_protocol_address *address, void *user_data)
201 {
202 test_session_store_data *data = user_data;
203
204 test_session_store_session *s;
205
206 test_session_store_session l;
207 memset(&l, 0, sizeof(test_session_store_session));
208 l.key.recipient_id = jenkins_hash(address->name, address->name_len);
209 l.key.device_id = address->device_id;
210 HASH_FIND(hh, data->sessions, &l.key, sizeof(test_session_store_session_key), s);
211
212 if(!s) {
213 return 0;
214 }
215 signal_buffer *result = signal_buffer_copy(s->record);
216 if(!result) {
217 return SG_ERR_NOMEM;
218 }
219 *record = result;
220 return 1;
221 }
222
test_session_store_get_sub_device_sessions(signal_int_list ** sessions,const char * name,size_t name_len,void * user_data)223 int test_session_store_get_sub_device_sessions(signal_int_list **sessions, const char *name, size_t name_len, void *user_data)
224 {
225 test_session_store_data *data = user_data;
226
227 signal_int_list *result = signal_int_list_alloc();
228 if(!result) {
229 return SG_ERR_NOMEM;
230 }
231
232 int64_t recipient_hash = jenkins_hash(name, name_len);
233 test_session_store_session *cur_node;
234 test_session_store_session *tmp_node;
235 HASH_ITER(hh, data->sessions, cur_node, tmp_node) {
236 if(cur_node->key.recipient_id == recipient_hash) {
237 signal_int_list_push_back(result, cur_node->key.device_id);
238 }
239 }
240
241 *sessions = result;
242 return 0;
243 }
244
test_session_store_store_session(const signal_protocol_address * address,uint8_t * record,size_t record_len,uint8_t * user_record_data,size_t user_record_len,void * user_data)245 int test_session_store_store_session(const signal_protocol_address *address, uint8_t *record, size_t record_len, uint8_t *user_record_data, size_t user_record_len, void *user_data)
246 {
247 test_session_store_data *data = user_data;
248
249 test_session_store_session *s;
250
251 test_session_store_session l;
252 memset(&l, 0, sizeof(test_session_store_session));
253 l.key.recipient_id = jenkins_hash(address->name, address->name_len);
254 l.key.device_id = address->device_id;
255
256 signal_buffer *record_buf = signal_buffer_create(record, record_len);
257 if(!record_buf) {
258 return SG_ERR_NOMEM;
259 }
260
261 HASH_FIND(hh, data->sessions, &l.key, sizeof(test_session_store_session_key), s);
262
263 if(s) {
264 signal_buffer_free(s->record);
265 s->record = record_buf;
266 }
267 else {
268 s = malloc(sizeof(test_session_store_session));
269 if(!s) {
270 signal_buffer_free(record_buf);
271 return SG_ERR_NOMEM;
272 }
273 memset(s, 0, sizeof(test_session_store_session));
274 s->key.recipient_id = jenkins_hash(address->name, address->name_len);
275 s->key.device_id = address->device_id;
276 s->record = record_buf;
277 HASH_ADD(hh, data->sessions, key, sizeof(test_session_store_session_key), s);
278 }
279
280 return 0;
281 }
282
test_session_store_contains_session(const signal_protocol_address * address,void * user_data)283 int test_session_store_contains_session(const signal_protocol_address *address, void *user_data)
284 {
285 test_session_store_data *data = user_data;
286 test_session_store_session *s;
287
288 test_session_store_session l;
289 memset(&l, 0, sizeof(test_session_store_session));
290 l.key.recipient_id = jenkins_hash(address->name, address->name_len);
291 l.key.device_id = address->device_id;
292
293 HASH_FIND(hh, data->sessions, &l.key, sizeof(test_session_store_session_key), s);
294
295 return (s == 0) ? 0 : 1;
296 }
297
test_session_store_delete_session(const signal_protocol_address * address,void * user_data)298 int test_session_store_delete_session(const signal_protocol_address *address, void *user_data)
299 {
300 int result = 0;
301 test_session_store_data *data = user_data;
302 test_session_store_session *s;
303
304 test_session_store_session l;
305 memset(&l, 0, sizeof(test_session_store_session));
306 l.key.recipient_id = jenkins_hash(address->name, address->name_len);
307 l.key.device_id = address->device_id;
308
309 HASH_FIND(hh, data->sessions, &l.key, sizeof(test_session_store_session_key), s);
310
311 if(s) {
312 HASH_DEL(data->sessions, s);
313 signal_buffer_free(s->record);
314 free(s);
315 result = 1;
316 }
317 return result;
318 }
319
test_session_store_delete_all_sessions(const char * name,size_t name_len,void * user_data)320 int test_session_store_delete_all_sessions(const char *name, size_t name_len, void *user_data)
321 {
322 int result = 0;
323 test_session_store_data *data = user_data;
324
325 int64_t recipient_hash = jenkins_hash(name, name_len);
326 test_session_store_session *cur_node;
327 test_session_store_session *tmp_node;
328 HASH_ITER(hh, data->sessions, cur_node, tmp_node) {
329 if(cur_node->key.recipient_id == recipient_hash) {
330 HASH_DEL(data->sessions, cur_node);
331 signal_buffer_free(cur_node->record);
332 free(cur_node);
333 result++;
334 }
335 }
336
337 return result;
338 }
339
test_session_store_destroy(void * user_data)340 void test_session_store_destroy(void *user_data)
341 {
342 test_session_store_data *data = user_data;
343
344 test_session_store_session *cur_node;
345 test_session_store_session *tmp_node;
346 HASH_ITER(hh, data->sessions, cur_node, tmp_node) {
347 HASH_DEL(data->sessions, cur_node);
348 signal_buffer_free(cur_node->record);
349 free(cur_node);
350 }
351
352 free(data);
353 }
354
setup_test_session_store(signal_protocol_store_context * context)355 void setup_test_session_store(signal_protocol_store_context *context)
356 {
357 test_session_store_data *data = malloc(sizeof(test_session_store_data));
358 memset(data, 0, sizeof(test_session_store_data));
359
360 signal_protocol_session_store store = {
361 .load_session_func = test_session_store_load_session,
362 .get_sub_device_sessions_func = test_session_store_get_sub_device_sessions,
363 .store_session_func = test_session_store_store_session,
364 .contains_session_func = test_session_store_contains_session,
365 .delete_session_func = test_session_store_delete_session,
366 .delete_all_sessions_func = test_session_store_delete_all_sessions,
367 .destroy_func = test_session_store_destroy,
368 .user_data = data
369 };
370
371 signal_protocol_store_context_set_session_store(context, &store);
372 }
373
374 /*------------------------------------------------------------------------*/
375
376 typedef struct {
377 uint32_t key_id;
378 signal_buffer *key_record;
379 UT_hash_handle hh;
380 } test_pre_key_store_key;
381
382 typedef struct {
383 test_pre_key_store_key *keys;
384 } test_pre_key_store_data;
385
test_pre_key_store_load_pre_key(signal_buffer ** record,uint32_t pre_key_id,void * user_data)386 int test_pre_key_store_load_pre_key(signal_buffer **record, uint32_t pre_key_id, void *user_data)
387 {
388 test_pre_key_store_data *data = user_data;
389
390 test_pre_key_store_key *s;
391
392 HASH_FIND(hh, data->keys, &pre_key_id, sizeof(uint32_t), s);
393 if(s) {
394 *record = signal_buffer_copy(s->key_record);
395 return SG_SUCCESS;
396 }
397 else {
398 return SG_ERR_INVALID_KEY_ID;
399 }
400 }
401
test_pre_key_store_store_pre_key(uint32_t pre_key_id,uint8_t * record,size_t record_len,void * user_data)402 int test_pre_key_store_store_pre_key(uint32_t pre_key_id, uint8_t *record, size_t record_len, void *user_data)
403 {
404 test_pre_key_store_data *data = user_data;
405
406 test_pre_key_store_key *s;
407
408 signal_buffer *key_buf = signal_buffer_create(record, record_len);
409 if(!key_buf) {
410 return SG_ERR_NOMEM;
411 }
412
413 HASH_FIND(hh, data->keys, &pre_key_id, sizeof(uint32_t), s);
414 if(s) {
415 signal_buffer_free(s->key_record);
416 s->key_record = key_buf;
417 }
418 else {
419 s = malloc(sizeof(test_pre_key_store_key));
420 if(!s) {
421 signal_buffer_free(key_buf);
422 return SG_ERR_NOMEM;
423 }
424 memset(s, 0, sizeof(test_pre_key_store_key));
425 s->key_id = pre_key_id;
426 s->key_record = key_buf;
427 HASH_ADD(hh, data->keys, key_id, sizeof(uint32_t), s);
428 }
429
430 return 0;
431 }
432
test_pre_key_store_contains_pre_key(uint32_t pre_key_id,void * user_data)433 int test_pre_key_store_contains_pre_key(uint32_t pre_key_id, void *user_data)
434 {
435 test_pre_key_store_data *data = user_data;
436
437 test_pre_key_store_key *s;
438 HASH_FIND(hh, data->keys, &pre_key_id, sizeof(uint32_t), s);
439
440 return (s == 0) ? 0 : 1;
441 }
442
test_pre_key_store_remove_pre_key(uint32_t pre_key_id,void * user_data)443 int test_pre_key_store_remove_pre_key(uint32_t pre_key_id, void *user_data)
444 {
445 test_pre_key_store_data *data = user_data;
446
447 test_pre_key_store_key *s;
448 HASH_FIND(hh, data->keys, &pre_key_id, sizeof(uint32_t), s);
449 if(s) {
450 HASH_DEL(data->keys, s);
451 signal_buffer_free(s->key_record);
452 free(s);
453 }
454
455 return 0;
456 }
457
test_pre_key_store_destroy(void * user_data)458 void test_pre_key_store_destroy(void *user_data)
459 {
460 test_pre_key_store_data *data = user_data;
461
462 test_pre_key_store_key *cur_node;
463 test_pre_key_store_key *tmp_node;
464 HASH_ITER(hh, data->keys, cur_node, tmp_node) {
465 HASH_DEL(data->keys, cur_node);
466 signal_buffer_free(cur_node->key_record);
467 free(cur_node);
468 }
469 free(data);
470 }
471
setup_test_pre_key_store(signal_protocol_store_context * context)472 void setup_test_pre_key_store(signal_protocol_store_context *context)
473 {
474 test_pre_key_store_data *data = malloc(sizeof(test_pre_key_store_data));
475 memset(data, 0, sizeof(test_pre_key_store_data));
476
477 signal_protocol_pre_key_store store = {
478 .load_pre_key = test_pre_key_store_load_pre_key,
479 .store_pre_key = test_pre_key_store_store_pre_key,
480 .contains_pre_key = test_pre_key_store_contains_pre_key,
481 .remove_pre_key = test_pre_key_store_remove_pre_key,
482 .destroy_func = test_pre_key_store_destroy,
483 .user_data = data
484 };
485
486 signal_protocol_store_context_set_pre_key_store(context, &store);
487 }
488
489 /*------------------------------------------------------------------------*/
490
491 typedef struct {
492 uint32_t key_id;
493 signal_buffer *key_record;
494 UT_hash_handle hh;
495 } test_signed_pre_key_store_key;
496
497 typedef struct {
498 test_signed_pre_key_store_key *keys;
499 } test_signed_pre_key_store_data;
500
501
test_signed_pre_key_store_load_signed_pre_key(signal_buffer ** record,uint32_t signed_pre_key_id,void * user_data)502 int test_signed_pre_key_store_load_signed_pre_key(signal_buffer **record, uint32_t signed_pre_key_id, void *user_data)
503 {
504 test_signed_pre_key_store_data *data = user_data;
505 test_signed_pre_key_store_key *s;
506
507 HASH_FIND(hh, data->keys, &signed_pre_key_id, sizeof(uint32_t), s);
508 if(s) {
509 *record = signal_buffer_copy(s->key_record);
510 return SG_SUCCESS;
511 }
512 else {
513 return SG_ERR_INVALID_KEY_ID;
514 }
515 }
516
test_signed_pre_key_store_store_signed_pre_key(uint32_t signed_pre_key_id,uint8_t * record,size_t record_len,void * user_data)517 int test_signed_pre_key_store_store_signed_pre_key(uint32_t signed_pre_key_id, uint8_t *record, size_t record_len, void *user_data)
518 {
519 test_signed_pre_key_store_data *data = user_data;
520 test_signed_pre_key_store_key *s;
521
522 signal_buffer *key_buf = signal_buffer_create(record, record_len);
523 if(!key_buf) {
524 return SG_ERR_NOMEM;
525 }
526
527 HASH_FIND(hh, data->keys, &signed_pre_key_id, sizeof(uint32_t), s);
528 if(s) {
529 signal_buffer_free(s->key_record);
530 s->key_record = key_buf;
531 }
532 else {
533 s = malloc(sizeof(test_signed_pre_key_store_key));
534 if(!s) {
535 signal_buffer_free(key_buf);
536 return SG_ERR_NOMEM;
537 }
538 memset(s, 0, sizeof(test_signed_pre_key_store_key));
539 s->key_id = signed_pre_key_id;
540 s->key_record = key_buf;
541 HASH_ADD(hh, data->keys, key_id, sizeof(uint32_t), s);
542 }
543
544 return 0;
545 }
546
test_signed_pre_key_store_contains_signed_pre_key(uint32_t signed_pre_key_id,void * user_data)547 int test_signed_pre_key_store_contains_signed_pre_key(uint32_t signed_pre_key_id, void *user_data)
548 {
549 test_signed_pre_key_store_data *data = user_data;
550
551 test_signed_pre_key_store_key *s;
552 HASH_FIND(hh, data->keys, &signed_pre_key_id, sizeof(uint32_t), s);
553
554 return (s == 0) ? 0 : 1;
555 }
556
test_signed_pre_key_store_remove_signed_pre_key(uint32_t signed_pre_key_id,void * user_data)557 int test_signed_pre_key_store_remove_signed_pre_key(uint32_t signed_pre_key_id, void *user_data)
558 {
559 test_signed_pre_key_store_data *data = user_data;
560
561 test_signed_pre_key_store_key *s;
562 HASH_FIND(hh, data->keys, &signed_pre_key_id, sizeof(uint32_t), s);
563 if(s) {
564 HASH_DEL(data->keys, s);
565 signal_buffer_free(s->key_record);
566 free(s);
567 }
568
569 return 0;
570 }
571
test_signed_pre_key_store_destroy(void * user_data)572 void test_signed_pre_key_store_destroy(void *user_data)
573 {
574 test_signed_pre_key_store_data *data = user_data;
575
576 test_signed_pre_key_store_key *cur_node;
577 test_signed_pre_key_store_key *tmp_node;
578 HASH_ITER(hh, data->keys, cur_node, tmp_node) {
579 HASH_DEL(data->keys, cur_node);
580 signal_buffer_free(cur_node->key_record);
581 free(cur_node);
582 }
583 free(data);
584 }
585
setup_test_signed_pre_key_store(signal_protocol_store_context * context)586 void setup_test_signed_pre_key_store(signal_protocol_store_context *context)
587 {
588 test_signed_pre_key_store_data *data = malloc(sizeof(test_signed_pre_key_store_data));
589 memset(data, 0, sizeof(test_signed_pre_key_store_data));
590
591 signal_protocol_signed_pre_key_store store = {
592 .load_signed_pre_key = test_signed_pre_key_store_load_signed_pre_key,
593 .store_signed_pre_key = test_signed_pre_key_store_store_signed_pre_key,
594 .contains_signed_pre_key = test_signed_pre_key_store_contains_signed_pre_key,
595 .remove_signed_pre_key = test_signed_pre_key_store_remove_signed_pre_key,
596 .destroy_func = test_signed_pre_key_store_destroy,
597 .user_data = data
598 };
599
600 signal_protocol_store_context_set_signed_pre_key_store(context, &store);
601 }
602
603 /*------------------------------------------------------------------------*/
604
605 typedef struct {
606 int64_t recipient_id;
607 signal_buffer *identity_key;
608 UT_hash_handle hh;
609 } test_identity_store_key;
610
611 typedef struct {
612 test_identity_store_key *keys;
613 signal_buffer *identity_key_public;
614 signal_buffer *identity_key_private;
615 uint32_t local_registration_id;
616 } test_identity_store_data;
617
test_identity_key_store_get_identity_key_pair(signal_buffer ** public_data,signal_buffer ** private_data,void * user_data)618 int test_identity_key_store_get_identity_key_pair(signal_buffer **public_data, signal_buffer **private_data, void *user_data)
619 {
620 test_identity_store_data *data = user_data;
621 *public_data = signal_buffer_copy(data->identity_key_public);
622 *private_data = signal_buffer_copy(data->identity_key_private);
623 return 0;
624 }
625
test_identity_key_store_get_local_registration_id(void * user_data,uint32_t * registration_id)626 int test_identity_key_store_get_local_registration_id(void *user_data, uint32_t *registration_id)
627 {
628 test_identity_store_data *data = user_data;
629 *registration_id = data->local_registration_id;
630 return 0;
631 }
632
test_identity_key_store_save_identity(const signal_protocol_address * address,uint8_t * key_data,size_t key_len,void * user_data)633 int test_identity_key_store_save_identity(const signal_protocol_address *address, uint8_t *key_data, size_t key_len, void *user_data)
634 {
635 test_identity_store_data *data = user_data;
636
637 test_identity_store_key *s;
638
639 signal_buffer *key_buf = signal_buffer_create(key_data, key_len);
640 if(!key_buf) {
641 return SG_ERR_NOMEM;
642 }
643
644 int64_t recipient_hash = jenkins_hash(address->name, address->name_len);
645
646 HASH_FIND(hh, data->keys, &recipient_hash, sizeof(int64_t), s);
647 if(s) {
648 signal_buffer_free(s->identity_key);
649 s->identity_key = key_buf;
650 }
651 else {
652 s = malloc(sizeof(test_identity_store_key));
653 if(!s) {
654 signal_buffer_free(key_buf);
655 return SG_ERR_NOMEM;
656 }
657 memset(s, 0, sizeof(test_identity_store_key));
658 s->recipient_id = recipient_hash;
659 s->identity_key = key_buf;
660 HASH_ADD(hh, data->keys, recipient_id, sizeof(int64_t), s);
661 }
662
663 return 0;
664 }
665
test_identity_key_store_is_trusted_identity(const signal_protocol_address * address,uint8_t * key_data,size_t key_len,void * user_data)666 int test_identity_key_store_is_trusted_identity(const signal_protocol_address *address, uint8_t *key_data, size_t key_len, void *user_data)
667 {
668 test_identity_store_data *data = user_data;
669
670 int64_t recipient_hash = jenkins_hash(address->name, address->name_len);
671
672 test_identity_store_key *s;
673 HASH_FIND(hh, data->keys, &recipient_hash, sizeof(int64_t), s);
674
675 if(s) {
676 uint8_t *store_data = signal_buffer_data(s->identity_key);
677 size_t store_len = signal_buffer_len(s->identity_key);
678 if(store_len != key_len) {
679 return 0;
680 }
681 if(memcmp(key_data, store_data, key_len) == 0) {
682 return 1;
683 }
684 else {
685 return 0;
686 }
687 }
688 else {
689 return 1;
690 }
691 }
692
test_identity_key_store_destroy(void * user_data)693 void test_identity_key_store_destroy(void *user_data)
694 {
695 test_identity_store_data *data = user_data;
696
697 test_identity_store_key *cur_node;
698 test_identity_store_key *tmp_node;
699 HASH_ITER(hh, data->keys, cur_node, tmp_node) {
700 HASH_DEL(data->keys, cur_node);
701 signal_buffer_free(cur_node->identity_key);
702 free(cur_node);
703 }
704 signal_buffer_free(data->identity_key_public);
705 signal_buffer_free(data->identity_key_private);
706 free(data);
707 }
708
setup_test_identity_key_store(signal_protocol_store_context * context,signal_context * global_context)709 void setup_test_identity_key_store(signal_protocol_store_context *context, signal_context *global_context)
710 {
711 test_identity_store_data *data = malloc(sizeof(test_identity_store_data));
712 memset(data, 0, sizeof(test_identity_store_data));
713
714 ec_key_pair *identity_key_pair_keys = 0;
715 curve_generate_key_pair(global_context, &identity_key_pair_keys);
716
717 ec_public_key *identity_key_public = ec_key_pair_get_public(identity_key_pair_keys);
718 ec_private_key *identity_key_private = ec_key_pair_get_private(identity_key_pair_keys);
719
720 ec_public_key_serialize(&data->identity_key_public, identity_key_public);
721 ec_private_key_serialize(&data->identity_key_private, identity_key_private);
722 SIGNAL_UNREF(identity_key_pair_keys);
723
724 data->local_registration_id = (rand() % 16380) + 1;
725
726 signal_protocol_identity_key_store store = {
727 .get_identity_key_pair = test_identity_key_store_get_identity_key_pair,
728 .get_local_registration_id = test_identity_key_store_get_local_registration_id,
729 .save_identity = test_identity_key_store_save_identity,
730 .is_trusted_identity = test_identity_key_store_is_trusted_identity,
731 .destroy_func = test_identity_key_store_destroy,
732 .user_data = data
733 };
734
735 signal_protocol_store_context_set_identity_key_store(context, &store);
736 }
737
738 /*------------------------------------------------------------------------*/
739
740 typedef struct {
741 int64_t group_id;
742 int64_t recipient_id;
743 int32_t device_id;
744 } test_sender_key_store_key;
745
746 typedef struct {
747 test_sender_key_store_key key;
748 signal_buffer *record;
749 UT_hash_handle hh;
750 } test_sender_key_store_record;
751
752 typedef struct {
753 test_sender_key_store_record *records;
754 } test_sender_key_store_data;
755
test_sender_key_store_store_sender_key(const signal_protocol_sender_key_name * sender_key_name,uint8_t * record,size_t record_len,uint8_t * user_record_data,size_t user_record_len,void * user_data)756 int test_sender_key_store_store_sender_key(const signal_protocol_sender_key_name *sender_key_name, uint8_t *record, size_t record_len, uint8_t *user_record_data, size_t user_record_len, void *user_data)
757 {
758 test_sender_key_store_data *data = user_data;
759
760 test_sender_key_store_record *s;
761
762 test_sender_key_store_record l;
763 memset(&l, 0, sizeof(test_sender_key_store_record));
764 l.key.group_id = jenkins_hash(sender_key_name->group_id, sender_key_name->group_id_len);
765 l.key.recipient_id = jenkins_hash(sender_key_name->sender.name, sender_key_name->sender.name_len);
766 l.key.device_id = sender_key_name->sender.device_id;
767
768 signal_buffer *record_buf = signal_buffer_create(record, record_len);
769 if(!record_buf) {
770 return SG_ERR_NOMEM;
771 }
772
773 HASH_FIND(hh, data->records, &l.key, sizeof(test_sender_key_store_key), s);
774
775 if(s) {
776 signal_buffer_free(s->record);
777 s->record = record_buf;
778 }
779 else {
780 s = malloc(sizeof(test_sender_key_store_record));
781 if(!s) {
782 signal_buffer_free(record_buf);
783 return SG_ERR_NOMEM;
784 }
785 memset(s, 0, sizeof(test_sender_key_store_record));
786 s->key.group_id = jenkins_hash(sender_key_name->group_id, sender_key_name->group_id_len);
787 s->key.recipient_id = jenkins_hash(sender_key_name->sender.name, sender_key_name->sender.name_len);
788 s->key.device_id = sender_key_name->sender.device_id;
789 s->record = record_buf;
790 HASH_ADD(hh, data->records, key, sizeof(test_sender_key_store_key), s);
791 }
792
793 return 0;
794 }
795
test_sender_key_store_load_sender_key(signal_buffer ** record,signal_buffer ** user_record,const signal_protocol_sender_key_name * sender_key_name,void * user_data)796 int test_sender_key_store_load_sender_key(signal_buffer **record, signal_buffer **user_record, const signal_protocol_sender_key_name *sender_key_name, void *user_data)
797 {
798 test_sender_key_store_data *data = user_data;
799
800 test_sender_key_store_record *s;
801
802 test_sender_key_store_record l;
803 memset(&l, 0, sizeof(test_sender_key_store_record));
804 l.key.group_id = jenkins_hash(sender_key_name->group_id, sender_key_name->group_id_len);
805 l.key.recipient_id = jenkins_hash(sender_key_name->sender.name, sender_key_name->sender.name_len);
806 l.key.device_id = sender_key_name->sender.device_id;
807 HASH_FIND(hh, data->records, &l.key, sizeof(test_sender_key_store_key), s);
808
809 if(!s) {
810 return 0;
811 }
812 signal_buffer *result = signal_buffer_copy(s->record);
813 if(!result) {
814 return SG_ERR_NOMEM;
815 }
816 *record = result;
817 return 1;
818 }
819
test_sender_key_store_destroy(void * user_data)820 void test_sender_key_store_destroy(void *user_data)
821 {
822 test_sender_key_store_data *data = user_data;
823
824 test_sender_key_store_record *cur_node;
825 test_sender_key_store_record *tmp_node;
826 HASH_ITER(hh, data->records, cur_node, tmp_node) {
827 HASH_DEL(data->records, cur_node);
828 signal_buffer_free(cur_node->record);
829 free(cur_node);
830 }
831 free(data);
832 }
833
setup_test_sender_key_store(signal_protocol_store_context * context,signal_context * global_context)834 void setup_test_sender_key_store(signal_protocol_store_context *context, signal_context *global_context)
835 {
836 test_sender_key_store_data *data = malloc(sizeof(test_sender_key_store_data));
837 memset(data, 0, sizeof(test_sender_key_store_data));
838
839 signal_protocol_sender_key_store store = {
840 .store_sender_key = test_sender_key_store_store_sender_key,
841 .load_sender_key = test_sender_key_store_load_sender_key,
842 .destroy_func = test_sender_key_store_destroy,
843 .user_data = data
844 };
845
846 signal_protocol_store_context_set_sender_key_store(context, &store);
847 }
848
849 #ifndef __OpenBSD__
srand_deterministic(unsigned int seed)850 void srand_deterministic(unsigned int seed)
851 {
852 srand(seed);
853 }
854 #endif
855
856